xref: /aosp_15_r20/frameworks/base/native/android/activity_manager.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #define LOG_NDEBUG 0
18*d57664e9SAndroid Build Coastguard Worker #define LOG_TAG "AActivityManager"
19*d57664e9SAndroid Build Coastguard Worker #include <utils/Log.h>
20*d57664e9SAndroid Build Coastguard Worker 
21*d57664e9SAndroid Build Coastguard Worker #include <android/activity_manager.h>
22*d57664e9SAndroid Build Coastguard Worker #include <binder/ActivityManager.h>
23*d57664e9SAndroid Build Coastguard Worker 
24*d57664e9SAndroid Build Coastguard Worker namespace android {
25*d57664e9SAndroid Build Coastguard Worker namespace activitymanager {
26*d57664e9SAndroid Build Coastguard Worker 
27*d57664e9SAndroid Build Coastguard Worker // Global instance of ActivityManager, service is obtained only on first use.
28*d57664e9SAndroid Build Coastguard Worker static ActivityManager gAm;
29*d57664e9SAndroid Build Coastguard Worker // String tag used with ActivityManager.
getTag()30*d57664e9SAndroid Build Coastguard Worker static const String16& getTag() {
31*d57664e9SAndroid Build Coastguard Worker     static String16 tag("libandroid");
32*d57664e9SAndroid Build Coastguard Worker     return tag;
33*d57664e9SAndroid Build Coastguard Worker }
34*d57664e9SAndroid Build Coastguard Worker 
35*d57664e9SAndroid Build Coastguard Worker struct UidObserver : public BnUidObserver, public virtual IBinder::DeathRecipient {
UidObserverandroid::activitymanager::UidObserver36*d57664e9SAndroid Build Coastguard Worker     explicit UidObserver(const AActivityManager_onUidImportance& cb,
37*d57664e9SAndroid Build Coastguard Worker                          int32_t cutpoint, void* cookie)
38*d57664e9SAndroid Build Coastguard Worker           : mCallback(cb), mImportanceCutpoint(cutpoint), mCookie(cookie), mRegistered(false) {}
39*d57664e9SAndroid Build Coastguard Worker     bool registerSelf();
40*d57664e9SAndroid Build Coastguard Worker     void unregisterSelf();
41*d57664e9SAndroid Build Coastguard Worker 
42*d57664e9SAndroid Build Coastguard Worker     // IUidObserver
43*d57664e9SAndroid Build Coastguard Worker     void onUidGone(uid_t uid, bool disabled) override;
44*d57664e9SAndroid Build Coastguard Worker     void onUidActive(uid_t uid) override;
45*d57664e9SAndroid Build Coastguard Worker     void onUidIdle(uid_t uid, bool disabled) override;
46*d57664e9SAndroid Build Coastguard Worker     void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
47*d57664e9SAndroid Build Coastguard Worker                            int32_t capability) override;
48*d57664e9SAndroid Build Coastguard Worker     void onUidProcAdjChanged(uid_t uid, int32_t adj) override;
49*d57664e9SAndroid Build Coastguard Worker 
50*d57664e9SAndroid Build Coastguard Worker     // IBinder::DeathRecipient implementation
51*d57664e9SAndroid Build Coastguard Worker     void binderDied(const wp<IBinder>& who) override;
52*d57664e9SAndroid Build Coastguard Worker 
53*d57664e9SAndroid Build Coastguard Worker     static int32_t procStateToImportance(int32_t procState);
54*d57664e9SAndroid Build Coastguard Worker     static int32_t importanceToProcState(int32_t importance);
55*d57664e9SAndroid Build Coastguard Worker 
56*d57664e9SAndroid Build Coastguard Worker     AActivityManager_onUidImportance mCallback;
57*d57664e9SAndroid Build Coastguard Worker     int32_t mImportanceCutpoint;
58*d57664e9SAndroid Build Coastguard Worker     void* mCookie;
59*d57664e9SAndroid Build Coastguard Worker     std::mutex mRegisteredLock;
60*d57664e9SAndroid Build Coastguard Worker     bool mRegistered GUARDED_BY(mRegisteredLock);
61*d57664e9SAndroid Build Coastguard Worker };
62*d57664e9SAndroid Build Coastguard Worker 
63*d57664e9SAndroid Build Coastguard Worker //static
procStateToImportance(int32_t procState)64*d57664e9SAndroid Build Coastguard Worker int32_t UidObserver::procStateToImportance(int32_t procState) {
65*d57664e9SAndroid Build Coastguard Worker     // TODO: remove this after adding Importance to onUidStateChanged callback.
66*d57664e9SAndroid Build Coastguard Worker     if (procState == ActivityManager::PROCESS_STATE_NONEXISTENT) {
67*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_GONE;
68*d57664e9SAndroid Build Coastguard Worker     } else if (procState >= ActivityManager::PROCESS_STATE_HOME) {
69*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_CACHED;
70*d57664e9SAndroid Build Coastguard Worker     } else if (procState == ActivityManager::PROCESS_STATE_HEAVY_WEIGHT) {
71*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_CANT_SAVE_STATE;
72*d57664e9SAndroid Build Coastguard Worker     } else if (procState >= ActivityManager::PROCESS_STATE_TOP_SLEEPING) {
73*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_TOP_SLEEPING;
74*d57664e9SAndroid Build Coastguard Worker     } else if (procState >= ActivityManager::PROCESS_STATE_SERVICE) {
75*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_SERVICE;
76*d57664e9SAndroid Build Coastguard Worker     } else if (procState >= ActivityManager::PROCESS_STATE_TRANSIENT_BACKGROUND) {
77*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE;
78*d57664e9SAndroid Build Coastguard Worker     } else if (procState >= ActivityManager::PROCESS_STATE_IMPORTANT_FOREGROUND) {
79*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_VISIBLE;
80*d57664e9SAndroid Build Coastguard Worker     } else if (procState >= ActivityManager::PROCESS_STATE_FOREGROUND_SERVICE) {
81*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_FOREGROUND_SERVICE;
82*d57664e9SAndroid Build Coastguard Worker     } else {
83*d57664e9SAndroid Build Coastguard Worker         return AACTIVITYMANAGER_IMPORTANCE_FOREGROUND;
84*d57664e9SAndroid Build Coastguard Worker     }
85*d57664e9SAndroid Build Coastguard Worker }
86*d57664e9SAndroid Build Coastguard Worker 
87*d57664e9SAndroid Build Coastguard Worker //static
importanceToProcState(int32_t importance)88*d57664e9SAndroid Build Coastguard Worker int32_t UidObserver::importanceToProcState(int32_t importance) {
89*d57664e9SAndroid Build Coastguard Worker     // TODO: remove this after adding Importance to onUidStateChanged callback.
90*d57664e9SAndroid Build Coastguard Worker     if (importance == AACTIVITYMANAGER_IMPORTANCE_GONE) {
91*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_NONEXISTENT;
92*d57664e9SAndroid Build Coastguard Worker     } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_CACHED) {
93*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_HOME;
94*d57664e9SAndroid Build Coastguard Worker     } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_CANT_SAVE_STATE) {
95*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_HEAVY_WEIGHT;
96*d57664e9SAndroid Build Coastguard Worker     } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_TOP_SLEEPING) {
97*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_TOP_SLEEPING;
98*d57664e9SAndroid Build Coastguard Worker     } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_SERVICE) {
99*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_SERVICE;
100*d57664e9SAndroid Build Coastguard Worker     } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE) {
101*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_TRANSIENT_BACKGROUND;
102*d57664e9SAndroid Build Coastguard Worker     } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_VISIBLE) {
103*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_IMPORTANT_FOREGROUND;
104*d57664e9SAndroid Build Coastguard Worker     } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_FOREGROUND_SERVICE) {
105*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_FOREGROUND_SERVICE;
106*d57664e9SAndroid Build Coastguard Worker     } else {
107*d57664e9SAndroid Build Coastguard Worker         return ActivityManager::PROCESS_STATE_TOP;
108*d57664e9SAndroid Build Coastguard Worker     }
109*d57664e9SAndroid Build Coastguard Worker }
110*d57664e9SAndroid Build Coastguard Worker 
111*d57664e9SAndroid Build Coastguard Worker 
onUidGone(uid_t uid,bool disabled __unused)112*d57664e9SAndroid Build Coastguard Worker void UidObserver::onUidGone(uid_t uid, bool disabled __unused) {
113*d57664e9SAndroid Build Coastguard Worker     std::scoped_lock lock{mRegisteredLock};
114*d57664e9SAndroid Build Coastguard Worker 
115*d57664e9SAndroid Build Coastguard Worker     if (mRegistered && mCallback) {
116*d57664e9SAndroid Build Coastguard Worker         mCallback(uid, AACTIVITYMANAGER_IMPORTANCE_GONE, mCookie);
117*d57664e9SAndroid Build Coastguard Worker     }
118*d57664e9SAndroid Build Coastguard Worker }
119*d57664e9SAndroid Build Coastguard Worker 
onUidActive(uid_t uid __unused)120*d57664e9SAndroid Build Coastguard Worker void UidObserver::onUidActive(uid_t uid __unused) {}
121*d57664e9SAndroid Build Coastguard Worker 
onUidIdle(uid_t uid __unused,bool disabled __unused)122*d57664e9SAndroid Build Coastguard Worker void UidObserver::onUidIdle(uid_t uid __unused, bool disabled __unused) {}
123*d57664e9SAndroid Build Coastguard Worker 
onUidProcAdjChanged(uid_t uid __unused,int32_t adj __unused)124*d57664e9SAndroid Build Coastguard Worker void UidObserver::onUidProcAdjChanged(uid_t uid __unused, int32_t adj __unused) {}
125*d57664e9SAndroid Build Coastguard Worker 
onUidStateChanged(uid_t uid,int32_t procState,int64_t procStateSeq __unused,int32_t capability __unused)126*d57664e9SAndroid Build Coastguard Worker void UidObserver::onUidStateChanged(uid_t uid, int32_t procState,
127*d57664e9SAndroid Build Coastguard Worker                                     int64_t procStateSeq __unused,
128*d57664e9SAndroid Build Coastguard Worker                                     int32_t capability __unused) {
129*d57664e9SAndroid Build Coastguard Worker     std::scoped_lock lock{mRegisteredLock};
130*d57664e9SAndroid Build Coastguard Worker 
131*d57664e9SAndroid Build Coastguard Worker     if (mRegistered && mCallback) {
132*d57664e9SAndroid Build Coastguard Worker         mCallback(uid, procStateToImportance(procState), mCookie);
133*d57664e9SAndroid Build Coastguard Worker     }
134*d57664e9SAndroid Build Coastguard Worker }
135*d57664e9SAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> &)136*d57664e9SAndroid Build Coastguard Worker void UidObserver::binderDied(const wp<IBinder>& /*who*/) {
137*d57664e9SAndroid Build Coastguard Worker     // ActivityManager is dead, try to re-register.
138*d57664e9SAndroid Build Coastguard Worker     {
139*d57664e9SAndroid Build Coastguard Worker         std::scoped_lock lock{mRegisteredLock};
140*d57664e9SAndroid Build Coastguard Worker         // If client already unregistered, don't try to re-register.
141*d57664e9SAndroid Build Coastguard Worker         if (!mRegistered) {
142*d57664e9SAndroid Build Coastguard Worker             return;
143*d57664e9SAndroid Build Coastguard Worker         }
144*d57664e9SAndroid Build Coastguard Worker         // Clear mRegistered to re-register.
145*d57664e9SAndroid Build Coastguard Worker         mRegistered = false;
146*d57664e9SAndroid Build Coastguard Worker     }
147*d57664e9SAndroid Build Coastguard Worker     registerSelf();
148*d57664e9SAndroid Build Coastguard Worker }
149*d57664e9SAndroid Build Coastguard Worker 
registerSelf()150*d57664e9SAndroid Build Coastguard Worker bool UidObserver::registerSelf() {
151*d57664e9SAndroid Build Coastguard Worker     std::scoped_lock lock{mRegisteredLock};
152*d57664e9SAndroid Build Coastguard Worker     if (mRegistered) {
153*d57664e9SAndroid Build Coastguard Worker         return true;
154*d57664e9SAndroid Build Coastguard Worker     }
155*d57664e9SAndroid Build Coastguard Worker 
156*d57664e9SAndroid Build Coastguard Worker     status_t res = gAm.linkToDeath(this);
157*d57664e9SAndroid Build Coastguard Worker     if (res != OK) {
158*d57664e9SAndroid Build Coastguard Worker         ALOGE("UidObserver: Failed to linkToDeath with ActivityManager (err %d)", res);
159*d57664e9SAndroid Build Coastguard Worker         return false;
160*d57664e9SAndroid Build Coastguard Worker     }
161*d57664e9SAndroid Build Coastguard Worker 
162*d57664e9SAndroid Build Coastguard Worker     // TODO: it seems only way to get all changes is to set cutoff to PROCESS_STATE_UNKNOWN.
163*d57664e9SAndroid Build Coastguard Worker     // But there is no equivalent of PROCESS_STATE_UNKNOWN in the UidImportance.
164*d57664e9SAndroid Build Coastguard Worker     // If mImportanceCutpoint is < 0, use PROCESS_STATE_UNKNOWN instead.
165*d57664e9SAndroid Build Coastguard Worker     res = gAm.registerUidObserver(
166*d57664e9SAndroid Build Coastguard Worker             this,
167*d57664e9SAndroid Build Coastguard Worker             ActivityManager::UID_OBSERVER_GONE | ActivityManager::UID_OBSERVER_PROCSTATE,
168*d57664e9SAndroid Build Coastguard Worker             (mImportanceCutpoint < 0) ? ActivityManager::PROCESS_STATE_UNKNOWN
169*d57664e9SAndroid Build Coastguard Worker                                       : importanceToProcState(mImportanceCutpoint),
170*d57664e9SAndroid Build Coastguard Worker             getTag());
171*d57664e9SAndroid Build Coastguard Worker     if (res != OK) {
172*d57664e9SAndroid Build Coastguard Worker         ALOGE("UidObserver: Failed to register with ActivityManager (err %d)", res);
173*d57664e9SAndroid Build Coastguard Worker         gAm.unlinkToDeath(this);
174*d57664e9SAndroid Build Coastguard Worker         return false;
175*d57664e9SAndroid Build Coastguard Worker     }
176*d57664e9SAndroid Build Coastguard Worker 
177*d57664e9SAndroid Build Coastguard Worker     mRegistered = true;
178*d57664e9SAndroid Build Coastguard Worker     ALOGV("UidObserver: Registered with ActivityManager");
179*d57664e9SAndroid Build Coastguard Worker     return true;
180*d57664e9SAndroid Build Coastguard Worker }
181*d57664e9SAndroid Build Coastguard Worker 
unregisterSelf()182*d57664e9SAndroid Build Coastguard Worker void UidObserver::unregisterSelf() {
183*d57664e9SAndroid Build Coastguard Worker     std::scoped_lock lock{mRegisteredLock};
184*d57664e9SAndroid Build Coastguard Worker 
185*d57664e9SAndroid Build Coastguard Worker     if (mRegistered) {
186*d57664e9SAndroid Build Coastguard Worker         gAm.unregisterUidObserver(this);
187*d57664e9SAndroid Build Coastguard Worker         gAm.unlinkToDeath(this);
188*d57664e9SAndroid Build Coastguard Worker         mRegistered = false;
189*d57664e9SAndroid Build Coastguard Worker     }
190*d57664e9SAndroid Build Coastguard Worker 
191*d57664e9SAndroid Build Coastguard Worker     ALOGV("UidObserver: Unregistered with ActivityManager");
192*d57664e9SAndroid Build Coastguard Worker }
193*d57664e9SAndroid Build Coastguard Worker 
194*d57664e9SAndroid Build Coastguard Worker } // activitymanager
195*d57664e9SAndroid Build Coastguard Worker } // android
196*d57664e9SAndroid Build Coastguard Worker 
197*d57664e9SAndroid Build Coastguard Worker using namespace android;
198*d57664e9SAndroid Build Coastguard Worker using namespace activitymanager;
199*d57664e9SAndroid Build Coastguard Worker 
200*d57664e9SAndroid Build Coastguard Worker struct AActivityManager_UidImportanceListener : public UidObserver {
201*d57664e9SAndroid Build Coastguard Worker };
202*d57664e9SAndroid Build Coastguard Worker 
AActivityManager_addUidImportanceListener(AActivityManager_onUidImportance onUidImportance,int32_t importanceCutpoint,void * cookie)203*d57664e9SAndroid Build Coastguard Worker AActivityManager_UidImportanceListener* AActivityManager_addUidImportanceListener(
204*d57664e9SAndroid Build Coastguard Worker         AActivityManager_onUidImportance onUidImportance, int32_t importanceCutpoint, void* cookie) {
205*d57664e9SAndroid Build Coastguard Worker     sp<UidObserver> observer(new UidObserver(onUidImportance, importanceCutpoint, cookie));
206*d57664e9SAndroid Build Coastguard Worker     if (observer == nullptr || !observer->registerSelf()) {
207*d57664e9SAndroid Build Coastguard Worker         return nullptr;
208*d57664e9SAndroid Build Coastguard Worker     }
209*d57664e9SAndroid Build Coastguard Worker     observer->incStrong((void *)AActivityManager_addUidImportanceListener);
210*d57664e9SAndroid Build Coastguard Worker     return static_cast<AActivityManager_UidImportanceListener*>(observer.get());
211*d57664e9SAndroid Build Coastguard Worker }
212*d57664e9SAndroid Build Coastguard Worker 
AActivityManager_removeUidImportanceListener(AActivityManager_UidImportanceListener * listener)213*d57664e9SAndroid Build Coastguard Worker void AActivityManager_removeUidImportanceListener(
214*d57664e9SAndroid Build Coastguard Worker         AActivityManager_UidImportanceListener* listener) {
215*d57664e9SAndroid Build Coastguard Worker     if (listener != nullptr) {
216*d57664e9SAndroid Build Coastguard Worker         UidObserver* observer = static_cast<UidObserver*>(listener);
217*d57664e9SAndroid Build Coastguard Worker         observer->unregisterSelf();
218*d57664e9SAndroid Build Coastguard Worker         observer->decStrong((void *)AActivityManager_addUidImportanceListener);
219*d57664e9SAndroid Build Coastguard Worker     }
220*d57664e9SAndroid Build Coastguard Worker }
221*d57664e9SAndroid Build Coastguard Worker 
AActivityManager_isUidActive(uid_t uid)222*d57664e9SAndroid Build Coastguard Worker bool AActivityManager_isUidActive(uid_t uid) {
223*d57664e9SAndroid Build Coastguard Worker     return gAm.isUidActive(uid, getTag());
224*d57664e9SAndroid Build Coastguard Worker }
225*d57664e9SAndroid Build Coastguard Worker 
AActivityManager_getUidImportance(uid_t uid)226*d57664e9SAndroid Build Coastguard Worker int32_t AActivityManager_getUidImportance(uid_t uid) {
227*d57664e9SAndroid Build Coastguard Worker     return UidObserver::procStateToImportance(gAm.getUidProcessState(uid, getTag()));
228*d57664e9SAndroid Build Coastguard Worker }
229*d57664e9SAndroid Build Coastguard Worker 
230