android_activity/
config.rs

1use core::fmt;
2use std::sync::{Arc, RwLock};
3
4use ndk::configuration::{
5    Configuration, Keyboard, KeysHidden, LayoutDir, NavHidden, Navigation, Orientation, ScreenLong,
6    ScreenSize, Touchscreen, UiModeNight, UiModeType,
7};
8
9/// A (cheaply clonable) reference to this application's [`ndk::configuration::Configuration`]
10///
11/// This provides a thread-safe way to access the latest configuration state for
12/// an application without deeply copying the large [`ndk::configuration::Configuration`] struct.
13///
14/// If the application is notified of configuration changes then those changes
15/// will become visible via pre-existing configuration references.
16#[derive(Clone)]
17pub struct ConfigurationRef {
18    config: Arc<RwLock<Configuration>>,
19}
20impl PartialEq for ConfigurationRef {
21    fn eq(&self, other: &Self) -> bool {
22        if Arc::ptr_eq(&self.config, &other.config) {
23            true
24        } else {
25            let other_guard = other.config.read().unwrap();
26            self.config.read().unwrap().eq(&*other_guard)
27        }
28    }
29}
30impl Eq for ConfigurationRef {}
31unsafe impl Send for ConfigurationRef {}
32unsafe impl Sync for ConfigurationRef {}
33
34impl fmt::Debug for ConfigurationRef {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        self.config.read().unwrap().fmt(f)
37    }
38}
39
40impl ConfigurationRef {
41    pub(crate) fn new(config: Configuration) -> Self {
42        Self {
43            config: Arc::new(RwLock::new(config)),
44        }
45    }
46
47    pub(crate) fn replace(&self, src: Configuration) {
48        self.config.write().unwrap().copy(&src);
49    }
50
51    // Returns a deep copy of the full application configuration
52    pub fn copy(&self) -> Configuration {
53        let mut dest = Configuration::new();
54        dest.copy(&self.config.read().unwrap());
55        dest
56    }
57    /// Returns the country code, as a [`String`] of two characters, if set
58    pub fn country(&self) -> Option<String> {
59        self.config.read().unwrap().country()
60    }
61
62    /// Returns the screen density in dpi.
63    ///
64    /// On some devices it can return values outside of the density enum.
65    pub fn density(&self) -> Option<u32> {
66        self.config.read().unwrap().density()
67    }
68
69    /// Returns the keyboard type.
70    pub fn keyboard(&self) -> Keyboard {
71        self.config.read().unwrap().keyboard()
72    }
73
74    /// Returns keyboard visibility/availability.
75    pub fn keys_hidden(&self) -> KeysHidden {
76        self.config.read().unwrap().keys_hidden()
77    }
78
79    /// Returns the language, as a `String` of two characters, if a language is set
80    pub fn language(&self) -> Option<String> {
81        self.config.read().unwrap().language()
82    }
83
84    /// Returns the layout direction
85    pub fn layout_direction(&self) -> LayoutDir {
86        self.config.read().unwrap().layout_direction()
87    }
88
89    /// Returns the mobile country code.
90    pub fn mcc(&self) -> i32 {
91        self.config.read().unwrap().mcc()
92    }
93
94    /// Returns the mobile network code, if one is defined
95    pub fn mnc(&self) -> Option<i32> {
96        self.config.read().unwrap().mnc()
97    }
98
99    pub fn nav_hidden(&self) -> NavHidden {
100        self.config.read().unwrap().nav_hidden()
101    }
102
103    pub fn navigation(&self) -> Navigation {
104        self.config.read().unwrap().navigation()
105    }
106
107    pub fn orientation(&self) -> Orientation {
108        self.config.read().unwrap().orientation()
109    }
110
111    pub fn screen_height_dp(&self) -> Option<i32> {
112        self.config.read().unwrap().screen_height_dp()
113    }
114
115    pub fn screen_width_dp(&self) -> Option<i32> {
116        self.config.read().unwrap().screen_width_dp()
117    }
118
119    pub fn screen_long(&self) -> ScreenLong {
120        self.config.read().unwrap().screen_long()
121    }
122
123    #[cfg(feature = "api-level-30")]
124    pub fn screen_round(&self) -> ScreenRound {
125        self.config.read().unwrap().screen_round()
126    }
127
128    pub fn screen_size(&self) -> ScreenSize {
129        self.config.read().unwrap().screen_size()
130    }
131
132    pub fn sdk_version(&self) -> i32 {
133        self.config.read().unwrap().sdk_version()
134    }
135
136    pub fn smallest_screen_width_dp(&self) -> Option<i32> {
137        self.config.read().unwrap().smallest_screen_width_dp()
138    }
139
140    pub fn touchscreen(&self) -> Touchscreen {
141        self.config.read().unwrap().touchscreen()
142    }
143
144    pub fn ui_mode_night(&self) -> UiModeNight {
145        self.config.read().unwrap().ui_mode_night()
146    }
147
148    pub fn ui_mode_type(&self) -> UiModeType {
149        self.config.read().unwrap().ui_mode_type()
150    }
151}