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