xref: /aosp_15_r20/frameworks/av/services/mediaresourcemanager/UidObserver.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2023, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker **     http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "ResourceManagerMetrics"
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker #include <android/binder_process.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/ProcessInfo.h>
23*ec779b8eSAndroid Build Coastguard Worker #include "UidObserver.h"
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker namespace {
26*ec779b8eSAndroid Build Coastguard Worker const char* kActivityServiceName = "activity";
27*ec779b8eSAndroid Build Coastguard Worker }; // namespace anonymous
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker namespace android {
30*ec779b8eSAndroid Build Coastguard Worker 
UidObserver(const sp<ProcessInfoInterface> & processInfo,OnProcessTerminated onProcessTerminated)31*ec779b8eSAndroid Build Coastguard Worker UidObserver::UidObserver(const sp<ProcessInfoInterface>& processInfo,
32*ec779b8eSAndroid Build Coastguard Worker                          OnProcessTerminated onProcessTerminated) :
33*ec779b8eSAndroid Build Coastguard Worker      mRegistered(false),
34*ec779b8eSAndroid Build Coastguard Worker      mOnProcessTerminated(std::move(onProcessTerminated)),
35*ec779b8eSAndroid Build Coastguard Worker      mProcessInfo(processInfo) {
36*ec779b8eSAndroid Build Coastguard Worker }
37*ec779b8eSAndroid Build Coastguard Worker 
~UidObserver()38*ec779b8eSAndroid Build Coastguard Worker UidObserver::~UidObserver() {
39*ec779b8eSAndroid Build Coastguard Worker     stop();
40*ec779b8eSAndroid Build Coastguard Worker }
41*ec779b8eSAndroid Build Coastguard Worker 
start()42*ec779b8eSAndroid Build Coastguard Worker void UidObserver::start() {
43*ec779b8eSAndroid Build Coastguard Worker     // Use check service to see if the activity service is available
44*ec779b8eSAndroid Build Coastguard Worker     // If not available then register for notifications, instead of blocking
45*ec779b8eSAndroid Build Coastguard Worker     // till the service is ready
46*ec779b8eSAndroid Build Coastguard Worker     sp<IServiceManager> sm = defaultServiceManager();
47*ec779b8eSAndroid Build Coastguard Worker     sp<IBinder> binder = sm->checkService(String16(kActivityServiceName));
48*ec779b8eSAndroid Build Coastguard Worker     if (!binder) {
49*ec779b8eSAndroid Build Coastguard Worker         sm->registerForNotifications(String16(kActivityServiceName), this);
50*ec779b8eSAndroid Build Coastguard Worker     } else {
51*ec779b8eSAndroid Build Coastguard Worker         registerWithActivityManager();
52*ec779b8eSAndroid Build Coastguard Worker     }
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker 
stop()55*ec779b8eSAndroid Build Coastguard Worker void UidObserver::stop() {
56*ec779b8eSAndroid Build Coastguard Worker     std::scoped_lock lock{mLock};
57*ec779b8eSAndroid Build Coastguard Worker 
58*ec779b8eSAndroid Build Coastguard Worker     if (mRegistered) {
59*ec779b8eSAndroid Build Coastguard Worker         // Unregistered with ActivityManager
60*ec779b8eSAndroid Build Coastguard Worker         mAm.unregisterUidObserver(this);
61*ec779b8eSAndroid Build Coastguard Worker         mAm.unlinkToDeath(this);
62*ec779b8eSAndroid Build Coastguard Worker         mRegistered = false;
63*ec779b8eSAndroid Build Coastguard Worker     }
64*ec779b8eSAndroid Build Coastguard Worker }
65*ec779b8eSAndroid Build Coastguard Worker 
add(int pid,uid_t uid)66*ec779b8eSAndroid Build Coastguard Worker void UidObserver::add(int pid, uid_t uid) {
67*ec779b8eSAndroid Build Coastguard Worker     bool needToRegister = false;
68*ec779b8eSAndroid Build Coastguard Worker     {
69*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock(mLock);
70*ec779b8eSAndroid Build Coastguard Worker         std::map<uid_t, std::set<int32_t>>::iterator found = mUids.find(uid);
71*ec779b8eSAndroid Build Coastguard Worker         if (found != mUids.end()) {
72*ec779b8eSAndroid Build Coastguard Worker             found->second.insert(pid);
73*ec779b8eSAndroid Build Coastguard Worker         } else {
74*ec779b8eSAndroid Build Coastguard Worker             std::set<int32_t> pids{pid};
75*ec779b8eSAndroid Build Coastguard Worker             mUids.emplace(uid, std::move(pids));
76*ec779b8eSAndroid Build Coastguard Worker         }
77*ec779b8eSAndroid Build Coastguard Worker         needToRegister = !mRegistered;
78*ec779b8eSAndroid Build Coastguard Worker     }
79*ec779b8eSAndroid Build Coastguard Worker     if (needToRegister) {
80*ec779b8eSAndroid Build Coastguard Worker         start();
81*ec779b8eSAndroid Build Coastguard Worker     }
82*ec779b8eSAndroid Build Coastguard Worker }
83*ec779b8eSAndroid Build Coastguard Worker 
registerWithActivityManager()84*ec779b8eSAndroid Build Coastguard Worker void UidObserver::registerWithActivityManager() {
85*ec779b8eSAndroid Build Coastguard Worker     std::scoped_lock lock{mLock};
86*ec779b8eSAndroid Build Coastguard Worker 
87*ec779b8eSAndroid Build Coastguard Worker     if (mRegistered) {
88*ec779b8eSAndroid Build Coastguard Worker         return;
89*ec779b8eSAndroid Build Coastguard Worker     }
90*ec779b8eSAndroid Build Coastguard Worker     status_t res = mAm.linkToDeath(this);
91*ec779b8eSAndroid Build Coastguard Worker     // Register for UID gone.
92*ec779b8eSAndroid Build Coastguard Worker     mAm.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE,
93*ec779b8eSAndroid Build Coastguard Worker                             ActivityManager::PROCESS_STATE_UNKNOWN,
94*ec779b8eSAndroid Build Coastguard Worker                             String16("mediaserver"));
95*ec779b8eSAndroid Build Coastguard Worker     if (res == OK) {
96*ec779b8eSAndroid Build Coastguard Worker         mRegistered = true;
97*ec779b8eSAndroid Build Coastguard Worker         ALOGV("UidObserver: Registered with ActivityManager");
98*ec779b8eSAndroid Build Coastguard Worker     }
99*ec779b8eSAndroid Build Coastguard Worker }
100*ec779b8eSAndroid Build Coastguard Worker 
onServiceRegistration(const String16 & name,const sp<IBinder> &)101*ec779b8eSAndroid Build Coastguard Worker void UidObserver::onServiceRegistration(const String16& name, const sp<IBinder>&) {
102*ec779b8eSAndroid Build Coastguard Worker     if (name != String16(kActivityServiceName)) {
103*ec779b8eSAndroid Build Coastguard Worker         return;
104*ec779b8eSAndroid Build Coastguard Worker     }
105*ec779b8eSAndroid Build Coastguard Worker 
106*ec779b8eSAndroid Build Coastguard Worker     registerWithActivityManager();
107*ec779b8eSAndroid Build Coastguard Worker }
108*ec779b8eSAndroid Build Coastguard Worker 
getTerminatedProcesses(const std::vector<int32_t> & pids,std::vector<int32_t> & terminatedPids)109*ec779b8eSAndroid Build Coastguard Worker void UidObserver::getTerminatedProcesses(const std::vector<int32_t>& pids,
110*ec779b8eSAndroid Build Coastguard Worker                                          std::vector<int32_t>& terminatedPids) {
111*ec779b8eSAndroid Build Coastguard Worker     std::vector<bool> existent;
112*ec779b8eSAndroid Build Coastguard Worker     terminatedPids.clear();
113*ec779b8eSAndroid Build Coastguard Worker     if (mProcessInfo->checkProcessExistent(pids, &existent)) {
114*ec779b8eSAndroid Build Coastguard Worker         for (size_t index = 0; index < existent.size(); index++) {
115*ec779b8eSAndroid Build Coastguard Worker             if (!existent[index]) {
116*ec779b8eSAndroid Build Coastguard Worker                 // This process has been terminated already.
117*ec779b8eSAndroid Build Coastguard Worker                 terminatedPids.push_back(pids[index]);
118*ec779b8eSAndroid Build Coastguard Worker             }
119*ec779b8eSAndroid Build Coastguard Worker         }
120*ec779b8eSAndroid Build Coastguard Worker     }
121*ec779b8eSAndroid Build Coastguard Worker }
122*ec779b8eSAndroid Build Coastguard Worker 
123*ec779b8eSAndroid Build Coastguard Worker // This callback will be issued for every UID that is gone/terminated.
124*ec779b8eSAndroid Build Coastguard Worker // Since one UID could have multiple PIDs, this callback can be issued
125*ec779b8eSAndroid Build Coastguard Worker // multiple times with that same UID for each activity/pid.
126*ec779b8eSAndroid Build Coastguard Worker // So, we need to check which one among the PIDs (that share the same UID)
127*ec779b8eSAndroid Build Coastguard Worker // is gone.
onUidGone(uid_t uid,bool)128*ec779b8eSAndroid Build Coastguard Worker void UidObserver::onUidGone(uid_t uid, bool /*disabled*/) {
129*ec779b8eSAndroid Build Coastguard Worker     std::vector<int32_t> terminatedPids;
130*ec779b8eSAndroid Build Coastguard Worker     {
131*ec779b8eSAndroid Build Coastguard Worker         std::scoped_lock lock{mLock};
132*ec779b8eSAndroid Build Coastguard Worker         std::map<uid_t, std::set<int32_t>>::iterator found = mUids.find(uid);
133*ec779b8eSAndroid Build Coastguard Worker         if (found != mUids.end()) {
134*ec779b8eSAndroid Build Coastguard Worker             if (found->second.size() == 1) {
135*ec779b8eSAndroid Build Coastguard Worker                 terminatedPids.push_back(*(found->second.begin()));
136*ec779b8eSAndroid Build Coastguard Worker                 // Only one PID. So we can remove this UID entry.
137*ec779b8eSAndroid Build Coastguard Worker                 mUids.erase(found);
138*ec779b8eSAndroid Build Coastguard Worker             } else {
139*ec779b8eSAndroid Build Coastguard Worker                 // There are multiple PIDs with the same UID.
140*ec779b8eSAndroid Build Coastguard Worker                 // Get the list of all terminated PIDs (with the same UID)
141*ec779b8eSAndroid Build Coastguard Worker                 std::vector<int32_t> pids;
142*ec779b8eSAndroid Build Coastguard Worker                 std::copy(found->second.begin(), found->second.end(), std::back_inserter(pids));
143*ec779b8eSAndroid Build Coastguard Worker                 getTerminatedProcesses(pids, terminatedPids);
144*ec779b8eSAndroid Build Coastguard Worker                 for (int32_t pid : terminatedPids) {
145*ec779b8eSAndroid Build Coastguard Worker                     // Remove all the terminated PIDs
146*ec779b8eSAndroid Build Coastguard Worker                     found->second.erase(pid);
147*ec779b8eSAndroid Build Coastguard Worker                 }
148*ec779b8eSAndroid Build Coastguard Worker                 // If all PIDs under this UID have terminated, remove this UID entry.
149*ec779b8eSAndroid Build Coastguard Worker                 if (found->second.size() == 0) {
150*ec779b8eSAndroid Build Coastguard Worker                     mUids.erase(uid);
151*ec779b8eSAndroid Build Coastguard Worker                 }
152*ec779b8eSAndroid Build Coastguard Worker             }
153*ec779b8eSAndroid Build Coastguard Worker         }
154*ec779b8eSAndroid Build Coastguard Worker     }
155*ec779b8eSAndroid Build Coastguard Worker 
156*ec779b8eSAndroid Build Coastguard Worker     for (int32_t pid : terminatedPids) {
157*ec779b8eSAndroid Build Coastguard Worker         mOnProcessTerminated(pid, uid);
158*ec779b8eSAndroid Build Coastguard Worker     }
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker 
onUidActive(uid_t)161*ec779b8eSAndroid Build Coastguard Worker void UidObserver::onUidActive(uid_t /*uid*/) {
162*ec779b8eSAndroid Build Coastguard Worker }
163*ec779b8eSAndroid Build Coastguard Worker 
onUidIdle(uid_t,bool)164*ec779b8eSAndroid Build Coastguard Worker void UidObserver::onUidIdle(uid_t /*uid*/, bool /*disabled*/) {
165*ec779b8eSAndroid Build Coastguard Worker }
166*ec779b8eSAndroid Build Coastguard Worker 
onUidStateChanged(uid_t,int32_t,int64_t,int32_t)167*ec779b8eSAndroid Build Coastguard Worker void UidObserver::onUidStateChanged(uid_t /*uid*/,
168*ec779b8eSAndroid Build Coastguard Worker                                     int32_t /*procState*/,
169*ec779b8eSAndroid Build Coastguard Worker                                     int64_t /*procStateSeq*/,
170*ec779b8eSAndroid Build Coastguard Worker                                     int32_t /*capability*/) {
171*ec779b8eSAndroid Build Coastguard Worker }
172*ec779b8eSAndroid Build Coastguard Worker 
onUidProcAdjChanged(uid_t,int32_t)173*ec779b8eSAndroid Build Coastguard Worker void UidObserver::onUidProcAdjChanged(uid_t /*uid*/, int32_t /*adj*/) {
174*ec779b8eSAndroid Build Coastguard Worker }
175*ec779b8eSAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> &)176*ec779b8eSAndroid Build Coastguard Worker void UidObserver::binderDied(const wp<IBinder>& /*who*/) {
177*ec779b8eSAndroid Build Coastguard Worker     std::scoped_lock lock{mLock};
178*ec779b8eSAndroid Build Coastguard Worker     ALOGE("UidObserver: ActivityManager has died");
179*ec779b8eSAndroid Build Coastguard Worker     mRegistered = false;
180*ec779b8eSAndroid Build Coastguard Worker }
181*ec779b8eSAndroid Build Coastguard Worker 
182*ec779b8eSAndroid Build Coastguard Worker }  // namespace android
183