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