1 //! Bindings for `AConfiguration`. 2 //! 3 //! See also the [NDK docs](https://developer.android.com/ndk/reference/group/configuration) for 4 //! `AConfiguration`, as well as the [docs for providing 5 //! resources](https://developer.android.com/guide/topics/resources/providing-resources.html), 6 //! which explain many of the configuration values. The [`android.content.res.Configuration` 7 //! javadoc](https://developer.android.com/reference/android/content/res/Configuration.html) may 8 //! also have useful information. 9 10 use crate::asset::AssetManager; 11 use num_enum::{IntoPrimitive, TryFromPrimitive}; 12 use std::convert::TryInto; 13 use std::fmt; 14 use std::ptr::NonNull; 15 16 /// A native `AConfiguration *`. 17 /// 18 /// This stores information about configuration. See [the NDK 19 /// docs](https://developer.android.com/ndk/reference/group/configuration) 20 pub struct Configuration { 21 ptr: NonNull<ffi::AConfiguration>, 22 } 23 24 unsafe impl Send for Configuration {} 25 unsafe impl Sync for Configuration {} 26 27 impl Drop for Configuration { drop(&mut self)28 fn drop(&mut self) { 29 unsafe { ffi::AConfiguration_delete(self.ptr.as_ptr()) } 30 } 31 } 32 33 impl Clone for Configuration { clone(&self) -> Self34 fn clone(&self) -> Self { 35 let mut new = Self::new(); 36 new.copy(self); 37 new 38 } 39 } 40 41 impl PartialEq for Configuration { eq(&self, other: &Self) -> bool42 fn eq(&self, other: &Self) -> bool { 43 self.diff(other).0 == 0 44 } 45 } 46 impl Eq for Configuration {} 47 48 impl fmt::Debug for Configuration { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result49 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 50 f.debug_struct("Configuration") 51 .field("mcc", &self.mcc()) 52 .field("mnc", &self.mnc()) 53 .field("lang", &self.language()) 54 .field("country", &self.country()) 55 .field("orientation", &self.orientation()) 56 .field("touchscreen", &self.touchscreen()) 57 .field("density", &self.density()) 58 .field("keyboard", &self.keyboard()) 59 .field("navigation", &self.navigation()) 60 .field("keys_hidden", &self.keys_hidden()) 61 .field("nav_hidden", &self.nav_hidden()) 62 .field("sdk_version", &self.sdk_version()) 63 .field("screen_size", &self.screen_size()) 64 .field("screen_long", &self.screen_long()) 65 .field("ui_mode_type", &self.ui_mode_type()) 66 .field("ui_mode_night", &self.ui_mode_night()) 67 .finish() 68 } 69 } 70 71 impl Configuration { 72 /// Construct a `Configuration` from a pointer. 73 /// 74 /// By calling this function, you assert that it is a valid pointer to a native 75 /// `AConfiguration`, and give ownership of it to the `Configuration` instance. from_ptr(ptr: NonNull<ffi::AConfiguration>) -> Self76 pub unsafe fn from_ptr(ptr: NonNull<ffi::AConfiguration>) -> Self { 77 Self { ptr } 78 } 79 80 /// Create a new `Configuration`, with the same contents as the `AConfiguration` referenced by 81 /// the pointer. 82 /// 83 /// This is useful if you have a pointer, but not ownership of it. clone_from_ptr(ptr: NonNull<ffi::AConfiguration>) -> Self84 pub unsafe fn clone_from_ptr(ptr: NonNull<ffi::AConfiguration>) -> Self { 85 let conf = Self::new(); 86 ffi::AConfiguration_copy(conf.ptr.as_ptr(), ptr.as_ptr()); 87 conf 88 } 89 90 /// The pointer to the native `AConfiguration`. Keep in mind that the `Configuration` object 91 /// still has ownership, and will free it when dropped. ptr(&self) -> NonNull<ffi::AConfiguration>92 pub fn ptr(&self) -> NonNull<ffi::AConfiguration> { 93 self.ptr 94 } 95 from_asset_manager(am: &AssetManager) -> Self96 pub fn from_asset_manager(am: &AssetManager) -> Self { 97 let config = Self::new(); 98 unsafe { 99 ffi::AConfiguration_fromAssetManager(config.ptr().as_mut(), am.ptr().as_mut()); 100 } 101 config 102 } 103 104 /// Create a new `Configuration`, with none of the values set. new() -> Self105 pub fn new() -> Self { 106 unsafe { 107 Self { 108 ptr: NonNull::new(ffi::AConfiguration_new()).unwrap(), 109 } 110 } 111 } 112 113 /// `dest.copy(&src)` copies the contents of `src` to `dest` copy(&mut self, other: &Self)114 pub fn copy(&mut self, other: &Self) { 115 unsafe { ffi::AConfiguration_copy(self.ptr.as_ptr(), other.ptr.as_ptr()) } 116 } 117 118 /// Information about what fields differ between the two configurations diff(&self, other: &Self) -> DiffResult119 pub fn diff(&self, other: &Self) -> DiffResult { 120 unsafe { 121 DiffResult(ffi::AConfiguration_diff(self.ptr.as_ptr(), other.ptr.as_ptr()) as u32) 122 } 123 } 124 125 /// Returns false if anything in `self` conflicts with `requested` matches(&self, requested: &Self) -> bool126 pub fn matches(&self, requested: &Self) -> bool { 127 unsafe { ffi::AConfiguration_match(self.ptr.as_ptr(), requested.ptr.as_ptr()) != 0 } 128 } 129 130 /// Returns the country code. It will always be two letters. country(&self) -> String131 pub fn country(&self) -> String { 132 let mut result = " ".to_owned(); 133 unsafe { 134 ffi::AConfiguration_getCountry(self.ptr.as_ptr(), result.as_mut_ptr() as *mut _); 135 } 136 result 137 } 138 139 /// Returns the screen density in dpi. 140 /// 141 /// On some devices it can return values outside of the density enum. density(&self) -> Option<u32>142 pub fn density(&self) -> Option<u32> { 143 let density = unsafe { ffi::AConfiguration_getDensity(self.ptr.as_ptr()) as u32 }; 144 match density { 145 ffi::ACONFIGURATION_DENSITY_DEFAULT => Some(160), 146 ffi::ACONFIGURATION_DENSITY_ANY => None, 147 ffi::ACONFIGURATION_DENSITY_NONE => None, 148 density => Some(density), 149 } 150 } 151 152 /// Returns the keyboard type. keyboard(&self) -> Keyboard153 pub fn keyboard(&self) -> Keyboard { 154 unsafe { 155 (ffi::AConfiguration_getKeyboard(self.ptr.as_ptr()) as u32) 156 .try_into() 157 .unwrap() 158 } 159 } 160 161 /// Returns keyboard visibility/availability. keys_hidden(&self) -> KeysHidden162 pub fn keys_hidden(&self) -> KeysHidden { 163 unsafe { 164 (ffi::AConfiguration_getKeysHidden(self.ptr.as_ptr()) as u32) 165 .try_into() 166 .unwrap() 167 } 168 } 169 170 /// Returns the language, as a `String` of two characters, if a language is set language(&self) -> Option<String>171 pub fn language(&self) -> Option<String> { 172 let mut chars = [0u8; 2]; 173 unsafe { 174 ffi::AConfiguration_getLanguage(self.ptr.as_ptr(), chars[..].as_mut_ptr() as *mut _); 175 } 176 if chars[0] == 0 { 177 None 178 } else { 179 Some(std::str::from_utf8(&chars[..]).unwrap().to_owned()) 180 } 181 } 182 183 /// Returns the layout direction layout_direction(&self) -> LayoutDir184 pub fn layout_direction(&self) -> LayoutDir { 185 unsafe { 186 (ffi::AConfiguration_getLayoutDirection(self.ptr.as_ptr()) as u32) 187 .try_into() 188 .unwrap() 189 } 190 } 191 192 /// Returns the mobile country code. mcc(&self) -> i32193 pub fn mcc(&self) -> i32 { 194 unsafe { ffi::AConfiguration_getMcc(self.ptr.as_ptr()) } 195 } 196 197 /// Returns the mobile network code, if one is defined mnc(&self) -> Option<i32>198 pub fn mnc(&self) -> Option<i32> { 199 unsafe { 200 match ffi::AConfiguration_getMnc(self.ptr.as_ptr()) { 201 0 => None, 202 x if x == ffi::ACONFIGURATION_MNC_ZERO as i32 => Some(0), 203 x => Some(x), 204 } 205 } 206 } 207 nav_hidden(&self) -> NavHidden208 pub fn nav_hidden(&self) -> NavHidden { 209 unsafe { 210 (ffi::AConfiguration_getNavHidden(self.ptr.as_ptr()) as u32) 211 .try_into() 212 .unwrap() 213 } 214 } 215 navigation(&self) -> Navigation216 pub fn navigation(&self) -> Navigation { 217 unsafe { 218 (ffi::AConfiguration_getNavigation(self.ptr.as_ptr()) as u32) 219 .try_into() 220 .unwrap() 221 } 222 } 223 orientation(&self) -> Orientation224 pub fn orientation(&self) -> Orientation { 225 unsafe { 226 (ffi::AConfiguration_getOrientation(self.ptr.as_ptr()) as u32) 227 .try_into() 228 .unwrap() 229 } 230 } 231 screen_height_dp(&self) -> Option<i32>232 pub fn screen_height_dp(&self) -> Option<i32> { 233 unsafe { 234 let height = ffi::AConfiguration_getScreenHeightDp(self.ptr.as_ptr()); 235 if height == ffi::ACONFIGURATION_SCREEN_HEIGHT_DP_ANY as i32 { 236 None 237 } else { 238 Some(height) 239 } 240 } 241 } 242 screen_width_dp(&self) -> Option<i32>243 pub fn screen_width_dp(&self) -> Option<i32> { 244 unsafe { 245 let width = ffi::AConfiguration_getScreenWidthDp(self.ptr.as_ptr()); 246 if width == ffi::ACONFIGURATION_SCREEN_WIDTH_DP_ANY as i32 { 247 None 248 } else { 249 Some(width) 250 } 251 } 252 } 253 screen_long(&self) -> ScreenLong254 pub fn screen_long(&self) -> ScreenLong { 255 unsafe { 256 (ffi::AConfiguration_getScreenLong(self.ptr.as_ptr()) as u32) 257 .try_into() 258 .unwrap() 259 } 260 } 261 screen_round(&self) -> ScreenRound262 pub fn screen_round(&self) -> ScreenRound { 263 unsafe { 264 (ffi::AConfiguration_getScreenRound(self.ptr.as_ptr()) as u32) 265 .try_into() 266 .unwrap() 267 } 268 } 269 screen_size(&self) -> ScreenSize270 pub fn screen_size(&self) -> ScreenSize { 271 unsafe { 272 (ffi::AConfiguration_getScreenSize(self.ptr.as_ptr()) as u32) 273 .try_into() 274 .unwrap() 275 } 276 } 277 sdk_version(&self) -> i32278 pub fn sdk_version(&self) -> i32 { 279 unsafe { ffi::AConfiguration_getSdkVersion(self.ptr.as_ptr()) } 280 } 281 smallest_screen_width_dp(&self) -> Option<i32>282 pub fn smallest_screen_width_dp(&self) -> Option<i32> { 283 unsafe { 284 let width = ffi::AConfiguration_getSmallestScreenWidthDp(self.ptr.as_ptr()); 285 if width == ffi::ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY as i32 { 286 None 287 } else { 288 Some(width) 289 } 290 } 291 } 292 touchscreen(&self) -> Touchscreen293 pub fn touchscreen(&self) -> Touchscreen { 294 unsafe { 295 (ffi::AConfiguration_getTouchscreen(self.ptr.as_ptr()) as u32) 296 .try_into() 297 .unwrap() 298 } 299 } 300 ui_mode_night(&self) -> UiModeNight301 pub fn ui_mode_night(&self) -> UiModeNight { 302 unsafe { 303 (ffi::AConfiguration_getUiModeNight(self.ptr.as_ptr()) as u32) 304 .try_into() 305 .unwrap() 306 } 307 } 308 ui_mode_type(&self) -> UiModeType309 pub fn ui_mode_type(&self) -> UiModeType { 310 unsafe { 311 (ffi::AConfiguration_getUiModeType(self.ptr.as_ptr()) as u32) 312 .try_into() 313 .unwrap() 314 } 315 } 316 } 317 318 /// A bitfield representing the differences between two `Configuration`s 319 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 320 pub struct DiffResult(pub u32); 321 322 impl DiffResult { mcc(self) -> bool323 pub fn mcc(self) -> bool { 324 self.0 & ffi::ACONFIGURATION_MCC != 0 325 } mnc(self) -> bool326 pub fn mnc(self) -> bool { 327 self.0 & ffi::ACONFIGURATION_MNC != 0 328 } locale(self) -> bool329 pub fn locale(self) -> bool { 330 self.0 & ffi::ACONFIGURATION_LOCALE != 0 331 } touchscreen(self) -> bool332 pub fn touchscreen(self) -> bool { 333 self.0 & ffi::ACONFIGURATION_TOUCHSCREEN != 0 334 } keyboard(self) -> bool335 pub fn keyboard(self) -> bool { 336 self.0 & ffi::ACONFIGURATION_KEYBOARD != 0 337 } keyboard_hidden(self) -> bool338 pub fn keyboard_hidden(self) -> bool { 339 self.0 & ffi::ACONFIGURATION_KEYBOARD_HIDDEN != 0 340 } navigation(self) -> bool341 pub fn navigation(self) -> bool { 342 self.0 & ffi::ACONFIGURATION_NAVIGATION != 0 343 } orientation(self) -> bool344 pub fn orientation(self) -> bool { 345 self.0 & ffi::ACONFIGURATION_ORIENTATION != 0 346 } density(self) -> bool347 pub fn density(self) -> bool { 348 self.0 & ffi::ACONFIGURATION_DENSITY != 0 349 } screen_size(self) -> bool350 pub fn screen_size(self) -> bool { 351 self.0 & ffi::ACONFIGURATION_SCREEN_SIZE != 0 352 } version(self) -> bool353 pub fn version(self) -> bool { 354 self.0 & ffi::ACONFIGURATION_VERSION != 0 355 } screen_layout(self) -> bool356 pub fn screen_layout(self) -> bool { 357 self.0 & ffi::ACONFIGURATION_SCREEN_LAYOUT != 0 358 } ui_mode(self) -> bool359 pub fn ui_mode(self) -> bool { 360 self.0 & ffi::ACONFIGURATION_UI_MODE != 0 361 } smallest_screen_size(self) -> bool362 pub fn smallest_screen_size(self) -> bool { 363 self.0 & ffi::ACONFIGURATION_SMALLEST_SCREEN_SIZE != 0 364 } layout_dir(self) -> bool365 pub fn layout_dir(self) -> bool { 366 self.0 & ffi::ACONFIGURATION_LAYOUTDIR != 0 367 } screen_round(self) -> bool368 pub fn screen_round(self) -> bool { 369 self.0 & ffi::ACONFIGURATION_SCREEN_ROUND != 0 370 } color_mode(self) -> bool371 pub fn color_mode(self) -> bool { 372 self.0 & ffi::ACONFIGURATION_COLOR_MODE != 0 373 } 374 } 375 376 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 377 #[repr(u32)] 378 pub enum Orientation { 379 Any = ffi::ACONFIGURATION_ORIENTATION_ANY, 380 Port = ffi::ACONFIGURATION_ORIENTATION_PORT, 381 Land = ffi::ACONFIGURATION_ORIENTATION_LAND, 382 Square = ffi::ACONFIGURATION_ORIENTATION_SQUARE, 383 } 384 385 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 386 #[repr(u32)] 387 pub enum Touchscreen { 388 Any = ffi::ACONFIGURATION_TOUCHSCREEN_ANY, 389 NoTouch = ffi::ACONFIGURATION_TOUCHSCREEN_NOTOUCH, 390 Stylus = ffi::ACONFIGURATION_TOUCHSCREEN_STYLUS, 391 Finger = ffi::ACONFIGURATION_TOUCHSCREEN_FINGER, 392 } 393 394 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 395 #[repr(u32)] 396 pub enum Density { 397 Default = ffi::ACONFIGURATION_DENSITY_DEFAULT, 398 Low = ffi::ACONFIGURATION_DENSITY_LOW, 399 Medium = ffi::ACONFIGURATION_DENSITY_MEDIUM, 400 TV = ffi::ACONFIGURATION_DENSITY_TV, 401 High = ffi::ACONFIGURATION_DENSITY_HIGH, 402 XHigh = ffi::ACONFIGURATION_DENSITY_XHIGH, 403 XXHigh = ffi::ACONFIGURATION_DENSITY_XXHIGH, 404 XXXHigh = ffi::ACONFIGURATION_DENSITY_XXXHIGH, 405 Any = ffi::ACONFIGURATION_DENSITY_ANY, 406 None = ffi::ACONFIGURATION_DENSITY_NONE, 407 } 408 409 impl Density { 410 /// The DPI associated with the density class. 411 /// See [the Android screen density 412 /// docs](https://developer.android.com/training/multiscreen/screendensities#TaskProvideAltBmp) 413 /// 414 /// There are some `Density` values that have no associated DPI; these values return `None`. dpi(self) -> Option<u32>415 pub fn dpi(self) -> Option<u32> { 416 match self { 417 Self::Default => Some(160), // Or should it be None? 418 Self::Low => Some(120), 419 Self::Medium => Some(160), 420 Self::High => Some(240), 421 Self::XHigh => Some(320), 422 Self::XXHigh => Some(480), 423 Self::XXXHigh => Some(640), 424 Self::TV => Some(213), 425 Self::Any => None, 426 Self::None => None, 427 } 428 } 429 430 /// The Hi-DPI factor associated with the density class. This is the factor by which an 431 /// image/resource should be scaled to match its size across devices. The baseline is a 160dpi 432 /// screen (i.e., Hi-DPI factor = DPI / 160). 433 /// See [the Android screen density 434 /// docs](https://developer.android.com/training/multiscreen/screendensities#TaskProvideAltBmp) 435 /// 436 /// There are some `Density` values that have no associated DPI; these values return `None`. approx_hidpi_factor(self) -> Option<f64>437 pub fn approx_hidpi_factor(self) -> Option<f64> { 438 match self { 439 Self::Default => Some(1.), // Or should it be None? 440 Self::Low => Some(0.75), 441 Self::Medium => Some(1.), 442 Self::High => Some(1.5), 443 Self::XHigh => Some(2.), 444 Self::XXHigh => Some(3.), 445 Self::XXXHigh => Some(4.), 446 Self::TV => Some(4. / 3.), 447 Self::Any => None, 448 Self::None => None, 449 } 450 } 451 } 452 453 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 454 #[repr(u32)] 455 pub enum Keyboard { 456 Any = ffi::ACONFIGURATION_KEYBOARD_ANY, 457 NoKeys = ffi::ACONFIGURATION_KEYBOARD_NOKEYS, 458 Qwerty = ffi::ACONFIGURATION_KEYBOARD_QWERTY, 459 TwelveKey = ffi::ACONFIGURATION_KEYBOARD_12KEY, 460 } 461 462 // FIXME is it a bitmask? 463 // FIXME are they all bitmasks? 464 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 465 #[repr(u32)] 466 pub enum Navigation { 467 Any = ffi::ACONFIGURATION_NAVIGATION_ANY, 468 NoNav = ffi::ACONFIGURATION_NAVIGATION_NONAV, 469 DPad = ffi::ACONFIGURATION_NAVIGATION_DPAD, 470 Trackball = ffi::ACONFIGURATION_NAVIGATION_TRACKBALL, 471 Wheel = ffi::ACONFIGURATION_NAVIGATION_WHEEL, 472 } 473 474 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 475 #[repr(u32)] 476 pub enum KeysHidden { 477 Any = ffi::ACONFIGURATION_KEYSHIDDEN_ANY, 478 No = ffi::ACONFIGURATION_KEYSHIDDEN_NO, 479 Yes = ffi::ACONFIGURATION_KEYSHIDDEN_YES, 480 Soft = ffi::ACONFIGURATION_KEYSHIDDEN_SOFT, 481 } 482 483 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 484 #[repr(u32)] 485 pub enum NavHidden { 486 Any = ffi::ACONFIGURATION_NAVHIDDEN_ANY, 487 No = ffi::ACONFIGURATION_NAVHIDDEN_NO, 488 Yes = ffi::ACONFIGURATION_NAVHIDDEN_YES, 489 } 490 491 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 492 #[repr(u32)] 493 pub enum ScreenSize { 494 Any = ffi::ACONFIGURATION_SCREENSIZE_ANY, 495 Small = ffi::ACONFIGURATION_SCREENSIZE_SMALL, 496 Normal = ffi::ACONFIGURATION_SCREENSIZE_NORMAL, 497 Large = ffi::ACONFIGURATION_SCREENSIZE_LARGE, 498 XLarge = ffi::ACONFIGURATION_SCREENSIZE_XLARGE, 499 } 500 501 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 502 #[repr(u32)] 503 pub enum ScreenLong { 504 Any = ffi::ACONFIGURATION_SCREENLONG_ANY, 505 No = ffi::ACONFIGURATION_SCREENLONG_NO, 506 Yes = ffi::ACONFIGURATION_SCREENLONG_YES, 507 } 508 509 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 510 #[repr(u32)] 511 pub enum ScreenRound { 512 Any = ffi::ACONFIGURATION_SCREENROUND_ANY, 513 No = ffi::ACONFIGURATION_SCREENROUND_NO, 514 Yes = ffi::ACONFIGURATION_SCREENROUND_YES, 515 } 516 517 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 518 #[repr(u32)] 519 pub enum WideColorGamut { 520 Any = ffi::ACONFIGURATION_WIDE_COLOR_GAMUT_ANY, 521 No = ffi::ACONFIGURATION_WIDE_COLOR_GAMUT_NO, 522 Yes = ffi::ACONFIGURATION_WIDE_COLOR_GAMUT_YES, 523 } 524 525 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 526 #[repr(u32)] 527 pub enum HDR { 528 Any = ffi::ACONFIGURATION_HDR_ANY, 529 No = ffi::ACONFIGURATION_HDR_NO, 530 Yes = ffi::ACONFIGURATION_HDR_YES, 531 } 532 533 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 534 #[repr(u32)] 535 pub enum LayoutDir { 536 Any = ffi::ACONFIGURATION_LAYOUTDIR_ANY, 537 Ltr = ffi::ACONFIGURATION_LAYOUTDIR_LTR, 538 Rtl = ffi::ACONFIGURATION_LAYOUTDIR_RTL, 539 } 540 541 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 542 #[repr(u32)] 543 pub enum UiModeType { 544 Any = ffi::ACONFIGURATION_UI_MODE_TYPE_ANY, 545 Normal = ffi::ACONFIGURATION_UI_MODE_TYPE_NORMAL, 546 Desk = ffi::ACONFIGURATION_UI_MODE_TYPE_DESK, 547 Car = ffi::ACONFIGURATION_UI_MODE_TYPE_CAR, 548 Television = ffi::ACONFIGURATION_UI_MODE_TYPE_TELEVISION, 549 Applicance = ffi::ACONFIGURATION_UI_MODE_TYPE_APPLIANCE, 550 Watch = ffi::ACONFIGURATION_UI_MODE_TYPE_WATCH, 551 VrHeadset = ffi::ACONFIGURATION_UI_MODE_TYPE_VR_HEADSET, 552 } 553 554 #[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 555 #[repr(u32)] 556 pub enum UiModeNight { 557 Any = ffi::ACONFIGURATION_UI_MODE_NIGHT_ANY, 558 No = ffi::ACONFIGURATION_UI_MODE_NIGHT_NO, 559 Yes = ffi::ACONFIGURATION_UI_MODE_NIGHT_YES, 560 } 561