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