rust_macios/foundation/
ns_process_info.rs

1use std::fmt::Display;
2
3use block::{ConcreteBlock, IntoConcreteBlock};
4use libc::c_ulonglong;
5use objc::{msg_send, sel, sel_impl};
6
7use crate::{
8    object,
9    objective_c_runtime::{
10        id,
11        macros::interface_impl,
12        traits::{FromId, PNSObject},
13    },
14    utils::to_bool,
15};
16
17use super::{Int, NSArray, NSDictionary, NSNotificationName, NSString, NSTimeInterval, UInt};
18
19/// A structure that contains version information about the currently executing operating system, including major, minor, and patch version numbers.
20#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
21pub struct NSOperatingSystemVersion {
22    /// The major release number, such as 10 in version 10.9.3.
23    pub major: isize,
24    /// The minor release number, such as 9 in version 10.9.3.
25    pub minor: isize,
26    /// The update release number, such as 3 in version 10.9.3.
27    pub patch_version: isize,
28}
29
30impl Display for NSOperatingSystemVersion {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        write!(f, "{}.{}.{}", self.major, self.minor, self.patch_version)
33    }
34}
35
36/// Option flags used with `begin_activity_with_options_reason` and `perform_activity_with_options_reason_using_block`.
37#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
38#[repr(u64)]
39pub enum NSActivityOptions {
40    /// A flag to require the screen to stay powered on.
41    IdleDisplaySleepDisabled = 1 << 40,
42    /// A flag to prevent idle sleep.
43    IdleSystemSleepDisabled = 1 << 20,
44    /// A flag to prevent sudden termination.
45    SuddenTerminationDisabled = 1 << 14,
46    /// A flag to prevent automatic termination.
47    AutomaticTerminationDisabled = 1 << 15,
48    /// A flag to indicate the app is performing a user-requested action.
49    UserInitiated = 0x00FFFFFF | Self::IdleSystemSleepDisabled as u64,
50    /// A flag to indicate the app is responding to user interaction.
51    UserInteractive = (Self::UserInitiated as u64 | Self::LatencyCritical as u64),
52    /// A flag to indicate the app has initiated some kind of work, but not as the direct result of user request.
53    Background = 0x000000ff,
54    /// A flag to indicate the activity requires the highest amount of timer and I/O precision available.
55    LatencyCritical = 0xFF00000000,
56    /// A flag to indicate the app is performing a user-requested action, but that the system can sleep on idle.
57    InitiatedAllowingIdleSystemSleep =
58        Self::UserInitiated as u64 & !(Self::IdleSystemSleepDisabled as u64),
59    /// A flag to track the activity with an animation signpost interval.
60    AnimationTrackingEnabled = (1 << 45),
61    /// A flag to track the activity with a signpost interval.
62    TrackingEnabled = (1 << 46),
63}
64
65/// Values used to indicate the system’s thermal state.
66#[derive(Debug)]
67#[repr(i64)]
68pub enum NSProcessInfoThermalState {
69    /// The thermal state is within normal limits.
70    Nominal,
71    /// The thermal state is slightly elevated.
72    Fair,
73    /// The thermal state is high.
74    Serious,
75    /// The thermal state is significantly impacting the performance of the system and the device needs to cool down.
76    Critical,
77}
78
79object! {
80    /// A collection of information about the current process.
81    unsafe pub struct NSProcessInfo;
82}
83
84#[interface_impl(NSObject)]
85impl NSProcessInfo {
86    /* Getting the Process Information Agent
87     */
88
89    /// Returns the process information agent for the process.
90    #[property]
91    pub fn process_info() -> NSProcessInfo {
92        unsafe { NSProcessInfo::from_id(msg_send![Self::m_class(), processInfo]) }
93    }
94
95    /* Getting the Process Information Agent
96     */
97
98    /// Array of strings with the command-line arguments for the process.
99    #[property]
100    pub fn arguments(&self) -> NSArray<NSString> {
101        unsafe { NSArray::from_id(msg_send![self.m_self(), arguments]) }
102    }
103
104    /// The variable names (keys) and their values in the environment from which the process was launched.
105    #[property]
106    pub fn environment(&self) -> NSDictionary<NSString, NSString> {
107        unsafe { NSDictionary::from_id(msg_send![self.m_self(), environment]) }
108    }
109
110    /// Global unique identifier for the process.
111    #[property]
112    pub fn globally_unique_string(&self) -> NSString {
113        unsafe { NSString::from_id(msg_send![self.m_self(), globallyUniqueString]) }
114    }
115
116    /// A Boolean value that indicates whether the process originated as an iOS app and runs on macOS.
117    #[property]
118    pub fn mac_catalyst_app(&self) -> bool {
119        unsafe { to_bool(msg_send![self.m_self(), isMacCatalystApp]) }
120    }
121
122    /// A Boolean value that indicates whether the process is an iPhone or iPad app running on a Mac.
123    #[property]
124    pub fn ios_app_on_mac(&self) -> bool {
125        unsafe { to_bool(msg_send![self.m_self(), isiOSAppOnMac]) }
126    }
127
128    /// The identifier of the process (often called process ID).
129    #[property]
130    pub fn process_identifier(&self) -> Int {
131        unsafe { msg_send![self.m_self(), processIdentifier] }
132    }
133
134    /// The name of the process.
135    #[property]
136    pub fn process_name(&self) -> NSString {
137        unsafe { NSString::from_id(msg_send![self.m_self(), processName]) }
138    }
139
140    /// Sets the name of the process
141    ///
142    /// # Warning
143    ///
144    /// User defaults and other aspects of the environment might depend on the process name, so be very careful if you change it. Setting the process name in this manner is not thread safe.
145
146    #[property]
147    pub fn set_process_name(&mut self, name: NSString) {
148        unsafe { msg_send![self.m_self(), setProcessName: name] }
149    }
150
151    /* Accessing User Information
152     */
153
154    /// Returns the account name of the current user.
155    #[property]
156    pub fn user_name(&self) -> NSString {
157        unsafe { NSString::from_id(msg_send![self.m_self(), userName]) }
158    }
159
160    /// Returns the full name of the current user.
161    #[property]
162    pub fn full_user_name(&self) -> NSString {
163        unsafe { NSString::from_id(msg_send![self.m_self(), fullUserName]) }
164    }
165
166    /* Sudden Application Termination
167     */
168
169    /// Disables the application for quickly killing using sudden termination.
170    #[method]
171    pub fn disable_sudden_termination(&mut self) {
172        unsafe { msg_send![self.m_self(), disableSuddenTermination] }
173    }
174
175    /// Enables the application for quick killing using sudden termination.
176    #[method]
177    pub fn enable_sudden_termination(&mut self) {
178        unsafe { msg_send![self.m_self(), enableSuddenTermination] }
179    }
180
181    /* Controlling Automatic Termination
182     */
183
184    /// Disables automatic termination for the application.
185    #[method]
186    pub fn disable_automatic_termination(&mut self, reason: &NSString) {
187        unsafe { msg_send![self.m_self(), disableAutomaticTermination: reason.m_self()] }
188    }
189
190    /// Enables automatic termination for the application.
191    #[method]
192    pub fn enable_automatic_termination(&mut self, reason: &NSString) {
193        unsafe { msg_send![self.m_self(), enableAutomaticTermination: reason.m_self()] }
194    }
195
196    /// A Boolean value indicating whether the app supports automatic termination.
197    #[property]
198    pub fn automatic_termination_support_enabled(&self) -> bool {
199        unsafe { to_bool(msg_send![self.m_self(), automaticTerminationSupportEnabled]) }
200    }
201
202    /* Getting Host Information
203     */
204
205    /// The name of the host computer on which the process is executing.
206    #[property]
207    pub fn host_name(&self) -> NSString {
208        unsafe { NSString::from_id(msg_send![self.m_self(), hostName]) }
209    }
210
211    /// A string containing the version of the operating system on which the process is executing.
212    #[property]
213    pub fn operating_system_version_string(&self) -> NSString {
214        unsafe { NSString::from_id(msg_send![self.m_self(), operatingSystemVersionString]) }
215    }
216
217    /// The version of the operating system on which the process is executing.
218    #[property]
219    pub fn operating_system_version(&self) -> NSOperatingSystemVersion {
220        unsafe { msg_send![self.m_self(), operatingSystemVersion] }
221    }
222
223    /// Returns a Boolean value indicating whether the version of the operating system on which the process is executing is the same or later than the given version.
224    #[method]
225    pub fn is_operating_system_at_least_version(&self, version: NSOperatingSystemVersion) -> bool {
226        unsafe {
227            to_bool(msg_send![
228                self.m_self(),
229                isOperatingSystemAtLeastVersion: version
230            ])
231        }
232    }
233
234    /// Returns a constant to indicate the operating system on which the process is executing.
235    #[deprecated = "Use `operating_system_version` or `is_operating_system_at_least_version` instead"]
236    #[method]
237    pub fn operating_system(&self) -> UInt {
238        unsafe { msg_send![self.m_self(), operatingSystem] }
239    }
240
241    /// Returns a string containing the name of the operating system on which the process is executing.
242    #[method]
243    #[deprecated = "Use `operating_system_version` or `is_operating_system_at_least_version` instead"]
244    pub fn operating_system_name(&self) -> NSString {
245        unsafe { NSString::from_id(msg_send![self.m_self(), operatingSystemName]) }
246    }
247
248    /* Getting Computer Information */
249
250    /// The number of processing cores available on the computer.
251    #[property]
252    pub fn processor_count(&self) -> UInt {
253        unsafe { msg_send![self.m_self(), processorCount] }
254    }
255
256    /// The number of active processing cores available on the computer.
257    #[property]
258    pub fn active_processor_count(&self) -> UInt {
259        unsafe { msg_send![self.m_self(), activeProcessorCount] }
260    }
261
262    /// The amount of physical memory on the computer in bytes.
263    #[property]
264    pub fn physical_memory(&self) -> c_ulonglong {
265        unsafe { msg_send![self.m_self(), physicalMemory] }
266    }
267
268    /// The amount of time the system has been awake since the last time it was restarted.
269    #[property]
270    pub fn system_uptime(&self) -> NSTimeInterval {
271        unsafe { msg_send![self.m_self(), systemUptime] }
272    }
273
274    /* Managing Activities
275     */
276
277    /// Begin an activity using the given options and reason.
278    #[method]
279    pub fn begin_activity_with_options_reason(
280        &self,
281        options: NSActivityOptions,
282        reason: &NSString,
283    ) -> id {
284        unsafe {
285            msg_send![self.m_self(), beginActivityWithOptions: options reason: reason.m_self()]
286        }
287    }
288
289    /// Ends the given activity.
290    #[method]
291    pub fn end_activity(&self, activity: id) {
292        unsafe { msg_send![self.m_self(), endActivity: activity] }
293    }
294
295    /// Synchronously perform an activity defined by a given block using the given options.
296    #[method]
297    pub fn perform_activity_with_options_reason_using_block<F>(
298        &self,
299        activity: id,
300        reason: &NSString,
301        block: F,
302    ) where
303        F: IntoConcreteBlock<(), Ret = ()> + 'static,
304    {
305        let block = ConcreteBlock::new(block);
306        let block = block.copy();
307
308        unsafe {
309            msg_send![self.m_self(), performActivityWithOptions: activity reason: reason.m_self() usingBlock: block]
310        }
311    }
312
313    /// Performs the specified block asynchronously and notifies you if the process is about to be suspended.
314    #[method]
315    pub fn perform_expiring_activity_with_reason_using_block<F>(&self, reason: &NSString, block: F)
316    where
317        F: IntoConcreteBlock<(bool,), Ret = ()> + 'static,
318    {
319        let block = ConcreteBlock::new(block);
320        let block = block.copy();
321
322        unsafe {
323            msg_send![self.m_self(), performExpiringActivityWithReason: reason.m_self() usingBlock: block]
324        }
325    }
326
327    /*  Getting the Thermal State */
328
329    /// The current thermal state of the system.
330    #[property]
331    pub fn thermal_state(&self) -> NSProcessInfoThermalState {
332        unsafe { msg_send![self.m_self(), thermalState] }
333    }
334
335    /* Determining Whether Low Power Mode is Enabled
336     */
337
338    /// A Boolean value that indicates the current state of Low Power Mode.
339    #[property]
340    pub fn low_power_mode_enabled(&self) -> bool {
341        unsafe { msg_send![self.m_self(), isLowPowerModeEnabled] }
342    }
343}
344
345extern "C" {
346    /// Posts when the thermal state of the system changes.
347    pub static NSProcessInfoThermalStateDidChangeNotification: NSNotificationName;
348
349    /// Posts when the power state of a device changes.
350    pub static NSProcessInfoPowerStateDidChangeNotification: NSNotificationName;
351}