1 /*
2  * Copyright (C) 2019 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 
17 package com.android.server.am;
18 
19 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
20 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT;
21 import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL;
22 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
23 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
24 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
25 import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
26 import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
27 import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
28 import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
29 import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
30 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
31 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
32 import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
33 import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
34 import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
35 import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
36 import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
37 import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
38 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
39 import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
40 import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
41 import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
42 import static android.app.ActivityManager.PROCESS_STATE_TOP;
43 import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
44 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ACTIVITY;
45 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ALLOWLIST;
46 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BACKUP;
47 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BIND_SERVICE;
48 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_COMPONENT_DISABLED;
49 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_EXECUTING_SERVICE;
50 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_FINISH_RECEIVER;
51 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_GET_PROVIDER;
52 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_NONE;
53 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_BEGIN;
54 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_END;
55 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_REMOVE_PROVIDER;
56 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_REMOVE_TASK;
57 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_RESTRICTION_CHANGE;
58 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHELL;
59 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHORT_FGS_TIMEOUT;
60 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_RECEIVER;
61 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_SERVICE;
62 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_STOP_SERVICE;
63 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SYSTEM_INIT;
64 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UID_IDLE;
65 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UI_VISIBILITY;
66 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UNBIND_SERVICE;
67 import static android.content.Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE;
68 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
69 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
70 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
71 import static android.os.Process.SCHED_OTHER;
72 import static android.os.Process.THREAD_GROUP_BACKGROUND;
73 import static android.os.Process.THREAD_GROUP_DEFAULT;
74 import static android.os.Process.THREAD_GROUP_RESTRICTED;
75 import static android.os.Process.THREAD_GROUP_TOP_APP;
76 import static android.os.Process.THREAD_PRIORITY_DISPLAY;
77 import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
78 import static android.os.Process.setProcessGroup;
79 import static android.os.Process.setThreadPriority;
80 import static android.os.Process.setThreadScheduler;
81 
82 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
83 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
84 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
85 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
86 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
87 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
88 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
89 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
90 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
91 import static com.android.server.am.ActivityManagerService.DISPATCH_OOM_ADJ_OBSERVER_MSG;
92 import static com.android.server.am.ActivityManagerService.IDLE_UIDS_MSG;
93 import static com.android.server.am.ActivityManagerService.TAG_BACKUP;
94 import static com.android.server.am.ActivityManagerService.TAG_LRU;
95 import static com.android.server.am.ActivityManagerService.TAG_OOM_ADJ;
96 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
97 import static com.android.server.am.AppProfiler.TAG_PSS;
98 import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_CAMERA_MICROPHONE_CAPABILITY;
99 import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_PROCESS_CAPABILITY;
100 import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME;
101 import static com.android.server.am.ProcessList.BACKUP_APP_ADJ;
102 import static com.android.server.am.ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
103 import static com.android.server.am.ProcessList.CACHED_APP_MAX_ADJ;
104 import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
105 import static com.android.server.am.ProcessList.FOREGROUND_APP_ADJ;
106 import static com.android.server.am.ProcessList.HEAVY_WEIGHT_APP_ADJ;
107 import static com.android.server.am.ProcessList.HOME_APP_ADJ;
108 import static com.android.server.am.ProcessList.INVALID_ADJ;
109 import static com.android.server.am.ProcessList.PERCEPTIBLE_APP_ADJ;
110 import static com.android.server.am.ProcessList.PERCEPTIBLE_LOW_APP_ADJ;
111 import static com.android.server.am.ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ;
112 import static com.android.server.am.ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
113 import static com.android.server.am.ProcessList.PERSISTENT_SERVICE_ADJ;
114 import static com.android.server.am.ProcessList.PREVIOUS_APP_ADJ;
115 import static com.android.server.am.ProcessList.SCHED_GROUP_BACKGROUND;
116 import static com.android.server.am.ProcessList.SCHED_GROUP_DEFAULT;
117 import static com.android.server.am.ProcessList.SCHED_GROUP_RESTRICTED;
118 import static com.android.server.am.ProcessList.SCHED_GROUP_TOP_APP;
119 import static com.android.server.am.ProcessList.SCHED_GROUP_TOP_APP_BOUND;
120 import static com.android.server.am.ProcessList.SERVICE_ADJ;
121 import static com.android.server.am.ProcessList.SERVICE_B_ADJ;
122 import static com.android.server.am.ProcessList.TAG_PROCESS_OBSERVERS;
123 import static com.android.server.am.ProcessList.UNKNOWN_ADJ;
124 import static com.android.server.am.ProcessList.VISIBLE_APP_ADJ;
125 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
126 
127 import android.annotation.Nullable;
128 import android.app.ActivityManager;
129 import android.app.ActivityManagerInternal.OomAdjReason;
130 import android.app.ActivityThread;
131 import android.app.AppProtoEnums;
132 import android.app.ApplicationExitInfo;
133 import android.app.usage.UsageEvents;
134 import android.compat.annotation.ChangeId;
135 import android.compat.annotation.EnabledAfter;
136 import android.compat.annotation.EnabledSince;
137 import android.content.BroadcastReceiver;
138 import android.content.ComponentName;
139 import android.content.Context;
140 import android.content.Intent;
141 import android.content.IntentFilter;
142 import android.content.pm.ApplicationInfo;
143 import android.content.pm.ServiceInfo;
144 import android.net.NetworkPolicyManager;
145 import android.os.Handler;
146 import android.os.IBinder;
147 import android.os.PowerManagerInternal;
148 import android.os.Process;
149 import android.os.RemoteException;
150 import android.os.SystemClock;
151 import android.os.Trace;
152 import android.util.ArrayMap;
153 import android.util.ArraySet;
154 import android.util.Slog;
155 import android.util.proto.ProtoOutputStream;
156 
157 import com.android.internal.annotations.CompositeRWLock;
158 import com.android.internal.annotations.GuardedBy;
159 import com.android.internal.annotations.VisibleForTesting;
160 import com.android.server.LocalServices;
161 import com.android.server.ServiceThread;
162 import com.android.server.am.PlatformCompatCache.CachedCompatChangeId;
163 import com.android.server.wm.ActivityServiceConnectionsHolder;
164 import com.android.server.wm.WindowProcessController;
165 
166 import java.io.PrintWriter;
167 import java.util.ArrayDeque;
168 import java.util.ArrayList;
169 import java.util.Arrays;
170 import java.util.List;
171 
172 /**
173  * All of the code required to compute proc states and oom_adj values.
174  */
175 public class OomAdjuster {
176     static final String TAG = "OomAdjuster";
177 
oomAdjReasonToProto(@omAdjReason int oomReason)178     public static final int oomAdjReasonToProto(@OomAdjReason int oomReason) {
179         switch (oomReason) {
180             case OOM_ADJ_REASON_NONE:
181                 return AppProtoEnums.OOM_ADJ_REASON_NONE;
182             case OOM_ADJ_REASON_ACTIVITY:
183                 return AppProtoEnums.OOM_ADJ_REASON_ACTIVITY;
184             case OOM_ADJ_REASON_FINISH_RECEIVER:
185                 return AppProtoEnums.OOM_ADJ_REASON_FINISH_RECEIVER;
186             case OOM_ADJ_REASON_START_RECEIVER:
187                 return AppProtoEnums.OOM_ADJ_REASON_START_RECEIVER;
188             case OOM_ADJ_REASON_BIND_SERVICE:
189                 return AppProtoEnums.OOM_ADJ_REASON_BIND_SERVICE;
190             case OOM_ADJ_REASON_UNBIND_SERVICE:
191                 return AppProtoEnums.OOM_ADJ_REASON_UNBIND_SERVICE;
192             case OOM_ADJ_REASON_START_SERVICE:
193                 return AppProtoEnums.OOM_ADJ_REASON_START_SERVICE;
194             case OOM_ADJ_REASON_GET_PROVIDER:
195                 return AppProtoEnums.OOM_ADJ_REASON_GET_PROVIDER;
196             case OOM_ADJ_REASON_REMOVE_PROVIDER:
197                 return AppProtoEnums.OOM_ADJ_REASON_REMOVE_PROVIDER;
198             case OOM_ADJ_REASON_UI_VISIBILITY:
199                 return AppProtoEnums.OOM_ADJ_REASON_UI_VISIBILITY;
200             case OOM_ADJ_REASON_ALLOWLIST:
201                 return AppProtoEnums.OOM_ADJ_REASON_ALLOWLIST;
202             case OOM_ADJ_REASON_PROCESS_BEGIN:
203                 return AppProtoEnums.OOM_ADJ_REASON_PROCESS_BEGIN;
204             case OOM_ADJ_REASON_PROCESS_END:
205                 return AppProtoEnums.OOM_ADJ_REASON_PROCESS_END;
206             case OOM_ADJ_REASON_SHORT_FGS_TIMEOUT:
207                 return AppProtoEnums.OOM_ADJ_REASON_SHORT_FGS_TIMEOUT;
208             case OOM_ADJ_REASON_SYSTEM_INIT:
209                 return AppProtoEnums.OOM_ADJ_REASON_SYSTEM_INIT;
210             case OOM_ADJ_REASON_BACKUP:
211                 return AppProtoEnums.OOM_ADJ_REASON_BACKUP;
212             case OOM_ADJ_REASON_SHELL:
213                 return AppProtoEnums.OOM_ADJ_REASON_SHELL;
214             case OOM_ADJ_REASON_REMOVE_TASK:
215                 return AppProtoEnums.OOM_ADJ_REASON_REMOVE_TASK;
216             case OOM_ADJ_REASON_UID_IDLE:
217                 return AppProtoEnums.OOM_ADJ_REASON_UID_IDLE;
218             case OOM_ADJ_REASON_STOP_SERVICE:
219                 return AppProtoEnums.OOM_ADJ_REASON_STOP_SERVICE;
220             case OOM_ADJ_REASON_EXECUTING_SERVICE:
221                 return AppProtoEnums.OOM_ADJ_REASON_EXECUTING_SERVICE;
222             case OOM_ADJ_REASON_RESTRICTION_CHANGE:
223                 return AppProtoEnums.OOM_ADJ_REASON_RESTRICTION_CHANGE;
224             case OOM_ADJ_REASON_COMPONENT_DISABLED:
225                 return AppProtoEnums.OOM_ADJ_REASON_COMPONENT_DISABLED;
226             default:
227                 return AppProtoEnums.OOM_ADJ_REASON_UNKNOWN_TO_PROTO;
228         }
229     }
230 
oomAdjReasonToString(@omAdjReason int oomReason)231     public static final String oomAdjReasonToString(@OomAdjReason int oomReason) {
232         final String OOM_ADJ_REASON_METHOD = "updateOomAdj";
233         switch (oomReason) {
234             case OOM_ADJ_REASON_NONE:
235                 return OOM_ADJ_REASON_METHOD + "_meh";
236             case OOM_ADJ_REASON_ACTIVITY:
237                 return OOM_ADJ_REASON_METHOD + "_activityChange";
238             case OOM_ADJ_REASON_FINISH_RECEIVER:
239                 return OOM_ADJ_REASON_METHOD + "_finishReceiver";
240             case OOM_ADJ_REASON_START_RECEIVER:
241                 return OOM_ADJ_REASON_METHOD + "_startReceiver";
242             case OOM_ADJ_REASON_BIND_SERVICE:
243                 return OOM_ADJ_REASON_METHOD + "_bindService";
244             case OOM_ADJ_REASON_UNBIND_SERVICE:
245                 return OOM_ADJ_REASON_METHOD + "_unbindService";
246             case OOM_ADJ_REASON_START_SERVICE:
247                 return OOM_ADJ_REASON_METHOD + "_startService";
248             case OOM_ADJ_REASON_GET_PROVIDER:
249                 return OOM_ADJ_REASON_METHOD + "_getProvider";
250             case OOM_ADJ_REASON_REMOVE_PROVIDER:
251                 return OOM_ADJ_REASON_METHOD + "_removeProvider";
252             case OOM_ADJ_REASON_UI_VISIBILITY:
253                 return OOM_ADJ_REASON_METHOD + "_uiVisibility";
254             case OOM_ADJ_REASON_ALLOWLIST:
255                 return OOM_ADJ_REASON_METHOD + "_allowlistChange";
256             case OOM_ADJ_REASON_PROCESS_BEGIN:
257                 return OOM_ADJ_REASON_METHOD + "_processBegin";
258             case OOM_ADJ_REASON_PROCESS_END:
259                 return OOM_ADJ_REASON_METHOD + "_processEnd";
260             case OOM_ADJ_REASON_SHORT_FGS_TIMEOUT:
261                 return OOM_ADJ_REASON_METHOD + "_shortFgs";
262             case OOM_ADJ_REASON_SYSTEM_INIT:
263                 return OOM_ADJ_REASON_METHOD + "_systemInit";
264             case OOM_ADJ_REASON_BACKUP:
265                 return OOM_ADJ_REASON_METHOD + "_backup";
266             case OOM_ADJ_REASON_SHELL:
267                 return OOM_ADJ_REASON_METHOD + "_shell";
268             case OOM_ADJ_REASON_REMOVE_TASK:
269                 return OOM_ADJ_REASON_METHOD + "_removeTask";
270             case OOM_ADJ_REASON_UID_IDLE:
271                 return OOM_ADJ_REASON_METHOD + "_uidIdle";
272             case OOM_ADJ_REASON_STOP_SERVICE:
273                 return OOM_ADJ_REASON_METHOD + "_stopService";
274             case OOM_ADJ_REASON_EXECUTING_SERVICE:
275                 return OOM_ADJ_REASON_METHOD + "_executingService";
276             case OOM_ADJ_REASON_RESTRICTION_CHANGE:
277                 return OOM_ADJ_REASON_METHOD + "_restrictionChange";
278             case OOM_ADJ_REASON_COMPONENT_DISABLED:
279                 return OOM_ADJ_REASON_METHOD + "_componentDisabled";
280             default:
281                 return "_unknown";
282         }
283     }
284 
285     /**
286      * Flag {@link android.content.Context#BIND_INCLUDE_CAPABILITIES} is used
287      * to pass while-in-use capabilities from client process to bound service. In targetSdkVersion
288      * R and above, if client is a TOP activity, when this flag is present, bound service gets all
289      * while-in-use capabilities; when this flag is not present, bound service gets no while-in-use
290      * capability from client.
291      */
292     @ChangeId
293     @EnabledAfter(targetSdkVersion=android.os.Build.VERSION_CODES.Q)
294     static final long PROCESS_CAPABILITY_CHANGE_ID = 136274596L;
295 
296     /**
297      * In targetSdkVersion R and above, foreground service has camera and microphone while-in-use
298      * capability only when the {@link android.R.attr#foregroundServiceType} is configured as
299      * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_CAMERA} and
300      * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE} respectively in the
301      * manifest file.
302      * In targetSdkVersion below R, foreground service automatically have camera and microphone
303      * capabilities.
304      */
305     @ChangeId
306     @EnabledAfter(targetSdkVersion=android.os.Build.VERSION_CODES.Q)
307     static final long CAMERA_MICROPHONE_CAPABILITY_CHANGE_ID = 136219221L;
308 
309     /**
310      * For apps targeting S+, this determines whether to use a shorter timeout before elevating the
311      * standby bucket to ACTIVE when apps start a foreground service.
312      */
313     @ChangeId
314     @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S)
315     static final long USE_SHORT_FGS_USAGE_INTERACTION_TIME = 183972877L;
316 
317     /**
318      * For some direct access we need to power manager.
319      */
320     PowerManagerInternal mLocalPowerManager;
321 
322     /**
323      * Service for optimizing resource usage from background apps.
324      */
325     CachedAppOptimizer mCachedAppOptimizer;
326 
327     /**
328      * Re-rank apps getting a cache oom adjustment from lru to weighted order
329      * based on weighted scores for LRU, PSS and cache use count.
330      */
331     CacheOomRanker mCacheOomRanker;
332 
333     ActivityManagerConstants mConstants;
334 
335     final long[] mTmpLong = new long[3];
336 
337     /**
338      * Current sequence id for oom_adj computation traversal.
339      */
340     int mAdjSeq = 0;
341 
342     /**
343      * Keep track of the number of service processes we last found, to
344      * determine on the next iteration which should be B services.
345      */
346     int mNumServiceProcs = 0;
347     int mNewNumAServiceProcs = 0;
348     int mNewNumServiceProcs = 0;
349 
350     /**
351      * Keep track of the non-cached/empty process we last found, to help
352      * determine how to distribute cached/empty processes next time.
353      */
354     int mNumNonCachedProcs = 0;
355 
356     /**
357      * Keep track of the number of cached hidden procs, to balance oom adj
358      * distribution between those and empty procs.
359      */
360     int mNumCachedHiddenProcs = 0;
361 
362     /** Track all uids that have actively running processes. */
363     @CompositeRWLock({"mService", "mProcLock"})
364     ActiveUids mActiveUids;
365 
366     /**
367      * The handler to execute {@link #setProcessGroup} (it may be heavy if the process has many
368      * threads) for reducing the time spent in {@link #applyOomAdjLSP}.
369      */
370     private final Handler mProcessGroupHandler;
371 
372     private final int[] mTmpSchedGroup = new int[1];
373 
374     private final ActivityManagerService mService;
375     private final ProcessList mProcessList;
376     private final ActivityManagerGlobalLock mProcLock;
377 
378     private final int mNumSlots;
379     private final ArrayList<ProcessRecord> mTmpProcessList = new ArrayList<ProcessRecord>();
380     private final ArrayList<UidRecord> mTmpBecameIdle = new ArrayList<UidRecord>();
381     private final ActiveUids mTmpUidRecords;
382     private final ArrayDeque<ProcessRecord> mTmpQueue;
383     private final ArraySet<ProcessRecord> mTmpProcessSet = new ArraySet<>();
384     private final ArraySet<ProcessRecord> mPendingProcessSet = new ArraySet<>();
385     private final ArraySet<ProcessRecord> mProcessesInCycle = new ArraySet<>();
386 
387     /**
388      * Flag to mark if there is an ongoing oomAdjUpdate: potentially the oomAdjUpdate
389      * could be called recursively because of the indirect calls during the update;
390      * however the oomAdjUpdate itself doesn't support recursion - in this case we'd
391      * have to queue up the new targets found during the update, and perform another
392      * round of oomAdjUpdate at the end of last update.
393      */
394     @GuardedBy("mService")
395     private boolean mOomAdjUpdateOngoing = false;
396 
397     /**
398      * Flag to mark if there is a pending full oomAdjUpdate.
399      */
400     @GuardedBy("mService")
401     private boolean mPendingFullOomAdjUpdate = false;
402 
403     /** Overrideable by a test */
404     @VisibleForTesting
isChangeEnabled(@achedCompatChangeId int cachedCompatChangeId, ApplicationInfo app, boolean defaultValue)405     protected boolean isChangeEnabled(@CachedCompatChangeId int cachedCompatChangeId,
406             ApplicationInfo app, boolean defaultValue) {
407         return PlatformCompatCache.getInstance()
408                 .isChangeEnabled(cachedCompatChangeId, app, defaultValue);
409     }
410 
OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids)411     OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids) {
412         this(service, processList, activeUids, createAdjusterThread());
413     }
414 
createAdjusterThread()415     private static ServiceThread createAdjusterThread() {
416         // The process group is usually critical to the response time of foreground app, so the
417         // setter should apply it as soon as possible.
418         final ServiceThread adjusterThread =
419                 new ServiceThread(TAG, THREAD_PRIORITY_TOP_APP_BOOST, false /* allowIo */);
420         adjusterThread.start();
421         return adjusterThread;
422     }
423 
OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, ServiceThread adjusterThread)424     OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids,
425             ServiceThread adjusterThread) {
426         mService = service;
427         mProcessList = processList;
428         mProcLock = service.mProcLock;
429         mActiveUids = activeUids;
430 
431         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
432         mConstants = mService.mConstants;
433         mCachedAppOptimizer = new CachedAppOptimizer(mService);
434         mCacheOomRanker = new CacheOomRanker(service);
435 
436         mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> {
437             final int pid = msg.arg1;
438             final int group = msg.arg2;
439             if (pid == ActivityManagerService.MY_PID) {
440                 // Skip setting the process group for system_server, keep it as default.
441                 return true;
442             }
443             if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
444                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup "
445                         + msg.obj + " to " + group);
446             }
447             try {
448                 setProcessGroup(pid, group);
449             } catch (Exception e) {
450                 if (DEBUG_ALL) {
451                     Slog.w(TAG, "Failed setting process group of " + pid + " to " + group, e);
452                 }
453             } finally {
454                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
455             }
456             return true;
457         });
458         mTmpUidRecords = new ActiveUids(service, false);
459         mTmpQueue = new ArrayDeque<ProcessRecord>(mConstants.CUR_MAX_CACHED_PROCESSES << 1);
460         mNumSlots = ((CACHED_APP_MAX_ADJ - CACHED_APP_MIN_ADJ + 1) >> 1)
461                 / CACHED_APP_IMPORTANCE_LEVELS;
462     }
463 
initSettings()464     void initSettings() {
465         mCachedAppOptimizer.init();
466         mCacheOomRanker.init(ActivityThread.currentApplication().getMainExecutor());
467         if (mService.mConstants.KEEP_WARMING_SERVICES.size() > 0) {
468             final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
469             mService.mContext.registerReceiverForAllUsers(new BroadcastReceiver() {
470                 @Override
471                 public void onReceive(Context context, Intent intent) {
472                     synchronized (mService) {
473                         handleUserSwitchedLocked();
474                     }
475                 }
476             }, filter, null, mService.mHandler);
477         }
478     }
479 
480     /**
481      * Update the keep-warming service flags upon user switches
482      */
483     @VisibleForTesting
484     @GuardedBy("mService")
handleUserSwitchedLocked()485     void handleUserSwitchedLocked() {
486         mProcessList.forEachLruProcessesLOSP(false,
487                 this::updateKeepWarmIfNecessaryForProcessLocked);
488     }
489 
490     @GuardedBy("mService")
updateKeepWarmIfNecessaryForProcessLocked(final ProcessRecord app)491     private void updateKeepWarmIfNecessaryForProcessLocked(final ProcessRecord app) {
492         final ArraySet<ComponentName> warmServices = mService.mConstants.KEEP_WARMING_SERVICES;
493         boolean includeWarmPkg = false;
494         final PackageList pkgList = app.getPkgList();
495         for (int j = warmServices.size() - 1; j >= 0; j--) {
496             if (pkgList.containsKey(warmServices.valueAt(j).getPackageName())) {
497                 includeWarmPkg = true;
498                 break;
499             }
500         }
501         if (!includeWarmPkg) {
502             return;
503         }
504         final ProcessServiceRecord psr = app.mServices;
505         for (int j = psr.numberOfRunningServices() - 1; j >= 0; j--) {
506             psr.getRunningServiceAt(j).updateKeepWarmLocked();
507         }
508     }
509 
510     /**
511      * Perform oom adj update on the given process. It does NOT do the re-computation
512      * if there is a cycle, caller should check {@link #mProcessesInCycle} and do it on its own.
513      */
514     @GuardedBy({"mService", "mProcLock"})
performUpdateOomAdjLSP(ProcessRecord app, int cachedAdj, ProcessRecord topApp, long now, @OomAdjReason int oomAdjReason)515     private boolean performUpdateOomAdjLSP(ProcessRecord app, int cachedAdj,
516             ProcessRecord topApp, long now, @OomAdjReason int oomAdjReason) {
517         if (app.getThread() == null) {
518             return false;
519         }
520 
521         app.mState.resetCachedInfo();
522         app.mState.setCurBoundByNonBgRestrictedApp(false);
523         UidRecord uidRec = app.getUidRecord();
524         if (uidRec != null) {
525             if (DEBUG_UID_OBSERVERS) {
526                 Slog.i(TAG_UID_OBSERVERS, "Starting update of " + uidRec);
527             }
528             uidRec.reset();
529         }
530 
531         // Check if this process is in the pending list too, remove from pending list if so.
532         mPendingProcessSet.remove(app);
533 
534         mProcessesInCycle.clear();
535         computeOomAdjLSP(app, cachedAdj, topApp, false, now, false, true);
536         if (!mProcessesInCycle.isEmpty()) {
537             // We can't use the score here if there is a cycle, abort.
538             for (int i = mProcessesInCycle.size() - 1; i >= 0; i--) {
539                 // Reset the adj seq
540                 mProcessesInCycle.valueAt(i).mState.setCompletedAdjSeq(mAdjSeq - 1);
541             }
542             return true;
543         }
544 
545         if (uidRec != null) {
546             // After uidRec.reset() above, for UidRecord with multiple processes (ProcessRecord),
547             // we need to apply all ProcessRecord into UidRecord.
548             uidRec.forEachProcess(this::updateAppUidRecIfNecessaryLSP);
549             if (uidRec.getCurProcState() != PROCESS_STATE_NONEXISTENT
550                     && (uidRec.getSetProcState() != uidRec.getCurProcState()
551                     || uidRec.getSetCapability() != uidRec.getCurCapability()
552                     || uidRec.isSetAllowListed() != uidRec.isCurAllowListed())) {
553                 ActiveUids uids = mTmpUidRecords;
554                 uids.clear();
555                 uids.put(uidRec.getUid(), uidRec);
556                 updateUidsLSP(uids, SystemClock.elapsedRealtime());
557             }
558         }
559 
560         return applyOomAdjLSP(app, false, now, SystemClock.elapsedRealtime(), oomAdjReason);
561     }
562 
563     /**
564      * Update OomAdj for all processes in LRU list
565      */
566     @GuardedBy("mService")
updateOomAdjLocked(@omAdjReason int oomAdjReason)567     void updateOomAdjLocked(@OomAdjReason int oomAdjReason) {
568         synchronized (mProcLock) {
569             updateOomAdjLSP(oomAdjReason);
570         }
571     }
572 
573     @GuardedBy({"mService", "mProcLock"})
updateOomAdjLSP(@omAdjReason int oomAdjReason)574     private void updateOomAdjLSP(@OomAdjReason int oomAdjReason) {
575         if (checkAndEnqueueOomAdjTargetLocked(null)) {
576             // Simply return as there is an oomAdjUpdate ongoing
577             return;
578         }
579         try {
580             mOomAdjUpdateOngoing = true;
581             performUpdateOomAdjLSP(oomAdjReason);
582         } finally {
583             // Kick off the handling of any pending targets enqueued during the above update
584             mOomAdjUpdateOngoing = false;
585             updateOomAdjPendingTargetsLocked(oomAdjReason);
586         }
587     }
588 
589     @GuardedBy({"mService", "mProcLock"})
performUpdateOomAdjLSP(@omAdjReason int oomAdjReason)590     private void performUpdateOomAdjLSP(@OomAdjReason int oomAdjReason) {
591         final ProcessRecord topApp = mService.getTopApp();
592         // Clear any pending ones because we are doing a full update now.
593         mPendingProcessSet.clear();
594         mService.mAppProfiler.mHasPreviousProcess = mService.mAppProfiler.mHasHomeProcess = false;
595         updateOomAdjInnerLSP(oomAdjReason, topApp , null, null, true, true);
596     }
597 
598     /**
599      * Update OomAdj for specific process and its reachable processes (with direction/indirect
600      * bindings from this process); Note its clients' proc state won't be re-evaluated if this proc
601      * is hosting any service/content provider.
602      *
603      * @param app The process to update, or null to update all processes
604      * @param oomAdjReason
605      */
606     @GuardedBy("mService")
updateOomAdjLocked(ProcessRecord app, @OomAdjReason int oomAdjReason)607     boolean updateOomAdjLocked(ProcessRecord app, @OomAdjReason int oomAdjReason) {
608         synchronized (mProcLock) {
609             return updateOomAdjLSP(app, oomAdjReason);
610         }
611     }
612 
613     @GuardedBy({"mService", "mProcLock"})
updateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason)614     private boolean updateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason) {
615         if (app == null || !mConstants.OOMADJ_UPDATE_QUICK) {
616             updateOomAdjLSP(oomAdjReason);
617             return true;
618         }
619 
620         if (checkAndEnqueueOomAdjTargetLocked(app)) {
621             // Simply return true as there is an oomAdjUpdate ongoing
622             return true;
623         }
624 
625         try {
626             mOomAdjUpdateOngoing = true;
627             return performUpdateOomAdjLSP(app, oomAdjReason);
628         } finally {
629             // Kick off the handling of any pending targets enqueued during the above update
630             mOomAdjUpdateOngoing = false;
631             updateOomAdjPendingTargetsLocked(oomAdjReason);
632         }
633     }
634 
635     @GuardedBy({"mService", "mProcLock"})
performUpdateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason)636     private boolean performUpdateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason) {
637         final ProcessRecord topApp = mService.getTopApp();
638 
639         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason));
640         mService.mOomAdjProfiler.oomAdjStarted();
641         mAdjSeq++;
642 
643         // Firstly, try to see if the importance of itself gets changed
644         final ProcessStateRecord state = app.mState;
645         final boolean wasCached = state.isCached();
646         final int oldAdj = state.getCurRawAdj();
647         final int cachedAdj = oldAdj >= CACHED_APP_MIN_ADJ
648                 ? oldAdj : UNKNOWN_ADJ;
649         final boolean wasBackground = ActivityManager.isProcStateBackground(
650                 state.getSetProcState());
651         final int oldCap = state.getSetCapability();
652         state.setContainsCycle(false);
653         state.setProcStateChanged(false);
654         state.resetCachedInfo();
655         state.setCurBoundByNonBgRestrictedApp(false);
656         // Check if this process is in the pending list too, remove from pending list if so.
657         mPendingProcessSet.remove(app);
658         app.mOptRecord.setLastOomAdjChangeReason(oomAdjReason);
659         boolean success = performUpdateOomAdjLSP(app, cachedAdj, topApp,
660                 SystemClock.uptimeMillis(), oomAdjReason);
661         // The 'app' here itself might or might not be in the cycle, for example,
662         // the case A <=> B vs. A -> B <=> C; anyway, if we spot a cycle here, re-compute them.
663         if (!success || (wasCached == state.isCached() && oldAdj != INVALID_ADJ
664                 && mProcessesInCycle.isEmpty() /* Force re-compute if there is a cycle */
665                 && oldCap == state.getCurCapability()
666                 && wasBackground == ActivityManager.isProcStateBackground(
667                         state.getSetProcState()))) {
668             mProcessesInCycle.clear();
669             // Okay, it's unchanged, it won't impact any service it binds to, we're done here.
670             if (DEBUG_OOM_ADJ) {
671                 Slog.i(TAG_OOM_ADJ, "No oomadj changes for " + app);
672             }
673             mService.mOomAdjProfiler.oomAdjEnded();
674             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
675             return success;
676         }
677 
678         // Next to find out all its reachable processes
679         ArrayList<ProcessRecord> processes = mTmpProcessList;
680         ActiveUids uids = mTmpUidRecords;
681         mPendingProcessSet.add(app);
682 
683         // Add all processes with cycles into the list to scan
684         for (int i = mProcessesInCycle.size() - 1; i >= 0; i--) {
685             mPendingProcessSet.add(mProcessesInCycle.valueAt(i));
686         }
687         mProcessesInCycle.clear();
688 
689         boolean containsCycle = collectReachableProcessesLocked(mPendingProcessSet,
690                 processes, uids);
691 
692         // Clear the pending set as they should've been included in 'processes'.
693         mPendingProcessSet.clear();
694 
695         if (!containsCycle) {
696             // Reset the flag
697             state.setReachable(false);
698             // Remove this app from the return list because we've done the computation on it.
699             processes.remove(app);
700         }
701 
702         int size = processes.size();
703         if (size > 0) {
704             mAdjSeq--;
705             // Update these reachable processes
706             updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, containsCycle, false);
707         } else if (state.getCurRawAdj() == UNKNOWN_ADJ) {
708             // In case the app goes from non-cached to cached but it doesn't have other reachable
709             // processes, its adj could be still unknown as of now, assign one.
710             processes.add(app);
711             assignCachedAdjIfNecessary(processes);
712             applyOomAdjLSP(app, false, SystemClock.uptimeMillis(),
713                     SystemClock.elapsedRealtime(), oomAdjReason);
714         }
715         mTmpProcessList.clear();
716         mService.mOomAdjProfiler.oomAdjEnded();
717         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
718         return true;
719     }
720 
721     @GuardedBy("mService")
collectReachableProcessesLocked(ArraySet<ProcessRecord> apps, ArrayList<ProcessRecord> processes, ActiveUids uids)722     private boolean collectReachableProcessesLocked(ArraySet<ProcessRecord> apps,
723             ArrayList<ProcessRecord> processes, ActiveUids uids) {
724         final ArrayDeque<ProcessRecord> queue = mTmpQueue;
725         queue.clear();
726         processes.clear();
727         for (int i = 0, size = apps.size(); i < size; i++) {
728             final ProcessRecord app = apps.valueAt(i);
729             app.mState.setReachable(true);
730             queue.offer(app);
731         }
732 
733         uids.clear();
734 
735         // Track if any of them reachables could include a cycle
736         boolean containsCycle = false;
737         // Scan downstreams of the process record
738         for (ProcessRecord pr = queue.poll(); pr != null; pr = queue.poll()) {
739             processes.add(pr);
740             final UidRecord uidRec = pr.getUidRecord();
741             if (uidRec != null) {
742                 uids.put(uidRec.getUid(), uidRec);
743             }
744             final ProcessServiceRecord psr = pr.mServices;
745             for (int i = psr.numberOfConnections() - 1; i >= 0; i--) {
746                 ConnectionRecord cr = psr.getConnectionAt(i);
747                 ProcessRecord service = cr.hasFlag(ServiceInfo.FLAG_ISOLATED_PROCESS)
748                         ? cr.binding.service.isolationHostProc : cr.binding.service.app;
749                 if (service == null || service == pr
750                         || ((service.mState.getMaxAdj() >= ProcessList.SYSTEM_ADJ)
751                                 && (service.mState.getMaxAdj() < FOREGROUND_APP_ADJ))) {
752                     continue;
753                 }
754                 containsCycle |= service.mState.isReachable();
755                 if (service.mState.isReachable()) {
756                     continue;
757                 }
758                 if (cr.hasFlag(Context.BIND_WAIVE_PRIORITY)
759                         && cr.notHasFlag(Context.BIND_TREAT_LIKE_ACTIVITY
760                         | Context.BIND_ADJUST_WITH_ACTIVITY)) {
761                     continue;
762                 }
763                 queue.offer(service);
764                 service.mState.setReachable(true);
765             }
766             final ProcessProviderRecord ppr = pr.mProviders;
767             for (int i = ppr.numberOfProviderConnections() - 1; i >= 0; i--) {
768                 ContentProviderConnection cpc = ppr.getProviderConnectionAt(i);
769                 ProcessRecord provider = cpc.provider.proc;
770                 if (provider == null || provider == pr
771                         || ((provider.mState.getMaxAdj() >= ProcessList.SYSTEM_ADJ)
772                                 && (provider.mState.getMaxAdj() < FOREGROUND_APP_ADJ))) {
773                     continue;
774                 }
775                 containsCycle |= provider.mState.isReachable();
776                 if (provider.mState.isReachable()) {
777                     continue;
778                 }
779                 queue.offer(provider);
780                 provider.mState.setReachable(true);
781             }
782             // See if this process has any corresponding SDK sandbox processes running, and if so
783             // scan them as well.
784             final List<ProcessRecord> sdkSandboxes =
785                     mProcessList.getSdkSandboxProcessesForAppLocked(pr.uid);
786             final int numSdkSandboxes = sdkSandboxes != null ? sdkSandboxes.size() : 0;
787             for (int i = numSdkSandboxes - 1; i >= 0; i--) {
788                 ProcessRecord sdkSandbox = sdkSandboxes.get(i);
789                 containsCycle |= sdkSandbox.mState.isReachable();
790                 if (sdkSandbox.mState.isReachable()) {
791                     continue;
792                 }
793                 queue.offer(sdkSandbox);
794                 sdkSandbox.mState.setReachable(true);
795             }
796             // If this process is a sandbox itself, also scan the app on whose behalf its running
797             if (pr.isSdkSandbox) {
798                 for (int is = psr.numberOfRunningServices() - 1; is >= 0; is--) {
799                     ServiceRecord s = psr.getRunningServiceAt(is);
800                     ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections =
801                             s.getConnections();
802                     for (int conni = serviceConnections.size() - 1; conni >= 0; conni--) {
803                         ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni);
804                         for (int i = clist.size() - 1; i >= 0; i--) {
805                             ConnectionRecord cr = clist.get(i);
806                             ProcessRecord attributedApp = cr.binding.attributedClient;
807                             if (attributedApp == null || attributedApp == pr
808                                     || ((attributedApp.mState.getMaxAdj() >= ProcessList.SYSTEM_ADJ)
809                                     && (attributedApp.mState.getMaxAdj() < FOREGROUND_APP_ADJ))) {
810                                 continue;
811                             }
812                             if (attributedApp.mState.isReachable()) {
813                                 continue;
814                             }
815                             queue.offer(attributedApp);
816                             attributedApp.mState.setReachable(true);
817                         }
818                     }
819                 }
820             }
821         }
822 
823         int size = processes.size();
824         if (size > 0) {
825             // Reverse the process list, since the updateOomAdjInnerLSP scans from the end of it.
826             for (int l = 0, r = size - 1; l < r; l++, r--) {
827                 ProcessRecord t = processes.get(l);
828                 processes.set(l, processes.get(r));
829                 processes.set(r, t);
830             }
831         }
832         return containsCycle;
833     }
834 
835     /**
836      * Enqueue the given process for a later oom adj update
837      */
838     @GuardedBy("mService")
enqueueOomAdjTargetLocked(ProcessRecord app)839     void enqueueOomAdjTargetLocked(ProcessRecord app) {
840         if (app != null && app.mState.getMaxAdj() > FOREGROUND_APP_ADJ) {
841             mPendingProcessSet.add(app);
842         }
843     }
844 
845     @GuardedBy("mService")
removeOomAdjTargetLocked(ProcessRecord app, boolean procDied)846     void removeOomAdjTargetLocked(ProcessRecord app, boolean procDied) {
847         if (app != null) {
848             mPendingProcessSet.remove(app);
849             if (procDied) {
850                 PlatformCompatCache.getInstance().invalidate(app.info);
851             }
852         }
853     }
854 
855     /**
856      * Check if there is an ongoing oomAdjUpdate, enqueue the given process record
857      * to {@link #mPendingProcessSet} if there is one.
858      *
859      * @param app The target app to get an oomAdjUpdate, or a full oomAdjUpdate if it's null.
860      * @return {@code true} if there is an ongoing oomAdjUpdate.
861      */
862     @GuardedBy("mService")
checkAndEnqueueOomAdjTargetLocked(@ullable ProcessRecord app)863     private boolean checkAndEnqueueOomAdjTargetLocked(@Nullable ProcessRecord app) {
864         if (!mOomAdjUpdateOngoing) {
865             return false;
866         }
867         if (app != null) {
868             mPendingProcessSet.add(app);
869         } else {
870             mPendingFullOomAdjUpdate = true;
871         }
872         return true;
873     }
874 
875     /**
876      * Kick off an oom adj update pass for the pending targets which are enqueued via
877      * {@link #enqueueOomAdjTargetLocked}.
878      */
879     @GuardedBy("mService")
updateOomAdjPendingTargetsLocked(@omAdjReason int oomAdjReason)880     void updateOomAdjPendingTargetsLocked(@OomAdjReason int oomAdjReason) {
881         // First check if there is pending full update
882         if (mPendingFullOomAdjUpdate) {
883             mPendingFullOomAdjUpdate = false;
884             mPendingProcessSet.clear();
885             updateOomAdjLocked(oomAdjReason);
886             return;
887         }
888         if (mPendingProcessSet.isEmpty()) {
889             return;
890         }
891 
892         if (mOomAdjUpdateOngoing) {
893             // There's another oomAdjUpdate ongoing, return from here now;
894             // that ongoing update would call us again at the end of it.
895             return;
896         }
897         try {
898             mOomAdjUpdateOngoing = true;
899             performUpdateOomAdjPendingTargetsLocked(oomAdjReason);
900         } finally {
901             // Kick off the handling of any pending targets enqueued during the above update
902             mOomAdjUpdateOngoing = false;
903             updateOomAdjPendingTargetsLocked(oomAdjReason);
904         }
905     }
906 
907     @GuardedBy("mService")
performUpdateOomAdjPendingTargetsLocked(@omAdjReason int oomAdjReason)908     private void performUpdateOomAdjPendingTargetsLocked(@OomAdjReason int oomAdjReason) {
909         final ProcessRecord topApp = mService.getTopApp();
910 
911         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason));
912         mService.mOomAdjProfiler.oomAdjStarted();
913 
914         final ArrayList<ProcessRecord> processes = mTmpProcessList;
915         final ActiveUids uids = mTmpUidRecords;
916         collectReachableProcessesLocked(mPendingProcessSet, processes, uids);
917         mPendingProcessSet.clear();
918         synchronized (mProcLock) {
919             updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, true, false);
920         }
921         processes.clear();
922 
923         mService.mOomAdjProfiler.oomAdjEnded();
924         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
925     }
926 
927     /**
928      * Update OomAdj for all processes within the given list (could be partial), or the whole LRU
929      * list if the given list is null; when it's partial update, each process's client proc won't
930      * get evaluated recursively here.
931      */
932     @GuardedBy({"mService", "mProcLock"})
updateOomAdjInnerLSP(@omAdjReason int oomAdjReason, final ProcessRecord topApp, ArrayList<ProcessRecord> processes, ActiveUids uids, boolean potentialCycles, boolean startProfiling)933     private void updateOomAdjInnerLSP(@OomAdjReason int oomAdjReason, final ProcessRecord topApp,
934             ArrayList<ProcessRecord> processes, ActiveUids uids, boolean potentialCycles,
935             boolean startProfiling) {
936         if (startProfiling) {
937             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason));
938             mService.mOomAdjProfiler.oomAdjStarted();
939         }
940         final long now = SystemClock.uptimeMillis();
941         final long nowElapsed = SystemClock.elapsedRealtime();
942         final long oldTime = now - mConstants.mMaxEmptyTimeMillis;
943         final boolean fullUpdate = processes == null;
944         ActiveUids activeUids = uids;
945         ArrayList<ProcessRecord> activeProcesses = fullUpdate ? mProcessList.getLruProcessesLOSP()
946                 : processes;
947         final int numProc = activeProcesses.size();
948 
949         if (activeUids == null) {
950             final int numUids = mActiveUids.size();
951             activeUids = mTmpUidRecords;
952             activeUids.clear();
953             for (int i = 0; i < numUids; i++) {
954                 UidRecord uidRec = mActiveUids.valueAt(i);
955                 activeUids.put(uidRec.getUid(), uidRec);
956             }
957         }
958 
959         // Reset state in all uid records.
960         for (int  i = activeUids.size() - 1; i >= 0; i--) {
961             final UidRecord uidRec = activeUids.valueAt(i);
962             if (DEBUG_UID_OBSERVERS) {
963                 Slog.i(TAG_UID_OBSERVERS, "Starting update of " + uidRec);
964             }
965             uidRec.reset();
966         }
967 
968         mAdjSeq++;
969         if (fullUpdate) {
970             mNewNumServiceProcs = 0;
971             mNewNumAServiceProcs = 0;
972         }
973 
974         boolean retryCycles = false;
975         boolean computeClients = fullUpdate || potentialCycles;
976 
977         // need to reset cycle state before calling computeOomAdjLSP because of service conns
978         for (int i = numProc - 1; i >= 0; i--) {
979             ProcessRecord app = activeProcesses.get(i);
980             final ProcessStateRecord state = app.mState;
981             state.setReachable(false);
982             // No need to compute again it has been evaluated in previous iteration
983             if (state.getAdjSeq() != mAdjSeq) {
984                 state.setContainsCycle(false);
985                 state.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY);
986                 state.setCurRawAdj(UNKNOWN_ADJ);
987                 state.setSetCapability(PROCESS_CAPABILITY_NONE);
988                 state.resetCachedInfo();
989                 state.setCurBoundByNonBgRestrictedApp(false);
990             }
991         }
992         mProcessesInCycle.clear();
993         for (int i = numProc - 1; i >= 0; i--) {
994             ProcessRecord app = activeProcesses.get(i);
995             final ProcessStateRecord state = app.mState;
996             if (!app.isKilledByAm() && app.getThread() != null) {
997                 state.setProcStateChanged(false);
998                 app.mOptRecord.setLastOomAdjChangeReason(oomAdjReason);
999                 computeOomAdjLSP(app, UNKNOWN_ADJ, topApp, fullUpdate, now, false,
1000                         computeClients); // It won't enter cycle if not computing clients.
1001                 // if any app encountered a cycle, we need to perform an additional loop later
1002                 retryCycles |= state.containsCycle();
1003                 // Keep the completedAdjSeq to up to date.
1004                 state.setCompletedAdjSeq(mAdjSeq);
1005             }
1006         }
1007 
1008         if (mCacheOomRanker.useOomReranking()) {
1009             mCacheOomRanker.reRankLruCachedAppsLSP(mProcessList.getLruProcessesLSP(),
1010                     mProcessList.getLruProcessServiceStartLOSP());
1011         }
1012 
1013         if (computeClients) { // There won't be cycles if we didn't compute clients above.
1014             // Cycle strategy:
1015             // - Retry computing any process that has encountered a cycle.
1016             // - Continue retrying until no process was promoted.
1017             // - Iterate from least important to most important.
1018             int cycleCount = 0;
1019             while (retryCycles && cycleCount < 10) {
1020                 cycleCount++;
1021                 retryCycles = false;
1022 
1023                 for (int i = 0; i < numProc; i++) {
1024                     ProcessRecord app = activeProcesses.get(i);
1025                     final ProcessStateRecord state = app.mState;
1026                     if (!app.isKilledByAm() && app.getThread() != null && state.containsCycle()) {
1027                         state.decAdjSeq();
1028                         state.decCompletedAdjSeq();
1029                     }
1030                 }
1031 
1032                 for (int i = 0; i < numProc; i++) {
1033                     ProcessRecord app = activeProcesses.get(i);
1034                     final ProcessStateRecord state = app.mState;
1035                     if (!app.isKilledByAm() && app.getThread() != null && state.containsCycle()) {
1036                         if (computeOomAdjLSP(app, UNKNOWN_ADJ, topApp, true, now,
1037                                 true, true)) {
1038                             retryCycles = true;
1039                         }
1040                     }
1041                 }
1042             }
1043         }
1044         mProcessesInCycle.clear();
1045 
1046         assignCachedAdjIfNecessary(mProcessList.getLruProcessesLOSP());
1047 
1048         mNumNonCachedProcs = 0;
1049         mNumCachedHiddenProcs = 0;
1050 
1051         boolean allChanged = updateAndTrimProcessLSP(now, nowElapsed, oldTime, activeUids,
1052                 oomAdjReason);
1053         mNumServiceProcs = mNewNumServiceProcs;
1054 
1055         if (mService.mAlwaysFinishActivities) {
1056             // Need to do this on its own message because the stack may not
1057             // be in a consistent state at this point.
1058             mService.mAtmInternal.scheduleDestroyAllActivities("always-finish");
1059         }
1060 
1061         if (allChanged) {
1062             mService.mAppProfiler.requestPssAllProcsLPr(now, false,
1063                     mService.mProcessStats.isMemFactorLowered());
1064         }
1065 
1066         updateUidsLSP(activeUids, nowElapsed);
1067 
1068         synchronized (mService.mProcessStats.mLock) {
1069             final long nowUptime = SystemClock.uptimeMillis();
1070             if (mService.mProcessStats.shouldWriteNowLocked(nowUptime)) {
1071                 mService.mHandler.post(new ActivityManagerService.ProcStatsRunnable(mService,
1072                         mService.mProcessStats));
1073             }
1074 
1075             // Run this after making sure all procstates are updated.
1076             mService.mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, nowUptime);
1077         }
1078 
1079         if (DEBUG_OOM_ADJ) {
1080             final long duration = SystemClock.uptimeMillis() - now;
1081             if (false) {
1082                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
1083                         new RuntimeException("here").fillInStackTrace());
1084             } else {
1085                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
1086             }
1087         }
1088         if (startProfiling) {
1089             mService.mOomAdjProfiler.oomAdjEnded();
1090             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1091         }
1092     }
1093 
1094     @GuardedBy({"mService", "mProcLock"})
assignCachedAdjIfNecessary(ArrayList<ProcessRecord> lruList)1095     private void assignCachedAdjIfNecessary(ArrayList<ProcessRecord> lruList) {
1096         final int numLru = lruList.size();
1097         if (mConstants.USE_TIERED_CACHED_ADJ) {
1098             final long now = SystemClock.uptimeMillis();
1099             for (int i = numLru - 1; i >= 0; i--) {
1100                 ProcessRecord app = lruList.get(i);
1101                 final ProcessStateRecord state = app.mState;
1102                 final ProcessCachedOptimizerRecord opt = app.mOptRecord;
1103                 if (!app.isKilledByAm() && app.getThread() != null && state.getCurAdj()
1104                         >= UNKNOWN_ADJ) {
1105                     final ProcessServiceRecord psr = app.mServices;
1106                     int targetAdj = CACHED_APP_MIN_ADJ;
1107 
1108                     if (opt != null && opt.isFreezeExempt()) {
1109                         // BIND_WAIVE_PRIORITY and the like get oom_adj 900
1110                         targetAdj += 0;
1111                     } else if ((state.getSetAdj() >= CACHED_APP_MIN_ADJ)
1112                             && (state.getLastStateTime()
1113                                     + mConstants.TIERED_CACHED_ADJ_DECAY_TIME) < now) {
1114                         // Older cached apps get 950
1115                         targetAdj += 50;
1116                     } else {
1117                         // Newer cached apps get 910
1118                         targetAdj += 10;
1119                     }
1120                     state.setCurRawAdj(targetAdj);
1121                     state.setCurAdj(psr.modifyRawOomAdj(targetAdj));
1122                 }
1123             }
1124         } else {
1125             // First update the OOM adjustment for each of the
1126             // application processes based on their current state.
1127             int curCachedAdj = CACHED_APP_MIN_ADJ;
1128             int nextCachedAdj = curCachedAdj + (CACHED_APP_IMPORTANCE_LEVELS * 2);
1129             int curCachedImpAdj = 0;
1130             int curEmptyAdj = CACHED_APP_MIN_ADJ + CACHED_APP_IMPORTANCE_LEVELS;
1131             int nextEmptyAdj = curEmptyAdj + (CACHED_APP_IMPORTANCE_LEVELS * 2);
1132 
1133             final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
1134             final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES
1135                                            - emptyProcessLimit;
1136             // Let's determine how many processes we have running vs.
1137             // how many slots we have for background processes; we may want
1138             // to put multiple processes in a slot of there are enough of
1139             // them.
1140             int numEmptyProcs = numLru - mNumNonCachedProcs - mNumCachedHiddenProcs;
1141             if (numEmptyProcs > cachedProcessLimit) {
1142                 // If there are more empty processes than our limit on cached
1143                 // processes, then use the cached process limit for the factor.
1144                 // This ensures that the really old empty processes get pushed
1145                 // down to the bottom, so if we are running low on memory we will
1146                 // have a better chance at keeping around more cached processes
1147                 // instead of a gazillion empty processes.
1148                 numEmptyProcs = cachedProcessLimit;
1149             }
1150             int cachedFactor = (mNumCachedHiddenProcs > 0
1151                     ? (mNumCachedHiddenProcs + mNumSlots - 1) : 1)
1152                                / mNumSlots;
1153             if (cachedFactor < 1) cachedFactor = 1;
1154 
1155             int emptyFactor = (numEmptyProcs + mNumSlots - 1) / mNumSlots;
1156             if (emptyFactor < 1) emptyFactor = 1;
1157 
1158             int stepCached = -1;
1159             int stepEmpty = -1;
1160             int lastCachedGroup = 0;
1161             int lastCachedGroupImportance = 0;
1162             int lastCachedGroupUid = 0;
1163 
1164 
1165             for (int i = numLru - 1; i >= 0; i--) {
1166                 ProcessRecord app = lruList.get(i);
1167                 final ProcessStateRecord state = app.mState;
1168                 // If we haven't yet assigned the final cached adj
1169                 // to the process, do that now.
1170                 if (!app.isKilledByAm() && app.getThread() != null && state.getCurAdj()
1171                     >= UNKNOWN_ADJ) {
1172                     final ProcessServiceRecord psr = app.mServices;
1173                     switch (state.getCurProcState()) {
1174                         case PROCESS_STATE_CACHED_ACTIVITY:
1175                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
1176                         case ActivityManager.PROCESS_STATE_CACHED_RECENT:
1177                             // Figure out the next cached level, taking into account groups.
1178                             boolean inGroup = false;
1179                             final int connectionGroup = psr.getConnectionGroup();
1180                             if (connectionGroup != 0) {
1181                                 final int connectionImportance = psr.getConnectionImportance();
1182                                 if (lastCachedGroupUid == app.uid
1183                                     && lastCachedGroup == connectionGroup) {
1184                                     // This is in the same group as the last process, just tweak
1185                                     // adjustment by importance.
1186                                     if (connectionImportance > lastCachedGroupImportance) {
1187                                         lastCachedGroupImportance = connectionImportance;
1188                                         if (curCachedAdj < nextCachedAdj
1189                                             && curCachedAdj < CACHED_APP_MAX_ADJ) {
1190                                             curCachedImpAdj++;
1191                                         }
1192                                     }
1193                                     inGroup = true;
1194                                 } else {
1195                                     lastCachedGroupUid = app.uid;
1196                                     lastCachedGroup = connectionGroup;
1197                                     lastCachedGroupImportance = connectionImportance;
1198                                 }
1199                             }
1200                             if (!inGroup && curCachedAdj != nextCachedAdj) {
1201                                 stepCached++;
1202                                 curCachedImpAdj = 0;
1203                                 if (stepCached >= cachedFactor) {
1204                                     stepCached = 0;
1205                                     curCachedAdj = nextCachedAdj;
1206                                     nextCachedAdj += CACHED_APP_IMPORTANCE_LEVELS * 2;
1207                                     if (nextCachedAdj > CACHED_APP_MAX_ADJ) {
1208                                         nextCachedAdj = CACHED_APP_MAX_ADJ;
1209                                     }
1210                                 }
1211                             }
1212                             // This process is a cached process holding activities...
1213                             // assign it the next cached value for that type, and then
1214                             // step that cached level.
1215                             state.setCurRawAdj(curCachedAdj + curCachedImpAdj);
1216                             state.setCurAdj(psr.modifyRawOomAdj(curCachedAdj + curCachedImpAdj));
1217                             if (DEBUG_LRU) {
1218                                 Slog.d(TAG_LRU, "Assigning activity LRU #" + i
1219                                         + " adj: " + state.getCurAdj()
1220                                         + " (curCachedAdj=" + curCachedAdj
1221                                         + " curCachedImpAdj=" + curCachedImpAdj + ")");
1222                             }
1223                             break;
1224                         default:
1225                             // Figure out the next cached level.
1226                             if (curEmptyAdj != nextEmptyAdj) {
1227                                 stepEmpty++;
1228                                 if (stepEmpty >= emptyFactor) {
1229                                     stepEmpty = 0;
1230                                     curEmptyAdj = nextEmptyAdj;
1231                                     nextEmptyAdj += CACHED_APP_IMPORTANCE_LEVELS * 2;
1232                                     if (nextEmptyAdj > CACHED_APP_MAX_ADJ) {
1233                                         nextEmptyAdj = CACHED_APP_MAX_ADJ;
1234                                     }
1235                                 }
1236                             }
1237                             // For everything else, assign next empty cached process
1238                             // level and bump that up.  Note that this means that
1239                             // long-running services that have dropped down to the
1240                             // cached level will be treated as empty (since their process
1241                             // state is still as a service), which is what we want.
1242                             state.setCurRawAdj(curEmptyAdj);
1243                             state.setCurAdj(psr.modifyRawOomAdj(curEmptyAdj));
1244                             if (DEBUG_LRU) {
1245                                 Slog.d(TAG_LRU, "Assigning empty LRU #" + i
1246                                         + " adj: " + state.getCurAdj()
1247                                         + " (curEmptyAdj=" + curEmptyAdj
1248                                         + ")");
1249                             }
1250                             break;
1251                     }
1252                 }
1253             }
1254         }
1255     }
1256     private long mNextNoKillDebugMessageTime;
1257 
1258     private double mLastFreeSwapPercent = 1.00;
1259 
getFreeSwapPercent()1260     private static double getFreeSwapPercent() {
1261         return CachedAppOptimizer.getFreeSwapPercent();
1262     }
1263 
1264     @GuardedBy({"mService", "mProcLock"})
updateAndTrimProcessLSP(final long now, final long nowElapsed, final long oldTime, final ActiveUids activeUids, @OomAdjReason int oomAdjReason)1265     private boolean updateAndTrimProcessLSP(final long now, final long nowElapsed,
1266             final long oldTime, final ActiveUids activeUids, @OomAdjReason int oomAdjReason) {
1267         ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP();
1268         final int numLru = lruList.size();
1269 
1270         final boolean doKillExcessiveProcesses = shouldKillExcessiveProcesses(now);
1271         if (!doKillExcessiveProcesses) {
1272             if (mNextNoKillDebugMessageTime < now) {
1273                 Slog.d(TAG, "Not killing cached processes"); // STOPSHIP Remove it b/222365734
1274                 mNextNoKillDebugMessageTime = now + 5000; // Every 5 seconds
1275             }
1276         }
1277         final int emptyProcessLimit = doKillExcessiveProcesses
1278                 ? mConstants.CUR_MAX_EMPTY_PROCESSES : Integer.MAX_VALUE;
1279         final int cachedProcessLimit = doKillExcessiveProcesses
1280                 ? (mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit) : Integer.MAX_VALUE;
1281         int lastCachedGroup = 0;
1282         int lastCachedGroupUid = 0;
1283         int numCached = 0;
1284         int numCachedExtraGroup = 0;
1285         int numEmpty = 0;
1286         int numTrimming = 0;
1287 
1288         boolean proactiveKillsEnabled = mConstants.PROACTIVE_KILLS_ENABLED;
1289         double lowSwapThresholdPercent = mConstants.LOW_SWAP_THRESHOLD_PERCENT;
1290         double freeSwapPercent =  proactiveKillsEnabled ? getFreeSwapPercent() : 1.00;
1291         ProcessRecord lruCachedApp = null;
1292 
1293         for (int i = numLru - 1; i >= 0; i--) {
1294             ProcessRecord app = lruList.get(i);
1295             final ProcessStateRecord state = app.mState;
1296             if (!app.isKilledByAm() && app.getThread() != null) {
1297                 // We don't need to apply the update for the process which didn't get computed
1298                 if (state.getCompletedAdjSeq() == mAdjSeq) {
1299                     applyOomAdjLSP(app, true, now, nowElapsed, oomAdjReason);
1300                 }
1301 
1302                 if (app.isPendingFinishAttach()) {
1303                     // Avoid trimming processes that are still initializing. If they aren't
1304                     // hosting any components yet because they may be unfairly killed.
1305                     // We however apply the oom scores set at #setAttachingProcessStatesLSP.
1306                     continue;
1307                 }
1308 
1309                 final ProcessServiceRecord psr = app.mServices;
1310                 // Count the number of process types.
1311                 switch (state.getCurProcState()) {
1312                     case PROCESS_STATE_CACHED_ACTIVITY:
1313                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
1314                         mNumCachedHiddenProcs++;
1315                         numCached++;
1316                         final int connectionGroup = psr.getConnectionGroup();
1317                         if (connectionGroup != 0) {
1318                             if (lastCachedGroupUid == app.info.uid
1319                                     && lastCachedGroup == connectionGroup) {
1320                                 // If this process is the next in the same group, we don't
1321                                 // want it to count against our limit of the number of cached
1322                                 // processes, so bump up the group count to account for it.
1323                                 numCachedExtraGroup++;
1324                             } else {
1325                                 lastCachedGroupUid = app.info.uid;
1326                                 lastCachedGroup = connectionGroup;
1327                             }
1328                         } else {
1329                             lastCachedGroupUid = lastCachedGroup = 0;
1330                         }
1331                         if ((numCached - numCachedExtraGroup) > cachedProcessLimit) {
1332                             app.killLocked("cached #" + numCached,
1333                                     "too many cached",
1334                                     ApplicationExitInfo.REASON_OTHER,
1335                                     ApplicationExitInfo.SUBREASON_TOO_MANY_CACHED,
1336                                     true);
1337                         } else if (proactiveKillsEnabled) {
1338                             lruCachedApp = app;
1339                         }
1340                         break;
1341                     case PROCESS_STATE_CACHED_EMPTY:
1342                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
1343                                 && app.getLastActivityTime() < oldTime) {
1344                             app.killLocked("empty for " + ((now
1345                                     - app.getLastActivityTime()) / 1000) + "s",
1346                                     "empty for too long",
1347                                     ApplicationExitInfo.REASON_OTHER,
1348                                     ApplicationExitInfo.SUBREASON_TRIM_EMPTY,
1349                                     true);
1350                         } else {
1351                             numEmpty++;
1352                             if (numEmpty > emptyProcessLimit) {
1353                                 app.killLocked("empty #" + numEmpty,
1354                                         "too many empty",
1355                                         ApplicationExitInfo.REASON_OTHER,
1356                                         ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY,
1357                                         true);
1358                             } else if (proactiveKillsEnabled) {
1359                                 lruCachedApp = app;
1360                             }
1361                         }
1362                         break;
1363                     default:
1364                         mNumNonCachedProcs++;
1365                         break;
1366                 }
1367 
1368                 if (app.isolated && psr.numberOfRunningServices() <= 0
1369                         && app.getIsolatedEntryPoint() == null) {
1370                     // If this is an isolated process, there are no services
1371                     // running in it, and it's not a special process with a
1372                     // custom entry point, then the process is no longer
1373                     // needed.  We agressively kill these because we can by
1374                     // definition not re-use the same process again, and it is
1375                     // good to avoid having whatever code was running in them
1376                     // left sitting around after no longer needed.
1377                     app.killLocked("isolated not needed", ApplicationExitInfo.REASON_OTHER,
1378                             ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true);
1379                 } else if (app.isSdkSandbox && psr.numberOfRunningServices() <= 0
1380                         && app.getActiveInstrumentation() == null) {
1381                     // If this is an SDK sandbox process and there are no services running it, we
1382                     // aggressively kill the sandbox as we usually don't want to re-use the same
1383                     // sandbox again.
1384                     app.killLocked("sandbox not needed", ApplicationExitInfo.REASON_OTHER,
1385                             ApplicationExitInfo.SUBREASON_SDK_SANDBOX_NOT_NEEDED, true);
1386                 } else {
1387                     // Keeping this process, update its uid.
1388                     updateAppUidRecLSP(app);
1389                 }
1390 
1391                 if (state.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME
1392                         && !app.isKilledByAm()) {
1393                     numTrimming++;
1394                 }
1395             }
1396         }
1397 
1398         if (proactiveKillsEnabled                               // Proactive kills enabled?
1399                 && doKillExcessiveProcesses                     // Should kill excessive processes?
1400                 && freeSwapPercent < lowSwapThresholdPercent    // Swap below threshold?
1401                 && lruCachedApp != null                         // If no cached app, let LMKD decide
1402                 // If swap is non-decreasing, give reclaim a chance to catch up
1403                 && freeSwapPercent < mLastFreeSwapPercent) {
1404             lruCachedApp.killLocked("swap low and too many cached",
1405                     ApplicationExitInfo.REASON_OTHER,
1406                     ApplicationExitInfo.SUBREASON_TOO_MANY_CACHED,
1407                     true);
1408         }
1409 
1410         mLastFreeSwapPercent = freeSwapPercent;
1411 
1412         return mService.mAppProfiler.updateLowMemStateLSP(numCached, numEmpty, numTrimming, now);
1413     }
1414 
1415     @GuardedBy({"mService", "mProcLock"})
updateAppUidRecIfNecessaryLSP(final ProcessRecord app)1416     private void updateAppUidRecIfNecessaryLSP(final ProcessRecord app) {
1417         if (!app.isKilledByAm() && app.getThread() != null) {
1418             if (app.isolated && app.mServices.numberOfRunningServices() <= 0
1419                     && app.getIsolatedEntryPoint() == null) {
1420                 // No op.
1421             } else {
1422                 // Keeping this process, update its uid.
1423                 updateAppUidRecLSP(app);
1424             }
1425         }
1426     }
1427 
1428     @GuardedBy({"mService", "mProcLock"})
updateAppUidRecLSP(ProcessRecord app)1429     private void updateAppUidRecLSP(ProcessRecord app) {
1430         final UidRecord uidRec = app.getUidRecord();
1431         if (uidRec != null) {
1432             final ProcessStateRecord state = app.mState;
1433             uidRec.setEphemeral(app.info.isInstantApp());
1434             if (uidRec.getCurProcState() > state.getCurProcState()) {
1435                 uidRec.setCurProcState(state.getCurProcState());
1436             }
1437             if (app.mServices.hasForegroundServices()) {
1438                 uidRec.setForegroundServices(true);
1439             }
1440             uidRec.setCurCapability(uidRec.getCurCapability() | state.getCurCapability());
1441         }
1442     }
1443 
1444     @GuardedBy({"mService", "mProcLock"})
updateUidsLSP(ActiveUids activeUids, final long nowElapsed)1445     private void updateUidsLSP(ActiveUids activeUids, final long nowElapsed) {
1446         // This compares previously set procstate to the current procstate in regards to whether
1447         // or not the app's network access will be blocked. So, this needs to be called before
1448         // we update the UidRecord's procstate by calling {@link UidRecord#setSetProcState}.
1449         mProcessList.incrementProcStateSeqAndNotifyAppsLOSP(activeUids);
1450 
1451         ArrayList<UidRecord> becameIdle = mTmpBecameIdle;
1452         becameIdle.clear();
1453 
1454         // Update from any uid changes.
1455         if (mLocalPowerManager != null) {
1456             mLocalPowerManager.startUidChanges();
1457         }
1458         for (int i = activeUids.size() - 1; i >= 0; i--) {
1459             final UidRecord uidRec = activeUids.valueAt(i);
1460             if (uidRec.getCurProcState() != PROCESS_STATE_NONEXISTENT) {
1461                 if (uidRec.getSetProcState() != uidRec.getCurProcState()
1462                         || uidRec.getSetCapability() != uidRec.getCurCapability()
1463                         || uidRec.isSetAllowListed() != uidRec.isCurAllowListed()
1464                         || uidRec.getProcAdjChanged()) {
1465                     int uidChange = 0;
1466                     if (DEBUG_UID_OBSERVERS) {
1467                         Slog.i(TAG_UID_OBSERVERS, "Changes in " + uidRec
1468                                 + ": proc state from " + uidRec.getSetProcState() + " to "
1469                                 + uidRec.getCurProcState() + ", capability from "
1470                                 + uidRec.getSetCapability() + " to " + uidRec.getCurCapability()
1471                                 + ", allowlist from " + uidRec.isSetAllowListed()
1472                                 + " to " + uidRec.isCurAllowListed()
1473                                 + ", procAdjChanged: " + uidRec.getProcAdjChanged());
1474                     }
1475                     if (ActivityManager.isProcStateBackground(uidRec.getCurProcState())
1476                             && !uidRec.isCurAllowListed()) {
1477                         // UID is now in the background (and not on the temp allowlist).  Was it
1478                         // previously in the foreground (or on the temp allowlist)?
1479                         if (!ActivityManager.isProcStateBackground(uidRec.getSetProcState())
1480                                 || uidRec.isSetAllowListed()) {
1481                             uidRec.setLastBackgroundTime(nowElapsed);
1482                             if (mService.mDeterministicUidIdle
1483                                     || !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) {
1484                                 // Note: the background settle time is in elapsed realtime, while
1485                                 // the handler time base is uptime.  All this means is that we may
1486                                 // stop background uids later than we had intended, but that only
1487                                 // happens because the device was sleeping so we are okay anyway.
1488                                 mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
1489                                         mConstants.BACKGROUND_SETTLE_TIME);
1490                             }
1491                         }
1492                         if (uidRec.isIdle() && !uidRec.isSetIdle()) {
1493                             uidChange |= UidRecord.CHANGE_IDLE;
1494                             if (uidRec.getSetProcState() != PROCESS_STATE_NONEXISTENT) {
1495                                 // don't stop the bg services if it's just started.
1496                                 becameIdle.add(uidRec);
1497                             }
1498                         }
1499                     } else {
1500                         if (uidRec.isIdle()) {
1501                             uidChange |= UidRecord.CHANGE_ACTIVE;
1502                             EventLogTags.writeAmUidActive(uidRec.getUid());
1503                             uidRec.setIdle(false);
1504                         }
1505                         uidRec.setLastBackgroundTime(0);
1506                     }
1507                     final boolean wasCached = uidRec.getSetProcState()
1508                             > ActivityManager.PROCESS_STATE_RECEIVER;
1509                     final boolean isCached = uidRec.getCurProcState()
1510                             > ActivityManager.PROCESS_STATE_RECEIVER;
1511                     if (wasCached != isCached
1512                             || uidRec.getSetProcState() == PROCESS_STATE_NONEXISTENT) {
1513                         uidChange |= isCached ? UidRecord.CHANGE_CACHED :
1514                                 UidRecord.CHANGE_UNCACHED;
1515                     }
1516                     if (uidRec.getSetCapability() != uidRec.getCurCapability()) {
1517                         uidChange |= UidRecord.CHANGE_CAPABILITY;
1518                     }
1519                     if (uidRec.getSetProcState() != uidRec.getCurProcState()) {
1520                         uidChange |= UidRecord.CHANGE_PROCSTATE;
1521                     }
1522                     if (uidRec.getProcAdjChanged()) {
1523                         uidChange |= UidRecord.CHANGE_PROCADJ;
1524                     }
1525                     uidRec.setSetProcState(uidRec.getCurProcState());
1526                     uidRec.setSetCapability(uidRec.getCurCapability());
1527                     uidRec.setSetAllowListed(uidRec.isCurAllowListed());
1528                     uidRec.setSetIdle(uidRec.isIdle());
1529                     uidRec.clearProcAdjChanged();
1530                     if ((uidChange & UidRecord.CHANGE_PROCSTATE) != 0
1531                             || (uidChange & UidRecord.CHANGE_CAPABILITY) != 0) {
1532                         mService.mAtmInternal.onUidProcStateChanged(
1533                                 uidRec.getUid(), uidRec.getSetProcState());
1534                     }
1535                     if (uidChange != 0) {
1536                         mService.enqueueUidChangeLocked(uidRec, -1, uidChange);
1537                     }
1538                     if ((uidChange & UidRecord.CHANGE_PROCSTATE) != 0
1539                             || (uidChange & UidRecord.CHANGE_CAPABILITY) != 0) {
1540                         mService.noteUidProcessState(uidRec.getUid(), uidRec.getCurProcState(),
1541                                 uidRec.getCurCapability());
1542                     }
1543                     if (uidRec.hasForegroundServices()) {
1544                         mService.mServices.foregroundServiceProcStateChangedLocked(uidRec);
1545                     }
1546                 }
1547             }
1548             mService.mInternal.deletePendingTopUid(uidRec.getUid(), nowElapsed);
1549         }
1550         if (mLocalPowerManager != null) {
1551             mLocalPowerManager.finishUidChanges();
1552         }
1553 
1554         int size = becameIdle.size();
1555         if (size > 0) {
1556             // If we have any new uids that became idle this time, we need to make sure
1557             // they aren't left with running services.
1558             for (int i = size - 1; i >= 0; i--) {
1559                 mService.mServices.stopInBackgroundLocked(becameIdle.get(i).getUid());
1560             }
1561         }
1562     }
1563 
1564     /**
1565      * Return true if we should kill excessive cached/empty processes.
1566      */
shouldKillExcessiveProcesses(long nowUptime)1567     private boolean shouldKillExcessiveProcesses(long nowUptime) {
1568         final long lastUserUnlockingUptime = mService.mUserController.getLastUserUnlockingUptime();
1569 
1570         if (lastUserUnlockingUptime == 0) {
1571             // No users have been unlocked.
1572             return !mConstants.mNoKillCachedProcessesUntilBootCompleted;
1573         }
1574         final long noKillCachedProcessesPostBootCompletedDurationMillis =
1575                 mConstants.mNoKillCachedProcessesPostBootCompletedDurationMillis;
1576         if ((lastUserUnlockingUptime + noKillCachedProcessesPostBootCompletedDurationMillis)
1577                 > nowUptime) {
1578             return false;
1579         }
1580         return true;
1581     }
1582 
1583     private final ComputeOomAdjWindowCallback mTmpComputeOomAdjWindowCallback =
1584             new ComputeOomAdjWindowCallback();
1585 
1586     /** These methods are called inline during computeOomAdjLSP(), on the same thread */
1587     final class ComputeOomAdjWindowCallback
1588             implements WindowProcessController.ComputeOomAdjCallback {
1589 
1590         ProcessRecord app;
1591         int adj;
1592         boolean foregroundActivities;
1593         boolean mHasVisibleActivities;
1594         int procState;
1595         int schedGroup;
1596         int appUid;
1597         int logUid;
1598         int processStateCurTop;
1599         ProcessStateRecord mState;
1600 
initialize(ProcessRecord app, int adj, boolean foregroundActivities, boolean hasVisibleActivities, int procState, int schedGroup, int appUid, int logUid, int processStateCurTop)1601         void initialize(ProcessRecord app, int adj, boolean foregroundActivities,
1602                 boolean hasVisibleActivities, int procState, int schedGroup, int appUid,
1603                 int logUid, int processStateCurTop) {
1604             this.app = app;
1605             this.adj = adj;
1606             this.foregroundActivities = foregroundActivities;
1607             this.mHasVisibleActivities = hasVisibleActivities;
1608             this.procState = procState;
1609             this.schedGroup = schedGroup;
1610             this.appUid = appUid;
1611             this.logUid = logUid;
1612             this.processStateCurTop = processStateCurTop;
1613             this.mState = app.mState;
1614         }
1615 
1616         @Override
onVisibleActivity()1617         public void onVisibleActivity() {
1618             // App has a visible activity; only upgrade adjustment.
1619             if (adj > VISIBLE_APP_ADJ) {
1620                 adj = VISIBLE_APP_ADJ;
1621                 mState.setAdjType("vis-activity");
1622                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1623                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to vis-activity: " + app);
1624                 }
1625             }
1626             if (procState > processStateCurTop) {
1627                 procState = processStateCurTop;
1628                 mState.setAdjType("vis-activity");
1629                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1630                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
1631                             "Raise procstate to vis-activity (top): " + app);
1632                 }
1633             }
1634             if (schedGroup < SCHED_GROUP_DEFAULT) {
1635                 schedGroup = SCHED_GROUP_DEFAULT;
1636             }
1637             mState.setCached(false);
1638             mState.setEmpty(false);
1639             foregroundActivities = true;
1640             mHasVisibleActivities = true;
1641         }
1642 
1643         @Override
onPausedActivity()1644         public void onPausedActivity() {
1645             if (adj > PERCEPTIBLE_APP_ADJ) {
1646                 adj = PERCEPTIBLE_APP_ADJ;
1647                 mState.setAdjType("pause-activity");
1648                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1649                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to pause-activity: "  + app);
1650                 }
1651             }
1652             if (procState > processStateCurTop) {
1653                 procState = processStateCurTop;
1654                 mState.setAdjType("pause-activity");
1655                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1656                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
1657                             "Raise procstate to pause-activity (top): "  + app);
1658                 }
1659             }
1660             if (schedGroup < SCHED_GROUP_DEFAULT) {
1661                 schedGroup = SCHED_GROUP_DEFAULT;
1662             }
1663             mState.setCached(false);
1664             mState.setEmpty(false);
1665             foregroundActivities = true;
1666             mHasVisibleActivities = false;
1667         }
1668 
1669         @Override
onStoppingActivity(boolean finishing)1670         public void onStoppingActivity(boolean finishing) {
1671             if (adj > PERCEPTIBLE_APP_ADJ) {
1672                 adj = PERCEPTIBLE_APP_ADJ;
1673                 mState.setAdjType("stop-activity");
1674                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1675                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
1676                             "Raise adj to stop-activity: "  + app);
1677                 }
1678             }
1679 
1680             // For the process state, we will at this point consider the process to be cached. It
1681             // will be cached either as an activity or empty depending on whether the activity is
1682             // finishing. We do this so that we can treat the process as cached for purposes of
1683             // memory trimming (determining current memory level, trim command to send to process)
1684             // since there can be an arbitrary number of stopping processes and they should soon all
1685             // go into the cached state.
1686             if (!finishing) {
1687                 if (procState > PROCESS_STATE_LAST_ACTIVITY) {
1688                     procState = PROCESS_STATE_LAST_ACTIVITY;
1689                     mState.setAdjType("stop-activity");
1690                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1691                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
1692                                 "Raise procstate to stop-activity: " + app);
1693                     }
1694                 }
1695             }
1696             mState.setCached(false);
1697             mState.setEmpty(false);
1698             foregroundActivities = true;
1699             mHasVisibleActivities = false;
1700         }
1701 
1702         @Override
onOtherActivity()1703         public void onOtherActivity() {
1704             if (procState > PROCESS_STATE_CACHED_ACTIVITY) {
1705                 procState = PROCESS_STATE_CACHED_ACTIVITY;
1706                 mState.setAdjType("cch-act");
1707                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1708                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
1709                             "Raise procstate to cached activity: " + app);
1710                 }
1711             }
1712             mHasVisibleActivities = false;
1713         }
1714     }
1715 
isScreenOnOrAnimatingLocked(ProcessStateRecord state)1716     private boolean isScreenOnOrAnimatingLocked(ProcessStateRecord state) {
1717         return mService.mWakefulness.get() == PowerManagerInternal.WAKEFULNESS_AWAKE
1718                 || state.isRunningRemoteAnimation();
1719     }
1720 
1721     @GuardedBy({"mService", "mProcLock"})
computeOomAdjLSP(ProcessRecord app, int cachedAdj, ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval, boolean computeClients)1722     private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,
1723             ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
1724             boolean computeClients) {
1725         final ProcessStateRecord state = app.mState;
1726         if (mAdjSeq == state.getAdjSeq()) {
1727             if (state.getAdjSeq() == state.getCompletedAdjSeq()) {
1728                 // This adjustment has already been computed successfully.
1729                 return false;
1730             } else {
1731                 // The process is being computed, so there is a cycle. We cannot
1732                 // rely on this process's state.
1733                 state.setContainsCycle(true);
1734                 mProcessesInCycle.add(app);
1735 
1736                 return false;
1737             }
1738         }
1739 
1740         if (app.getThread() == null) {
1741             state.setAdjSeq(mAdjSeq);
1742             state.setCurrentSchedulingGroup(SCHED_GROUP_BACKGROUND);
1743             state.setCurProcState(PROCESS_STATE_CACHED_EMPTY);
1744             state.setCurAdj(CACHED_APP_MAX_ADJ);
1745             state.setCurRawAdj(CACHED_APP_MAX_ADJ);
1746             state.setCompletedAdjSeq(state.getAdjSeq());
1747             state.setCurCapability(PROCESS_CAPABILITY_NONE);
1748             return false;
1749         }
1750 
1751         state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN);
1752         state.setAdjSource(null);
1753         state.setAdjTarget(null);
1754         state.setEmpty(false);
1755         state.setCached(false);
1756         if (!cycleReEval) {
1757             // Don't reset this flag when doing cycles re-evaluation.
1758             state.setNoKillOnBgRestrictedAndIdle(false);
1759             // If this UID is currently allowlisted, it should not be frozen.
1760             final UidRecord uidRec = app.getUidRecord();
1761             app.mOptRecord.setShouldNotFreeze(uidRec != null && uidRec.isCurAllowListed());
1762         }
1763 
1764         final int appUid = app.info.uid;
1765         final int logUid = mService.mCurOomAdjUid;
1766 
1767         int prevAppAdj = state.getCurAdj();
1768         int prevProcState = state.getCurProcState();
1769         int prevCapability = state.getCurCapability();
1770         final ProcessServiceRecord psr = app.mServices;
1771 
1772         if (state.getMaxAdj() <= FOREGROUND_APP_ADJ) {
1773             // The max adjustment doesn't allow this app to be anything
1774             // below foreground, so it is not worth doing work for it.
1775             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1776                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
1777             }
1778             state.setAdjType("fixed");
1779             state.setAdjSeq(mAdjSeq);
1780             state.setCurRawAdj(state.getMaxAdj());
1781             state.setHasForegroundActivities(false);
1782             state.setCurrentSchedulingGroup(SCHED_GROUP_DEFAULT);
1783             state.setCurCapability(PROCESS_CAPABILITY_ALL); // BFSL allowed
1784             state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
1785             // System processes can do UI, and when they do we want to have
1786             // them trim their memory after the user leaves the UI.  To
1787             // facilitate this, here we need to determine whether or not it
1788             // is currently showing UI.
1789             state.setSystemNoUi(true);
1790             if (app == topApp) {
1791                 state.setSystemNoUi(false);
1792                 state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP);
1793                 state.setAdjType("pers-top-activity");
1794             } else if (state.hasTopUi()) {
1795                 // sched group/proc state adjustment is below
1796                 state.setSystemNoUi(false);
1797                 state.setAdjType("pers-top-ui");
1798             } else if (state.getCachedHasVisibleActivities()) {
1799                 state.setSystemNoUi(false);
1800             }
1801             if (!state.isSystemNoUi()) {
1802                 if (isScreenOnOrAnimatingLocked(state)) {
1803                     // screen on or animating, promote UI
1804                     state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI);
1805                     state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP);
1806                 } else {
1807                     // screen off, restrict UI scheduling
1808                     state.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
1809                     state.setCurrentSchedulingGroup(SCHED_GROUP_RESTRICTED);
1810                 }
1811             }
1812             state.setCurRawProcState(state.getCurProcState());
1813             state.setCurAdj(state.getMaxAdj());
1814             state.setCompletedAdjSeq(state.getAdjSeq());
1815             // if curAdj is less than prevAppAdj, then this process was promoted
1816             return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState;
1817         }
1818 
1819         state.setSystemNoUi(false);
1820 
1821         final int PROCESS_STATE_CUR_TOP = mService.mAtmInternal.getTopProcessState();
1822 
1823         // Determine the importance of the process, starting with most
1824         // important to least, and assign an appropriate OOM adjustment.
1825         int adj;
1826         int schedGroup;
1827         int procState;
1828         int capability = cycleReEval ? app.mState.getCurCapability() : 0;
1829 
1830         boolean foregroundActivities = false;
1831         boolean hasVisibleActivities = false;
1832         if (app == topApp && PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) {
1833             // The last app on the list is the foreground app.
1834             adj = FOREGROUND_APP_ADJ;
1835             if (mService.mAtmInternal.useTopSchedGroupForTopProcess()) {
1836                 schedGroup = SCHED_GROUP_TOP_APP;
1837                 state.setAdjType("top-activity");
1838             } else {
1839                 // Demote the scheduling group to avoid CPU contention if there is another more
1840                 // important process which also uses top-app, such as if SystemUI is animating.
1841                 schedGroup = SCHED_GROUP_DEFAULT;
1842                 state.setAdjType("intermediate-top-activity");
1843             }
1844             foregroundActivities = true;
1845             hasVisibleActivities = true;
1846             procState = PROCESS_STATE_TOP;
1847             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1848                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
1849             }
1850         } else if (state.isRunningRemoteAnimation()) {
1851             adj = VISIBLE_APP_ADJ;
1852             schedGroup = SCHED_GROUP_TOP_APP;
1853             state.setAdjType("running-remote-anim");
1854             procState = PROCESS_STATE_CUR_TOP;
1855             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1856                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
1857             }
1858         } else if (app.getActiveInstrumentation() != null) {
1859             // Don't want to kill running instrumentation.
1860             adj = FOREGROUND_APP_ADJ;
1861             schedGroup = SCHED_GROUP_DEFAULT;
1862             state.setAdjType("instrumentation");
1863             procState = PROCESS_STATE_FOREGROUND_SERVICE;
1864             capability |= PROCESS_CAPABILITY_BFSL;
1865             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1866                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
1867             }
1868         } else if (state.getCachedIsReceivingBroadcast(mTmpSchedGroup)) {
1869             // An app that is currently receiving a broadcast also
1870             // counts as being in the foreground for OOM killer purposes.
1871             // It's placed in a sched group based on the nature of the
1872             // broadcast as reflected by which queue it's active in.
1873             adj = FOREGROUND_APP_ADJ;
1874             schedGroup = mTmpSchedGroup[0];
1875             state.setAdjType("broadcast");
1876             procState = ActivityManager.PROCESS_STATE_RECEIVER;
1877             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1878                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
1879             }
1880         } else if (psr.numberOfExecutingServices() > 0) {
1881             // An app that is currently executing a service callback also
1882             // counts as being in the foreground.
1883             adj = FOREGROUND_APP_ADJ;
1884             schedGroup = psr.shouldExecServicesFg()
1885                     ? SCHED_GROUP_DEFAULT : SCHED_GROUP_BACKGROUND;
1886             state.setAdjType("exec-service");
1887             procState = PROCESS_STATE_SERVICE;
1888             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1889                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
1890             }
1891         } else if (app == topApp) {
1892             adj = FOREGROUND_APP_ADJ;
1893             schedGroup = SCHED_GROUP_BACKGROUND;
1894             state.setAdjType("top-sleeping");
1895             foregroundActivities = true;
1896             procState = PROCESS_STATE_CUR_TOP;
1897             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1898                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
1899             }
1900         } else {
1901             // As far as we know the process is empty.  We may change our mind later.
1902             schedGroup = SCHED_GROUP_BACKGROUND;
1903             // At this point we don't actually know the adjustment.  Use the cached adj
1904             // value that the caller wants us to.
1905             adj = cachedAdj;
1906             procState = PROCESS_STATE_CACHED_EMPTY;
1907             if (!state.containsCycle()) {
1908                 state.setCached(true);
1909                 state.setEmpty(true);
1910                 state.setAdjType("cch-empty");
1911             }
1912             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1913                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
1914             }
1915         }
1916 
1917         // Examine all activities if not already foreground.
1918         if (!foregroundActivities && state.getCachedHasActivities()) {
1919             state.computeOomAdjFromActivitiesIfNecessary(mTmpComputeOomAdjWindowCallback,
1920                     adj, foregroundActivities, hasVisibleActivities, procState, schedGroup,
1921                     appUid, logUid, PROCESS_STATE_CUR_TOP);
1922 
1923             adj = state.getCachedAdj();
1924             foregroundActivities = state.getCachedForegroundActivities();
1925             hasVisibleActivities = state.getCachedHasVisibleActivities();
1926             procState = state.getCachedProcState();
1927             schedGroup = state.getCachedSchedGroup();
1928         }
1929 
1930         if (procState > PROCESS_STATE_CACHED_RECENT && state.getCachedHasRecentTasks()) {
1931             procState = PROCESS_STATE_CACHED_RECENT;
1932             state.setAdjType("cch-rec");
1933             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1934                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app);
1935             }
1936         }
1937 
1938         int capabilityFromFGS = 0; // capability from foreground service.
1939 
1940         final boolean hasForegroundServices = psr.hasForegroundServices();
1941         final boolean hasNonShortForegroundServices = psr.hasNonShortForegroundServices();
1942         final boolean hasShortForegroundServices = hasForegroundServices
1943                 && !psr.areAllShortForegroundServicesProcstateTimedOut(now);
1944 
1945         // Adjust for FGS or "has-overlay-ui".
1946         if (adj > PERCEPTIBLE_APP_ADJ
1947                 || procState > PROCESS_STATE_FOREGROUND_SERVICE) {
1948             String adjType = null;
1949             int newAdj = 0;
1950             int newProcState = 0;
1951 
1952             if (hasForegroundServices && hasNonShortForegroundServices) {
1953                 // For regular (non-short) FGS.
1954                 adjType = "fg-service";
1955                 newAdj = PERCEPTIBLE_APP_ADJ;
1956                 newProcState = PROCESS_STATE_FOREGROUND_SERVICE;
1957                 capabilityFromFGS |= PROCESS_CAPABILITY_BFSL;
1958 
1959             } else if (hasShortForegroundServices) {
1960 
1961                 // For short FGS.
1962                 adjType = "fg-service-short";
1963 
1964                 // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ
1965                 // (which uses MEDIUM_APP_ADJ + 1)
1966                 // from short-FGS.
1967                 // (We use +1 and +2, not +0 and +1, to be consistent with the following
1968                 // RECENT_FOREGROUND_APP_ADJ tweak)
1969                 newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1;
1970 
1971                 // We give the FGS procstate, but not PROCESS_CAPABILITY_BFSL, so
1972                 // short-fgs can't start FGS from the background.
1973                 newProcState = PROCESS_STATE_FOREGROUND_SERVICE;
1974 
1975             } else if (state.hasOverlayUi()) {
1976                 adjType = "has-overlay-ui";
1977                 newAdj = PERCEPTIBLE_APP_ADJ;
1978                 newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
1979             }
1980 
1981             if (adjType != null) {
1982                 adj = newAdj;
1983                 procState = newProcState;
1984                 state.setAdjType(adjType);
1985                 state.setCached(false);
1986                 schedGroup = SCHED_GROUP_DEFAULT;
1987 
1988                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
1989                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType + ": "
1990                             + app + " ");
1991                 }
1992             }
1993         }
1994 
1995         // If the app was recently in the foreground and moved to a foreground service status,
1996         // allow it to get a higher rank in memory for some time, compared to other foreground
1997         // services so that it can finish performing any persistence/processing of in-memory state.
1998         if (psr.hasForegroundServices() && adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
1999                 && (state.getLastTopTime() + mConstants.TOP_TO_FGS_GRACE_DURATION > now
2000                 || state.getSetProcState() <= PROCESS_STATE_TOP)) {
2001             if (psr.hasNonShortForegroundServices()) {
2002                 adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
2003                 state.setAdjType("fg-service-act");
2004             } else {
2005                 // For short-service FGS, we +1 the value, so we'll be able to detect it in
2006                 // various dashboards.
2007                 adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1;
2008                 state.setAdjType("fg-service-short-act");
2009             }
2010             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2011                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
2012             }
2013         }
2014 
2015         // If the app was recently in the foreground and has expedited jobs running,
2016         // allow it to get a higher rank in memory for some time, compared to other EJS and even
2017         // foreground services so that it can finish performing any persistence/processing of
2018         // in-memory state.
2019         if (psr.hasTopStartedAlmostPerceptibleServices()
2020                 && (adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2)
2021                 && (state.getLastTopTime()
2022                         + mConstants.TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION > now
2023                 || state.getSetProcState() <= PROCESS_STATE_TOP)) {
2024             // For EJ, we +2 the value, so we'll be able to detect it in
2025             // various dashboards.
2026             adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2;
2027             // This shall henceforth be called the "EJ" exemption, despite utilizing the
2028             // ALMOST_PERCEPTIBLE flag to work.
2029             state.setAdjType("top-ej-act");
2030             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2031                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg for EJ: " + app);
2032             }
2033         }
2034 
2035         if (adj > PERCEPTIBLE_APP_ADJ
2036                 || procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
2037             if (state.getForcingToImportant() != null) {
2038                 // This is currently used for toasts...  they are not interactive, and
2039                 // we don't want them to cause the app to become fully foreground (and
2040                 // thus out of background check), so we yes the best background level we can.
2041                 adj = PERCEPTIBLE_APP_ADJ;
2042                 procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
2043                 state.setCached(false);
2044                 state.setAdjType("force-imp");
2045                 state.setAdjSource(state.getForcingToImportant());
2046                 schedGroup = SCHED_GROUP_DEFAULT;
2047                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2048                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
2049                 }
2050             }
2051         }
2052 
2053         if (state.getCachedIsHeavyWeight()) {
2054             if (adj > HEAVY_WEIGHT_APP_ADJ) {
2055                 // We don't want to kill the current heavy-weight process.
2056                 adj = HEAVY_WEIGHT_APP_ADJ;
2057                 schedGroup = SCHED_GROUP_BACKGROUND;
2058                 state.setCached(false);
2059                 state.setAdjType("heavy");
2060                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2061                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app);
2062                 }
2063             }
2064             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
2065                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
2066                 state.setAdjType("heavy");
2067                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2068                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app);
2069                 }
2070             }
2071         }
2072 
2073         if (state.getCachedIsHomeProcess()) {
2074             if (adj > HOME_APP_ADJ) {
2075                 // This process is hosting what we currently consider to be the
2076                 // home app, so we don't want to let it go into the background.
2077                 adj = HOME_APP_ADJ;
2078                 schedGroup = SCHED_GROUP_BACKGROUND;
2079                 state.setCached(false);
2080                 state.setAdjType("home");
2081                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2082                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app);
2083                 }
2084             }
2085             if (procState > ActivityManager.PROCESS_STATE_HOME) {
2086                 procState = ActivityManager.PROCESS_STATE_HOME;
2087                 state.setAdjType("home");
2088                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2089                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app);
2090                 }
2091             }
2092         }
2093         if (state.getCachedIsPreviousProcess() && state.getCachedHasActivities()) {
2094             // This was the previous process that showed UI to the user.  We want to
2095             // try to keep it around more aggressively, to give a good experience
2096             // around switching between two apps. However, we don't want to keep the
2097             // process in this privileged state indefinitely. Eventually, allow the
2098             // app to be demoted to cached.
2099             if (procState >= PROCESS_STATE_LAST_ACTIVITY
2100                     && state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY
2101                     && (state.getLastStateTime() + mConstants.MAX_PREVIOUS_TIME) < now) {
2102                 procState = PROCESS_STATE_LAST_ACTIVITY;
2103                 schedGroup = SCHED_GROUP_BACKGROUND;
2104                 state.setAdjType("previous-expired");
2105                 adj = CACHED_APP_MIN_ADJ;
2106                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2107                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Expire prev adj: " + app);
2108                 }
2109             } else {
2110                 if (adj > PREVIOUS_APP_ADJ) {
2111                     adj = PREVIOUS_APP_ADJ;
2112                     schedGroup = SCHED_GROUP_BACKGROUND;
2113                     state.setCached(false);
2114                     state.setAdjType("previous");
2115                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2116                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
2117                     }
2118                 }
2119                 if (procState > PROCESS_STATE_LAST_ACTIVITY) {
2120                     procState = PROCESS_STATE_LAST_ACTIVITY;
2121                     state.setAdjType("previous");
2122                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2123                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
2124                     }
2125                 }
2126             }
2127         }
2128 
2129         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
2130                 + " reason=" + state.getAdjType());
2131 
2132         // By default, we use the computed adjustment.  It may be changed if
2133         // there are applications dependent on our services or providers, but
2134         // this gives us a baseline and makes sure we don't get into an
2135         // infinite recursion. If we're re-evaluating due to cycles, use the previously computed
2136         // values.
2137         if (cycleReEval) {
2138             procState = Math.min(procState, state.getCurRawProcState());
2139             adj = Math.min(adj, state.getCurRawAdj());
2140             schedGroup = Math.max(schedGroup, state.getCurrentSchedulingGroup());
2141         }
2142         state.setCurRawAdj(adj);
2143         state.setCurRawProcState(procState);
2144 
2145         state.setHasStartedServices(false);
2146         state.setAdjSeq(mAdjSeq);
2147 
2148         final BackupRecord backupTarget = mService.mBackupTargets.get(app.userId);
2149         if (backupTarget != null && app == backupTarget.app) {
2150             // If possible we want to avoid killing apps while they're being backed up
2151             if (adj > BACKUP_APP_ADJ) {
2152                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
2153                 adj = BACKUP_APP_ADJ;
2154                 if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
2155                     procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
2156                 }
2157                 state.setAdjType("backup");
2158                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2159                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
2160                 }
2161                 state.setCached(false);
2162             }
2163             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
2164                 procState = ActivityManager.PROCESS_STATE_BACKUP;
2165                 state.setAdjType("backup");
2166                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2167                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app);
2168                 }
2169             }
2170         }
2171 
2172         boolean boundByNonBgRestricted = state.isCurBoundByNonBgRestrictedApp();
2173         boolean scheduleLikeTopApp = false;
2174         for (int is = psr.numberOfRunningServices() - 1;
2175                 is >= 0 && (adj > FOREGROUND_APP_ADJ
2176                         || schedGroup == SCHED_GROUP_BACKGROUND
2177                         || procState > PROCESS_STATE_TOP);
2178                 is--) {
2179             ServiceRecord s = psr.getRunningServiceAt(is);
2180             if (s.startRequested) {
2181                 state.setHasStartedServices(true);
2182                 if (procState > PROCESS_STATE_SERVICE) {
2183                     procState = PROCESS_STATE_SERVICE;
2184                     state.setAdjType("started-services");
2185                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2186                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
2187                                 "Raise procstate to started service: " + app);
2188                     }
2189                 }
2190                 if (!s.mKeepWarming && state.hasShownUi() && !state.getCachedIsHomeProcess()) {
2191                     // If this process has shown some UI, let it immediately
2192                     // go to the LRU list because it may be pretty heavy with
2193                     // UI stuff.  We'll tag it with a label just to help
2194                     // debug and understand what is going on.
2195                     if (adj > SERVICE_ADJ) {
2196                         state.setAdjType("cch-started-ui-services");
2197                     }
2198                 } else {
2199                     if (s.mKeepWarming
2200                             || now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
2201                         // This service has seen some activity within
2202                         // recent memory, so we will keep its process ahead
2203                         // of the background processes.
2204                         if (adj > SERVICE_ADJ) {
2205                             adj = SERVICE_ADJ;
2206                             state.setAdjType("started-services");
2207                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2208                                 reportOomAdjMessageLocked(TAG_OOM_ADJ,
2209                                         "Raise adj to started service: " + app);
2210                             }
2211                             state.setCached(false);
2212                         }
2213                     }
2214                     // If we have let the service slide into the background
2215                     // state, still have some text describing what it is doing
2216                     // even though the service no longer has an impact.
2217                     if (adj > SERVICE_ADJ) {
2218                         state.setAdjType("cch-started-services");
2219                     }
2220                 }
2221             }
2222 
2223             if (s.isForeground) {
2224                 final int fgsType = s.foregroundServiceType;
2225                 if (s.isFgsAllowedWIU()) {
2226                     capabilityFromFGS |=
2227                             (fgsType & FOREGROUND_SERVICE_TYPE_LOCATION)
2228                                     != 0 ? PROCESS_CAPABILITY_FOREGROUND_LOCATION : 0;
2229 
2230                     final boolean enabled = state.getCachedCompatChange(
2231                             CACHED_COMPAT_CHANGE_CAMERA_MICROPHONE_CAPABILITY);
2232                     if (enabled) {
2233                         capabilityFromFGS |=
2234                                 (fgsType & FOREGROUND_SERVICE_TYPE_CAMERA)
2235                                         != 0 ? PROCESS_CAPABILITY_FOREGROUND_CAMERA : 0;
2236                         capabilityFromFGS |=
2237                                 (fgsType & FOREGROUND_SERVICE_TYPE_MICROPHONE)
2238                                         != 0 ? PROCESS_CAPABILITY_FOREGROUND_MICROPHONE : 0;
2239                     } else {
2240                         capabilityFromFGS |= PROCESS_CAPABILITY_FOREGROUND_CAMERA
2241                                 | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
2242                     }
2243                 }
2244             }
2245 
2246             ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections();
2247             for (int conni = serviceConnections.size() - 1;
2248                     conni >= 0 && (adj > FOREGROUND_APP_ADJ
2249                             || schedGroup == SCHED_GROUP_BACKGROUND
2250                             || procState > PROCESS_STATE_TOP);
2251                     conni--) {
2252                 ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni);
2253                 for (int i = 0;
2254                         i < clist.size() && (adj > FOREGROUND_APP_ADJ
2255                                 || schedGroup == SCHED_GROUP_BACKGROUND
2256                                 || procState > PROCESS_STATE_TOP);
2257                         i++) {
2258                     // XXX should compute this based on the max of
2259                     // all connected clients.
2260                     ConnectionRecord cr = clist.get(i);
2261                     if (cr.binding.client == app) {
2262                         // Binding to oneself is not interesting.
2263                         continue;
2264                     }
2265 
2266                     boolean trackedProcState = false;
2267 
2268                     ProcessRecord client = cr.binding.client;
2269                     if (app.isSdkSandbox && cr.binding.attributedClient != null) {
2270                         // For SDK sandboxes, use the attributed client (eg the app that
2271                         // requested the sandbox)
2272                         client = cr.binding.attributedClient;
2273                     }
2274                     final ProcessStateRecord cstate = client.mState;
2275                     if (computeClients) {
2276                         computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now,
2277                                 cycleReEval, true);
2278                     } else {
2279                         cstate.setCurRawAdj(cstate.getCurAdj());
2280                         cstate.setCurRawProcState(cstate.getCurProcState());
2281                     }
2282 
2283                     int clientAdj = cstate.getCurRawAdj();
2284                     int clientProcState = cstate.getCurRawProcState();
2285 
2286                     final boolean clientIsSystem = clientProcState < PROCESS_STATE_TOP;
2287 
2288                     boundByNonBgRestricted |= cstate.isCurBoundByNonBgRestrictedApp()
2289                             || clientProcState <= PROCESS_STATE_BOUND_TOP
2290                             || (clientProcState == PROCESS_STATE_FOREGROUND_SERVICE
2291                                     && !cstate.isBackgroundRestricted());
2292 
2293                     if (client.mOptRecord.shouldNotFreeze()) {
2294                         // Propagate the shouldNotFreeze flag down the bindings.
2295                         app.mOptRecord.setShouldNotFreeze(true);
2296                     }
2297 
2298                     // We always propagate PROCESS_CAPABILITY_BFSL over bindings here,
2299                     // but, right before actually setting it to the process,
2300                     // we check the final procstate, and remove it if the procsate is below BFGS.
2301                     capability |= getBfslCapabilityFromClient(client);
2302 
2303                     if (cr.notHasFlag(Context.BIND_WAIVE_PRIORITY)) {
2304                         if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
2305                             capability |= cstate.getCurCapability();
2306                         }
2307 
2308                         // If an app has network capability by default
2309                         // (by having procstate <= BFGS), then the apps it binds to will get
2310                         // elevated to a high enough procstate anyway to get network unless they
2311                         // request otherwise, so don't propagate the network capability by default
2312                         // in this case unless they explicitly request it.
2313                         if ((cstate.getCurCapability()
2314                                 & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0) {
2315                             if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
2316                                 // This is used to grant network access to Expedited Jobs.
2317                                 if (cr.hasFlag(Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)) {
2318                                     capability |= PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
2319                                 }
2320                             } else {
2321                                 capability |= PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
2322                             }
2323                         }
2324                         if ((cstate.getCurCapability()
2325                                 & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0) {
2326                             if (clientProcState <= PROCESS_STATE_IMPORTANT_FOREGROUND) {
2327                                 // This is used to grant network access to User Initiated Jobs.
2328                                 if (cr.hasFlag(Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS)) {
2329                                     capability |= PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
2330                                 }
2331                             }
2332                         }
2333 
2334                         if (shouldSkipDueToCycle(app, cstate, procState, adj, cycleReEval)) {
2335                             continue;
2336                         }
2337 
2338                         if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
2339                             // If the other app is cached for any reason, for purposes here
2340                             // we are going to consider it empty.  The specific cached state
2341                             // doesn't propagate except under certain conditions.
2342                             clientProcState = PROCESS_STATE_CACHED_EMPTY;
2343                         }
2344                         String adjType = null;
2345                         if (cr.hasFlag(Context.BIND_ALLOW_OOM_MANAGEMENT)) {
2346                             // Similar to BIND_WAIVE_PRIORITY, keep it unfrozen.
2347                             if (clientAdj < CACHED_APP_MIN_ADJ) {
2348                                 app.mOptRecord.setShouldNotFreeze(true);
2349                             }
2350                             // Not doing bind OOM management, so treat
2351                             // this guy more like a started service.
2352                             if (state.hasShownUi() && !state.getCachedIsHomeProcess()) {
2353                                 // If this process has shown some UI, let it immediately
2354                                 // go to the LRU list because it may be pretty heavy with
2355                                 // UI stuff.  We'll tag it with a label just to help
2356                                 // debug and understand what is going on.
2357                                 if (adj > clientAdj) {
2358                                     adjType = "cch-bound-ui-services";
2359                                 }
2360                                 state.setCached(false);
2361                                 clientAdj = adj;
2362                                 clientProcState = procState;
2363                             } else {
2364                                 if (now >= (s.lastActivity
2365                                         + mConstants.MAX_SERVICE_INACTIVITY)) {
2366                                     // This service has not seen activity within
2367                                     // recent memory, so allow it to drop to the
2368                                     // LRU list if there is no other reason to keep
2369                                     // it around.  We'll also tag it with a label just
2370                                     // to help debug and undertand what is going on.
2371                                     if (adj > clientAdj) {
2372                                         adjType = "cch-bound-services";
2373                                     }
2374                                     clientAdj = adj;
2375                                 }
2376                             }
2377                         }
2378                         if (adj > clientAdj) {
2379                             // If this process has recently shown UI, and
2380                             // the process that is binding to it is less
2381                             // important than being visible, then we don't
2382                             // care about the binding as much as we care
2383                             // about letting this process get into the LRU
2384                             // list to be killed and restarted if needed for
2385                             // memory.
2386                             if (state.hasShownUi() && !state.getCachedIsHomeProcess()
2387                                     && clientAdj > PERCEPTIBLE_APP_ADJ) {
2388                                 if (adj >= CACHED_APP_MIN_ADJ) {
2389                                     adjType = "cch-bound-ui-services";
2390                                 }
2391                             } else {
2392                                 int newAdj;
2393                                 int lbAdj = VISIBLE_APP_ADJ; // lower bound of adj.
2394                                 if (cr.hasFlag(Context.BIND_ABOVE_CLIENT
2395                                         | Context.BIND_IMPORTANT)) {
2396                                     if (clientAdj >= PERSISTENT_SERVICE_ADJ) {
2397                                         newAdj = clientAdj;
2398                                     } else {
2399                                         // make this service persistent
2400                                         newAdj = PERSISTENT_SERVICE_ADJ;
2401                                         schedGroup = SCHED_GROUP_DEFAULT;
2402                                         procState = ActivityManager.PROCESS_STATE_PERSISTENT;
2403                                         cr.trackProcState(procState, mAdjSeq);
2404                                         trackedProcState = true;
2405                                     }
2406                                 } else if (cr.hasFlag(Context.BIND_NOT_PERCEPTIBLE)
2407                                         && clientAdj <= PERCEPTIBLE_APP_ADJ
2408                                         && adj >= (lbAdj = PERCEPTIBLE_LOW_APP_ADJ)) {
2409                                     newAdj = PERCEPTIBLE_LOW_APP_ADJ;
2410                                 } else if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE)
2411                                         && cr.notHasFlag(Context.BIND_NOT_FOREGROUND)
2412                                         && clientAdj < PERCEPTIBLE_APP_ADJ
2413                                         && adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) {
2414                                     // This is for user-initiated jobs.
2415                                     // We use APP_ADJ + 1 here, so we can tell them apart from FGS.
2416                                     newAdj = PERCEPTIBLE_APP_ADJ + 1;
2417                                 } else if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE)
2418                                         && cr.hasFlag(Context.BIND_NOT_FOREGROUND)
2419                                         && clientAdj < PERCEPTIBLE_APP_ADJ
2420                                         && adj >= (lbAdj = (PERCEPTIBLE_MEDIUM_APP_ADJ + 2))) {
2421                                     // This is for expedited jobs.
2422                                     // We use MEDIUM_APP_ADJ + 2 here, so we can tell apart
2423                                     // EJ and short-FGS.
2424                                     newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 2;
2425                                 } else if (cr.hasFlag(Context.BIND_NOT_VISIBLE)
2426                                         && clientAdj < PERCEPTIBLE_APP_ADJ
2427                                         && adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) {
2428                                     newAdj = PERCEPTIBLE_APP_ADJ;
2429                                 } else if (clientAdj >= PERCEPTIBLE_APP_ADJ) {
2430                                     newAdj = clientAdj;
2431                                 } else if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)
2432                                         && clientAdj <= VISIBLE_APP_ADJ
2433                                         && adj > VISIBLE_APP_ADJ) {
2434                                     newAdj = VISIBLE_APP_ADJ;
2435                                 } else {
2436                                     if (adj > VISIBLE_APP_ADJ) {
2437                                         // TODO: Is this too limiting for apps bound from TOP?
2438                                         newAdj = Math.max(clientAdj, lbAdj);
2439                                     } else {
2440                                         newAdj = adj;
2441                                     }
2442                                 }
2443                                 if (!cstate.isCached()) {
2444                                     state.setCached(false);
2445                                 }
2446                                 if (adj >  newAdj) {
2447                                     adj = newAdj;
2448                                     state.setCurRawAdj(adj);
2449                                     adjType = "service";
2450                                 }
2451                             }
2452                         }
2453                         if (cr.notHasFlag(Context.BIND_NOT_FOREGROUND
2454                                 | Context.BIND_IMPORTANT_BACKGROUND)) {
2455                             // This will treat important bound services identically to
2456                             // the top app, which may behave differently than generic
2457                             // foreground work.
2458                             final int curSchedGroup = cstate.getCurrentSchedulingGroup();
2459                             if (curSchedGroup > schedGroup) {
2460                                 if (cr.hasFlag(Context.BIND_IMPORTANT)) {
2461                                     schedGroup = curSchedGroup;
2462                                 } else {
2463                                     schedGroup = SCHED_GROUP_DEFAULT;
2464                                 }
2465                             }
2466                             if (clientProcState < PROCESS_STATE_TOP) {
2467                                 // Special handling for above-top states (persistent
2468                                 // processes).  These should not bring the current process
2469                                 // into the top state, since they are not on top.  Instead
2470                                 // give them the best bound state after that.
2471                                 if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)) {
2472                                     clientProcState = PROCESS_STATE_FOREGROUND_SERVICE;
2473                                 } else if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) {
2474                                     clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
2475                                 } else if (mService.mWakefulness.get()
2476                                         == PowerManagerInternal.WAKEFULNESS_AWAKE
2477                                         && cr.hasFlag(Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE))
2478                                 {
2479                                     clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
2480                                 } else {
2481                                     clientProcState =
2482                                             PROCESS_STATE_IMPORTANT_FOREGROUND;
2483                                 }
2484                             } else if (clientProcState == PROCESS_STATE_TOP) {
2485                                 // Go at most to BOUND_TOP, unless requested to elevate
2486                                 // to client's state.
2487                                 clientProcState = PROCESS_STATE_BOUND_TOP;
2488                                 final boolean enabled = cstate.getCachedCompatChange(
2489                                         CACHED_COMPAT_CHANGE_PROCESS_CAPABILITY);
2490                                 if (enabled) {
2491                                     if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
2492                                         // TOP process passes all capabilities to the service.
2493                                         capability |= cstate.getCurCapability();
2494                                     } else {
2495                                         // TOP process passes no capability to the service.
2496                                     }
2497                                 } else {
2498                                     // TOP process passes all capabilities to the service.
2499                                     capability |= cstate.getCurCapability();
2500                                 }
2501                             }
2502                         } else if (cr.notHasFlag(Context.BIND_IMPORTANT_BACKGROUND)) {
2503                             if (clientProcState <
2504                                     PROCESS_STATE_TRANSIENT_BACKGROUND) {
2505                                 clientProcState =
2506                                         PROCESS_STATE_TRANSIENT_BACKGROUND;
2507                             }
2508                         } else {
2509                             if (clientProcState <
2510                                     PROCESS_STATE_IMPORTANT_BACKGROUND) {
2511                                 clientProcState =
2512                                         PROCESS_STATE_IMPORTANT_BACKGROUND;
2513                             }
2514                         }
2515 
2516                         if (cr.hasFlag(Context.BIND_SCHEDULE_LIKE_TOP_APP) && clientIsSystem) {
2517                             schedGroup = SCHED_GROUP_TOP_APP;
2518                             scheduleLikeTopApp = true;
2519                         }
2520 
2521                         if (!trackedProcState) {
2522                             cr.trackProcState(clientProcState, mAdjSeq);
2523                         }
2524 
2525                         if (procState > clientProcState) {
2526                             procState = clientProcState;
2527                             state.setCurRawProcState(procState);
2528                             if (adjType == null) {
2529                                 adjType = "service";
2530                             }
2531                         }
2532                         if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND
2533                                 && cr.hasFlag(Context.BIND_SHOWING_UI)) {
2534                             app.setPendingUiClean(true);
2535                         }
2536                         if (adjType != null) {
2537                             state.setAdjType(adjType);
2538                             state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
2539                                     .REASON_SERVICE_IN_USE);
2540                             state.setAdjSource(client);
2541                             state.setAdjSourceProcState(clientProcState);
2542                             state.setAdjTarget(s.instanceName);
2543                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2544                                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
2545                                         + ": " + app + ", due to " + client
2546                                         + " adj=" + adj + " procState="
2547                                         + ProcessList.makeProcStateString(procState));
2548                             }
2549                         }
2550                     } else { // BIND_WAIVE_PRIORITY == true
2551                         // BIND_WAIVE_PRIORITY bindings are special when it comes to the
2552                         // freezer. Processes bound via WPRI are expected to be running,
2553                         // but they are not promoted in the LRU list to keep them out of
2554                         // cached. As a result, they can freeze based on oom_adj alone.
2555                         // Normally, bindToDeath would fire when a cached app would die
2556                         // in the background, but nothing will fire when a running process
2557                         // pings a frozen process. Accordingly, any cached app that is
2558                         // bound by an unfrozen app via a WPRI binding has to remain
2559                         // unfrozen.
2560                         if (clientAdj < CACHED_APP_MIN_ADJ) {
2561                             app.mOptRecord.setShouldNotFreeze(true);
2562                         }
2563                     }
2564                     if (cr.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) {
2565                         psr.setTreatLikeActivity(true);
2566                     }
2567                     final ActivityServiceConnectionsHolder a = cr.activity;
2568                     if (cr.hasFlag(Context.BIND_ADJUST_WITH_ACTIVITY)) {
2569                         if (a != null && adj > FOREGROUND_APP_ADJ
2570                                 && a.isActivityVisible()) {
2571                             adj = FOREGROUND_APP_ADJ;
2572                             state.setCurRawAdj(adj);
2573                             if (cr.notHasFlag(Context.BIND_NOT_FOREGROUND)) {
2574                                 if (cr.hasFlag(Context.BIND_IMPORTANT)) {
2575                                     schedGroup = SCHED_GROUP_TOP_APP_BOUND;
2576                                 } else {
2577                                     schedGroup = SCHED_GROUP_DEFAULT;
2578                                 }
2579                             }
2580                             state.setCached(false);
2581                             state.setAdjType("service");
2582                             state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
2583                                     .REASON_SERVICE_IN_USE);
2584                             state.setAdjSource(a);
2585                             state.setAdjSourceProcState(procState);
2586                             state.setAdjTarget(s.instanceName);
2587                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2588                                 reportOomAdjMessageLocked(TAG_OOM_ADJ,
2589                                         "Raise to service w/activity: " + app);
2590                             }
2591                         }
2592                     }
2593                 }
2594             }
2595         }
2596 
2597         final ProcessProviderRecord ppr = app.mProviders;
2598         for (int provi = ppr.numberOfProviders() - 1;
2599                 provi >= 0 && (adj > FOREGROUND_APP_ADJ
2600                         || schedGroup == SCHED_GROUP_BACKGROUND
2601                         || procState > PROCESS_STATE_TOP);
2602                 provi--) {
2603             ContentProviderRecord cpr = ppr.getProviderAt(provi);
2604             for (int i = cpr.connections.size() - 1;
2605                     i >= 0 && (adj > FOREGROUND_APP_ADJ
2606                             || schedGroup == SCHED_GROUP_BACKGROUND
2607                             || procState > PROCESS_STATE_TOP);
2608                     i--) {
2609                 ContentProviderConnection conn = cpr.connections.get(i);
2610                 ProcessRecord client = conn.client;
2611                 final ProcessStateRecord cstate = client.mState;
2612                 if (client == app) {
2613                     // Being our own client is not interesting.
2614                     continue;
2615                 }
2616                 if (computeClients) {
2617                     computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now, cycleReEval, true);
2618                 } else {
2619                     cstate.setCurRawAdj(cstate.getCurAdj());
2620                     cstate.setCurRawProcState(cstate.getCurProcState());
2621                 }
2622 
2623                 if (shouldSkipDueToCycle(app, cstate, procState, adj, cycleReEval)) {
2624                     continue;
2625                 }
2626 
2627                 int clientAdj = cstate.getCurRawAdj();
2628                 int clientProcState = cstate.getCurRawProcState();
2629 
2630                 // We always propagate PROCESS_CAPABILITY_BFSL to providers here,
2631                 // but, right before actually setting it to the process,
2632                 // we check the final procstate, and remove it if the procsate is below BFGS.
2633                 capability |= getBfslCapabilityFromClient(client);
2634 
2635                 if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
2636                     // If the other app is cached for any reason, for purposes here
2637                     // we are going to consider it empty.
2638                     clientProcState = PROCESS_STATE_CACHED_EMPTY;
2639                 }
2640                 if (client.mOptRecord.shouldNotFreeze()) {
2641                     // Propagate the shouldNotFreeze flag down the bindings.
2642                     app.mOptRecord.setShouldNotFreeze(true);
2643                 }
2644 
2645                 boundByNonBgRestricted |= cstate.isCurBoundByNonBgRestrictedApp()
2646                         || clientProcState <= PROCESS_STATE_BOUND_TOP
2647                         || (clientProcState == PROCESS_STATE_FOREGROUND_SERVICE
2648                                 && !cstate.isBackgroundRestricted());
2649 
2650                 String adjType = null;
2651                 if (adj > clientAdj) {
2652                     if (state.hasShownUi() && !state.getCachedIsHomeProcess()
2653                             && clientAdj > PERCEPTIBLE_APP_ADJ) {
2654                         adjType = "cch-ui-provider";
2655                     } else {
2656                         adj = Math.max(clientAdj, FOREGROUND_APP_ADJ);
2657                         state.setCurRawAdj(adj);
2658                         adjType = "provider";
2659                     }
2660                     state.setCached(state.isCached() & cstate.isCached());
2661                 }
2662 
2663                 if (clientProcState <= PROCESS_STATE_FOREGROUND_SERVICE) {
2664                     if (adjType == null) {
2665                         adjType = "provider";
2666                     }
2667                     if (clientProcState == PROCESS_STATE_TOP) {
2668                         clientProcState = PROCESS_STATE_BOUND_TOP;
2669                     } else {
2670                         clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
2671                     }
2672                 }
2673 
2674                 conn.trackProcState(clientProcState, mAdjSeq);
2675                 if (procState > clientProcState) {
2676                     procState = clientProcState;
2677                     state.setCurRawProcState(procState);
2678                 }
2679                 if (cstate.getCurrentSchedulingGroup() > schedGroup) {
2680                     schedGroup = SCHED_GROUP_DEFAULT;
2681                 }
2682                 if (adjType != null) {
2683                     state.setAdjType(adjType);
2684                     state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
2685                             .REASON_PROVIDER_IN_USE);
2686                     state.setAdjSource(client);
2687                     state.setAdjSourceProcState(clientProcState);
2688                     state.setAdjTarget(cpr.name);
2689                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2690                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
2691                                 + ": " + app + ", due to " + client
2692                                 + " adj=" + adj + " procState="
2693                                 + ProcessList.makeProcStateString(procState));
2694                     }
2695                 }
2696             }
2697             // If the provider has external (non-framework) process
2698             // dependencies, ensure that its adjustment is at least
2699             // FOREGROUND_APP_ADJ.
2700             if (cpr.hasExternalProcessHandles()) {
2701                 if (adj > FOREGROUND_APP_ADJ) {
2702                     adj = FOREGROUND_APP_ADJ;
2703                     state.setCurRawAdj(adj);
2704                     schedGroup = SCHED_GROUP_DEFAULT;
2705                     state.setCached(false);
2706                     state.setAdjType("ext-provider");
2707                     state.setAdjTarget(cpr.name);
2708                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2709                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
2710                                 "Raise adj to external provider: " + app);
2711                     }
2712                 }
2713                 if (procState > PROCESS_STATE_IMPORTANT_FOREGROUND) {
2714                     procState = PROCESS_STATE_IMPORTANT_FOREGROUND;
2715                     state.setCurRawProcState(procState);
2716                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2717                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
2718                                 "Raise procstate to external provider: " + app);
2719                     }
2720                 }
2721             }
2722         }
2723 
2724         if (ppr.getLastProviderTime() > 0
2725                 && (ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
2726             if (adj > PREVIOUS_APP_ADJ) {
2727                 adj = PREVIOUS_APP_ADJ;
2728                 schedGroup = SCHED_GROUP_BACKGROUND;
2729                 state.setCached(false);
2730                 state.setAdjType("recent-provider");
2731                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2732                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
2733                             "Raise adj to recent provider: " + app);
2734                 }
2735             }
2736             if (procState > PROCESS_STATE_LAST_ACTIVITY) {
2737                 procState = PROCESS_STATE_LAST_ACTIVITY;
2738                 state.setAdjType("recent-provider");
2739                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
2740                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
2741                             "Raise procstate to recent provider: " + app);
2742                 }
2743             }
2744         }
2745 
2746         if (procState >= PROCESS_STATE_CACHED_EMPTY) {
2747             if (psr.hasClientActivities()) {
2748                 // This is a cached process, but with client activities.  Mark it so.
2749                 procState = PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
2750                 state.setAdjType("cch-client-act");
2751             } else if (psr.isTreatedLikeActivity()) {
2752                 // This is a cached process, but somebody wants us to treat it like it has
2753                 // an activity, okay!
2754                 procState = PROCESS_STATE_CACHED_ACTIVITY;
2755                 state.setAdjType("cch-as-act");
2756             }
2757         }
2758 
2759         if (adj == SERVICE_ADJ) {
2760             if (doingAll && !cycleReEval) {
2761                 state.setServiceB(mNewNumAServiceProcs > (mNumServiceProcs / 3));
2762                 mNewNumServiceProcs++;
2763                 if (!state.isServiceB()) {
2764                     // This service isn't far enough down on the LRU list to
2765                     // normally be a B service, but if we are low on RAM and it
2766                     // is large we want to force it down since we would prefer to
2767                     // keep launcher over it.
2768                     if (!mService.mAppProfiler.isLastMemoryLevelNormal()
2769                             && app.mProfile.getLastPss()
2770                             >= mProcessList.getCachedRestoreThresholdKb()) {
2771                         state.setServiceHighRam(true);
2772                         state.setServiceB(true);
2773                         //Slog.i(TAG, "ADJ " + app + " high ram!");
2774                     } else {
2775                         mNewNumAServiceProcs++;
2776                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
2777                     }
2778                 } else {
2779                     state.setServiceHighRam(false);
2780                 }
2781             }
2782             if (state.isServiceB()) {
2783                 adj = SERVICE_B_ADJ;
2784             }
2785         }
2786 
2787         state.setCurRawAdj(adj);
2788         adj = psr.modifyRawOomAdj(adj);
2789         if (adj > state.getMaxAdj()) {
2790             adj = state.getMaxAdj();
2791             if (adj <= PERCEPTIBLE_LOW_APP_ADJ) {
2792                 schedGroup = SCHED_GROUP_DEFAULT;
2793             }
2794         }
2795 
2796         // Put bound foreground services in a special sched group for additional
2797         // restrictions on screen off
2798         if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE
2799                 && mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
2800                 && !scheduleLikeTopApp) {
2801             if (schedGroup > SCHED_GROUP_RESTRICTED) {
2802                 schedGroup = SCHED_GROUP_RESTRICTED;
2803             }
2804         }
2805 
2806         // apply capability from FGS.
2807         if (psr.hasForegroundServices()) {
2808             capability |= capabilityFromFGS;
2809         }
2810 
2811         capability |= getDefaultCapability(app, procState);
2812 
2813         // Procstates below BFGS should never have this capability.
2814         if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
2815             capability &= ~PROCESS_CAPABILITY_BFSL;
2816         }
2817 
2818 
2819         if (app.isPendingFinishAttach()) {
2820             // If the app is still starting up. We reset the computations to the
2821             // hardcoded values in setAttachingProcessStatesLSP. This ensures that the app keeps
2822             // hard-coded default 'startup' oom scores while starting up. When it finishes startup,
2823             // we'll recompute oom scores based on it's actual hosted compoenents.
2824             setAttachingProcessStatesLSP(app);
2825             state.setAdjSeq(mAdjSeq);
2826             state.setCompletedAdjSeq(state.getAdjSeq());
2827             return false;
2828         }
2829 
2830         // Do final modification to adj.  Everything we do between here and applying
2831         // the final setAdj must be done in this function, because we will also use
2832         // it when computing the final cached adj later.  Note that we don't need to
2833         // worry about this for max adj above, since max adj will always be used to
2834         // keep it out of the cached vaues.
2835         state.setCurAdj(adj);
2836         state.setCurCapability(capability);
2837         state.setCurrentSchedulingGroup(schedGroup);
2838         state.setCurProcState(procState);
2839         state.setCurRawProcState(procState);
2840         state.updateLastInvisibleTime(hasVisibleActivities);
2841         state.setHasForegroundActivities(foregroundActivities);
2842         state.setCompletedAdjSeq(mAdjSeq);
2843         state.setCurBoundByNonBgRestrictedApp(boundByNonBgRestricted);
2844 
2845         // if curAdj or curProcState improved, then this process was promoted
2846         return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState
2847                 || state.getCurCapability() != prevCapability;
2848     }
2849 
getDefaultCapability(ProcessRecord app, int procState)2850     private int getDefaultCapability(ProcessRecord app, int procState) {
2851         final int networkCapabilities =
2852                 NetworkPolicyManager.getDefaultProcessNetworkCapabilities(procState);
2853         final int baseCapabilities;
2854         switch (procState) {
2855             case PROCESS_STATE_PERSISTENT:
2856             case PROCESS_STATE_PERSISTENT_UI:
2857             case PROCESS_STATE_TOP:
2858                 baseCapabilities = PROCESS_CAPABILITY_ALL; // BFSL allowed
2859                 break;
2860             case PROCESS_STATE_BOUND_TOP:
2861                 baseCapabilities = PROCESS_CAPABILITY_BFSL;
2862                 break;
2863             case PROCESS_STATE_FOREGROUND_SERVICE:
2864                 if (app.getActiveInstrumentation() != null) {
2865                     baseCapabilities = PROCESS_CAPABILITY_ALL_IMPLICIT;
2866                 } else {
2867                     // Capability from foreground service is conditional depending on
2868                     // foregroundServiceType in the manifest file and the
2869                     // mAllowWhileInUsePermissionInFgs flag.
2870                     baseCapabilities = PROCESS_CAPABILITY_NONE;
2871                 }
2872                 break;
2873             default:
2874                 baseCapabilities = PROCESS_CAPABILITY_NONE;
2875                 break;
2876         }
2877         return baseCapabilities | networkCapabilities;
2878     }
2879 
2880     /**
2881      * @return the BFSL capability from a client (of a service binding or provider).
2882      */
getBfslCapabilityFromClient(ProcessRecord client)2883     int getBfslCapabilityFromClient(ProcessRecord client) {
2884         // Procstates above FGS should always have this flag. We shouldn't need this logic,
2885         // but let's do it just in case.
2886         if (client.mState.getCurProcState() < PROCESS_STATE_FOREGROUND_SERVICE) {
2887             return PROCESS_CAPABILITY_BFSL;
2888         }
2889         // Otherwise, use the process's cur capability.
2890 
2891         // Note: BFSL is a per-UID check, not per-process, but here, the BFSL capability is still
2892         // propagated on a per-process basis.
2893         //
2894         // For example, consider this case:
2895         // - There are App 1 and App 2.
2896         // - App 1 has two processes
2897         //   Proc #1A, procstate BFGS with CAPABILITY_BFSL
2898         //   Proc #1B, procstate FGS with no CAPABILITY_BFSL (i.e. process has a short FGS)
2899         //        And this process binds to Proc #2 of App 2.
2900         //
2901         //       (Note because #1A has CAPABILITY_BFSL, App 1's UidRecord has CAPABILITY_BFSL.)
2902         //
2903         // - App 2 has one process:
2904         //   Proc #2, procstate FGS due to the above binding, _with no CAPABILITY_BFSL_.
2905         //
2906         // In this case, #2 will not get CAPABILITY_BFSL because the binding client (#1B)
2907         // doesn't have this capability. (Even though App 1's UidRecord has it.)
2908         //
2909         // This may look weird, because App 2 _is_ still BFSL allowed, because "it's bound by
2910         // an app that is BFSL-allowed". (See [bookmark: 61867f60-007c-408c-a2c4-e19e96056135]
2911         // in ActiveServices.)
2912         //
2913         // So why don't we propagate PROCESS_CAPABILITY_BFSL from App 1's UID record?
2914         // This is because short-FGS acts like "below BFGS" as far as BFSL is concerned,
2915         // similar to how JobScheduler jobs are below BFGS and apps can't start FGS from there.
2916         //
2917         // If #1B was running a job instead of a short-FGS, then its procstate would be below BFGS.
2918         // Then #2's procstate would also be below BFGS. So #2 wouldn't get CAPABILITY_BFSL.
2919         // Similarly, if #1B has a short FGS, even though the procstate of #1B and #2 would be FGS,
2920         // they both still wouldn't get CAPABILITY_BFSL.
2921         //
2922         // However, again, because #2 is bound by App 1, which is BFSL-allowed (because of #1A)
2923         // App 2 would still BFSL-allowed, due to the aforementioned check in ActiveServices.
2924         return client.mState.getCurCapability() & PROCESS_CAPABILITY_BFSL;
2925     }
2926 
2927     /**
2928      * Checks if for the given app and client, there's a cycle that should skip over the client
2929      * for now or use partial values to evaluate the effect of the client binding.
2930      * @param app
2931      * @param client
2932      * @param procState procstate evaluated so far for this app
2933      * @param adj oom_adj evaluated so far for this app
2934      * @param cycleReEval whether we're currently re-evaluating due to a cycle, and not the first
2935      *                    evaluation.
2936      * @return whether to skip using the client connection at this time
2937      */
shouldSkipDueToCycle(ProcessRecord app, ProcessStateRecord client, int procState, int adj, boolean cycleReEval)2938     private boolean shouldSkipDueToCycle(ProcessRecord app, ProcessStateRecord client,
2939             int procState, int adj, boolean cycleReEval) {
2940         if (client.containsCycle()) {
2941             // We've detected a cycle. We should retry computeOomAdjLSP later in
2942             // case a later-checked connection from a client  would raise its
2943             // priority legitimately.
2944             app.mState.setContainsCycle(true);
2945             mProcessesInCycle.add(app);
2946             // If the client has not been completely evaluated, check if it's worth
2947             // using the partial values.
2948             if (client.getCompletedAdjSeq() < mAdjSeq) {
2949                 if (cycleReEval) {
2950                     // If the partial values are no better, skip until the next
2951                     // attempt
2952                     if (client.getCurRawProcState() >= procState
2953                             && client.getCurRawAdj() >= adj) {
2954                         return true;
2955                     }
2956                     // Else use the client's partial procstate and adj to adjust the
2957                     // effect of the binding
2958                 } else {
2959                     return true;
2960                 }
2961             }
2962         }
2963         return false;
2964     }
2965 
2966     /** Inform the oomadj observer of changes to oomadj. Used by tests. */
2967     @GuardedBy("mService")
reportOomAdjMessageLocked(String tag, String msg)2968     private void reportOomAdjMessageLocked(String tag, String msg) {
2969         Slog.d(tag, msg);
2970         synchronized (mService.mOomAdjObserverLock) {
2971             if (mService.mCurOomAdjObserver != null) {
2972                 mService.mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg)
2973                         .sendToTarget();
2974             }
2975         }
2976     }
2977 
onWakefulnessChanged(int wakefulness)2978     void onWakefulnessChanged(int wakefulness) {
2979         mCachedAppOptimizer.onWakefulnessChanged(wakefulness);
2980     }
2981 
2982     /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */
2983     @GuardedBy({"mService", "mProcLock"})
applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReson)2984     private boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now,
2985             long nowElapsed, @OomAdjReason int oomAdjReson) {
2986         boolean success = true;
2987         final ProcessStateRecord state = app.mState;
2988         final UidRecord uidRec = app.getUidRecord();
2989 
2990         if (state.getCurRawAdj() != state.getSetRawAdj()) {
2991             state.setSetRawAdj(state.getCurRawAdj());
2992         }
2993 
2994         int changes = 0;
2995 
2996         if (state.getCurAdj() != state.getSetAdj()) {
2997             mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app);
2998         }
2999 
3000         if (state.getCurAdj() != state.getSetAdj()) {
3001             ProcessList.setOomAdj(app.getPid(), app.uid, state.getCurAdj());
3002             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) {
3003                 String msg = "Set " + app.getPid() + " " + app.processName + " adj "
3004                         + state.getCurAdj() + ": " + state.getAdjType();
3005                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
3006             }
3007             state.setSetAdj(state.getCurAdj());
3008             if (uidRec != null) {
3009                 uidRec.noteProcAdjChanged();
3010             }
3011             state.setVerifiedAdj(INVALID_ADJ);
3012         }
3013 
3014         final int curSchedGroup = state.getCurrentSchedulingGroup();
3015         if (state.getSetSchedGroup() != curSchedGroup) {
3016             int oldSchedGroup = state.getSetSchedGroup();
3017             state.setSetSchedGroup(curSchedGroup);
3018             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.uid) {
3019                 String msg = "Setting sched group of " + app.processName
3020                         + " to " + curSchedGroup + ": " + state.getAdjType();
3021                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
3022             }
3023             if (app.getWaitingToKill() != null && app.mReceivers.numberOfCurReceivers() == 0
3024                     && ActivityManager.isProcStateBackground(state.getSetProcState())) {
3025                 app.killLocked(app.getWaitingToKill(), ApplicationExitInfo.REASON_USER_REQUESTED,
3026                         ApplicationExitInfo.SUBREASON_REMOVE_TASK, true);
3027                 success = false;
3028             } else {
3029                 int processGroup;
3030                 switch (curSchedGroup) {
3031                     case SCHED_GROUP_BACKGROUND:
3032                         processGroup = THREAD_GROUP_BACKGROUND;
3033                         break;
3034                     case SCHED_GROUP_TOP_APP:
3035                     case SCHED_GROUP_TOP_APP_BOUND:
3036                         processGroup = THREAD_GROUP_TOP_APP;
3037                         break;
3038                     case SCHED_GROUP_RESTRICTED:
3039                         processGroup = THREAD_GROUP_RESTRICTED;
3040                         break;
3041                     default:
3042                         processGroup = THREAD_GROUP_DEFAULT;
3043                         break;
3044                 }
3045                 mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage(
3046                         0 /* unused */, app.getPid(), processGroup, app.processName));
3047                 try {
3048                     final int renderThreadTid = app.getRenderThreadTid();
3049                     if (curSchedGroup == SCHED_GROUP_TOP_APP) {
3050                         // do nothing if we already switched to RT
3051                         if (oldSchedGroup != SCHED_GROUP_TOP_APP) {
3052                             app.getWindowProcessController().onTopProcChanged();
3053                             if (mService.mUseFifoUiScheduling) {
3054                                 // Switch UI pipeline for app to SCHED_FIFO
3055                                 state.setSavedPriority(Process.getThreadPriority(app.getPid()));
3056                                 mService.scheduleAsFifoPriority(app.getPid(), true);
3057                                 if (renderThreadTid != 0) {
3058                                     mService.scheduleAsFifoPriority(renderThreadTid,
3059                                             /* suppressLogs */true);
3060                                     if (DEBUG_OOM_ADJ) {
3061                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
3062                                                 renderThreadTid + ") to FIFO");
3063                                     }
3064                                 } else {
3065                                     if (DEBUG_OOM_ADJ) {
3066                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
3067                                     }
3068                                 }
3069                             } else {
3070                                 // Boost priority for top app UI and render threads
3071                                 setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
3072                                 if (renderThreadTid != 0) {
3073                                     try {
3074                                         setThreadPriority(renderThreadTid,
3075                                                 THREAD_PRIORITY_TOP_APP_BOOST);
3076                                     } catch (IllegalArgumentException e) {
3077                                         // thread died, ignore
3078                                     }
3079                                 }
3080                             }
3081                         }
3082                     } else if (oldSchedGroup == SCHED_GROUP_TOP_APP
3083                             && curSchedGroup != SCHED_GROUP_TOP_APP) {
3084                         app.getWindowProcessController().onTopProcChanged();
3085                         if (mService.mUseFifoUiScheduling) {
3086                             try {
3087                                 // Reset UI pipeline to SCHED_OTHER
3088                                 setThreadScheduler(app.getPid(), SCHED_OTHER, 0);
3089                                 setThreadPriority(app.getPid(), state.getSavedPriority());
3090                                 if (renderThreadTid != 0) {
3091                                     setThreadScheduler(renderThreadTid,
3092                                             SCHED_OTHER, 0);
3093                                 }
3094                             } catch (IllegalArgumentException e) {
3095                                 Slog.w(TAG,
3096                                         "Failed to set scheduling policy, thread does not exist:\n"
3097                                                 + e);
3098                             } catch (SecurityException e) {
3099                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
3100                             }
3101                         } else {
3102                             // Reset priority for top app UI and render threads
3103                             setThreadPriority(app.getPid(), 0);
3104                         }
3105 
3106                         if (renderThreadTid != 0) {
3107                             setThreadPriority(renderThreadTid, THREAD_PRIORITY_DISPLAY);
3108                         }
3109                     }
3110                 } catch (Exception e) {
3111                     if (DEBUG_ALL) {
3112                         Slog.w(TAG, "Failed setting thread priority of " + app.getPid(), e);
3113                     }
3114                 }
3115             }
3116         }
3117         if (state.hasRepForegroundActivities() != state.hasForegroundActivities()) {
3118             state.setRepForegroundActivities(state.hasForegroundActivities());
3119             changes |= ActivityManagerService.ProcessChangeItem.CHANGE_ACTIVITIES;
3120         }
3121 
3122         updateAppFreezeStateLSP(app, oomAdjReson);
3123 
3124         if (state.getReportedProcState() != state.getCurProcState()) {
3125             state.setReportedProcState(state.getCurProcState());
3126             if (app.getThread() != null) {
3127                 try {
3128                     if (false) {
3129                         //RuntimeException h = new RuntimeException("here");
3130                         Slog.i(TAG, "Sending new process state " + state.getReportedProcState()
3131                                 + " to " + app /*, h*/);
3132                     }
3133                     app.getThread().setProcessState(state.getReportedProcState());
3134                 } catch (RemoteException e) {
3135                 }
3136             }
3137         }
3138         boolean forceUpdatePssTime = false;
3139         if (state.getSetProcState() == PROCESS_STATE_NONEXISTENT
3140                 || ProcessList.procStatesDifferForMem(
3141                         state.getCurProcState(), state.getSetProcState())) {
3142             state.setLastStateTime(now);
3143             forceUpdatePssTime = true;
3144             if (DEBUG_PSS) {
3145                 Slog.d(TAG_PSS, "Process state change from "
3146                         + ProcessList.makeProcStateString(state.getSetProcState()) + " to "
3147                         + ProcessList.makeProcStateString(state.getCurProcState()) + " next pss in "
3148                         + (app.mProfile.getNextPssTime() - now) + ": " + app);
3149             }
3150         }
3151         synchronized (mService.mAppProfiler.mProfilerLock) {
3152             app.mProfile.updateProcState(app.mState);
3153             mService.mAppProfiler.updateNextPssTimeLPf(
3154                     state.getCurProcState(), app.mProfile, now, forceUpdatePssTime);
3155         }
3156         if (state.getSetProcState() != state.getCurProcState()) {
3157             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.uid) {
3158                 String msg = "Proc state change of " + app.processName
3159                         + " to " + ProcessList.makeProcStateString(state.getCurProcState())
3160                         + " (" + state.getCurProcState() + ")" + ": " + state.getAdjType();
3161                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
3162             }
3163             boolean setImportant = state.getSetProcState() < PROCESS_STATE_SERVICE;
3164             boolean curImportant = state.getCurProcState() < PROCESS_STATE_SERVICE;
3165             if (setImportant && !curImportant) {
3166                 // This app is no longer something we consider important enough to allow to use
3167                 // arbitrary amounts of battery power. Note its current CPU time to later know to
3168                 // kill it if it is not behaving well.
3169                 state.setWhenUnimportant(now);
3170                 app.mProfile.mLastCpuTime.set(0);
3171             }
3172             // Inform UsageStats of important process state change
3173             // Must be called before updating setProcState
3174             maybeUpdateUsageStatsLSP(app, nowElapsed);
3175 
3176             maybeUpdateLastTopTime(state, now);
3177 
3178             state.setSetProcState(state.getCurProcState());
3179             if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_HOME) {
3180                 state.setNotCachedSinceIdle(false);
3181             }
3182             if (!doingAll) {
3183                 synchronized (mService.mProcessStats.mLock) {
3184                     mService.setProcessTrackerStateLOSP(app,
3185                             mService.mProcessStats.getMemFactorLocked());
3186                 }
3187             } else {
3188                 state.setProcStateChanged(true);
3189             }
3190         } else if (state.hasReportedInteraction()) {
3191             final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange(
3192                     CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME);
3193             final long interactionThreshold = fgsInteractionChangeEnabled
3194                     ? mConstants.USAGE_STATS_INTERACTION_INTERVAL_POST_S
3195                     : mConstants.USAGE_STATS_INTERACTION_INTERVAL_PRE_S;
3196             // For apps that sit around for a long time in the interactive state, we need
3197             // to report this at least once a day so they don't go idle.
3198             if ((nowElapsed - state.getInteractionEventTime()) > interactionThreshold) {
3199                 maybeUpdateUsageStatsLSP(app, nowElapsed);
3200             }
3201         } else {
3202             final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange(
3203                     CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME);
3204             final long interactionThreshold = fgsInteractionChangeEnabled
3205                     ? mConstants.SERVICE_USAGE_INTERACTION_TIME_POST_S
3206                     : mConstants.SERVICE_USAGE_INTERACTION_TIME_PRE_S;
3207             // For foreground services that sit around for a long time but are not interacted with.
3208             if ((nowElapsed - state.getFgInteractionTime()) > interactionThreshold) {
3209                 maybeUpdateUsageStatsLSP(app, nowElapsed);
3210             }
3211         }
3212 
3213         if (state.getCurCapability() != state.getSetCapability()) {
3214             state.setSetCapability(state.getCurCapability());
3215         }
3216 
3217         final boolean curBoundByNonBgRestrictedApp = state.isCurBoundByNonBgRestrictedApp();
3218         if (curBoundByNonBgRestrictedApp != state.isSetBoundByNonBgRestrictedApp()) {
3219             state.setSetBoundByNonBgRestrictedApp(curBoundByNonBgRestrictedApp);
3220             if (!curBoundByNonBgRestrictedApp && state.isBackgroundRestricted()) {
3221                 mService.mHandler.post(() -> {
3222                     synchronized (mService) {
3223                         mService.mServices.stopAllForegroundServicesLocked(
3224                                 app.uid, app.info.packageName);
3225                     }
3226                 });
3227             }
3228         }
3229 
3230         if (changes != 0) {
3231             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3232                     "Changes in " + app + ": " + changes);
3233             ActivityManagerService.ProcessChangeItem item =
3234                     mProcessList.enqueueProcessChangeItemLocked(app.getPid(), app.info.uid);
3235             item.changes |= changes;
3236             item.foregroundActivities = state.hasRepForegroundActivities();
3237             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3238                     "Item " + Integer.toHexString(System.identityHashCode(item))
3239                             + " " + app.toShortString() + ": changes=" + item.changes
3240                             + " foreground=" + item.foregroundActivities
3241                             + " type=" + state.getAdjType() + " source=" + state.getAdjSource()
3242                             + " target=" + state.getAdjTarget());
3243         }
3244 
3245         if (state.isCached() && !state.shouldNotKillOnBgRestrictedAndIdle()) {
3246             // It's eligible to get killed when in UID idle and bg restricted mode,
3247             // check if these states are just flipped.
3248             if (!state.isSetCached() || state.isSetNoKillOnBgRestrictedAndIdle()) {
3249                 // Take the timestamp, we'd hold the killing for the background settle time
3250                 // (for states debouncing to avoid from thrashing).
3251                 state.setLastCanKillOnBgRestrictedAndIdleTime(nowElapsed);
3252                 // Kick off the delayed checkup message if needed.
3253                 if (mService.mDeterministicUidIdle
3254                         || !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) {
3255                     mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
3256                             mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs);
3257                 }
3258             }
3259         }
3260         state.setSetCached(state.isCached());
3261         state.setSetNoKillOnBgRestrictedAndIdle(state.shouldNotKillOnBgRestrictedAndIdle());
3262 
3263         return success;
3264     }
3265 
3266     @GuardedBy({"mService", "mProcLock"})
setAttachingProcessStatesLSP(ProcessRecord app)3267     void setAttachingProcessStatesLSP(ProcessRecord app) {
3268         int initialSchedGroup = SCHED_GROUP_DEFAULT;
3269         int initialProcState = PROCESS_STATE_CACHED_EMPTY;
3270         int initialCapability =  PROCESS_CAPABILITY_NONE;
3271         boolean initialCached = true;
3272         final ProcessStateRecord state = app.mState;
3273         // If the process has been marked as foreground, it is starting as the top app (with
3274         // Zygote#START_AS_TOP_APP_ARG), so boost the thread priority of its default UI thread.
3275         if (state.hasForegroundActivities()) {
3276             try {
3277                 // The priority must be the same as how does {@link #applyOomAdjLSP} set for
3278                 // {@link SCHED_GROUP_TOP_APP}. We don't check render thread because it
3279                 // is not ready when attaching.
3280                 app.getWindowProcessController().onTopProcChanged();
3281                 if (mService.mUseFifoUiScheduling) {
3282                     mService.scheduleAsFifoPriority(app.getPid(), true);
3283                 } else {
3284                     setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
3285                 }
3286                 if (isScreenOnOrAnimatingLocked(state)) {
3287                     initialSchedGroup = SCHED_GROUP_TOP_APP;
3288                     initialProcState = PROCESS_STATE_TOP;
3289                 }
3290                 initialCapability = PROCESS_CAPABILITY_ALL;
3291                 initialCached = false;
3292             } catch (Exception e) {
3293                 Slog.w(TAG, "Failed to pre-set top priority to " + app + " " + e);
3294             }
3295         }
3296 
3297         state.setCurrentSchedulingGroup(initialSchedGroup);
3298         state.setCurProcState(initialProcState);
3299         state.setCurRawProcState(initialProcState);
3300         state.setCurCapability(initialCapability);
3301         state.setCached(initialCached);
3302 
3303         state.setCurAdj(ProcessList.FOREGROUND_APP_ADJ);
3304         state.setCurRawAdj(ProcessList.FOREGROUND_APP_ADJ);
3305         state.setForcingToImportant(null);
3306         state.setHasShownUi(false);
3307     }
3308 
3309     // ONLY used for unit testing in OomAdjusterTests.java
3310     @VisibleForTesting
maybeUpdateUsageStats(ProcessRecord app, long nowElapsed)3311     void maybeUpdateUsageStats(ProcessRecord app, long nowElapsed) {
3312         synchronized (mService) {
3313             synchronized (mProcLock) {
3314                 maybeUpdateUsageStatsLSP(app, nowElapsed);
3315             }
3316         }
3317     }
3318 
3319     @GuardedBy({"mService", "mProcLock"})
maybeUpdateUsageStatsLSP(ProcessRecord app, long nowElapsed)3320     private void maybeUpdateUsageStatsLSP(ProcessRecord app, long nowElapsed) {
3321         final ProcessStateRecord state = app.mState;
3322         if (DEBUG_USAGE_STATS) {
3323             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
3324                     + "] state changes: old = " + state.getSetProcState() + ", new = "
3325                     + state.getCurProcState());
3326         }
3327         if (mService.mUsageStatsService == null) {
3328             return;
3329         }
3330         final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange(
3331                 CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME);
3332         boolean isInteraction;
3333         // To avoid some abuse patterns, we are going to be careful about what we consider
3334         // to be an app interaction.  Being the top activity doesn't count while the display
3335         // is sleeping, nor do short foreground services.
3336         if (ActivityManager.isProcStateConsideredInteraction(state.getCurProcState())) {
3337             isInteraction = true;
3338             state.setFgInteractionTime(0);
3339         } else if (state.getCurProcState() <= PROCESS_STATE_FOREGROUND_SERVICE) {
3340             if (state.getFgInteractionTime() == 0) {
3341                 state.setFgInteractionTime(nowElapsed);
3342                 isInteraction = false;
3343             } else {
3344                 final long interactionTime = fgsInteractionChangeEnabled
3345                         ? mConstants.SERVICE_USAGE_INTERACTION_TIME_POST_S
3346                         : mConstants.SERVICE_USAGE_INTERACTION_TIME_PRE_S;
3347                 isInteraction = nowElapsed > state.getFgInteractionTime() + interactionTime;
3348             }
3349         } else {
3350             isInteraction =
3351                     state.getCurProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND;
3352             state.setFgInteractionTime(0);
3353         }
3354         final long interactionThreshold = fgsInteractionChangeEnabled
3355                 ? mConstants.USAGE_STATS_INTERACTION_INTERVAL_POST_S
3356                 : mConstants.USAGE_STATS_INTERACTION_INTERVAL_PRE_S;
3357         if (isInteraction
3358                 && (!state.hasReportedInteraction()
3359                     || (nowElapsed - state.getInteractionEventTime()) > interactionThreshold)) {
3360             state.setInteractionEventTime(nowElapsed);
3361             String[] packages = app.getPackageList();
3362             if (packages != null) {
3363                 for (int i = 0; i < packages.length; i++) {
3364                     mService.mUsageStatsService.reportEvent(packages[i], app.userId,
3365                             UsageEvents.Event.SYSTEM_INTERACTION);
3366                 }
3367             }
3368         }
3369         state.setReportedInteraction(isInteraction);
3370         if (!isInteraction) {
3371             state.setInteractionEventTime(0);
3372         }
3373     }
3374 
maybeUpdateLastTopTime(ProcessStateRecord state, long nowUptime)3375     private void maybeUpdateLastTopTime(ProcessStateRecord state, long nowUptime) {
3376         if (state.getSetProcState() <= PROCESS_STATE_TOP
3377                 && state.getCurProcState() > PROCESS_STATE_TOP) {
3378             state.setLastTopTime(nowUptime);
3379         }
3380     }
3381 
3382     /**
3383      * Look for recently inactive apps and mark them idle after a grace period. If idled, stop
3384      * any background services and inform listeners.
3385      */
3386     @GuardedBy("mService")
idleUidsLocked()3387     void idleUidsLocked() {
3388         final int N = mActiveUids.size();
3389         mService.mHandler.removeMessages(IDLE_UIDS_MSG);
3390         if (N <= 0) {
3391             return;
3392         }
3393         final long nowElapsed = SystemClock.elapsedRealtime();
3394         final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
3395         long nextTime = 0;
3396         if (mLocalPowerManager != null) {
3397             mLocalPowerManager.startUidChanges();
3398         }
3399         for (int i = N - 1; i >= 0; i--) {
3400             final UidRecord uidRec = mActiveUids.valueAt(i);
3401             final long bgTime = uidRec.getLastBackgroundTime();
3402             if (bgTime > 0 && !uidRec.isIdle()) {
3403                 if (bgTime <= maxBgTime) {
3404                     EventLogTags.writeAmUidIdle(uidRec.getUid());
3405                     synchronized (mProcLock) {
3406                         uidRec.setIdle(true);
3407                         uidRec.setSetIdle(true);
3408                     }
3409                     mService.doStopUidLocked(uidRec.getUid(), uidRec);
3410                 } else {
3411                     if (nextTime == 0 || nextTime > bgTime) {
3412                         nextTime = bgTime;
3413                     }
3414                 }
3415             }
3416         }
3417         if (mLocalPowerManager != null) {
3418             mLocalPowerManager.finishUidChanges();
3419         }
3420         // Also check if there are any apps in cached and background restricted mode,
3421         // if so, kill it if it's been there long enough, or kick off a msg to check
3422         // it later.
3423         if (mService.mConstants.mKillBgRestrictedAndCachedIdle) {
3424             final ArraySet<ProcessRecord> apps = mProcessList.mAppsInBackgroundRestricted;
3425             for (int i = 0, size = apps.size(); i < size; i++) {
3426                 // Check to see if needs to be killed.
3427                 final long bgTime = mProcessList.killAppIfBgRestrictedAndCachedIdleLocked(
3428                         apps.valueAt(i), nowElapsed) - mConstants.BACKGROUND_SETTLE_TIME;
3429                 if (bgTime > 0 && (nextTime == 0 || nextTime > bgTime)) {
3430                     nextTime = bgTime;
3431                 }
3432             }
3433         }
3434         if (nextTime > 0) {
3435             mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
3436                     nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
3437         }
3438     }
3439 
3440     @GuardedBy({"mService", "mProcLock"})
setAppIdTempAllowlistStateLSP(int uid, boolean onAllowlist)3441     void setAppIdTempAllowlistStateLSP(int uid, boolean onAllowlist) {
3442         boolean changed = false;
3443         for (int i = mActiveUids.size() - 1; i >= 0; i--) {
3444             final UidRecord uidRec = mActiveUids.valueAt(i);
3445             if (uidRec.getUid() == uid && uidRec.isCurAllowListed() != onAllowlist) {
3446                 uidRec.setCurAllowListed(onAllowlist);
3447                 changed = true;
3448             }
3449         }
3450         if (changed) {
3451             updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
3452         }
3453     }
3454 
3455     @GuardedBy({"mService", "mProcLock"})
setUidTempAllowlistStateLSP(int uid, boolean onAllowlist)3456     void setUidTempAllowlistStateLSP(int uid, boolean onAllowlist) {
3457         boolean changed = false;
3458         final UidRecord uidRec = mActiveUids.get(uid);
3459         if (uidRec != null && uidRec.isCurAllowListed() != onAllowlist) {
3460             uidRec.setCurAllowListed(onAllowlist);
3461             updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
3462         }
3463     }
3464 
3465     @GuardedBy("mService")
dumpProcessListVariablesLocked(ProtoOutputStream proto)3466     void dumpProcessListVariablesLocked(ProtoOutputStream proto) {
3467         proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
3468         proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mProcessList.getLruSeqLOSP());
3469         proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS,
3470                 mNumNonCachedProcs);
3471         proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
3472         proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS,
3473                 mNewNumServiceProcs);
3474 
3475     }
3476 
3477     @GuardedBy("mService")
dumpSequenceNumbersLocked(PrintWriter pw)3478     void dumpSequenceNumbersLocked(PrintWriter pw) {
3479         pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mProcessList.getLruSeqLOSP());
3480     }
3481 
3482     @GuardedBy("mService")
dumpProcCountsLocked(PrintWriter pw)3483     void dumpProcCountsLocked(PrintWriter pw) {
3484         pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
3485                 + " (" + mProcessList.getLruSizeLOSP() + " total)"
3486                 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
3487                 + " mNumServiceProcs=" + mNumServiceProcs
3488                 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
3489     }
3490 
3491     @GuardedBy("mProcLock")
dumpCachedAppOptimizerSettings(PrintWriter pw)3492     void dumpCachedAppOptimizerSettings(PrintWriter pw) {
3493         mCachedAppOptimizer.dump(pw);
3494     }
3495 
3496     @GuardedBy("mService")
dumpCacheOomRankerSettings(PrintWriter pw)3497     void dumpCacheOomRankerSettings(PrintWriter pw) {
3498         mCacheOomRanker.dump(pw);
3499     }
3500 
3501     @GuardedBy({"mService", "mProcLock"})
updateAppFreezeStateLSP(ProcessRecord app, @OomAdjReason int oomAdjReason)3502     private void updateAppFreezeStateLSP(ProcessRecord app, @OomAdjReason int oomAdjReason) {
3503         if (!mCachedAppOptimizer.useFreezer()) {
3504             return;
3505         }
3506 
3507         if (app.mOptRecord.isFreezeExempt()) {
3508             return;
3509         }
3510 
3511         final ProcessCachedOptimizerRecord opt = app.mOptRecord;
3512         // if an app is already frozen and shouldNotFreeze becomes true, immediately unfreeze
3513         if (opt.isFrozen() && opt.shouldNotFreeze()) {
3514             mCachedAppOptimizer.unfreezeAppLSP(app,
3515                     CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason));
3516             return;
3517         }
3518 
3519         final ProcessStateRecord state = app.mState;
3520         // Use current adjustment when freezing, set adjustment when unfreezing.
3521         if (state.getCurAdj() >= CACHED_APP_MIN_ADJ && !opt.isFrozen()
3522                 && !opt.shouldNotFreeze()) {
3523             mCachedAppOptimizer.freezeAppAsyncLSP(app);
3524         } else if (state.getSetAdj() < CACHED_APP_MIN_ADJ) {
3525             mCachedAppOptimizer.unfreezeAppLSP(app,
3526                     CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason));
3527         }
3528     }
3529 
3530     @GuardedBy("mService")
unfreezeTemporarily(ProcessRecord app, @OomAdjReason int reason)3531     void unfreezeTemporarily(ProcessRecord app, @OomAdjReason int reason) {
3532         if (!mCachedAppOptimizer.useFreezer()) {
3533             return;
3534         }
3535 
3536         final ProcessCachedOptimizerRecord opt = app.mOptRecord;
3537         if (!opt.isFrozen() && !opt.isPendingFreeze()) {
3538             return;
3539         }
3540 
3541         final ArrayList<ProcessRecord> processes = mTmpProcessList;
3542         final ActiveUids uids = mTmpUidRecords;
3543         mTmpProcessSet.add(app);
3544         collectReachableProcessesLocked(mTmpProcessSet, processes, uids);
3545         mTmpProcessSet.clear();
3546         // Now processes contains app's downstream and app
3547         final int size = processes.size();
3548         for (int i = 0; i < size; i++) {
3549             ProcessRecord proc = processes.get(i);
3550             mCachedAppOptimizer.unfreezeTemporarily(proc, reason);
3551         }
3552         processes.clear();
3553     }
3554 }
3555