• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 #ifndef ANDROID_POWERHALWRAPPER_H
18 #define ANDROID_POWERHALWRAPPER_H
19 
20 #include <android-base/thread_annotations.h>
21 #include <android/hardware/power/1.1/IPower.h>
22 #include <android/hardware/power/1.2/IPower.h>
23 #include <android/hardware/power/1.3/IPower.h>
24 #include <android/hardware/power/Boost.h>
25 #include <android/hardware/power/IPower.h>
26 #include <android/hardware/power/IPowerHintSession.h>
27 #include <android/hardware/power/Mode.h>
28 
29 namespace android {
30 
31 namespace power {
32 
33 // State of Power HAL support for individual apis.
34 enum class HalSupport {
35     UNKNOWN = 0,
36     ON = 1,
37     OFF = 2,
38 };
39 
40 // Result of a call to the Power HAL wrapper, holding data if successful.
41 template <typename T>
42 class HalResult {
43 public:
ok(T value)44     static HalResult<T> ok(T value) { return HalResult(value); }
failed(std::string msg)45     static HalResult<T> failed(std::string msg) {
46         return HalResult(std::move(msg), /* unsupported= */ false);
47     }
unsupported()48     static HalResult<T> unsupported() { return HalResult("", /* unsupported= */ true); }
49 
fromStatus(binder::Status status,T data)50     static HalResult<T> fromStatus(binder::Status status, T data) {
51         if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
52             return HalResult<T>::unsupported();
53         }
54         if (status.isOk()) {
55             return HalResult<T>::ok(data);
56         }
57         return HalResult<T>::failed(std::string(status.toString8().c_str()));
58     }
59     static HalResult<T> fromStatus(hardware::power::V1_0::Status status, T data);
60 
61     template <typename R>
62     static HalResult<T> fromReturn(hardware::Return<R>& ret, T data);
63 
64     template <typename R>
65     static HalResult<T> fromReturn(hardware::Return<R>& ret, hardware::power::V1_0::Status status,
66                                    T data);
67 
68     // This will throw std::bad_optional_access if this result is not ok.
value()69     const T& value() const { return mValue.value(); }
isOk()70     bool isOk() const { return !mUnsupported && mValue.has_value(); }
isFailed()71     bool isFailed() const { return !mUnsupported && !mValue.has_value(); }
isUnsupported()72     bool isUnsupported() const { return mUnsupported; }
errorMessage()73     const char* errorMessage() const { return mErrorMessage.c_str(); }
74 
75 private:
76     std::optional<T> mValue;
77     std::string mErrorMessage;
78     bool mUnsupported;
79 
HalResult(T value)80     explicit HalResult(T value)
81           : mValue(std::make_optional(value)), mErrorMessage(), mUnsupported(false) {}
HalResult(std::string errorMessage,bool unsupported)82     explicit HalResult(std::string errorMessage, bool unsupported)
83           : mValue(), mErrorMessage(std::move(errorMessage)), mUnsupported(unsupported) {}
84 };
85 
86 // Empty result of a call to the Power HAL wrapper.
87 template <>
88 class HalResult<void> {
89 public:
ok()90     static HalResult<void> ok() { return HalResult(); }
failed(std::string msg)91     static HalResult<void> failed(std::string msg) { return HalResult(std::move(msg)); }
unsupported()92     static HalResult<void> unsupported() { return HalResult(/* unsupported= */ true); }
93 
94     static HalResult<void> fromStatus(status_t status);
95     static HalResult<void> fromStatus(binder::Status status);
96     static HalResult<void> fromStatus(hardware::power::V1_0::Status status);
97 
98     template <typename R>
99     static HalResult<void> fromReturn(hardware::Return<R>& ret);
100 
isOk()101     bool isOk() const { return !mUnsupported && !mFailed; }
isFailed()102     bool isFailed() const { return !mUnsupported && mFailed; }
isUnsupported()103     bool isUnsupported() const { return mUnsupported; }
errorMessage()104     const char* errorMessage() const { return mErrorMessage.c_str(); }
105 
106 private:
107     std::string mErrorMessage;
108     bool mFailed;
109     bool mUnsupported;
110 
111     explicit HalResult(bool unsupported = false)
mErrorMessage()112           : mErrorMessage(), mFailed(false), mUnsupported(unsupported) {}
HalResult(std::string errorMessage)113     explicit HalResult(std::string errorMessage)
114           : mErrorMessage(std::move(errorMessage)), mFailed(true), mUnsupported(false) {}
115 };
116 
117 // Wrapper for Power HAL handlers.
118 class HalWrapper {
119 public:
120     virtual ~HalWrapper() = default;
121 
122     virtual HalResult<void> setBoost(hardware::power::Boost boost, int32_t durationMs) = 0;
123     virtual HalResult<void> setMode(hardware::power::Mode mode, bool enabled) = 0;
124     virtual HalResult<sp<hardware::power::IPowerHintSession>> createHintSession(
125             int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
126             int64_t durationNanos) = 0;
127     virtual HalResult<int64_t> getHintSessionPreferredRate() = 0;
128 };
129 
130 // Empty Power HAL wrapper that ignores all api calls.
131 class EmptyHalWrapper : public HalWrapper {
132 public:
133     EmptyHalWrapper() = default;
134     ~EmptyHalWrapper() = default;
135 
136     virtual HalResult<void> setBoost(hardware::power::Boost boost, int32_t durationMs) override;
137     virtual HalResult<void> setMode(hardware::power::Mode mode, bool enabled) override;
138     virtual HalResult<sp<hardware::power::IPowerHintSession>> createHintSession(
139             int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
140             int64_t durationNanos) override;
141     virtual HalResult<int64_t> getHintSessionPreferredRate() override;
142 };
143 
144 // Wrapper for the HIDL Power HAL v1.0.
145 class HidlHalWrapperV1_0 : public HalWrapper {
146 public:
HidlHalWrapperV1_0(sp<hardware::power::V1_0::IPower> handleV1_0)147     explicit HidlHalWrapperV1_0(sp<hardware::power::V1_0::IPower> handleV1_0)
148           : mHandleV1_0(std::move(handleV1_0)) {}
149     virtual ~HidlHalWrapperV1_0() = default;
150 
151     virtual HalResult<void> setBoost(hardware::power::Boost boost, int32_t durationMs) override;
152     virtual HalResult<void> setMode(hardware::power::Mode mode, bool enabled) override;
153     virtual HalResult<sp<hardware::power::IPowerHintSession>> createHintSession(
154             int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
155             int64_t durationNanos) override;
156     virtual HalResult<int64_t> getHintSessionPreferredRate() override;
157 
158 protected:
159     const sp<hardware::power::V1_0::IPower> mHandleV1_0;
160     virtual HalResult<void> sendPowerHint(hardware::power::V1_3::PowerHint hintId, uint32_t data);
161 
162 private:
163     HalResult<void> setInteractive(bool enabled);
164     HalResult<void> setFeature(hardware::power::V1_0::Feature feature, bool enabled);
165 };
166 
167 // Wrapper for the HIDL Power HAL v1.1.
168 class HidlHalWrapperV1_1 : public HidlHalWrapperV1_0 {
169 public:
HidlHalWrapperV1_1(sp<hardware::power::V1_1::IPower> handleV1_1)170     HidlHalWrapperV1_1(sp<hardware::power::V1_1::IPower> handleV1_1)
171           : HidlHalWrapperV1_0(std::move(handleV1_1)) {}
172     virtual ~HidlHalWrapperV1_1() = default;
173 
174 protected:
175     virtual HalResult<void> sendPowerHint(hardware::power::V1_3::PowerHint hintId,
176                                           uint32_t data) override;
177 };
178 
179 // Wrapper for the HIDL Power HAL v1.2.
180 class HidlHalWrapperV1_2 : public HidlHalWrapperV1_1 {
181 public:
182     virtual HalResult<void> setBoost(hardware::power::Boost boost, int32_t durationMs) override;
183     virtual HalResult<void> setMode(hardware::power::Mode mode, bool enabled) override;
HidlHalWrapperV1_2(sp<hardware::power::V1_2::IPower> handleV1_2)184     HidlHalWrapperV1_2(sp<hardware::power::V1_2::IPower> handleV1_2)
185           : HidlHalWrapperV1_1(std::move(handleV1_2)) {}
186     virtual ~HidlHalWrapperV1_2() = default;
187 
188 protected:
189     virtual HalResult<void> sendPowerHint(hardware::power::V1_3::PowerHint hintId,
190                                           uint32_t data) override;
191 };
192 
193 // Wrapper for the HIDL Power HAL v1.3.
194 class HidlHalWrapperV1_3 : public HidlHalWrapperV1_2 {
195 public:
196     virtual HalResult<void> setMode(hardware::power::Mode mode, bool enabled) override;
HidlHalWrapperV1_3(sp<hardware::power::V1_3::IPower> handleV1_3)197     HidlHalWrapperV1_3(sp<hardware::power::V1_3::IPower> handleV1_3)
198           : HidlHalWrapperV1_2(std::move(handleV1_3)) {}
199     virtual ~HidlHalWrapperV1_3() = default;
200 
201 protected:
202     virtual HalResult<void> sendPowerHint(hardware::power::V1_3::PowerHint hintId,
203                                           uint32_t data) override;
204 };
205 
206 // Wrapper for the AIDL Power HAL.
207 class AidlHalWrapper : public HalWrapper {
208 public:
AidlHalWrapper(sp<hardware::power::IPower> handle)209     explicit AidlHalWrapper(sp<hardware::power::IPower> handle) : mHandle(std::move(handle)) {}
210     virtual ~AidlHalWrapper() = default;
211 
212     virtual HalResult<void> setBoost(hardware::power::Boost boost, int32_t durationMs) override;
213     virtual HalResult<void> setMode(hardware::power::Mode mode, bool enabled) override;
214     virtual HalResult<sp<hardware::power::IPowerHintSession>> createHintSession(
215             int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
216             int64_t durationNanos) override;
217     virtual HalResult<int64_t> getHintSessionPreferredRate() override;
218 
219 private:
220     // Control access to the boost and mode supported arrays.
221     std::mutex mBoostMutex;
222     std::mutex mModeMutex;
223     sp<hardware::power::IPower> mHandle;
224     // Android framework only sends boost upto DISPLAY_UPDATE_IMMINENT.
225     // Need to increase the array size if more boost supported.
226     std::array<std::atomic<HalSupport>,
227                static_cast<int32_t>(hardware::power::Boost::DISPLAY_UPDATE_IMMINENT) + 1>
228             mBoostSupportedArray GUARDED_BY(mBoostMutex) = {HalSupport::UNKNOWN};
229     std::array<std::atomic<HalSupport>,
230                static_cast<int32_t>(*(android::enum_range<hardware::power::Mode>().end() - 1)) + 1>
231             mModeSupportedArray GUARDED_BY(mModeMutex) = {HalSupport::UNKNOWN};
232 };
233 
234 }; // namespace power
235 
236 }; // namespace android
237 
238 #endif // ANDROID_POWERHALWRAPPER_H
239