Loading system/gd/rust/linux/stack/src/battery_service.rs +73 −46 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ use crate::bluetooth_gatt::{ BluetoothGatt, BluetoothGattService, IBluetoothGatt, IBluetoothGattCallback, }; use crate::callbacks::Callbacks; use crate::uuid::UuidHelper; use crate::Message; use crate::RPCProxy; use crate::{uuid, APIMessage, BluetoothAPI}; Loading Loading @@ -162,63 +163,53 @@ impl BatteryService { DisplayAddress(&addr), status ); self.drop_device(addr); return; } let (bas_uuid, battery_level_uuid) = match ( Uuid::from_string(uuid::BAS), Uuid::from_string(CHARACTERISTIC_BATTERY_LEVEL), ) { (Some(bas_uuid), Some(battery_level_uuid)) => (bas_uuid, battery_level_uuid), _ => return, }; // TODO(b/233101174): handle multiple instances of BAS let bas = match services.iter().find(|service| service.uuid == bas_uuid) { Some(bas) => bas, None => { let handle = match self.get_battery_level_handle(addr.clone(), services) { Ok(battery_level_handle) => battery_level_handle, Err(status) => { if let Some(BatteryServiceStatus::BatteryServiceNotSupported) = status { self.callbacks.for_all_callbacks(|callback| { callback.on_battery_service_status_updated( addr, addr.clone(), BatteryServiceStatus::BatteryServiceNotSupported, ) }); return; } }; let battery_level = match bas .characteristics .iter() .find(|characteristic| characteristic.uuid == battery_level_uuid) { Some(battery_level) => battery_level, None => { debug!( "Device {} has no BatteryLevel characteristic", DisplayAddress(&addr) ); self.drop_device(addr); return; } }; let client_id = match self.client_id { Some(id) => id, None => return, None => { self.drop_device(addr); return; } }; let handle = battery_level.instance_id; self.handles.insert(addr, handle.clone()); self.gatt.lock().unwrap().register_for_notification(client_id, addr, handle, true); if let None = self.battery_sets.get(&addr) { self.gatt.lock().unwrap().read_characteristic( client_id, addr, battery_level.instance_id, 0, ); self.gatt.lock().unwrap().read_characteristic(client_id, addr, handle, 0); } } BatteryServiceActions::OnCharacteristicRead(addr, status, _handle, value) => { BatteryServiceActions::OnCharacteristicRead(addr, status, handle, value) => { if status != GattStatus::Success { return; } match self.handles.get(&addr) { Some(stored_handle) => { if *stored_handle != handle { return; } } None => { self.drop_device(addr); return; } } let battery_info = self.set_battery_info(&addr, &value); self.callbacks.for_all_callbacks(|callback| { callback.on_battery_info_updated(addr, battery_info.clone()); Loading Loading @@ -281,6 +272,15 @@ impl BatteryService { } fn drop_device(&mut self, remote_address: RawAddress) { if self.handles.contains_key(&remote_address) { // Let BatteryProviderManager know that BAS no longer has a battery for this device. self.battery_provider_manager.lock().unwrap().remove_battery_info( self.battery_provider_id, remote_address.clone(), uuid::BAS.to_string(), ); } self.battery_sets.remove(&remote_address); self.handles.remove(&remote_address); match self.client_id { Some(client_id) => { Loading @@ -288,13 +288,40 @@ impl BatteryService { } None => return, } // Let BatteryProviderManager know that BAS no longer has a battery for this device. self.battery_provider_manager.lock().unwrap().remove_battery_info( self.battery_provider_id, remote_address, uuid::BAS.to_string(), } fn get_battery_level_handle( &mut self, remote_address: RawAddress, services: Vec<BluetoothGattService>, ) -> Result<i32, Option<BatteryServiceStatus>> { let (bas_uuid, battery_level_uuid) = match (Uuid::from_string(uuid::BAS), Uuid::from_string(CHARACTERISTIC_BATTERY_LEVEL)) { (Some(bas_uuid), Some(battery_level_uuid)) => (bas_uuid, battery_level_uuid), _ => { return Err(None); } }; // TODO(b/233101174): handle multiple instances of BAS let bas = match services.iter().find(|service| service.uuid == bas_uuid) { Some(bas) => bas, None => return Err(Some(BatteryServiceStatus::BatteryServiceNotSupported)), }; let battery_level = match bas .characteristics .iter() .find(|characteristic| characteristic.uuid == battery_level_uuid) { Some(battery_level) => battery_level, None => { debug!( "Device {} has no BatteryLevel characteristic", DisplayAddress(&remote_address) ); self.battery_sets.remove(&remote_address); return Err(None); } }; Ok(battery_level.instance_id) } /// Perform an explicit read on all devices BAS knows about. Loading Loading
system/gd/rust/linux/stack/src/battery_service.rs +73 −46 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ use crate::bluetooth_gatt::{ BluetoothGatt, BluetoothGattService, IBluetoothGatt, IBluetoothGattCallback, }; use crate::callbacks::Callbacks; use crate::uuid::UuidHelper; use crate::Message; use crate::RPCProxy; use crate::{uuid, APIMessage, BluetoothAPI}; Loading Loading @@ -162,63 +163,53 @@ impl BatteryService { DisplayAddress(&addr), status ); self.drop_device(addr); return; } let (bas_uuid, battery_level_uuid) = match ( Uuid::from_string(uuid::BAS), Uuid::from_string(CHARACTERISTIC_BATTERY_LEVEL), ) { (Some(bas_uuid), Some(battery_level_uuid)) => (bas_uuid, battery_level_uuid), _ => return, }; // TODO(b/233101174): handle multiple instances of BAS let bas = match services.iter().find(|service| service.uuid == bas_uuid) { Some(bas) => bas, None => { let handle = match self.get_battery_level_handle(addr.clone(), services) { Ok(battery_level_handle) => battery_level_handle, Err(status) => { if let Some(BatteryServiceStatus::BatteryServiceNotSupported) = status { self.callbacks.for_all_callbacks(|callback| { callback.on_battery_service_status_updated( addr, addr.clone(), BatteryServiceStatus::BatteryServiceNotSupported, ) }); return; } }; let battery_level = match bas .characteristics .iter() .find(|characteristic| characteristic.uuid == battery_level_uuid) { Some(battery_level) => battery_level, None => { debug!( "Device {} has no BatteryLevel characteristic", DisplayAddress(&addr) ); self.drop_device(addr); return; } }; let client_id = match self.client_id { Some(id) => id, None => return, None => { self.drop_device(addr); return; } }; let handle = battery_level.instance_id; self.handles.insert(addr, handle.clone()); self.gatt.lock().unwrap().register_for_notification(client_id, addr, handle, true); if let None = self.battery_sets.get(&addr) { self.gatt.lock().unwrap().read_characteristic( client_id, addr, battery_level.instance_id, 0, ); self.gatt.lock().unwrap().read_characteristic(client_id, addr, handle, 0); } } BatteryServiceActions::OnCharacteristicRead(addr, status, _handle, value) => { BatteryServiceActions::OnCharacteristicRead(addr, status, handle, value) => { if status != GattStatus::Success { return; } match self.handles.get(&addr) { Some(stored_handle) => { if *stored_handle != handle { return; } } None => { self.drop_device(addr); return; } } let battery_info = self.set_battery_info(&addr, &value); self.callbacks.for_all_callbacks(|callback| { callback.on_battery_info_updated(addr, battery_info.clone()); Loading Loading @@ -281,6 +272,15 @@ impl BatteryService { } fn drop_device(&mut self, remote_address: RawAddress) { if self.handles.contains_key(&remote_address) { // Let BatteryProviderManager know that BAS no longer has a battery for this device. self.battery_provider_manager.lock().unwrap().remove_battery_info( self.battery_provider_id, remote_address.clone(), uuid::BAS.to_string(), ); } self.battery_sets.remove(&remote_address); self.handles.remove(&remote_address); match self.client_id { Some(client_id) => { Loading @@ -288,13 +288,40 @@ impl BatteryService { } None => return, } // Let BatteryProviderManager know that BAS no longer has a battery for this device. self.battery_provider_manager.lock().unwrap().remove_battery_info( self.battery_provider_id, remote_address, uuid::BAS.to_string(), } fn get_battery_level_handle( &mut self, remote_address: RawAddress, services: Vec<BluetoothGattService>, ) -> Result<i32, Option<BatteryServiceStatus>> { let (bas_uuid, battery_level_uuid) = match (Uuid::from_string(uuid::BAS), Uuid::from_string(CHARACTERISTIC_BATTERY_LEVEL)) { (Some(bas_uuid), Some(battery_level_uuid)) => (bas_uuid, battery_level_uuid), _ => { return Err(None); } }; // TODO(b/233101174): handle multiple instances of BAS let bas = match services.iter().find(|service| service.uuid == bas_uuid) { Some(bas) => bas, None => return Err(Some(BatteryServiceStatus::BatteryServiceNotSupported)), }; let battery_level = match bas .characteristics .iter() .find(|characteristic| characteristic.uuid == battery_level_uuid) { Some(battery_level) => battery_level, None => { debug!( "Device {} has no BatteryLevel characteristic", DisplayAddress(&remote_address) ); self.battery_sets.remove(&remote_address); return Err(None); } }; Ok(battery_level.instance_id) } /// Perform an explicit read on all devices BAS knows about. Loading