1 /* 2 * Copyright 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //! InputFilter manages all the filtering components that can intercept events, modify the events, 18 //! block events, etc depending on the situation. This will be used support Accessibility features 19 //! like Sticky keys, Slow keys, Bounce keys, etc. 20 21 use binder::{Interface, Strong}; 22 use com_android_server_inputflinger::aidl::com::android::server::inputflinger::{ 23 DeviceInfo::DeviceInfo, 24 IInputFilter::{IInputFilter, IInputFilterCallbacks::IInputFilterCallbacks}, 25 IInputThread::{IInputThread, IInputThreadCallback::IInputThreadCallback}, 26 InputFilterConfiguration::InputFilterConfiguration, 27 KeyEvent::KeyEvent, 28 }; 29 30 use crate::bounce_keys_filter::BounceKeysFilter; 31 use crate::input_filter_thread::InputFilterThread; 32 use crate::slow_keys_filter::SlowKeysFilter; 33 use crate::sticky_keys_filter::StickyKeysFilter; 34 use input::ModifierState; 35 use log::{error, info}; 36 use std::any::Any; 37 use std::collections::HashMap; 38 use std::sync::{Arc, Mutex, RwLock}; 39 40 /// Virtual keyboard device ID 41 pub const VIRTUAL_KEYBOARD_DEVICE_ID: i32 = -1; 42 43 /// Interface for all the sub input filters 44 pub trait Filter { notify_key(&mut self, event: &KeyEvent)45 fn notify_key(&mut self, event: &KeyEvent); notify_devices_changed(&mut self, device_infos: &[DeviceInfo])46 fn notify_devices_changed(&mut self, device_infos: &[DeviceInfo]); destroy(&mut self)47 fn destroy(&mut self); save( &mut self, state: HashMap<&'static str, Box<dyn Any + Send + Sync>>, ) -> HashMap<&'static str, Box<dyn Any + Send + Sync>>48 fn save( 49 &mut self, 50 state: HashMap<&'static str, Box<dyn Any + Send + Sync>>, 51 ) -> HashMap<&'static str, Box<dyn Any + Send + Sync>>; restore(&mut self, state: &HashMap<&'static str, Box<dyn Any + Send + Sync>>)52 fn restore(&mut self, state: &HashMap<&'static str, Box<dyn Any + Send + Sync>>); dump(&mut self, dump_str: String) -> String53 fn dump(&mut self, dump_str: String) -> String; 54 } 55 56 struct InputFilterState { 57 first_filter: Box<dyn Filter + Send + Sync>, 58 enabled: bool, 59 } 60 61 /// The rust implementation of InputFilter 62 pub struct InputFilter { 63 // In order to have multiple immutable references to the callbacks that is thread safe need to 64 // wrap the callbacks in Arc<RwLock<...>> 65 callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>, 66 // Access to mutable references to mutable state (includes access to filters, enabled, etc.) is 67 // guarded by Mutex for thread safety 68 state: Mutex<InputFilterState>, 69 input_filter_thread: InputFilterThread, 70 } 71 72 impl Interface for InputFilter {} 73 74 impl InputFilter { 75 /// Create a new InputFilter instance. new(callbacks: Strong<dyn IInputFilterCallbacks>) -> InputFilter76 pub fn new(callbacks: Strong<dyn IInputFilterCallbacks>) -> InputFilter { 77 let ref_callbacks = Arc::new(RwLock::new(callbacks)); 78 let base_filter = Box::new(BaseFilter::new(ref_callbacks.clone())); 79 Self::create_input_filter(base_filter, ref_callbacks) 80 } 81 82 /// Create test instance of InputFilter create_input_filter( first_filter: Box<dyn Filter + Send + Sync>, callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>, ) -> InputFilter83 fn create_input_filter( 84 first_filter: Box<dyn Filter + Send + Sync>, 85 callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>, 86 ) -> InputFilter { 87 Self { 88 callbacks: callbacks.clone(), 89 state: Mutex::new(InputFilterState { first_filter, enabled: false }), 90 input_filter_thread: InputFilterThread::new(InputFilterThreadCreator::new(callbacks)), 91 } 92 } 93 } 94 95 impl IInputFilter for InputFilter { isEnabled(&self) -> binder::Result<bool>96 fn isEnabled(&self) -> binder::Result<bool> { 97 Result::Ok(self.state.lock().unwrap().enabled) 98 } 99 notifyKey(&self, event: &KeyEvent) -> binder::Result<()>100 fn notifyKey(&self, event: &KeyEvent) -> binder::Result<()> { 101 let first_filter = &mut self.state.lock().unwrap().first_filter; 102 first_filter.notify_key(event); 103 Result::Ok(()) 104 } 105 notifyInputDevicesChanged(&self, device_infos: &[DeviceInfo]) -> binder::Result<()>106 fn notifyInputDevicesChanged(&self, device_infos: &[DeviceInfo]) -> binder::Result<()> { 107 let first_filter = &mut self.state.lock().unwrap().first_filter; 108 first_filter.notify_devices_changed(device_infos); 109 Result::Ok(()) 110 } 111 notifyConfigurationChanged(&self, config: &InputFilterConfiguration) -> binder::Result<()>112 fn notifyConfigurationChanged(&self, config: &InputFilterConfiguration) -> binder::Result<()> { 113 { 114 let mut state = self.state.lock().unwrap(); 115 let saved_state = state.first_filter.save(HashMap::new()); 116 state.first_filter.destroy(); 117 let mut first_filter: Box<dyn Filter + Send + Sync> = 118 Box::new(BaseFilter::new(self.callbacks.clone())); 119 if config.stickyKeysEnabled { 120 first_filter = Box::new(StickyKeysFilter::new( 121 first_filter, 122 ModifierStateListener::new(self.callbacks.clone()), 123 )); 124 state.enabled = true; 125 info!("Sticky keys filter is installed"); 126 } 127 if config.slowKeysThresholdNs > 0 { 128 first_filter = Box::new(SlowKeysFilter::new( 129 first_filter, 130 config.slowKeysThresholdNs, 131 self.input_filter_thread.clone(), 132 )); 133 state.enabled = true; 134 info!( 135 "Slow keys filter is installed, threshold = {:?}ns", 136 config.slowKeysThresholdNs 137 ); 138 } 139 if config.bounceKeysThresholdNs > 0 { 140 first_filter = 141 Box::new(BounceKeysFilter::new(first_filter, config.bounceKeysThresholdNs)); 142 state.enabled = true; 143 info!( 144 "Bounce keys filter is installed, threshold = {:?}ns", 145 config.bounceKeysThresholdNs 146 ); 147 } 148 state.first_filter = first_filter; 149 state.first_filter.restore(&saved_state); 150 } 151 Result::Ok(()) 152 } 153 dumpFilter(&self) -> binder::Result<String>154 fn dumpFilter(&self) -> binder::Result<String> { 155 let first_filter = &mut self.state.lock().unwrap().first_filter; 156 let dump_str = first_filter.dump(String::new()); 157 Result::Ok(dump_str) 158 } 159 } 160 161 struct BaseFilter { 162 callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>, 163 } 164 165 impl BaseFilter { new(callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>) -> BaseFilter166 fn new(callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>) -> BaseFilter { 167 Self { callbacks } 168 } 169 } 170 171 impl Filter for BaseFilter { notify_key(&mut self, event: &KeyEvent)172 fn notify_key(&mut self, event: &KeyEvent) { 173 match self.callbacks.read().unwrap().sendKeyEvent(event) { 174 Ok(_) => (), 175 _ => error!("Failed to send key event back to native C++"), 176 } 177 } 178 notify_devices_changed(&mut self, _device_infos: &[DeviceInfo])179 fn notify_devices_changed(&mut self, _device_infos: &[DeviceInfo]) { 180 // do nothing 181 } 182 destroy(&mut self)183 fn destroy(&mut self) { 184 // do nothing 185 } 186 save( &mut self, state: HashMap<&'static str, Box<dyn Any + Send + Sync>>, ) -> HashMap<&'static str, Box<dyn Any + Send + Sync>>187 fn save( 188 &mut self, 189 state: HashMap<&'static str, Box<dyn Any + Send + Sync>>, 190 ) -> HashMap<&'static str, Box<dyn Any + Send + Sync>> { 191 // do nothing 192 state 193 } 194 restore(&mut self, _state: &HashMap<&'static str, Box<dyn Any + Send + Sync>>)195 fn restore(&mut self, _state: &HashMap<&'static str, Box<dyn Any + Send + Sync>>) { 196 // do nothing 197 } 198 dump(&mut self, dump_str: String) -> String199 fn dump(&mut self, dump_str: String) -> String { 200 // do nothing 201 dump_str 202 } 203 } 204 205 /// This struct wraps around IInputFilterCallbacks restricting access to only 206 /// {@code onModifierStateChanged()} method of the callback. 207 #[derive(Clone)] 208 pub struct ModifierStateListener(Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>); 209 210 impl ModifierStateListener { new(callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>) -> ModifierStateListener211 pub fn new(callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>) -> ModifierStateListener { 212 Self(callbacks) 213 } 214 modifier_state_changed( &self, modifier_state: ModifierState, locked_modifier_state: ModifierState, )215 pub fn modifier_state_changed( 216 &self, 217 modifier_state: ModifierState, 218 locked_modifier_state: ModifierState, 219 ) { 220 let _ = self.0.read().unwrap().onModifierStateChanged( 221 modifier_state.bits() as i32, 222 locked_modifier_state.bits() as i32, 223 ); 224 } 225 } 226 227 /// This struct wraps around IInputFilterCallbacks restricting access to only 228 /// {@code createInputFilterThread()} method of the callback. 229 #[derive(Clone)] 230 pub struct InputFilterThreadCreator(Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>); 231 232 impl InputFilterThreadCreator { new( callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>, ) -> InputFilterThreadCreator233 pub fn new( 234 callbacks: Arc<RwLock<Strong<dyn IInputFilterCallbacks>>>, 235 ) -> InputFilterThreadCreator { 236 Self(callbacks) 237 } 238 create( &self, input_thread_callback: &Strong<dyn IInputThreadCallback>, ) -> Strong<dyn IInputThread>239 pub fn create( 240 &self, 241 input_thread_callback: &Strong<dyn IInputThreadCallback>, 242 ) -> Strong<dyn IInputThread> { 243 self.0.read().unwrap().createInputFilterThread(input_thread_callback).unwrap() 244 } 245 } 246 247 #[cfg(test)] 248 mod tests { 249 use crate::input_filter::{ 250 test_callbacks::TestCallbacks, test_filter::TestFilter, InputFilter, 251 }; 252 use android_hardware_input_common::aidl::android::hardware::input::common::Source::Source; 253 use binder::Strong; 254 use com_android_server_inputflinger::aidl::com::android::server::inputflinger::{ 255 DeviceInfo::DeviceInfo, IInputFilter::IInputFilter, 256 InputFilterConfiguration::InputFilterConfiguration, KeyEvent::KeyEvent, 257 KeyEventAction::KeyEventAction, 258 }; 259 use input::KeyboardType; 260 use std::sync::{Arc, RwLock}; 261 262 #[test] test_not_enabled_with_default_filter()263 fn test_not_enabled_with_default_filter() { 264 let test_callbacks = TestCallbacks::new(); 265 let input_filter = InputFilter::new(Strong::new(Box::new(test_callbacks))); 266 let result = input_filter.isEnabled(); 267 assert!(result.is_ok()); 268 assert!(!result.unwrap()); 269 } 270 271 #[test] test_notify_key_with_no_filters()272 fn test_notify_key_with_no_filters() { 273 let test_callbacks = TestCallbacks::new(); 274 let input_filter = InputFilter::new(Strong::new(Box::new(test_callbacks.clone()))); 275 let event = create_key_event(); 276 assert!(input_filter.notifyKey(&event).is_ok()); 277 assert_eq!(test_callbacks.last_event().unwrap(), event); 278 } 279 280 #[test] test_notify_key_with_filter()281 fn test_notify_key_with_filter() { 282 let test_filter = TestFilter::new(); 283 let test_callbacks = TestCallbacks::new(); 284 let input_filter = InputFilter::create_input_filter( 285 Box::new(test_filter.clone()), 286 Arc::new(RwLock::new(Strong::new(Box::new(test_callbacks)))), 287 ); 288 let event = create_key_event(); 289 assert!(input_filter.notifyKey(&event).is_ok()); 290 assert_eq!(test_filter.last_event().unwrap(), event); 291 } 292 293 #[test] test_notify_devices_changed()294 fn test_notify_devices_changed() { 295 let test_filter = TestFilter::new(); 296 let test_callbacks = TestCallbacks::new(); 297 let input_filter = InputFilter::create_input_filter( 298 Box::new(test_filter.clone()), 299 Arc::new(RwLock::new(Strong::new(Box::new(test_callbacks)))), 300 ); 301 assert!(input_filter 302 .notifyInputDevicesChanged(&[DeviceInfo { 303 deviceId: 0, 304 external: true, 305 keyboardType: KeyboardType::None as i32 306 }]) 307 .is_ok()); 308 assert!(test_filter.is_device_changed_called()); 309 } 310 311 #[test] test_notify_configuration_changed_enabled_bounce_keys()312 fn test_notify_configuration_changed_enabled_bounce_keys() { 313 let test_callbacks = TestCallbacks::new(); 314 let input_filter = InputFilter::new(Strong::new(Box::new(test_callbacks))); 315 let result = input_filter.notifyConfigurationChanged(&InputFilterConfiguration { 316 bounceKeysThresholdNs: 100, 317 ..Default::default() 318 }); 319 assert!(result.is_ok()); 320 let result = input_filter.isEnabled(); 321 assert!(result.is_ok()); 322 assert!(result.unwrap()); 323 } 324 325 #[test] test_notify_configuration_changed_enabled_sticky_keys()326 fn test_notify_configuration_changed_enabled_sticky_keys() { 327 let test_callbacks = TestCallbacks::new(); 328 let input_filter = InputFilter::new(Strong::new(Box::new(test_callbacks))); 329 let result = input_filter.notifyConfigurationChanged(&InputFilterConfiguration { 330 stickyKeysEnabled: true, 331 ..Default::default() 332 }); 333 assert!(result.is_ok()); 334 let result = input_filter.isEnabled(); 335 assert!(result.is_ok()); 336 assert!(result.unwrap()); 337 } 338 339 #[test] test_notify_configuration_changed_enabled_slow_keys()340 fn test_notify_configuration_changed_enabled_slow_keys() { 341 let test_callbacks = TestCallbacks::new(); 342 let input_filter = InputFilter::new(Strong::new(Box::new(test_callbacks))); 343 let result = input_filter.notifyConfigurationChanged(&InputFilterConfiguration { 344 slowKeysThresholdNs: 100, 345 ..Default::default() 346 }); 347 assert!(result.is_ok()); 348 let result = input_filter.isEnabled(); 349 assert!(result.is_ok()); 350 assert!(result.unwrap()); 351 } 352 353 #[test] test_notify_configuration_changed_destroys_existing_filters()354 fn test_notify_configuration_changed_destroys_existing_filters() { 355 let test_filter = TestFilter::new(); 356 let test_callbacks = TestCallbacks::new(); 357 let input_filter = InputFilter::create_input_filter( 358 Box::new(test_filter.clone()), 359 Arc::new(RwLock::new(Strong::new(Box::new(test_callbacks)))), 360 ); 361 let _ = input_filter 362 .notifyConfigurationChanged(&InputFilterConfiguration { ..Default::default() }); 363 assert!(test_filter.is_destroy_called()); 364 } 365 create_key_event() -> KeyEvent366 fn create_key_event() -> KeyEvent { 367 KeyEvent { 368 id: 1, 369 deviceId: 1, 370 downTime: 0, 371 readTime: 0, 372 eventTime: 0, 373 source: Source::KEYBOARD, 374 displayId: 0, 375 policyFlags: 0, 376 action: KeyEventAction::DOWN, 377 flags: 0, 378 keyCode: 0, 379 scanCode: 0, 380 metaState: 0, 381 } 382 } 383 } 384 385 #[cfg(test)] 386 pub mod test_filter { 387 use crate::input_filter::Filter; 388 use com_android_server_inputflinger::aidl::com::android::server::inputflinger::{ 389 DeviceInfo::DeviceInfo, KeyEvent::KeyEvent, 390 }; 391 use std::any::Any; 392 use std::collections::HashMap; 393 use std::sync::{Arc, RwLock, RwLockWriteGuard}; 394 395 #[derive(Default)] 396 struct TestFilterInner { 397 is_device_changed_called: bool, 398 last_event: Option<KeyEvent>, 399 is_destroy_called: bool, 400 } 401 402 #[derive(Default, Clone)] 403 pub struct TestFilter(Arc<RwLock<TestFilterInner>>); 404 405 impl TestFilter { new() -> Self406 pub fn new() -> Self { 407 Default::default() 408 } 409 inner(&mut self) -> RwLockWriteGuard<'_, TestFilterInner>410 fn inner(&mut self) -> RwLockWriteGuard<'_, TestFilterInner> { 411 self.0.write().unwrap() 412 } 413 last_event(&self) -> Option<KeyEvent>414 pub fn last_event(&self) -> Option<KeyEvent> { 415 self.0.read().unwrap().last_event 416 } 417 clear(&mut self)418 pub fn clear(&mut self) { 419 self.inner().last_event = None 420 } 421 is_device_changed_called(&self) -> bool422 pub fn is_device_changed_called(&self) -> bool { 423 self.0.read().unwrap().is_device_changed_called 424 } 425 is_destroy_called(&self) -> bool426 pub fn is_destroy_called(&self) -> bool { 427 self.0.read().unwrap().is_destroy_called 428 } 429 } 430 431 impl Filter for TestFilter { notify_key(&mut self, event: &KeyEvent)432 fn notify_key(&mut self, event: &KeyEvent) { 433 self.inner().last_event = Some(*event); 434 } notify_devices_changed(&mut self, _device_infos: &[DeviceInfo])435 fn notify_devices_changed(&mut self, _device_infos: &[DeviceInfo]) { 436 self.inner().is_device_changed_called = true; 437 } destroy(&mut self)438 fn destroy(&mut self) { 439 self.inner().is_destroy_called = true; 440 } save( &mut self, state: HashMap<&'static str, Box<dyn Any + Send + Sync>>, ) -> HashMap<&'static str, Box<dyn Any + Send + Sync>>441 fn save( 442 &mut self, 443 state: HashMap<&'static str, Box<dyn Any + Send + Sync>>, 444 ) -> HashMap<&'static str, Box<dyn Any + Send + Sync>> { 445 // do nothing 446 state 447 } restore(&mut self, _state: &HashMap<&'static str, Box<dyn Any + Send + Sync>>)448 fn restore(&mut self, _state: &HashMap<&'static str, Box<dyn Any + Send + Sync>>) { 449 // do nothing 450 } dump(&mut self, dump_str: String) -> String451 fn dump(&mut self, dump_str: String) -> String { 452 // do nothing 453 dump_str 454 } 455 } 456 } 457 458 #[cfg(test)] 459 pub mod test_callbacks { 460 use binder::{BinderFeatures, Interface, Strong}; 461 use com_android_server_inputflinger::aidl::com::android::server::inputflinger::{ 462 IInputFilter::IInputFilterCallbacks::IInputFilterCallbacks, 463 IInputThread::{BnInputThread, IInputThread, IInputThreadCallback::IInputThreadCallback}, 464 KeyEvent::KeyEvent, 465 }; 466 use input::ModifierState; 467 use nix::{sys::time::TimeValLike, time::clock_gettime, time::ClockId}; 468 use std::sync::{atomic::AtomicBool, atomic::Ordering, Arc, RwLock, RwLockWriteGuard}; 469 use std::time::Duration; 470 471 #[derive(Default)] 472 struct TestCallbacksInner { 473 last_modifier_state: ModifierState, 474 last_locked_modifier_state: ModifierState, 475 last_event: Option<KeyEvent>, 476 test_thread: Option<FakeCppThread>, 477 } 478 479 #[derive(Default, Clone)] 480 pub struct TestCallbacks(Arc<RwLock<TestCallbacksInner>>); 481 482 impl Interface for TestCallbacks {} 483 484 impl TestCallbacks { new() -> Self485 pub fn new() -> Self { 486 Default::default() 487 } 488 inner(&self) -> RwLockWriteGuard<'_, TestCallbacksInner>489 fn inner(&self) -> RwLockWriteGuard<'_, TestCallbacksInner> { 490 self.0.write().unwrap() 491 } 492 last_event(&self) -> Option<KeyEvent>493 pub fn last_event(&self) -> Option<KeyEvent> { 494 self.0.read().unwrap().last_event 495 } 496 clear(&mut self)497 pub fn clear(&mut self) { 498 self.inner().last_event = None; 499 self.inner().last_modifier_state = ModifierState::None; 500 self.inner().last_locked_modifier_state = ModifierState::None; 501 } 502 get_last_modifier_state(&self) -> ModifierState503 pub fn get_last_modifier_state(&self) -> ModifierState { 504 self.0.read().unwrap().last_modifier_state 505 } 506 get_last_locked_modifier_state(&self) -> ModifierState507 pub fn get_last_locked_modifier_state(&self) -> ModifierState { 508 self.0.read().unwrap().last_locked_modifier_state 509 } 510 is_thread_running(&self) -> bool511 pub fn is_thread_running(&self) -> bool { 512 if let Some(test_thread) = &self.0.read().unwrap().test_thread { 513 return test_thread.is_running(); 514 } 515 false 516 } 517 } 518 519 impl IInputFilterCallbacks for TestCallbacks { sendKeyEvent(&self, event: &KeyEvent) -> binder::Result<()>520 fn sendKeyEvent(&self, event: &KeyEvent) -> binder::Result<()> { 521 self.inner().last_event = Some(*event); 522 Result::Ok(()) 523 } 524 onModifierStateChanged( &self, modifier_state: i32, locked_modifier_state: i32, ) -> std::result::Result<(), binder::Status>525 fn onModifierStateChanged( 526 &self, 527 modifier_state: i32, 528 locked_modifier_state: i32, 529 ) -> std::result::Result<(), binder::Status> { 530 self.inner().last_modifier_state = 531 ModifierState::from_bits(modifier_state as u32).unwrap(); 532 self.inner().last_locked_modifier_state = 533 ModifierState::from_bits(locked_modifier_state as u32).unwrap(); 534 Result::Ok(()) 535 } 536 createInputFilterThread( &self, callback: &Strong<dyn IInputThreadCallback>, ) -> std::result::Result<Strong<dyn IInputThread>, binder::Status>537 fn createInputFilterThread( 538 &self, 539 callback: &Strong<dyn IInputThreadCallback>, 540 ) -> std::result::Result<Strong<dyn IInputThread>, binder::Status> { 541 let test_thread = FakeCppThread::new(callback.clone()); 542 test_thread.start_looper(); 543 self.inner().test_thread = Some(test_thread.clone()); 544 Result::Ok(BnInputThread::new_binder(test_thread, BinderFeatures::default())) 545 } 546 } 547 548 #[derive(Default)] 549 struct FakeCppThreadInner { 550 join_handle: Option<std::thread::JoinHandle<()>>, 551 } 552 553 #[derive(Clone)] 554 struct FakeCppThread { 555 callback: Arc<RwLock<Strong<dyn IInputThreadCallback>>>, 556 inner: Arc<RwLock<FakeCppThreadInner>>, 557 exit_flag: Arc<AtomicBool>, 558 } 559 560 impl Interface for FakeCppThread {} 561 562 impl FakeCppThread { new(callback: Strong<dyn IInputThreadCallback>) -> Self563 pub fn new(callback: Strong<dyn IInputThreadCallback>) -> Self { 564 let thread = Self { 565 callback: Arc::new(RwLock::new(callback)), 566 inner: Arc::new(RwLock::new(FakeCppThreadInner { join_handle: None })), 567 exit_flag: Arc::new(AtomicBool::new(true)), 568 }; 569 thread.create_looper(); 570 thread 571 } 572 inner(&self) -> RwLockWriteGuard<'_, FakeCppThreadInner>573 fn inner(&self) -> RwLockWriteGuard<'_, FakeCppThreadInner> { 574 self.inner.write().unwrap() 575 } 576 create_looper(&self)577 fn create_looper(&self) { 578 let clone = self.clone(); 579 let join_handle = std::thread::Builder::new() 580 .name("fake_cpp_thread".to_string()) 581 .spawn(move || loop { 582 if !clone.exit_flag.load(Ordering::Relaxed) { 583 clone.loop_once(); 584 } 585 }) 586 .unwrap(); 587 self.inner().join_handle = Some(join_handle); 588 // Sleep until the looper thread starts 589 std::thread::sleep(Duration::from_millis(10)); 590 } 591 start_looper(&self)592 pub fn start_looper(&self) { 593 self.exit_flag.store(false, Ordering::Relaxed); 594 } 595 stop_looper(&self)596 pub fn stop_looper(&self) { 597 self.exit_flag.store(true, Ordering::Relaxed); 598 if let Some(join_handle) = &self.inner.read().unwrap().join_handle { 599 join_handle.thread().unpark(); 600 } 601 } 602 is_running(&self) -> bool603 pub fn is_running(&self) -> bool { 604 !self.exit_flag.load(Ordering::Relaxed) 605 } 606 loop_once(&self)607 fn loop_once(&self) { 608 let _ = self.callback.read().unwrap().loopOnce(); 609 } 610 } 611 612 impl IInputThread for FakeCppThread { finish(&self) -> binder::Result<()>613 fn finish(&self) -> binder::Result<()> { 614 self.stop_looper(); 615 Result::Ok(()) 616 } 617 wake(&self) -> binder::Result<()>618 fn wake(&self) -> binder::Result<()> { 619 if let Some(join_handle) = &self.inner.read().unwrap().join_handle { 620 join_handle.thread().unpark(); 621 } 622 Result::Ok(()) 623 } 624 sleepUntil(&self, wake_up_time: i64) -> binder::Result<()>625 fn sleepUntil(&self, wake_up_time: i64) -> binder::Result<()> { 626 let now = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap().num_nanoseconds(); 627 if wake_up_time == i64::MAX { 628 std::thread::park(); 629 } else { 630 let duration_now = Duration::from_nanos(now as u64); 631 let duration_wake_up = Duration::from_nanos(wake_up_time as u64); 632 std::thread::park_timeout(duration_wake_up - duration_now); 633 } 634 Result::Ok(()) 635 } 636 } 637 } 638