1 /*
2 * Copyright 2021 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 "powerhal-libperfmgr"
18 #define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
19
20 #include <log/log.h>
21 #include <processgroup/processgroup.h>
22 #include <utils/Trace.h>
23
24 #include "PowerSessionManager.h"
25
26 namespace aidl {
27 namespace google {
28 namespace hardware {
29 namespace power {
30 namespace impl {
31 namespace pixel {
32
setHintManager(std::shared_ptr<HintManager> const & hint_manager)33 void PowerSessionManager::setHintManager(std::shared_ptr<HintManager> const &hint_manager) {
34 // Only initialize hintmanager instance if hint is supported.
35 if (hint_manager->IsHintSupported(kDisableBoostHintName)) {
36 mHintManager = hint_manager;
37 }
38 }
39
updateHintMode(const std::string & mode,bool enabled)40 void PowerSessionManager::updateHintMode(const std::string &mode, bool enabled) {
41 ALOGV("PowerSessionManager::updateHintMode: mode: %s, enabled: %d", mode.c_str(), enabled);
42 if (enabled && mode.compare(0, 8, "REFRESH_") == 0) {
43 if (mode.compare("REFRESH_120FPS") == 0) {
44 mDisplayRefreshRate = 120;
45 } else if (mode.compare("REFRESH_90FPS") == 0) {
46 mDisplayRefreshRate = 90;
47 } else if (mode.compare("REFRESH_60FPS") == 0) {
48 mDisplayRefreshRate = 60;
49 }
50 }
51 }
52
getDisplayRefreshRate()53 int PowerSessionManager::getDisplayRefreshRate() {
54 return mDisplayRefreshRate;
55 }
56
addPowerSession(PowerHintSession * session)57 void PowerSessionManager::addPowerSession(PowerHintSession *session) {
58 std::lock_guard<std::mutex> guard(mLock);
59 for (auto t : session->getTidList()) {
60 if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) {
61 if (!SetTaskProfiles(t, {"ResetUclampGrp"})) {
62 ALOGW("Failed to set ResetUclampGrp task profile for tid:%d", t);
63 } else {
64 mTidRefCountMap[t] = 1;
65 }
66 continue;
67 }
68 if (mTidRefCountMap[t] <= 0) {
69 ALOGE("Error! Unexpected zero/negative RefCount:%d for tid:%d", mTidRefCountMap[t], t);
70 continue;
71 }
72 mTidRefCountMap[t]++;
73 }
74 mSessions.insert(session);
75 }
76
removePowerSession(PowerHintSession * session)77 void PowerSessionManager::removePowerSession(PowerHintSession *session) {
78 std::lock_guard<std::mutex> guard(mLock);
79 for (auto t : session->getTidList()) {
80 if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) {
81 ALOGE("Unexpected Error! Failed to look up tid:%d in TidRefCountMap", t);
82 continue;
83 }
84 mTidRefCountMap[t]--;
85 if (mTidRefCountMap[t] <= 0) {
86 if (!SetTaskProfiles(t, {"NoResetUclampGrp"})) {
87 ALOGW("Failed to set NoResetUclampGrp task profile for tid:%d", t);
88 }
89 mTidRefCountMap.erase(t);
90 }
91 }
92 mSessions.erase(session);
93 }
94
isAnySessionActive()95 std::optional<bool> PowerSessionManager::isAnySessionActive() {
96 std::lock_guard<std::mutex> guard(mLock);
97 bool active = false;
98 for (PowerHintSession *s : mSessions) {
99 // session active and not stale is actually active.
100 if (s->isActive() && !s->isStale()) {
101 active = true;
102 break;
103 }
104 }
105 if (active == mActive) {
106 return std::nullopt;
107 } else {
108 mActive = active;
109 }
110
111 return active;
112 }
113
handleMessage(const Message &)114 void PowerSessionManager::handleMessage(const Message &) {
115 auto active = isAnySessionActive();
116 if (!active.has_value()) {
117 return;
118 }
119 if (active.value()) {
120 disableSystemTopAppBoost();
121 } else {
122 enableSystemTopAppBoost();
123 }
124 }
125
enableSystemTopAppBoost()126 void PowerSessionManager::enableSystemTopAppBoost() {
127 if (mHintManager) {
128 ALOGV("PowerSessionManager::enableSystemTopAppBoost!!");
129 mHintManager->EndHint(kDisableBoostHintName);
130 }
131 }
132
disableSystemTopAppBoost()133 void PowerSessionManager::disableSystemTopAppBoost() {
134 if (mHintManager) {
135 ALOGV("PowerSessionManager::disableSystemTopAppBoost!!");
136 mHintManager->DoHint(kDisableBoostHintName);
137 }
138 }
139
140 // =========== PowerHintMonitor implementation start from here ===========
start()141 void PowerHintMonitor::start() {
142 if (!isRunning()) {
143 run("PowerHintMonitor", ::android::PRIORITY_HIGHEST);
144 }
145 }
146
threadLoop()147 bool PowerHintMonitor::threadLoop() {
148 while (true) {
149 mLooper->pollOnce(-1);
150 }
151 return true;
152 }
153
getLooper()154 sp<Looper> PowerHintMonitor::getLooper() {
155 return mLooper;
156 }
157
158 } // namespace pixel
159 } // namespace impl
160 } // namespace power
161 } // namespace hardware
162 } // namespace google
163 } // namespace aidl
164