1 /*
2  * Copyright (C) 2011 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_NONE;
20 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
22 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_END;
23 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_RESTRICTION_CHANGE;
24 import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
25 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
26 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
27 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
28 import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
29 import static android.os.Process.SYSTEM_UID;
30 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
31 import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
32 import static android.os.Process.getAdvertisedMem;
33 import static android.os.Process.getFreeMemory;
34 import static android.os.Process.getTotalMemory;
35 import static android.os.Process.killProcessQuiet;
36 import static android.os.Process.startWebView;
37 import static android.system.OsConstants.EAGAIN;
38 
39 import static com.android.sdksandbox.flags.Flags.selinuxInputSelector;
40 import static com.android.sdksandbox.flags.Flags.selinuxSdkSandboxAudit;
41 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
42 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
43 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
44 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
45 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
46 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
47 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
48 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
49 import static com.android.server.am.ActivityManagerService.DISPATCH_PROCESSES_CHANGED_UI_MSG;
50 import static com.android.server.am.ActivityManagerService.DISPATCH_PROCESS_DIED_UI_MSG;
51 import static com.android.server.am.ActivityManagerService.IDLE_UIDS_MSG;
52 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS;
53 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG;
54 import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK;
55 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT;
56 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG;
57 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER;
58 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
59 import static com.android.server.am.ActivityManagerService.TAG_LRU;
60 import static com.android.server.am.ActivityManagerService.TAG_NETWORK;
61 import static com.android.server.am.ActivityManagerService.TAG_PROCESSES;
62 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
63 import static com.android.server.wm.WindowProcessController.STOPPED_STATE_FIRST_LAUNCH;
64 import static com.android.server.wm.WindowProcessController.STOPPED_STATE_FORCE_STOPPED;
65 
66 import android.Manifest;
67 import android.annotation.NonNull;
68 import android.annotation.Nullable;
69 import android.app.ActivityManager;
70 import android.app.ActivityManager.ProcessCapability;
71 import android.app.ActivityThread;
72 import android.app.AppGlobals;
73 import android.app.AppProtoEnums;
74 import android.app.ApplicationExitInfo;
75 import android.app.ApplicationExitInfo.Reason;
76 import android.app.ApplicationExitInfo.SubReason;
77 import android.app.ApplicationStartInfo;
78 import android.app.IApplicationThread;
79 import android.app.IProcessObserver;
80 import android.app.UidObserver;
81 import android.compat.annotation.ChangeId;
82 import android.compat.annotation.EnabledAfter;
83 import android.content.BroadcastReceiver;
84 import android.content.ComponentName;
85 import android.content.Context;
86 import android.content.Intent;
87 import android.content.IntentFilter;
88 import android.content.pm.ApplicationInfo;
89 import android.content.pm.IPackageManager;
90 import android.content.pm.PackageManager;
91 import android.content.pm.PackageManagerInternal;
92 import android.content.res.Resources;
93 import android.graphics.Point;
94 import android.net.LocalSocket;
95 import android.net.LocalSocketAddress;
96 import android.os.AppZygote;
97 import android.os.Binder;
98 import android.os.Build;
99 import android.os.Bundle;
100 import android.os.DropBoxManager;
101 import android.os.Handler;
102 import android.os.IBinder;
103 import android.os.Looper;
104 import android.os.Message;
105 import android.os.OomKillRecord;
106 import android.os.PowerManager;
107 import android.os.Process;
108 import android.os.RemoteCallbackList;
109 import android.os.RemoteException;
110 import android.os.StrictMode;
111 import android.os.SystemClock;
112 import android.os.SystemProperties;
113 import android.os.Trace;
114 import android.os.UserHandle;
115 import android.os.storage.StorageManagerInternal;
116 import android.provider.DeviceConfig;
117 import android.system.Os;
118 import android.system.OsConstants;
119 import android.text.TextUtils;
120 import android.util.ArrayMap;
121 import android.util.ArraySet;
122 import android.util.DebugUtils;
123 import android.util.EventLog;
124 import android.util.LongSparseArray;
125 import android.util.Pair;
126 import android.util.Slog;
127 import android.util.SparseArray;
128 import android.util.SparseBooleanArray;
129 import android.util.TimeUtils;
130 import android.util.proto.ProtoOutputStream;
131 import android.view.Display;
132 
133 import com.android.internal.annotations.CompositeRWLock;
134 import com.android.internal.annotations.GuardedBy;
135 import com.android.internal.annotations.VisibleForTesting;
136 import com.android.internal.app.ProcessMap;
137 import com.android.internal.os.Zygote;
138 import com.android.internal.util.ArrayUtils;
139 import com.android.internal.util.MemInfoReader;
140 import com.android.server.AppStateTracker;
141 import com.android.server.LocalServices;
142 import com.android.server.ServiceThread;
143 import com.android.server.SystemConfig;
144 import com.android.server.Watchdog;
145 import com.android.server.am.ActivityManagerService.ProcessChangeItem;
146 import com.android.server.compat.PlatformCompat;
147 import com.android.server.pm.pkg.AndroidPackage;
148 import com.android.server.pm.pkg.PackageStateInternal;
149 import com.android.server.wm.ActivityServiceConnectionsHolder;
150 import com.android.server.wm.WindowManagerService;
151 import com.android.server.wm.WindowProcessController;
152 
153 import dalvik.system.VMRuntime;
154 
155 import java.io.DataInputStream;
156 import java.io.File;
157 import java.io.FileDescriptor;
158 import java.io.IOException;
159 import java.io.OutputStream;
160 import java.io.PrintWriter;
161 import java.nio.ByteBuffer;
162 import java.util.ArrayList;
163 import java.util.Arrays;
164 import java.util.BitSet;
165 import java.util.Collections;
166 import java.util.Comparator;
167 import java.util.HashMap;
168 import java.util.List;
169 import java.util.Map;
170 import java.util.Set;
171 import java.util.function.Consumer;
172 import java.util.function.Function;
173 
174 /**
175  * Activity manager code dealing with processes.
176  */
177 public final class ProcessList {
178     static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
179 
180     static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
181 
182     // A system property to control if app data isolation is enabled.
183     static final String ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY =
184             "persist.zygote.app_data_isolation";
185 
186     // A system property to control if obb app data isolation is enabled in vold.
187     static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
188             "persist.sys.vold_app_data_isolation_enabled";
189 
190     private static final String APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS = ":isSdkSandboxAudit";
191     private static final String APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = ":isSdkSandboxNext";
192 
193     // OOM adjustments for processes in various states:
194 
195     // Uninitialized value for any major or minor adj fields
196     public static final int INVALID_ADJ = -10000;
197 
198     // Adjustment used in certain places where we don't know it yet.
199     // (Generally this is something that is going to be cached, but we
200     // don't know the exact value in the cached range to assign yet.)
201     public static final int UNKNOWN_ADJ = 1001;
202 
203     // This is a process only hosting activities that are not visible,
204     // so it can be killed without any disruption.
205     public static final int CACHED_APP_MAX_ADJ = 999;
206     public static final int CACHED_APP_MIN_ADJ = 900;
207 
208     // This is the oom_adj level that we allow to die first. This cannot be equal to
209     // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
210     // CACHED_APP_MAX_ADJ.
211     public static final int CACHED_APP_LMK_FIRST_ADJ = 950;
212 
213     // Number of levels we have available for different service connection group importance
214     // levels.
215     public static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
216 
217     // The B list of SERVICE_ADJ -- these are the old and decrepit
218     // services that aren't as shiny and interesting as the ones in the A list.
219     public static final int SERVICE_B_ADJ = 800;
220 
221     // This is the process of the previous application that the user was in.
222     // This process is kept above other things, because it is very common to
223     // switch back to the previous app.  This is important both for recent
224     // task switch (toggling between the two top recent apps) as well as normal
225     // UI flow such as clicking on a URI in the e-mail app to view in the browser,
226     // and then pressing back to return to e-mail.
227     public static final int PREVIOUS_APP_ADJ = 700;
228 
229     // This is a process holding the home application -- we want to try
230     // avoiding killing it, even if it would normally be in the background,
231     // because the user interacts with it so much.
232     public static final int HOME_APP_ADJ = 600;
233 
234     // This is a process holding an application service -- killing it will not
235     // have much of an impact as far as the user is concerned.
236     public static final int SERVICE_ADJ = 500;
237 
238     // This is a process with a heavy-weight application.  It is in the
239     // background, but we want to try to avoid killing it.  Value set in
240     // system/rootdir/init.rc on startup.
241     public static final int HEAVY_WEIGHT_APP_ADJ = 400;
242 
243     // This is a process currently hosting a backup operation.  Killing it
244     // is not entirely fatal but is generally a bad idea.
245     public static final int BACKUP_APP_ADJ = 300;
246 
247     // This is a process bound by the system (or other app) that's more important than services but
248     // not so perceptible that it affects the user immediately if killed.
249     public static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
250 
251     // This is a process hosting services that are not perceptible to the user but the
252     // client (system) binding to it requested to treat it as if it is perceptible and avoid killing
253     // it if possible.
254     public static final int PERCEPTIBLE_MEDIUM_APP_ADJ = 225;
255 
256     // This is a process only hosting components that are perceptible to the
257     // user, and we really want to avoid killing them, but they are not
258     // immediately visible. An example is background music playback.
259     public static final int PERCEPTIBLE_APP_ADJ = 200;
260 
261     // This is a process only hosting activities that are visible to the
262     // user, so we'd prefer they don't disappear.
263     public static final int VISIBLE_APP_ADJ = 100;
264     static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
265 
266     // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
267     // like a foreground app for a while.
268     // @see TOP_TO_FGS_GRACE_PERIOD
269     public static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
270 
271     // This is the process running the current foreground app.  We'd really
272     // rather not kill it!
273     public static final int FOREGROUND_APP_ADJ = 0;
274 
275     // This is a process that the system or a persistent process has bound to,
276     // and indicated it is important.
277     public static final int PERSISTENT_SERVICE_ADJ = -700;
278 
279     // This is a system persistent process, such as telephony.  Definitely
280     // don't want to kill it, but doing so is not completely fatal.
281     public static final int PERSISTENT_PROC_ADJ = -800;
282 
283     // The system process runs at the default adjustment.
284     public static final int SYSTEM_ADJ = -900;
285 
286     // Special code for native processes that are not being managed by the system (so
287     // don't have an oom adj assigned by the system).
288     public static final int NATIVE_ADJ = -1000;
289 
290     // Memory page size.
291     static final int PAGE_SIZE = (int) Os.sysconf(OsConstants._SC_PAGESIZE);
292 
293     // Activity manager's version of an undefined schedule group
294     static final int SCHED_GROUP_UNDEFINED = Integer.MIN_VALUE;
295     // Activity manager's version of Process.THREAD_GROUP_BACKGROUND
296     static final int SCHED_GROUP_BACKGROUND = 0;
297       // Activity manager's version of Process.THREAD_GROUP_RESTRICTED
298     static final int SCHED_GROUP_RESTRICTED = 1;
299     // Activity manager's version of Process.THREAD_GROUP_DEFAULT
300     static final int SCHED_GROUP_DEFAULT = 2;
301     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
302     public static final int SCHED_GROUP_TOP_APP = 3;
303     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
304     // Disambiguate between actual top app and processes bound to the top app
305     static final int SCHED_GROUP_TOP_APP_BOUND = 4;
306 
307     // The minimum number of cached apps we want to be able to keep around,
308     // without empty apps being able to push them out of memory.
309     static final int MIN_CACHED_APPS = 2;
310 
311     // Threshold of number of cached+empty where we consider memory critical.
312     static final int TRIM_CRITICAL_THRESHOLD = 3;
313 
314     // Threshold of number of cached+empty where we consider memory critical.
315     static final int TRIM_LOW_THRESHOLD = 5;
316 
317     /**
318      * State indicating that there is no need for any blocking for network.
319      */
320     @VisibleForTesting
321     static final int NETWORK_STATE_NO_CHANGE = 0;
322 
323     /**
324      * State indicating that the main thread needs to be informed about the network wait.
325      */
326     @VisibleForTesting
327     static final int NETWORK_STATE_BLOCK = 1;
328 
329     /**
330      * State indicating that any threads waiting for network state to get updated can be unblocked.
331      */
332     @VisibleForTesting
333     static final int NETWORK_STATE_UNBLOCK = 2;
334 
335     // If true, then we pass the flag to ART to load the app image startup cache.
336     private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
337             "persist.device_config.runtime_native.use_app_image_startup_cache";
338 
339     // The socket path for zygote to send unsolicited msg.
340     // Must keep sync with com_android_internal_os_Zygote.cpp.
341     private static final String UNSOL_ZYGOTE_MSG_SOCKET_PATH = "/data/system/unsolzygotesocket";
342 
343     // Low Memory Killer Daemon command codes.
344     // These must be kept in sync with lmk_cmd definitions in lmkd.h
345     //
346     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
347     // LMK_PROCPRIO <pid> <uid> <prio>
348     // LMK_PROCREMOVE <pid>
349     // LMK_PROCPURGE
350     // LMK_GETKILLCNT
351     // LMK_SUBSCRIBE
352     // LMK_PROCKILL
353     // LMK_UPDATE_PROPS
354     // LMK_KILL_OCCURRED
355     // LMK_START_MONITORING
356     // LMK_BOOT_COMPLETED
357     // LMK_PROCS_PRIO
358     static final byte LMK_TARGET = 0;
359     static final byte LMK_PROCPRIO = 1;
360     static final byte LMK_PROCREMOVE = 2;
361     static final byte LMK_PROCPURGE = 3;
362     static final byte LMK_GETKILLCNT = 4;
363     static final byte LMK_SUBSCRIBE = 5;
364     static final byte LMK_PROCKILL = 6; // Note: this is an unsolicited command
365     static final byte LMK_UPDATE_PROPS = 7;
366     static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event
367     static final byte LMK_START_MONITORING = 9; // Start monitoring if delayed earlier
368     static final byte LMK_BOOT_COMPLETED = 10;
369     static final byte LMK_PROCS_PRIO = 11;  // Batch option for LMK_PROCPRIO
370 
371     // Low Memory Killer Daemon command codes.
372     // These must be kept in sync with async_event_type definitions in lmkd.h
373     //
374     static final int LMK_ASYNC_EVENT_KILL = 0;
375     static final int LMK_ASYNC_EVENT_STAT = 1;
376 
377     // lmkd reconnect delay in msecs
378     private static final long LMKD_RECONNECT_DELAY_MS = 1000;
379 
380     /**
381      * The cuttoff adj for the freezer, app processes with adj greater than this value will be
382      * eligible for the freezer.
383      */
384     static final int FREEZER_CUTOFF_ADJ = CACHED_APP_MIN_ADJ;
385 
386     /**
387      * Apps have no access to the private data directories of any other app, even if the other
388      * app has made them world-readable.
389      */
390     @ChangeId
391     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
392     private static final long APP_DATA_DIRECTORY_ISOLATION = 143937733; // See b/143937733
393 
394     ActivityManagerService mService = null;
395 
396     // To kill process groups asynchronously
397     static KillHandler sKillHandler = null;
398     static ServiceThread sKillThread = null;
399 
400     // These are the various interesting memory levels that we will give to
401     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
402     // can't give it a different value for every possible kind of process.
403     private final int[] mOomAdj = new int[] {
404             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
405             PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
406     };
407     // These are the low-end OOM level limits.  This is appropriate for an
408     // HVGA or smaller phone with less than 512MB.  Values are in KB.
409     private final int[] mOomMinFreeLow = new int[] {
410             12288, 18432, 24576,
411             36864, 43008, 49152
412     };
413     // These are the high-end OOM level limits.  This is appropriate for a
414     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
415     private final int[] mOomMinFreeHigh = new int[] {
416             73728, 92160, 110592,
417             129024, 147456, 184320
418     };
419     // The actual OOM killer memory levels we are using.
420     private final int[] mOomMinFree = new int[mOomAdj.length];
421 
422     private final long mTotalMemMb;
423 
424     private long mCachedRestoreLevel;
425 
426     private boolean mHaveDisplaySize;
427 
428     private static LmkdConnection sLmkdConnection = null;
429 
430     private static OomConnection sOomConnection = null;
431 
432     private boolean mOomLevelsSet = false;
433 
434     private boolean mAppDataIsolationEnabled = false;
435 
436     private boolean mVoldAppDataIsolationEnabled = false;
437 
438     private ArrayList<String> mAppDataIsolationAllowlistedApps;
439 
440     /**
441      * Temporary to avoid allocations.  Protected by main lock.
442      */
443     @GuardedBy("mService")
444     final StringBuilder mStringBuilder = new StringBuilder(256);
445 
446     /**
447      * A global counter for generating sequence numbers.
448      * This value will be used when incrementing sequence numbers in individual uidRecords.
449      *
450      * Having a global counter ensures that seq numbers are monotonically increasing for a
451      * particular uid even when the uidRecord is re-created.
452      */
453     @VisibleForTesting
454     volatile long mProcStateSeqCounter = 0;
455 
456     /**
457      * A global counter for generating sequence numbers to uniquely identify pending process starts.
458      */
459     @GuardedBy("mService")
460     private long mProcStartSeqCounter = 0;
461 
462     /**
463      * Contains {@link ProcessRecord} objects for pending process starts.
464      *
465      * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
466      */
467     @GuardedBy("mService")
468     final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
469 
470     /**
471      * List of running applications, sorted by recent usage.
472      * The first entry in the list is the least recently used.
473      */
474     @CompositeRWLock({"mService", "mProcLock"})
475     private final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
476 
477     /**
478      * Where in mLruProcesses that the processes hosting activities start.
479      */
480     @CompositeRWLock({"mService", "mProcLock"})
481     private int mLruProcessActivityStart = 0;
482 
483     /**
484      * Where in mLruProcesses that the processes hosting services start.
485      * This is after (lower index) than mLruProcessesActivityStart.
486      */
487     @CompositeRWLock({"mService", "mProcLock"})
488     private int mLruProcessServiceStart = 0;
489 
490     /**
491      * Current sequence id for process LRU updating.
492      */
493     @CompositeRWLock({"mService", "mProcLock"})
494     private int mLruSeq = 0;
495 
496     @CompositeRWLock({"mService", "mProcLock"})
497     ActiveUids mActiveUids;
498 
499     /**
500      * The currently running isolated processes.
501      */
502     @GuardedBy("mService")
503     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
504 
505     /**
506      * The currently running application zygotes.
507      */
508     @GuardedBy("mService")
509     final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
510 
511     /** Manages the {@link android.app.ApplicationStartInfo} records. */
512     @GuardedBy("mAppStartInfoTracker")
513     private final AppStartInfoTracker mAppStartInfoTracker = new AppStartInfoTracker();
514 
515     /**
516      * The currently running SDK sandbox processes for a uid.
517      */
518     @GuardedBy("mService")
519     final SparseArray<ArrayList<ProcessRecord>> mSdkSandboxes = new SparseArray<>();
520 
521     /**
522      * Managees the {@link android.app.ApplicationExitInfo} records.
523      */
524     @GuardedBy("mAppExitInfoTracker")
525     final AppExitInfoTracker mAppExitInfoTracker = new AppExitInfoTracker();
526 
527     /**
528      * The processes that are forked off an application zygote.
529      */
530     @GuardedBy("mService")
531     final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses =
532             new ArrayMap<AppZygote, ArrayList<ProcessRecord>>();
533 
534     /**
535      * The list of apps in background restricted mode.
536      */
537     @GuardedBy("mService")
538     final ArraySet<ProcessRecord> mAppsInBackgroundRestricted = new ArraySet<>();
539 
540     private PlatformCompat mPlatformCompat = null;
541 
542     /**
543      * The server socket in system_server, zygote will connect to it
544      * in order to send unsolicited messages to system_server.
545      */
546     private LocalSocket mSystemServerSocketForZygote;
547 
548     /**
549      * Maximum number of bytes that an incoming unsolicited zygote message could be.
550      * To be updated if new message type needs to be supported.
551      */
552     private static final int MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE = 16;
553 
554     /**
555      * The buffer to be used to receive the incoming unsolicited zygote message.
556      */
557     private final byte[] mZygoteUnsolicitedMessage = new byte[MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE];
558 
559     /**
560      * The buffer to be used to receive the SIGCHLD data, it includes pid/uid/status.
561      */
562     private final int[] mZygoteSigChldMessage = new int[3];
563 
564     ActivityManagerGlobalLock mProcLock;
565 
566     private static final String PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS =
567             "apply_sdk_sandbox_audit_restrictions";
568     private static final boolean DEFAULT_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS = false;
569 
570     private static final String PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS =
571             "apply_sdk_sandbox_next_restrictions";
572     private static final boolean DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = false;
573 
574     @GuardedBy("mService")
575     private ProcessListSettingsListener mProcessListSettingsListener;
576 
577     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
getProcessListSettingsListener()578     ProcessListSettingsListener getProcessListSettingsListener() {
579         synchronized (mService) {
580             if (mProcessListSettingsListener == null) {
581                 mProcessListSettingsListener = new ProcessListSettingsListener(mService.mContext);
582                 mProcessListSettingsListener.registerObserver();
583             }
584             return mProcessListSettingsListener;
585         }
586     }
587 
588     static class ProcessListSettingsListener implements DeviceConfig.OnPropertiesChangedListener {
589 
590         private final Context mContext;
591         private final Object mLock = new Object();
592 
593         @GuardedBy("mLock")
594         private boolean mSdkSandboxApplyRestrictionsAudit =
595                 DeviceConfig.getBoolean(
596                 DeviceConfig.NAMESPACE_ADSERVICES,
597                 PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS,
598                 DEFAULT_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS);
599 
600         @GuardedBy("mLock")
601         private boolean mSdkSandboxApplyRestrictionsNext =
602                 DeviceConfig.getBoolean(
603                 DeviceConfig.NAMESPACE_ADSERVICES,
604                 PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS,
605                 DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
606 
ProcessListSettingsListener(Context context)607         ProcessListSettingsListener(Context context) {
608             mContext = context;
609         }
610 
registerObserver()611         private void registerObserver() {
612             DeviceConfig.addOnPropertiesChangedListener(
613                     DeviceConfig.NAMESPACE_ADSERVICES, mContext.getMainExecutor(), this);
614         }
615 
616         @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
unregisterObserver()617         void unregisterObserver() {
618             DeviceConfig.removeOnPropertiesChangedListener(this);
619         }
620 
applySdkSandboxRestrictionsAudit()621         boolean applySdkSandboxRestrictionsAudit() {
622             synchronized (mLock) {
623                 return mSdkSandboxApplyRestrictionsAudit;
624             }
625         }
626 
applySdkSandboxRestrictionsNext()627         boolean applySdkSandboxRestrictionsNext() {
628             synchronized (mLock) {
629                 return mSdkSandboxApplyRestrictionsNext;
630             }
631         }
632 
633         @Override
onPropertiesChanged(@onNull DeviceConfig.Properties properties)634         public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
635             synchronized (mLock) {
636                 for (String name : properties.getKeyset()) {
637                     if (name == null) {
638                         continue;
639                     }
640 
641                     switch (name) {
642                         case PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS:
643                             mSdkSandboxApplyRestrictionsAudit =
644                                 properties.getBoolean(
645                                     PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS,
646                                     DEFAULT_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS);
647                             break;
648                         case PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS:
649                             mSdkSandboxApplyRestrictionsNext =
650                                 properties.getBoolean(
651                                     PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS,
652                                     DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
653                             break;
654                         default:
655                     }
656                 }
657             }
658         }
659     }
660 
661     final class IsolatedUidRange {
662         @VisibleForTesting
663         public final int mFirstUid;
664         @VisibleForTesting
665         public final int mLastUid;
666 
667         @GuardedBy("ProcessList.this.mService")
668         private final SparseBooleanArray mUidUsed = new SparseBooleanArray();
669 
670         @GuardedBy("ProcessList.this.mService")
671         private int mNextUid;
672 
IsolatedUidRange(int firstUid, int lastUid)673         IsolatedUidRange(int firstUid, int lastUid) {
674             mFirstUid = firstUid;
675             mLastUid = lastUid;
676             mNextUid = firstUid;
677         }
678 
679         @GuardedBy("ProcessList.this.mService")
allocateIsolatedUidLocked(int userId)680         int allocateIsolatedUidLocked(int userId) {
681             int uid;
682             int stepsLeft = (mLastUid - mFirstUid + 1);
683             for (int i = 0; i < stepsLeft; ++i) {
684                 if (mNextUid < mFirstUid || mNextUid > mLastUid) {
685                     mNextUid = mFirstUid;
686                 }
687                 uid = UserHandle.getUid(userId, mNextUid);
688                 mNextUid++;
689                 if (!mUidUsed.get(uid, false)) {
690                     mUidUsed.put(uid, true);
691                     return uid;
692                 }
693             }
694             return -1;
695         }
696 
697         @GuardedBy("ProcessList.this.mService")
freeIsolatedUidLocked(int uid)698         void freeIsolatedUidLocked(int uid) {
699             mUidUsed.delete(uid);
700         }
701     };
702 
703     /**
704      * A class that allocates ranges of isolated UIDs per application, and keeps track of them.
705      */
706     final class IsolatedUidRangeAllocator {
707         private final int mFirstUid;
708         private final int mNumUidRanges;
709         private final int mNumUidsPerRange;
710         /**
711          * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange)
712          * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that.
713          */
714         @GuardedBy("ProcessList.this.mService")
715         private final BitSet mAvailableUidRanges;
716         @GuardedBy("ProcessList.this.mService")
717         private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>();
718 
IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange)719         IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) {
720             mFirstUid = firstUid;
721             mNumUidsPerRange = numUidsPerRange;
722             mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange;
723             mAvailableUidRanges = new BitSet(mNumUidRanges);
724             // Mark all as available
725             mAvailableUidRanges.set(0, mNumUidRanges);
726         }
727 
728         @GuardedBy("ProcessList.this.mService")
getIsolatedUidRangeLocked(String processName, int uid)729         IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) {
730             return mAppRanges.get(processName, uid);
731         }
732 
733         @GuardedBy("ProcessList.this.mService")
getOrCreateIsolatedUidRangeLocked(String processName, int uid)734         IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) {
735             IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid);
736             if (range == null) {
737                 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
738                 if (uidRangeIndex < 0) {
739                     // No free range
740                     return null;
741                 }
742                 mAvailableUidRanges.clear(uidRangeIndex);
743                 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
744                 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
745                 mAppRanges.put(processName, uid, range);
746             }
747             return range;
748         }
749 
750         @GuardedBy("ProcessList.this.mService")
freeUidRangeLocked(ApplicationInfo info)751         void freeUidRangeLocked(ApplicationInfo info) {
752             // Find the UID range
753             IsolatedUidRange range = mAppRanges.get(info.processName, info.uid);
754             if (range != null) {
755                 // Map back to starting uid
756                 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange;
757                 // Mark it as available in the underlying bitset
758                 mAvailableUidRanges.set(uidRangeIndex);
759                 // And the map
760                 mAppRanges.remove(info.processName, info.uid);
761             }
762         }
763     }
764 
765     /**
766      * The available isolated UIDs for processes that are not spawned from an application zygote.
767      */
768     @VisibleForTesting
769     @GuardedBy("mService")
770     IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID,
771             Process.LAST_ISOLATED_UID);
772 
773     /**
774      * An allocator for isolated UID ranges for apps that use an application zygote.
775      */
776     @VisibleForTesting
777     @GuardedBy("mService")
778     IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator =
779             new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
780                     Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE);
781 
782     /**
783      * Processes that are being forcibly torn down.
784      */
785     @GuardedBy("mService")
786     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
787 
788     /**
789      * Processes that are killed by us and being waiting for the death notification.
790      */
791     @GuardedBy("mService")
792     final ProcessMap<ProcessRecord> mDyingProcesses = new ProcessMap<>();
793 
794     // Self locked with the inner lock within the RemoteCallbackList
795     private final RemoteCallbackList<IProcessObserver> mProcessObservers =
796             new RemoteCallbackList<>();
797 
798     // No lock is needed as it's accessed from single thread only
799     private ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
800 
801     @GuardedBy("mProcessChangeLock")
802     private final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
803 
804     @GuardedBy("mProcessChangeLock")
805     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
806 
807     /**
808      * A dedicated lock for dispatching the process changes as it occurs frequently
809      */
810     private final Object mProcessChangeLock = new Object();
811 
812     /**
813      * All of the applications we currently have running organized by name.
814      * The keys are strings of the application package name (as
815      * returned by the package manager), and the keys are ApplicationRecord
816      * objects.
817      */
818     @CompositeRWLock({"mService", "mProcLock"})
819     private final MyProcessMap mProcessNames = new MyProcessMap();
820 
821     final class MyProcessMap extends ProcessMap<ProcessRecord> {
822         @Override
put(String name, int uid, ProcessRecord value)823         public ProcessRecord put(String name, int uid, ProcessRecord value) {
824             final ProcessRecord r = super.put(name, uid, value);
825             mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());
826             return r;
827         }
828 
829         @Override
remove(String name, int uid)830         public ProcessRecord remove(String name, int uid) {
831             final ProcessRecord r = super.remove(name, uid);
832             mService.mAtmInternal.onProcessRemoved(name, uid);
833             return r;
834         }
835     }
836 
837     final class KillHandler extends Handler {
838         static final int KILL_PROCESS_GROUP_MSG = 4000;
839         static final int LMKD_RECONNECT_MSG = 4001;
840 
KillHandler(Looper looper)841         public KillHandler(Looper looper) {
842             super(looper, null, true);
843         }
844 
845         @Override
handleMessage(Message msg)846         public void handleMessage(Message msg) {
847             switch (msg.what) {
848                 case KILL_PROCESS_GROUP_MSG:
849                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
850                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
851                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
852                     break;
853                 case LMKD_RECONNECT_MSG:
854                     if (!sLmkdConnection.connect()) {
855                         Slog.i(TAG, "Failed to connect to lmkd, retry after " +
856                                 LMKD_RECONNECT_DELAY_MS + " ms");
857                         // retry after LMKD_RECONNECT_DELAY_MS
858                         sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
859                                 KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
860                     }
861                     break;
862                 default:
863                     super.handleMessage(msg);
864             }
865         }
866     }
867 
868     /**
869      * A runner to handle the imperceptible killings.
870      */
871     ImperceptibleKillRunner mImperceptibleKillRunner;
872 
873     ////////////////////  END FIELDS  ////////////////////
874 
ProcessList()875     ProcessList() {
876         MemInfoReader minfo = new MemInfoReader();
877         minfo.readMemInfo();
878         mTotalMemMb = minfo.getTotalSize()/(1024*1024);
879         updateOomLevels(0, 0, false);
880     }
881 
init(ActivityManagerService service, ActiveUids activeUids, PlatformCompat platformCompat)882     void init(ActivityManagerService service, ActiveUids activeUids,
883             PlatformCompat platformCompat) {
884         mService = service;
885         mActiveUids = activeUids;
886         mPlatformCompat = platformCompat;
887         mProcLock = service.mProcLock;
888         // Get this after boot, and won't be changed until it's rebooted, as we don't
889         // want some apps enabled while some apps disabled
890         mAppDataIsolationEnabled =
891                 SystemProperties.getBoolean(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true);
892         mVoldAppDataIsolationEnabled = SystemProperties.getBoolean(
893                 ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false);
894         mAppDataIsolationAllowlistedApps = new ArrayList<>(
895                 SystemConfig.getInstance().getAppDataIsolationWhitelistedApps());
896 
897         if (sKillHandler == null) {
898             sKillThread = new ServiceThread(TAG + ":kill",
899                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
900             sKillThread.start();
901             sKillHandler = new KillHandler(sKillThread.getLooper());
902             sOomConnection = new OomConnection(new OomConnection.OomConnectionListener() {
903                 @Override
904                 public void handleOomEvent(OomKillRecord[] oomKills) {
905                     for (OomKillRecord oomKill: oomKills) {
906                         synchronized (mProcLock) {
907                             noteAppKill(
908                                 oomKill.getPid(),
909                                 oomKill.getUid(),
910                                 ApplicationExitInfo.REASON_LOW_MEMORY,
911                                 ApplicationExitInfo.SUBREASON_OOM_KILL,
912                                 "oom");
913 
914                             oomKill.logKillOccurred();
915                         }
916                     }
917                 }
918             });
919             sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(),
920                     new LmkdConnection.LmkdConnectionListener() {
921                         @Override
922                         public boolean onConnect(OutputStream ostream) {
923                             Slog.i(TAG, "Connection with lmkd established");
924                             return onLmkdConnect(ostream);
925                         }
926 
927                         @Override
928                         public void onDisconnect() {
929                             Slog.w(TAG, "Lost connection to lmkd");
930                             // start reconnection after delay to let lmkd restart
931                             sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
932                                     KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
933                         }
934 
935                         @Override
936                         public boolean isReplyExpected(ByteBuffer replyBuf,
937                                 ByteBuffer dataReceived, int receivedLen) {
938                             // compare the preambule (currently one integer) to check if
939                             // this is the reply packet we are waiting for
940                             return (receivedLen == replyBuf.array().length &&
941                                     dataReceived.getInt(0) == replyBuf.getInt(0));
942                         }
943 
944                         @Override
945                         public boolean handleUnsolicitedMessage(DataInputStream inputData,
946                                 int receivedLen) {
947                             if (receivedLen < 4) {
948                                 return false;
949                             }
950 
951                             try {
952                                 switch (inputData.readInt()) {
953                                     case LMK_PROCKILL:
954                                         if (receivedLen != 12) {
955                                             return false;
956                                         }
957                                         final int pid = inputData.readInt();
958                                         final int uid = inputData.readInt();
959                                         mAppExitInfoTracker.scheduleNoteLmkdProcKilled(pid, uid);
960                                         return true;
961                                     case LMK_KILL_OCCURRED:
962                                         if (receivedLen
963                                                 < LmkdStatsReporter.KILL_OCCURRED_MSG_SIZE) {
964                                             return false;
965                                         }
966                                         // Note: directly access
967                                         // ActiveServices.sNumForegroundServices, do not try to
968                                         // hold AMS lock here, otherwise it is a potential deadlock.
969                                         Pair<Integer, Integer> foregroundServices =
970                                                 ActiveServices.sNumForegroundServices.get();
971                                         LmkdStatsReporter.logKillOccurred(inputData,
972                                                 foregroundServices.first,
973                                                 foregroundServices.second);
974                                         return true;
975                                     default:
976                                         return false;
977                                 }
978                             } catch (IOException e) {
979                                 Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
980                             }
981                             return false;
982                         }
983                     }
984             );
985             // Start listening on incoming connections from zygotes.
986             mSystemServerSocketForZygote = createSystemServerSocketForZygote();
987             if (mSystemServerSocketForZygote != null) {
988                 sKillHandler.getLooper().getQueue().addOnFileDescriptorEventListener(
989                         mSystemServerSocketForZygote.getFileDescriptor(),
990                         EVENT_INPUT, this::handleZygoteMessages);
991             }
992             mAppStartInfoTracker.init(mService);
993             mAppExitInfoTracker.init(mService);
994             mImperceptibleKillRunner = new ImperceptibleKillRunner(sKillThread.getLooper());
995         }
996     }
997 
onSystemReady()998     void onSystemReady() {
999         mAppStartInfoTracker.onSystemReady();
1000         mAppExitInfoTracker.onSystemReady();
1001     }
1002 
applyDisplaySize(WindowManagerService wm)1003     void applyDisplaySize(WindowManagerService wm) {
1004         if (!mHaveDisplaySize) {
1005             Point p = new Point();
1006             // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
1007             wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
1008             if (p.x != 0 && p.y != 0) {
1009                 updateOomLevels(p.x, p.y, true);
1010                 mHaveDisplaySize = true;
1011             }
1012         }
1013     }
1014 
1015     /**
1016      * Get a map of pid and package name that process of that pid Android/data and Android/obb
1017      * directory is not mounted to lowerfs to speed up access.
1018      */
getProcessesWithPendingBindMounts(int userId)1019     Map<Integer, String> getProcessesWithPendingBindMounts(int userId) {
1020         final Map<Integer, String> pidPackageMap = new HashMap<>();
1021         synchronized (mProcLock) {
1022             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
1023                 final ProcessRecord record = mLruProcesses.get(i);
1024                 if (record.userId != userId || !record.isBindMountPending()) {
1025                     continue;
1026                 }
1027                 final int pid = record.getPid();
1028                 // It can happen when app process is starting, but zygote work is not done yet so
1029                 // system does not this pid record yet.
1030                 if (pid == 0) {
1031                     throw new IllegalStateException("Pending process is not started yet,"
1032                             + "retry later");
1033                 }
1034                 pidPackageMap.put(pid, record.info.packageName);
1035             }
1036         }
1037         return pidPackageMap;
1038     }
1039 
updateOomLevels(int displayWidth, int displayHeight, boolean write)1040     private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
1041         // Scale buckets from avail memory: at 300MB we use the lowest values to
1042         // 700MB or more for the top values.
1043         float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
1044 
1045         // Scale buckets from screen size.
1046         int minSize = 480 * 800;  //  384000
1047         int maxSize = 1280 * 800; // 1024000  230400 870400  .264
1048         float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
1049         if (false) {
1050             Slog.i("XXXXXX", "scaleMem=" + scaleMem);
1051             Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
1052                     + " dh=" + displayHeight);
1053         }
1054 
1055         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
1056         if (scale < 0) scale = 0;
1057         else if (scale > 1) scale = 1;
1058         int minfree_adj = Resources.getSystem().getInteger(
1059                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
1060         int minfree_abs = Resources.getSystem().getInteger(
1061                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
1062         if (false) {
1063             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
1064         }
1065 
1066         final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
1067 
1068         for (int i = 0; i < mOomAdj.length; i++) {
1069             int low = mOomMinFreeLow[i];
1070             int high = mOomMinFreeHigh[i];
1071             if (is64bit) {
1072                 // Increase the high min-free levels for cached processes for 64-bit
1073                 if (i == 4) high = (high * 3) / 2;
1074                 else if (i == 5) high = (high * 7) / 4;
1075             }
1076             mOomMinFree[i] = (int)(low + ((high - low) * scale));
1077         }
1078 
1079         if (minfree_abs >= 0) {
1080             for (int i = 0; i < mOomAdj.length; i++) {
1081                 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
1082                         / mOomMinFree[mOomAdj.length - 1]);
1083             }
1084         }
1085 
1086         if (minfree_adj != 0) {
1087             for (int i = 0; i < mOomAdj.length; i++) {
1088                 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
1089                         / mOomMinFree[mOomAdj.length - 1]);
1090                 if (mOomMinFree[i] < 0) {
1091                     mOomMinFree[i] = 0;
1092                 }
1093             }
1094         }
1095 
1096         // The maximum size we will restore a process from cached to background, when under
1097         // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
1098         // before killing background processes.
1099         mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
1100 
1101         // Ask the kernel to try to keep enough memory free to allocate 3 full
1102         // screen 32bpp buffers without entering direct reclaim.
1103         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
1104         int reserve_adj = Resources.getSystem().getInteger(
1105                 com.android.internal.R.integer.config_extraFreeKbytesAdjust);
1106         int reserve_abs = Resources.getSystem().getInteger(
1107                 com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
1108 
1109         if (reserve_abs >= 0) {
1110             reserve = reserve_abs;
1111         }
1112 
1113         if (reserve_adj != 0) {
1114             reserve += reserve_adj;
1115             if (reserve < 0) {
1116                 reserve = 0;
1117             }
1118         }
1119 
1120         if (write) {
1121             ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
1122             buf.putInt(LMK_TARGET);
1123             for (int i = 0; i < mOomAdj.length; i++) {
1124                 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
1125                 buf.putInt(mOomAdj[i]);
1126             }
1127 
1128             writeLmkd(buf, null);
1129             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
1130             mOomLevelsSet = true;
1131         }
1132         // GB: 2048,3072,4096,6144,7168,8192
1133         // HC: 8192,10240,12288,14336,16384,20480
1134     }
1135 
computeEmptyProcessLimit(int totalProcessLimit)1136     public static int computeEmptyProcessLimit(int totalProcessLimit) {
1137         return totalProcessLimit/2;
1138     }
1139 
buildOomTag(String prefix, String compactPrefix, String space, int val, int base, boolean compact)1140     private static String buildOomTag(String prefix, String compactPrefix, String space, int val,
1141             int base, boolean compact) {
1142         final int diff = val - base;
1143         if (diff == 0) {
1144             if (compact) {
1145                 return compactPrefix;
1146             }
1147             if (space == null) return prefix;
1148             return prefix + space;
1149         }
1150         if (diff < 10) {
1151             return prefix + (compact ? "+" : "+ ") + Integer.toString(diff);
1152         }
1153         return prefix + "+" + Integer.toString(diff);
1154     }
1155 
makeOomAdjString(int setAdj, boolean compact)1156     public static String makeOomAdjString(int setAdj, boolean compact) {
1157         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
1158             return buildOomTag("cch", "cch", "   ", setAdj,
1159                     ProcessList.CACHED_APP_MIN_ADJ, compact);
1160         } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
1161             return buildOomTag("svcb  ", "svcb", null, setAdj,
1162                     ProcessList.SERVICE_B_ADJ, compact);
1163         } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
1164             return buildOomTag("prev  ", "prev", null, setAdj,
1165                     ProcessList.PREVIOUS_APP_ADJ, compact);
1166         } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
1167             return buildOomTag("home  ", "home", null, setAdj,
1168                     ProcessList.HOME_APP_ADJ, compact);
1169         } else if (setAdj >= ProcessList.SERVICE_ADJ) {
1170             return buildOomTag("svc   ", "svc", null, setAdj,
1171                     ProcessList.SERVICE_ADJ, compact);
1172         } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
1173             return buildOomTag("hvy   ", "hvy", null, setAdj,
1174                     ProcessList.HEAVY_WEIGHT_APP_ADJ, compact);
1175         } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
1176             return buildOomTag("bkup  ", "bkup", null, setAdj,
1177                     ProcessList.BACKUP_APP_ADJ, compact);
1178         } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
1179             return buildOomTag("prcl  ", "prcl", null, setAdj,
1180                     ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact);
1181         } else if (setAdj >= ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ) {
1182             return buildOomTag("prcm  ", "prcm", null, setAdj,
1183                     ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ, compact);
1184         } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
1185             return buildOomTag("prcp  ", "prcp", null, setAdj,
1186                     ProcessList.PERCEPTIBLE_APP_ADJ, compact);
1187         } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
1188             return buildOomTag("vis", "vis", "   ", setAdj,
1189                     ProcessList.VISIBLE_APP_ADJ, compact);
1190         } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1191             return buildOomTag("fg ", "fg ", "   ", setAdj,
1192                     ProcessList.FOREGROUND_APP_ADJ, compact);
1193         } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
1194             return buildOomTag("psvc  ", "psvc", null, setAdj,
1195                     ProcessList.PERSISTENT_SERVICE_ADJ, compact);
1196         } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
1197             return buildOomTag("pers  ", "pers", null, setAdj,
1198                     ProcessList.PERSISTENT_PROC_ADJ, compact);
1199         } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
1200             return buildOomTag("sys   ", "sys", null, setAdj,
1201                     ProcessList.SYSTEM_ADJ, compact);
1202         } else if (setAdj >= ProcessList.NATIVE_ADJ) {
1203             return buildOomTag("ntv  ", "ntv", null, setAdj,
1204                     ProcessList.NATIVE_ADJ, compact);
1205         } else {
1206             return Integer.toString(setAdj);
1207         }
1208     }
1209 
makeProcStateString(int curProcState)1210     public static String makeProcStateString(int curProcState) {
1211         return ActivityManager.procStateToString(curProcState);
1212     }
1213 
makeProcStateProtoEnum(int curProcState)1214     public static int makeProcStateProtoEnum(int curProcState) {
1215         switch (curProcState) {
1216             case ActivityManager.PROCESS_STATE_PERSISTENT:
1217                 return AppProtoEnums.PROCESS_STATE_PERSISTENT;
1218             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
1219                 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
1220             case ActivityManager.PROCESS_STATE_TOP:
1221                 return AppProtoEnums.PROCESS_STATE_TOP;
1222             case ActivityManager.PROCESS_STATE_BOUND_TOP:
1223                 return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
1224             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
1225                 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
1226             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
1227                 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
1228             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
1229                 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING;
1230             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
1231                 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
1232             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
1233                 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
1234             case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
1235                 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND;
1236             case ActivityManager.PROCESS_STATE_BACKUP:
1237                 return AppProtoEnums.PROCESS_STATE_BACKUP;
1238             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
1239                 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT;
1240             case ActivityManager.PROCESS_STATE_SERVICE:
1241                 return AppProtoEnums.PROCESS_STATE_SERVICE;
1242             case ActivityManager.PROCESS_STATE_RECEIVER:
1243                 return AppProtoEnums.PROCESS_STATE_RECEIVER;
1244             case ActivityManager.PROCESS_STATE_HOME:
1245                 return AppProtoEnums.PROCESS_STATE_HOME;
1246             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
1247                 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY;
1248             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
1249                 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY;
1250             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
1251                 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
1252             case ActivityManager.PROCESS_STATE_CACHED_RECENT:
1253                 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT;
1254             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
1255                 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY;
1256             case ActivityManager.PROCESS_STATE_NONEXISTENT:
1257                 return AppProtoEnums.PROCESS_STATE_NONEXISTENT;
1258             case ActivityManager.PROCESS_STATE_UNKNOWN:
1259                 return AppProtoEnums.PROCESS_STATE_UNKNOWN;
1260             default:
1261                 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO;
1262         }
1263     }
1264 
appendRamKb(StringBuilder sb, long ramKb)1265     public static void appendRamKb(StringBuilder sb, long ramKb) {
1266         for (int j = 0, fact = 10; j < 6; j++, fact *= 10) {
1267             if (ramKb < fact) {
1268                 sb.append(' ');
1269             }
1270         }
1271         sb.append(ramKb);
1272     }
1273 
1274     // How long after a state change that it is safe to collect PSS without it being dirty.
1275     public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
1276 
1277     // The minimum time interval after a state change it is safe to collect PSS.
1278     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
1279 
1280     // The maximum amount of time we want to go between PSS collections.
1281     public static final int PSS_MAX_INTERVAL = 60*60*1000;
1282 
1283     // The minimum amount of time between successive PSS requests for *all* processes.
1284     public static final int PSS_ALL_INTERVAL = 20*60*1000;
1285 
1286     // The amount of time until PSS when a persistent process first appears.
1287     private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;
1288 
1289     // The amount of time until PSS when a process first becomes top.
1290     private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
1291 
1292     // The amount of time until PSS when a process first goes into the background.
1293     private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
1294 
1295     // The amount of time until PSS when a process first becomes cached.
1296     private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;
1297 
1298     // The amount of time until PSS when an important process stays in the same state.
1299     private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;
1300 
1301     // The amount of time until PSS when the top process stays in the same state.
1302     private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;
1303 
1304     // The amount of time until PSS when an important process stays in the same state.
1305     private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;
1306 
1307     // The amount of time until PSS when a service process stays in the same state.
1308     private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;
1309 
1310     // The amount of time until PSS when a cached process stays in the same state.
1311     private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;
1312 
1313     // The amount of time until PSS when a persistent process first appears.
1314     private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
1315 
1316     // The amount of time until PSS when a process first becomes top.
1317     private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000;
1318 
1319     // The amount of time until PSS when a process first goes into the background.
1320     private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000;
1321 
1322     // The amount of time until PSS when a process first becomes cached.
1323     private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000;
1324 
1325     // The minimum time interval after a state change it is safe to collect PSS.
1326     public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
1327 
1328     // The amount of time during testing until PSS when a process first becomes top.
1329     private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
1330 
1331     // The amount of time during testing until PSS when a process first goes into the background.
1332     private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
1333 
1334     // The amount of time during testing until PSS when an important process stays in same state.
1335     private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
1336 
1337     // The amount of time during testing until PSS when a background process stays in same state.
1338     private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
1339 
1340     public static final int PROC_MEM_PERSISTENT = 0;
1341     public static final int PROC_MEM_TOP = 1;
1342     public static final int PROC_MEM_IMPORTANT = 2;
1343     public static final int PROC_MEM_SERVICE = 3;
1344     public static final int PROC_MEM_CACHED = 4;
1345     public static final int PROC_MEM_NUM = 5;
1346 
1347     // Map large set of system process states to
1348     private static final int[] sProcStateToProcMem = new int[] {
1349         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
1350         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
1351         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
1352         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
1353         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_BOUND_TOP
1354         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
1355         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
1356         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
1357         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
1358         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BACKUP
1359         PROC_MEM_SERVICE,               // ActivityManager.PROCESS_STATE_SERVICE
1360         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_RECEIVER
1361         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
1362         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
1363         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_HOME
1364         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
1365         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
1366         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
1367         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_RECENT
1368         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_EMPTY
1369     };
1370 
1371     private static final long[] sFirstAwakePssTimes = new long[] {
1372         PSS_FIRST_PERSISTENT_INTERVAL,  // PROC_MEM_PERSISTENT
1373         PSS_FIRST_TOP_INTERVAL,         // PROC_MEM_TOP
1374         PSS_FIRST_BACKGROUND_INTERVAL,  // PROC_MEM_IMPORTANT
1375         PSS_FIRST_BACKGROUND_INTERVAL,  // PROC_MEM_SERVICE
1376         PSS_FIRST_CACHED_INTERVAL,      // PROC_MEM_CACHED
1377     };
1378 
1379     private static final long[] sSameAwakePssTimes = new long[] {
1380         PSS_SAME_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1381         PSS_SAME_TOP_INTERVAL,          // PROC_MEM_TOP
1382         PSS_SAME_IMPORTANT_INTERVAL,    // PROC_MEM_IMPORTANT
1383         PSS_SAME_SERVICE_INTERVAL,      // PROC_MEM_SERVICE
1384         PSS_SAME_CACHED_INTERVAL,       // PROC_MEM_CACHED
1385     };
1386 
1387     private static final long[] sFirstAsleepPssTimes = new long[] {
1388         PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1389         PSS_FIRST_ASLEEP_TOP_INTERVAL,          // PROC_MEM_TOP
1390         PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // PROC_MEM_IMPORTANT
1391         PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // PROC_MEM_SERVICE
1392         PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // PROC_MEM_CACHED
1393     };
1394 
1395     private static final long[] sSameAsleepPssTimes = new long[] {
1396         PSS_SAME_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1397         PSS_SAME_TOP_INTERVAL,          // PROC_MEM_TOP
1398         PSS_SAME_IMPORTANT_INTERVAL,    // PROC_MEM_IMPORTANT
1399         PSS_SAME_SERVICE_INTERVAL,      // PROC_MEM_SERVICE
1400         PSS_SAME_CACHED_INTERVAL,       // PROC_MEM_CACHED
1401     };
1402 
1403     private static final long[] sTestFirstPssTimes = new long[] {
1404         PSS_TEST_FIRST_TOP_INTERVAL,        // PROC_MEM_PERSISTENT
1405         PSS_TEST_FIRST_TOP_INTERVAL,        // PROC_MEM_TOP
1406         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1407         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1408         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
1409     };
1410 
1411     private static final long[] sTestSamePssTimes = new long[] {
1412         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_PERSISTENT
1413         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // PROC_MEM_TOP
1414         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // PROC_MEM_IMPORTANT
1415         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_SERVICE
1416         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_CACHED
1417     };
1418 
1419     public static final class ProcStateMemTracker {
1420         final int[] mHighestMem = new int[PROC_MEM_NUM];
1421         final float[] mScalingFactor = new float[PROC_MEM_NUM];
1422         int mTotalHighestMem = PROC_MEM_CACHED;
1423 
1424         int mPendingMemState;
1425         int mPendingHighestMemState;
1426         float mPendingScalingFactor;
1427 
ProcStateMemTracker()1428         public ProcStateMemTracker() {
1429             for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
1430                 mHighestMem[i] = PROC_MEM_NUM;
1431                 mScalingFactor[i] = 1.0f;
1432             }
1433             mPendingMemState = -1;
1434         }
1435 
dumpLine(PrintWriter pw)1436         public void dumpLine(PrintWriter pw) {
1437             pw.print("best=");
1438             pw.print(mTotalHighestMem);
1439             pw.print(" (");
1440             boolean needSep = false;
1441             for (int i = 0; i < PROC_MEM_NUM; i++) {
1442                 if (mHighestMem[i] < PROC_MEM_NUM) {
1443                     if (needSep) {
1444                         pw.print(", ");
1445                         needSep = false;
1446                     }
1447                     pw.print(i);
1448                     pw.print("=");
1449                     pw.print(mHighestMem[i]);
1450                     pw.print(" ");
1451                     pw.print(mScalingFactor[i]);
1452                     pw.print("x");
1453                     needSep = true;
1454                 }
1455             }
1456             pw.print(")");
1457             if (mPendingMemState >= 0) {
1458                 pw.print(" / pending state=");
1459                 pw.print(mPendingMemState);
1460                 pw.print(" highest=");
1461                 pw.print(mPendingHighestMemState);
1462                 pw.print(" ");
1463                 pw.print(mPendingScalingFactor);
1464                 pw.print("x");
1465             }
1466             pw.println();
1467         }
1468     }
1469 
procStatesDifferForMem(int procState1, int procState2)1470     public static boolean procStatesDifferForMem(int procState1, int procState2) {
1471         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
1472     }
1473 
minTimeFromStateChange(boolean test)1474     public static long minTimeFromStateChange(boolean test) {
1475         return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
1476     }
1477 
computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, boolean sleeping, long now, long earliest)1478     public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
1479             boolean sleeping, long now, long earliest) {
1480         boolean first;
1481         float scalingFactor;
1482         final int memState = sProcStateToProcMem[procState];
1483         if (tracker != null) {
1484             final int highestMemState = memState < tracker.mTotalHighestMem
1485                     ? memState : tracker.mTotalHighestMem;
1486             first = highestMemState < tracker.mHighestMem[memState];
1487             tracker.mPendingMemState = memState;
1488             tracker.mPendingHighestMemState = highestMemState;
1489             if (first) {
1490                 tracker.mPendingScalingFactor = scalingFactor = 1.0f;
1491             } else {
1492                 scalingFactor = tracker.mScalingFactor[memState];
1493                 tracker.mPendingScalingFactor = scalingFactor * 1.5f;
1494             }
1495         } else {
1496             first = true;
1497             scalingFactor = 1.0f;
1498         }
1499         final long[] table = test
1500                 ? (first
1501                 ? sTestFirstPssTimes
1502                 : sTestSamePssTimes)
1503                 : (first
1504                 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
1505                 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
1506         long delay = (long)(table[memState] * scalingFactor);
1507         if (delay > PSS_MAX_INTERVAL) {
1508             delay = PSS_MAX_INTERVAL;
1509         }
1510         return Math.max(now + delay, earliest);
1511     }
1512 
1513     long getMemLevel(int adjustment) {
1514         for (int i = 0; i < mOomAdj.length; i++) {
1515             if (adjustment <= mOomAdj[i]) {
1516                 return mOomMinFree[i] * 1024;
1517             }
1518         }
1519         return mOomMinFree[mOomAdj.length - 1] * 1024;
1520     }
1521 
1522     /**
1523      * Return the maximum pss size in kb that we consider a process acceptable to
1524      * restore from its cached state for running in the background when RAM is low.
1525      */
1526     long getCachedRestoreThresholdKb() {
1527         return mCachedRestoreLevel;
1528     }
1529 
1530     AppStartInfoTracker getAppStartInfoTracker() {
1531         return mAppStartInfoTracker;
1532     }
1533 
1534     /**
1535      * Set the out-of-memory badness adjustment for a process.
1536      * If {@code pid <= 0}, this method will be a no-op.
1537      *
1538      * @param pid The process identifier to set.
1539      * @param uid The uid of the app
1540      * @param amt Adjustment value -- lmkd allows -1000 to +1000
1541      *
1542      * {@hide}
1543      */
1544     public static void setOomAdj(int pid, int uid, int amt) {
1545         // This indicates that the process is not started yet and so no need to proceed further.
1546         if (pid <= 0) {
1547             return;
1548         }
1549         if (amt == UNKNOWN_ADJ)
1550             return;
1551 
1552         long start = SystemClock.elapsedRealtime();
1553         ByteBuffer buf = ByteBuffer.allocate(4 * 4);
1554         buf.putInt(LMK_PROCPRIO);
1555         buf.putInt(pid);
1556         buf.putInt(uid);
1557         buf.putInt(amt);
1558         writeLmkd(buf, null);
1559         long now = SystemClock.elapsedRealtime();
1560         if ((now-start) > 250) {
1561             Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
1562                     + " = " + amt);
1563         }
1564     }
1565 
1566 
1567     // The max size for PROCS_PRIO cmd in LMKD
1568     private static final int MAX_PROCS_PRIO_PACKET_SIZE = 3;
1569 
1570     // (4 bytes per field * 4 fields * 3 processes per batch) + 4 bytes for the LMKD cmd
1571     private static final int MAX_OOM_ADJ_BATCH_LENGTH = ((4 * 4) * MAX_PROCS_PRIO_PACKET_SIZE) + 4;
1572 
1573     /**
1574      * Set the out-of-memory badness adjustment for a list of processes.
1575      *
1576      * @param apps App list to adjust their respective oom score.
1577      *
1578      * {@hide}
1579      */
1580     public static void batchSetOomAdj(ArrayList<ProcessRecord> apps) {
1581         final int totalApps = apps.size();
1582         if (totalApps == 0) {
1583             return;
1584         }
1585 
1586         ByteBuffer buf = ByteBuffer.allocate(MAX_OOM_ADJ_BATCH_LENGTH);
1587         int total_procs_in_buf = 0;
1588         buf.putInt(LMK_PROCS_PRIO);
1589         for (int i = 0; i < totalApps; i++) {
1590             final int pid = apps.get(i).getPid();
1591             final int amt = apps.get(i).mState.getCurAdj();
1592             final int uid = apps.get(i).uid;
1593             if (pid <= 0 || amt == UNKNOWN_ADJ) continue;
1594             if (total_procs_in_buf >= MAX_PROCS_PRIO_PACKET_SIZE) {
1595                 writeLmkd(buf, null);
1596                 buf.clear();
1597                 total_procs_in_buf = 0;
1598                 buf.allocate(MAX_OOM_ADJ_BATCH_LENGTH);
1599                 buf.putInt(LMK_PROCS_PRIO);
1600             }
1601             buf.putInt(pid);
1602             buf.putInt(uid);
1603             buf.putInt(amt);
1604             buf.putInt(0);  // Default proc type to PROC_TYPE_APP
1605             total_procs_in_buf++;
1606         }
1607         writeLmkd(buf, null);
1608     }
1609 
1610     /*
1611      * {@hide}
1612      */
1613     public static final void remove(int pid) {
1614         // This indicates that the process is not started yet and so no need to proceed further.
1615         if (pid <= 0) {
1616             return;
1617         }
1618         ByteBuffer buf = ByteBuffer.allocate(4 * 2);
1619         buf.putInt(LMK_PROCREMOVE);
1620         buf.putInt(pid);
1621         writeLmkd(buf, null);
1622     }
1623 
1624     /*
1625      * {@hide}
1626      */
1627     public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) {
1628         ByteBuffer buf = ByteBuffer.allocate(4 * 3);
1629         ByteBuffer repl = ByteBuffer.allocate(4 * 2);
1630         buf.putInt(LMK_GETKILLCNT);
1631         buf.putInt(min_oom_adj);
1632         buf.putInt(max_oom_adj);
1633         // indicate what we are waiting for
1634         repl.putInt(LMK_GETKILLCNT);
1635         repl.rewind();
1636         if (writeLmkd(buf, repl) && repl.getInt() == LMK_GETKILLCNT) {
1637             return new Integer(repl.getInt());
1638         }
1639         return null;
1640     }
1641 
1642     public boolean onLmkdConnect(OutputStream ostream) {
1643         try {
1644             // Purge any previously registered pids
1645             ByteBuffer buf = ByteBuffer.allocate(4);
1646             buf.putInt(LMK_PROCPURGE);
1647             ostream.write(buf.array(), 0, buf.position());
1648             if (mOomLevelsSet) {
1649                 // Reset oom_adj levels
1650                 buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
1651                 buf.putInt(LMK_TARGET);
1652                 for (int i = 0; i < mOomAdj.length; i++) {
1653                     buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
1654                     buf.putInt(mOomAdj[i]);
1655                 }
1656                 ostream.write(buf.array(), 0, buf.position());
1657             }
1658             // Subscribe for kill event notifications
1659             buf = ByteBuffer.allocate(4 * 2);
1660             buf.putInt(LMK_SUBSCRIBE);
1661             buf.putInt(LMK_ASYNC_EVENT_KILL);
1662             ostream.write(buf.array(), 0, buf.position());
1663 
1664             // Subscribe for stats event notifications
1665             buf = ByteBuffer.allocate(4 * 2);
1666             buf.putInt(LMK_SUBSCRIBE);
1667             buf.putInt(LMK_ASYNC_EVENT_STAT);
1668             ostream.write(buf.array(), 0, buf.position());
1669         } catch (IOException ex) {
1670             return false;
1671         }
1672         return true;
1673     }
1674 
1675     /**
1676      * {@hide}
1677      */
1678     public static void startPsiMonitoringAfterBoot() {
1679         ByteBuffer buf = ByteBuffer.allocate(4);
1680         buf.putInt(LMK_START_MONITORING);
1681         writeLmkd(buf, null);
1682     }
1683 
1684     private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
1685         if (!sLmkdConnection.isConnected()) {
1686             // try to connect immediately and then keep retrying
1687             sKillHandler.sendMessage(
1688                     sKillHandler.obtainMessage(KillHandler.LMKD_RECONNECT_MSG));
1689 
1690             // wait for connection retrying 3 times (up to 3 seconds)
1691             if (!sLmkdConnection.waitForConnection(3 * LMKD_RECONNECT_DELAY_MS)) {
1692                 return false;
1693             }
1694         }
1695 
1696         return sLmkdConnection.exchange(buf, repl);
1697     }
1698 
1699     static void killProcessGroup(int uid, int pid) {
1700         /* static; one-time init here */
1701         if (sKillHandler != null) {
1702             sKillHandler.sendMessage(
1703                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
1704         } else {
1705             Slog.w(TAG, "Asked to kill process group before system bringup!");
1706             Process.killProcessGroup(uid, pid);
1707         }
1708     }
1709 
1710     @GuardedBy("mService")
1711     ProcessRecord getProcessRecordLocked(String processName, int uid) {
1712         if (uid == SYSTEM_UID) {
1713             // The system gets to run in any process.  If there are multiple
1714             // processes with the same uid, just pick the first (this
1715             // should never happen).
1716             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
1717             if (procs == null) return null;
1718             final int procCount = procs.size();
1719             for (int i = 0; i < procCount; i++) {
1720                 final int procUid = procs.keyAt(i);
1721                 if (!UserHandle.isCore(procUid) || !UserHandle.isSameUser(procUid, uid)) {
1722                     // Don't use an app process or different user process for system component.
1723                     continue;
1724                 }
1725                 return procs.valueAt(i);
1726             }
1727         }
1728         return mProcessNames.get(processName, uid);
1729     }
1730 
1731     void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
1732         final long homeAppMem = getMemLevel(HOME_APP_ADJ);
1733         final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ);
1734         outInfo.advertisedMem = getAdvertisedMem();
1735         outInfo.availMem = getFreeMemory();
1736         outInfo.totalMem = getTotalMemory();
1737         outInfo.threshold = homeAppMem;
1738         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
1739         outInfo.hiddenAppThreshold = cachedAppMem;
1740         outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ);
1741         outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ);
1742         outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ);
1743     }
1744 
1745     @GuardedBy(anyOf = {"mService", "mProcLock"})
1746     ProcessRecord findAppProcessLOSP(IBinder app, String reason) {
1747         final int NP = mProcessNames.getMap().size();
1748         for (int ip = 0; ip < NP; ip++) {
1749             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
1750             final int NA = apps.size();
1751             for (int ia = 0; ia < NA; ia++) {
1752                 ProcessRecord p = apps.valueAt(ia);
1753                 final IApplicationThread thread = p.getThread();
1754                 if (thread != null && thread.asBinder() == app) {
1755                     return p;
1756                 }
1757             }
1758         }
1759 
1760         Slog.w(TAG, "Can't find mystery application for " + reason
1761                 + " from pid=" + Binder.getCallingPid()
1762                 + " uid=" + Binder.getCallingUid() + ": " + app);
1763         return null;
1764     }
1765 
1766     private void checkSlow(long startTime, String where) {
1767         long now = SystemClock.uptimeMillis();
1768         if ((now - startTime) > 50) {
1769             // If we are taking more than 50ms, log about it.
1770             Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where);
1771         }
1772     }
1773 
1774     private int[] computeGidsForProcess(int mountExternal, int uid, int[] permGids,
1775             boolean externalStorageAccess) {
1776         ArrayList<Integer> gidList = new ArrayList<>(permGids.length + 5);
1777 
1778         final int sharedAppGid = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
1779         final int cacheAppGid = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
1780         final int userGid = UserHandle.getUserGid(UserHandle.getUserId(uid));
1781 
1782         // Add shared application and profile GIDs so applications can share some
1783         // resources like shared libraries and access user-wide resources
1784         for (int permGid : permGids) {
1785             gidList.add(permGid);
1786         }
1787         if (sharedAppGid != UserHandle.ERR_GID) {
1788             gidList.add(sharedAppGid);
1789         }
1790         if (cacheAppGid != UserHandle.ERR_GID) {
1791             gidList.add(cacheAppGid);
1792         }
1793         if (userGid != UserHandle.ERR_GID) {
1794             gidList.add(userGid);
1795         }
1796         if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE
1797                 || mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
1798             // For DownloadProviders and MTP: To grant access to /sdcard/Android/
1799             // And a special case for the FUSE daemon since it runs an MTP server and should have
1800             // access to Android/
1801             // Note that we must add in the user id, because sdcardfs synthesizes this permission
1802             // based on the user
1803             gidList.add(UserHandle.getUid(UserHandle.getUserId(uid), Process.SDCARD_RW_GID));
1804 
1805             // For devices without sdcardfs, these GIDs are needed instead; note that we
1806             // consciously don't add the user_id in the GID, since these apps are anyway
1807             // isolated to only their own user
1808             gidList.add(Process.EXT_DATA_RW_GID);
1809             gidList.add(Process.EXT_OBB_RW_GID);
1810         }
1811         if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
1812             // For devices without sdcardfs, this GID is needed to allow installers access to OBBs
1813             gidList.add(Process.EXT_OBB_RW_GID);
1814         }
1815         if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
1816             // For the FUSE daemon: To grant access to the lower filesystem.
1817             // EmulatedVolumes: /data/media and /mnt/expand/<volume>/data/media
1818             // PublicVolumes: /mnt/media_rw/<volume>
1819             gidList.add(Process.MEDIA_RW_GID);
1820         }
1821         if (externalStorageAccess) {
1822             // Apps with MANAGE_EXTERNAL_STORAGE PERMISSION need the external_storage gid to access
1823             // USB OTG (unreliable) volumes on /mnt/media_rw/<vol name>
1824             gidList.add(Process.EXTERNAL_STORAGE_GID);
1825         }
1826 
1827         int[] gidArray = new int[gidList.size()];
1828         for (int i = 0; i < gidArray.length; i++) {
1829             gidArray[i] = gidList.get(i);
1830         }
1831         return gidArray;
1832     }
1833 
1834     /**
1835      * @return {@code true} if process start is successful, false otherwise.
1836      */
1837     @GuardedBy("mService")
1838     boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1839             int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
1840             String abiOverride) {
1841         if (app.isPendingStart()) {
1842             return true;
1843         }
1844         final long startUptime = SystemClock.uptimeMillis();
1845         final long startElapsedTime = SystemClock.elapsedRealtime();
1846         if (app.getPid() > 0 && app.getPid() != ActivityManagerService.MY_PID) {
1847             checkSlow(startUptime, "startProcess: removing from pids map");
1848             mService.removePidLocked(app.getPid(), app);
1849             app.setBindMountPending(false);
1850             mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1851             checkSlow(startUptime, "startProcess: done removing from pids map");
1852             app.setPid(0);
1853             app.setStartSeq(0);
1854         }
1855         // Clear any residual death recipient link as the ProcessRecord could be reused.
1856         app.unlinkDeathRecipient();
1857         app.setDyingPid(0);
1858 
1859         if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
1860                 TAG_PROCESSES,
1861                 "startProcessLocked removing on hold: " + app);
1862         mService.mProcessesOnHold.remove(app);
1863 
1864         checkSlow(startUptime, "startProcess: starting to update cpu stats");
1865         mService.updateCpuStats();
1866         checkSlow(startUptime, "startProcess: done updating cpu stats");
1867 
1868         try {
1869             final int userId = UserHandle.getUserId(app.uid);
1870             try {
1871                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
1872             } catch (RemoteException e) {
1873                 throw e.rethrowAsRuntimeException();
1874             }
1875 
1876             int uid = app.uid;
1877             int[] gids = null;
1878             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1879             boolean externalStorageAccess = false;
1880             if (!app.isolated) {
1881                 int[] permGids = null;
1882                 try {
1883                     checkSlow(startUptime, "startProcess: getting gids from package manager");
1884                     final IPackageManager pm = AppGlobals.getPackageManager();
1885                     permGids = pm.getPackageGids(app.info.packageName,
1886                             MATCH_DIRECT_BOOT_AUTO, app.userId);
1887                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
1888                             StorageManagerInternal.class);
1889                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
1890                             app.info.packageName);
1891                     externalStorageAccess = storageManagerInternal.hasExternalStorageAccess(uid,
1892                             app.info.packageName);
1893                     if (mService.isAppFreezerExemptInstPkg()
1894                             && pm.checkPermission(Manifest.permission.INSTALL_PACKAGES,
1895                             app.info.packageName, userId)
1896                             == PackageManager.PERMISSION_GRANTED) {
1897                         Slog.i(TAG, app.info.packageName + " is exempt from freezer");
1898                         app.mOptRecord.setFreezeExempt(true);
1899                     }
1900                 } catch (RemoteException e) {
1901                     throw e.rethrowAsRuntimeException();
1902                 }
1903 
1904                 // Remove any gids needed if the process has been denied permissions.
1905                 // NOTE: eventually we should probably have the package manager pre-compute
1906                 // this for us?
1907                 if (app.processInfo != null && app.processInfo.deniedPermissions != null) {
1908                     for (int i = app.processInfo.deniedPermissions.size() - 1; i >= 0; i--) {
1909                         int[] denyGids = mService.mPackageManagerInt.getPermissionGids(
1910                                 app.processInfo.deniedPermissions.valueAt(i), app.userId);
1911                         if (denyGids != null) {
1912                             for (int gid : denyGids) {
1913                                 permGids = ArrayUtils.removeInt(permGids, gid);
1914                             }
1915                         }
1916                     }
1917                 }
1918 
1919                 gids = computeGidsForProcess(mountExternal, uid, permGids, externalStorageAccess);
1920             }
1921             app.setMountMode(mountExternal);
1922             checkSlow(startUptime, "startProcess: building args");
1923             if (app.getWindowProcessController().isFactoryTestProcess()) {
1924                 uid = 0;
1925             }
1926             int runtimeFlags = 0;
1927 
1928             boolean debuggableFlag = (app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
1929             boolean isProfileableByShell = app.info.isProfileableByShell();
1930             boolean isProfileable = app.info.isProfileable();
1931 
1932             if (app.isSdkSandbox) {
1933                 ApplicationInfo clientInfo = app.getClientInfoForSdkSandbox();
1934                 if (clientInfo != null) {
1935                     debuggableFlag |= (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
1936                     isProfileableByShell |= clientInfo.isProfileableByShell();
1937                     isProfileable |= clientInfo.isProfileable();
1938                 }
1939             }
1940 
1941             if (debuggableFlag) {
1942                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
1943                 runtimeFlags |= Zygote.DEBUG_ENABLE_PTRACE;
1944                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1945                 // Also turn on CheckJNI for debuggable apps. It's quite
1946                 // awkward to turn on otherwise.
1947                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1948 
1949                 // Check if the developer does not want ART verification
1950                 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(),
1951                         android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) {
1952                     runtimeFlags |= Zygote.DISABLE_VERIFIER;
1953                     Slog.w(TAG_PROCESSES, app + ": ART verification disabled");
1954                 }
1955             }
1956             // Run the app in safe mode if its manifest requests so or the
1957             // system is booted in safe mode.
1958             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) {
1959                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1960             }
1961             if (isProfileableByShell) {
1962                 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
1963             }
1964             if (isProfileable) {
1965                 runtimeFlags |= Zygote.PROFILEABLE;
1966             }
1967             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1968                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1969             }
1970             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1971             if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1972                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1973             }
1974             String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1975             if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1976                 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1977             }
1978             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1979                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1980             }
1981             if ("1".equals(SystemProperties.get("debug.assert"))) {
1982                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1983             }
1984             if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) {
1985                 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER;
1986             }
1987             if (mService.mNativeDebuggingApp != null
1988                     && mService.mNativeDebuggingApp.equals(app.processName)) {
1989                 // Enable all debug flags required by the native debugger.
1990                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
1991                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1992                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
1993                 mService.mNativeDebuggingApp = null;
1994             }
1995 
1996             if (app.info.isEmbeddedDexUsed()
1997                     || (app.processInfo != null && app.processInfo.useEmbeddedDex)) {
1998                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1999             }
2000 
2001             if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
2002                 app.info.maybeUpdateHiddenApiEnforcementPolicy(
2003                         mService.mHiddenApiBlacklist.getPolicy());
2004                 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
2005                         app.info.getHiddenApiEnforcementPolicy();
2006                 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
2007                 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
2008                     throw new IllegalStateException("Invalid API policy: " + policy);
2009                 }
2010                 runtimeFlags |= policyBits;
2011 
2012                 if (disableTestApiChecks) {
2013                     runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY;
2014                 }
2015             }
2016 
2017             String useAppImageCache = SystemProperties.get(
2018                     PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
2019             // Property defaults to true currently.
2020             if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) {
2021                 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
2022             }
2023 
2024             String invokeWith = null;
2025             if (debuggableFlag) {
2026                 // Debuggable apps may include a wrapper script with their library directory.
2027                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
2028                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
2029                 try {
2030                     if (new File(wrapperFileName).exists()) {
2031                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
2032                     }
2033                 } finally {
2034                     StrictMode.setThreadPolicy(oldPolicy);
2035                 }
2036             }
2037 
2038             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2039             if (requiredAbi == null) {
2040                 requiredAbi = Build.SUPPORTED_ABIS[0];
2041             }
2042 
2043             String instructionSet = null;
2044             if (app.info.primaryCpuAbi != null) {
2045                 // If ABI override is specified, use the isa derived from the value of ABI override.
2046                 // Otherwise, use the isa derived from primary ABI
2047                 instructionSet = VMRuntime.getInstructionSet(requiredAbi);
2048             }
2049 
2050             app.setGids(gids);
2051             app.setRequiredAbi(requiredAbi);
2052             app.setInstructionSet(instructionSet);
2053 
2054             // If this was an external service, the package name and uid in the passed in
2055             // ApplicationInfo have been changed to match those of the calling package;
2056             // that will incorrectly apply compat feature overrides for the calling package instead
2057             // of the defining one.
2058             ApplicationInfo definingAppInfo;
2059             if (hostingRecord.getDefiningPackageName() != null) {
2060                 definingAppInfo = new ApplicationInfo(app.info);
2061                 definingAppInfo.packageName = hostingRecord.getDefiningPackageName();
2062                 definingAppInfo.uid = uid;
2063             } else {
2064                 definingAppInfo = app.info;
2065             }
2066 
2067             runtimeFlags |= Zygote.getMemorySafetyRuntimeFlags(
2068                     definingAppInfo, app.processInfo, instructionSet, mPlatformCompat);
2069 
2070             // the per-user SELinux context must be set
2071             if (TextUtils.isEmpty(app.info.seInfoUser)) {
2072                 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
2073                         new IllegalStateException("SELinux tag not defined for "
2074                                 + app.info.packageName + " (uid " + app.uid + ")"));
2075             }
2076 
2077             String seInfo = updateSeInfo(app);
2078 
2079             // Start the process.  It will either succeed and return a result containing
2080             // the PID of the new process, or else throw a RuntimeException.
2081             final String entryPoint = "android.app.ActivityThread";
2082 
2083             return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
2084                     runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
2085                     instructionSet, invokeWith, startUptime, startElapsedTime);
2086         } catch (RuntimeException e) {
2087             Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
2088 
2089             // Something went very wrong while trying to start this process; one
2090             // common case is when the package is frozen due to an active
2091             // upgrade. To recover, clean up any active bookkeeping related to
2092             // starting this process. (We already invoked this method once when
2093             // the package was initially frozen through KILL_APPLICATION_MSG, so
2094             // it doesn't hurt to use it again.)
2095             mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
2096                     false, false, true, false, false, false, app.userId, "start failure");
2097             return false;
2098         }
2099     }
2100 
2101     @VisibleForTesting
2102     @GuardedBy("mService")
2103     String updateSeInfo(ProcessRecord app) {
2104         String extraInfo = "";
2105         // By the time the first the SDK sandbox process is started, device config service
2106         // should be available. If both Next and Audit are enabled, Next takes precedence.
2107         if (app.isSdkSandbox) {
2108             if (getProcessListSettingsListener().applySdkSandboxRestrictionsNext()) {
2109                 extraInfo = APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS;
2110             } else if (selinuxSdkSandboxAudit()
2111                     && getProcessListSettingsListener().applySdkSandboxRestrictionsAudit()) {
2112                 extraInfo = APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS;
2113             }
2114         }
2115 
2116         // The order of selectors in seInfo matters, the string is terminated by the word complete.
2117         if (selinuxInputSelector()) {
2118             return app.info.seInfo + extraInfo + TextUtils.emptyIfNull(app.info.seInfoUser);
2119         } else {
2120             return app.info.seInfo
2121                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser)
2122                     + extraInfo;
2123         }
2124     }
2125 
2126     @GuardedBy("mService")
2127     boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
2128             int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
2129             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
2130             long startUptime, long startElapsedTime) {
2131         app.setPendingStart(true);
2132         app.setRemoved(false);
2133         synchronized (mProcLock) {
2134             app.setKilledByAm(false);
2135             app.setKilled(false);
2136         }
2137         if (app.getStartSeq() != 0) {
2138             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
2139                     + " with non-zero startSeq:" + app.getStartSeq());
2140         }
2141         if (app.getPid() != 0) {
2142             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
2143                     + " with non-zero pid:" + app.getPid());
2144         }
2145         app.setDisabledCompatChanges(null);
2146         app.setLoggableCompatChanges(null);
2147         if (mPlatformCompat != null) {
2148             app.setDisabledCompatChanges(mPlatformCompat.getDisabledChanges(app.info));
2149             app.setLoggableCompatChanges(mPlatformCompat.getLoggableChanges(app.info));
2150         }
2151         final long startSeq = ++mProcStartSeqCounter;
2152         app.setStartSeq(startSeq);
2153         app.setStartParams(uid, hostingRecord, seInfo, startUptime, startElapsedTime);
2154         app.setUsingWrapper(invokeWith != null
2155                 || Zygote.getWrapProperty(app.processName) != null);
2156         mPendingStarts.put(startSeq, app);
2157 
2158         if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
2159             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
2160                     "Posting procStart msg for " + app.toShortString());
2161             mService.mProcStartHandler.post(() -> handleProcessStart(
2162                     app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
2163                     requiredAbi, instructionSet, invokeWith, startSeq));
2164             return true;
2165         } else {
2166             try {
2167                 final Process.ProcessStartResult startResult = startProcess(hostingRecord,
2168                         entryPoint, app,
2169                         uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
2170                         requiredAbi, instructionSet, invokeWith, startUptime);
2171                 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
2172                         startSeq, false);
2173             } catch (RuntimeException e) {
2174                 Slog.e(ActivityManagerService.TAG, "Failure starting process "
2175                         + app.processName, e);
2176                 app.setPendingStart(false);
2177                 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
2178                         false, false, true, false, false, false, app.userId, "start failure");
2179             }
2180             return app.getPid() > 0;
2181         }
2182     }
2183 
2184     /**
2185      * Main handler routine to start the given process from the ProcStartHandler.
2186      *
2187      * <p>Note: this function doesn't hold the global AM lock intentionally.</p>
2188      */
2189     private void handleProcessStart(final ProcessRecord app, final String entryPoint,
2190             final int[] gids, final int runtimeFlags, int zygotePolicyFlags,
2191             final int mountExternal, final String requiredAbi, final String instructionSet,
2192             final String invokeWith, final long startSeq) {
2193         final Runnable startRunnable = () -> {
2194             try {
2195                 final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(),
2196                         entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags,
2197                         mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith,
2198                         app.getStartTime());
2199 
2200                 synchronized (mService) {
2201                     handleProcessStartedLocked(app, startResult, startSeq);
2202                 }
2203             } catch (RuntimeException e) {
2204                 synchronized (mService) {
2205                     Slog.e(ActivityManagerService.TAG, "Failure starting process "
2206                             + app.processName, e);
2207                     mPendingStarts.remove(startSeq);
2208                     app.setPendingStart(false);
2209                     mService.forceStopPackageLocked(app.info.packageName,
2210                             UserHandle.getAppId(app.uid),
2211                             false, false, true, false, false, false, app.userId, "start failure");
2212                     app.doEarlyCleanupIfNecessaryLocked();
2213                 }
2214             }
2215         };
2216         // Use local reference since we are not using locks here
2217         final ProcessRecord predecessor = app.mPredecessor;
2218         if (predecessor != null && predecessor.getDyingPid() > 0) {
2219             handleProcessStartWithPredecessor(predecessor, startRunnable);
2220         } else {
2221             // Kick off the process start for real.
2222             startRunnable.run();
2223         }
2224     }
2225 
2226     /**
2227      * Handle the case where the given process is killed but still not gone, but we'd need to start
2228      * the new instance of it.
2229      */
2230     private void handleProcessStartWithPredecessor(final ProcessRecord predecessor,
2231             final Runnable successorStartRunnable) {
2232         // If there is a preceding instance of the process, wait for its death with a timeout.
2233         if (predecessor.mSuccessorStartRunnable != null) {
2234             // It's been watched already, this shouldn't happen.
2235             Slog.wtf(TAG, "We've been watching for the death of " + predecessor);
2236             return;
2237         }
2238         predecessor.mSuccessorStartRunnable = successorStartRunnable;
2239         mService.mProcStartHandler.sendMessageDelayed(mService.mProcStartHandler.obtainMessage(
2240                 ProcStartHandler.MSG_PROCESS_KILL_TIMEOUT, predecessor),
2241                 mService.mConstants.mProcessKillTimeoutMs);
2242     }
2243 
2244     static final class ProcStartHandler extends Handler {
2245         static final int MSG_PROCESS_DIED = 1;
2246         static final int MSG_PROCESS_KILL_TIMEOUT = 2;
2247 
2248         private final ActivityManagerService mService;
2249 
2250         ProcStartHandler(ActivityManagerService service, Looper looper) {
2251             super(looper);
2252             mService = service;
2253         }
2254 
2255         @Override
2256         public void handleMessage(Message msg) {
2257             switch (msg.what) {
2258                 case MSG_PROCESS_DIED:
2259                     mService.mProcessList.handlePredecessorProcDied((ProcessRecord) msg.obj);
2260                     break;
2261                 case MSG_PROCESS_KILL_TIMEOUT:
2262                     synchronized (mService) {
2263                         mService.handleProcessStartOrKillTimeoutLocked((ProcessRecord) msg.obj,
2264                                 /* isKillTimeout */ true);
2265                     }
2266                     break;
2267             }
2268         }
2269     }
2270 
2271     /**
2272      * Called when the dying process we're waiting for is really gone.
2273      */
2274     private void handlePredecessorProcDied(ProcessRecord app) {
2275         if (DEBUG_PROCESSES) {
2276             Slog.i(TAG, app.toString() + " is really gone now");
2277         }
2278 
2279         // Now kick off the subsequent process start if there is any.
2280         final Runnable start = app.mSuccessorStartRunnable;
2281         if (start != null) {
2282             app.mSuccessorStartRunnable = null;
2283             start.run();
2284         }
2285     }
2286 
2287     @GuardedBy("mService")
2288     public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) {
2289         final ApplicationInfo appInfo = appZygote.getAppInfo();
2290         ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
2291         if (zygoteProcesses != null && (force || zygoteProcesses.size() == 0)) {
2292             // Only remove if no longer in use now, or forced kill
2293             mAppZygotes.remove(appInfo.processName, appInfo.uid);
2294             mAppZygoteProcesses.remove(appZygote);
2295             mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
2296             appZygote.stopZygote();
2297         }
2298     }
2299 
2300     @GuardedBy("mService")
2301     private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
2302         // Free the isolated uid for this process
2303         final IsolatedUidRange appUidRange =
2304                 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName,
2305                         app.getHostingRecord().getDefiningUid());
2306         if (appUidRange != null) {
2307             appUidRange.freeIsolatedUidLocked(app.uid);
2308         }
2309 
2310         final AppZygote appZygote = mAppZygotes.get(app.info.processName,
2311                 app.getHostingRecord().getDefiningUid());
2312         if (appZygote != null) {
2313             ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
2314             zygoteProcesses.remove(app);
2315             if (zygoteProcesses.size() == 0) {
2316                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG);
2317                 if (app.isRemoved()) {
2318                     // If we stopped this process because the package hosting it was removed,
2319                     // there's no point in delaying the app zygote kill.
2320                     killAppZygoteIfNeededLocked(appZygote, false /* force */);
2321                 } else {
2322                     Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
2323                     msg.obj = appZygote;
2324                     mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS);
2325                 }
2326             }
2327         }
2328     }
2329 
2330     private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
2331         synchronized (mService) {
2332             // The UID for the app zygote should be the UID of the application hosting
2333             // the service.
2334             final int uid = app.getHostingRecord().getDefiningUid();
2335             AppZygote appZygote = mAppZygotes.get(app.info.processName, uid);
2336             final ArrayList<ProcessRecord> zygoteProcessList;
2337             if (appZygote == null) {
2338                 if (DEBUG_PROCESSES) {
2339                     Slog.d(TAG_PROCESSES, "Creating new app zygote.");
2340                 }
2341                 final IsolatedUidRange uidRange =
2342                         mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(
2343                                 app.info.processName, app.getHostingRecord().getDefiningUid());
2344                 final int userId = UserHandle.getUserId(uid);
2345                 // Create the app-zygote and provide it with the UID-range it's allowed
2346                 // to setresuid/setresgid to.
2347                 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
2348                 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
2349                 ApplicationInfo appInfo = new ApplicationInfo(app.info);
2350                 // If this was an external service, the package name and uid in the passed in
2351                 // ApplicationInfo have been changed to match those of the calling package;
2352                 // that is not what we want for the AppZygote though, which needs to have the
2353                 // packageName and uid of the defining application. This is because the
2354                 // preloading only makes sense in the context of the defining application,
2355                 // not the calling one.
2356                 appInfo.packageName = app.getHostingRecord().getDefiningPackageName();
2357                 appInfo.uid = uid;
2358                 appZygote = new AppZygote(appInfo, app.processInfo, uid, firstUid, lastUid);
2359                 mAppZygotes.put(app.info.processName, uid, appZygote);
2360                 zygoteProcessList = new ArrayList<ProcessRecord>();
2361                 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
2362             } else {
2363                 if (DEBUG_PROCESSES) {
2364                     Slog.d(TAG_PROCESSES, "Reusing existing app zygote.");
2365                 }
2366                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
2367                 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
2368             }
2369             // Note that we already add the app to mAppZygoteProcesses here;
2370             // this is so that another thread can't come in and kill the zygote
2371             // before we've even tried to start the process. If the process launch
2372             // goes wrong, we'll clean this up in removeProcessNameLocked()
2373             zygoteProcessList.add(app);
2374 
2375             return appZygote;
2376         }
2377     }
2378 
2379     private Map<String, Pair<String, Long>> getPackageAppDataInfoMap(PackageManagerInternal pmInt,
2380             String[] packages, int uid) {
2381         Map<String, Pair<String, Long>> result = new ArrayMap<>(packages.length);
2382         int userId = UserHandle.getUserId(uid);
2383         for (String packageName : packages) {
2384             final PackageStateInternal packageState = pmInt.getPackageStateInternal(packageName);
2385             if (packageState == null) {
2386                 Slog.w(TAG, "Unknown package:" + packageName);
2387                 continue;
2388             }
2389             String volumeUuid = packageState.getVolumeUuid();
2390             long inode = packageState.getUserStateOrDefault(userId).getCeDataInode();
2391             if (inode == 0) {
2392                 Slog.w(TAG, packageName + " inode == 0 (b/152760674)");
2393                 return null;
2394             }
2395             result.put(packageName, Pair.create(volumeUuid, inode));
2396         }
2397 
2398         return result;
2399     }
2400 
2401     private boolean needsStorageDataIsolation(StorageManagerInternal storageManagerInternal,
2402             ProcessRecord app) {
2403         final int mountMode = app.getMountMode();
2404         return mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid)
2405                 && !storageManagerInternal.isExternalStorageService(app.uid)
2406                 // Special mounting mode doesn't need to have data isolation as they won't
2407                 // access /mnt/user anyway.
2408                 && mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE
2409                 && mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH
2410                 && mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER
2411                 && mountMode != Zygote.MOUNT_EXTERNAL_NONE;
2412     }
2413 
2414     private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
2415             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
2416             int mountExternal, String seInfo, String requiredAbi, String instructionSet,
2417             String invokeWith, long startTime) {
2418         try {
2419             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
2420                     app.processName);
2421             checkSlow(startTime, "startProcess: asking zygote to start proc");
2422             final boolean isTopApp = hostingRecord.isTopApp();
2423             if (isTopApp) {
2424                 // Use has-foreground-activities as a temporary hint so the current scheduling
2425                 // group won't be lost when the process is attaching. The actual state will be
2426                 // refreshed when computing oom-adj.
2427                 app.mState.setHasForegroundActivities(true);
2428             }
2429 
2430             Map<String, Pair<String, Long>> pkgDataInfoMap;
2431             Map<String, Pair<String, Long>> allowlistedAppDataInfoMap;
2432             boolean bindMountAppStorageDirs = false;
2433             boolean bindMountAppsData = mAppDataIsolationEnabled
2434                     && (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid)
2435                         || app.isSdkSandbox)
2436                     && mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info);
2437 
2438             // Get all packages belongs to the same shared uid. sharedPackages is empty array
2439             // if it doesn't have shared uid.
2440             final PackageManagerInternal pmInt = mService.getPackageManagerInternal();
2441 
2442             // In the case of sdk sandbox, the pkgDataInfoMap of only the client app associated with
2443             // the sandbox is required to handle app visibility restrictions for the sandbox.
2444             final String[] targetPackagesList;
2445             if (app.isSdkSandbox) {
2446                 targetPackagesList = new String[]{app.sdkSandboxClientAppPackage};
2447             } else {
2448                 final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage(
2449                         app.info.packageName, app.userId);
2450                 targetPackagesList = sharedPackages.length == 0
2451                         ? new String[]{app.info.packageName} : sharedPackages;
2452             }
2453 
2454             final boolean hasAppStorage = hasAppStorage(pmInt, app.info.packageName);
2455 
2456             pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, targetPackagesList, uid);
2457             if (pkgDataInfoMap == null) {
2458                 // TODO(b/152760674): Handle inode == 0 case properly, now we just give it a
2459                 // tmp free pass.
2460                 bindMountAppsData = false;
2461             }
2462 
2463             // Remove all packages in pkgDataInfoMap from mAppDataIsolationAllowlistedApps, so
2464             // it won't be mounted twice.
2465             final Set<String> allowlistedApps = new ArraySet<>(mAppDataIsolationAllowlistedApps);
2466             for (String pkg : targetPackagesList) {
2467                 allowlistedApps.remove(pkg);
2468             }
2469 
2470             allowlistedAppDataInfoMap = getPackageAppDataInfoMap(pmInt,
2471                     allowlistedApps.toArray(new String[0]), uid);
2472             if (allowlistedAppDataInfoMap == null) {
2473                 // TODO(b/152760674): Handle inode == 0 case properly, now we just give it a
2474                 // tmp free pass.
2475                 bindMountAppsData = false;
2476             }
2477 
2478             if (!hasAppStorage && !app.isSdkSandbox) {
2479                 bindMountAppsData = false;
2480                 pkgDataInfoMap = null;
2481                 allowlistedAppDataInfoMap = null;
2482             }
2483 
2484             int userId = UserHandle.getUserId(uid);
2485             StorageManagerInternal storageManagerInternal = LocalServices.getService(
2486                     StorageManagerInternal.class);
2487             if (needsStorageDataIsolation(storageManagerInternal, app)) {
2488                 // We will run prepareStorageDirs() after we trigger zygote fork, so it won't
2489                 // slow down app starting speed as those dirs might not be cached.
2490                 if (pkgDataInfoMap != null && storageManagerInternal.isFuseMounted(userId)) {
2491                     bindMountAppStorageDirs = true;
2492                 } else {
2493                     // Fuse is not mounted or inode == 0,
2494                     // so we won't mount it in zygote, but resume the mount after unlocking device.
2495                     app.setBindMountPending(true);
2496                     bindMountAppStorageDirs = false;
2497                 }
2498             }
2499 
2500             // If it's an isolated process, it should not even mount its own app data directories,
2501             // since it has no access to them anyway.
2502             if (app.isolated) {
2503                 pkgDataInfoMap = null;
2504                 allowlistedAppDataInfoMap = null;
2505             }
2506 
2507             boolean bindOverrideSysprops = false;
2508             String[] syspropOverridePkgNames = DeviceConfig.getString(
2509                     DeviceConfig.NAMESPACE_APP_COMPAT,
2510                             "appcompat_sysprop_override_pkgs", "").split(",");
2511             String[] pkgs = app.getPackageList();
2512             for (int i = 0; i < pkgs.length; i++) {
2513                 if (ArrayUtils.contains(syspropOverridePkgNames, pkgs[i])) {
2514                     bindOverrideSysprops = true;
2515                     break;
2516                 }
2517             }
2518 
2519             AppStateTracker ast = mService.mServices.mAppStateTracker;
2520             if (ast != null) {
2521                 final boolean inBgRestricted = ast.isAppBackgroundRestricted(
2522                         app.info.uid, app.info.packageName);
2523                 if (inBgRestricted) {
2524                     synchronized (mService) {
2525                         mAppsInBackgroundRestricted.add(app);
2526                     }
2527                 }
2528                 app.mState.setBackgroundRestricted(inBgRestricted);
2529             }
2530 
2531             final Process.ProcessStartResult startResult;
2532             boolean regularZygote = false;
2533             app.mProcessGroupCreated = false;
2534             app.mSkipProcessGroupCreation = false;
2535             long forkTimeNs = SystemClock.uptimeNanos();
2536             if (hostingRecord.usesWebviewZygote()) {
2537                 startResult = startWebView(entryPoint,
2538                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2539                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2540                         app.info.dataDir, null, app.info.packageName,
2541                         app.getDisabledCompatChanges(),
2542                         new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
2543             } else if (hostingRecord.usesAppZygote()) {
2544                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
2545 
2546                 // We can't isolate app data and storage data as parent zygote already did that.
2547                 startResult = appZygote.getProcess().start(entryPoint,
2548                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2549                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2550                         app.info.dataDir, null, app.info.packageName,
2551                         /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
2552                         app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,
2553                         false, false, false,
2554                         new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
2555             } else {
2556                 regularZygote = true;
2557                 startResult = Process.start(entryPoint,
2558                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2559                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2560                         app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
2561                         isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
2562                         allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
2563                         bindOverrideSysprops,
2564                         new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
2565                 // By now the process group should have been created by zygote.
2566                 app.mProcessGroupCreated = true;
2567             }
2568 
2569             if (android.app.Flags.appStartInfoTimestamps()) {
2570                 mAppStartInfoTracker.addTimestampToStart(app, forkTimeNs,
2571                         ApplicationStartInfo.START_TIMESTAMP_FORK);
2572             }
2573 
2574             if (!regularZygote) {
2575                 // webview and app zygote don't have the permission to create the nodes
2576                 synchronized (app) {
2577                     if (!app.mSkipProcessGroupCreation) {
2578                         // If we're not told to skip the process group creation, go create it.
2579                         final int res = Process.createProcessGroup(uid, startResult.pid);
2580                         if (res < 0) {
2581                             if (res == -OsConstants.ESRCH) {
2582                                 Slog.e(ActivityManagerService.TAG,
2583                                         "Unable to create process group for "
2584                                         + app.processName + " (" + startResult.pid + ")");
2585                             } else {
2586                                 throw new AssertionError("Unable to create process group for "
2587                                     + app.processName + " (" + startResult.pid + ")");
2588                             }
2589                         } else {
2590                             app.mProcessGroupCreated = true;
2591                         }
2592                     }
2593                 }
2594             }
2595 
2596             // This runs after Process.start() as this method may block app process starting time
2597             // if dir is not cached. Running this method after Process.start() can make it
2598             // cache the dir asynchronously, so zygote can use it without waiting for it.
2599             if (bindMountAppStorageDirs) {
2600                 storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
2601                         app.processName);
2602             }
2603             checkSlow(startTime, "startProcess: returned from zygote!");
2604             return startResult;
2605         } finally {
2606             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2607         }
2608     }
2609 
2610     private boolean hasAppStorage(PackageManagerInternal pmInt, String packageName) {
2611         final AndroidPackage pkg = pmInt.getPackage(packageName);
2612         if (pkg == null) {
2613             Slog.w(TAG, "Unknown package " + packageName);
2614             return false;
2615         }
2616         final PackageManager.Property noAppStorageProp =
2617                     pkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE);
2618         return noAppStorageProp == null || !noAppStorageProp.getBoolean();
2619     }
2620 
2621     @GuardedBy("mService")
2622     void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, int zygotePolicyFlags) {
2623         startProcessLocked(app, hostingRecord, zygotePolicyFlags, null /* abiOverride */);
2624     }
2625 
2626     @GuardedBy("mService")
2627     boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
2628             int zygotePolicyFlags, String abiOverride) {
2629         return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
2630                 false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
2631                 abiOverride);
2632     }
2633 
2634     @GuardedBy("mService")
2635     ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2636             boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
2637             int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
2638             boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
2639             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2640         long startTime = SystemClock.uptimeMillis();
2641         final long startTimeNs = SystemClock.elapsedRealtimeNanos();
2642         ProcessRecord app;
2643         if (!isolated) {
2644             app = getProcessRecordLocked(processName, info.uid);
2645             checkSlow(startTime, "startProcess: after getProcessRecord");
2646 
2647             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2648                 // If we are in the background, then check to see if this process
2649                 // is bad.  If so, we will just silently fail.
2650                 if (mService.mAppErrors.isBadProcess(processName, info.uid)) {
2651                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2652                             + "/" + processName);
2653                     return null;
2654                 }
2655             } else {
2656                 // When the user is explicitly starting a process, then clear its
2657                 // crash count so that we won't make it bad until they see at
2658                 // least one crash dialog again, and make the process good again
2659                 // if it had been bad.
2660                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2661                         + "/" + processName);
2662                 mService.mAppErrors.resetProcessCrashTime(processName, info.uid);
2663                 if (mService.mAppErrors.isBadProcess(processName, info.uid)) {
2664                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2665                             UserHandle.getUserId(info.uid), info.uid,
2666                             info.processName);
2667                     mService.mAppErrors.clearBadProcess(processName, info.uid);
2668                     if (app != null) {
2669                         app.mErrorState.setBad(false);
2670                     }
2671                 }
2672             }
2673         } else {
2674             // If this is an isolated process, it can't re-use an existing process.
2675             app = null;
2676         }
2677 
2678         // We don't have to do anything more if:
2679         // (1) There is an existing application record; and
2680         // (2) The caller doesn't think it is dead, OR there is no thread
2681         //     object attached to it so we know it couldn't have crashed; and
2682         // (3) There is a pid assigned to it, so it is either starting or
2683         //     already running.
2684         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
2685                 + " app=" + app + " knownToBeDead=" + knownToBeDead
2686                 + " thread=" + (app != null ? app.getThread() : null)
2687                 + " pid=" + (app != null ? app.getPid() : -1));
2688         ProcessRecord predecessor = null;
2689         if (app != null && app.getPid() > 0) {
2690             if ((!knownToBeDead && !app.isKilled()) || app.getThread() == null) {
2691                 // We already have the app running, or are waiting for it to
2692                 // come up (we have a pid but not yet its thread), so keep it.
2693                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
2694                 // If this is a new package in the process, add the package to the list
2695                 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
2696                 checkSlow(startTime, "startProcess: done, added package to proc");
2697                 return app;
2698             }
2699 
2700             // An application record is attached to a previous process,
2701             // clean it up now.
2702             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
2703             checkSlow(startTime, "startProcess: bad proc running, killing");
2704             ProcessList.killProcessGroup(app.uid, app.getPid());
2705             checkSlow(startTime, "startProcess: done killing old proc");
2706 
2707             if (!app.isKilled()) {
2708                 // Throw a wtf if it's not killed
2709                 Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");
2710             } else {
2711                 Slog.w(TAG_PROCESSES, app.toString() + " is attached to a previous process");
2712             }
2713             // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup
2714             // routine of it yet, but we'd set it as the predecessor of the new process.
2715             predecessor = app;
2716             app = null;
2717         } else if (!isolated) {
2718             // This app may have been removed from process name maps, probably because we killed it
2719             // and did the cleanup before the actual death notification. Check the dying processes.
2720             predecessor = mDyingProcesses.get(processName, info.uid);
2721             if (predecessor != null) {
2722                 // The process record could have existed but its pid is set to 0. In this case,
2723                 // the 'app' and 'predecessor' could end up pointing to the same instance;
2724                 // so make sure we check this case here.
2725                 if (app != null && app != predecessor) {
2726                     app.mPredecessor = predecessor;
2727                     predecessor.mSuccessor = app;
2728                 } else {
2729                     app = null;
2730                 }
2731                 Slog.w(TAG_PROCESSES, predecessor.toString() + " is attached to a previous process "
2732                         + predecessor.getDyingPid());
2733             }
2734         }
2735 
2736         if (app == null) {
2737             checkSlow(startTime, "startProcess: creating new process record");
2738             app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox,
2739                     sdkSandboxUid, sdkSandboxClientAppPackage, hostingRecord);
2740             if (app == null) {
2741                 Slog.w(TAG, "Failed making new process record for "
2742                         + processName + "/" + info.uid + " isolated=" + isolated);
2743                 return null;
2744             }
2745             app.mErrorState.setCrashHandler(crashHandler);
2746             app.setIsolatedEntryPoint(entryPoint);
2747             app.setIsolatedEntryPointArgs(entryPointArgs);
2748             if (predecessor != null) {
2749                 app.mPredecessor = predecessor;
2750                 predecessor.mSuccessor = app;
2751             }
2752             checkSlow(startTime, "startProcess: done creating new process record");
2753         } else {
2754             // If this is a new package in the process, add the package to the list
2755             app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
2756             checkSlow(startTime, "startProcess: added package to existing proc");
2757         }
2758 
2759         // If the system is not ready yet, then hold off on starting this
2760         // process until it is.
2761         if (!mService.mProcessesReady
2762                 && !mService.isAllowedWhileBooting(info)
2763                 && !allowWhileBooting) {
2764             if (!mService.mProcessesOnHold.contains(app)) {
2765                 mService.mProcessesOnHold.add(app);
2766             }
2767             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
2768                     "System not ready, putting on hold: " + app);
2769             checkSlow(startTime, "startProcess: returning with proc on hold");
2770             return app;
2771         }
2772 
2773         checkSlow(startTime, "startProcess: stepping in to startProcess");
2774         final boolean success =
2775                 startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
2776         checkSlow(startTime, "startProcess: done starting proc!");
2777         return success ? app : null;
2778     }
2779 
2780     @GuardedBy("mService")
2781     String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
2782         StringBuilder sb = null;
2783         if (app.isKilledByAm()) {
2784             if (sb == null) sb = new StringBuilder();
2785             sb.append("killedByAm=true;");
2786         }
2787         if (mProcessNames.get(app.processName, app.uid) != app) {
2788             if (sb == null) sb = new StringBuilder();
2789             sb.append("No entry in mProcessNames;");
2790         }
2791         if (!app.isPendingStart()) {
2792             if (sb == null) sb = new StringBuilder();
2793             sb.append("pendingStart=false;");
2794         }
2795         if (app.getStartSeq() > expectedStartSeq) {
2796             if (sb == null) sb = new StringBuilder();
2797             sb.append("seq=" + app.getStartSeq() + ",expected=" + expectedStartSeq + ";");
2798         }
2799         try {
2800             AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, app.userId);
2801         } catch (RemoteException e) {
2802             // unexpected; ignore
2803         } catch (SecurityException e) {
2804             if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
2805                 if (sb == null) sb = new StringBuilder();
2806                 sb.append("Package is frozen;");
2807             } else {
2808                 // we're not being started async and so should throw to the caller.
2809                 throw e;
2810             }
2811         }
2812         return sb == null ? null : sb.toString();
2813     }
2814 
2815     @GuardedBy("mService")
2816     private boolean handleProcessStartedLocked(ProcessRecord pending,
2817             Process.ProcessStartResult startResult, long expectedStartSeq) {
2818         // Indicates that this process start has been taken care of.
2819         if (mPendingStarts.get(expectedStartSeq) == null) {
2820             if (pending.getPid() == startResult.pid) {
2821                 pending.setUsingWrapper(startResult.usingWrapper);
2822                 // TODO: Update already existing clients of usingWrapper
2823             }
2824             return false;
2825         }
2826         return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
2827                 expectedStartSeq, false);
2828     }
2829 
2830     @GuardedBy("mService")
2831     boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
2832             long expectedStartSeq, boolean procAttached) {
2833         mPendingStarts.remove(expectedStartSeq);
2834         final String reason = isProcStartValidLocked(app, expectedStartSeq);
2835         if (reason != null) {
2836             Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
2837                     pid
2838                     + ", " + reason);
2839             app.setPendingStart(false);
2840             killProcessQuiet(pid);
2841             final int appPid = app.getPid();
2842             if (appPid != 0) {
2843                 Process.killProcessGroup(app.uid, appPid);
2844             }
2845             noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2846                     ApplicationExitInfo.SUBREASON_INVALID_START, reason);
2847             app.doEarlyCleanupIfNecessaryLocked();
2848             return false;
2849         }
2850         mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2851         checkSlow(app.getStartTime(), "startProcess: done updating battery stats");
2852 
2853         EventLog.writeEvent(EventLogTags.AM_PROC_START,
2854                 UserHandle.getUserId(app.getStartUid()), pid, app.getStartUid(),
2855                 app.processName, app.getHostingRecord().getType(),
2856                 app.getHostingRecord().getName() != null ? app.getHostingRecord().getName() : "");
2857 
2858         try {
2859             AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.info.packageName,
2860                     app.processName, app.uid, app.getSeInfo(), app.info.sourceDir, pid);
2861         } catch (RemoteException ex) {
2862             // Ignore
2863         }
2864 
2865         Watchdog.getInstance().processStarted(app.processName, pid);
2866 
2867         checkSlow(app.getStartTime(), "startProcess: building log message");
2868         StringBuilder buf = mStringBuilder;
2869         buf.setLength(0);
2870         buf.append("Start proc ");
2871         buf.append(pid);
2872         buf.append(':');
2873         buf.append(app.processName);
2874         buf.append('/');
2875         UserHandle.formatUid(buf, app.getStartUid());
2876         if (app.getIsolatedEntryPoint() != null) {
2877             buf.append(" [");
2878             buf.append(app.getIsolatedEntryPoint());
2879             buf.append("]");
2880         }
2881         buf.append(" for ");
2882         buf.append(app.getHostingRecord().getType());
2883         if (app.getHostingRecord().getName() != null) {
2884             buf.append(" ");
2885             buf.append(app.getHostingRecord().getName());
2886         }
2887         mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.getStartUid());
2888         synchronized (mProcLock) {
2889             app.setPid(pid);
2890             app.setUsingWrapper(usingWrapper);
2891             app.setPendingStart(false);
2892         }
2893         checkSlow(app.getStartTime(), "startProcess: starting to update pids map");
2894         ProcessRecord oldApp;
2895         synchronized (mService.mPidsSelfLocked) {
2896             oldApp = mService.mPidsSelfLocked.get(pid);
2897         }
2898         // If there is already an app occupying that pid that hasn't been cleaned up
2899         if (oldApp != null && !app.isolated) {
2900             // Clean up anything relating to this pid first
2901             Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
2902                     + " startSeq:" + app.getStartSeq()
2903                     + " pid:" + pid
2904                     + " belongs to another existing app:" + oldApp.processName
2905                     + " startSeq:" + oldApp.getStartSeq());
2906             mService.cleanUpApplicationRecordLocked(oldApp, pid, false, false, -1,
2907                     true /*replacingPid*/, false /* fromBinderDied */);
2908         }
2909         mService.addPidLocked(app);
2910         synchronized (mService.mPidsSelfLocked) {
2911             if (!procAttached) {
2912                 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2913                 msg.obj = app;
2914                 mService.mHandler.sendMessageDelayed(msg, usingWrapper
2915                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2916             }
2917         }
2918         dispatchProcessStarted(app, pid);
2919         checkSlow(app.getStartTime(), "startProcess: done updating pids map");
2920         return true;
2921     }
2922 
2923     @GuardedBy("mService")
2924     void removeLruProcessLocked(ProcessRecord app) {
2925         int lrui = mLruProcesses.lastIndexOf(app);
2926         if (lrui >= 0) {
2927             synchronized (mProcLock) {
2928                 if (!app.isKilled()) {
2929                     if (app.isPersistent()) {
2930                         Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2931                     } else {
2932                         Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2933                         if (app.getPid() > 0) {
2934                             killProcessQuiet(app.getPid());
2935                             ProcessList.killProcessGroup(app.uid, app.getPid());
2936                             noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2937                                     ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed");
2938                         } else {
2939                             app.setPendingStart(false);
2940                         }
2941                     }
2942                 }
2943                 if (lrui < mLruProcessActivityStart) {
2944                     mLruProcessActivityStart--;
2945                 }
2946                 if (lrui < mLruProcessServiceStart) {
2947                     mLruProcessServiceStart--;
2948                 }
2949                 mLruProcesses.remove(lrui);
2950             }
2951         }
2952         mService.removeOomAdjTargetLocked(app, true);
2953     }
2954 
2955     @GuardedBy({"mService", "mProcLock"})
2956     boolean killPackageProcessesLSP(String packageName, int appId, int userId, int minOomAdj,
2957             int reasonCode, int subReason, String reason) {
2958         return killPackageProcessesLSP(packageName, appId, userId, minOomAdj,
2959                 false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2960                 false /* evenPersistent */, false /* setRemoved */, false /* uninstalling */,
2961                 reasonCode, subReason, reason);
2962     }
2963 
2964     @GuardedBy("mService")
2965     void killAppZygotesLocked(String packageName, int appId, int userId, boolean force) {
2966         // See if there are any app zygotes running for this packageName / UID combination,
2967         // and kill it if so.
2968         final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2969         for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2970             for (int i = 0; i < appZygotes.size(); ++i) {
2971                 final int appZygoteUid = appZygotes.keyAt(i);
2972                 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2973                     continue;
2974                 }
2975                 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2976                     continue;
2977                 }
2978                 final AppZygote appZygote = appZygotes.valueAt(i);
2979                 if (packageName != null
2980                         && !packageName.equals(appZygote.getAppInfo().packageName)) {
2981                     continue;
2982                 }
2983                 zygotesToKill.add(appZygote);
2984             }
2985         }
2986         for (AppZygote appZygote : zygotesToKill) {
2987             killAppZygoteIfNeededLocked(appZygote, force);
2988         }
2989     }
2990 
2991     private static boolean freezePackageCgroup(int packageUID, boolean freeze) {
2992         try {
2993             Process.freezeCgroupUid(packageUID, freeze);
2994         } catch (RuntimeException e) {
2995             final String logtxt = freeze ? "freeze" : "unfreeze";
2996             Slog.e(TAG, "Unable to " + logtxt + " cgroup uid: " + packageUID + ": " + e);
2997             return false;
2998         }
2999         return true;
3000     }
3001 
3002     private static boolean unfreezePackageCgroup(int packageUID) {
3003         return freezePackageCgroup(packageUID, false);
3004     }
3005 
3006     private static void freezeBinderAndPackageCgroup(List<Pair<ProcessRecord, Boolean>> procs,
3007                                                      int packageUID) {
3008         // Freeze all binder processes under the target UID (whose cgroup is about to be frozen).
3009         // Since we're going to kill these, we don't need to unfreze them later.
3010         // The procs list may not include all processes under the UID cgroup, but unincluded
3011         // processes (forks) should not be Binder users.
3012         int N = procs.size();
3013         for (int i = 0; i < N; i++) {
3014             final int pid = procs.get(i).first.getPid();
3015             int nRetries = 0;
3016             if (pid > 0) {
3017                 try {
3018                     int rc;
3019                     do {
3020                         rc = CachedAppOptimizer.freezeBinder(pid, true, 10 /* timeout_ms */);
3021                     } while (rc == -EAGAIN && nRetries++ < 1);
3022                     if (rc != 0) Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + rc);
3023                 } catch (RuntimeException e) {
3024                     Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + e);
3025                 }
3026             }
3027         }
3028 
3029         // We freeze the entire UID (parent) cgroup so that newly-specialized processes also freeze
3030         // despite being added to a child cgroup created after this call that would otherwise be
3031         // unfrozen.
3032         freezePackageCgroup(packageUID, true);
3033     }
3034 
3035     private static List<Pair<ProcessRecord, Boolean>> getUIDSublist(
3036             List<Pair<ProcessRecord, Boolean>> procs, int startIdx) {
3037         final int uid = procs.get(startIdx).first.uid;
3038         int endIdx = startIdx + 1;
3039         while (endIdx < procs.size() && procs.get(endIdx).first.uid == uid) ++endIdx;
3040         return procs.subList(startIdx, endIdx);
3041     }
3042 
3043     @GuardedBy({"mService", "mProcLock"})
3044     boolean killPackageProcessesLSP(String packageName, int appId,
3045             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3046             boolean doit, boolean evenPersistent, boolean setRemoved, boolean uninstalling,
3047             int reasonCode, int subReason, String reason) {
3048         final PackageManagerInternal pm = mService.getPackageManagerInternal();
3049         final ArrayList<Pair<ProcessRecord, Boolean>> procs = new ArrayList<>();
3050 
3051         // Remove all processes this package may have touched: all with the
3052         // same UID (except for the system or root user), and all whose name
3053         // matches the package name.
3054         final int NP = mProcessNames.getMap().size();
3055         for (int ip = 0; ip < NP; ip++) {
3056             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3057             final int NA = apps.size();
3058             for (int ia = 0; ia < NA; ia++) {
3059                 ProcessRecord app = apps.valueAt(ia);
3060                 if (app.isPersistent() && !evenPersistent) {
3061                     // we don't kill persistent processes
3062                     continue;
3063                 }
3064                 if (app.isRemoved()) {
3065                     if (doit) {
3066                         boolean shouldAllowRestart = false;
3067                         if (!uninstalling && packageName != null) {
3068                             // This package has a dependency on the given package being stopped,
3069                             // while it's not being frozen nor uninstalled, allow to restart it.
3070                             shouldAllowRestart = !app.getPkgList().containsKey(packageName)
3071                                     && app.getPkgDeps() != null
3072                                     && app.getPkgDeps().contains(packageName)
3073                                     && app.info != null
3074                                     && !pm.isPackageFrozen(app.info.packageName, app.uid,
3075                                             app.userId);
3076                         }
3077                         procs.add(new Pair<>(app, shouldAllowRestart));
3078                     }
3079                     continue;
3080                 }
3081 
3082                 // Skip process if it doesn't meet our oom adj requirement.
3083                 if (app.mState.getSetAdj() < minOomAdj) {
3084                     // Note it is still possible to have a process with oom adj 0 in the killed
3085                     // processes, but it does not mean misjudgment. E.g. a bound service process
3086                     // and its client activity process are both in the background, so they are
3087                     // collected to be killed. If the client activity is killed first, the service
3088                     // may be scheduled to unbind and become an executing service (oom adj 0).
3089                     continue;
3090                 }
3091 
3092                 boolean shouldAllowRestart = false;
3093 
3094                 // If no package is specified, we call all processes under the
3095                 // given user id.
3096                 if (packageName == null) {
3097                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
3098                         continue;
3099                     }
3100                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
3101                         continue;
3102                     }
3103                     // Package has been specified, we want to hit all processes
3104                     // that match it.  We need to qualify this by the processes
3105                     // that are running under the specified app and user ID.
3106                 } else {
3107                     final boolean isDep = app.getPkgDeps() != null
3108                             && app.getPkgDeps().contains(packageName);
3109                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
3110                         continue;
3111                     }
3112                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
3113                         continue;
3114                     }
3115                     final boolean isInPkgList = app.getPkgList().containsKey(packageName);
3116                     if (!isInPkgList && !isDep) {
3117                         continue;
3118                     }
3119                     if (!isInPkgList && isDep && !uninstalling && app.info != null
3120                             && !pm.isPackageFrozen(app.info.packageName, app.uid, app.userId)) {
3121                         // This package has a dependency on the given package being stopped,
3122                         // while it's not being frozen nor uninstalled, allow to restart it.
3123                         shouldAllowRestart = true;
3124                     }
3125                 }
3126 
3127                 // Process has passed all conditions, kill it!
3128                 if (!doit) {
3129                     return true;
3130                 }
3131                 if (setRemoved) {
3132                     app.setRemoved(true);
3133                 }
3134                 procs.add(new Pair<>(app, shouldAllowRestart));
3135             }
3136         }
3137 
3138         final boolean killingUserApp = appId >= Process.FIRST_APPLICATION_UID
3139                                     && appId <= Process.LAST_APPLICATION_UID;
3140 
3141         if (killingUserApp) {
3142             procs.sort((o1, o2) -> Integer.compare(o1.first.uid, o2.first.uid));
3143         }
3144 
3145         int idx = 0;
3146         while (idx < procs.size()) {
3147             final List<Pair<ProcessRecord, Boolean>> uidProcs = getUIDSublist(procs, idx);
3148             final int packageUID = uidProcs.get(0).first.uid;
3149 
3150             // Do not freeze for system apps or for dependencies of the targeted package, but
3151             // make sure to freeze the targeted package for all users if called with USER_ALL.
3152             final boolean doFreeze = killingUserApp && UserHandle.getAppId(packageUID) == appId;
3153 
3154             if (doFreeze) freezeBinderAndPackageCgroup(uidProcs, packageUID);
3155 
3156             for (Pair<ProcessRecord, Boolean> proc : uidProcs) {
3157                 removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second,
3158                         reasonCode, subReason, reason, !doFreeze /* async */);
3159             }
3160             killAppZygotesLocked(packageName, appId, userId, false /* force */);
3161 
3162             if (doFreeze) unfreezePackageCgroup(packageUID);
3163 
3164             idx += uidProcs.size();
3165         }
3166         mService.updateOomAdjLocked(OOM_ADJ_REASON_PROCESS_END);
3167         return procs.size() > 0;
3168     }
3169 
3170     @GuardedBy("mService")
3171     boolean removeProcessLocked(ProcessRecord app,
3172             boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) {
3173         return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode,
3174                 ApplicationExitInfo.SUBREASON_UNKNOWN, reason, true);
3175     }
3176 
3177     @GuardedBy("mService")
3178     boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
3179             boolean allowRestart, int reasonCode, int subReason, String reason) {
3180         return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode, subReason,
3181                 reason, true);
3182     }
3183 
3184     @GuardedBy("mService")
3185     boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
3186             boolean allowRestart, int reasonCode, int subReason, String reason, boolean async) {
3187         final String name = app.processName;
3188         final int uid = app.uid;
3189         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
3190                 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
3191 
3192         ProcessRecord old = mProcessNames.get(name, uid);
3193         if (old != app) {
3194             // This process is no longer active, so nothing to do.
3195             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
3196             return false;
3197         }
3198         removeProcessNameLocked(name, uid);
3199         mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
3200 
3201         boolean needRestart = false;
3202         final int pid = app.getPid();
3203         if ((pid > 0 && pid != ActivityManagerService.MY_PID)
3204                 || (pid == 0 && app.isPendingStart())) {
3205             if (pid > 0) {
3206                 mService.removePidLocked(pid, app);
3207                 app.setBindMountPending(false);
3208                 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3209                 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3210                 if (app.isolated) {
3211                     mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3212                     mService.getPackageManagerInternal().removeIsolatedUid(app.uid);
3213                 }
3214             }
3215             boolean willRestart = false;
3216             if (app.isPersistent() && !app.isolated) {
3217                 if (!callerWillRestart) {
3218                     willRestart = true;
3219                 } else {
3220                     needRestart = true;
3221                 }
3222             }
3223             app.killLocked(reason, reasonCode, subReason, true, async);
3224             mService.handleAppDiedLocked(app, pid, willRestart, allowRestart,
3225                     false /* fromBinderDied */);
3226             if (willRestart) {
3227                 removeLruProcessLocked(app);
3228                 mService.addAppLocked(app.info, null, false, null /* ABI override */,
3229                         ZYGOTE_POLICY_FLAG_EMPTY);
3230             }
3231         } else {
3232             mRemovedProcesses.add(app);
3233         }
3234 
3235         return needRestart;
3236     }
3237 
3238     @GuardedBy("mService")
3239     void addProcessNameLocked(ProcessRecord proc) {
3240         // We shouldn't already have a process under this name, but just in case we
3241         // need to clean up whatever may be there now.
3242         synchronized (mProcLock) {
3243             ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
3244             if (old == proc && proc.isPersistent()) {
3245                 // We are re-adding a persistent process.  Whatevs!  Just leave it there.
3246                 Slog.w(TAG, "Re-adding persistent process " + proc);
3247                 // Ensure that the mCrashing flag is cleared, since this is a restart
3248                 proc.resetCrashingOnRestart();
3249             } else if (old != null) {
3250                 if (old.isKilled()) {
3251                     // The old process has been killed, we probably haven't had
3252                     // a chance to clean up the old record, just log a warning
3253                     Slog.w(TAG, "Existing proc " + old + " was killed "
3254                             + (SystemClock.uptimeMillis() - old.getKillTime())
3255                             + "ms ago when adding " + proc);
3256                 } else {
3257                     Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
3258                 }
3259             }
3260             UidRecord uidRec = mActiveUids.get(proc.uid);
3261             if (uidRec == null) {
3262                 uidRec = new UidRecord(proc.uid, mService);
3263                 // This is the first appearance of the uid, report it now!
3264                 if (DEBUG_UID_OBSERVERS) {
3265                     Slog.i(TAG_UID_OBSERVERS, "Creating new process uid: " + uidRec);
3266                 }
3267                 if (Arrays.binarySearch(mService.mDeviceIdleTempAllowlist,
3268                             UserHandle.getAppId(proc.uid)) >= 0
3269                         || mService.mPendingTempAllowlist.indexOfKey(proc.uid) >= 0) {
3270                     uidRec.setCurAllowListed(true);
3271                     uidRec.setSetAllowListed(true);
3272                 }
3273                 uidRec.updateHasInternetPermission();
3274                 mActiveUids.put(proc.uid, uidRec);
3275                 EventLogTags.writeAmUidRunning(uidRec.getUid());
3276                 mService.noteUidProcessState(uidRec.getUid(), uidRec.getCurProcState(),
3277                         uidRec.getCurCapability());
3278             }
3279             proc.setUidRecord(uidRec);
3280             uidRec.addProcess(proc);
3281 
3282             // Reset render thread tid if it was already set, so new process can set it again.
3283             proc.setRenderThreadTid(0);
3284             mProcessNames.put(proc.processName, proc.uid, proc);
3285         }
3286         if (proc.isolated) {
3287             mIsolatedProcesses.put(proc.uid, proc);
3288         }
3289         if (proc.isSdkSandbox) {
3290             ArrayList<ProcessRecord> sdkSandboxes = mSdkSandboxes.get(proc.uid);
3291             if (sdkSandboxes == null) {
3292                 sdkSandboxes = new ArrayList<>();
3293             }
3294             sdkSandboxes.add(proc);
3295             mSdkSandboxes.put(Process.getAppUidForSdkSandboxUid(proc.uid), sdkSandboxes);
3296         }
3297     }
3298 
3299     @GuardedBy("mService")
3300     private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
3301             HostingRecord hostingRecord) {
3302         if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
3303             // Allocate an isolated UID from the global range
3304             return mGlobalIsolatedUids;
3305         } else {
3306             return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
3307                     info.processName, hostingRecord.getDefiningUid());
3308         }
3309     }
3310 
3311     ProcessRecord getSharedIsolatedProcess(String processName, int uid, String packageName) {
3312         for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
3313             final ProcessRecord app = mIsolatedProcesses.valueAt(i);
3314             if (app.info.uid == uid && app.info.packageName.equals(packageName)
3315                     && app.processName.equals(processName)) {
3316                 return app;
3317             }
3318         }
3319         return null;
3320     }
3321     @Nullable
3322     @GuardedBy("mService")
3323     List<Integer> getIsolatedProcessesLocked(int uid) {
3324         List<Integer> ret = null;
3325         for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
3326             final ProcessRecord app = mIsolatedProcesses.valueAt(i);
3327             if (app.info.uid == uid) {
3328                 if (ret == null) {
3329                     ret = new ArrayList<>();
3330                 }
3331                 ret.add(app.getPid());
3332             }
3333         }
3334         return ret;
3335     }
3336 
3337     /**
3338      * Returns the associated SDK sandbox processes for a UID. Note that this does
3339      * NOT return a copy, so callers should not modify the result, or use it outside
3340      * of the lock scope.
3341      *
3342      * @param uid UID to return sansdbox processes for
3343      */
3344     @Nullable
3345     @GuardedBy("mService")
3346     List<ProcessRecord> getSdkSandboxProcessesForAppLocked(int uid) {
3347         return mSdkSandboxes.get(uid);
3348     }
3349 
3350     @GuardedBy("mService")
3351     ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
3352             boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid,
3353             String sdkSandboxClientAppPackage, HostingRecord hostingRecord) {
3354         String proc = customProcess != null ? customProcess : info.processName;
3355         final int userId = UserHandle.getUserId(info.uid);
3356         int uid = info.uid;
3357         if (isSdkSandbox) {
3358             uid = sdkSandboxUid;
3359         }
3360         if (Process.isSdkSandboxUid(uid) && (!isSdkSandbox || sdkSandboxClientAppPackage == null)) {
3361             Slog.e(TAG, "Abort creating new sandbox process as required parameters are missing.");
3362             return null;
3363         }
3364         if (isolated) {
3365             if (isolatedUid == 0) {
3366                 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
3367                 if (uidRange == null) {
3368                     return null;
3369                 }
3370                 uid = uidRange.allocateIsolatedUidLocked(userId);
3371                 if (uid == -1) {
3372                     return null;
3373                 }
3374             } else {
3375                 // Special case for startIsolatedProcess (internal only), where
3376                 // the uid of the isolated process is specified by the caller.
3377                 uid = isolatedUid;
3378             }
3379             mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid);
3380             mService.getPackageManagerInternal().addIsolatedUid(uid, info.uid);
3381 
3382             // Register the isolated UID with this application so BatteryStats knows to
3383             // attribute resource usage to the application.
3384             //
3385             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
3386             // about the process state of the isolated UID *before* it is registered with the
3387             // owning application.
3388             mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
3389         }
3390         final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,
3391                 sdkSandboxClientAppPackage,
3392                 hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());
3393         final ProcessStateRecord state = r.mState;
3394 
3395         final boolean wasStopped = (info.flags & ApplicationInfo.FLAG_STOPPED) != 0;
3396         // Check if we should mark the processrecord for first launch after force-stopping
3397         if (wasStopped) {
3398             // Check if the hosting record is for an activity or not. Since the stopped
3399             // state tracking is handled differently to avoid WM calling back into AM,
3400             // store the state in the correct record
3401             if (hostingRecord.isTypeActivity()) {
3402                 final boolean wasPackageEverLaunched = mService
3403                         .wasPackageEverLaunched(r.getApplicationInfo().packageName, r.userId);
3404                 // If the package was launched in the past but is currently stopped, only then
3405                 // should it be considered as force-stopped.
3406                 @WindowProcessController.StoppedState int stoppedState = wasPackageEverLaunched
3407                         ? STOPPED_STATE_FORCE_STOPPED
3408                         : STOPPED_STATE_FIRST_LAUNCH;
3409                 r.getWindowProcessController().setStoppedState(stoppedState);
3410             } else {
3411                 r.setWasForceStopped(true);
3412                 // first launch is computed just before logging, for non-activity types
3413             }
3414         }
3415 
3416         if (!isolated && !isSdkSandbox
3417                 && userId == UserHandle.USER_SYSTEM
3418                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK
3419                 && (TextUtils.equals(proc, info.processName))) {
3420             // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
3421             state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
3422             state.setSetSchedGroup(ProcessList.SCHED_GROUP_DEFAULT);
3423             r.setPersistent(true);
3424             state.setMaxAdj(ProcessList.PERSISTENT_PROC_ADJ);
3425         }
3426         if (isolated && isolatedUid != 0) {
3427             // Special case for startIsolatedProcess (internal only) - assume the process
3428             // is required by the system server to prevent it being killed.
3429             state.setMaxAdj(ProcessList.PERSISTENT_SERVICE_ADJ);
3430         }
3431         addProcessNameLocked(r);
3432         return r;
3433     }
3434 
3435     @GuardedBy("mService")
3436     ProcessRecord removeProcessNameLocked(final String name, final int uid) {
3437         return removeProcessNameLocked(name, uid, null);
3438     }
3439 
3440     @GuardedBy("mService")
3441     ProcessRecord removeProcessNameLocked(final String name, final int uid,
3442             final ProcessRecord expecting) {
3443         ProcessRecord old = mProcessNames.get(name, uid);
3444         final ProcessRecord record = expecting != null ? expecting : old;
3445         synchronized (mProcLock) {
3446             // Only actually remove when the currently recorded value matches the
3447             // record that we expected; if it doesn't match then we raced with a
3448             // newly created process and we don't want to destroy the new one.
3449             if ((expecting == null) || (old == expecting)) {
3450                 mProcessNames.remove(name, uid);
3451             }
3452             if (record != null) {
3453                 final UidRecord uidRecord = record.getUidRecord();
3454                 if (uidRecord != null) {
3455                     uidRecord.removeProcess(record);
3456                     if (uidRecord.getNumOfProcs() == 0) {
3457                         // No more processes using this uid, tell clients it is gone.
3458                         if (DEBUG_UID_OBSERVERS) {
3459                             Slog.i(TAG_UID_OBSERVERS, "No more processes in " + uidRecord);
3460                         }
3461                         mService.enqueueUidChangeLocked(uidRecord, -1,
3462                                 UidRecord.CHANGE_GONE | UidRecord.CHANGE_PROCSTATE);
3463                         EventLogTags.writeAmUidStopped(uid);
3464                         mActiveUids.remove(uid);
3465                         mService.mFgsStartTempAllowList.removeUid(record.info.uid);
3466                         mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
3467                                 ActivityManager.PROCESS_CAPABILITY_NONE);
3468                     }
3469                     record.setUidRecord(null);
3470                 }
3471             }
3472         }
3473         mIsolatedProcesses.remove(uid);
3474         mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
3475         // Remove the (expected) ProcessRecord from the app zygote
3476         if (record != null && record.appZygote) {
3477             removeProcessFromAppZygoteLocked(record);
3478         }
3479         if (record != null && record.isSdkSandbox) {
3480             final int appUid = Process.getAppUidForSdkSandboxUid(uid);
3481             final ArrayList<ProcessRecord> sdkSandboxesForUid = mSdkSandboxes.get(appUid);
3482             if (sdkSandboxesForUid != null) {
3483                 sdkSandboxesForUid.remove(record);
3484                 if (sdkSandboxesForUid.size() == 0) {
3485                     mSdkSandboxes.remove(appUid);
3486                 }
3487             }
3488         }
3489         mAppsInBackgroundRestricted.remove(record);
3490 
3491         return old;
3492     }
3493 
3494     /** Call setCoreSettings on all LRU processes, with the new settings. */
3495     @GuardedBy(anyOf = {"mService", "mProcLock"})
3496     void updateCoreSettingsLOSP(Bundle settings) {
3497         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3498             ProcessRecord processRecord = mLruProcesses.get(i);
3499             final IApplicationThread thread = processRecord.getThread();
3500             try {
3501                 if (thread != null) {
3502                     thread.setCoreSettings(settings);
3503                 }
3504             } catch (RemoteException re) {
3505                 /* ignore */
3506             }
3507         }
3508     }
3509 
3510     /**
3511      * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
3512      * procstate lower than maxProcState.
3513      * @param minTargetSdk
3514      * @param maxProcState
3515      */
3516     @GuardedBy({"mService", "mProcLock"})
3517     void killAllBackgroundProcessesExceptLSP(int minTargetSdk, int maxProcState) {
3518         final ArrayList<ProcessRecord> procs = new ArrayList<>();
3519         final int NP = mProcessNames.getMap().size();
3520         for (int ip = 0; ip < NP; ip++) {
3521             final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3522             final int NA = apps.size();
3523             for (int ia = 0; ia < NA; ia++) {
3524                 final ProcessRecord app = apps.valueAt(ia);
3525                 if (app.isRemoved()
3526                         || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
3527                         && (maxProcState < 0 || app.mState.getSetProcState() > maxProcState))) {
3528                     procs.add(app);
3529                 }
3530             }
3531         }
3532 
3533         final int N = procs.size();
3534         for (int i = 0; i < N; i++) {
3535             removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER,
3536                     ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except");
3537         }
3538     }
3539 
3540     /**
3541      * Call updateTimePrefs on all LRU processes
3542      * @param timePref The time pref to pass to each process
3543      */
3544     @GuardedBy(anyOf = {"mService", "mProcLock"})
3545     void updateAllTimePrefsLOSP(int timePref) {
3546         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3547             ProcessRecord r = mLruProcesses.get(i);
3548             final IApplicationThread thread = r.getThread();
3549             if (thread != null) {
3550                 try {
3551                     thread.updateTimePrefs(timePref);
3552                 } catch (RemoteException ex) {
3553                     Slog.w(TAG, "Failed to update preferences for: "
3554                             + r.info.processName);
3555                 }
3556             }
3557         }
3558     }
3559 
3560     void setAllHttpProxy() {
3561         // Update the HTTP proxy for each application thread.
3562         synchronized (mProcLock) {
3563             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
3564                 ProcessRecord r = mLruProcesses.get(i);
3565                 IApplicationThread thread = r.getThread();
3566                 // Don't dispatch to isolated processes as they can't access ConnectivityManager and
3567                 // don't have network privileges anyway. Exclude system server and update it
3568                 // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
3569                 if (r.getPid() != ActivityManagerService.MY_PID && thread != null && !r.isolated) {
3570                     try {
3571                         thread.updateHttpProxy();
3572                     } catch (RemoteException ex) {
3573                         Slog.w(TAG, "Failed to update http proxy for: "
3574                                 + r.info.processName);
3575                     }
3576                 }
3577             }
3578         }
3579         ActivityThread.updateHttpProxy(mService.mContext);
3580     }
3581 
3582     @GuardedBy(anyOf = {"mService", "mProcLock"})
3583     void clearAllDnsCacheLOSP() {
3584         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3585             ProcessRecord r = mLruProcesses.get(i);
3586             final IApplicationThread thread = r.getThread();
3587             if (thread != null) {
3588                 try {
3589                     thread.clearDnsCache();
3590                 } catch (RemoteException ex) {
3591                     Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
3592                 }
3593             }
3594         }
3595     }
3596 
3597     @GuardedBy(anyOf = {"mService", "mProcLock"})
3598     void handleAllTrustStorageUpdateLOSP() {
3599         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3600             ProcessRecord r = mLruProcesses.get(i);
3601             final IApplicationThread thread = r.getThread();
3602             if (thread != null) {
3603                 try {
3604                     thread.handleTrustStorageUpdate();
3605                 } catch (RemoteException ex) {
3606                     Slog.w(TAG, "Failed to handle trust storage update for: " +
3607                             r.info.processName);
3608                 }
3609             }
3610         }
3611     }
3612 
3613     @GuardedBy({"mService", "mProcLock"})
3614     private int updateLruProcessInternalLSP(ProcessRecord app, long now, int index,
3615             int lruSeq, String what, Object obj, ProcessRecord srcApp) {
3616         app.setLastActivityTime(now);
3617 
3618         if (app.hasActivitiesOrRecentTasks()) {
3619             // Don't want to touch dependent processes that are hosting activities.
3620             return index;
3621         }
3622 
3623         int lrui = mLruProcesses.lastIndexOf(app);
3624         if (lrui < 0) {
3625             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3626                     + what + " " + obj + " from " + srcApp);
3627             return index;
3628         }
3629 
3630         if (lrui >= index) {
3631             // Don't want to cause this to move dependent processes *back* in the
3632             // list as if they were less frequently used.
3633             return index;
3634         }
3635 
3636         if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
3637             // Don't want to touch dependent processes that are hosting activities.
3638             return index;
3639         }
3640 
3641         mLruProcesses.remove(lrui);
3642         if (index > 0) {
3643             index--;
3644         }
3645         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3646                 + " in LRU list: " + app);
3647         mLruProcesses.add(index, app);
3648         app.setLruSeq(lruSeq);
3649         return index;
3650     }
3651 
3652     /**
3653      * Handle the case where we are inserting a process hosting client activities:
3654      * Make sure any groups have their order match their importance, and take care of
3655      * distributing old clients across other activity processes so they can't spam
3656      * the LRU list.  Processing of the list will be restricted by the indices provided,
3657      * and not extend out of them.
3658      *
3659      * @param topApp The app at the top that has just been inserted in to the list.
3660      * @param topI The position in the list where topApp was inserted; this is the start (at the
3661      *             top) where we are going to do our processing.
3662      * @param bottomI The last position at which we will be processing; this is the end position
3663      *                of whichever section of the LRU list we are in.  Nothing past it will be
3664      *                touched.
3665      * @param endIndex The current end of the top being processed.  Typically topI - 1.  That is,
3666      *                 where we are going to start potentially adjusting other entries in the list.
3667      */
3668     @GuardedBy({"mService", "mProcLock"})
3669     private void updateClientActivitiesOrderingLSP(final ProcessRecord topApp, final int topI,
3670             final int bottomI, int endIndex) {
3671         final ProcessServiceRecord topPsr = topApp.mServices;
3672         if (topApp.hasActivitiesOrRecentTasks() || topPsr.isTreatedLikeActivity()
3673                 || !topPsr.hasClientActivities()) {
3674             // If this is not a special process that has client activities, then there is
3675             // nothing to do.
3676             return;
3677         }
3678 
3679         final int uid = topApp.info.uid;
3680         final int topConnectionGroup = topPsr.getConnectionGroup();
3681         if (topConnectionGroup > 0) {
3682             int endImportance = topPsr.getConnectionImportance();
3683             for (int i = endIndex; i >= bottomI; i--) {
3684                 final ProcessRecord subProc = mLruProcesses.get(i);
3685                 final ProcessServiceRecord subPsr = subProc.mServices;
3686                 final int subConnectionGroup = subPsr.getConnectionGroup();
3687                 final int subConnectionImportance = subPsr.getConnectionImportance();
3688                 if (subProc.info.uid == uid
3689                         && subConnectionGroup == topConnectionGroup) {
3690                     if (i == endIndex && subConnectionImportance >= endImportance) {
3691                         // This process is already in the group, and its importance
3692                         // is not as strong as the process before it, so keep it
3693                         // correctly positioned in the group.
3694                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3695                                 "Keeping in-place above " + subProc
3696                                         + " endImportance=" + endImportance
3697                                         + " group=" + subConnectionGroup
3698                                         + " importance=" + subConnectionImportance);
3699                         endIndex--;
3700                         endImportance = subConnectionImportance;
3701                     } else {
3702                         // We want to pull this up to be with the rest of the group,
3703                         // and order within the group by importance.
3704                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3705                                 "Pulling up " + subProc
3706                                         + " to position in group with importance="
3707                                         + subConnectionImportance);
3708                         boolean moved = false;
3709                         for (int pos = topI; pos > endIndex; pos--) {
3710                             final ProcessRecord posProc = mLruProcesses.get(pos);
3711                             if (subConnectionImportance
3712                                     <= posProc.mServices.getConnectionImportance()) {
3713                                 mLruProcesses.remove(i);
3714                                 mLruProcesses.add(pos, subProc);
3715                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3716                                         "Moving " + subProc
3717                                                 + " from position " + i + " to above " + posProc
3718                                                 + " @ " + pos);
3719                                 moved = true;
3720                                 endIndex--;
3721                                 break;
3722                             }
3723                         }
3724                         if (!moved) {
3725                             // Goes to the end of the group.
3726                             mLruProcesses.remove(i);
3727                             mLruProcesses.add(endIndex, subProc);
3728                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3729                                     "Moving " + subProc
3730                                             + " from position " + i + " to end of group @ "
3731                                             + endIndex);
3732                             endIndex--;
3733                             endImportance = subConnectionImportance;
3734                         }
3735                     }
3736                 }
3737             }
3738 
3739         }
3740         // To keep it from spamming the LRU list (by making a bunch of clients),
3741         // we will distribute other entries owned by it to be in-between other apps.
3742         int i = endIndex;
3743         while (i >= bottomI) {
3744             ProcessRecord subProc = mLruProcesses.get(i);
3745             final ProcessServiceRecord subPsr = subProc.mServices;
3746             final int subConnectionGroup = subPsr.getConnectionGroup();
3747             if (DEBUG_LRU) Slog.d(TAG_LRU,
3748                     "Looking to spread old procs, at " + subProc + " @ " + i);
3749             if (subProc.info.uid != uid) {
3750                 // This is a different app...  if we have gone through some of the
3751                 // target app, pull this up to be before them.  We want to pull up
3752                 // one activity process, but any number of non-activity processes.
3753                 if (i < endIndex) {
3754                     boolean hasActivity = false;
3755                     int connUid = 0;
3756                     int connGroup = 0;
3757                     while (i >= bottomI) {
3758                         mLruProcesses.remove(i);
3759                         mLruProcesses.add(endIndex, subProc);
3760                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3761                                 "Different app, moving to " + endIndex);
3762                         i--;
3763                         if (i < bottomI) {
3764                             break;
3765                         }
3766                         subProc = mLruProcesses.get(i);
3767                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3768                                 "Looking at next app at " + i + ": " + subProc);
3769                         if (subProc.hasActivitiesOrRecentTasks()
3770                                 || subPsr.isTreatedLikeActivity()) {
3771                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3772                                     "This is hosting an activity!");
3773                             if (hasActivity) {
3774                                 // Already found an activity, done.
3775                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3776                                         "Already found an activity, done");
3777                                 break;
3778                             }
3779                             hasActivity = true;
3780                         } else if (subPsr.hasClientActivities()) {
3781                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3782                                     "This is a client of an activity");
3783                             if (hasActivity) {
3784                                 if (connUid == 0 || connUid != subProc.info.uid) {
3785                                     // Already have an activity that is not from from a client
3786                                     // connection or is a different client connection, done.
3787                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
3788                                             "Already found a different activity: connUid="
3789                                             + connUid + " uid=" + subProc.info.uid);
3790                                     break;
3791                                 } else if (connGroup == 0 || connGroup != subConnectionGroup) {
3792                                     // Previously saw a different group or not from a group,
3793                                     // want to treat these as different things.
3794                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
3795                                             "Already found a different group: connGroup="
3796                                             + connGroup + " group=" + subConnectionGroup);
3797                                     break;
3798                                 }
3799                             } else {
3800                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3801                                         "This is an activity client!  uid="
3802                                         + subProc.info.uid + " group=" + subConnectionGroup);
3803                                 hasActivity = true;
3804                                 connUid = subProc.info.uid;
3805                                 connGroup = subConnectionGroup;
3806                             }
3807                         }
3808                         endIndex--;
3809                     }
3810                 }
3811                 // Find the end of the next group of processes for target app.  This
3812                 // is after any entries of different apps (so we don't change the existing
3813                 // relative order of apps) and then after the next last group of processes
3814                 // of the target app.
3815                 for (endIndex--; endIndex >= bottomI; endIndex--) {
3816                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
3817                     if (endProc.info.uid == uid) {
3818                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3819                                 "Found next group of app: " + endProc + " @ "
3820                                         + endIndex);
3821                         break;
3822                     }
3823                 }
3824                 if (endIndex >= bottomI) {
3825                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
3826                     final ProcessServiceRecord endPsr = endProc.mServices;
3827                     final int endConnectionGroup = endPsr.getConnectionGroup();
3828                     for (endIndex--; endIndex >= bottomI; endIndex--) {
3829                         final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
3830                         final int nextConnectionGroup = nextEndProc.mServices.getConnectionGroup();
3831                         if (nextEndProc.info.uid != uid
3832                                 || nextConnectionGroup != endConnectionGroup) {
3833                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3834                                     "Found next group or app: " + nextEndProc + " @ "
3835                                             + endIndex + " group=" + nextConnectionGroup);
3836                             break;
3837                         }
3838                     }
3839                 }
3840                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3841                         "Bumping scan position to " + endIndex);
3842                 i = endIndex;
3843             } else {
3844                 i--;
3845             }
3846         }
3847     }
3848 
3849     @GuardedBy("mService")
3850     void updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client) {
3851         final ProcessServiceRecord psr = app.mServices;
3852         final boolean hasActivity = app.hasActivitiesOrRecentTasks() || psr.hasClientActivities()
3853                 || psr.isTreatedLikeActivity();
3854         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3855         if (!activityChange && hasActivity) {
3856             // The process has activities, so we are only allowing activity-based adjustments
3857             // to move it.  It should be kept in the front of the list with other
3858             // processes that have activities, and we don't want those to change their
3859             // order except due to activity operations.
3860             return;
3861         }
3862 
3863         if (app.getPid() == 0 && !app.isPendingStart()) {
3864             // This process has been killed and its cleanup is done, don't proceed the LRU update.
3865             return;
3866         }
3867 
3868         synchronized (mProcLock) {
3869             updateLruProcessLSP(app, client, hasActivity, hasService);
3870         }
3871     }
3872 
3873     @GuardedBy({"mService", "mProcLock"})
3874     private void updateLruProcessLSP(ProcessRecord app, ProcessRecord client,
3875             boolean hasActivity, boolean hasService) {
3876         mLruSeq++;
3877         final long now = SystemClock.uptimeMillis();
3878         final ProcessServiceRecord psr = app.mServices;
3879         app.setLastActivityTime(now);
3880 
3881         // First a quick reject: if the app is already at the position we will
3882         // put it, then there is nothing to do.
3883         if (hasActivity) {
3884             final int N = mLruProcesses.size();
3885             if (N > 0 && mLruProcesses.get(N - 1) == app) {
3886                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3887                 return;
3888             }
3889         } else {
3890             if (mLruProcessServiceStart > 0
3891                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3892                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3893                 return;
3894             }
3895         }
3896 
3897         int lrui = mLruProcesses.lastIndexOf(app);
3898 
3899         if (app.isPersistent() && lrui >= 0) {
3900             // We don't care about the position of persistent processes, as long as
3901             // they are in the list.
3902             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3903             return;
3904         }
3905 
3906         /* In progress: compute new position first, so we can avoid doing work
3907            if the process is not actually going to move.  Not yet working.
3908         int addIndex;
3909         int nextIndex;
3910         boolean inActivity = false, inService = false;
3911         if (hasActivity) {
3912             // Process has activities, put it at the very tipsy-top.
3913             addIndex = mLruProcesses.size();
3914             nextIndex = mLruProcessServiceStart;
3915             inActivity = true;
3916         } else if (hasService) {
3917             // Process has services, put it at the top of the service list.
3918             addIndex = mLruProcessActivityStart;
3919             nextIndex = mLruProcessServiceStart;
3920             inActivity = true;
3921             inService = true;
3922         } else  {
3923             // Process not otherwise of interest, it goes to the top of the non-service area.
3924             addIndex = mLruProcessServiceStart;
3925             if (client != null) {
3926                 int clientIndex = mLruProcesses.lastIndexOf(client);
3927                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3928                         + app);
3929                 if (clientIndex >= 0 && addIndex > clientIndex) {
3930                     addIndex = clientIndex;
3931                 }
3932             }
3933             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3934         }
3935 
3936         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3937                 + mLruProcessActivityStart + "): " + app);
3938         */
3939 
3940         if (lrui >= 0) {
3941             if (lrui < mLruProcessActivityStart) {
3942                 mLruProcessActivityStart--;
3943             }
3944             if (lrui < mLruProcessServiceStart) {
3945                 mLruProcessServiceStart--;
3946             }
3947             /*
3948             if (addIndex > lrui) {
3949                 addIndex--;
3950             }
3951             if (nextIndex > lrui) {
3952                 nextIndex--;
3953             }
3954             */
3955             mLruProcesses.remove(lrui);
3956         }
3957 
3958         /*
3959         mLruProcesses.add(addIndex, app);
3960         if (inActivity) {
3961             mLruProcessActivityStart++;
3962         }
3963         if (inService) {
3964             mLruProcessActivityStart++;
3965         }
3966         */
3967 
3968         int nextIndex;
3969         int nextActivityIndex = -1;
3970         if (hasActivity) {
3971             final int N = mLruProcesses.size();
3972             nextIndex = mLruProcessServiceStart;
3973             if (!app.hasActivitiesOrRecentTasks() && !psr.isTreatedLikeActivity()
3974                     && mLruProcessActivityStart < (N - 1)) {
3975                 // Process doesn't have activities, but has clients with
3976                 // activities...  move it up, but below the app that is binding to it.
3977                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3978                         "Adding to second-top of LRU activity list: " + app
3979                         + " group=" + psr.getConnectionGroup()
3980                         + " importance=" + psr.getConnectionImportance());
3981                 int pos = N - 1;
3982                 while (pos > mLruProcessActivityStart) {
3983                     final ProcessRecord posproc = mLruProcesses.get(pos);
3984                     if (posproc.info.uid == app.info.uid) {
3985                         // Technically this app could have multiple processes with different
3986                         // activities and so we should be looking for the actual process that
3987                         // is bound to the target proc...  but I don't really care, do you?
3988                         break;
3989                     }
3990                     pos--;
3991                 }
3992                 mLruProcesses.add(pos, app);
3993                 // If this process is part of a group, need to pull up any other processes
3994                 // in that group to be with it.
3995                 int endIndex = pos - 1;
3996                 if (endIndex < mLruProcessActivityStart) {
3997                     endIndex = mLruProcessActivityStart;
3998                 }
3999                 nextActivityIndex = endIndex;
4000                 updateClientActivitiesOrderingLSP(app, pos, mLruProcessActivityStart, endIndex);
4001             } else {
4002                 // Process has activities, put it at the very tipsy-top.
4003                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
4004                 mLruProcesses.add(app);
4005                 nextActivityIndex = mLruProcesses.size() - 1;
4006             }
4007         } else if (hasService) {
4008             // Process has services, put it at the top of the service list.
4009             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
4010             mLruProcesses.add(mLruProcessActivityStart, app);
4011             nextIndex = mLruProcessServiceStart;
4012             mLruProcessActivityStart++;
4013         } else  {
4014             // Process not otherwise of interest, it goes to the top of the non-service area.
4015             int index = mLruProcessServiceStart;
4016             if (client != null) {
4017                 // If there is a client, don't allow the process to be moved up higher
4018                 // in the list than that client.
4019                 int clientIndex = mLruProcesses.lastIndexOf(client);
4020                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
4021                         + " when updating " + app);
4022                 if (clientIndex <= lrui) {
4023                     // Don't allow the client index restriction to push it down farther in the
4024                     // list than it already is.
4025                     clientIndex = lrui;
4026                 }
4027                 if (clientIndex >= 0 && index > clientIndex) {
4028                     index = clientIndex;
4029                 }
4030             }
4031             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
4032             mLruProcesses.add(index, app);
4033             nextIndex = index - 1;
4034             mLruProcessActivityStart++;
4035             mLruProcessServiceStart++;
4036             if (index > 1) {
4037                 updateClientActivitiesOrderingLSP(app, mLruProcessServiceStart - 1, 0, index - 1);
4038             }
4039         }
4040 
4041         app.setLruSeq(mLruSeq);
4042 
4043         // If the app is currently using a content provider or service,
4044         // bump those processes as well.
4045         for (int j = psr.numberOfConnections() - 1; j >= 0; j--) {
4046             ConnectionRecord cr = psr.getConnectionAt(j);
4047             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
4048                     && cr.binding.service.app != null
4049                     && cr.binding.service.app.getLruSeq() != mLruSeq
4050                     && cr.notHasFlag(Context.BIND_REDUCTION_FLAGS)
4051                     && !cr.binding.service.app.isPersistent()) {
4052                 if (cr.binding.service.app.mServices.hasClientActivities()) {
4053                     if (nextActivityIndex >= 0) {
4054                         nextActivityIndex = updateLruProcessInternalLSP(cr.binding.service.app,
4055                                 now,
4056                                 nextActivityIndex, mLruSeq,
4057                                 "service connection", cr, app);
4058                     }
4059                 } else {
4060                     nextIndex = updateLruProcessInternalLSP(cr.binding.service.app,
4061                             now,
4062                             nextIndex, mLruSeq,
4063                             "service connection", cr, app);
4064                 }
4065             }
4066         }
4067         final ProcessProviderRecord ppr = app.mProviders;
4068         for (int j = ppr.numberOfProviderConnections() - 1; j >= 0; j--) {
4069             ContentProviderRecord cpr = ppr.getProviderConnectionAt(j).provider;
4070             if (cpr.proc != null && cpr.proc.getLruSeq() != mLruSeq && !cpr.proc.isPersistent()) {
4071                 nextIndex = updateLruProcessInternalLSP(cpr.proc, now, nextIndex, mLruSeq,
4072                         "provider reference", cpr, app);
4073             }
4074         }
4075     }
4076 
4077     @GuardedBy(anyOf = {"mService", "mProcLock"})
4078     ProcessRecord getLRURecordForAppLOSP(IApplicationThread thread) {
4079         if (thread == null) {
4080             return null;
4081         }
4082         return getLRURecordForAppLOSP(thread.asBinder());
4083     }
4084 
4085     @GuardedBy(anyOf = {"mService", "mProcLock"})
4086     ProcessRecord getLRURecordForAppLOSP(IBinder threadBinder) {
4087         if (threadBinder == null) {
4088             return null;
4089         }
4090         // Find the application record.
4091         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4092             final ProcessRecord rec = mLruProcesses.get(i);
4093             final IApplicationThread t = rec.getThread();
4094             if (t != null && t.asBinder() == threadBinder) {
4095                 return rec;
4096             }
4097         }
4098         return null;
4099     }
4100 
4101     @GuardedBy(anyOf = {"mService", "mProcLock"})
4102     boolean haveBackgroundProcessLOSP() {
4103         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4104             final ProcessRecord rec = mLruProcesses.get(i);
4105             if (rec.getThread() != null
4106                     && rec.mState.getSetProcState() >= PROCESS_STATE_CACHED_ACTIVITY) {
4107                 return true;
4108             }
4109         }
4110         return false;
4111     }
4112 
4113     private static int procStateToImportance(int procState, int memAdj,
4114             ActivityManager.RunningAppProcessInfo currApp,
4115             int clientTargetSdk) {
4116         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
4117                 procState, clientTargetSdk);
4118         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
4119             currApp.lru = memAdj;
4120         } else {
4121             currApp.lru = 0;
4122         }
4123         return imp;
4124     }
4125 
4126     @GuardedBy(anyOf = {"mService", "mProcLock"})
4127     void fillInProcMemInfoLOSP(ProcessRecord app,
4128             ActivityManager.RunningAppProcessInfo outInfo,
4129             int clientTargetSdk) {
4130         outInfo.pid = app.getPid();
4131         outInfo.uid = app.info.uid;
4132         if (app.getWindowProcessController().isHeavyWeightProcess()) {
4133             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
4134         }
4135         if (app.isPersistent()) {
4136             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
4137         }
4138         if (app.hasActivities()) {
4139             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
4140         }
4141         outInfo.lastTrimLevel = app.mProfile.getTrimMemoryLevel();
4142         final ProcessStateRecord state = app.mState;
4143         int adj = state.getCurAdj();
4144         int procState = state.getCurProcState();
4145         outInfo.importance = procStateToImportance(procState, adj, outInfo,
4146                 clientTargetSdk);
4147         outInfo.importanceReasonCode = state.getAdjTypeCode();
4148         outInfo.processState = procState;
4149         outInfo.isFocused = (app == mService.getTopApp());
4150         outInfo.lastActivityTime = app.getLastActivityTime();
4151     }
4152 
4153     @GuardedBy(anyOf = {"mService", "mProcLock"})
4154     List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLOSP(boolean allUsers,
4155             int userId, boolean allUids, int callingUid, int clientTargetSdk) {
4156         // Lazy instantiation of list
4157         List<ActivityManager.RunningAppProcessInfo> runList = null;
4158 
4159         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4160             ProcessRecord app = mLruProcesses.get(i);
4161             final ProcessStateRecord state = app.mState;
4162             final ProcessErrorStateRecord errState = app.mErrorState;
4163             if ((!allUsers && app.userId != userId)
4164                     || (!allUids && app.uid != callingUid)) {
4165                 continue;
4166             }
4167             if ((app.getThread() != null)
4168                     && (!errState.isCrashing() && !errState.isNotResponding())) {
4169                 // Generate process state info for running application
4170                 ActivityManager.RunningAppProcessInfo currApp =
4171                         new ActivityManager.RunningAppProcessInfo(app.processName,
4172                                 app.getPid(), app.getPackageList());
4173                 if (app.getPkgDeps() != null) {
4174                     final int size = app.getPkgDeps().size();
4175                     currApp.pkgDeps = app.getPkgDeps().toArray(new String[size]);
4176                 }
4177                 fillInProcMemInfoLOSP(app, currApp, clientTargetSdk);
4178                 if (state.getAdjSource() instanceof ProcessRecord) {
4179                     currApp.importanceReasonPid = ((ProcessRecord) state.getAdjSource()).getPid();
4180                     currApp.importanceReasonImportance =
4181                             ActivityManager.RunningAppProcessInfo.procStateToImportance(
4182                                     state.getAdjSourceProcState());
4183                 } else if (state.getAdjSource() instanceof ActivityServiceConnectionsHolder) {
4184                     final ActivityServiceConnectionsHolder r =
4185                             (ActivityServiceConnectionsHolder) state.getAdjSource();
4186                     final int pid = r.getActivityPid();
4187                     if (pid != -1) {
4188                         currApp.importanceReasonPid = pid;
4189                     }
4190                 }
4191                 if (state.getAdjTarget() instanceof ComponentName) {
4192                     currApp.importanceReasonComponent = (ComponentName) state.getAdjTarget();
4193                 }
4194                 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
4195                 //        + " lru=" + currApp.lru);
4196                 if (runList == null) {
4197                     runList = new ArrayList<>();
4198                 }
4199                 runList.add(currApp);
4200             }
4201         }
4202         return runList;
4203     }
4204 
4205     @GuardedBy(anyOf = {"mService", "mProcLock"})
4206     int getLruSizeLOSP() {
4207         return mLruProcesses.size();
4208     }
4209 
4210     /**
4211      * Return the reference to the LRU list, call this function for read-only access
4212      */
4213     @GuardedBy(anyOf = {"mService", "mProcLock"})
4214     ArrayList<ProcessRecord> getLruProcessesLOSP() {
4215         return mLruProcesses;
4216     }
4217 
4218     /**
4219      * Return the reference to the LRU list, call this function for read/write access
4220      */
4221     @GuardedBy({"mService", "mProcLock"})
4222     ArrayList<ProcessRecord> getLruProcessesLSP() {
4223         return mLruProcesses;
4224     }
4225 
4226     /**
4227      * For test only
4228      */
4229     @VisibleForTesting
4230     @GuardedBy({"mService", "mProcLock"})
4231     void setLruProcessServiceStartLSP(int pos) {
4232         mLruProcessServiceStart = pos;
4233     }
4234 
4235     @GuardedBy(anyOf = {"mService", "mProcLock"})
4236     int getLruProcessServiceStartLOSP() {
4237         return mLruProcessServiceStart;
4238     }
4239 
4240     /**
4241      * Iterate the whole LRU list, invoke the given {@code callback} with each of the ProcessRecord
4242      * in that list.
4243      *
4244      * @param iterateForward If {@code true}, iterate the LRU list from the least recent used
4245      *                       to most recent used ProcessRecord.
4246      * @param callback The callback interface to accept the current ProcessRecord.
4247      */
4248     @GuardedBy(anyOf = {"mService", "mProcLock"})
4249     void forEachLruProcessesLOSP(boolean iterateForward,
4250             @NonNull Consumer<ProcessRecord> callback) {
4251         if (iterateForward) {
4252             for (int i = 0, size = mLruProcesses.size(); i < size; i++) {
4253                 callback.accept(mLruProcesses.get(i));
4254             }
4255         } else {
4256             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4257                 callback.accept(mLruProcesses.get(i));
4258             }
4259         }
4260     }
4261 
4262     /**
4263      * Search in the LRU list, invoke the given {@code callback} with each of the ProcessRecord
4264      * in that list; if the callback returns a non-null object, halt the search, return that
4265      * object as the return value of this search function.
4266      *
4267      * @param iterateForward If {@code true}, iterate the LRU list from the least recent used
4268      *                       to most recent used ProcessRecord.
4269      * @param callback The callback interface to accept the current ProcessRecord; if it returns
4270      *                 a non-null object, the search will be halted and this object will be used
4271      *                 as the return value of this search function.
4272      */
4273     @GuardedBy(anyOf = {"mService", "mProcLock"})
4274     <R> R searchEachLruProcessesLOSP(boolean iterateForward,
4275             @NonNull Function<ProcessRecord, R> callback) {
4276         if (iterateForward) {
4277             for (int i = 0, size = mLruProcesses.size(); i < size; i++) {
4278                 R r;
4279                 if ((r = callback.apply(mLruProcesses.get(i))) != null) {
4280                     return r;
4281                 }
4282             }
4283         } else {
4284             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4285                 R r;
4286                 if ((r = callback.apply(mLruProcesses.get(i))) != null) {
4287                     return r;
4288                 }
4289             }
4290         }
4291         return null;
4292     }
4293 
4294     @GuardedBy(anyOf = {"mService", "mProcLock"})
4295     boolean isInLruListLOSP(ProcessRecord app) {
4296         return mLruProcesses.contains(app);
4297     }
4298 
4299     @GuardedBy(anyOf = {"mService", "mProcLock"})
4300     int getLruSeqLOSP() {
4301         return mLruSeq;
4302     }
4303 
4304     @GuardedBy(anyOf = {"mService", "mProcLock"})
4305     MyProcessMap getProcessNamesLOSP() {
4306         return mProcessNames;
4307     }
4308 
4309     @GuardedBy("mService")
4310     void dumpLruListHeaderLocked(PrintWriter pw) {
4311         pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
4312         pw.print(" total, non-act at ");
4313         pw.print(mLruProcesses.size() - mLruProcessActivityStart);
4314         pw.print(", non-svc at ");
4315         pw.print(mLruProcesses.size() - mLruProcessServiceStart);
4316         pw.println("):");
4317     }
4318 
4319     @GuardedBy("mService")
4320     private void dumpLruEntryLocked(PrintWriter pw, int index, ProcessRecord proc, String prefix) {
4321         pw.print(prefix);
4322         pw.print('#');
4323         if (index < 10) {
4324             pw.print(' ');
4325         }
4326         pw.print(index);
4327         pw.print(": ");
4328         pw.print(makeOomAdjString(proc.mState.getSetAdj(), false));
4329         pw.print(' ');
4330         pw.print(makeProcStateString(proc.mState.getCurProcState()));
4331         pw.print(' ');
4332         ActivityManager.printCapabilitiesSummary(pw, proc.mState.getCurCapability());
4333         pw.print(' ');
4334         pw.print(proc.toShortString());
4335         final ProcessServiceRecord psr = proc.mServices;
4336         if (proc.hasActivitiesOrRecentTasks() || psr.hasClientActivities()
4337                 || psr.isTreatedLikeActivity()) {
4338             pw.print(" act:");
4339             boolean printed = false;
4340             if (proc.hasActivities()) {
4341                 pw.print("activities");
4342                 printed = true;
4343             }
4344             if (proc.hasRecentTasks()) {
4345                 if (printed) {
4346                     pw.print("|");
4347                 }
4348                 pw.print("recents");
4349                 printed = true;
4350             }
4351             if (psr.hasClientActivities()) {
4352                 if (printed) {
4353                     pw.print("|");
4354                 }
4355                 pw.print("client");
4356                 printed = true;
4357             }
4358             if (psr.isTreatedLikeActivity()) {
4359                 if (printed) {
4360                     pw.print("|");
4361                 }
4362                 pw.print("treated");
4363             }
4364         }
4365         pw.println();
4366     }
4367 
4368     @GuardedBy("mService")
4369     boolean dumpLruLocked(PrintWriter pw, String dumpPackage, String prefix) {
4370         final int lruSize = mLruProcesses.size();
4371         final String innerPrefix;
4372         if (prefix == null) {
4373             pw.println("ACTIVITY MANAGER LRU PROCESSES (dumpsys activity lru)");
4374             innerPrefix = "  ";
4375         } else {
4376             boolean haveAny = false;
4377             for (int i = lruSize - 1; i >= 0; i--) {
4378                 final ProcessRecord r = mLruProcesses.get(i);
4379                 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4380                     continue;
4381                 }
4382                 haveAny = true;
4383                 break;
4384             }
4385             if (!haveAny) {
4386                 return false;
4387             }
4388             pw.print(prefix);
4389             pw.println("Raw LRU list (dumpsys activity lru):");
4390             innerPrefix = prefix + "  ";
4391         }
4392         int i;
4393         boolean first = true;
4394         for (i = lruSize - 1; i >= mLruProcessActivityStart; i--) {
4395             final ProcessRecord r = mLruProcesses.get(i);
4396             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4397                 continue;
4398             }
4399             if (first) {
4400                 pw.print(innerPrefix);
4401                 pw.println("Activities:");
4402                 first = false;
4403             }
4404             dumpLruEntryLocked(pw, i, r, innerPrefix);
4405         }
4406         first = true;
4407         for (; i >= mLruProcessServiceStart; i--) {
4408             final ProcessRecord r = mLruProcesses.get(i);
4409             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4410                 continue;
4411             }
4412             if (first) {
4413                 pw.print(innerPrefix);
4414                 pw.println("Services:");
4415                 first = false;
4416             }
4417             dumpLruEntryLocked(pw, i, r, innerPrefix);
4418         }
4419         first = true;
4420         for (; i >= 0; i--) {
4421             final ProcessRecord r = mLruProcesses.get(i);
4422             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4423                 continue;
4424             }
4425             if (first) {
4426                 pw.print(innerPrefix);
4427                 pw.println("Other:");
4428                 first = false;
4429             }
4430             dumpLruEntryLocked(pw, i, r, innerPrefix);
4431         }
4432         return true;
4433     }
4434 
4435     @GuardedBy({"mService", "mProcLock"})
4436     void dumpProcessesLSP(FileDescriptor fd, PrintWriter pw, String[] args,
4437             int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
4438         boolean needSep = false;
4439         int numPers = 0;
4440 
4441         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
4442 
4443         if (dumpAll || dumpPackage != null) {
4444             final int numOfNames = mProcessNames.getMap().size();
4445             for (int ip = 0; ip < numOfNames; ip++) {
4446                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
4447                 for (int ia = 0, size = procs.size(); ia < size; ia++) {
4448                     ProcessRecord r = procs.valueAt(ia);
4449                     if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4450                         continue;
4451                     }
4452                     if (!needSep) {
4453                         pw.println("  All known processes:");
4454                         needSep = true;
4455                     }
4456                     pw.print(r.isPersistent() ? "  *PERS*" : "  *APP*");
4457                     pw.print(" UID "); pw.print(procs.keyAt(ia));
4458                     pw.print(" "); pw.println(r);
4459                     r.dump(pw, "    ");
4460                     if (r.isPersistent()) {
4461                         numPers++;
4462                     }
4463                 }
4464             }
4465         }
4466 
4467         if (mIsolatedProcesses.size() > 0) {
4468             boolean printed = false;
4469             for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
4470                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
4471                 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4472                     continue;
4473                 }
4474                 if (!printed) {
4475                     if (needSep) {
4476                         pw.println();
4477                     }
4478                     pw.println("  Isolated process list (sorted by uid):");
4479                     printed = true;
4480                     needSep = true;
4481                 }
4482                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
4483                 pw.println(r);
4484             }
4485         }
4486 
4487         needSep = mService.dumpActiveInstruments(pw, dumpPackage, needSep);
4488 
4489         if (dumpOomLocked(fd, pw, needSep, args, opti, dumpAll, dumpPackage, false)) {
4490             needSep = true;
4491         }
4492 
4493         if (mActiveUids.size() > 0) {
4494             needSep |= mActiveUids.dump(pw, dumpPackage, dumpAppId,
4495                     "UID states:", needSep);
4496         }
4497 
4498         if (dumpAll) {
4499             needSep |= mService.mUidObserverController.dumpValidateUids(pw,
4500                     dumpPackage, dumpAppId, "UID validation:", needSep);
4501         }
4502 
4503         if (needSep) {
4504             pw.println();
4505         }
4506         if (dumpLruLocked(pw, dumpPackage, "  ")) {
4507             needSep = true;
4508         }
4509 
4510         if (getLruSizeLOSP() > 0) {
4511             if (needSep) {
4512                 pw.println();
4513             }
4514             dumpLruListHeaderLocked(pw);
4515             dumpProcessOomList(pw, mService, mLruProcesses, "    ", "Proc", "PERS", false,
4516                     dumpPackage);
4517             needSep = true;
4518         }
4519 
4520         mService.dumpOtherProcessesInfoLSP(fd, pw, dumpAll, dumpPackage, dumpAppId, numPers,
4521                 needSep);
4522     }
4523 
4524     @GuardedBy({"mService", "mProcLock"})
4525     void writeProcessesToProtoLSP(ProtoOutputStream proto, String dumpPackage) {
4526         int numPers = 0;
4527 
4528         final int numOfNames = mProcessNames.getMap().size();
4529         for (int ip = 0; ip < numOfNames; ip++) {
4530             SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
4531             for (int ia = 0, size = procs.size(); ia < size; ia++) {
4532                 ProcessRecord r = procs.valueAt(ia);
4533                 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4534                     continue;
4535                 }
4536                 r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.PROCS,
4537                         mLruProcesses.indexOf(r)
4538                 );
4539                 if (r.isPersistent()) {
4540                     numPers++;
4541                 }
4542             }
4543         }
4544 
4545         for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
4546             ProcessRecord r = mIsolatedProcesses.valueAt(i);
4547             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4548                 continue;
4549             }
4550             r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS,
4551                     mLruProcesses.indexOf(r)
4552             );
4553         }
4554 
4555         final int dumpAppId = mService.getAppId(dumpPackage);
4556         mActiveUids.dumpProto(proto, dumpPackage, dumpAppId,
4557                 ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
4558 
4559         if (getLruSizeLOSP() > 0) {
4560             long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
4561             int total = getLruSizeLOSP();
4562             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
4563             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT,
4564                     total - mLruProcessActivityStart);
4565             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT,
4566                     total - mLruProcessServiceStart);
4567             writeProcessOomListToProto(proto,
4568                     ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, mService,
4569                     mLruProcesses, true, dumpPackage);
4570             proto.end(lruToken);
4571         }
4572 
4573         mService.writeOtherProcessesInfoToProtoLSP(proto, dumpPackage, dumpAppId, numPers);
4574     }
4575 
4576     private static ArrayList<Pair<ProcessRecord, Integer>> sortProcessOomList(
4577             List<ProcessRecord> origList, String dumpPackage) {
4578         ArrayList<Pair<ProcessRecord, Integer>> list =
4579                 new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
4580         for (int i = 0, size = origList.size(); i < size; i++) {
4581             ProcessRecord r = origList.get(i);
4582             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4583                 continue;
4584             }
4585             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
4586         }
4587 
4588         Comparator<Pair<ProcessRecord, Integer>> comparator =
4589                 new Comparator<Pair<ProcessRecord, Integer>>() {
4590             @Override
4591             public int compare(Pair<ProcessRecord, Integer> object1,
4592                     Pair<ProcessRecord, Integer> object2) {
4593                 final int adj = object2.first.mState.getSetAdj() - object1.first.mState.getSetAdj();
4594                 if (adj != 0) {
4595                     return adj;
4596                 }
4597                 final int procState = object2.first.mState.getSetProcState()
4598                         - object1.first.mState.getSetProcState();
4599                 if (procState != 0) {
4600                     return procState;
4601                 }
4602                 final int val = object2.second - object1.second;
4603                 if (val != 0) {
4604                     return val;
4605                 }
4606                 return 0;
4607             }
4608         };
4609 
4610         Collections.sort(list, comparator);
4611         return list;
4612     }
4613 
4614     private static boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
4615             ActivityManagerService service, List<ProcessRecord> origList,
4616             boolean inclDetails, String dumpPackage) {
4617         ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
4618         if (list.isEmpty()) return false;
4619 
4620         final long curUptime = SystemClock.uptimeMillis();
4621 
4622         for (int i = list.size() - 1; i >= 0; i--) {
4623             ProcessRecord r = list.get(i).first;
4624             final ProcessStateRecord state = r.mState;
4625             final ProcessServiceRecord psr = r.mServices;
4626             long token = proto.start(fieldId);
4627             String oomAdj = makeOomAdjString(state.getSetAdj(), true);
4628             proto.write(ProcessOomProto.PERSISTENT, r.isPersistent());
4629             proto.write(ProcessOomProto.NUM, (origList.size() - 1) - list.get(i).second);
4630             proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
4631             int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
4632             switch (state.getSetSchedGroup()) {
4633                 case SCHED_GROUP_BACKGROUND:
4634                     schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
4635                     break;
4636                 case SCHED_GROUP_DEFAULT:
4637                     schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
4638                     break;
4639                 case SCHED_GROUP_TOP_APP:
4640                     schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
4641                     break;
4642                 case SCHED_GROUP_TOP_APP_BOUND:
4643                     schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
4644                     break;
4645             }
4646             if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
4647                 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
4648             }
4649             if (state.hasForegroundActivities()) {
4650                 proto.write(ProcessOomProto.ACTIVITIES, true);
4651             } else if (psr.hasForegroundServices()) {
4652                 proto.write(ProcessOomProto.SERVICES, true);
4653             }
4654             proto.write(ProcessOomProto.STATE,
4655                     makeProcStateProtoEnum(state.getCurProcState()));
4656             proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.mProfile.getTrimMemoryLevel());
4657             r.dumpDebug(proto, ProcessOomProto.PROC);
4658             proto.write(ProcessOomProto.ADJ_TYPE, state.getAdjType());
4659             if (state.getAdjSource() != null || state.getAdjTarget() != null) {
4660                 if (state.getAdjTarget() instanceof  ComponentName) {
4661                     ComponentName cn = (ComponentName) state.getAdjTarget();
4662                     cn.dumpDebug(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
4663                 } else if (state.getAdjTarget() != null) {
4664                     proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, state.getAdjTarget().toString());
4665                 }
4666                 if (state.getAdjSource() instanceof ProcessRecord) {
4667                     ProcessRecord p = (ProcessRecord) state.getAdjSource();
4668                     p.dumpDebug(proto, ProcessOomProto.ADJ_SOURCE_PROC);
4669                 } else if (state.getAdjSource() != null) {
4670                     proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, state.getAdjSource().toString());
4671                 }
4672             }
4673             if (inclDetails) {
4674                 long detailToken = proto.start(ProcessOomProto.DETAIL);
4675                 proto.write(ProcessOomProto.Detail.MAX_ADJ, state.getMaxAdj());
4676                 proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, state.getCurRawAdj());
4677                 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, state.getSetRawAdj());
4678                 proto.write(ProcessOomProto.Detail.CUR_ADJ, state.getCurAdj());
4679                 proto.write(ProcessOomProto.Detail.SET_ADJ, state.getSetAdj());
4680                 proto.write(ProcessOomProto.Detail.CURRENT_STATE,
4681                         makeProcStateProtoEnum(state.getCurProcState()));
4682                 proto.write(ProcessOomProto.Detail.SET_STATE,
4683                         makeProcStateProtoEnum(state.getSetProcState()));
4684                 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
4685                         r.mProfile.getLastPss() * 1024, new StringBuilder()));
4686                 proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
4687                         r.mProfile.getLastSwapPss() * 1024, new StringBuilder()));
4688                 // TODO(b/296454553): This proto field should be replaced with last cached RSS once
4689                 // AppProfiler is no longer collecting PSS.
4690                 proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
4691                         r.mProfile.getLastCachedPss() * 1024, new StringBuilder()));
4692                 proto.write(ProcessOomProto.Detail.CACHED, state.isCached());
4693                 proto.write(ProcessOomProto.Detail.EMPTY, state.isEmpty());
4694                 proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, psr.hasAboveClient());
4695 
4696                 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
4697                     long lastCpuTime = r.mProfile.mLastCpuTime.get();
4698                     long uptimeSince = curUptime - service.mLastPowerCheckUptime;
4699                     if (lastCpuTime != 0 && uptimeSince > 0) {
4700                         long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime;
4701                         long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
4702                         proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
4703                         proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
4704                         proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
4705                                 (100.0 * timeUsed) / uptimeSince);
4706                         proto.end(cpuTimeToken);
4707                     }
4708                 }
4709                 proto.end(detailToken);
4710             }
4711             proto.end(token);
4712         }
4713 
4714         return true;
4715     }
4716 
4717     private static boolean dumpProcessOomList(PrintWriter pw,
4718             ActivityManagerService service, List<ProcessRecord> origList,
4719             String prefix, String normalLabel, String persistentLabel,
4720             boolean inclDetails, String dumpPackage) {
4721 
4722         ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
4723         if (list.isEmpty()) return false;
4724 
4725         final long curUptime = SystemClock.uptimeMillis();
4726         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
4727 
4728         for (int i = list.size() - 1; i >= 0; i--) {
4729             ProcessRecord r = list.get(i).first;
4730             final ProcessStateRecord state = r.mState;
4731             final ProcessServiceRecord psr = r.mServices;
4732             String oomAdj = makeOomAdjString(state.getSetAdj(), false);
4733             char schedGroup;
4734             switch (state.getSetSchedGroup()) {
4735                 case SCHED_GROUP_BACKGROUND:
4736                     schedGroup = 'b';
4737                     break;
4738                 case SCHED_GROUP_DEFAULT:
4739                     schedGroup = 'F';
4740                     break;
4741                 case SCHED_GROUP_TOP_APP:
4742                     schedGroup = 'T';
4743                     break;
4744                 case SCHED_GROUP_RESTRICTED:
4745                     schedGroup = 'R';
4746                     break;
4747                 case SCHED_GROUP_TOP_APP_BOUND:
4748                     schedGroup = 'B';
4749                     break;
4750                 default:
4751                     schedGroup = '?';
4752                     break;
4753             }
4754             char foreground;
4755             if (state.hasForegroundActivities()) {
4756                 foreground = 'A';
4757             } else if (psr.hasForegroundServices()) {
4758                 foreground = 'S';
4759             } else {
4760                 foreground = ' ';
4761             }
4762             String procState = makeProcStateString(state.getCurProcState());
4763             pw.print(prefix);
4764             pw.print(r.isPersistent() ? persistentLabel : normalLabel);
4765             pw.print(" #");
4766             int num = (origList.size() - 1) - list.get(i).second;
4767             if (num < 10) pw.print(' ');
4768             pw.print(num);
4769             pw.print(": ");
4770             pw.print(oomAdj);
4771             pw.print(' ');
4772             pw.print(schedGroup);
4773             pw.print('/');
4774             pw.print(foreground);
4775             pw.print('/');
4776             pw.print(procState);
4777             pw.print(' ');
4778             ActivityManager.printCapabilitiesSummary(pw, state.getCurCapability());
4779             pw.print(' ');
4780             pw.print(" t:");
4781             if (r.mProfile.getTrimMemoryLevel() < 10) pw.print(' ');
4782             pw.print(r.mProfile.getTrimMemoryLevel());
4783             pw.print(' ');
4784             pw.print(r.toShortString());
4785             pw.print(" (");
4786             pw.print(state.getAdjType());
4787             pw.println(')');
4788             if (state.getAdjSource() != null || state.getAdjTarget() != null) {
4789                 pw.print(prefix);
4790                 pw.print("    ");
4791                 if (state.getAdjTarget() instanceof ComponentName) {
4792                     pw.print(((ComponentName) state.getAdjTarget()).flattenToShortString());
4793                 } else if (state.getAdjTarget() != null) {
4794                     pw.print(state.getAdjTarget().toString());
4795                 } else {
4796                     pw.print("{null}");
4797                 }
4798                 pw.print("<=");
4799                 if (state.getAdjSource() instanceof ProcessRecord) {
4800                     pw.print("Proc{");
4801                     pw.print(((ProcessRecord) state.getAdjSource()).toShortString());
4802                     pw.println("}");
4803                 } else if (state.getAdjSource() != null) {
4804                     pw.println(state.getAdjSource().toString());
4805                 } else {
4806                     pw.println("{null}");
4807                 }
4808             }
4809             if (inclDetails) {
4810                 pw.print(prefix);
4811                 pw.print("    ");
4812                 pw.print("oom: max="); pw.print(state.getMaxAdj());
4813                 pw.print(" curRaw="); pw.print(state.getCurRawAdj());
4814                 pw.print(" setRaw="); pw.print(state.getSetRawAdj());
4815                 pw.print(" cur="); pw.print(state.getCurAdj());
4816                 pw.print(" set="); pw.println(state.getSetAdj());
4817                 pw.print(prefix);
4818                 pw.print("    ");
4819                 pw.print("state: cur="); pw.print(makeProcStateString(state.getCurProcState()));
4820                 pw.print(" set="); pw.print(makeProcStateString(state.getSetProcState()));
4821                 // These values won't be collected if the flag is enabled.
4822                 if (service.mAppProfiler.isProfilingPss()) {
4823                     pw.print(" lastPss=");
4824                     DebugUtils.printSizeValue(pw, r.mProfile.getLastPss() * 1024);
4825                     pw.print(" lastSwapPss=");
4826                     DebugUtils.printSizeValue(pw, r.mProfile.getLastSwapPss() * 1024);
4827                     pw.print(" lastCachedPss=");
4828                     DebugUtils.printSizeValue(pw, r.mProfile.getLastCachedPss() * 1024);
4829                 } else {
4830                     pw.print(" lastRss=");
4831                     DebugUtils.printSizeValue(pw, r.mProfile.getLastRss() * 1024);
4832                     pw.print(" lastCachedRss=");
4833                     DebugUtils.printSizeValue(pw, r.mProfile.getLastCachedRss() * 1024);
4834                 }
4835                 pw.println();
4836                 pw.print(prefix);
4837                 pw.print("    ");
4838                 pw.print("cached="); pw.print(state.isCached());
4839                 pw.print(" empty="); pw.print(state.isEmpty());
4840                 pw.print(" hasAboveClient="); pw.println(psr.hasAboveClient());
4841 
4842                 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
4843                     long lastCpuTime = r.mProfile.mLastCpuTime.get();
4844                     if (lastCpuTime != 0 && uptimeSince > 0) {
4845                         long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime;
4846                         pw.print(prefix);
4847                         pw.print("    ");
4848                         pw.print("run cpu over ");
4849                         TimeUtils.formatDuration(uptimeSince, pw);
4850                         pw.print(" used ");
4851                         TimeUtils.formatDuration(timeUsed, pw);
4852                         pw.print(" (");
4853                         pw.print((timeUsed * 100) / uptimeSince);
4854                         pw.println("%)");
4855                     }
4856                 }
4857             }
4858         }
4859         return true;
4860     }
4861 
4862     private void printOomLevel(PrintWriter pw, String name, int adj) {
4863         pw.print("    ");
4864         if (adj >= 0) {
4865             pw.print(' ');
4866             if (adj < 10) pw.print(' ');
4867         } else {
4868             if (adj > -10) pw.print(' ');
4869         }
4870         pw.print(adj);
4871         pw.print(": ");
4872         pw.print(name);
4873         pw.print(" (");
4874         pw.print(ActivityManagerService.stringifySize(getMemLevel(adj), 1024));
4875         pw.println(")");
4876     }
4877 
4878     @GuardedBy("mService")
4879     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String[] args,
4880             int opti, boolean dumpAll, String dumpPackage, boolean inclGc) {
4881         if (getLruSizeLOSP() > 0) {
4882             if (needSep) pw.println();
4883             needSep = true;
4884             pw.println("  OOM levels:");
4885             printOomLevel(pw, "SYSTEM_ADJ", SYSTEM_ADJ);
4886             printOomLevel(pw, "PERSISTENT_PROC_ADJ", PERSISTENT_PROC_ADJ);
4887             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", PERSISTENT_SERVICE_ADJ);
4888             printOomLevel(pw, "FOREGROUND_APP_ADJ", FOREGROUND_APP_ADJ);
4889             printOomLevel(pw, "VISIBLE_APP_ADJ", VISIBLE_APP_ADJ);
4890             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", PERCEPTIBLE_APP_ADJ);
4891             printOomLevel(pw, "PERCEPTIBLE_MEDIUM_APP_ADJ", PERCEPTIBLE_MEDIUM_APP_ADJ);
4892             printOomLevel(pw, "PERCEPTIBLE_LOW_APP_ADJ", PERCEPTIBLE_LOW_APP_ADJ);
4893             printOomLevel(pw, "BACKUP_APP_ADJ", BACKUP_APP_ADJ);
4894             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", HEAVY_WEIGHT_APP_ADJ);
4895             printOomLevel(pw, "SERVICE_ADJ", SERVICE_ADJ);
4896             printOomLevel(pw, "HOME_APP_ADJ", HOME_APP_ADJ);
4897             printOomLevel(pw, "PREVIOUS_APP_ADJ", PREVIOUS_APP_ADJ);
4898             printOomLevel(pw, "SERVICE_B_ADJ", SERVICE_B_ADJ);
4899             printOomLevel(pw, "CACHED_APP_MIN_ADJ", CACHED_APP_MIN_ADJ);
4900             printOomLevel(pw, "CACHED_APP_MAX_ADJ", CACHED_APP_MAX_ADJ);
4901 
4902             if (needSep) pw.println();
4903             pw.print("  Process OOM control ("); pw.print(getLruSizeLOSP());
4904             pw.print(" total, non-act at ");
4905             pw.print(getLruSizeLOSP() - mLruProcessActivityStart);
4906             pw.print(", non-svc at ");
4907             pw.print(getLruSizeLOSP() - mLruProcessServiceStart);
4908             pw.println("):");
4909             dumpProcessOomList(pw, mService, mLruProcesses,
4910                     "    ", "Proc", "PERS", true, dumpPackage);
4911             needSep = true;
4912         }
4913 
4914         synchronized (mService.mAppProfiler.mProfilerLock) {
4915             mService.mAppProfiler.dumpProcessesToGc(pw, needSep, dumpPackage);
4916         }
4917 
4918         pw.println();
4919         mService.mAtmInternal.dumpForOom(pw);
4920 
4921         return true;
4922     }
4923 
4924     void registerProcessObserver(IProcessObserver observer) {
4925         mProcessObservers.register(observer);
4926     }
4927 
4928     void unregisterProcessObserver(IProcessObserver observer) {
4929         mProcessObservers.unregister(observer);
4930     }
4931 
4932     void dispatchProcessesChanged() {
4933         int numOfChanges;
4934         synchronized (mProcessChangeLock) {
4935             numOfChanges = mPendingProcessChanges.size();
4936             if (mActiveProcessChanges.length < numOfChanges) {
4937                 mActiveProcessChanges = new ProcessChangeItem[numOfChanges];
4938             }
4939             mPendingProcessChanges.toArray(mActiveProcessChanges);
4940             mPendingProcessChanges.clear();
4941             if (DEBUG_PROCESS_OBSERVERS) {
4942                 Slog.i(TAG_PROCESS_OBSERVERS,
4943                         "*** Delivering " + numOfChanges + " process changes");
4944             }
4945         }
4946 
4947         int i = mProcessObservers.beginBroadcast();
4948         while (i > 0) {
4949             i--;
4950             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4951             if (observer != null) {
4952                 try {
4953                     for (int j = 0; j < numOfChanges; j++) {
4954                         ProcessChangeItem item = mActiveProcessChanges[j];
4955                         if ((item.changes & ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4956                             if (DEBUG_PROCESS_OBSERVERS) {
4957                                 Slog.i(TAG_PROCESS_OBSERVERS,
4958                                         "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4959                                         + item.uid + ": " + item.foregroundActivities);
4960                             }
4961                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4962                                     item.foregroundActivities);
4963                         }
4964                         if ((item.changes & ProcessChangeItem.CHANGE_FOREGROUND_SERVICES) != 0) {
4965                             if (DEBUG_PROCESS_OBSERVERS) {
4966                                 Slog.i(TAG_PROCESS_OBSERVERS,
4967                                         "FOREGROUND SERVICES CHANGED pid=" + item.pid + " uid="
4968                                         + item.uid + ": " + item.foregroundServiceTypes);
4969                             }
4970                             observer.onForegroundServicesChanged(item.pid, item.uid,
4971                                     item.foregroundServiceTypes);
4972                         }
4973                     }
4974                 } catch (RemoteException e) {
4975                 }
4976             }
4977         }
4978         mProcessObservers.finishBroadcast();
4979 
4980         synchronized (mProcessChangeLock) {
4981             for (int j = 0; j < numOfChanges; j++) {
4982                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4983             }
4984         }
4985     }
4986 
4987     @GuardedBy("mService")
4988     ProcessChangeItem enqueueProcessChangeItemLocked(int pid, int uid) {
4989         synchronized (mProcessChangeLock) {
4990             int i = mPendingProcessChanges.size() - 1;
4991             ActivityManagerService.ProcessChangeItem item = null;
4992             while (i >= 0) {
4993                 item = mPendingProcessChanges.get(i);
4994                 if (item.pid == pid) {
4995                     if (DEBUG_PROCESS_OBSERVERS) {
4996                         Slog.i(TAG_PROCESS_OBSERVERS, "Re-using existing item: " + item);
4997                     }
4998                     break;
4999                 }
5000                 i--;
5001             }
5002 
5003             if (i < 0) {
5004                 // No existing item in pending changes; need a new one.
5005                 final int num = mAvailProcessChanges.size();
5006                 if (num > 0) {
5007                     item = mAvailProcessChanges.remove(num - 1);
5008                     if (DEBUG_PROCESS_OBSERVERS) {
5009                         Slog.i(TAG_PROCESS_OBSERVERS, "Retrieving available item: " + item);
5010                     }
5011                 } else {
5012                     item = new ActivityManagerService.ProcessChangeItem();
5013                     if (DEBUG_PROCESS_OBSERVERS) {
5014                         Slog.i(TAG_PROCESS_OBSERVERS, "Allocating new item: " + item);
5015                     }
5016                 }
5017                 item.changes = 0;
5018                 item.pid = pid;
5019                 item.uid = uid;
5020                 if (mPendingProcessChanges.size() == 0) {
5021                     if (DEBUG_PROCESS_OBSERVERS) {
5022                         Slog.i(TAG_PROCESS_OBSERVERS, "*** Enqueueing dispatch processes changed!");
5023                     }
5024                     mService.mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG)
5025                             .sendToTarget();
5026                 }
5027                 mPendingProcessChanges.add(item);
5028             }
5029 
5030             return item;
5031         }
5032     }
5033 
5034     @GuardedBy("mService")
5035     void scheduleDispatchProcessDiedLocked(int pid, int uid) {
5036         synchronized (mProcessChangeLock) {
5037             for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
5038                 ProcessChangeItem item = mPendingProcessChanges.get(i);
5039                 if (pid > 0 && item.pid == pid) {
5040                     mPendingProcessChanges.remove(i);
5041                     mAvailProcessChanges.add(item);
5042                 }
5043             }
5044             mService.mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, pid, uid,
5045                     null).sendToTarget();
5046         }
5047     }
5048 
5049     void dispatchProcessStarted(ProcessRecord app, int pid) {
5050         // TODO(b/323959187) Add the implementation.
5051     }
5052 
5053     void dispatchProcessDied(int pid, int uid) {
5054         int i = mProcessObservers.beginBroadcast();
5055         while (i > 0) {
5056             i--;
5057             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
5058             if (observer != null) {
5059                 try {
5060                     observer.onProcessDied(pid, uid);
5061                 } catch (RemoteException e) {
5062                 }
5063             }
5064         }
5065         mProcessObservers.finishBroadcast();
5066     }
5067 
5068     @GuardedBy(anyOf = {"mService", "mProcLock"})
5069     ArrayList<ProcessRecord> collectProcessesLOSP(int start, boolean allPkgs, String[] args) {
5070         ArrayList<ProcessRecord> procs;
5071         if (args != null && args.length > start
5072                 && args[start].charAt(0) != '-') {
5073             procs = new ArrayList<ProcessRecord>();
5074             int pid = -1;
5075             try {
5076                 pid = Integer.parseInt(args[start]);
5077             } catch (NumberFormatException e) {
5078             }
5079             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5080                 ProcessRecord proc = mLruProcesses.get(i);
5081                 if (proc.getPid() > 0 && proc.getPid() == pid) {
5082                     procs.add(proc);
5083                 } else if (allPkgs && proc.getPkgList() != null
5084                         && proc.getPkgList().containsKey(args[start])) {
5085                     procs.add(proc);
5086                 } else if (proc.processName.equals(args[start])) {
5087                     procs.add(proc);
5088                 }
5089             }
5090             if (procs.size() <= 0) {
5091                 return null;
5092             }
5093         } else {
5094             procs = new ArrayList<ProcessRecord>(mLruProcesses);
5095         }
5096         return procs;
5097     }
5098 
5099     @GuardedBy(anyOf = {"mService", "mProcLock"})
5100     void updateApplicationInfoLOSP(List<String> packagesToUpdate, int userId,
5101             boolean updateFrameworkRes) {
5102         final ArrayMap<String, ApplicationInfo> applicationInfoByPackage = new ArrayMap<>();
5103         for (int i = packagesToUpdate.size() - 1; i >= 0; i--) {
5104             final String packageName = packagesToUpdate.get(i);
5105             final ApplicationInfo ai = mService.getPackageManagerInternal().getApplicationInfo(
5106                     packageName, STOCK_PM_FLAGS, Process.SYSTEM_UID, userId);
5107             if (ai != null) {
5108                 applicationInfoByPackage.put(packageName, ai);
5109             }
5110         }
5111         mService.mActivityTaskManager.updateActivityApplicationInfo(userId,
5112                 applicationInfoByPackage);
5113 
5114         final ArrayList<WindowProcessController> targetProcesses = new ArrayList<>();
5115         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5116             final ProcessRecord app = mLruProcesses.get(i);
5117             if (app.getThread() == null) {
5118                 continue;
5119             }
5120 
5121             if (userId != UserHandle.USER_ALL && app.userId != userId) {
5122                 continue;
5123             }
5124 
5125             app.getPkgList().forEachPackage(packageName -> {
5126                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
5127                     try {
5128                         final ApplicationInfo ai = applicationInfoByPackage.get(packageName);
5129                         if (ai != null) {
5130                             if (ai.packageName.equals(app.info.packageName)) {
5131                                 app.info = ai;
5132                                 PlatformCompatCache.getInstance()
5133                                         .onApplicationInfoChanged(ai);
5134                             }
5135                             app.getThread().scheduleApplicationInfoChanged(ai);
5136                             targetProcesses.add(app.getWindowProcessController());
5137                         }
5138                     } catch (RemoteException e) {
5139                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
5140                                     packageName, app));
5141                     }
5142                 }
5143             });
5144         }
5145 
5146         mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes);
5147     }
5148 
5149     @GuardedBy("mService")
5150     void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
5151         boolean foundProcess = false;
5152         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5153             ProcessRecord r = mLruProcesses.get(i);
5154             final IApplicationThread thread = r.getThread();
5155             if (thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
5156                 try {
5157                     for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
5158                         if (packages[index].equals(r.info.packageName)) {
5159                             foundProcess = true;
5160                         }
5161                     }
5162                     thread.dispatchPackageBroadcast(cmd, packages);
5163                 } catch (RemoteException ex) {
5164                 }
5165             }
5166         }
5167 
5168         if (!foundProcess) {
5169             try {
5170                 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
5171             } catch (RemoteException ignored) {
5172             }
5173         }
5174     }
5175 
5176     /**
5177      * Returns the uid's process state or {@link ActivityManager#PROCESS_STATE_NONEXISTENT}
5178      * if not running
5179      */
5180     @GuardedBy(anyOf = {"mService", "mProcLock"})
5181     int getUidProcStateLOSP(int uid) {
5182         UidRecord uidRec = mActiveUids.get(uid);
5183         return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
5184     }
5185 
5186     /**
5187      * Returns the uid's process capability or {@link ActivityManager#PROCESS_CAPABILITY_NONE}
5188      * if not running
5189      */
5190     @GuardedBy(anyOf = {"mService", "mProcLock"})
5191     @ProcessCapability int getUidProcessCapabilityLOSP(int uid) {
5192         UidRecord uidRec = mActiveUids.get(uid);
5193         return uidRec == null ? PROCESS_CAPABILITY_NONE : uidRec.getCurCapability();
5194     }
5195 
5196     /** Returns the UidRecord for the given uid, if it exists. */
5197     @GuardedBy(anyOf = {"mService", "mProcLock"})
5198     UidRecord getUidRecordLOSP(int uid) {
5199         return mActiveUids.get(uid);
5200     }
5201 
5202     /**
5203      * Call {@link ActivityManagerService#doStopUidLocked}
5204      * (which will also stop background services) for all idle UIDs.
5205      */
5206     @GuardedBy("mService")
5207     void doStopUidForIdleUidsLocked() {
5208         final int size = mActiveUids.size();
5209         for (int i = 0; i < size; i++) {
5210             final int uid = mActiveUids.keyAt(i);
5211             if (UserHandle.isCore(uid)) {
5212                 continue;
5213             }
5214             final UidRecord uidRec = mActiveUids.valueAt(i);
5215             if (!uidRec.isIdle()) {
5216                 continue;
5217             }
5218             mService.doStopUidLocked(uidRec.getUid(), uidRec);
5219         }
5220     }
5221 
5222     /**
5223      * Checks if the uid is coming from background to foreground or vice versa and returns
5224      * appropriate block state based on this.
5225      *
5226      * @return blockState based on whether the uid is coming from background to foreground or
5227      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
5228      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
5229      *         {@link #NETWORK_STATE_NO_CHANGE}.
5230      */
5231     @VisibleForTesting
5232     @GuardedBy(anyOf = {"mService", "mProcLock"})
5233     int getBlockStateForUid(UidRecord uidRec) {
5234         // Denotes whether uid's process state is currently allowed network access.
5235         final boolean isAllowed =
5236                 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState(),
5237                         uidRec.getCurCapability())
5238                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState(),
5239                         uidRec.getCurCapability());
5240         // Denotes whether uid's process state was previously allowed network access.
5241         final boolean wasAllowed =
5242                 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getSetProcState(),
5243                         uidRec.getSetCapability())
5244                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getSetProcState(),
5245                         uidRec.getSetCapability());
5246 
5247         // When the uid is coming to foreground, AMS should inform the app thread that it should
5248         // block for the network rules to get updated before launching an activity.
5249         if (!wasAllowed && isAllowed) {
5250             return NETWORK_STATE_BLOCK;
5251         }
5252         // When the uid is going to background, AMS should inform the app thread that if an
5253         // activity launch is blocked for the network rules to get updated, it should be unblocked.
5254         if (wasAllowed && !isAllowed) {
5255             return NETWORK_STATE_UNBLOCK;
5256         }
5257         return NETWORK_STATE_NO_CHANGE;
5258     }
5259 
5260     /**
5261      * Increments the {@link UidRecord#curProcStateSeq} for all uids using global seq counter
5262      * {@link ProcessList#mProcStateSeqCounter} and checks if any uid is coming
5263      * from background to foreground or vice versa and if so, notifies the app if it needs to block.
5264      */
5265     @VisibleForTesting
5266     @GuardedBy(anyOf = {"mService", "mProcLock"})
5267     void incrementProcStateSeqAndNotifyAppsLOSP(ActiveUids activeUids) {
5268         for (int i = activeUids.size() - 1; i >= 0; --i) {
5269             final UidRecord uidRec = activeUids.valueAt(i);
5270             uidRec.curProcStateSeq = getNextProcStateSeq();
5271         }
5272         if (mService.mConstants.mNetworkAccessTimeoutMs <= 0) {
5273             return;
5274         }
5275         // Used for identifying which uids need to block for network.
5276         ArrayList<Integer> blockingUids = null;
5277         for (int i = activeUids.size() - 1; i >= 0; --i) {
5278             final UidRecord uidRec = activeUids.valueAt(i);
5279             // If the network is not restricted for uid, then nothing to do here.
5280             if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.getUid())) {
5281                 continue;
5282             }
5283             if (!UserHandle.isApp(uidRec.getUid()) || !uidRec.hasInternetPermission) {
5284                 continue;
5285             }
5286             // If process state and capabilities are not changed, then there's nothing to do.
5287             if (uidRec.getSetProcState() == uidRec.getCurProcState()
5288                     && uidRec.getSetCapability() == uidRec.getCurCapability()) {
5289                 continue;
5290             }
5291             final int blockState = getBlockStateForUid(uidRec);
5292             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
5293             // there's nothing the app needs to do in this scenario.
5294             if (blockState == NETWORK_STATE_NO_CHANGE) {
5295                 continue;
5296             }
5297             synchronized (uidRec.networkStateLock) {
5298                 if (blockState == NETWORK_STATE_BLOCK) {
5299                     if (blockingUids == null) {
5300                         blockingUids = new ArrayList<>();
5301                     }
5302                     blockingUids.add(uidRec.getUid());
5303                 } else {
5304                     if (DEBUG_NETWORK) {
5305                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
5306                                 + " threads for uid: " + uidRec);
5307                     }
5308                     if (uidRec.procStateSeqWaitingForNetwork != 0) {
5309                         uidRec.networkStateLock.notifyAll();
5310                     }
5311                 }
5312             }
5313         }
5314 
5315         // There are no uids that need to block, so nothing more to do.
5316         if (blockingUids == null) {
5317             return;
5318         }
5319 
5320         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
5321             final ProcessRecord app = mLruProcesses.get(i);
5322             if (!blockingUids.contains(app.uid)) {
5323                 continue;
5324             }
5325             final IApplicationThread thread = app.getThread();
5326             if (!app.isKilledByAm() && thread != null) {
5327                 final UidRecord uidRec = getUidRecordLOSP(app.uid);
5328                 try {
5329                     if (DEBUG_NETWORK) {
5330                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
5331                                 + uidRec);
5332                     }
5333                     if (uidRec != null) {
5334                         thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
5335                     }
5336                 } catch (RemoteException ignored) {
5337                 }
5338             }
5339         }
5340     }
5341 
5342     long getNextProcStateSeq() {
5343         return ++mProcStateSeqCounter;
5344     }
5345 
5346     /**
5347      * Create a server socket in system_server, zygote will connect to it
5348      * in order to send unsolicited messages to system_server.
5349      */
5350     private LocalSocket createSystemServerSocketForZygote() {
5351         // The file system entity for this socket is created with 0666 perms, owned
5352         // by system:system. selinux restricts things so that only zygotes can
5353         // access it.
5354         final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH);
5355         if (socketFile.exists()) {
5356             socketFile.delete();
5357         }
5358 
5359         LocalSocket serverSocket = null;
5360         try {
5361             serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM);
5362             serverSocket.bind(new LocalSocketAddress(
5363                     UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM));
5364             Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666);
5365         } catch (Exception e) {
5366             if (serverSocket != null) {
5367                 try {
5368                     serverSocket.close();
5369                 } catch (IOException ex) {
5370                 }
5371                 serverSocket = null;
5372             }
5373         }
5374         return serverSocket;
5375     }
5376 
5377     /**
5378      * Handle the unsolicited message from zygote.
5379      */
5380     private int handleZygoteMessages(FileDescriptor fd, int events) {
5381         final int eventFd = fd.getInt$();
5382         if ((events & EVENT_INPUT) != 0) {
5383             // An incoming message from zygote
5384             try {
5385                 final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0,
5386                         mZygoteUnsolicitedMessage.length);
5387                 if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld(
5388                         mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) {
5389                     mAppExitInfoTracker.handleZygoteSigChld(
5390                             mZygoteSigChldMessage[0] /* pid */,
5391                             mZygoteSigChldMessage[1] /* uid */,
5392                             mZygoteSigChldMessage[2] /* status */);
5393                 }
5394             } catch (Exception e) {
5395                 Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e);
5396             }
5397         }
5398         return EVENT_INPUT;
5399     }
5400 
5401     /**
5402      * Handle the death notification if it's a dying app.
5403      *
5404      * @return {@code true} if it's a dying app that we were tracking.
5405      */
5406     @GuardedBy("mService")
5407     boolean handleDyingAppDeathLocked(ProcessRecord app, int pid) {
5408         if (mProcessNames.get(app.processName, app.uid) != app
5409                 && mDyingProcesses.get(app.processName, app.uid) == app) {
5410             // App has been removed already, meaning cleanup has done.
5411             Slog.v(TAG, "Got obituary of " + pid + ":" + app.processName);
5412             app.unlinkDeathRecipient();
5413             // It's really gone now, let's remove from the dying process list.
5414             mDyingProcesses.remove(app.processName, app.uid);
5415             app.setDyingPid(0);
5416             handlePrecedingAppDiedLocked(app);
5417             // Remove from the LRU list if it's still there.
5418             removeLruProcessLocked(app);
5419             return true;
5420         }
5421         return false;
5422     }
5423 
5424     /**
5425      * Handle the case where the given app is a preceding instance of another process instance.
5426      *
5427      * @return {@code false} if this given app should not be allowed to restart.
5428      */
5429     @GuardedBy("mService")
5430     boolean handlePrecedingAppDiedLocked(ProcessRecord app) {
5431         if (app.mSuccessor != null) {
5432             // We don't allow restart with this ProcessRecord now,
5433             // because we have created a new one already.
5434             // If it's persistent, add the successor to mPersistentStartingProcesses
5435             if (app.isPersistent() && !app.isRemoved()) {
5436                 if (mService.mPersistentStartingProcesses.indexOf(app.mSuccessor) < 0) {
5437                     mService.mPersistentStartingProcesses.add(app.mSuccessor);
5438                 }
5439             }
5440             // clean up the field so the successor's proc starter could proceed.
5441             app.mSuccessor.mPredecessor = null;
5442             app.mSuccessor = null;
5443             // Remove any pending timeout msg.
5444             mService.mProcStartHandler.removeMessages(
5445                     ProcStartHandler.MSG_PROCESS_KILL_TIMEOUT, app);
5446             // Kick off the proc start for the succeeding instance
5447             mService.mProcStartHandler.obtainMessage(
5448                     ProcStartHandler.MSG_PROCESS_DIED, app).sendToTarget();
5449             return false;
5450         }
5451         return true;
5452     }
5453 
5454     @GuardedBy("mService")
5455     void updateBackgroundRestrictedForUidPackageLocked(int uid, String packageName,
5456             boolean restricted) {
5457         final UidRecord uidRec = getUidRecordLOSP(uid);
5458         if (uidRec != null) {
5459             final long nowElapsed = SystemClock.elapsedRealtime();
5460             uidRec.forEachProcess(app -> {
5461                 if (TextUtils.equals(app.info.packageName, packageName)) {
5462                     app.mState.setBackgroundRestricted(restricted);
5463                     if (restricted) {
5464                         mAppsInBackgroundRestricted.add(app);
5465                         final long future = killAppIfBgRestrictedAndCachedIdleLocked(
5466                                 app, nowElapsed);
5467                         if (future > 0
5468                                 && (mService.mDeterministicUidIdle
5469                                         || !mService.mHandler.hasMessages(IDLE_UIDS_MSG))) {
5470                             mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
5471                                     future - nowElapsed);
5472                         }
5473                     } else {
5474                         mAppsInBackgroundRestricted.remove(app);
5475                     }
5476                     if (!app.isKilledByAm()) {
5477                         mService.enqueueOomAdjTargetLocked(app);
5478                     }
5479                 }
5480             });
5481             /* Will be a no-op if nothing pending */
5482             mService.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_RESTRICTION_CHANGE);
5483         }
5484     }
5485 
5486     /**
5487      * Kill the given app if it's in cached idle and background restricted mode.
5488      *
5489      * @return A future timestamp when the app should be killed at, or a 0 if it shouldn't
5490      * be killed or it has been killed.
5491      */
5492     @GuardedBy("mService")
5493     long killAppIfBgRestrictedAndCachedIdleLocked(ProcessRecord app, long nowElapsed) {
5494         final UidRecord uidRec = app.getUidRecord();
5495         final long lastCanKillTime = app.mState.getLastCanKillOnBgRestrictedAndIdleTime();
5496         if (!mService.mConstants.mKillBgRestrictedAndCachedIdle
5497                 || app.isKilled() || app.getThread() == null || uidRec == null || !uidRec.isIdle()
5498                 || !app.isCached() || app.mState.shouldNotKillOnBgRestrictedAndIdle()
5499                 || !app.mState.isBackgroundRestricted() || lastCanKillTime == 0) {
5500             return 0;
5501         }
5502         final long future = lastCanKillTime
5503                 + mService.mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs;
5504         if (future <= nowElapsed) {
5505             app.killLocked("cached idle & background restricted",
5506                     ApplicationExitInfo.REASON_OTHER,
5507                     ApplicationExitInfo.SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY,
5508                     true);
5509             return 0;
5510         }
5511         return future;
5512     }
5513 
5514     /**
5515      * Called by {@link ActivityManagerService#enqueueUidChangeLocked} only, it doesn't schedule
5516      * the standy killing checks because it should have been scheduled before enqueueing UID idle
5517      * changed.
5518      */
5519     @GuardedBy("mService")
5520     void killAppIfBgRestrictedAndCachedIdleLocked(UidRecord uidRec) {
5521         final long nowElapsed = SystemClock.elapsedRealtime();
5522         uidRec.forEachProcess(app -> killAppIfBgRestrictedAndCachedIdleLocked(app, nowElapsed));
5523     }
5524 
5525     /**
5526      * Called by ActivityManagerService when a process died.
5527      */
5528     @GuardedBy("mService")
5529     void noteProcessDiedLocked(final ProcessRecord app) {
5530         if (DEBUG_PROCESSES) {
5531             Slog.i(TAG, "note: " + app + " died, saving the exit info");
5532         }
5533 
5534         Watchdog.getInstance().processDied(app.processName, app.getPid());
5535         if (app.getDeathRecipient() == null
5536                 && mDyingProcesses.get(app.processName, app.uid) == app) {
5537             // If we've done unlinkDeathRecipient before calling into this, remove from dying list.
5538             mDyingProcesses.remove(app.processName, app.uid);
5539             app.setDyingPid(0);
5540         }
5541         mAppExitInfoTracker.scheduleNoteProcessDied(app);
5542     }
5543 
5544     /**
5545      * Called by ActivityManagerService when a recoverable native crash occurs.
5546      */
5547     @GuardedBy("mService")
5548     void noteAppRecoverableCrash(final ProcessRecord app) {
5549         if (DEBUG_PROCESSES) {
5550             Slog.i(TAG, "note: " + app + " has a recoverable native crash");
5551         }
5552         mAppExitInfoTracker.scheduleNoteAppRecoverableCrash(app);
5553     }
5554 
5555     /**
5556      * Called by ActivityManagerService when it decides to kill an application process.
5557      */
5558     @GuardedBy("mService")
5559     void noteAppKill(final ProcessRecord app, final @Reason int reason,
5560             final @SubReason int subReason, final String msg) {
5561         if (DEBUG_PROCESSES) {
5562             Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
5563                     + ", sub-reason: " + subReason + ", message: " + msg);
5564         }
5565         if (app.getPid() > 0 && !app.isolated && app.getDeathRecipient() != null) {
5566             // We are killing it, put it into the dying process list.
5567             mDyingProcesses.put(app.processName, app.uid, app);
5568             app.setDyingPid(app.getPid());
5569         }
5570         mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg);
5571     }
5572 
5573     @GuardedBy("mService")
5574     void noteAppKill(final int pid, final int uid, final @Reason int reason,
5575             final @SubReason int subReason, final String msg) {
5576         if (DEBUG_PROCESSES) {
5577             Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason
5578                     + ", sub-reason: " + subReason + ", message: " + msg);
5579         }
5580 
5581         final ProcessRecord app;
5582         synchronized (mService.mPidsSelfLocked) {
5583             app = mService.mPidsSelfLocked.get(pid);
5584         }
5585         if (app != null && app.uid == uid && !app.isolated && app.getDeathRecipient() != null) {
5586             // We are killing it, put it into the dying process list.
5587             mDyingProcesses.put(app.processName, uid, app);
5588             app.setDyingPid(app.getPid());
5589         }
5590         mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg);
5591     }
5592 
5593     /**
5594      * Schedule to kill the given pids when the device is idle
5595      */
5596     void killProcessesWhenImperceptible(int[] pids, String reason, int requester) {
5597         if (ArrayUtils.isEmpty(pids)) {
5598             return;
5599         }
5600 
5601         synchronized (mService) {
5602             ProcessRecord app;
5603             for (int i = 0; i < pids.length; i++) {
5604                 synchronized (mService.mPidsSelfLocked) {
5605                     app = mService.mPidsSelfLocked.get(pids[i]);
5606                 }
5607                 if (app != null) {
5608                     mImperceptibleKillRunner.enqueueLocked(app, reason, requester);
5609                 }
5610             }
5611         }
5612     }
5613 
5614     /**
5615      * Get the number of foreground services in all processes and number of processes that have
5616      * foreground service within.
5617      */
5618     Pair<Integer, Integer> getNumForegroundServices() {
5619         int numForegroundServices = 0;
5620         int procs = 0;
5621         synchronized (mService) {
5622             for (int i = 0, size = mLruProcesses.size(); i < size; i++) {
5623                 ProcessRecord pr = mLruProcesses.get(i);
5624                 int numFgs = pr.mServices.getNumForegroundServices();
5625                 if (numFgs > 0) {
5626                     numForegroundServices += numFgs;
5627                     procs++;
5628                 }
5629             }
5630         }
5631         return new Pair<>(numForegroundServices, procs);
5632     }
5633 
5634     private final class ImperceptibleKillRunner extends UidObserver {
5635         private static final String EXTRA_PID = "pid";
5636         private static final String EXTRA_UID = "uid";
5637         private static final String EXTRA_TIMESTAMP = "timestamp";
5638         private static final String EXTRA_REASON = "reason";
5639         private static final String EXTRA_REQUESTER = "requester";
5640 
5641         private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill";
5642         private static final boolean LOG_TO_DROPBOX = false;
5643 
5644         // uid -> killing information mapping
5645         private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>();
5646 
5647         // The last time the various processes have been killed by us.
5648         private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>();
5649 
5650         // Device idle or not.
5651         private volatile boolean mIdle;
5652         private boolean mUidObserverEnabled;
5653         private Handler mHandler;
5654         private IdlenessReceiver mReceiver;
5655 
5656         private final class H extends Handler {
5657             static final int MSG_DEVICE_IDLE = 0;
5658             static final int MSG_UID_GONE = 1;
5659             static final int MSG_UID_STATE_CHANGED = 2;
5660 
5661             H(Looper looper) {
5662                 super(looper);
5663             }
5664 
5665             @Override
5666             public void handleMessage(Message msg) {
5667                 switch (msg.what) {
5668                     case MSG_DEVICE_IDLE:
5669                         handleDeviceIdle();
5670                         break;
5671                     case MSG_UID_GONE:
5672                         handleUidGone(msg.arg1 /* uid */);
5673                         break;
5674                     case MSG_UID_STATE_CHANGED:
5675                         handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */);
5676                         break;
5677                 }
5678             }
5679         }
5680 
5681         private final class IdlenessReceiver extends BroadcastReceiver {
5682             @Override
5683             public void onReceive(Context context, Intent intent) {
5684                 final PowerManager pm = mService.mContext.getSystemService(PowerManager.class);
5685                 switch (intent.getAction()) {
5686                     case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
5687                         notifyDeviceIdleness(pm.isLightDeviceIdleMode());
5688                         break;
5689                     case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
5690                         notifyDeviceIdleness(pm.isDeviceIdleMode());
5691                         break;
5692                 }
5693             }
5694         }
5695 
5696         ImperceptibleKillRunner(Looper looper) {
5697             mHandler = new H(looper);
5698         }
5699 
5700         @GuardedBy("mService")
5701         boolean enqueueLocked(ProcessRecord app, String reason, int requester) {
5702             // Throttle the killing request for potential bad app to avoid cpu thrashing
5703             Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid);
5704             if ((last != null) && (SystemClock.uptimeMillis()
5705                     < (last + ActivityManagerConstants.MIN_CRASH_INTERVAL))) {
5706                 return false;
5707             }
5708 
5709             final Bundle bundle = new Bundle();
5710             bundle.putInt(EXTRA_PID, app.getPid());
5711             bundle.putInt(EXTRA_UID, app.uid);
5712             // Since the pid could be reused, let's get the actual start time of each process
5713             bundle.putLong(EXTRA_TIMESTAMP, app.getStartTime());
5714             bundle.putString(EXTRA_REASON, reason);
5715             bundle.putInt(EXTRA_REQUESTER, requester);
5716             List<Bundle> list = mWorkItems.get(app.uid);
5717             if (list == null) {
5718                 list = new ArrayList<Bundle>();
5719                 mWorkItems.put(app.uid, list);
5720             }
5721             list.add(bundle);
5722             if (mReceiver == null) {
5723                 mReceiver = new IdlenessReceiver();
5724                 IntentFilter filter = new IntentFilter(
5725                         PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
5726                 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
5727                 mService.mContext.registerReceiver(mReceiver, filter);
5728             }
5729             return true;
5730         }
5731 
5732         void notifyDeviceIdleness(boolean idle) {
5733             // No lock is held regarding mIdle, this function is the only updater and caller
5734             // won't re-entry.
5735             boolean diff = mIdle != idle;
5736             mIdle = idle;
5737             if (diff && idle) {
5738                 synchronized (mService) {
5739                     if (mWorkItems.size() > 0) {
5740                         mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE);
5741                     }
5742                 }
5743             }
5744         }
5745 
5746         private void handleDeviceIdle() {
5747             final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
5748             final boolean logToDropbox = LOG_TO_DROPBOX && dbox != null
5749                     && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
5750 
5751             synchronized (mService) {
5752                 final int size = mWorkItems.size();
5753                 for (int i = size - 1; mIdle && i >= 0; i--) {
5754                     List<Bundle> list = mWorkItems.valueAt(i);
5755                     final int len = list.size();
5756                     for (int j = len - 1; mIdle && j >= 0; j--) {
5757                         Bundle bundle = list.get(j);
5758                         if (killProcessLocked(
5759                                 bundle.getInt(EXTRA_PID),
5760                                 bundle.getInt(EXTRA_UID),
5761                                 bundle.getLong(EXTRA_TIMESTAMP),
5762                                 bundle.getString(EXTRA_REASON),
5763                                 bundle.getInt(EXTRA_REQUESTER),
5764                                 dbox, logToDropbox)) {
5765                             list.remove(j);
5766                         }
5767                     }
5768                     if (list.size() == 0) {
5769                         mWorkItems.removeAt(i);
5770                     }
5771                 }
5772                 registerUidObserverIfNecessaryLocked();
5773             }
5774         }
5775 
5776         @GuardedBy("mService")
5777         private void registerUidObserverIfNecessaryLocked() {
5778             // If there are still works remaining, register UID observer
5779             if (!mUidObserverEnabled && mWorkItems.size() > 0) {
5780                 mUidObserverEnabled = true;
5781                 mService.registerUidObserver(this,
5782                         ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
5783                         ActivityManager.PROCESS_STATE_UNKNOWN, "android");
5784             } else if (mUidObserverEnabled && mWorkItems.size() == 0) {
5785                 mUidObserverEnabled = false;
5786                 mService.unregisterUidObserver(this);
5787             }
5788         }
5789 
5790         /**
5791          * Kill the given processes, if they are not exempted.
5792          *
5793          * @return True if the process is killed, or it's gone already, or we are not allowed to
5794          *         kill it (one of the packages in this process is being exempted).
5795          */
5796         @GuardedBy("mService")
5797         private boolean killProcessLocked(final int pid, final int uid, final long timestamp,
5798                 final String reason, final int requester, final DropBoxManager dbox,
5799                 final boolean logToDropbox) {
5800             ProcessRecord app = null;
5801             synchronized (mService.mPidsSelfLocked) {
5802                 app = mService.mPidsSelfLocked.get(pid);
5803             }
5804 
5805             if (app == null || app.getPid() != pid || app.uid != uid
5806                     || app.getStartTime() != timestamp) {
5807                 // This process record has been reused for another process, meaning the old process
5808                 // has been gone.
5809                 return true;
5810             }
5811 
5812             if (app.getPkgList().searchEachPackage(pkgName -> {
5813                 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(pkgName)) {
5814                     // One of the packages in this process is exempted
5815                     return Boolean.TRUE;
5816                 }
5817                 return null;
5818             }) != null) {
5819                 return true;
5820             }
5821 
5822             if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(
5823                     app.mState.getReportedProcState())) {
5824                 // We need to reschedule it.
5825                 return false;
5826             }
5827 
5828             app.killLocked(reason, ApplicationExitInfo.REASON_OTHER,
5829                     ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true);
5830 
5831             if (!app.isolated) {
5832                 mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());
5833             }
5834 
5835             if (logToDropbox) {
5836                 final long now = SystemClock.elapsedRealtime();
5837                 final StringBuilder sb = new StringBuilder();
5838                 mService.appendDropBoxProcessHeaders(app, app.processName, null, sb);
5839                 sb.append("Reason: " + reason).append("\n");
5840                 sb.append("Requester UID: " + requester).append("\n");
5841                 dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString());
5842             }
5843             return true;
5844         }
5845 
5846         private void handleUidStateChanged(int uid, int procState) {
5847             final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
5848             final boolean logToDropbox = dbox != null
5849                     && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
5850             synchronized (mService) {
5851                 if (mIdle && !mService.mConstants
5852                         .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) {
5853                     List<Bundle> list = mWorkItems.get(uid);
5854                     if (list != null) {
5855                         final int len = list.size();
5856                         for (int j = len - 1; mIdle && j >= 0; j--) {
5857                             Bundle bundle = list.get(j);
5858                             if (killProcessLocked(
5859                                     bundle.getInt(EXTRA_PID),
5860                                     bundle.getInt(EXTRA_UID),
5861                                     bundle.getLong(EXTRA_TIMESTAMP),
5862                                     bundle.getString(EXTRA_REASON),
5863                                     bundle.getInt(EXTRA_REQUESTER),
5864                                     dbox, logToDropbox)) {
5865                                 list.remove(j);
5866                             }
5867                         }
5868                         if (list.size() == 0) {
5869                             mWorkItems.remove(uid);
5870                         }
5871                         registerUidObserverIfNecessaryLocked();
5872                     }
5873                 }
5874             }
5875         }
5876 
5877         private void handleUidGone(int uid) {
5878             synchronized (mService) {
5879                 mWorkItems.remove(uid);
5880                 registerUidObserverIfNecessaryLocked();
5881             }
5882         }
5883 
5884         @Override
5885         public void onUidGone(int uid, boolean disabled) {
5886             mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget();
5887         }
5888 
5889         @Override
5890         public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
5891             mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
5892         }
5893     };
5894 }
5895