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