diff --git a/system/gd/rust/linux/service/src/iface_battery_provider_manager.rs b/system/gd/rust/linux/service/src/iface_battery_provider_manager.rs index f2ce28bd2bc9beb5e76da79bf1c9cfcd21c15592..dac6457c8a3ae73da2cafa7dabfc1dc3c4f8f879 100644 --- a/system/gd/rust/linux/service/src/iface_battery_provider_manager.rs +++ b/system/gd/rust/linux/service/src/iface_battery_provider_manager.rs @@ -41,4 +41,9 @@ impl IBatteryProviderManager for IBatteryProviderManagerDBus { fn set_battery_info(&mut self, battery_provider_id: u32, battery_set: BatterySet) { dbus_generated!() } + + #[dbus_method("RemoveBatteryInfo")] + fn remove_battery_info(&mut self, battery_provider_id: u32, address: String, uuid: String) { + dbus_generated!() + } } diff --git a/system/gd/rust/linux/stack/src/battery_manager.rs b/system/gd/rust/linux/stack/src/battery_manager.rs index 5723b686bbdfe55c9882ca209de242f6baf447a8..393761c448673d0f0099b764794ffb518d9dfdd3 100644 --- a/system/gd/rust/linux/stack/src/battery_manager.rs +++ b/system/gd/rust/linux/stack/src/battery_manager.rs @@ -3,6 +3,7 @@ use crate::callbacks::Callbacks; use crate::uuid; use crate::Message; use crate::RPCProxy; +use itertools::Itertools; use std::sync::{Arc, Mutex}; use tokio::sync::mpsc::Sender; @@ -137,11 +138,22 @@ impl Batteries { } } + pub fn remove_battery_set(&mut self, uuid: &String) { + self.0.retain(|battery_set| &battery_set.source_uuid != uuid); + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + /// Returns the best BatterySet from among reported battery data. pub fn pick_best(&self) -> Option<BatterySet> { self.0 .iter() - .find(|battery_set| battery_set.source_uuid == uuid::BAS) + .filter(|battery_set| !battery_set.batteries.is_empty()) + // Now we prefer BAS, but we might need to prioritize other sources first + // TODO (b/295577710): Make a preference list + .find_or_first(|battery_set| battery_set.source_uuid == uuid::BAS) .or_else(|| self.0.first()) .cloned() } diff --git a/system/gd/rust/linux/stack/src/battery_provider_manager.rs b/system/gd/rust/linux/stack/src/battery_provider_manager.rs index b8e0c2ea90933d2eb998c8f656c51df67f0d4b2a..a0138e2787c914784950b5e9bf076692a704af8f 100644 --- a/system/gd/rust/linux/stack/src/battery_provider_manager.rs +++ b/system/gd/rust/linux/stack/src/battery_provider_manager.rs @@ -25,6 +25,9 @@ pub trait IBatteryProviderManager { /// Updates the battery information for the battery associated with battery_id. fn set_battery_info(&mut self, battery_provider_id: u32, battery_set: BatterySet); + + /// Removes the battery information for the battery associated with battery_id. + fn remove_battery_info(&mut self, battery_provider_id: u32, address: String, uuid: String); } /// Represents the BatteryProviderManager, a central point for collecting battery information from @@ -75,6 +78,16 @@ impl IBatteryProviderManager for BatteryProviderManager { self.remove_battery_provider_callback(battery_provider_id); } + fn remove_battery_info(&mut self, _battery_provider_id: u32, address: String, uuid: String) { + if let Some(batteries) = self.battery_info.get_mut(&address) { + batteries.remove_battery_set(&uuid); + + if batteries.is_empty() { + self.battery_info.remove(&address); + } + } + } + fn set_battery_info(&mut self, _battery_provider_id: u32, battery_set: BatterySet) { debug!( "BatteryProviderManager received BatterySet for [{}] from \"{}\": {:?}", @@ -82,11 +95,17 @@ impl IBatteryProviderManager for BatteryProviderManager { battery_set.source_info.clone(), battery_set.clone() ); + + if battery_set.batteries.is_empty() { + return; + } + let batteries = self .battery_info .entry(battery_set.address.clone()) .or_insert_with(|| Batteries::new()); batteries.add_or_update_battery_set(battery_set); + if let Some(best_battery_set) = batteries.pick_best() { let tx = self.tx.clone(); tokio::spawn(async move { diff --git a/system/gd/rust/linux/stack/src/battery_service.rs b/system/gd/rust/linux/stack/src/battery_service.rs index f822fa3020696082c3dc10df4736cd9a0d797431..a8f8ae44944a9da09bea8965dc1a5dcbfccc9a58 100644 --- a/system/gd/rust/linux/stack/src/battery_service.rs +++ b/system/gd/rust/linux/stack/src/battery_service.rs @@ -284,14 +284,10 @@ impl BatteryService { None => return, } // Let BatteryProviderManager know that BAS no longer has a battery for this device. - self.battery_provider_manager.lock().unwrap().set_battery_info( + self.battery_provider_manager.lock().unwrap().remove_battery_info( self.battery_provider_id, - BatterySet::new( - remote_address.clone(), - uuid::BAS.to_string(), - "BAS".to_string(), - vec![], - ), + remote_address.clone(), + uuid::BAS.to_string(), ); self.battery_sets.remove(&remote_address); }