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