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