| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/quick_pair/keyed_service/battery_update_message_handler.h" |
| |
| #include "base/containers/adapters.h" |
| #include "base/containers/contains.h" |
| #include "base/functional/bind.h" |
| #include "base/functional/callback.h" |
| #include "components/cross_device/logging/logging.h" |
| #include "device/bluetooth/bluetooth_adapter.h" |
| #include "device/bluetooth/bluetooth_adapter_factory.h" |
| #include "device/bluetooth/bluetooth_device.h" |
| |
| namespace { |
| |
| device::BluetoothDevice::BatteryInfo GetBatteryInfo( |
| const ash::quick_pair::mojom::BatteryInfoPtr& battery_info, |
| const device::BluetoothDevice::BatteryType& battery_type) { |
| if (battery_info->percentage == -1) { |
| return device::BluetoothDevice::BatteryInfo( |
| battery_type, |
| /*percentage=*/std::nullopt, |
| battery_info->is_charging |
| ? device::BluetoothDevice::BatteryInfo::ChargeState::kCharging |
| : device::BluetoothDevice::BatteryInfo::ChargeState::kDischarging); |
| } |
| |
| return device::BluetoothDevice::BatteryInfo( |
| battery_type, battery_info->percentage, |
| battery_info->is_charging |
| ? device::BluetoothDevice::BatteryInfo::ChargeState::kCharging |
| : device::BluetoothDevice::BatteryInfo::ChargeState::kDischarging); |
| } |
| |
| } // namespace |
| |
| namespace ash { |
| namespace quick_pair { |
| |
| BatteryUpdateMessageHandler::BatteryUpdateMessageHandler( |
| MessageStreamLookup* message_stream_lookup) { |
| device::BluetoothAdapterFactory::Get()->GetAdapter( |
| base::BindOnce(&BatteryUpdateMessageHandler::OnGetAdapter, |
| weak_ptr_factory_.GetWeakPtr())); |
| message_stream_lookup_observation_.Observe(message_stream_lookup); |
| } |
| |
| void BatteryUpdateMessageHandler::OnGetAdapter( |
| scoped_refptr<device::BluetoothAdapter> adapter) { |
| adapter_ = adapter; |
| } |
| |
| BatteryUpdateMessageHandler::~BatteryUpdateMessageHandler() { |
| // Remove any observation of remaining MessageStreams. |
| for (auto it = message_streams_.begin(); it != message_streams_.end(); it++) { |
| it->second->RemoveObserver(this); |
| } |
| } |
| |
| void BatteryUpdateMessageHandler::OnMessageStreamConnected( |
| const std::string& device_address, |
| MessageStream* message_stream) { |
| if (!message_stream) |
| return; |
| |
| message_stream->AddObserver(this); |
| message_streams_[device_address] = message_stream; |
| GetBatteryUpdateFromMessageStream(device_address, message_stream); |
| } |
| |
| void BatteryUpdateMessageHandler::GetBatteryUpdateFromMessageStream( |
| const std::string& device_address, |
| MessageStream* message_stream) { |
| DCHECK(message_stream); |
| |
| // Iterate over messages for battery update if it already exists. |
| for (const auto& message : base::Reversed(message_stream->messages())) { |
| if (message->is_battery_update()) { |
| SetBatteryInfo(device_address, message->get_battery_update()); |
| return; |
| } |
| } |
| } |
| |
| void BatteryUpdateMessageHandler::OnBatteryUpdateMessage( |
| const std::string& device_address, |
| const mojom::BatteryUpdatePtr& battery_update) { |
| SetBatteryInfo(device_address, battery_update); |
| } |
| |
| void BatteryUpdateMessageHandler::OnDisconnected( |
| const std::string& device_address) { |
| CleanUpMessageStream(device_address); |
| } |
| |
| void BatteryUpdateMessageHandler::OnMessageStreamDestroyed( |
| const std::string& device_address) { |
| CleanUpMessageStream(device_address); |
| } |
| |
| void BatteryUpdateMessageHandler::SetBatteryInfo( |
| const std::string& device_address, |
| const mojom::BatteryUpdatePtr& battery_update) { |
| device::BluetoothDevice* device = adapter_->GetDevice(device_address); |
| if (!device) { |
| CD_LOG(INFO, Feature::FP) |
| << "Device lost from adapter before battery info was set."; |
| CleanUpMessageStream(device_address); |
| return; |
| } |
| |
| device::BluetoothDevice::BatteryInfo left_bud_info = |
| GetBatteryInfo(/*battery_info=*/battery_update->left_bud_info, |
| /*battery_type=*/device::BluetoothDevice::BatteryType:: |
| kLeftBudTrueWireless); |
| device->SetBatteryInfo(left_bud_info); |
| |
| device::BluetoothDevice::BatteryInfo right_bud_info = |
| GetBatteryInfo(/*battery_info=*/battery_update->right_bud_info, |
| /*battery_type=*/device::BluetoothDevice::BatteryType:: |
| kRightBudTrueWireless); |
| device->SetBatteryInfo(right_bud_info); |
| |
| device::BluetoothDevice::BatteryInfo case_info = GetBatteryInfo( |
| /*battery_info=*/battery_update->case_info, |
| /*battery_type=*/device::BluetoothDevice::BatteryType::kCaseTrueWireless); |
| device->SetBatteryInfo(case_info); |
| } |
| |
| void BatteryUpdateMessageHandler::CleanUpMessageStream( |
| const std::string& device_address) { |
| if (!base::Contains(message_streams_, device_address)) { |
| return; |
| } |
| |
| message_streams_[device_address]->RemoveObserver(this); |
| message_streams_.erase(device_address); |
| } |
| |
| } // namespace quick_pair |
| } // namespace ash |