blob: b5eb028635cbee1aa91919d5f8bea7cb8a48832f [file] [log] [blame]
Chong Zhangacb33502020-04-20 11:04:48 -07001/*
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
Chong Zhang75222182020-04-29 14:43:42 -070017//#define LOG_NDEBUG 0
Chong Zhangacb33502020-04-20 11:04:48 -070018#define LOG_TAG "TranscodingUidPolicy"
19
Chong Zhangad8fdfc2020-10-21 19:05:15 -070020#include <android/activity_manager.h>
Chong Zhang97d367b2020-09-16 12:53:14 -070021#include <android/binder_manager.h>
22#include <android/binder_process.h>
Chong Zhangacb33502020-04-20 11:04:48 -070023#include <inttypes.h>
24#include <media/TranscodingUidPolicy.h>
25#include <utils/Log.h>
26
27#include <utility>
28
29namespace android {
30
31constexpr static uid_t OFFLINE_UID = -1;
Chong Zhangad8fdfc2020-10-21 19:05:15 -070032constexpr static int32_t IMPORTANCE_UNKNOWN = INT32_MAX;
Chong Zhangacb33502020-04-20 11:04:48 -070033
34TranscodingUidPolicy::TranscodingUidPolicy()
Chong Zhang8677f1f2021-01-21 20:37:35 +000035 : mUidObserver(nullptr), mRegistered(false), mTopUidState(IMPORTANCE_UNKNOWN) {
Chong Zhangacb33502020-04-20 11:04:48 -070036 registerSelf();
37}
38
39TranscodingUidPolicy::~TranscodingUidPolicy() {
40 unregisterSelf();
41}
42
Chong Zhangad8fdfc2020-10-21 19:05:15 -070043void TranscodingUidPolicy::OnUidImportance(uid_t uid, int32_t uidImportance, void* cookie) {
44 TranscodingUidPolicy* owner = reinterpret_cast<TranscodingUidPolicy*>(cookie);
45 owner->onUidStateChanged(uid, uidImportance);
46}
47
Chong Zhangacb33502020-04-20 11:04:48 -070048void TranscodingUidPolicy::registerSelf() {
Chong Zhang5c504ee2021-01-21 18:53:19 -080049 if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
Jiyong Parkff998612021-01-15 16:01:38 +090050 mUidObserver = AActivityManager_addUidImportanceListener(&OnUidImportance, -1, (void*)this);
51 }
Chong Zhangacb33502020-04-20 11:04:48 -070052
Chong Zhangad8fdfc2020-10-21 19:05:15 -070053 if (mUidObserver == nullptr) {
54 ALOGE("Failed to register uid observer");
55 return;
Chong Zhangacb33502020-04-20 11:04:48 -070056 }
Chong Zhangad8fdfc2020-10-21 19:05:15 -070057
58 Mutex::Autolock _l(mUidLock);
59 mRegistered = true;
60 ALOGI("Registered uid observer");
Chong Zhangacb33502020-04-20 11:04:48 -070061}
62
63void TranscodingUidPolicy::unregisterSelf() {
Chong Zhang5c504ee2021-01-21 18:53:19 -080064 if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
Jiyong Parkff998612021-01-15 16:01:38 +090065 AActivityManager_removeUidImportanceListener(mUidObserver);
66 mUidObserver = nullptr;
Chong Zhangacb33502020-04-20 11:04:48 -070067
Jiyong Parkff998612021-01-15 16:01:38 +090068 Mutex::Autolock _l(mUidLock);
69 mRegistered = false;
70 ALOGI("Unregistered uid observer");
71 } else {
72 ALOGE("Failed to unregister uid observer");
73 }
Chong Zhangacb33502020-04-20 11:04:48 -070074}
75
76void TranscodingUidPolicy::setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) {
77 mUidPolicyCallback = cb;
78}
79
80void TranscodingUidPolicy::registerMonitorUid(uid_t uid) {
81 Mutex::Autolock _l(mUidLock);
82 if (uid == OFFLINE_UID) {
83 ALOGW("Ignoring the offline uid");
84 return;
85 }
86 if (mUidStateMap.find(uid) != mUidStateMap.end()) {
87 ALOGE("%s: Trying to register uid: %d which is already monitored!", __FUNCTION__, uid);
88 return;
89 }
90
Chong Zhangad8fdfc2020-10-21 19:05:15 -070091 int32_t state = IMPORTANCE_UNKNOWN;
Chong Zhang5c504ee2021-01-21 18:53:19 -080092 if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
Jiyong Parkff998612021-01-15 16:01:38 +090093 if (mRegistered && AActivityManager_isUidActive(uid)) {
94 state = AActivityManager_getUidImportance(uid);
95 }
Chong Zhangacb33502020-04-20 11:04:48 -070096 }
97
98 ALOGV("%s: inserting new uid: %u, procState %d", __FUNCTION__, uid, state);
99
100 mUidStateMap.emplace(std::pair<uid_t, int32_t>(uid, state));
101 mStateUidMap[state].insert(uid);
102
103 updateTopUid_l();
104}
105
106void TranscodingUidPolicy::unregisterMonitorUid(uid_t uid) {
107 Mutex::Autolock _l(mUidLock);
108
109 auto it = mUidStateMap.find(uid);
110 if (it == mUidStateMap.end()) {
111 ALOGE("%s: Trying to unregister uid: %d which is not monitored!", __FUNCTION__, uid);
112 return;
113 }
114
115 auto stateIt = mStateUidMap.find(it->second);
116 if (stateIt != mStateUidMap.end()) {
117 stateIt->second.erase(uid);
118 if (stateIt->second.empty()) {
119 mStateUidMap.erase(stateIt);
120 }
121 }
122 mUidStateMap.erase(it);
123
124 updateTopUid_l();
125}
126
127bool TranscodingUidPolicy::isUidOnTop(uid_t uid) {
128 Mutex::Autolock _l(mUidLock);
129
Chong Zhang8677f1f2021-01-21 20:37:35 +0000130 return mTopUidState != IMPORTANCE_UNKNOWN && mTopUidState == getProcState_l(uid);
Chong Zhangacb33502020-04-20 11:04:48 -0700131}
132
133std::unordered_set<uid_t> TranscodingUidPolicy::getTopUids() const {
134 Mutex::Autolock _l(mUidLock);
135
Chong Zhangad8fdfc2020-10-21 19:05:15 -0700136 if (mTopUidState == IMPORTANCE_UNKNOWN) {
Chong Zhangacb33502020-04-20 11:04:48 -0700137 return std::unordered_set<uid_t>();
138 }
139
140 return mStateUidMap.at(mTopUidState);
141}
142
143void TranscodingUidPolicy::onUidStateChanged(uid_t uid, int32_t procState) {
144 ALOGV("onUidStateChanged: %u, procState %d", uid, procState);
145
146 bool topUidSetChanged = false;
147 std::unordered_set<uid_t> topUids;
148 {
149 Mutex::Autolock _l(mUidLock);
150 auto it = mUidStateMap.find(uid);
151 if (it != mUidStateMap.end() && it->second != procState) {
152 // Top set changed if 1) the uid is in the current top uid set, or 2) the
153 // new procState is at least the same priority as the current top uid state.
Chong Zhangad8fdfc2020-10-21 19:05:15 -0700154 bool isUidCurrentTop =
Chong Zhang8677f1f2021-01-21 20:37:35 +0000155 mTopUidState != IMPORTANCE_UNKNOWN && mStateUidMap[mTopUidState].count(uid) > 0;
Chong Zhangad8fdfc2020-10-21 19:05:15 -0700156 bool isNewStateHigherThanTop =
157 procState != IMPORTANCE_UNKNOWN &&
Chong Zhang8677f1f2021-01-21 20:37:35 +0000158 (procState <= mTopUidState || mTopUidState == IMPORTANCE_UNKNOWN);
Chong Zhangacb33502020-04-20 11:04:48 -0700159 topUidSetChanged = (isUidCurrentTop || isNewStateHigherThanTop);
160
161 // Move uid to the new procState.
162 mStateUidMap[it->second].erase(uid);
163 mStateUidMap[procState].insert(uid);
164 it->second = procState;
165
166 if (topUidSetChanged) {
167 updateTopUid_l();
168
169 // Make a copy of the uid set for callback.
170 topUids = mStateUidMap[mTopUidState];
171 }
172 }
173 }
174
175 ALOGV("topUidSetChanged: %d", topUidSetChanged);
176
177 if (topUidSetChanged) {
178 auto callback = mUidPolicyCallback.lock();
179 if (callback != nullptr) {
180 callback->onTopUidsChanged(topUids);
181 }
182 }
183}
184
185void TranscodingUidPolicy::updateTopUid_l() {
Chong Zhangad8fdfc2020-10-21 19:05:15 -0700186 mTopUidState = IMPORTANCE_UNKNOWN;
Chong Zhang75222182020-04-29 14:43:42 -0700187
188 // Find the lowest uid state (ignoring PROCESS_STATE_UNKNOWN) with some monitored uids.
Chong Zhangacb33502020-04-20 11:04:48 -0700189 for (auto stateIt = mStateUidMap.begin(); stateIt != mStateUidMap.end(); stateIt++) {
Chong Zhang8677f1f2021-01-21 20:37:35 +0000190 if (stateIt->first != IMPORTANCE_UNKNOWN && !stateIt->second.empty()) {
Chong Zhangacb33502020-04-20 11:04:48 -0700191 mTopUidState = stateIt->first;
192 break;
193 }
194 }
195
196 ALOGV("%s: top uid state is %d", __FUNCTION__, mTopUidState);
197}
198
199int32_t TranscodingUidPolicy::getProcState_l(uid_t uid) {
200 auto it = mUidStateMap.find(uid);
201 if (it != mUidStateMap.end()) {
202 return it->second;
203 }
Chong Zhangad8fdfc2020-10-21 19:05:15 -0700204 return IMPORTANCE_UNKNOWN;
Chong Zhangacb33502020-04-20 11:04:48 -0700205}
206
207} // namespace android