1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ASH_SYSTEM_POWER_PERIPHERAL_BATTERY_NOTIFIER_H_ 6 #define ASH_SYSTEM_POWER_PERIPHERAL_BATTERY_NOTIFIER_H_ 7 8 #include <cstdint> 9 #include <map> 10 11 #include "ash/ash_export.h" 12 #include "base/compiler_specific.h" 13 #include "base/gtest_prod_util.h" 14 #include "base/macros.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/optional.h" 17 #include "base/time/tick_clock.h" 18 #include "chromeos/dbus/power/power_manager_client.h" 19 #include "device/bluetooth/bluetooth_adapter.h" 20 21 namespace ash { 22 23 class BluetoothDevice; 24 class PeripheralBatteryNotifierTest; 25 26 // This class listens for peripheral device battery status and shows 27 // notifications for low battery conditions. 28 class ASH_EXPORT PeripheralBatteryNotifier 29 : public chromeos::PowerManagerClient::Observer, 30 public device::BluetoothAdapter::Observer { 31 public: 32 static const char kStylusNotificationId[]; 33 34 // This class registers/unregisters itself as an observer in ctor/dtor. 35 PeripheralBatteryNotifier(); 36 ~PeripheralBatteryNotifier() override; 37 38 39 // chromeos::PowerManagerClient::Observer: 40 void PeripheralBatteryStatusReceived(const std::string& path, 41 const std::string& name, 42 int level) override; 43 44 // device::BluetoothAdapter::Observer: 45 void DeviceBatteryChanged( 46 device::BluetoothAdapter* adapter, 47 device::BluetoothDevice* device, 48 base::Optional<uint8_t> new_battery_percentage) override; 49 void DeviceConnectedStateChanged(device::BluetoothAdapter* adapter, 50 device::BluetoothDevice* device, 51 bool is_now_connected) override; 52 void DeviceRemoved(device::BluetoothAdapter* adapter, 53 device::BluetoothDevice* device) override; 54 55 private: 56 friend class PeripheralBatteryNotifierTest; 57 FRIEND_TEST_ALL_PREFIXES(PeripheralBatteryNotifierTest, Basic); 58 FRIEND_TEST_ALL_PREFIXES(PeripheralBatteryNotifierTest, InvalidBatteryInfo); 59 FRIEND_TEST_ALL_PREFIXES(PeripheralBatteryNotifierTest, 60 ExtractBluetoothAddress); 61 FRIEND_TEST_ALL_PREFIXES(PeripheralBatteryNotifierTest, DeviceRemove); 62 63 struct BatteryInfo { 64 BatteryInfo(); 65 BatteryInfo(const base::string16& name, 66 base::Optional<uint8_t> level, 67 base::TimeTicks last_notification_timestamp, 68 bool is_stylus, 69 const std::string& bluetooth_address); 70 ~BatteryInfo(); 71 BatteryInfo(const BatteryInfo& info); 72 73 // Human readable name for the device. It is changeable. 74 base::string16 name; 75 // Battery level within range [0, 100]. 76 base::Optional<uint8_t> level; 77 base::TimeTicks last_notification_timestamp; 78 bool is_stylus = false; 79 // Peripheral's Bluetooth address. Empty for non-Bluetooth devices. 80 std::string bluetooth_address; 81 }; 82 83 void InitializeOnBluetoothReady( 84 scoped_refptr<device::BluetoothAdapter> adapter); 85 86 // Removes the Bluetooth battery with address |bluetooth_address|, as well as 87 // the associated notification. Called when a bluetooth device has been 88 // changed or removed. 89 void RemoveBluetoothBattery(const std::string& bluetooth_address); 90 91 // Updates the battery information of the peripheral with the corresponding 92 // |map_key|, and calls to post a notification if the battery level is under 93 // the threshold. 94 void UpdateBattery(const std::string& map_key, 95 const BatteryInfo& battery_info); 96 97 // Updates the battery percentage in the corresponding notification. 98 void UpdateBatteryNotificationIfVisible(const std::string& map_key, 99 const BatteryInfo& battery); 100 101 // Calls to display a notification only if kNotificationInterval seconds have 102 // passed since the last notification showed, avoiding the case where the 103 // battery level oscillates around the threshold level. 104 void ShowNotification(const std::string& map_key, const BatteryInfo& battery); 105 106 // Posts a low battery notification with id as |map_key|. If a notification 107 // with the same id exists, its content gets updated. 108 void ShowOrUpdateNotification(const std::string& map_key, 109 const BatteryInfo& battery); 110 111 void CancelNotification(const std::string& map_key); 112 113 // Record of existing battery information. For Bluetooth Devices, the key is 114 // kBluetoothDeviceIdPrefix + the device's address. For HID devices, the key 115 // is the device path. If a device uses HID over Bluetooth, it is indexed as a 116 // Bluetooth device. 117 std::map<std::string, BatteryInfo> batteries_; 118 119 // PeripheralBatteryNotifier is an observer of |bluetooth_adapter_| for 120 // bluetooth device change/remove events. 121 scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; 122 123 const base::TickClock* clock_; 124 125 std::unique_ptr<base::WeakPtrFactory<PeripheralBatteryNotifier>> 126 weakptr_factory_; 127 128 DISALLOW_COPY_AND_ASSIGN(PeripheralBatteryNotifier); 129 }; 130 131 } // namespace ash 132 133 #endif // ASH_SYSTEM_POWER_PERIPHERAL_BATTERY_NOTIFIER_H_ 134