blob: f321ebc1727ef1f5badfac4994e38e168b394fcb [file] [log] [blame]
Girish4e531c82023-02-17 00:36:29 +00001/*
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
25namespace {
26const char* kActivityServiceName = "activity";
27}; // namespace anonymous
28
29namespace android {
30
31UidObserver::UidObserver(const sp<ProcessInfoInterface>& processInfo,
32 OnProcessTerminated onProcessTerminated) :
33 mRegistered(false),
34 mOnProcessTerminated(std::move(onProcessTerminated)),
35 mProcessInfo(processInfo) {
36}
37
38UidObserver::~UidObserver() {
39 stop();
40}
41
42void 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
55void 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
66void 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
84void 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
101void UidObserver::onServiceRegistration(const String16& name, const sp<IBinder>&) {
102 if (name != String16(kActivityServiceName)) {
103 return;
104 }
105
106 registerWithActivityManager();
107}
108
109void 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.
128void 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
161void UidObserver::onUidActive(uid_t /*uid*/) {
162}
163
164void UidObserver::onUidIdle(uid_t /*uid*/, bool /*disabled*/) {
165}
166
167void UidObserver::onUidStateChanged(uid_t /*uid*/,
168 int32_t /*procState*/,
169 int64_t /*procStateSeq*/,
170 int32_t /*capability*/) {
171}
172
173void UidObserver::onUidProcAdjChanged(uid_t /*uid*/) {
174}
175
176void 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