Skip to main content

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 runtime-replacable reference to [`ndk::configuration::Configuration`].
10///
11/// # Warning
12///
13/// The value held by this reference **will change** with every [`super::MainEvent::ConfigChanged`]
14/// event that is raised.  You should **not** [`Clone`] this type to compare it against a
15/// "new" [`super::AndroidApp::config()`] when that event is raised, since both point to the same
16/// internal [`ndk::configuration::Configuration`] and will be identical.
17#[derive(Clone)]
18pub struct ConfigurationRef {
19    config: Arc<RwLock<Configuration>>,
20}
21impl PartialEq for ConfigurationRef {
22    fn eq(&self, other: &Self) -> bool {
23        if Arc::ptr_eq(&self.config, &other.config) {
24            true
25        } else {
26            let other_guard = other.config.read().unwrap();
27            self.config.read().unwrap().eq(&*other_guard)
28        }
29    }
30}
31impl Eq for ConfigurationRef {}
32
33impl fmt::Debug for ConfigurationRef {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        self.config.read().unwrap().fmt(f)
36    }
37}
38
39impl ConfigurationRef {
40    pub(crate) fn new(config: Configuration) -> Self {
41        Self {
42            config: Arc::new(RwLock::new(config)),
43        }
44    }
45
46    pub(crate) fn replace(&self, src: Configuration) {
47        self.config.write().unwrap().copy(&src);
48    }
49
50    // Returns a deep copy of the full application configuration
51    pub fn copy(&self) -> Configuration {
52        let mut dest = Configuration::new();
53        dest.copy(&self.config.read().unwrap());
54        dest
55    }
56    /// Returns the country code, as a [`String`] of two characters, if set
57    pub fn country(&self) -> Option<String> {
58        self.config.read().unwrap().country()
59    }
60
61    /// Returns the screen density in dpi.
62    ///
63    /// On some devices it can return values outside of the density enum.
64    pub fn density(&self) -> Option<u32> {
65        self.config.read().unwrap().density()
66    }
67
68    /// Returns the keyboard type.
69    pub fn keyboard(&self) -> Keyboard {
70        self.config.read().unwrap().keyboard()
71    }
72
73    /// Returns keyboard visibility/availability.
74    pub fn keys_hidden(&self) -> KeysHidden {
75        self.config.read().unwrap().keys_hidden()
76    }
77
78    /// Returns the language, as a `String` of two characters, if a language is set
79    pub fn language(&self) -> Option<String> {
80        self.config.read().unwrap().language()
81    }
82
83    /// Returns the layout direction
84    pub fn layout_direction(&self) -> LayoutDir {
85        self.config.read().unwrap().layout_direction()
86    }
87
88    /// Returns the mobile country code.
89    pub fn mcc(&self) -> i32 {
90        self.config.read().unwrap().mcc()
91    }
92
93    /// Returns the mobile network code, if one is defined
94    pub fn mnc(&self) -> Option<i32> {
95        self.config.read().unwrap().mnc()
96    }
97
98    pub fn nav_hidden(&self) -> NavHidden {
99        self.config.read().unwrap().nav_hidden()
100    }
101
102    pub fn navigation(&self) -> Navigation {
103        self.config.read().unwrap().navigation()
104    }
105
106    pub fn orientation(&self) -> Orientation {
107        self.config.read().unwrap().orientation()
108    }
109
110    pub fn screen_height_dp(&self) -> Option<i32> {
111        self.config.read().unwrap().screen_height_dp()
112    }
113
114    pub fn screen_width_dp(&self) -> Option<i32> {
115        self.config.read().unwrap().screen_width_dp()
116    }
117
118    pub fn screen_long(&self) -> ScreenLong {
119        self.config.read().unwrap().screen_long()
120    }
121
122    #[cfg(feature = "api-level-30")]
123    pub fn screen_round(&self) -> ScreenRound {
124        self.config.read().unwrap().screen_round()
125    }
126
127    pub fn screen_size(&self) -> ScreenSize {
128        self.config.read().unwrap().screen_size()
129    }
130
131    pub fn sdk_version(&self) -> i32 {
132        self.config.read().unwrap().sdk_version()
133    }
134
135    pub fn smallest_screen_width_dp(&self) -> Option<i32> {
136        self.config.read().unwrap().smallest_screen_width_dp()
137    }
138
139    pub fn touchscreen(&self) -> Touchscreen {
140        self.config.read().unwrap().touchscreen()
141    }
142
143    pub fn ui_mode_night(&self) -> UiModeNight {
144        self.config.read().unwrap().ui_mode_night()
145    }
146
147    pub fn ui_mode_type(&self) -> UiModeType {
148        self.config.read().unwrap().ui_mode_type()
149    }
150}