• 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 #define LOG_TAG "HalWrapper"
18 #include <android/hardware/power/Boost.h>
19 #include <android/hardware/power/IPowerHintSession.h>
20 #include <android/hardware/power/Mode.h>
21 #include <powermanager/PowerHalWrapper.h>
22 #include <utils/Log.h>
23 
24 #include <cinttypes>
25 
26 using namespace android::hardware::power;
27 namespace V1_0 = android::hardware::power::V1_0;
28 namespace V1_1 = android::hardware::power::V1_1;
29 namespace Aidl = android::hardware::power;
30 
31 namespace android {
32 
33 namespace power {
34 
35 // -------------------------------------------------------------------------------------------------
36 
toHalResult(const binder::Status & result)37 inline HalResult<void> toHalResult(const binder::Status& result) {
38     if (result.isOk()) {
39         return HalResult<void>::ok();
40     }
41     ALOGE("Power HAL request failed: %s", result.toString8().c_str());
42     return HalResult<void>::fromStatus(result);
43 }
44 
45 template <typename T>
46 template <typename R>
fromReturn(hardware::Return<R> & ret,T data)47 HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, T data) {
48     return ret.isOk() ? HalResult<T>::ok(data) : HalResult<T>::failed(ret.description());
49 }
50 
51 template <typename T>
52 template <typename R>
fromReturn(hardware::Return<R> & ret,V1_0::Status status,T data)53 HalResult<T> HalResult<T>::fromReturn(hardware::Return<R>& ret, V1_0::Status status, T data) {
54     return ret.isOk() ? HalResult<T>::fromStatus(status, data)
55                       : HalResult<T>::failed(ret.description());
56 }
57 
58 // -------------------------------------------------------------------------------------------------
59 
fromStatus(status_t status)60 HalResult<void> HalResult<void>::fromStatus(status_t status) {
61     if (status == android::OK) {
62         return HalResult<void>::ok();
63     }
64     return HalResult<void>::failed(statusToString(status));
65 }
66 
fromStatus(binder::Status status)67 HalResult<void> HalResult<void>::fromStatus(binder::Status status) {
68     if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
69         return HalResult<void>::unsupported();
70     }
71     if (status.isOk()) {
72         return HalResult<void>::ok();
73     }
74     return HalResult<void>::failed(std::string(status.toString8().c_str()));
75 }
76 
77 template <typename R>
fromReturn(hardware::Return<R> & ret)78 HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {
79     return ret.isOk() ? HalResult<void>::ok() : HalResult<void>::failed(ret.description());
80 }
81 // -------------------------------------------------------------------------------------------------
82 
setBoost(Boost boost,int32_t durationMs)83 HalResult<void> EmptyHalWrapper::setBoost(Boost boost, int32_t durationMs) {
84     ALOGV("Skipped setBoost %s with duration %dms because Power HAL not available",
85           toString(boost).c_str(), durationMs);
86     return HalResult<void>::unsupported();
87 }
88 
setMode(Mode mode,bool enabled)89 HalResult<void> EmptyHalWrapper::setMode(Mode mode, bool enabled) {
90     ALOGV("Skipped setMode %s to %s because Power HAL not available", toString(mode).c_str(),
91           enabled ? "true" : "false");
92     return HalResult<void>::unsupported();
93 }
94 
createHintSession(int32_t,int32_t,const std::vector<int32_t> & threadIds,int64_t)95 HalResult<sp<Aidl::IPowerHintSession>> EmptyHalWrapper::createHintSession(
96         int32_t, int32_t, const std::vector<int32_t>& threadIds, int64_t) {
97     ALOGV("Skipped createHintSession(task num=%zu) because Power HAL not available",
98           threadIds.size());
99     return HalResult<sp<Aidl::IPowerHintSession>>::unsupported();
100 }
101 
getHintSessionPreferredRate()102 HalResult<int64_t> EmptyHalWrapper::getHintSessionPreferredRate() {
103     ALOGV("Skipped getHintSessionPreferredRate because Power HAL not available");
104     return HalResult<int64_t>::unsupported();
105 }
106 
107 // -------------------------------------------------------------------------------------------------
108 
setBoost(Boost boost,int32_t durationMs)109 HalResult<void> HidlHalWrapperV1_0::setBoost(Boost boost, int32_t durationMs) {
110     if (boost == Boost::INTERACTION) {
111         return sendPowerHint(V1_0::PowerHint::INTERACTION, durationMs);
112     } else {
113         ALOGV("Skipped setBoost %s because Power HAL AIDL not available", toString(boost).c_str());
114         return HalResult<void>::unsupported();
115     }
116 }
117 
setMode(Mode mode,bool enabled)118 HalResult<void> HidlHalWrapperV1_0::setMode(Mode mode, bool enabled) {
119     uint32_t data = enabled ? 1 : 0;
120     switch (mode) {
121         case Mode::LAUNCH:
122             return sendPowerHint(V1_0::PowerHint::LAUNCH, data);
123         case Mode::LOW_POWER:
124             return sendPowerHint(V1_0::PowerHint::LOW_POWER, data);
125         case Mode::SUSTAINED_PERFORMANCE:
126             return sendPowerHint(V1_0::PowerHint::SUSTAINED_PERFORMANCE, data);
127         case Mode::VR:
128             return sendPowerHint(V1_0::PowerHint::VR_MODE, data);
129         case Mode::INTERACTIVE:
130             return setInteractive(enabled);
131         case Mode::DOUBLE_TAP_TO_WAKE:
132             return setFeature(V1_0::Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE, enabled);
133         default:
134             ALOGV("Skipped setMode %s because Power HAL AIDL not available",
135                   toString(mode).c_str());
136             return HalResult<void>::unsupported();
137     }
138 }
139 
sendPowerHint(V1_0::PowerHint hintId,uint32_t data)140 HalResult<void> HidlHalWrapperV1_0::sendPowerHint(V1_0::PowerHint hintId, uint32_t data) {
141     auto ret = mHandleV1_0->powerHint(hintId, data);
142     return HalResult<void>::fromReturn(ret);
143 }
144 
setInteractive(bool enabled)145 HalResult<void> HidlHalWrapperV1_0::setInteractive(bool enabled) {
146     auto ret = mHandleV1_0->setInteractive(enabled);
147     return HalResult<void>::fromReturn(ret);
148 }
149 
setFeature(V1_0::Feature feature,bool enabled)150 HalResult<void> HidlHalWrapperV1_0::setFeature(V1_0::Feature feature, bool enabled) {
151     auto ret = mHandleV1_0->setFeature(feature, enabled);
152     return HalResult<void>::fromReturn(ret);
153 }
154 
createHintSession(int32_t,int32_t,const std::vector<int32_t> & threadIds,int64_t)155 HalResult<sp<Aidl::IPowerHintSession>> HidlHalWrapperV1_0::createHintSession(
156         int32_t, int32_t, const std::vector<int32_t>& threadIds, int64_t) {
157     ALOGV("Skipped createHintSession(task num=%zu) because Power HAL not available",
158           threadIds.size());
159     return HalResult<sp<Aidl::IPowerHintSession>>::unsupported();
160 }
161 
getHintSessionPreferredRate()162 HalResult<int64_t> HidlHalWrapperV1_0::getHintSessionPreferredRate() {
163     ALOGV("Skipped getHintSessionPreferredRate because Power HAL not available");
164     return HalResult<int64_t>::unsupported();
165 }
166 
167 // -------------------------------------------------------------------------------------------------
168 
sendPowerHint(V1_0::PowerHint hintId,uint32_t data)169 HalResult<void> HidlHalWrapperV1_1::sendPowerHint(V1_0::PowerHint hintId, uint32_t data) {
170     auto ret = mHandleV1_1->powerHintAsync(hintId, data);
171     return HalResult<void>::fromReturn(ret);
172 }
173 
174 // -------------------------------------------------------------------------------------------------
175 
setBoost(Boost boost,int32_t durationMs)176 HalResult<void> AidlHalWrapper::setBoost(Boost boost, int32_t durationMs) {
177     std::unique_lock<std::mutex> lock(mBoostMutex);
178     size_t idx = static_cast<size_t>(boost);
179 
180     // Quick return if boost is not supported by HAL
181     if (idx >= mBoostSupportedArray.size() || mBoostSupportedArray[idx] == HalSupport::OFF) {
182         ALOGV("Skipped setBoost %s because Power HAL doesn't support it", toString(boost).c_str());
183         return HalResult<void>::unsupported();
184     }
185 
186     if (mBoostSupportedArray[idx] == HalSupport::UNKNOWN) {
187         bool isSupported = false;
188         auto isSupportedRet = mHandle->isBoostSupported(boost, &isSupported);
189         if (!isSupportedRet.isOk()) {
190             ALOGE("Skipped setBoost %s because check support failed with: %s",
191                   toString(boost).c_str(), isSupportedRet.toString8().c_str());
192             // return HalResult::FAILED;
193             return HalResult<void>::fromStatus(isSupportedRet);
194         }
195 
196         mBoostSupportedArray[idx] = isSupported ? HalSupport::ON : HalSupport::OFF;
197         if (!isSupported) {
198             ALOGV("Skipped setBoost %s because Power HAL doesn't support it",
199                   toString(boost).c_str());
200             return HalResult<void>::unsupported();
201         }
202     }
203     lock.unlock();
204 
205     return toHalResult(mHandle->setBoost(boost, durationMs));
206 }
207 
setMode(Mode mode,bool enabled)208 HalResult<void> AidlHalWrapper::setMode(Mode mode, bool enabled) {
209     std::unique_lock<std::mutex> lock(mModeMutex);
210     size_t idx = static_cast<size_t>(mode);
211 
212     // Quick return if mode is not supported by HAL
213     if (idx >= mModeSupportedArray.size() || mModeSupportedArray[idx] == HalSupport::OFF) {
214         ALOGV("Skipped setMode %s because Power HAL doesn't support it", toString(mode).c_str());
215         return HalResult<void>::unsupported();
216     }
217 
218     if (mModeSupportedArray[idx] == HalSupport::UNKNOWN) {
219         bool isSupported = false;
220         auto isSupportedRet = mHandle->isModeSupported(mode, &isSupported);
221         if (!isSupportedRet.isOk()) {
222             return HalResult<void>::failed(isSupportedRet.toString8().c_str());
223         }
224 
225         mModeSupportedArray[idx] = isSupported ? HalSupport::ON : HalSupport::OFF;
226         if (!isSupported) {
227             ALOGV("Skipped setMode %s because Power HAL doesn't support it",
228                   toString(mode).c_str());
229             return HalResult<void>::unsupported();
230         }
231     }
232     lock.unlock();
233 
234     return toHalResult(mHandle->setMode(mode, enabled));
235 }
236 
createHintSession(int32_t tgid,int32_t uid,const std::vector<int32_t> & threadIds,int64_t durationNanos)237 HalResult<sp<Aidl::IPowerHintSession>> AidlHalWrapper::createHintSession(
238         int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds, int64_t durationNanos) {
239     sp<IPowerHintSession> appSession;
240     return HalResult<sp<Aidl::IPowerHintSession>>::
241             fromStatus(mHandle->createHintSession(tgid, uid, threadIds, durationNanos, &appSession),
242                        appSession);
243 }
244 
getHintSessionPreferredRate()245 HalResult<int64_t> AidlHalWrapper::getHintSessionPreferredRate() {
246     int64_t rate = -1;
247     auto result = mHandle->getHintSessionPreferredRate(&rate);
248     return HalResult<int64_t>::fromStatus(result, rate);
249 }
250 
251 // -------------------------------------------------------------------------------------------------
252 
253 } // namespace power
254 
255 } // namespace android
256