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