1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "PeripheralControllerInterface.h"
20 
21 namespace android {
22 
23 class PeripheralController : public PeripheralControllerInterface {
24     // Refer to https://developer.android.com/reference/kotlin/android/graphics/Color
25     /* Number of colors : {red, green, blue} */
26     static constexpr size_t COLOR_NUM = 3;
27     static constexpr int32_t MAX_BRIGHTNESS = 0xff;
28 
29 public:
30     explicit PeripheralController(InputDeviceContext& deviceContext);
31     ~PeripheralController() override;
32 
33     int32_t getEventHubId() const override;
34     void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
35     void dump(std::string& dump) override;
36     bool setLightColor(int32_t lightId, int32_t color) override;
37     bool setLightPlayerId(int32_t lightId, int32_t playerId) override;
38     std::optional<int32_t> getLightColor(int32_t lightId) override;
39     std::optional<int32_t> getLightPlayerId(int32_t lightId) override;
40     std::optional<int32_t> getBatteryCapacity(int32_t batteryId) override;
41     std::optional<int32_t> getBatteryStatus(int32_t batteryId) override;
42 
43 private:
getDeviceId()44     inline int32_t getDeviceId() { return mDeviceContext.getId(); }
getDeviceContext()45     inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
getDeviceContext()46     inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }
47 
48     InputDeviceContext& mDeviceContext;
49     void configureLights();
50     void configureBattries();
51 
52     struct Battery {
BatteryBattery53         explicit Battery(InputDeviceContext& context, const std::string& name, int32_t id)
54               : context(context), name(name), id(id) {}
~BatteryBattery55         virtual ~Battery() {}
56         InputDeviceContext& context;
57         std::string name;
58         int32_t id;
59     };
60 
61     struct Light {
LightLight62         explicit Light(InputDeviceContext& context, const std::string& name, int32_t id,
63                        InputDeviceLightType type)
64               : context(context), name(name), id(id), type(type) {}
~LightLight65         virtual ~Light() {}
66         InputDeviceContext& context;
67         std::string name;
68         int32_t id;
69         InputDeviceLightType type;
70         ftl::Flags<InputDeviceLightCapability> capabilityFlags;
71 
setLightColorLight72         virtual bool setLightColor(int32_t color) { return false; }
getLightColorLight73         virtual std::optional<int32_t> getLightColor() { return std::nullopt; }
setLightPlayerIdLight74         virtual bool setLightPlayerId(int32_t playerId) { return false; }
getLightPlayerIdLight75         virtual std::optional<int32_t> getLightPlayerId() { return std::nullopt; }
76 
dumpLight77         virtual void dump(std::string& dump) {}
78 
79         void configureSuggestedBrightnessLevels();
80         std::optional<std::int32_t> getRawLightBrightness(int32_t rawLightId);
81         void setRawLightBrightness(int32_t rawLightId, int32_t brightness);
82     };
83 
84     struct MonoLight : public Light {
MonoLightMonoLight85         explicit MonoLight(InputDeviceContext& context, const std::string& name, int32_t id,
86                            InputDeviceLightType type, int32_t rawId)
87               : Light(context, name, id, type), rawId(rawId) {
88             capabilityFlags |= InputDeviceLightCapability::BRIGHTNESS;
89         }
90         int32_t rawId;
91 
92         bool setLightColor(int32_t color) override;
93         std::optional<int32_t> getLightColor() override;
94         void dump(std::string& dump) override;
95     };
96 
97     struct RgbLight : public Light {
RgbLightRgbLight98         explicit RgbLight(InputDeviceContext& context, int32_t id, InputDeviceLightType type,
99                           const std::unordered_map<LightColor, int32_t>& rawRgbIds,
100                           std::optional<int32_t> rawGlobalId)
101               : Light(context, "RGB", id, type), rawRgbIds(rawRgbIds), rawGlobalId(rawGlobalId) {
102             brightness = rawGlobalId.has_value()
103                     ? getRawLightBrightness(rawGlobalId.value()).value_or(MAX_BRIGHTNESS)
104                     : MAX_BRIGHTNESS;
105             capabilityFlags |= InputDeviceLightCapability::BRIGHTNESS;
106             capabilityFlags |= InputDeviceLightCapability::RGB;
107         }
108         // Map from color to raw light id.
109         std::unordered_map<LightColor, int32_t /* rawLightId */> rawRgbIds;
110         // Optional global control raw light id.
111         std::optional<int32_t> rawGlobalId;
112         int32_t brightness;
113 
114         bool setLightColor(int32_t color) override;
115         std::optional<int32_t> getLightColor() override;
116         void dump(std::string& dump) override;
117     };
118 
119     struct MultiColorLight : public Light {
MultiColorLightMultiColorLight120         explicit MultiColorLight(InputDeviceContext& context, const std::string& name, int32_t id,
121                                  InputDeviceLightType type, int32_t rawId)
122               : Light(context, name, id, type), rawId(rawId) {
123             capabilityFlags |= InputDeviceLightCapability::BRIGHTNESS;
124             capabilityFlags |= InputDeviceLightCapability::RGB;
125         }
126         int32_t rawId;
127 
128         bool setLightColor(int32_t color) override;
129         std::optional<int32_t> getLightColor() override;
130         void dump(std::string& dump) override;
131     };
132 
133     struct PlayerIdLight : public Light {
PlayerIdLightPlayerIdLight134         explicit PlayerIdLight(InputDeviceContext& context, const std::string& name, int32_t id,
135                                const std::unordered_map<int32_t, int32_t>& rawLightIds)
136               : Light(context, name, id, InputDeviceLightType::PLAYER_ID),
137                 rawLightIds(rawLightIds) {}
138         // Map from player Id to raw light Id
139         std::unordered_map<int32_t, int32_t> rawLightIds;
140 
141         bool setLightPlayerId(int32_t playerId) override;
142         std::optional<int32_t> getLightPlayerId() override;
143         void dump(std::string& dump) override;
144     };
145 
146     int32_t mNextId = 0;
147 
148     // Light color map from light color to the color index.
149     static const std::unordered_map<std::string, size_t> LIGHT_COLORS;
150 
151     // Light map from light ID to Light
152     std::unordered_map<int32_t, std::unique_ptr<Light>> mLights;
153 
154     // Battery map from battery ID to battery
155     std::unordered_map<int32_t, std::unique_ptr<Battery>> mBatteries;
156 
157     std::set<BrightnessLevel> getPreferredBrightnessLevels(const Light* light) const;
158 };
159 
160 } // namespace android
161