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