blob: e2da0146061d8f4c727604995ccb0fd444da4924 [file] [log] [blame]
Lais Andrade4d51f6c2020-03-25 10:58:31 +00001/*
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
Matt Buckleydb4192a2023-12-21 20:00:32 +000017#pragma once
Lais Andrade4d51f6c2020-03-25 10:58:31 +000018
Xiang Wang99f6f3c2023-05-22 13:12:16 -070019#include <aidl/android/hardware/power/Boost.h>
Matt Buckleydb4192a2023-12-21 20:00:32 +000020#include <aidl/android/hardware/power/ChannelConfig.h>
Xiang Wang99f6f3c2023-05-22 13:12:16 -070021#include <aidl/android/hardware/power/IPower.h>
22#include <aidl/android/hardware/power/IPowerHintSession.h>
23#include <aidl/android/hardware/power/Mode.h>
Matt Buckleydb4192a2023-12-21 20:00:32 +000024#include <aidl/android/hardware/power/SessionConfig.h>
Lais Andrade4d51f6c2020-03-25 10:58:31 +000025#include <android-base/thread_annotations.h>
Lais Andrade4d51f6c2020-03-25 10:58:31 +000026#include <android/hardware/power/1.1/IPower.h>
Matt Buckleyc3894a42022-09-01 21:17:15 +000027#include <android/hardware/power/1.2/IPower.h>
28#include <android/hardware/power/1.3/IPower.h>
Xiang Wang99f6f3c2023-05-22 13:12:16 -070029#include <binder/Status.h>
Lais Andrade4d51f6c2020-03-25 10:58:31 +000030
Matt Buckleydb4192a2023-12-21 20:00:32 +000031#include <utility>
32
Lais Andrade4d51f6c2020-03-25 10:58:31 +000033namespace android {
34
Lais Andradeb59a9b52020-05-07 17:23:42 +010035namespace power {
36
Lais Andrade4d51f6c2020-03-25 10:58:31 +000037// State of Power HAL support for individual apis.
Lais Andradeb59a9b52020-05-07 17:23:42 +010038enum class HalSupport {
Lais Andrade4d51f6c2020-03-25 10:58:31 +000039 UNKNOWN = 0,
40 ON = 1,
41 OFF = 2,
42};
43
Jimmy Shiu0b264bb2021-03-03 00:30:50 +080044// Result of a call to the Power HAL wrapper, holding data if successful.
45template <typename T>
46class HalResult {
47public:
Matt Buckleydb4192a2023-12-21 20:00:32 +000048 static HalResult<T> ok(T&& value) { return HalResult(std::forward<T>(value)); }
49 static HalResult<T> ok(T& value) { return HalResult<T>::ok(T{value}); }
50 static HalResult<T> failed(std::string msg) { return HalResult(msg, /* unsupported= */ false); }
Jimmy Shiu0b264bb2021-03-03 00:30:50 +080051 static HalResult<T> unsupported() { return HalResult("", /* unsupported= */ true); }
52
Matt Buckleydb4192a2023-12-21 20:00:32 +000053 static HalResult<T> fromStatus(const binder::Status& status, T&& data) {
Jimmy Shiu0b264bb2021-03-03 00:30:50 +080054 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
55 return HalResult<T>::unsupported();
56 }
57 if (status.isOk()) {
Matt Buckleydb4192a2023-12-21 20:00:32 +000058 return HalResult<T>::ok(std::forward<T>(data));
Jimmy Shiu0b264bb2021-03-03 00:30:50 +080059 }
60 return HalResult<T>::failed(std::string(status.toString8().c_str()));
61 }
Xiang Wang99f6f3c2023-05-22 13:12:16 -070062
Matt Buckleydb4192a2023-12-21 20:00:32 +000063 static HalResult<T> fromStatus(const binder::Status& status, T& data) {
64 return HalResult<T>::fromStatus(status, T{data});
65 }
66
67 static HalResult<T> fromStatus(const ndk::ScopedAStatus& status, T&& data) {
Xiang Wang99f6f3c2023-05-22 13:12:16 -070068 if (status.getExceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
69 return HalResult<T>::unsupported();
70 }
71 if (status.isOk()) {
Matt Buckleydb4192a2023-12-21 20:00:32 +000072 return HalResult<T>::ok(std::forward<T>(data));
Xiang Wang99f6f3c2023-05-22 13:12:16 -070073 }
74 return HalResult<T>::failed(std::string(status.getDescription()));
75 }
Jimmy Shiu0b264bb2021-03-03 00:30:50 +080076
Matt Buckleydb4192a2023-12-21 20:00:32 +000077 static HalResult<T> fromStatus(const ndk::ScopedAStatus& status, T& data) {
78 return HalResult<T>::fromStatus(status, T{data});
79 }
80
Jimmy Shiu0b264bb2021-03-03 00:30:50 +080081 template <typename R>
Matt Buckleydb4192a2023-12-21 20:00:32 +000082 static HalResult<T> fromReturn(hardware::Return<R>& ret, T&& data) {
83 return ret.isOk() ? HalResult<T>::ok(std::forward<T>(data))
84 : HalResult<T>::failed(ret.description());
85 }
86
87 template <typename R>
88 static HalResult<T> fromReturn(hardware::Return<R>& ret, T& data) {
89 return HalResult<T>::fromReturn(ret, T{data});
Xiang Wang99f6f3c2023-05-22 13:12:16 -070090 }
Jimmy Shiu0b264bb2021-03-03 00:30:50 +080091
92 template <typename R>
93 static HalResult<T> fromReturn(hardware::Return<R>& ret, hardware::power::V1_0::Status status,
Matt Buckleydb4192a2023-12-21 20:00:32 +000094 T&& data) {
95 return ret.isOk() ? HalResult<T>::fromStatus(status, std::forward<T>(data))
Xiang Wang99f6f3c2023-05-22 13:12:16 -070096 : HalResult<T>::failed(ret.description());
97 }
Jimmy Shiu0b264bb2021-03-03 00:30:50 +080098
Matt Buckleydb4192a2023-12-21 20:00:32 +000099 template <typename R>
100 static HalResult<T> fromReturn(hardware::Return<R>& ret, hardware::power::V1_0::Status status,
101 T& data) {
102 return HalResult<T>::fromReturn(ret, status, T{data});
103 }
104
Jimmy Shiu0b264bb2021-03-03 00:30:50 +0800105 // This will throw std::bad_optional_access if this result is not ok.
106 const T& value() const { return mValue.value(); }
107 bool isOk() const { return !mUnsupported && mValue.has_value(); }
108 bool isFailed() const { return !mUnsupported && !mValue.has_value(); }
109 bool isUnsupported() const { return mUnsupported; }
110 const char* errorMessage() const { return mErrorMessage.c_str(); }
111
112private:
113 std::optional<T> mValue;
114 std::string mErrorMessage;
115 bool mUnsupported;
116
Matt Buckleydb4192a2023-12-21 20:00:32 +0000117 explicit HalResult(T&& value)
118 : mValue{std::move(value)}, mErrorMessage(), mUnsupported(false) {}
Jimmy Shiu0b264bb2021-03-03 00:30:50 +0800119 explicit HalResult(std::string errorMessage, bool unsupported)
120 : mValue(), mErrorMessage(std::move(errorMessage)), mUnsupported(unsupported) {}
121};
122
123// Empty result of a call to the Power HAL wrapper.
124template <>
125class HalResult<void> {
126public:
127 static HalResult<void> ok() { return HalResult(); }
128 static HalResult<void> failed(std::string msg) { return HalResult(std::move(msg)); }
129 static HalResult<void> unsupported() { return HalResult(/* unsupported= */ true); }
130
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700131 static HalResult<void> fromStatus(const binder::Status& status) {
132 if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
133 return HalResult<void>::unsupported();
134 }
135 if (status.isOk()) {
136 return HalResult<void>::ok();
137 }
138 return HalResult<void>::failed(std::string(status.toString8().c_str()));
139 }
140
141 static HalResult<void> fromStatus(const ndk::ScopedAStatus& status) {
142 if (status.getExceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
143 return HalResult<void>::unsupported();
144 }
145 if (status.isOk()) {
146 return HalResult<void>::ok();
147 }
148 return HalResult<void>::failed(std::string(status.getDescription()));
149 }
Jimmy Shiu0b264bb2021-03-03 00:30:50 +0800150
151 template <typename R>
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700152 static HalResult<void> fromReturn(hardware::Return<R>& ret) {
153 return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
154 }
Jimmy Shiu0b264bb2021-03-03 00:30:50 +0800155
156 bool isOk() const { return !mUnsupported && !mFailed; }
157 bool isFailed() const { return !mUnsupported && mFailed; }
158 bool isUnsupported() const { return mUnsupported; }
159 const char* errorMessage() const { return mErrorMessage.c_str(); }
160
161private:
162 std::string mErrorMessage;
163 bool mFailed;
164 bool mUnsupported;
165
166 explicit HalResult(bool unsupported = false)
167 : mErrorMessage(), mFailed(false), mUnsupported(unsupported) {}
168 explicit HalResult(std::string errorMessage)
169 : mErrorMessage(std::move(errorMessage)), mFailed(true), mUnsupported(false) {}
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000170};
171
172// Wrapper for Power HAL handlers.
Lais Andradeb59a9b52020-05-07 17:23:42 +0100173class HalWrapper {
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000174public:
Lais Andradeb59a9b52020-05-07 17:23:42 +0100175 virtual ~HalWrapper() = default;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000176
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700177 virtual HalResult<void> setBoost(aidl::android::hardware::power::Boost boost,
178 int32_t durationMs) = 0;
179 virtual HalResult<void> setMode(aidl::android::hardware::power::Mode mode, bool enabled) = 0;
180 virtual HalResult<std::shared_ptr<aidl::android::hardware::power::IPowerHintSession>>
181 createHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
182 int64_t durationNanos) = 0;
Matt Buckleydb4192a2023-12-21 20:00:32 +0000183 virtual HalResult<std::shared_ptr<aidl::android::hardware::power::IPowerHintSession>>
184 createHintSessionWithConfig(int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
185 int64_t durationNanos,
186 aidl::android::hardware::power::SessionTag tag,
187 aidl::android::hardware::power::SessionConfig* config) = 0;
Jimmy Shiu0b264bb2021-03-03 00:30:50 +0800188 virtual HalResult<int64_t> getHintSessionPreferredRate() = 0;
Matt Buckleydb4192a2023-12-21 20:00:32 +0000189 virtual HalResult<aidl::android::hardware::power::ChannelConfig> getSessionChannel(int tgid,
190 int uid) = 0;
191 virtual HalResult<void> closeSessionChannel(int tgid, int uid) = 0;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000192};
193
194// Empty Power HAL wrapper that ignores all api calls.
Lais Andradeb59a9b52020-05-07 17:23:42 +0100195class EmptyHalWrapper : public HalWrapper {
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000196public:
Lais Andradeb59a9b52020-05-07 17:23:42 +0100197 EmptyHalWrapper() = default;
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700198 ~EmptyHalWrapper() override = default;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000199
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700200 HalResult<void> setBoost(aidl::android::hardware::power::Boost boost,
201 int32_t durationMs) override;
202 HalResult<void> setMode(aidl::android::hardware::power::Mode mode, bool enabled) override;
203 HalResult<std::shared_ptr<aidl::android::hardware::power::IPowerHintSession>> createHintSession(
Jimmy Shiu0b264bb2021-03-03 00:30:50 +0800204 int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
205 int64_t durationNanos) override;
Matt Buckleydb4192a2023-12-21 20:00:32 +0000206 HalResult<std::shared_ptr<aidl::android::hardware::power::IPowerHintSession>>
207 createHintSessionWithConfig(int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
208 int64_t durationNanos,
209 aidl::android::hardware::power::SessionTag tag,
210 aidl::android::hardware::power::SessionConfig* config) override;
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700211 HalResult<int64_t> getHintSessionPreferredRate() override;
Matt Buckleydb4192a2023-12-21 20:00:32 +0000212 HalResult<aidl::android::hardware::power::ChannelConfig> getSessionChannel(int tgid,
213 int uid) override;
214 HalResult<void> closeSessionChannel(int tgid, int uid) override;
215
216protected:
217 virtual const char* getUnsupportedMessage();
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000218};
219
220// Wrapper for the HIDL Power HAL v1.0.
Matt Buckleydb4192a2023-12-21 20:00:32 +0000221class HidlHalWrapperV1_0 : public EmptyHalWrapper {
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000222public:
Matt Buckleyc3894a42022-09-01 21:17:15 +0000223 explicit HidlHalWrapperV1_0(sp<hardware::power::V1_0::IPower> handleV1_0)
224 : mHandleV1_0(std::move(handleV1_0)) {}
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700225 ~HidlHalWrapperV1_0() override = default;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000226
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700227 HalResult<void> setBoost(aidl::android::hardware::power::Boost boost,
228 int32_t durationMs) override;
229 HalResult<void> setMode(aidl::android::hardware::power::Mode mode, bool enabled) override;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000230
231protected:
Matt Buckleyc3894a42022-09-01 21:17:15 +0000232 const sp<hardware::power::V1_0::IPower> mHandleV1_0;
233 virtual HalResult<void> sendPowerHint(hardware::power::V1_3::PowerHint hintId, uint32_t data);
Matt Buckleydb4192a2023-12-21 20:00:32 +0000234 const char* getUnsupportedMessage();
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000235
236private:
Jimmy Shiu0b264bb2021-03-03 00:30:50 +0800237 HalResult<void> setInteractive(bool enabled);
238 HalResult<void> setFeature(hardware::power::V1_0::Feature feature, bool enabled);
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000239};
240
241// Wrapper for the HIDL Power HAL v1.1.
Lais Andradeb59a9b52020-05-07 17:23:42 +0100242class HidlHalWrapperV1_1 : public HidlHalWrapperV1_0 {
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000243public:
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700244 explicit HidlHalWrapperV1_1(sp<hardware::power::V1_1::IPower> handleV1_1)
Matt Buckleyc3894a42022-09-01 21:17:15 +0000245 : HidlHalWrapperV1_0(std::move(handleV1_1)) {}
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700246 ~HidlHalWrapperV1_1() override = default;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000247
248protected:
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700249 HalResult<void> sendPowerHint(hardware::power::V1_3::PowerHint hintId, uint32_t data) override;
Matt Buckleyc3894a42022-09-01 21:17:15 +0000250};
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000251
Matt Buckleyc3894a42022-09-01 21:17:15 +0000252// Wrapper for the HIDL Power HAL v1.2.
253class HidlHalWrapperV1_2 : public HidlHalWrapperV1_1 {
254public:
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700255 HalResult<void> setBoost(aidl::android::hardware::power::Boost boost,
256 int32_t durationMs) override;
257 HalResult<void> setMode(aidl::android::hardware::power::Mode mode, bool enabled) override;
258 explicit HidlHalWrapperV1_2(sp<hardware::power::V1_2::IPower> handleV1_2)
Matt Buckleyc3894a42022-09-01 21:17:15 +0000259 : HidlHalWrapperV1_1(std::move(handleV1_2)) {}
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700260 ~HidlHalWrapperV1_2() override = default;
Matt Buckleyc3894a42022-09-01 21:17:15 +0000261
262protected:
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700263 HalResult<void> sendPowerHint(hardware::power::V1_3::PowerHint hintId, uint32_t data) override;
Matt Buckleyc3894a42022-09-01 21:17:15 +0000264};
265
266// Wrapper for the HIDL Power HAL v1.3.
267class HidlHalWrapperV1_3 : public HidlHalWrapperV1_2 {
268public:
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700269 HalResult<void> setMode(aidl::android::hardware::power::Mode mode, bool enabled) override;
270 explicit HidlHalWrapperV1_3(sp<hardware::power::V1_3::IPower> handleV1_3)
Matt Buckleyc3894a42022-09-01 21:17:15 +0000271 : HidlHalWrapperV1_2(std::move(handleV1_3)) {}
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700272 ~HidlHalWrapperV1_3() override = default;
Matt Buckleyc3894a42022-09-01 21:17:15 +0000273
274protected:
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700275 HalResult<void> sendPowerHint(hardware::power::V1_3::PowerHint hintId, uint32_t data) override;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000276};
277
278// Wrapper for the AIDL Power HAL.
Matt Buckleydb4192a2023-12-21 20:00:32 +0000279class AidlHalWrapper : public EmptyHalWrapper {
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000280public:
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700281 explicit AidlHalWrapper(std::shared_ptr<aidl::android::hardware::power::IPower> handle)
282 : mHandle(std::move(handle)) {}
283 ~AidlHalWrapper() override = default;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000284
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700285 HalResult<void> setBoost(aidl::android::hardware::power::Boost boost,
286 int32_t durationMs) override;
287 HalResult<void> setMode(aidl::android::hardware::power::Mode mode, bool enabled) override;
288 HalResult<std::shared_ptr<aidl::android::hardware::power::IPowerHintSession>> createHintSession(
Jimmy Shiu0b264bb2021-03-03 00:30:50 +0800289 int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
290 int64_t durationNanos) override;
Matt Buckleydb4192a2023-12-21 20:00:32 +0000291 HalResult<std::shared_ptr<aidl::android::hardware::power::IPowerHintSession>>
292 createHintSessionWithConfig(int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
293 int64_t durationNanos,
294 aidl::android::hardware::power::SessionTag tag,
295 aidl::android::hardware::power::SessionConfig* config) override;
296
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700297 HalResult<int64_t> getHintSessionPreferredRate() override;
Matt Buckleydb4192a2023-12-21 20:00:32 +0000298 HalResult<aidl::android::hardware::power::ChannelConfig> getSessionChannel(int tgid,
299 int uid) override;
300 HalResult<void> closeSessionChannel(int tgid, int uid) override;
301
302protected:
303 const char* getUnsupportedMessage() override;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000304
305private:
306 // Control access to the boost and mode supported arrays.
307 std::mutex mBoostMutex;
308 std::mutex mModeMutex;
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700309 std::shared_ptr<aidl::android::hardware::power::IPower> mHandle;
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000310 // Android framework only sends boost upto DISPLAY_UPDATE_IMMINENT.
311 // Need to increase the array size if more boost supported.
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700312 std::array<
313 std::atomic<HalSupport>,
314 static_cast<int32_t>(aidl::android::hardware::power::Boost::DISPLAY_UPDATE_IMMINENT) +
315 1>
Lais Andradeb59a9b52020-05-07 17:23:42 +0100316 mBoostSupportedArray GUARDED_BY(mBoostMutex) = {HalSupport::UNKNOWN};
Lais Andradeb59a9b52020-05-07 17:23:42 +0100317 std::array<std::atomic<HalSupport>,
Xiang Wang99f6f3c2023-05-22 13:12:16 -0700318 static_cast<int32_t>(
319 *(ndk::enum_range<aidl::android::hardware::power::Mode>().end() - 1)) +
320 1>
Lais Andradeb59a9b52020-05-07 17:23:42 +0100321 mModeSupportedArray GUARDED_BY(mModeMutex) = {HalSupport::UNKNOWN};
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000322};
323
Lais Andradeb59a9b52020-05-07 17:23:42 +0100324}; // namespace power
325
Lais Andrade4d51f6c2020-03-25 10:58:31 +0000326}; // namespace android