• 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 ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
18 #define LOG_TAG "powerhal-libperfmgr"
19 
20 #include "Power.h"
21 
22 #include <android-base/file.h>
23 #include <android-base/logging.h>
24 #include <android-base/properties.h>
25 #include <android-base/strings.h>
26 #include <fmq/AidlMessageQueue.h>
27 #include <fmq/EventFlag.h>
28 #include <perfmgr/HintManager.h>
29 #include <utils/Log.h>
30 #include <utils/Trace.h>
31 
32 #include <cstdint>
33 #include <memory>
34 #include <optional>
35 
36 #include "AdpfTypes.h"
37 #include "ChannelManager.h"
38 #include "PowerHintSession.h"
39 #include "PowerSessionManager.h"
40 #include "SupportManager.h"
41 #include "disp-power/DisplayLowPower.h"
42 
43 namespace aidl {
44 namespace google {
45 namespace hardware {
46 namespace power {
47 namespace impl {
48 namespace pixel {
49 using ::android::perfmgr::HintManager;
50 
51 constexpr char kPowerHalStateProp[] = "vendor.powerhal.state";
52 constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio";
53 constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering";
54 
Power(std::shared_ptr<DisplayLowPower> dlpw)55 Power::Power(std::shared_ptr<DisplayLowPower> dlpw)
56     : mDisplayLowPower(dlpw),
57       mInteractionHandler(nullptr),
58       mVRModeOn(false),
59       mSustainedPerfModeOn(false) {
60     mInteractionHandler = std::make_unique<InteractionHandler>();
61     mInteractionHandler->Init();
62 
63     std::string state = ::android::base::GetProperty(kPowerHalStateProp, "");
64     if (state == "SUSTAINED_PERFORMANCE") {
65         LOG(INFO) << "Initialize with SUSTAINED_PERFORMANCE on";
66         HintManager::GetInstance()->DoHint("SUSTAINED_PERFORMANCE");
67         mSustainedPerfModeOn = true;
68     } else if (state == "VR") {
69         LOG(INFO) << "Initialize with VR on";
70         HintManager::GetInstance()->DoHint(state);
71         mVRModeOn = true;
72     } else if (state == "VR_SUSTAINED_PERFORMANCE") {
73         LOG(INFO) << "Initialize with SUSTAINED_PERFORMANCE and VR on";
74         HintManager::GetInstance()->DoHint("VR_SUSTAINED_PERFORMANCE");
75         mSustainedPerfModeOn = true;
76         mVRModeOn = true;
77     } else {
78         LOG(INFO) << "Initialize PowerHAL";
79     }
80 
81     state = ::android::base::GetProperty(kPowerHalAudioProp, "");
82     if (state == "AUDIO_STREAMING_LOW_LATENCY") {
83         LOG(INFO) << "Initialize with AUDIO_LOW_LATENCY on";
84         HintManager::GetInstance()->DoHint(state);
85     }
86 
87     state = ::android::base::GetProperty(kPowerHalRenderingProp, "");
88     if (state == "EXPENSIVE_RENDERING") {
89         LOG(INFO) << "Initialize with EXPENSIVE_RENDERING on";
90         HintManager::GetInstance()->DoHint("EXPENSIVE_RENDERING");
91     }
92 
93     auto status = this->getInterfaceVersion(&mServiceVersion);
94     LOG(INFO) << "PowerHAL InterfaceVersion:" << mServiceVersion << " isOK: " << status.isOk();
95 
96     mSupportInfo = SupportManager::makeSupportInfo();
97 }
98 
setMode(Mode type,bool enabled)99 ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
100     LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled;
101     ATRACE_NAME(("M:" + toString(type) + ":" + (enabled ? "on" : "off")).c_str());
102     if (HintManager::GetInstance()->IsAdpfSupported()) {
103         PowerSessionManager<>::getInstance()->updateHintMode(toString(type), enabled);
104     }
105     switch (type) {
106         case Mode::LOW_POWER:
107             mDisplayLowPower->SetDisplayLowPower(enabled);
108             if (enabled) {
109                 HintManager::GetInstance()->DoHint(toString(type));
110             } else {
111                 HintManager::GetInstance()->EndHint(toString(type));
112             }
113             break;
114         case Mode::SUSTAINED_PERFORMANCE:
115             if (enabled && !mSustainedPerfModeOn) {
116                 if (!mVRModeOn) {  // Sustained mode only.
117                     HintManager::GetInstance()->DoHint("SUSTAINED_PERFORMANCE");
118                 } else {  // Sustained + VR mode.
119                     HintManager::GetInstance()->EndHint("VR");
120                     HintManager::GetInstance()->DoHint("VR_SUSTAINED_PERFORMANCE");
121                 }
122                 mSustainedPerfModeOn = true;
123             } else if (!enabled && mSustainedPerfModeOn) {
124                 HintManager::GetInstance()->EndHint("VR_SUSTAINED_PERFORMANCE");
125                 HintManager::GetInstance()->EndHint("SUSTAINED_PERFORMANCE");
126                 if (mVRModeOn) {  // Switch back to VR Mode.
127                     HintManager::GetInstance()->DoHint("VR");
128                 }
129                 mSustainedPerfModeOn = false;
130             }
131             break;
132         case Mode::VR:
133             if (enabled && !mVRModeOn) {
134                 if (!mSustainedPerfModeOn) {  // VR mode only.
135                     HintManager::GetInstance()->DoHint("VR");
136                 } else {  // Sustained + VR mode.
137                     HintManager::GetInstance()->EndHint("SUSTAINED_PERFORMANCE");
138                     HintManager::GetInstance()->DoHint("VR_SUSTAINED_PERFORMANCE");
139                 }
140                 mVRModeOn = true;
141             } else if (!enabled && mVRModeOn) {
142                 HintManager::GetInstance()->EndHint("VR_SUSTAINED_PERFORMANCE");
143                 HintManager::GetInstance()->EndHint("VR");
144                 if (mSustainedPerfModeOn) {  // Switch back to sustained Mode.
145                     HintManager::GetInstance()->DoHint("SUSTAINED_PERFORMANCE");
146                 }
147                 mVRModeOn = false;
148             }
149             break;
150         case Mode::LAUNCH:
151             if (mVRModeOn || mSustainedPerfModeOn) {
152                 break;
153             }
154             [[fallthrough]];
155         case Mode::DOUBLE_TAP_TO_WAKE:
156             [[fallthrough]];
157         case Mode::FIXED_PERFORMANCE:
158             [[fallthrough]];
159         case Mode::EXPENSIVE_RENDERING:
160             [[fallthrough]];
161         case Mode::INTERACTIVE:
162             [[fallthrough]];
163         case Mode::DEVICE_IDLE:
164             [[fallthrough]];
165         case Mode::DISPLAY_INACTIVE:
166             [[fallthrough]];
167         case Mode::AUDIO_STREAMING_LOW_LATENCY:
168             [[fallthrough]];
169         case Mode::CAMERA_STREAMING_SECURE:
170             [[fallthrough]];
171         case Mode::CAMERA_STREAMING_LOW:
172             [[fallthrough]];
173         case Mode::CAMERA_STREAMING_MID:
174             [[fallthrough]];
175         case Mode::CAMERA_STREAMING_HIGH:
176             [[fallthrough]];
177         case Mode::GAME_LOADING:
178             [[fallthrough]];
179         default:
180             if (enabled) {
181                 HintManager::GetInstance()->DoHint(toString(type));
182             } else {
183                 HintManager::GetInstance()->EndHint(toString(type));
184             }
185             break;
186     }
187 
188     return ndk::ScopedAStatus::ok();
189 }
190 
isModeSupported(Mode type,bool * _aidl_return)191 ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) {
192     bool supported = supportFromBitset(mSupportInfo.modes, type);
193     LOG(INFO) << "Power Mode " << toString(type) << " isModeSupported: " << supported;
194     *_aidl_return = supported;
195     return ndk::ScopedAStatus::ok();
196 }
197 
setBoost(Boost type,int32_t durationMs)198 ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
199     LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs;
200     ATRACE_NAME(("B:" + toString(type) + ":" + std::to_string(durationMs)).c_str());
201     switch (type) {
202         case Boost::INTERACTION:
203             if (mVRModeOn || mSustainedPerfModeOn) {
204                 break;
205             }
206             mInteractionHandler->Acquire(durationMs);
207             break;
208         case Boost::DISPLAY_UPDATE_IMMINENT:
209             [[fallthrough]];
210         case Boost::ML_ACC:
211             [[fallthrough]];
212         case Boost::AUDIO_LAUNCH:
213             [[fallthrough]];
214         case Boost::CAMERA_LAUNCH:
215             [[fallthrough]];
216         case Boost::CAMERA_SHOT:
217             [[fallthrough]];
218         default:
219             if (mVRModeOn || mSustainedPerfModeOn) {
220                 break;
221             }
222             if (durationMs > 0) {
223                 HintManager::GetInstance()->DoHint(toString(type),
224                                                    std::chrono::milliseconds(durationMs));
225             } else if (durationMs == 0) {
226                 HintManager::GetInstance()->DoHint(toString(type));
227             } else {
228                 HintManager::GetInstance()->EndHint(toString(type));
229             }
230             break;
231     }
232 
233     return ndk::ScopedAStatus::ok();
234 }
235 
isBoostSupported(Boost type,bool * _aidl_return)236 ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool *_aidl_return) {
237     bool supported = supportFromBitset(mSupportInfo.boosts, type);
238     LOG(INFO) << "Power oost " << toString(type) << " isBoostSupported: " << supported;
239     *_aidl_return = supported;
240     return ndk::ScopedAStatus::ok();
241 }
242 
boolToString(bool b)243 constexpr const char *boolToString(bool b) {
244     return b ? "true" : "false";
245 }
246 
dump(int fd,const char **,uint32_t)247 binder_status_t Power::dump(int fd, const char **, uint32_t) {
248     std::string buf(::android::base::StringPrintf(
249             "HintManager Running: %s\n"
250             "VRMode: %s\n"
251             "SustainedPerformanceMode: %s\n",
252             boolToString(HintManager::GetInstance()->IsRunning()), boolToString(mVRModeOn),
253             boolToString(mSustainedPerfModeOn)));
254     // Dump nodes through libperfmgr
255     HintManager::GetInstance()->DumpToFd(fd);
256     PowerSessionManager<>::getInstance()->dumpToFd(fd);
257     if (!::android::base::WriteStringToFd(buf, fd)) {
258         PLOG(ERROR) << "Failed to dump state to fd";
259     }
260     fsync(fd);
261     return STATUS_OK;
262 }
263 
getCpuHeadroom(const CpuHeadroomParams & _,CpuHeadroomResult *)264 ndk::ScopedAStatus Power::getCpuHeadroom(const CpuHeadroomParams &_, CpuHeadroomResult *) {
265     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
266 }
267 
getGpuHeadroom(const GpuHeadroomParams & _,GpuHeadroomResult *)268 ndk::ScopedAStatus Power::getGpuHeadroom(const GpuHeadroomParams &_, GpuHeadroomResult *) {
269     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
270 }
271 
createHintSession(int32_t tgid,int32_t uid,const std::vector<int32_t> & threadIds,int64_t durationNanos,std::shared_ptr<IPowerHintSession> * _aidl_return)272 ndk::ScopedAStatus Power::createHintSession(int32_t tgid, int32_t uid,
273                                             const std::vector<int32_t> &threadIds,
274                                             int64_t durationNanos,
275                                             std::shared_ptr<IPowerHintSession> *_aidl_return) {
276     SessionConfig config;
277     return createHintSessionWithConfig(tgid, uid, threadIds, durationNanos, SessionTag::OTHER,
278                                        &config, _aidl_return);
279 }
280 
getHintSessionPreferredRate(int64_t * outNanoseconds)281 ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t *outNanoseconds) {
282     *outNanoseconds = HintManager::GetInstance()->IsAdpfSupported()
283                               ? HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs
284                               : 0;
285     if (*outNanoseconds <= 0) {
286         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
287     }
288 
289     return ndk::ScopedAStatus::ok();
290 }
291 
createHintSessionWithConfig(int32_t tgid,int32_t uid,const std::vector<int32_t> & threadIds,int64_t durationNanos,SessionTag tag,SessionConfig * config,std::shared_ptr<IPowerHintSession> * _aidl_return)292 ndk::ScopedAStatus Power::createHintSessionWithConfig(
293         int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds, int64_t durationNanos,
294         SessionTag tag, SessionConfig *config, std::shared_ptr<IPowerHintSession> *_aidl_return) {
295     if (!HintManager::GetInstance()->IsAdpfSupported()) {
296         *_aidl_return = nullptr;
297         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
298     }
299     if (threadIds.size() == 0) {
300         LOG(ERROR) << "Error: threadIds.size() shouldn't be " << threadIds.size();
301         *_aidl_return = nullptr;
302         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
303     }
304     std::shared_ptr<PowerHintSession<>> session =
305             ndk::SharedRefBase::make<PowerHintSession<>>(tgid, uid, threadIds, durationNanos, tag);
306 
307     *_aidl_return = session;
308     session->getSessionConfig(config);
309     PowerSessionManager<>::getInstance()->registerSession(session, config->id);
310 
311     return ndk::ScopedAStatus::ok();
312 }
313 
getSessionChannel(int32_t tgid,int32_t uid,ChannelConfig * _aidl_return)314 ndk::ScopedAStatus Power::getSessionChannel(int32_t tgid, int32_t uid,
315                                             ChannelConfig *_aidl_return) {
316     if (ChannelManager<>::getInstance()->getChannelConfig(tgid, uid, _aidl_return)) {
317         return ndk::ScopedAStatus::ok();
318     }
319     return ndk::ScopedAStatus::fromStatus(EX_ILLEGAL_STATE);
320 }
321 
closeSessionChannel(int32_t tgid,int32_t uid)322 ndk::ScopedAStatus Power::closeSessionChannel(int32_t tgid, int32_t uid) {
323     ChannelManager<>::getInstance()->closeChannel(tgid, uid);
324     return ndk::ScopedAStatus::ok();
325 }
326 
getSupportInfo(SupportInfo * _aidl_return)327 ndk::ScopedAStatus Power::getSupportInfo(SupportInfo *_aidl_return) {
328     // Copy the support object into the binder
329     *_aidl_return = mSupportInfo;
330     return ndk::ScopedAStatus::ok();
331 }
332 
sendCompositionData(const std::vector<CompositionData> &)333 ndk::ScopedAStatus Power::sendCompositionData(const std::vector<CompositionData> &) {
334     LOG(INFO) << "Composition data received!";
335     return ndk::ScopedAStatus::ok();
336 }
337 
sendCompositionUpdate(const CompositionUpdate &)338 ndk::ScopedAStatus Power::sendCompositionUpdate(const CompositionUpdate &) {
339     LOG(INFO) << "Composition update received!";
340     return ndk::ScopedAStatus::ok();
341 }
342 
343 }  // namespace pixel
344 }  // namespace impl
345 }  // namespace power
346 }  // namespace hardware
347 }  // namespace google
348 }  // namespace aidl
349