1 use crate::battery_manager::{Batteries, BatterySet}; 2 use crate::callbacks::Callbacks; 3 use crate::{Message, RPCProxy}; 4 use bt_topshim::btif::{DisplayAddress, RawAddress}; 5 use log::debug; 6 use std::collections::HashMap; 7 use tokio::sync::mpsc::Sender; 8 9 /// Callback for BatteryProvider implementers. 10 pub trait IBatteryProviderCallback: RPCProxy { 11 /// Requests that the BatteryProvider send updated battery information. refresh_battery_info(&mut self)12 fn refresh_battery_info(&mut self); 13 } 14 15 /// Interface for managing BatteryProvider instances. 16 pub trait IBatteryProviderManager { 17 /// Registers a BatteryProvider and generates a unique batttery provider ID for future calls. register_battery_provider( &mut self, battery_provider_callback: Box<dyn IBatteryProviderCallback + Send>, ) -> u3218 fn register_battery_provider( 19 &mut self, 20 battery_provider_callback: Box<dyn IBatteryProviderCallback + Send>, 21 ) -> u32; 22 23 /// Unregisters a BatteryProvider, potentially removes battery information for the remote device 24 /// if there are no other providers. unregister_battery_provider(&mut self, battery_provider_id: u32)25 fn unregister_battery_provider(&mut self, battery_provider_id: u32); 26 27 /// Updates the battery information for the battery associated with battery_id. set_battery_info(&mut self, battery_provider_id: u32, battery_set: BatterySet)28 fn set_battery_info(&mut self, battery_provider_id: u32, battery_set: BatterySet); 29 30 /// Removes the battery information for the battery associated with battery_id. remove_battery_info(&mut self, battery_provider_id: u32, address: RawAddress, uuid: String)31 fn remove_battery_info(&mut self, battery_provider_id: u32, address: RawAddress, uuid: String); 32 } 33 34 /// Represents the BatteryProviderManager, a central point for collecting battery information from 35 /// numerous sources. 36 pub struct BatteryProviderManager { 37 /// Sender for callback communication with the main thread. 38 tx: Sender<Message>, 39 battery_provider_callbacks: Callbacks<dyn IBatteryProviderCallback + Send>, 40 /// Stored information merged from all battery providers. 41 battery_info: HashMap<RawAddress, Batteries>, 42 } 43 44 impl BatteryProviderManager { 45 /// Constructs a new BatteryProviderManager with callbacks communicating on tx. new(tx: Sender<Message>) -> BatteryProviderManager46 pub fn new(tx: Sender<Message>) -> BatteryProviderManager { 47 let battery_provider_callbacks = 48 Callbacks::new(tx.clone(), Message::BatteryProviderManagerCallbackDisconnected); 49 let battery_info = HashMap::new(); 50 BatteryProviderManager { tx, battery_provider_callbacks, battery_info } 51 } 52 53 /// Request battery info refresh from all battery providers. refresh_battery_info(&mut self)54 pub fn refresh_battery_info(&mut self) { 55 self.battery_provider_callbacks 56 .for_all_callbacks(|callback| callback.refresh_battery_info()); 57 } 58 59 /// Get the best battery info available for a given device. get_battery_info(&self, remote_address: RawAddress) -> Option<BatterySet>60 pub fn get_battery_info(&self, remote_address: RawAddress) -> Option<BatterySet> { 61 self.battery_info.get(&remote_address)?.pick_best() 62 } 63 64 /// Removes a battery provider callback. remove_battery_provider_callback(&mut self, battery_provider_id: u32)65 pub fn remove_battery_provider_callback(&mut self, battery_provider_id: u32) { 66 self.battery_provider_callbacks.remove_callback(battery_provider_id); 67 } 68 } 69 70 impl IBatteryProviderManager for BatteryProviderManager { register_battery_provider( &mut self, battery_provider_callback: Box<dyn IBatteryProviderCallback + Send>, ) -> u3271 fn register_battery_provider( 72 &mut self, 73 battery_provider_callback: Box<dyn IBatteryProviderCallback + Send>, 74 ) -> u32 { 75 self.battery_provider_callbacks.add_callback(battery_provider_callback) 76 } 77 unregister_battery_provider(&mut self, battery_provider_id: u32)78 fn unregister_battery_provider(&mut self, battery_provider_id: u32) { 79 self.remove_battery_provider_callback(battery_provider_id); 80 } 81 remove_battery_info( &mut self, _battery_provider_id: u32, address: RawAddress, uuid: String, )82 fn remove_battery_info( 83 &mut self, 84 _battery_provider_id: u32, 85 address: RawAddress, 86 uuid: String, 87 ) { 88 if let Some(batteries) = self.battery_info.get_mut(&address) { 89 batteries.remove_battery_set(&uuid); 90 91 if batteries.is_empty() { 92 self.battery_info.remove(&address); 93 } 94 } 95 } 96 set_battery_info(&mut self, _battery_provider_id: u32, battery_set: BatterySet)97 fn set_battery_info(&mut self, _battery_provider_id: u32, battery_set: BatterySet) { 98 debug!( 99 "BatteryProviderManager received BatterySet for [{}] from \"{}\": {:?}", 100 DisplayAddress(&battery_set.address), 101 battery_set.source_info.clone(), 102 battery_set.clone() 103 ); 104 105 if battery_set.batteries.is_empty() { 106 return; 107 } 108 109 let batteries = 110 self.battery_info.entry(battery_set.address).or_insert_with(|| Batteries::new()); 111 batteries.add_or_update_battery_set(battery_set); 112 113 if let Some(best_battery_set) = batteries.pick_best() { 114 let tx = self.tx.clone(); 115 tokio::spawn(async move { 116 let _ = tx 117 .send(Message::BatteryProviderManagerBatteryUpdated( 118 best_battery_set.address, 119 best_battery_set, 120 )) 121 .await; 122 }); 123 } 124 } 125 } 126