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_STATE_CACHED_ACTIVITY;
20 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
21 import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
22 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
23 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
24 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
25 import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
26 import static android.os.Process.SYSTEM_UID;
27 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
28 import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
29 import static android.os.Process.getFreeMemory;
30 import static android.os.Process.getTotalMemory;
31 import static android.os.Process.killProcessQuiet;
32 import static android.os.Process.startWebView;
33 
34 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
35 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
36 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
37 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
38 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
39 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
40 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
41 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS;
42 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG;
43 import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK;
44 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT;
45 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG;
46 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER;
47 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
48 import static com.android.server.am.ActivityManagerService.TAG_LRU;
49 import static com.android.server.am.ActivityManagerService.TAG_NETWORK;
50 import static com.android.server.am.ActivityManagerService.TAG_PROCESSES;
51 import static com.android.server.am.ActivityManagerService.TAG_PSS;
52 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
53 
54 import android.app.ActivityManager;
55 import android.app.ActivityThread;
56 import android.app.AppGlobals;
57 import android.app.AppProtoEnums;
58 import android.app.ApplicationExitInfo;
59 import android.app.ApplicationExitInfo.Reason;
60 import android.app.ApplicationExitInfo.SubReason;
61 import android.app.IApplicationThread;
62 import android.app.IUidObserver;
63 import android.compat.annotation.ChangeId;
64 import android.compat.annotation.Disabled;
65 import android.compat.annotation.EnabledAfter;
66 import android.content.BroadcastReceiver;
67 import android.content.ComponentName;
68 import android.content.Context;
69 import android.content.Intent;
70 import android.content.IntentFilter;
71 import android.content.pm.ApplicationInfo;
72 import android.content.pm.IPackageManager;
73 import android.content.pm.PackageManagerInternal;
74 import android.content.res.Resources;
75 import android.graphics.Point;
76 import android.net.LocalSocket;
77 import android.net.LocalSocketAddress;
78 import android.os.AppZygote;
79 import android.os.Binder;
80 import android.os.Build;
81 import android.os.Bundle;
82 import android.os.DropBoxManager;
83 import android.os.Handler;
84 import android.os.IBinder;
85 import android.os.Looper;
86 import android.os.Message;
87 import android.os.PowerManager;
88 import android.os.Process;
89 import android.os.RemoteException;
90 import android.os.StrictMode;
91 import android.os.SystemClock;
92 import android.os.SystemProperties;
93 import android.os.Trace;
94 import android.os.UserHandle;
95 import android.os.storage.StorageManager;
96 import android.os.storage.StorageManagerInternal;
97 import android.system.Os;
98 import android.text.TextUtils;
99 import android.util.ArrayMap;
100 import android.util.ArraySet;
101 import android.util.EventLog;
102 import android.util.LongSparseArray;
103 import android.util.Pair;
104 import android.util.Slog;
105 import android.util.SparseArray;
106 import android.util.SparseBooleanArray;
107 import android.view.Display;
108 
109 import com.android.internal.annotations.GuardedBy;
110 import com.android.internal.annotations.VisibleForTesting;
111 import com.android.internal.app.ProcessMap;
112 import com.android.internal.app.procstats.ProcessStats;
113 import com.android.internal.os.Zygote;
114 import com.android.internal.util.ArrayUtils;
115 import com.android.internal.util.FrameworkStatsLog;
116 import com.android.internal.util.MemInfoReader;
117 import com.android.server.LocalServices;
118 import com.android.server.ServiceThread;
119 import com.android.server.SystemConfig;
120 import com.android.server.Watchdog;
121 import com.android.server.compat.PlatformCompat;
122 import com.android.server.pm.dex.DexManager;
123 import com.android.server.pm.parsing.pkg.AndroidPackage;
124 import com.android.server.wm.ActivityServiceConnectionsHolder;
125 import com.android.server.wm.WindowManagerService;
126 
127 import dalvik.annotation.compat.VersionCodes;
128 import dalvik.system.VMRuntime;
129 
130 import java.io.File;
131 import java.io.FileDescriptor;
132 import java.io.IOException;
133 import java.io.OutputStream;
134 import java.io.PrintWriter;
135 import java.nio.ByteBuffer;
136 import java.util.ArrayList;
137 import java.util.Arrays;
138 import java.util.BitSet;
139 import java.util.HashMap;
140 import java.util.List;
141 import java.util.Map;
142 import java.util.Set;
143 
144 /**
145  * Activity manager code dealing with processes.
146  */
147 public final class ProcessList {
148     static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
149 
150     // A system property to control if app data isolation is enabled.
151     static final String ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY =
152             "persist.zygote.app_data_isolation";
153 
154     // A system property to control if obb app data isolation is enabled in vold.
155     static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
156             "persist.sys.vold_app_data_isolation_enabled";
157 
158     // A system property to control if fuse is enabled.
159     static final String ANDROID_FUSE_ENABLED = "persist.sys.fuse";
160 
161     // The minimum time we allow between crashes, for us to consider this
162     // application to be bad and stop and its services and reject broadcasts.
163     static final int MIN_CRASH_INTERVAL = 60 * 1000;
164 
165     // OOM adjustments for processes in various states:
166 
167     // Uninitialized value for any major or minor adj fields
168     static final int INVALID_ADJ = -10000;
169 
170     // Adjustment used in certain places where we don't know it yet.
171     // (Generally this is something that is going to be cached, but we
172     // don't know the exact value in the cached range to assign yet.)
173     static final int UNKNOWN_ADJ = 1001;
174 
175     // This is a process only hosting activities that are not visible,
176     // so it can be killed without any disruption.
177     static final int CACHED_APP_MAX_ADJ = 999;
178     static final int CACHED_APP_MIN_ADJ = 900;
179 
180     // This is the oom_adj level that we allow to die first. This cannot be equal to
181     // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
182     // CACHED_APP_MAX_ADJ.
183     static final int CACHED_APP_LMK_FIRST_ADJ = 950;
184 
185     // Number of levels we have available for different service connection group importance
186     // levels.
187     static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
188 
189     // The B list of SERVICE_ADJ -- these are the old and decrepit
190     // services that aren't as shiny and interesting as the ones in the A list.
191     static final int SERVICE_B_ADJ = 800;
192 
193     // This is the process of the previous application that the user was in.
194     // This process is kept above other things, because it is very common to
195     // switch back to the previous app.  This is important both for recent
196     // task switch (toggling between the two top recent apps) as well as normal
197     // UI flow such as clicking on a URI in the e-mail app to view in the browser,
198     // and then pressing back to return to e-mail.
199     static final int PREVIOUS_APP_ADJ = 700;
200 
201     // This is a process holding the home application -- we want to try
202     // avoiding killing it, even if it would normally be in the background,
203     // because the user interacts with it so much.
204     static final int HOME_APP_ADJ = 600;
205 
206     // This is a process holding an application service -- killing it will not
207     // have much of an impact as far as the user is concerned.
208     static final int SERVICE_ADJ = 500;
209 
210     // This is a process with a heavy-weight application.  It is in the
211     // background, but we want to try to avoid killing it.  Value set in
212     // system/rootdir/init.rc on startup.
213     static final int HEAVY_WEIGHT_APP_ADJ = 400;
214 
215     // This is a process currently hosting a backup operation.  Killing it
216     // is not entirely fatal but is generally a bad idea.
217     static final int BACKUP_APP_ADJ = 300;
218 
219     // This is a process bound by the system (or other app) that's more important than services but
220     // not so perceptible that it affects the user immediately if killed.
221     static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
222 
223     // This is a process only hosting components that are perceptible to the
224     // user, and we really want to avoid killing them, but they are not
225     // immediately visible. An example is background music playback.
226     static final int PERCEPTIBLE_APP_ADJ = 200;
227 
228     // This is a process only hosting activities that are visible to the
229     // user, so we'd prefer they don't disappear.
230     static final int VISIBLE_APP_ADJ = 100;
231     static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
232 
233     // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
234     // like a foreground app for a while.
235     // @see TOP_TO_FGS_GRACE_PERIOD
236     static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
237 
238     // This is the process running the current foreground app.  We'd really
239     // rather not kill it!
240     static final int FOREGROUND_APP_ADJ = 0;
241 
242     // This is a process that the system or a persistent process has bound to,
243     // and indicated it is important.
244     static final int PERSISTENT_SERVICE_ADJ = -700;
245 
246     // This is a system persistent process, such as telephony.  Definitely
247     // don't want to kill it, but doing so is not completely fatal.
248     static final int PERSISTENT_PROC_ADJ = -800;
249 
250     // The system process runs at the default adjustment.
251     static final int SYSTEM_ADJ = -900;
252 
253     // Special code for native processes that are not being managed by the system (so
254     // don't have an oom adj assigned by the system).
255     static final int NATIVE_ADJ = -1000;
256 
257     // Memory pages are 4K.
258     static final int PAGE_SIZE = 4 * 1024;
259 
260     // Activity manager's version of Process.THREAD_GROUP_BACKGROUND
261     static final int SCHED_GROUP_BACKGROUND = 0;
262       // Activity manager's version of Process.THREAD_GROUP_RESTRICTED
263     static final int SCHED_GROUP_RESTRICTED = 1;
264     // Activity manager's version of Process.THREAD_GROUP_DEFAULT
265     static final int SCHED_GROUP_DEFAULT = 2;
266     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
267     public static final int SCHED_GROUP_TOP_APP = 3;
268     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
269     // Disambiguate between actual top app and processes bound to the top app
270     static final int SCHED_GROUP_TOP_APP_BOUND = 4;
271 
272     // The minimum number of cached apps we want to be able to keep around,
273     // without empty apps being able to push them out of memory.
274     static final int MIN_CACHED_APPS = 2;
275 
276     // We allow empty processes to stick around for at most 30 minutes.
277     static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
278 
279     // Threshold of number of cached+empty where we consider memory critical.
280     static final int TRIM_CRITICAL_THRESHOLD = 3;
281 
282     // Threshold of number of cached+empty where we consider memory critical.
283     static final int TRIM_LOW_THRESHOLD = 5;
284 
285     /**
286      * State indicating that there is no need for any blocking for network.
287      */
288     @VisibleForTesting
289     static final int NETWORK_STATE_NO_CHANGE = 0;
290 
291     /**
292      * State indicating that the main thread needs to be informed about the network wait.
293      */
294     @VisibleForTesting
295     static final int NETWORK_STATE_BLOCK = 1;
296 
297     /**
298      * State indicating that any threads waiting for network state to get updated can be unblocked.
299      */
300     @VisibleForTesting
301     static final int NETWORK_STATE_UNBLOCK = 2;
302 
303     // If true, then we pass the flag to ART to load the app image startup cache.
304     private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
305             "persist.device_config.runtime_native.use_app_image_startup_cache";
306 
307     // The socket path for zygote to send unsolicited msg.
308     // Must keep sync with com_android_internal_os_Zygote.cpp.
309     private static final String UNSOL_ZYGOTE_MSG_SOCKET_PATH = "/data/system/unsolzygotesocket";
310 
311     // Low Memory Killer Daemon command codes.
312     // These must be kept in sync with lmk_cmd definitions in lmkd.h
313     //
314     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
315     // LMK_PROCPRIO <pid> <uid> <prio>
316     // LMK_PROCREMOVE <pid>
317     // LMK_PROCPURGE
318     // LMK_GETKILLCNT
319     // LMK_SUBSCRIBE
320     // LMK_PROCKILL
321     static final byte LMK_TARGET = 0;
322     static final byte LMK_PROCPRIO = 1;
323     static final byte LMK_PROCREMOVE = 2;
324     static final byte LMK_PROCPURGE = 3;
325     static final byte LMK_GETKILLCNT = 4;
326     static final byte LMK_SUBSCRIBE = 5;
327     static final byte LMK_PROCKILL = 6; // Note: this is an unsolicated command
328 
329     // Low Memory Killer Daemon command codes.
330     // These must be kept in sync with async_event_type definitions in lmkd.h
331     //
332     static final int LMK_ASYNC_EVENT_KILL = 0;
333 
334     // lmkd reconnect delay in msecs
335     private static final long LMKD_RECONNECT_DELAY_MS = 1000;
336 
337     /**
338      * How long between a process kill and we actually receive its death recipient
339      */
340     private static final int PROC_KILL_TIMEOUT = 2000; // 2 seconds;
341 
342     /**
343      * Native heap allocations will now have a non-zero tag in the most significant byte.
344      * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged
345      * Pointers</a>
346      */
347     @ChangeId
348     @EnabledAfter(targetSdkVersion = VersionCodes.Q)
349     private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id.
350 
351     /**
352      * Enable sampled memory bug detection in the app.
353      * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>.
354      */
355     @ChangeId
356     @Disabled
357     private static final long GWP_ASAN = 135634846; // This is a bug id.
358 
359     /**
360      * Apps have no access to the private data directories of any other app, even if the other
361      * app has made them world-readable.
362      */
363     @ChangeId
364     @EnabledAfter(targetSdkVersion = VersionCodes.Q)
365     private static final long APP_DATA_DIRECTORY_ISOLATION = 143937733; // See b/143937733
366 
367     ActivityManagerService mService = null;
368 
369     // To kill process groups asynchronously
370     static KillHandler sKillHandler = null;
371     static ServiceThread sKillThread = null;
372 
373     // These are the various interesting memory levels that we will give to
374     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
375     // can't give it a different value for every possible kind of process.
376     private final int[] mOomAdj = new int[] {
377             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
378             PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
379     };
380     // These are the low-end OOM level limits.  This is appropriate for an
381     // HVGA or smaller phone with less than 512MB.  Values are in KB.
382     private final int[] mOomMinFreeLow = new int[] {
383             12288, 18432, 24576,
384             36864, 43008, 49152
385     };
386     // These are the high-end OOM level limits.  This is appropriate for a
387     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
388     private final int[] mOomMinFreeHigh = new int[] {
389             73728, 92160, 110592,
390             129024, 147456, 184320
391     };
392     // The actual OOM killer memory levels we are using.
393     private final int[] mOomMinFree = new int[mOomAdj.length];
394 
395     private final long mTotalMemMb;
396 
397     private long mCachedRestoreLevel;
398 
399     private boolean mHaveDisplaySize;
400 
401     private static LmkdConnection sLmkdConnection = null;
402 
403     private boolean mOomLevelsSet = false;
404 
405     private boolean mAppDataIsolationEnabled = false;
406 
407     private boolean mVoldAppDataIsolationEnabled = false;
408 
409     private ArrayList<String> mAppDataIsolationWhitelistedApps;
410 
411     /**
412      * Temporary to avoid allocations.  Protected by main lock.
413      */
414     @GuardedBy("mService")
415     final StringBuilder mStringBuilder = new StringBuilder(256);
416 
417     /**
418      * A global counter for generating sequence numbers.
419      * This value will be used when incrementing sequence numbers in individual uidRecords.
420      *
421      * Having a global counter ensures that seq numbers are monotonically increasing for a
422      * particular uid even when the uidRecord is re-created.
423      */
424     @GuardedBy("mService")
425     @VisibleForTesting
426     long mProcStateSeqCounter = 0;
427 
428     /**
429      * A global counter for generating sequence numbers to uniquely identify pending process starts.
430      */
431     @GuardedBy("mService")
432     private long mProcStartSeqCounter = 0;
433 
434     /**
435      * Contains {@link ProcessRecord} objects for pending process starts.
436      *
437      * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
438      */
439     @GuardedBy("mService")
440     final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
441 
442     /**
443      * List of running applications, sorted by recent usage.
444      * The first entry in the list is the least recently used.
445      */
446     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
447 
448     /**
449      * Where in mLruProcesses that the processes hosting activities start.
450      */
451     int mLruProcessActivityStart = 0;
452 
453     /**
454      * Where in mLruProcesses that the processes hosting services start.
455      * This is after (lower index) than mLruProcessesActivityStart.
456      */
457     int mLruProcessServiceStart = 0;
458 
459     /**
460      * Current sequence id for process LRU updating.
461      */
462     int mLruSeq = 0;
463 
464     ActiveUids mActiveUids;
465 
466     /**
467      * The currently running isolated processes.
468      */
469     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
470 
471     /**
472      * The currently running application zygotes.
473      */
474     final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
475 
476     /**
477      * Managees the {@link android.app.ApplicationExitInfo} records.
478      */
479     @GuardedBy("mAppExitInfoTracker")
480     final AppExitInfoTracker mAppExitInfoTracker = new AppExitInfoTracker();
481 
482     /**
483      * The processes that are forked off an application zygote.
484      */
485     final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses =
486             new ArrayMap<AppZygote, ArrayList<ProcessRecord>>();
487 
488     private PlatformCompat mPlatformCompat = null;
489 
490     /**
491      * The server socket in system_server, zygote will connect to it
492      * in order to send unsolicited messages to system_server.
493      */
494     private LocalSocket mSystemServerSocketForZygote;
495 
496     /**
497      * Maximum number of bytes that an incoming unsolicited zygote message could be.
498      * To be updated if new message type needs to be supported.
499      */
500     private static final int MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE = 16;
501 
502     /**
503      * The buffer to be used to receive the incoming unsolicited zygote message.
504      */
505     private final byte[] mZygoteUnsolicitedMessage = new byte[MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE];
506 
507     /**
508      * The buffer to be used to receive the SIGCHLD data, it includes pid/uid/status.
509      */
510     private final int[] mZygoteSigChldMessage = new int[3];
511 
512     final class IsolatedUidRange {
513         @VisibleForTesting
514         public final int mFirstUid;
515         @VisibleForTesting
516         public final int mLastUid;
517 
518         @GuardedBy("ProcessList.this.mService")
519         private final SparseBooleanArray mUidUsed = new SparseBooleanArray();
520 
521         @GuardedBy("ProcessList.this.mService")
522         private int mNextUid;
523 
IsolatedUidRange(int firstUid, int lastUid)524         IsolatedUidRange(int firstUid, int lastUid) {
525             mFirstUid = firstUid;
526             mLastUid = lastUid;
527             mNextUid = firstUid;
528         }
529 
530         @GuardedBy("ProcessList.this.mService")
allocateIsolatedUidLocked(int userId)531         int allocateIsolatedUidLocked(int userId) {
532             int uid;
533             int stepsLeft = (mLastUid - mFirstUid + 1);
534             for (int i = 0; i < stepsLeft; ++i) {
535                 if (mNextUid < mFirstUid || mNextUid > mLastUid) {
536                     mNextUid = mFirstUid;
537                 }
538                 uid = UserHandle.getUid(userId, mNextUid);
539                 mNextUid++;
540                 if (!mUidUsed.get(uid, false)) {
541                     mUidUsed.put(uid, true);
542                     return uid;
543                 }
544             }
545             return -1;
546         }
547 
548         @GuardedBy("ProcessList.this.mService")
freeIsolatedUidLocked(int uid)549         void freeIsolatedUidLocked(int uid) {
550             mUidUsed.delete(uid);
551         }
552     };
553 
554     /**
555      * A class that allocates ranges of isolated UIDs per application, and keeps track of them.
556      */
557     final class IsolatedUidRangeAllocator {
558         private final int mFirstUid;
559         private final int mNumUidRanges;
560         private final int mNumUidsPerRange;
561         /**
562          * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange)
563          * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that.
564          */
565         @GuardedBy("ProcessList.this.mService")
566         private final BitSet mAvailableUidRanges;
567         @GuardedBy("ProcessList.this.mService")
568         private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>();
569 
IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange)570         IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) {
571             mFirstUid = firstUid;
572             mNumUidsPerRange = numUidsPerRange;
573             mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange;
574             mAvailableUidRanges = new BitSet(mNumUidRanges);
575             // Mark all as available
576             mAvailableUidRanges.set(0, mNumUidRanges);
577         }
578 
579         @GuardedBy("ProcessList.this.mService")
getIsolatedUidRangeLocked(String processName, int uid)580         IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) {
581             return mAppRanges.get(processName, uid);
582         }
583 
584         @GuardedBy("ProcessList.this.mService")
getOrCreateIsolatedUidRangeLocked(String processName, int uid)585         IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) {
586             IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid);
587             if (range == null) {
588                 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
589                 if (uidRangeIndex < 0) {
590                     // No free range
591                     return null;
592                 }
593                 mAvailableUidRanges.clear(uidRangeIndex);
594                 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
595                 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
596                 mAppRanges.put(processName, uid, range);
597             }
598             return range;
599         }
600 
601         @GuardedBy("ProcessList.this.mService")
freeUidRangeLocked(ApplicationInfo info)602         void freeUidRangeLocked(ApplicationInfo info) {
603             // Find the UID range
604             IsolatedUidRange range = mAppRanges.get(info.processName, info.uid);
605             if (range != null) {
606                 // Map back to starting uid
607                 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange;
608                 // Mark it as available in the underlying bitset
609                 mAvailableUidRanges.set(uidRangeIndex);
610                 // And the map
611                 mAppRanges.remove(info.processName, info.uid);
612             }
613         }
614     }
615 
616     /**
617      * The available isolated UIDs for processes that are not spawned from an application zygote.
618      */
619     @VisibleForTesting
620     IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID,
621             Process.LAST_ISOLATED_UID);
622 
623     /**
624      * An allocator for isolated UID ranges for apps that use an application zygote.
625      */
626     @VisibleForTesting
627     IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator =
628             new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
629                     Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE);
630 
631     /**
632      * Processes that are being forcibly torn down.
633      */
634     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
635 
636     /**
637      * All of the applications we currently have running organized by name.
638      * The keys are strings of the application package name (as
639      * returned by the package manager), and the keys are ApplicationRecord
640      * objects.
641      */
642     final MyProcessMap mProcessNames = new MyProcessMap();
643 
644     final class MyProcessMap extends ProcessMap<ProcessRecord> {
645         @Override
put(String name, int uid, ProcessRecord value)646         public ProcessRecord put(String name, int uid, ProcessRecord value) {
647             final ProcessRecord r = super.put(name, uid, value);
648             mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());
649             return r;
650         }
651 
652         @Override
remove(String name, int uid)653         public ProcessRecord remove(String name, int uid) {
654             final ProcessRecord r = super.remove(name, uid);
655             mService.mAtmInternal.onProcessRemoved(name, uid);
656             return r;
657         }
658     }
659 
660     final class KillHandler extends Handler {
661         static final int KILL_PROCESS_GROUP_MSG = 4000;
662         static final int LMKD_RECONNECT_MSG = 4001;
663 
KillHandler(Looper looper)664         public KillHandler(Looper looper) {
665             super(looper, null, true);
666         }
667 
668         @Override
handleMessage(Message msg)669         public void handleMessage(Message msg) {
670             switch (msg.what) {
671                 case KILL_PROCESS_GROUP_MSG:
672                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
673                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
674                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
675                     break;
676                 case LMKD_RECONNECT_MSG:
677                     if (!sLmkdConnection.connect()) {
678                         Slog.i(TAG, "Failed to connect to lmkd, retry after " +
679                                 LMKD_RECONNECT_DELAY_MS + " ms");
680                         // retry after LMKD_RECONNECT_DELAY_MS
681                         sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
682                                 KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
683                     }
684                     break;
685                 default:
686                     super.handleMessage(msg);
687             }
688         }
689     }
690 
691     /**
692      * A runner to handle the imperceptible killings.
693      */
694     ImperceptibleKillRunner mImperceptibleKillRunner;
695 
696     ////////////////////  END FIELDS  ////////////////////
697 
ProcessList()698     ProcessList() {
699         MemInfoReader minfo = new MemInfoReader();
700         minfo.readMemInfo();
701         mTotalMemMb = minfo.getTotalSize()/(1024*1024);
702         updateOomLevels(0, 0, false);
703     }
704 
init(ActivityManagerService service, ActiveUids activeUids, PlatformCompat platformCompat)705     void init(ActivityManagerService service, ActiveUids activeUids,
706             PlatformCompat platformCompat) {
707         mService = service;
708         mActiveUids = activeUids;
709         mPlatformCompat = platformCompat;
710         // Get this after boot, and won't be changed until it's rebooted, as we don't
711         // want some apps enabled while some apps disabled
712         mAppDataIsolationEnabled =
713                 SystemProperties.getBoolean(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true);
714         boolean fuseEnabled = SystemProperties.getBoolean(ANDROID_FUSE_ENABLED, false);
715         boolean voldAppDataIsolationEnabled = SystemProperties.getBoolean(
716                 ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false);
717         if (!fuseEnabled && voldAppDataIsolationEnabled) {
718             Slog.e(TAG, "Fuse is not enabled while vold app data isolation is enabled");
719         }
720         mVoldAppDataIsolationEnabled = fuseEnabled && voldAppDataIsolationEnabled;
721         mAppDataIsolationWhitelistedApps = new ArrayList<>(
722                 SystemConfig.getInstance().getAppDataIsolationWhitelistedApps());
723 
724         if (sKillHandler == null) {
725             sKillThread = new ServiceThread(TAG + ":kill",
726                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
727             sKillThread.start();
728             sKillHandler = new KillHandler(sKillThread.getLooper());
729             sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(),
730                     new LmkdConnection.LmkdConnectionListener() {
731                         @Override
732                         public boolean onConnect(OutputStream ostream) {
733                             Slog.i(TAG, "Connection with lmkd established");
734                             return onLmkdConnect(ostream);
735                         }
736 
737                         @Override
738                         public void onDisconnect() {
739                             Slog.w(TAG, "Lost connection to lmkd");
740                             // start reconnection after delay to let lmkd restart
741                             sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
742                                     KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
743                         }
744 
745                         @Override
746                         public boolean isReplyExpected(ByteBuffer replyBuf,
747                                 ByteBuffer dataReceived, int receivedLen) {
748                             // compare the preambule (currently one integer) to check if
749                             // this is the reply packet we are waiting for
750                             return (receivedLen == replyBuf.array().length &&
751                                     dataReceived.getInt(0) == replyBuf.getInt(0));
752                         }
753 
754                         @Override
755                         public boolean handleUnsolicitedMessage(ByteBuffer dataReceived,
756                                 int receivedLen) {
757                             if (receivedLen < 4) {
758                                 return false;
759                             }
760                             switch (dataReceived.getInt(0)) {
761                                 case LMK_PROCKILL:
762                                     if (receivedLen != 12) {
763                                         return false;
764                                     }
765                                     mAppExitInfoTracker.scheduleNoteLmkdProcKilled(
766                                             dataReceived.getInt(4), dataReceived.getInt(8));
767                                     return true;
768                                 default:
769                                     return false;
770                             }
771                         }
772                     }
773             );
774             // Start listening on incoming connections from zygotes.
775             mSystemServerSocketForZygote = createSystemServerSocketForZygote();
776             if (mSystemServerSocketForZygote != null) {
777                 sKillHandler.getLooper().getQueue().addOnFileDescriptorEventListener(
778                         mSystemServerSocketForZygote.getFileDescriptor(),
779                         EVENT_INPUT, this::handleZygoteMessages);
780             }
781             mAppExitInfoTracker.init(mService);
782             mImperceptibleKillRunner = new ImperceptibleKillRunner(sKillThread.getLooper());
783         }
784     }
785 
onSystemReady()786     void onSystemReady() {
787         mAppExitInfoTracker.onSystemReady();
788     }
789 
applyDisplaySize(WindowManagerService wm)790     void applyDisplaySize(WindowManagerService wm) {
791         if (!mHaveDisplaySize) {
792             Point p = new Point();
793             // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
794             wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
795             if (p.x != 0 && p.y != 0) {
796                 updateOomLevels(p.x, p.y, true);
797                 mHaveDisplaySize = true;
798             }
799         }
800     }
801 
802     /**
803      * Get a map of pid and package name that process of that pid Android/data and Android/obb
804      * directory is not mounted to lowerfs to speed up access.
805      */
getProcessesWithPendingBindMounts(int userId)806     Map<Integer, String> getProcessesWithPendingBindMounts(int userId) {
807         final Map<Integer, String> pidPackageMap = new HashMap<>();
808         synchronized (mService) {
809             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
810                 final ProcessRecord record = mLruProcesses.get(i);
811                 if (record.userId != userId || !record.bindMountPending) {
812                     continue;
813                 }
814                 final int pid = record.pid;
815                 // It can happen when app process is starting, but zygote work is not done yet so
816                 // system does not this pid record yet.
817                 if (pid == 0) {
818                     throw new IllegalStateException("Pending process is not started yet,"
819                             + "retry later");
820                 }
821                 pidPackageMap.put(pid, record.info.packageName);
822             }
823             return pidPackageMap;
824         }
825     }
826 
updateOomLevels(int displayWidth, int displayHeight, boolean write)827     private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
828         // Scale buckets from avail memory: at 300MB we use the lowest values to
829         // 700MB or more for the top values.
830         float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
831 
832         // Scale buckets from screen size.
833         int minSize = 480 * 800;  //  384000
834         int maxSize = 1280 * 800; // 1024000  230400 870400  .264
835         float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
836         if (false) {
837             Slog.i("XXXXXX", "scaleMem=" + scaleMem);
838             Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
839                     + " dh=" + displayHeight);
840         }
841 
842         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
843         if (scale < 0) scale = 0;
844         else if (scale > 1) scale = 1;
845         int minfree_adj = Resources.getSystem().getInteger(
846                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
847         int minfree_abs = Resources.getSystem().getInteger(
848                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
849         if (false) {
850             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
851         }
852 
853         final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
854 
855         for (int i = 0; i < mOomAdj.length; i++) {
856             int low = mOomMinFreeLow[i];
857             int high = mOomMinFreeHigh[i];
858             if (is64bit) {
859                 // Increase the high min-free levels for cached processes for 64-bit
860                 if (i == 4) high = (high * 3) / 2;
861                 else if (i == 5) high = (high * 7) / 4;
862             }
863             mOomMinFree[i] = (int)(low + ((high - low) * scale));
864         }
865 
866         if (minfree_abs >= 0) {
867             for (int i = 0; i < mOomAdj.length; i++) {
868                 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
869                         / mOomMinFree[mOomAdj.length - 1]);
870             }
871         }
872 
873         if (minfree_adj != 0) {
874             for (int i = 0; i < mOomAdj.length; i++) {
875                 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
876                         / mOomMinFree[mOomAdj.length - 1]);
877                 if (mOomMinFree[i] < 0) {
878                     mOomMinFree[i] = 0;
879                 }
880             }
881         }
882 
883         // The maximum size we will restore a process from cached to background, when under
884         // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
885         // before killing background processes.
886         mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
887 
888         // Ask the kernel to try to keep enough memory free to allocate 3 full
889         // screen 32bpp buffers without entering direct reclaim.
890         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
891         int reserve_adj = Resources.getSystem().getInteger(
892                 com.android.internal.R.integer.config_extraFreeKbytesAdjust);
893         int reserve_abs = Resources.getSystem().getInteger(
894                 com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
895 
896         if (reserve_abs >= 0) {
897             reserve = reserve_abs;
898         }
899 
900         if (reserve_adj != 0) {
901             reserve += reserve_adj;
902             if (reserve < 0) {
903                 reserve = 0;
904             }
905         }
906 
907         if (write) {
908             ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
909             buf.putInt(LMK_TARGET);
910             for (int i = 0; i < mOomAdj.length; i++) {
911                 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
912                 buf.putInt(mOomAdj[i]);
913             }
914 
915             writeLmkd(buf, null);
916             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
917             mOomLevelsSet = true;
918         }
919         // GB: 2048,3072,4096,6144,7168,8192
920         // HC: 8192,10240,12288,14336,16384,20480
921     }
922 
computeEmptyProcessLimit(int totalProcessLimit)923     public static int computeEmptyProcessLimit(int totalProcessLimit) {
924         return totalProcessLimit/2;
925     }
926 
buildOomTag(String prefix, String compactPrefix, String space, int val, int base, boolean compact)927     private static String buildOomTag(String prefix, String compactPrefix, String space, int val,
928             int base, boolean compact) {
929         final int diff = val - base;
930         if (diff == 0) {
931             if (compact) {
932                 return compactPrefix;
933             }
934             if (space == null) return prefix;
935             return prefix + space;
936         }
937         if (diff < 10) {
938             return prefix + (compact ? "+" : "+ ") + Integer.toString(diff);
939         }
940         return prefix + "+" + Integer.toString(diff);
941     }
942 
makeOomAdjString(int setAdj, boolean compact)943     public static String makeOomAdjString(int setAdj, boolean compact) {
944         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
945             return buildOomTag("cch", "cch", "   ", setAdj,
946                     ProcessList.CACHED_APP_MIN_ADJ, compact);
947         } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
948             return buildOomTag("svcb  ", "svcb", null, setAdj,
949                     ProcessList.SERVICE_B_ADJ, compact);
950         } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
951             return buildOomTag("prev  ", "prev", null, setAdj,
952                     ProcessList.PREVIOUS_APP_ADJ, compact);
953         } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
954             return buildOomTag("home  ", "home", null, setAdj,
955                     ProcessList.HOME_APP_ADJ, compact);
956         } else if (setAdj >= ProcessList.SERVICE_ADJ) {
957             return buildOomTag("svc   ", "svc", null, setAdj,
958                     ProcessList.SERVICE_ADJ, compact);
959         } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
960             return buildOomTag("hvy   ", "hvy", null, setAdj,
961                     ProcessList.HEAVY_WEIGHT_APP_ADJ, compact);
962         } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
963             return buildOomTag("bkup  ", "bkup", null, setAdj,
964                     ProcessList.BACKUP_APP_ADJ, compact);
965         } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
966             return buildOomTag("prcl  ", "prcl", null, setAdj,
967                     ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact);
968         } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
969             return buildOomTag("prcp  ", "prcp", null, setAdj,
970                     ProcessList.PERCEPTIBLE_APP_ADJ, compact);
971         } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
972             return buildOomTag("vis", "vis", "   ", setAdj,
973                     ProcessList.VISIBLE_APP_ADJ, compact);
974         } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
975             return buildOomTag("fg ", "fg ", "   ", setAdj,
976                     ProcessList.FOREGROUND_APP_ADJ, compact);
977         } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
978             return buildOomTag("psvc  ", "psvc", null, setAdj,
979                     ProcessList.PERSISTENT_SERVICE_ADJ, compact);
980         } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
981             return buildOomTag("pers  ", "pers", null, setAdj,
982                     ProcessList.PERSISTENT_PROC_ADJ, compact);
983         } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
984             return buildOomTag("sys   ", "sys", null, setAdj,
985                     ProcessList.SYSTEM_ADJ, compact);
986         } else if (setAdj >= ProcessList.NATIVE_ADJ) {
987             return buildOomTag("ntv  ", "ntv", null, setAdj,
988                     ProcessList.NATIVE_ADJ, compact);
989         } else {
990             return Integer.toString(setAdj);
991         }
992     }
993 
makeProcStateString(int curProcState)994     public static String makeProcStateString(int curProcState) {
995         String procState;
996         switch (curProcState) {
997             case ActivityManager.PROCESS_STATE_PERSISTENT:
998                 procState = "PER ";
999                 break;
1000             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
1001                 procState = "PERU";
1002                 break;
1003             case ActivityManager.PROCESS_STATE_TOP:
1004                 procState = "TOP ";
1005                 break;
1006             case ActivityManager.PROCESS_STATE_BOUND_TOP:
1007                 procState = "BTOP";
1008                 break;
1009             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
1010                 procState = "FGS ";
1011                 break;
1012             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
1013                 procState = "BFGS";
1014                 break;
1015             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
1016                 procState = "IMPF";
1017                 break;
1018             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
1019                 procState = "IMPB";
1020                 break;
1021             case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
1022                 procState = "TRNB";
1023                 break;
1024             case ActivityManager.PROCESS_STATE_BACKUP:
1025                 procState = "BKUP";
1026                 break;
1027             case ActivityManager.PROCESS_STATE_SERVICE:
1028                 procState = "SVC ";
1029                 break;
1030             case ActivityManager.PROCESS_STATE_RECEIVER:
1031                 procState = "RCVR";
1032                 break;
1033             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
1034                 procState = "TPSL";
1035                 break;
1036             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
1037                 procState = "HVY ";
1038                 break;
1039             case ActivityManager.PROCESS_STATE_HOME:
1040                 procState = "HOME";
1041                 break;
1042             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
1043                 procState = "LAST";
1044                 break;
1045             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
1046                 procState = "CAC ";
1047                 break;
1048             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
1049                 procState = "CACC";
1050                 break;
1051             case ActivityManager.PROCESS_STATE_CACHED_RECENT:
1052                 procState = "CRE ";
1053                 break;
1054             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
1055                 procState = "CEM ";
1056                 break;
1057             case ActivityManager.PROCESS_STATE_NONEXISTENT:
1058                 procState = "NONE";
1059                 break;
1060             default:
1061                 procState = "??";
1062                 break;
1063         }
1064         return procState;
1065     }
1066 
makeProcStateProtoEnum(int curProcState)1067     public static int makeProcStateProtoEnum(int curProcState) {
1068         switch (curProcState) {
1069             case ActivityManager.PROCESS_STATE_PERSISTENT:
1070                 return AppProtoEnums.PROCESS_STATE_PERSISTENT;
1071             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
1072                 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
1073             case ActivityManager.PROCESS_STATE_TOP:
1074                 return AppProtoEnums.PROCESS_STATE_TOP;
1075             case ActivityManager.PROCESS_STATE_BOUND_TOP:
1076                 return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
1077             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
1078                 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
1079             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
1080                 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
1081             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
1082                 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING;
1083             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
1084                 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
1085             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
1086                 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
1087             case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
1088                 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND;
1089             case ActivityManager.PROCESS_STATE_BACKUP:
1090                 return AppProtoEnums.PROCESS_STATE_BACKUP;
1091             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
1092                 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT;
1093             case ActivityManager.PROCESS_STATE_SERVICE:
1094                 return AppProtoEnums.PROCESS_STATE_SERVICE;
1095             case ActivityManager.PROCESS_STATE_RECEIVER:
1096                 return AppProtoEnums.PROCESS_STATE_RECEIVER;
1097             case ActivityManager.PROCESS_STATE_HOME:
1098                 return AppProtoEnums.PROCESS_STATE_HOME;
1099             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
1100                 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY;
1101             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
1102                 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY;
1103             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
1104                 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
1105             case ActivityManager.PROCESS_STATE_CACHED_RECENT:
1106                 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT;
1107             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
1108                 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY;
1109             case ActivityManager.PROCESS_STATE_NONEXISTENT:
1110                 return AppProtoEnums.PROCESS_STATE_NONEXISTENT;
1111             case ActivityManager.PROCESS_STATE_UNKNOWN:
1112                 return AppProtoEnums.PROCESS_STATE_UNKNOWN;
1113             default:
1114                 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO;
1115         }
1116     }
1117 
appendRamKb(StringBuilder sb, long ramKb)1118     public static void appendRamKb(StringBuilder sb, long ramKb) {
1119         for (int j = 0, fact = 10; j < 6; j++, fact *= 10) {
1120             if (ramKb < fact) {
1121                 sb.append(' ');
1122             }
1123         }
1124         sb.append(ramKb);
1125     }
1126 
1127     // How long after a state change that it is safe to collect PSS without it being dirty.
1128     public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
1129 
1130     // The minimum time interval after a state change it is safe to collect PSS.
1131     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
1132 
1133     // The maximum amount of time we want to go between PSS collections.
1134     public static final int PSS_MAX_INTERVAL = 60*60*1000;
1135 
1136     // The minimum amount of time between successive PSS requests for *all* processes.
1137     public static final int PSS_ALL_INTERVAL = 20*60*1000;
1138 
1139     // The amount of time until PSS when a persistent process first appears.
1140     private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;
1141 
1142     // The amount of time until PSS when a process first becomes top.
1143     private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
1144 
1145     // The amount of time until PSS when a process first goes into the background.
1146     private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
1147 
1148     // The amount of time until PSS when a process first becomes cached.
1149     private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;
1150 
1151     // The amount of time until PSS when an important process stays in the same state.
1152     private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;
1153 
1154     // The amount of time until PSS when the top process stays in the same state.
1155     private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;
1156 
1157     // The amount of time until PSS when an important process stays in the same state.
1158     private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;
1159 
1160     // The amount of time until PSS when a service process stays in the same state.
1161     private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;
1162 
1163     // The amount of time until PSS when a cached process stays in the same state.
1164     private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;
1165 
1166     // The amount of time until PSS when a persistent process first appears.
1167     private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
1168 
1169     // The amount of time until PSS when a process first becomes top.
1170     private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000;
1171 
1172     // The amount of time until PSS when a process first goes into the background.
1173     private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000;
1174 
1175     // The amount of time until PSS when a process first becomes cached.
1176     private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000;
1177 
1178     // The minimum time interval after a state change it is safe to collect PSS.
1179     public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
1180 
1181     // The amount of time during testing until PSS when a process first becomes top.
1182     private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
1183 
1184     // The amount of time during testing until PSS when a process first goes into the background.
1185     private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
1186 
1187     // The amount of time during testing until PSS when an important process stays in same state.
1188     private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
1189 
1190     // The amount of time during testing until PSS when a background process stays in same state.
1191     private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
1192 
1193     public static final int PROC_MEM_PERSISTENT = 0;
1194     public static final int PROC_MEM_TOP = 1;
1195     public static final int PROC_MEM_IMPORTANT = 2;
1196     public static final int PROC_MEM_SERVICE = 3;
1197     public static final int PROC_MEM_CACHED = 4;
1198     public static final int PROC_MEM_NUM = 5;
1199 
1200     // Map large set of system process states to
1201     private static final int[] sProcStateToProcMem = new int[] {
1202         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
1203         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
1204         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
1205         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
1206         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_BOUND_TOP
1207         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
1208         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
1209         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
1210         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
1211         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BACKUP
1212         PROC_MEM_SERVICE,               // ActivityManager.PROCESS_STATE_SERVICE
1213         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_RECEIVER
1214         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
1215         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
1216         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_HOME
1217         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
1218         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
1219         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
1220         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_RECENT
1221         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_EMPTY
1222     };
1223 
1224     private static final long[] sFirstAwakePssTimes = new long[] {
1225         PSS_FIRST_PERSISTENT_INTERVAL,  // PROC_MEM_PERSISTENT
1226         PSS_FIRST_TOP_INTERVAL,         // PROC_MEM_TOP
1227         PSS_FIRST_BACKGROUND_INTERVAL,  // PROC_MEM_IMPORTANT
1228         PSS_FIRST_BACKGROUND_INTERVAL,  // PROC_MEM_SERVICE
1229         PSS_FIRST_CACHED_INTERVAL,      // PROC_MEM_CACHED
1230     };
1231 
1232     private static final long[] sSameAwakePssTimes = new long[] {
1233         PSS_SAME_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1234         PSS_SAME_TOP_INTERVAL,          // PROC_MEM_TOP
1235         PSS_SAME_IMPORTANT_INTERVAL,    // PROC_MEM_IMPORTANT
1236         PSS_SAME_SERVICE_INTERVAL,      // PROC_MEM_SERVICE
1237         PSS_SAME_CACHED_INTERVAL,       // PROC_MEM_CACHED
1238     };
1239 
1240     private static final long[] sFirstAsleepPssTimes = new long[] {
1241         PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1242         PSS_FIRST_ASLEEP_TOP_INTERVAL,          // PROC_MEM_TOP
1243         PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // PROC_MEM_IMPORTANT
1244         PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // PROC_MEM_SERVICE
1245         PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // PROC_MEM_CACHED
1246     };
1247 
1248     private static final long[] sSameAsleepPssTimes = new long[] {
1249         PSS_SAME_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1250         PSS_SAME_TOP_INTERVAL,          // PROC_MEM_TOP
1251         PSS_SAME_IMPORTANT_INTERVAL,    // PROC_MEM_IMPORTANT
1252         PSS_SAME_SERVICE_INTERVAL,      // PROC_MEM_SERVICE
1253         PSS_SAME_CACHED_INTERVAL,       // PROC_MEM_CACHED
1254     };
1255 
1256     private static final long[] sTestFirstPssTimes = new long[] {
1257         PSS_TEST_FIRST_TOP_INTERVAL,        // PROC_MEM_PERSISTENT
1258         PSS_TEST_FIRST_TOP_INTERVAL,        // PROC_MEM_TOP
1259         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1260         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1261         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
1262     };
1263 
1264     private static final long[] sTestSamePssTimes = new long[] {
1265         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_PERSISTENT
1266         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // PROC_MEM_TOP
1267         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // PROC_MEM_IMPORTANT
1268         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_SERVICE
1269         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_CACHED
1270     };
1271 
1272     public static final class ProcStateMemTracker {
1273         final int[] mHighestMem = new int[PROC_MEM_NUM];
1274         final float[] mScalingFactor = new float[PROC_MEM_NUM];
1275         int mTotalHighestMem = PROC_MEM_CACHED;
1276 
1277         int mPendingMemState;
1278         int mPendingHighestMemState;
1279         float mPendingScalingFactor;
1280 
ProcStateMemTracker()1281         public ProcStateMemTracker() {
1282             for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
1283                 mHighestMem[i] = PROC_MEM_NUM;
1284                 mScalingFactor[i] = 1.0f;
1285             }
1286             mPendingMemState = -1;
1287         }
1288 
dumpLine(PrintWriter pw)1289         public void dumpLine(PrintWriter pw) {
1290             pw.print("best=");
1291             pw.print(mTotalHighestMem);
1292             pw.print(" (");
1293             boolean needSep = false;
1294             for (int i = 0; i < PROC_MEM_NUM; i++) {
1295                 if (mHighestMem[i] < PROC_MEM_NUM) {
1296                     if (needSep) {
1297                         pw.print(", ");
1298                         needSep = false;
1299                     }
1300                     pw.print(i);
1301                     pw.print("=");
1302                     pw.print(mHighestMem[i]);
1303                     pw.print(" ");
1304                     pw.print(mScalingFactor[i]);
1305                     pw.print("x");
1306                     needSep = true;
1307                 }
1308             }
1309             pw.print(")");
1310             if (mPendingMemState >= 0) {
1311                 pw.print(" / pending state=");
1312                 pw.print(mPendingMemState);
1313                 pw.print(" highest=");
1314                 pw.print(mPendingHighestMemState);
1315                 pw.print(" ");
1316                 pw.print(mPendingScalingFactor);
1317                 pw.print("x");
1318             }
1319             pw.println();
1320         }
1321     }
1322 
procStatesDifferForMem(int procState1, int procState2)1323     public static boolean procStatesDifferForMem(int procState1, int procState2) {
1324         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
1325     }
1326 
minTimeFromStateChange(boolean test)1327     public static long minTimeFromStateChange(boolean test) {
1328         return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
1329     }
1330 
commitNextPssTime(ProcStateMemTracker tracker)1331     public static void commitNextPssTime(ProcStateMemTracker tracker) {
1332         if (tracker.mPendingMemState >= 0) {
1333             tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
1334             tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor;
1335             tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
1336             tracker.mPendingMemState = -1;
1337         }
1338     }
1339 
abortNextPssTime(ProcStateMemTracker tracker)1340     public static void abortNextPssTime(ProcStateMemTracker tracker) {
1341         tracker.mPendingMemState = -1;
1342     }
1343 
computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, boolean sleeping, long now)1344     public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
1345             boolean sleeping, long now) {
1346         boolean first;
1347         float scalingFactor;
1348         final int memState = sProcStateToProcMem[procState];
1349         if (tracker != null) {
1350             final int highestMemState = memState < tracker.mTotalHighestMem
1351                     ? memState : tracker.mTotalHighestMem;
1352             first = highestMemState < tracker.mHighestMem[memState];
1353             tracker.mPendingMemState = memState;
1354             tracker.mPendingHighestMemState = highestMemState;
1355             if (first) {
1356                 tracker.mPendingScalingFactor = scalingFactor = 1.0f;
1357             } else {
1358                 scalingFactor = tracker.mScalingFactor[memState];
1359                 tracker.mPendingScalingFactor = scalingFactor * 1.5f;
1360             }
1361         } else {
1362             first = true;
1363             scalingFactor = 1.0f;
1364         }
1365         final long[] table = test
1366                 ? (first
1367                 ? sTestFirstPssTimes
1368                 : sTestSamePssTimes)
1369                 : (first
1370                 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
1371                 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
1372         long delay = (long)(table[memState] * scalingFactor);
1373         if (delay > PSS_MAX_INTERVAL) {
1374             delay = PSS_MAX_INTERVAL;
1375         }
1376         return now + delay;
1377     }
1378 
1379     long getMemLevel(int adjustment) {
1380         for (int i = 0; i < mOomAdj.length; i++) {
1381             if (adjustment <= mOomAdj[i]) {
1382                 return mOomMinFree[i] * 1024;
1383             }
1384         }
1385         return mOomMinFree[mOomAdj.length - 1] * 1024;
1386     }
1387 
1388     /**
1389      * Return the maximum pss size in kb that we consider a process acceptable to
1390      * restore from its cached state for running in the background when RAM is low.
1391      */
1392     long getCachedRestoreThresholdKb() {
1393         return mCachedRestoreLevel;
1394     }
1395 
1396     /**
1397      * Set the out-of-memory badness adjustment for a process.
1398      * If {@code pid <= 0}, this method will be a no-op.
1399      *
1400      * @param pid The process identifier to set.
1401      * @param uid The uid of the app
1402      * @param amt Adjustment value -- lmkd allows -1000 to +1000
1403      *
1404      * {@hide}
1405      */
1406     public static void setOomAdj(int pid, int uid, int amt) {
1407         // This indicates that the process is not started yet and so no need to proceed further.
1408         if (pid <= 0) {
1409             return;
1410         }
1411         if (amt == UNKNOWN_ADJ)
1412             return;
1413 
1414         long start = SystemClock.elapsedRealtime();
1415         ByteBuffer buf = ByteBuffer.allocate(4 * 4);
1416         buf.putInt(LMK_PROCPRIO);
1417         buf.putInt(pid);
1418         buf.putInt(uid);
1419         buf.putInt(amt);
1420         writeLmkd(buf, null);
1421         long now = SystemClock.elapsedRealtime();
1422         if ((now-start) > 250) {
1423             Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
1424                     + " = " + amt);
1425         }
1426     }
1427 
1428     /*
1429      * {@hide}
1430      */
1431     public static final void remove(int pid) {
1432         // This indicates that the process is not started yet and so no need to proceed further.
1433         if (pid <= 0) {
1434             return;
1435         }
1436         ByteBuffer buf = ByteBuffer.allocate(4 * 2);
1437         buf.putInt(LMK_PROCREMOVE);
1438         buf.putInt(pid);
1439         writeLmkd(buf, null);
1440     }
1441 
1442     /*
1443      * {@hide}
1444      */
1445     public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) {
1446         ByteBuffer buf = ByteBuffer.allocate(4 * 3);
1447         ByteBuffer repl = ByteBuffer.allocate(4 * 2);
1448         buf.putInt(LMK_GETKILLCNT);
1449         buf.putInt(min_oom_adj);
1450         buf.putInt(max_oom_adj);
1451         // indicate what we are waiting for
1452         repl.putInt(LMK_GETKILLCNT);
1453         repl.rewind();
1454         if (writeLmkd(buf, repl) && repl.getInt() == LMK_GETKILLCNT) {
1455             return new Integer(repl.getInt());
1456         }
1457         return null;
1458     }
1459 
1460     public boolean onLmkdConnect(OutputStream ostream) {
1461         try {
1462             // Purge any previously registered pids
1463             ByteBuffer buf = ByteBuffer.allocate(4);
1464             buf.putInt(LMK_PROCPURGE);
1465             ostream.write(buf.array(), 0, buf.position());
1466             if (mOomLevelsSet) {
1467                 // Reset oom_adj levels
1468                 buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
1469                 buf.putInt(LMK_TARGET);
1470                 for (int i = 0; i < mOomAdj.length; i++) {
1471                     buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
1472                     buf.putInt(mOomAdj[i]);
1473                 }
1474                 ostream.write(buf.array(), 0, buf.position());
1475             }
1476             // Subscribe for kill event notifications
1477             buf = ByteBuffer.allocate(4 * 2);
1478             buf.putInt(LMK_SUBSCRIBE);
1479             buf.putInt(LMK_ASYNC_EVENT_KILL);
1480             ostream.write(buf.array(), 0, buf.position());
1481         } catch (IOException ex) {
1482             return false;
1483         }
1484         return true;
1485     }
1486 
1487     private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
1488         if (!sLmkdConnection.isConnected()) {
1489             // try to connect immediately and then keep retrying
1490             sKillHandler.sendMessage(
1491                     sKillHandler.obtainMessage(KillHandler.LMKD_RECONNECT_MSG));
1492 
1493             // wait for connection retrying 3 times (up to 3 seconds)
1494             if (!sLmkdConnection.waitForConnection(3 * LMKD_RECONNECT_DELAY_MS)) {
1495                 return false;
1496             }
1497         }
1498 
1499         return sLmkdConnection.exchange(buf, repl);
1500     }
1501 
1502     static void killProcessGroup(int uid, int pid) {
1503         /* static; one-time init here */
1504         if (sKillHandler != null) {
1505             sKillHandler.sendMessage(
1506                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
1507         } else {
1508             Slog.w(TAG, "Asked to kill process group before system bringup!");
1509             Process.killProcessGroup(uid, pid);
1510         }
1511     }
1512 
1513     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean
1514             keepIfLarge) {
1515         if (uid == SYSTEM_UID) {
1516             // The system gets to run in any process.  If there are multiple
1517             // processes with the same uid, just pick the first (this
1518             // should never happen).
1519             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
1520             if (procs == null) return null;
1521             final int procCount = procs.size();
1522             for (int i = 0; i < procCount; i++) {
1523                 final int procUid = procs.keyAt(i);
1524                 if (!UserHandle.isCore(procUid) || !UserHandle.isSameUser(procUid, uid)) {
1525                     // Don't use an app process or different user process for system component.
1526                     continue;
1527                 }
1528                 return procs.valueAt(i);
1529             }
1530         }
1531         ProcessRecord proc = mProcessNames.get(processName, uid);
1532         if (false && proc != null && !keepIfLarge
1533                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
1534                 && proc.lastCachedPss >= 4000) {
1535             // Turn this condition on to cause killing to happen regularly, for testing.
1536             if (proc.baseProcessTracker != null) {
1537                 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
1538                 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1539                     ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1540                     FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED,
1541                             proc.info.uid,
1542                             holder.state.getName(),
1543                             holder.state.getPackage(),
1544                             proc.lastCachedPss, holder.appVersion);
1545                 }
1546             }
1547             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached",
1548                     ApplicationExitInfo.REASON_OTHER,
1549                     ApplicationExitInfo.SUBREASON_LARGE_CACHED,
1550                     true);
1551         } else if (proc != null && !keepIfLarge
1552                 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
1553                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
1554             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc
1555                     .lastCachedPss);
1556             if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) {
1557                 if (proc.baseProcessTracker != null) {
1558                     proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
1559                             proc.lastCachedPss);
1560                     for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1561                         ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1562                         FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED,
1563                                 proc.info.uid,
1564                                 holder.state.getName(),
1565                                 holder.state.getPackage(),
1566                                 proc.lastCachedPss, holder.appVersion);
1567                     }
1568                 }
1569                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached",
1570                         ApplicationExitInfo.REASON_OTHER,
1571                         ApplicationExitInfo.SUBREASON_LARGE_CACHED,
1572                         true);
1573             }
1574         }
1575         return proc;
1576     }
1577 
getMemoryInfo(ActivityManager.MemoryInfo outInfo)1578     void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
1579         final long homeAppMem = getMemLevel(HOME_APP_ADJ);
1580         final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ);
1581         outInfo.availMem = getFreeMemory();
1582         outInfo.totalMem = getTotalMemory();
1583         outInfo.threshold = homeAppMem;
1584         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
1585         outInfo.hiddenAppThreshold = cachedAppMem;
1586         outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ);
1587         outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ);
1588         outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ);
1589     }
1590 
1591     ProcessRecord findAppProcessLocked(IBinder app, String reason) {
1592         final int NP = mProcessNames.getMap().size();
1593         for (int ip = 0; ip < NP; ip++) {
1594             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
1595             final int NA = apps.size();
1596             for (int ia = 0; ia < NA; ia++) {
1597                 ProcessRecord p = apps.valueAt(ia);
1598                 if (p.thread != null && p.thread.asBinder() == app) {
1599                     return p;
1600                 }
1601             }
1602         }
1603 
1604         Slog.w(TAG, "Can't find mystery application for " + reason
1605                 + " from pid=" + Binder.getCallingPid()
1606                 + " uid=" + Binder.getCallingUid() + ": " + app);
1607         return null;
1608     }
1609 
1610     private void checkSlow(long startTime, String where) {
1611         long now = SystemClock.uptimeMillis();
1612         if ((now - startTime) > 50) {
1613             // If we are taking more than 50ms, log about it.
1614             Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where);
1615         }
1616     }
1617 
1618     private int[] computeGidsForProcess(int mountExternal, int uid, int[] permGids) {
1619         ArrayList<Integer> gidList = new ArrayList<>(permGids.length + 5);
1620 
1621         final int sharedAppGid = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
1622         final int cacheAppGid = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
1623         final int userGid = UserHandle.getUserGid(UserHandle.getUserId(uid));
1624 
1625         // Add shared application and profile GIDs so applications can share some
1626         // resources like shared libraries and access user-wide resources
1627         for (int permGid : permGids) {
1628             gidList.add(permGid);
1629         }
1630         if (sharedAppGid != UserHandle.ERR_GID) {
1631             gidList.add(sharedAppGid);
1632         }
1633         if (cacheAppGid != UserHandle.ERR_GID) {
1634             gidList.add(cacheAppGid);
1635         }
1636         if (userGid != UserHandle.ERR_GID) {
1637             gidList.add(userGid);
1638         }
1639         if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE
1640                 || mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
1641             // For DownloadProviders and MTP: To grant access to /sdcard/Android/
1642             // And a special case for the FUSE daemon since it runs an MTP server and should have
1643             // access to Android/
1644             // Note that we must add in the user id, because sdcardfs synthesizes this permission
1645             // based on the user
1646             gidList.add(UserHandle.getUid(UserHandle.getUserId(uid), Process.SDCARD_RW_GID));
1647 
1648             // For devices without sdcardfs, these GIDs are needed instead; note that we
1649             // consciously don't add the user_id in the GID, since these apps are anyway
1650             // isolated to only their own user
1651             gidList.add(Process.EXT_DATA_RW_GID);
1652             gidList.add(Process.EXT_OBB_RW_GID);
1653         }
1654         if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
1655             // For devices without sdcardfs, this GID is needed to allow installers access to OBBs
1656             gidList.add(Process.EXT_OBB_RW_GID);
1657         }
1658         if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
1659             // For the FUSE daemon: To grant access to the lower filesystem.
1660             // EmulatedVolumes: /data/media and /mnt/expand/<volume>/data/media
1661             // PublicVolumes: /mnt/media_rw/<volume>
1662             gidList.add(Process.MEDIA_RW_GID);
1663         }
1664 
1665         int[] gidArray = new int[gidList.size()];
1666         for (int i = 0; i < gidArray.length; i++) {
1667             gidArray[i] = gidList.get(i);
1668         }
1669         return gidArray;
1670     }
1671 
1672     private boolean shouldEnableTaggedPointers(ProcessRecord app) {
1673         // Ensure we have platform + kernel support for TBI.
1674         if (!Zygote.nativeSupportsTaggedPointers()) {
1675             return false;
1676         }
1677 
1678         // Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute.
1679         if (!app.info.allowsNativeHeapPointerTagging()) {
1680             return false;
1681         }
1682 
1683         // Check to see that the compat feature for TBI is enabled.
1684         if (!mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) {
1685             return false;
1686         }
1687 
1688         return true;
1689     }
1690 
1691     private int decideTaggingLevel(ProcessRecord app) {
1692         if (shouldEnableTaggedPointers(app)) {
1693             return Zygote.MEMORY_TAG_LEVEL_TBI;
1694         }
1695 
1696         return 0;
1697     }
1698 
1699     private int decideGwpAsanLevel(ProcessRecord app) {
1700         // Look at the process attribute first.
1701        if (app.processInfo != null
1702                 && app.processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) {
1703             return app.processInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_ALWAYS
1704                     ? Zygote.GWP_ASAN_LEVEL_ALWAYS
1705                     : Zygote.GWP_ASAN_LEVEL_NEVER;
1706         }
1707         // Then at the applicaton attribute.
1708         if (app.info.getGwpAsanMode() != ApplicationInfo.GWP_ASAN_DEFAULT) {
1709             return app.info.getGwpAsanMode() == ApplicationInfo.GWP_ASAN_ALWAYS
1710                     ? Zygote.GWP_ASAN_LEVEL_ALWAYS
1711                     : Zygote.GWP_ASAN_LEVEL_NEVER;
1712         }
1713         // If the app does not specify gwpAsanMode, the default behavior is lottery among the
1714         // system apps, and disabled for user apps, unless overwritten by the compat feature.
1715         if (mPlatformCompat.isChangeEnabled(GWP_ASAN, app.info)) {
1716             return Zygote.GWP_ASAN_LEVEL_ALWAYS;
1717         }
1718         if ((app.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
1719             return Zygote.GWP_ASAN_LEVEL_LOTTERY;
1720         }
1721         return Zygote.GWP_ASAN_LEVEL_NEVER;
1722     }
1723 
1724     /**
1725      * @return {@code true} if process start is successful, false otherwise.
1726      */
1727     @GuardedBy("mService")
1728     boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1729             int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
1730             boolean mountExtStorageFull, String abiOverride) {
1731         if (app.pendingStart) {
1732             return true;
1733         }
1734         long startTime = SystemClock.uptimeMillis();
1735         if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
1736             checkSlow(startTime, "startProcess: removing from pids map");
1737             mService.removePidLocked(app);
1738             app.bindMountPending = false;
1739             mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1740             checkSlow(startTime, "startProcess: done removing from pids map");
1741             app.setPid(0);
1742             app.startSeq = 0;
1743         }
1744 
1745         if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
1746                 TAG_PROCESSES,
1747                 "startProcessLocked removing on hold: " + app);
1748         mService.mProcessesOnHold.remove(app);
1749 
1750         checkSlow(startTime, "startProcess: starting to update cpu stats");
1751         mService.updateCpuStats();
1752         checkSlow(startTime, "startProcess: done updating cpu stats");
1753 
1754         try {
1755             try {
1756                 final int userId = UserHandle.getUserId(app.uid);
1757                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
1758             } catch (RemoteException e) {
1759                 throw e.rethrowAsRuntimeException();
1760             }
1761 
1762             int uid = app.uid;
1763             int[] gids = null;
1764             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1765             if (!app.isolated) {
1766                 int[] permGids = null;
1767                 try {
1768                     checkSlow(startTime, "startProcess: getting gids from package manager");
1769                     final IPackageManager pm = AppGlobals.getPackageManager();
1770                     permGids = pm.getPackageGids(app.info.packageName,
1771                             MATCH_DIRECT_BOOT_AUTO, app.userId);
1772                     if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
1773                         mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
1774                     } else {
1775                         StorageManagerInternal storageManagerInternal = LocalServices.getService(
1776                                 StorageManagerInternal.class);
1777                         mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
1778                                 app.info.packageName);
1779                     }
1780                 } catch (RemoteException e) {
1781                     throw e.rethrowAsRuntimeException();
1782                 }
1783 
1784                 // Remove any gids needed if the process has been denied permissions.
1785                 // NOTE: eventually we should probably have the package manager pre-compute
1786                 // this for us?
1787                 if (app.processInfo != null && app.processInfo.deniedPermissions != null) {
1788                     for (int i = app.processInfo.deniedPermissions.size() - 1; i >= 0; i--) {
1789                         int[] denyGids = mService.mPackageManagerInt.getPermissionGids(
1790                                 app.processInfo.deniedPermissions.valueAt(i), app.userId);
1791                         if (denyGids != null) {
1792                             for (int gid : denyGids) {
1793                                 permGids = ArrayUtils.removeInt(permGids, gid);
1794                             }
1795                         }
1796                     }
1797                 }
1798 
1799                 gids = computeGidsForProcess(mountExternal, uid, permGids);
1800             }
1801             app.mountMode = mountExternal;
1802             checkSlow(startTime, "startProcess: building args");
1803             if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
1804                 uid = 0;
1805             }
1806             int runtimeFlags = 0;
1807             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1808                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
1809                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1810                 // Also turn on CheckJNI for debuggable apps. It's quite
1811                 // awkward to turn on otherwise.
1812                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1813 
1814                 // Check if the developer does not want ART verification
1815                 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(),
1816                         android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) {
1817                     runtimeFlags |= Zygote.DISABLE_VERIFIER;
1818                     Slog.w(TAG_PROCESSES, app + ": ART verification disabled");
1819                 }
1820             }
1821             // Run the app in safe mode if its manifest requests so or the
1822             // system is booted in safe mode.
1823             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) {
1824                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1825             }
1826             if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
1827                 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
1828             }
1829             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1830                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1831             }
1832             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1833             if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1834                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1835             }
1836             String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1837             if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1838                 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1839             }
1840             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1841                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1842             }
1843             if ("1".equals(SystemProperties.get("debug.assert"))) {
1844                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1845             }
1846             if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) {
1847                 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER;
1848             }
1849             if (mService.mNativeDebuggingApp != null
1850                     && mService.mNativeDebuggingApp.equals(app.processName)) {
1851                 // Enable all debug flags required by the native debugger.
1852                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
1853                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1854                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
1855                 mService.mNativeDebuggingApp = null;
1856             }
1857 
1858             if (app.info.isEmbeddedDexUsed()
1859                     || (app.info.isPrivilegedApp()
1860                         && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) {
1861                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1862             }
1863 
1864             if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
1865                 app.info.maybeUpdateHiddenApiEnforcementPolicy(
1866                         mService.mHiddenApiBlacklist.getPolicy());
1867                 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
1868                         app.info.getHiddenApiEnforcementPolicy();
1869                 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
1870                 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
1871                     throw new IllegalStateException("Invalid API policy: " + policy);
1872                 }
1873                 runtimeFlags |= policyBits;
1874 
1875                 if (disableTestApiChecks) {
1876                     runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY;
1877                 }
1878             }
1879 
1880             String useAppImageCache = SystemProperties.get(
1881                     PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
1882             // Property defaults to true currently.
1883             if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) {
1884                 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
1885             }
1886 
1887             runtimeFlags |= decideGwpAsanLevel(app);
1888 
1889             String invokeWith = null;
1890             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1891                 // Debuggable apps may include a wrapper script with their library directory.
1892                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
1893                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
1894                 try {
1895                     if (new File(wrapperFileName).exists()) {
1896                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
1897                     }
1898                 } finally {
1899                     StrictMode.setThreadPolicy(oldPolicy);
1900                 }
1901             }
1902 
1903             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
1904             if (requiredAbi == null) {
1905                 requiredAbi = Build.SUPPORTED_ABIS[0];
1906             }
1907 
1908             String instructionSet = null;
1909             if (app.info.primaryCpuAbi != null) {
1910                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
1911             }
1912 
1913             app.gids = gids;
1914             app.setRequiredAbi(requiredAbi);
1915             app.instructionSet = instructionSet;
1916 
1917             // If instructionSet is non-null, this indicates that the system_server is spawning a
1918             // process with an ISA that may be different from its own. System (kernel and hardware)
1919             // compatililty for these features is checked in the decideTaggingLevel in the
1920             // system_server process (not the child process). As TBI is only supported in aarch64,
1921             // we can simply ensure that the new process is also aarch64. This prevents the mismatch
1922             // where a 64-bit system server spawns a 32-bit child that thinks it should enable some
1923             // tagging variant. Theoretically, a 32-bit system server could exist that spawns 64-bit
1924             // processes, in which case the new process won't get any tagging. This is fine as we
1925             // haven't seen this configuration in practice, and we can reasonable assume that if
1926             // tagging is desired, the system server will be 64-bit.
1927             if (instructionSet == null || instructionSet.equals("arm64")) {
1928                 runtimeFlags |= decideTaggingLevel(app);
1929             }
1930 
1931             // the per-user SELinux context must be set
1932             if (TextUtils.isEmpty(app.info.seInfoUser)) {
1933                 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
1934                         new IllegalStateException("SELinux tag not defined for "
1935                                 + app.info.packageName + " (uid " + app.uid + ")"));
1936             }
1937             final String seInfo = app.info.seInfo
1938                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
1939             // Start the process.  It will either succeed and return a result containing
1940             // the PID of the new process, or else throw a RuntimeException.
1941             final String entryPoint = "android.app.ActivityThread";
1942 
1943             return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
1944                     runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
1945                     instructionSet, invokeWith, startTime);
1946         } catch (RuntimeException e) {
1947             Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1948 
1949             // Something went very wrong while trying to start this process; one
1950             // common case is when the package is frozen due to an active
1951             // upgrade. To recover, clean up any active bookkeeping related to
1952             // starting this process. (We already invoked this method once when
1953             // the package was initially frozen through KILL_APPLICATION_MSG, so
1954             // it doesn't hurt to use it again.)
1955             mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1956                     false, false, true, false, false, app.userId, "start failure");
1957             return false;
1958         }
1959     }
1960 
1961     @GuardedBy("mService")
1962     boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
1963             int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
1964             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1965             long startTime) {
1966         app.pendingStart = true;
1967         app.killedByAm = false;
1968         app.removed = false;
1969         app.killed = false;
1970         if (app.startSeq != 0) {
1971             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
1972                     + " with non-zero startSeq:" + app.startSeq);
1973         }
1974         if (app.pid != 0) {
1975             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
1976                     + " with non-zero pid:" + app.pid);
1977         }
1978         app.mDisabledCompatChanges = null;
1979         if (mPlatformCompat != null) {
1980             app.mDisabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info);
1981         }
1982         final long startSeq = app.startSeq = ++mProcStartSeqCounter;
1983         app.setStartParams(uid, hostingRecord, seInfo, startTime);
1984         app.setUsingWrapper(invokeWith != null
1985                 || Zygote.getWrapProperty(app.processName) != null);
1986         mPendingStarts.put(startSeq, app);
1987 
1988         if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
1989             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
1990                     "Posting procStart msg for " + app.toShortString());
1991             mService.mProcStartHandler.post(() -> handleProcessStart(
1992                     app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
1993                     requiredAbi, instructionSet, invokeWith, startSeq));
1994             return true;
1995         } else {
1996             try {
1997                 final Process.ProcessStartResult startResult = startProcess(hostingRecord,
1998                         entryPoint, app,
1999                         uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
2000                         requiredAbi, instructionSet, invokeWith, startTime);
2001                 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
2002                         startSeq, false);
2003             } catch (RuntimeException e) {
2004                 Slog.e(ActivityManagerService.TAG, "Failure starting process "
2005                         + app.processName, e);
2006                 app.pendingStart = false;
2007                 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
2008                         false, false, true, false, false, app.userId, "start failure");
2009             }
2010             return app.pid > 0;
2011         }
2012     }
2013 
2014     /**
2015      * Main handler routine to start the given process from the ProcStartHandler.
2016      *
2017      * <p>Note: this function doesn't hold the global AM lock intentionally.</p>
2018      */
2019     private void handleProcessStart(final ProcessRecord app, final String entryPoint,
2020             final int[] gids, final int runtimeFlags, int zygotePolicyFlags,
2021             final int mountExternal, final String requiredAbi, final String instructionSet,
2022             final String invokeWith, final long startSeq) {
2023         // If there is a precede instance of the process, wait for its death with a timeout.
2024         // Use local reference since we are not using locks here
2025         final ProcessRecord precedence = app.mPrecedence;
2026         if (precedence != null) {
2027             final int pid = precedence.pid;
2028             long now = System.currentTimeMillis();
2029             final long end = now + PROC_KILL_TIMEOUT;
2030             try {
2031                 Process.waitForProcessDeath(pid, PROC_KILL_TIMEOUT);
2032                 // It's killed successfully, but we'd make sure the cleanup work is done.
2033                 synchronized (precedence) {
2034                     if (app.mPrecedence != null) {
2035                         now = System.currentTimeMillis();
2036                         if (now < end) {
2037                             try {
2038                                 precedence.wait(end - now);
2039                             } catch (InterruptedException e) {
2040                             }
2041                         }
2042                     }
2043                     if (app.mPrecedence != null) {
2044                         // The cleanup work hasn't be done yet, let's log it and continue.
2045                         Slog.w(TAG, precedence + " has died, but its cleanup isn't done");
2046                     }
2047                 }
2048             } catch (Exception e) {
2049                 // It's still alive...
2050                 Slog.wtf(TAG, precedence.toString() + " refused to die, but we need to launch "
2051                         + app);
2052             }
2053         }
2054         try {
2055             final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
2056                     entryPoint, app, app.startUid, gids, runtimeFlags, zygotePolicyFlags,
2057                     mountExternal, app.seInfo, requiredAbi, instructionSet, invokeWith,
2058                     app.startTime);
2059 
2060             synchronized (mService) {
2061                 handleProcessStartedLocked(app, startResult, startSeq);
2062             }
2063         } catch (RuntimeException e) {
2064             synchronized (mService) {
2065                 Slog.e(ActivityManagerService.TAG, "Failure starting process "
2066                         + app.processName, e);
2067                 mPendingStarts.remove(startSeq);
2068                 app.pendingStart = false;
2069                 mService.forceStopPackageLocked(app.info.packageName,
2070                         UserHandle.getAppId(app.uid),
2071                         false, false, true, false, false, app.userId, "start failure");
2072             }
2073         }
2074     }
2075 
2076     @GuardedBy("mService")
2077     public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) {
2078         final ApplicationInfo appInfo = appZygote.getAppInfo();
2079         ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
2080         if (zygoteProcesses != null && (force || zygoteProcesses.size() == 0)) {
2081             // Only remove if no longer in use now, or forced kill
2082             mAppZygotes.remove(appInfo.processName, appInfo.uid);
2083             mAppZygoteProcesses.remove(appZygote);
2084             mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
2085             appZygote.stopZygote();
2086         }
2087     }
2088 
2089     @GuardedBy("mService")
2090     private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
2091         // Free the isolated uid for this process
2092         final IsolatedUidRange appUidRange =
2093                 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName,
2094                         app.hostingRecord.getDefiningUid());
2095         if (appUidRange != null) {
2096             appUidRange.freeIsolatedUidLocked(app.uid);
2097         }
2098 
2099         final AppZygote appZygote = mAppZygotes.get(app.info.processName,
2100                 app.hostingRecord.getDefiningUid());
2101         if (appZygote != null) {
2102             ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
2103             zygoteProcesses.remove(app);
2104             if (zygoteProcesses.size() == 0) {
2105                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG);
2106                 if (app.removed) {
2107                     // If we stopped this process because the package hosting it was removed,
2108                     // there's no point in delaying the app zygote kill.
2109                     killAppZygoteIfNeededLocked(appZygote, false /* force */);
2110                 } else {
2111                     Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
2112                     msg.obj = appZygote;
2113                     mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS);
2114                 }
2115             }
2116         }
2117     }
2118 
2119     private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
2120         synchronized (mService) {
2121             // The UID for the app zygote should be the UID of the application hosting
2122             // the service.
2123             final int uid = app.hostingRecord.getDefiningUid();
2124             AppZygote appZygote = mAppZygotes.get(app.info.processName, uid);
2125             final ArrayList<ProcessRecord> zygoteProcessList;
2126             if (appZygote == null) {
2127                 if (DEBUG_PROCESSES) {
2128                     Slog.d(TAG_PROCESSES, "Creating new app zygote.");
2129                 }
2130                 final IsolatedUidRange uidRange =
2131                         mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(
2132                                 app.info.processName, app.hostingRecord.getDefiningUid());
2133                 final int userId = UserHandle.getUserId(uid);
2134                 // Create the app-zygote and provide it with the UID-range it's allowed
2135                 // to setresuid/setresgid to.
2136                 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
2137                 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
2138                 ApplicationInfo appInfo = new ApplicationInfo(app.info);
2139                 // If this was an external service, the package name and uid in the passed in
2140                 // ApplicationInfo have been changed to match those of the calling package;
2141                 // that is not what we want for the AppZygote though, which needs to have the
2142                 // packageName and uid of the defining application. This is because the
2143                 // preloading only makes sense in the context of the defining application,
2144                 // not the calling one.
2145                 appInfo.packageName = app.hostingRecord.getDefiningPackageName();
2146                 appInfo.uid = uid;
2147                 appZygote = new AppZygote(appInfo, uid, firstUid, lastUid);
2148                 mAppZygotes.put(app.info.processName, uid, appZygote);
2149                 zygoteProcessList = new ArrayList<ProcessRecord>();
2150                 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
2151             } else {
2152                 if (DEBUG_PROCESSES) {
2153                     Slog.d(TAG_PROCESSES, "Reusing existing app zygote.");
2154                 }
2155                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
2156                 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
2157             }
2158             // Note that we already add the app to mAppZygoteProcesses here;
2159             // this is so that another thread can't come in and kill the zygote
2160             // before we've even tried to start the process. If the process launch
2161             // goes wrong, we'll clean this up in removeProcessNameLocked()
2162             zygoteProcessList.add(app);
2163 
2164             return appZygote;
2165         }
2166     }
2167 
2168     private Map<String, Pair<String, Long>> getPackageAppDataInfoMap(PackageManagerInternal pmInt,
2169             String[] packages, int uid) {
2170         Map<String, Pair<String, Long>> result = new ArrayMap<>(packages.length);
2171         int userId = UserHandle.getUserId(uid);
2172         for (String packageName : packages) {
2173             AndroidPackage androidPackage = pmInt.getPackage(packageName);
2174             if (androidPackage == null) {
2175                 Slog.w(TAG, "Unknown package:" + packageName);
2176                 continue;
2177             }
2178             String volumeUuid = androidPackage.getVolumeUuid();
2179             long inode = pmInt.getCeDataInode(packageName, userId);
2180             if (inode == 0) {
2181                 Slog.w(TAG, packageName + " inode == 0 (b/152760674)");
2182                 return null;
2183             }
2184             result.put(packageName, Pair.create(volumeUuid, inode));
2185         }
2186 
2187         return result;
2188     }
2189 
2190     private boolean needsStorageDataIsolation(StorageManagerInternal storageManagerInternal,
2191             ProcessRecord app) {
2192         return mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid)
2193                 && !storageManagerInternal.isExternalStorageService(app.uid)
2194                 // Special mounting mode doesn't need to have data isolation as they won't
2195                 // access /mnt/user anyway.
2196                 && app.mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE
2197                 && app.mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH
2198                 && app.mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER;
2199     }
2200 
2201     private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
2202             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
2203             int mountExternal, String seInfo, String requiredAbi, String instructionSet,
2204             String invokeWith, long startTime) {
2205         try {
2206             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
2207                     app.processName);
2208             checkSlow(startTime, "startProcess: asking zygote to start proc");
2209             final boolean isTopApp = hostingRecord.isTopApp();
2210             if (isTopApp) {
2211                 // Use has-foreground-activities as a temporary hint so the current scheduling
2212                 // group won't be lost when the process is attaching. The actual state will be
2213                 // refreshed when computing oom-adj.
2214                 app.setHasForegroundActivities(true);
2215             }
2216 
2217             Map<String, Pair<String, Long>> pkgDataInfoMap;
2218             Map<String, Pair<String, Long>> whitelistedAppDataInfoMap;
2219             boolean bindMountAppStorageDirs = false;
2220             boolean bindMountAppsData = mAppDataIsolationEnabled
2221                     && (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid))
2222                     && mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info);
2223 
2224             // Get all packages belongs to the same shared uid. sharedPackages is empty array
2225             // if it doesn't have shared uid.
2226             final PackageManagerInternal pmInt = mService.getPackageManagerInternalLocked();
2227             final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage(
2228                     app.info.packageName, app.userId);
2229             final String[] targetPackagesList = sharedPackages.length == 0
2230                     ? new String[]{app.info.packageName} : sharedPackages;
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 mAppDataIsolationWhitelistedApps, so
2240             // it won't be mounted twice.
2241             final Set<String> whitelistedApps = new ArraySet<>(mAppDataIsolationWhitelistedApps);
2242             for (String pkg : targetPackagesList) {
2243                 whitelistedApps.remove(pkg);
2244             }
2245 
2246             whitelistedAppDataInfoMap = getPackageAppDataInfoMap(pmInt,
2247                     whitelistedApps.toArray(new String[0]), uid);
2248             if (whitelistedAppDataInfoMap == 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             int userId = UserHandle.getUserId(uid);
2255             StorageManagerInternal storageManagerInternal = LocalServices.getService(
2256                     StorageManagerInternal.class);
2257             if (needsStorageDataIsolation(storageManagerInternal, app)) {
2258                 bindMountAppStorageDirs = true;
2259                 if (pkgDataInfoMap == null ||
2260                         !storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
2261                         app.processName)) {
2262                     // Cannot prepare Android/app and Android/obb directory or inode == 0,
2263                     // so we won't mount it in zygote, but resume the mount after unlocking device.
2264                     app.bindMountPending = true;
2265                     bindMountAppStorageDirs = false;
2266                 }
2267             }
2268 
2269             // If it's an isolated process, it should not even mount its own app data directories,
2270             // since it has no access to them anyway.
2271             if (app.isolated) {
2272                 pkgDataInfoMap = null;
2273                 whitelistedAppDataInfoMap = null;
2274             }
2275 
2276             final Process.ProcessStartResult startResult;
2277             if (hostingRecord.usesWebviewZygote()) {
2278                 startResult = startWebView(entryPoint,
2279                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2280                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2281                         app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
2282                         new String[]{PROC_START_SEQ_IDENT + app.startSeq});
2283             } else if (hostingRecord.usesAppZygote()) {
2284                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
2285 
2286                 // We can't isolate app data and storage data as parent zygote already did that.
2287                 startResult = appZygote.getProcess().start(entryPoint,
2288                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2289                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2290                         app.info.dataDir, null, app.info.packageName,
2291                         /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
2292                         app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
2293                         false, false,
2294                         new String[]{PROC_START_SEQ_IDENT + app.startSeq});
2295             } else {
2296                 startResult = Process.start(entryPoint,
2297                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2298                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2299                         app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
2300                         isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
2301                         whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
2302                         new String[]{PROC_START_SEQ_IDENT + app.startSeq});
2303             }
2304             checkSlow(startTime, "startProcess: returned from zygote!");
2305             return startResult;
2306         } finally {
2307             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2308         }
2309     }
2310 
2311     @GuardedBy("mService")
2312     void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, int zygotePolicyFlags) {
2313         startProcessLocked(app, hostingRecord, zygotePolicyFlags, null /* abiOverride */);
2314     }
2315 
2316     @GuardedBy("mService")
2317     final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
2318             int zygotePolicyFlags, String abiOverride) {
2319         return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
2320                 false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
2321                 false /* mountExtStorageFull */, abiOverride);
2322     }
2323 
2324     @GuardedBy("mService")
2325     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2326             boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
2327             int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
2328             boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
2329             Runnable crashHandler) {
2330         long startTime = SystemClock.uptimeMillis();
2331         ProcessRecord app;
2332         if (!isolated) {
2333             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2334             checkSlow(startTime, "startProcess: after getProcessRecord");
2335 
2336             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2337                 // If we are in the background, then check to see if this process
2338                 // is bad.  If so, we will just silently fail.
2339                 if (mService.mAppErrors.isBadProcessLocked(info)) {
2340                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2341                             + "/" + info.processName);
2342                     return null;
2343                 }
2344             } else {
2345                 // When the user is explicitly starting a process, then clear its
2346                 // crash count so that we won't make it bad until they see at
2347                 // least one crash dialog again, and make the process good again
2348                 // if it had been bad.
2349                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2350                         + "/" + info.processName);
2351                 mService.mAppErrors.resetProcessCrashTimeLocked(info);
2352                 if (mService.mAppErrors.isBadProcessLocked(info)) {
2353                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2354                             UserHandle.getUserId(info.uid), info.uid,
2355                             info.processName);
2356                     mService.mAppErrors.clearBadProcessLocked(info);
2357                     if (app != null) {
2358                         app.bad = false;
2359                     }
2360                 }
2361             }
2362         } else {
2363             // If this is an isolated process, it can't re-use an existing process.
2364             app = null;
2365         }
2366 
2367         // We don't have to do anything more if:
2368         // (1) There is an existing application record; and
2369         // (2) The caller doesn't think it is dead, OR there is no thread
2370         //     object attached to it so we know it couldn't have crashed; and
2371         // (3) There is a pid assigned to it, so it is either starting or
2372         //     already running.
2373         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
2374                 + " app=" + app + " knownToBeDead=" + knownToBeDead
2375                 + " thread=" + (app != null ? app.thread : null)
2376                 + " pid=" + (app != null ? app.pid : -1));
2377         ProcessRecord precedence = null;
2378         if (app != null && app.pid > 0) {
2379             if ((!knownToBeDead && !app.killed) || app.thread == null) {
2380                 // We already have the app running, or are waiting for it to
2381                 // come up (we have a pid but not yet its thread), so keep it.
2382                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
2383                 // If this is a new package in the process, add the package to the list
2384                 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
2385                 checkSlow(startTime, "startProcess: done, added package to proc");
2386                 return app;
2387             }
2388 
2389             // An application record is attached to a previous process,
2390             // clean it up now.
2391             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
2392             checkSlow(startTime, "startProcess: bad proc running, killing");
2393             ProcessList.killProcessGroup(app.uid, app.pid);
2394             checkSlow(startTime, "startProcess: done killing old proc");
2395 
2396             Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");
2397             // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup
2398             // routine of it yet, but we'd set it as the precedence of the new process.
2399             precedence = app;
2400             app = null;
2401         }
2402 
2403         if (app == null) {
2404             checkSlow(startTime, "startProcess: creating new process record");
2405             app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
2406             if (app == null) {
2407                 Slog.w(TAG, "Failed making new process record for "
2408                         + processName + "/" + info.uid + " isolated=" + isolated);
2409                 return null;
2410             }
2411             app.crashHandler = crashHandler;
2412             app.isolatedEntryPoint = entryPoint;
2413             app.isolatedEntryPointArgs = entryPointArgs;
2414             if (precedence != null) {
2415                 app.mPrecedence = precedence;
2416                 precedence.mSuccessor = app;
2417             }
2418             checkSlow(startTime, "startProcess: done creating new process record");
2419         } else {
2420             // If this is a new package in the process, add the package to the list
2421             app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
2422             checkSlow(startTime, "startProcess: added package to existing proc");
2423         }
2424 
2425         // If the system is not ready yet, then hold off on starting this
2426         // process until it is.
2427         if (!mService.mProcessesReady
2428                 && !mService.isAllowedWhileBooting(info)
2429                 && !allowWhileBooting) {
2430             if (!mService.mProcessesOnHold.contains(app)) {
2431                 mService.mProcessesOnHold.add(app);
2432             }
2433             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
2434                     "System not ready, putting on hold: " + app);
2435             checkSlow(startTime, "startProcess: returning with proc on hold");
2436             return app;
2437         }
2438 
2439         checkSlow(startTime, "startProcess: stepping in to startProcess");
2440         final boolean success =
2441                 startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
2442         checkSlow(startTime, "startProcess: done starting proc!");
2443         return success ? app : null;
2444     }
2445 
2446     @GuardedBy("mService")
2447     private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
2448         StringBuilder sb = null;
2449         if (app.killedByAm) {
2450             if (sb == null) sb = new StringBuilder();
2451             sb.append("killedByAm=true;");
2452         }
2453         if (mProcessNames.get(app.processName, app.uid) != app) {
2454             if (sb == null) sb = new StringBuilder();
2455             sb.append("No entry in mProcessNames;");
2456         }
2457         if (!app.pendingStart) {
2458             if (sb == null) sb = new StringBuilder();
2459             sb.append("pendingStart=false;");
2460         }
2461         if (app.startSeq > expectedStartSeq) {
2462             if (sb == null) sb = new StringBuilder();
2463             sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
2464         }
2465         try {
2466             AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, app.userId);
2467         } catch (RemoteException e) {
2468             // unexpected; ignore
2469         } catch (SecurityException e) {
2470             if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
2471                 if (sb == null) sb = new StringBuilder();
2472                 sb.append("Package is frozen;");
2473             } else {
2474                 // we're not being started async and so should throw to the caller.
2475                 throw e;
2476             }
2477         }
2478         return sb == null ? null : sb.toString();
2479     }
2480 
2481     @GuardedBy("mService")
handleProcessStartedLocked(ProcessRecord pending, Process.ProcessStartResult startResult, long expectedStartSeq)2482     private boolean handleProcessStartedLocked(ProcessRecord pending,
2483             Process.ProcessStartResult startResult, long expectedStartSeq) {
2484         // Indicates that this process start has been taken care of.
2485         if (mPendingStarts.get(expectedStartSeq) == null) {
2486             if (pending.pid == startResult.pid) {
2487                 pending.setUsingWrapper(startResult.usingWrapper);
2488                 // TODO: Update already existing clients of usingWrapper
2489             }
2490             return false;
2491         }
2492         return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
2493                 expectedStartSeq, false);
2494     }
2495 
2496     @GuardedBy("mService")
handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, long expectedStartSeq, boolean procAttached)2497     boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
2498             long expectedStartSeq, boolean procAttached) {
2499         mPendingStarts.remove(expectedStartSeq);
2500         final String reason = isProcStartValidLocked(app, expectedStartSeq);
2501         if (reason != null) {
2502             Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
2503                     pid
2504                     + ", " + reason);
2505             app.pendingStart = false;
2506             killProcessQuiet(pid);
2507             Process.killProcessGroup(app.uid, app.pid);
2508             noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2509                     ApplicationExitInfo.SUBREASON_INVALID_START, reason);
2510             return false;
2511         }
2512         mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2513         checkSlow(app.startTime, "startProcess: done updating battery stats");
2514 
2515         EventLog.writeEvent(EventLogTags.AM_PROC_START,
2516                 UserHandle.getUserId(app.startUid), pid, app.startUid,
2517                 app.processName, app.hostingRecord.getType(),
2518                 app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
2519 
2520         try {
2521             AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
2522                     app.seInfo, app.info.sourceDir, pid);
2523         } catch (RemoteException ex) {
2524             // Ignore
2525         }
2526 
2527         Watchdog.getInstance().processStarted(app.processName, pid);
2528 
2529         checkSlow(app.startTime, "startProcess: building log message");
2530         StringBuilder buf = mStringBuilder;
2531         buf.setLength(0);
2532         buf.append("Start proc ");
2533         buf.append(pid);
2534         buf.append(':');
2535         buf.append(app.processName);
2536         buf.append('/');
2537         UserHandle.formatUid(buf, app.startUid);
2538         if (app.isolatedEntryPoint != null) {
2539             buf.append(" [");
2540             buf.append(app.isolatedEntryPoint);
2541             buf.append("]");
2542         }
2543         buf.append(" for ");
2544         buf.append(app.hostingRecord.getType());
2545         if (app.hostingRecord.getName() != null) {
2546             buf.append(" ");
2547             buf.append(app.hostingRecord.getName());
2548         }
2549         mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
2550         app.setPid(pid);
2551         app.setUsingWrapper(usingWrapper);
2552         app.pendingStart = false;
2553         checkSlow(app.startTime, "startProcess: starting to update pids map");
2554         ProcessRecord oldApp;
2555         synchronized (mService.mPidsSelfLocked) {
2556             oldApp = mService.mPidsSelfLocked.get(pid);
2557         }
2558         // If there is already an app occupying that pid that hasn't been cleaned up
2559         if (oldApp != null && !app.isolated) {
2560             // Clean up anything relating to this pid first
2561             Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
2562                     + " startSeq:" + app.startSeq
2563                     + " pid:" + pid
2564                     + " belongs to another existing app:" + oldApp.processName
2565                     + " startSeq:" + oldApp.startSeq);
2566             mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
2567                     true /*replacingPid*/);
2568         }
2569         mService.addPidLocked(app);
2570         synchronized (mService.mPidsSelfLocked) {
2571             if (!procAttached) {
2572                 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2573                 msg.obj = app;
2574                 mService.mHandler.sendMessageDelayed(msg, usingWrapper
2575                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2576             }
2577         }
2578         checkSlow(app.startTime, "startProcess: done updating pids map");
2579         return true;
2580     }
2581 
removeLruProcessLocked(ProcessRecord app)2582     final void removeLruProcessLocked(ProcessRecord app) {
2583         int lrui = mLruProcesses.lastIndexOf(app);
2584         if (lrui >= 0) {
2585             if (!app.killed) {
2586                 if (app.isPersistent()) {
2587                     Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2588                 } else {
2589                     Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2590                     if (app.pid > 0) {
2591                         killProcessQuiet(app.pid);
2592                         ProcessList.killProcessGroup(app.uid, app.pid);
2593                         noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2594                                 ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed");
2595                     } else {
2596                         app.pendingStart = false;
2597                     }
2598                 }
2599             }
2600             if (lrui < mLruProcessActivityStart) {
2601                 mLruProcessActivityStart--;
2602             }
2603             if (lrui < mLruProcessServiceStart) {
2604                 mLruProcessServiceStart--;
2605             }
2606             mLruProcesses.remove(lrui);
2607         }
2608     }
2609 
2610     @GuardedBy("mService")
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, int reasonCode, int subReason, String reason)2611     boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
2612             int reasonCode, int subReason, String reason) {
2613         return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
2614                 false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2615                 false /* evenPersistent */, false /* setRemoved */, reasonCode,
2616                 subReason, reason);
2617     }
2618 
2619     @GuardedBy("mService")
killAppZygotesLocked(String packageName, int appId, int userId, boolean force)2620     void killAppZygotesLocked(String packageName, int appId, int userId, boolean force) {
2621         // See if there are any app zygotes running for this packageName / UID combination,
2622         // and kill it if so.
2623         final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2624         for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2625             for (int i = 0; i < appZygotes.size(); ++i) {
2626                 final int appZygoteUid = appZygotes.keyAt(i);
2627                 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2628                     continue;
2629                 }
2630                 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2631                     continue;
2632                 }
2633                 final AppZygote appZygote = appZygotes.valueAt(i);
2634                 if (packageName != null
2635                         && !packageName.equals(appZygote.getAppInfo().packageName)) {
2636                     continue;
2637                 }
2638                 zygotesToKill.add(appZygote);
2639             }
2640         }
2641         for (AppZygote appZygote : zygotesToKill) {
2642             killAppZygoteIfNeededLocked(appZygote, force);
2643         }
2644     }
2645 
2646     @GuardedBy("mService")
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode, int subReason, String reason)2647     final boolean killPackageProcessesLocked(String packageName, int appId,
2648             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
2649             boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode,
2650             int subReason, String reason) {
2651         ArrayList<ProcessRecord> procs = new ArrayList<>();
2652 
2653         // Remove all processes this package may have touched: all with the
2654         // same UID (except for the system or root user), and all whose name
2655         // matches the package name.
2656         final int NP = mProcessNames.getMap().size();
2657         for (int ip = 0; ip < NP; ip++) {
2658             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2659             final int NA = apps.size();
2660             for (int ia = 0; ia < NA; ia++) {
2661                 ProcessRecord app = apps.valueAt(ia);
2662                 if (app.isPersistent() && !evenPersistent) {
2663                     // we don't kill persistent processes
2664                     continue;
2665                 }
2666                 if (app.removed) {
2667                     if (doit) {
2668                         procs.add(app);
2669                     }
2670                     continue;
2671                 }
2672 
2673                 // Skip process if it doesn't meet our oom adj requirement.
2674                 if (app.setAdj < minOomAdj) {
2675                     // Note it is still possible to have a process with oom adj 0 in the killed
2676                     // processes, but it does not mean misjudgment. E.g. a bound service process
2677                     // and its client activity process are both in the background, so they are
2678                     // collected to be killed. If the client activity is killed first, the service
2679                     // may be scheduled to unbind and become an executing service (oom adj 0).
2680                     continue;
2681                 }
2682 
2683                 // If no package is specified, we call all processes under the
2684                 // give user id.
2685                 if (packageName == null) {
2686                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
2687                         continue;
2688                     }
2689                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2690                         continue;
2691                     }
2692                     // Package has been specified, we want to hit all processes
2693                     // that match it.  We need to qualify this by the processes
2694                     // that are running under the specified app and user ID.
2695                 } else {
2696                     final boolean isDep = app.pkgDeps != null
2697                             && app.pkgDeps.contains(packageName);
2698                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2699                         continue;
2700                     }
2701                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
2702                         continue;
2703                     }
2704                     if (!app.pkgList.containsKey(packageName) && !isDep) {
2705                         continue;
2706                     }
2707                 }
2708 
2709                 // Process has passed all conditions, kill it!
2710                 if (!doit) {
2711                     return true;
2712                 }
2713                 if (setRemoved) {
2714                     app.removed = true;
2715                 }
2716                 procs.add(app);
2717             }
2718         }
2719 
2720         int N = procs.size();
2721         for (int i=0; i<N; i++) {
2722             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart,
2723                     reasonCode, subReason, reason);
2724         }
2725         killAppZygotesLocked(packageName, appId, userId, false /* force */);
2726         mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
2727         return N > 0;
2728     }
2729 
2730     @GuardedBy("mService")
removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason)2731     boolean removeProcessLocked(ProcessRecord app,
2732             boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) {
2733         return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode,
2734                 ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
2735     }
2736 
2737     @GuardedBy("mService")
removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, int reasonCode, int subReason, String reason)2738     boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
2739             boolean allowRestart, int reasonCode, int subReason, String reason) {
2740         final String name = app.processName;
2741         final int uid = app.uid;
2742         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
2743                 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
2744 
2745         ProcessRecord old = mProcessNames.get(name, uid);
2746         if (old != app) {
2747             // This process is no longer active, so nothing to do.
2748             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
2749             return false;
2750         }
2751         removeProcessNameLocked(name, uid);
2752         mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
2753 
2754         boolean needRestart = false;
2755         if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
2756                 .pendingStart)) {
2757             int pid = app.pid;
2758             if (pid > 0) {
2759                 mService.removePidLocked(app);
2760                 app.bindMountPending = false;
2761                 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2762                 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2763                 if (app.isolated) {
2764                     mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2765                     mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
2766                 }
2767             }
2768             boolean willRestart = false;
2769             if (app.isPersistent() && !app.isolated) {
2770                 if (!callerWillRestart) {
2771                     willRestart = true;
2772                 } else {
2773                     needRestart = true;
2774                 }
2775             }
2776             app.kill(reason, reasonCode, subReason, true);
2777             mService.handleAppDiedLocked(app, willRestart, allowRestart);
2778             if (willRestart) {
2779                 removeLruProcessLocked(app);
2780                 mService.addAppLocked(app.info, null, false, null /* ABI override */,
2781                         ZYGOTE_POLICY_FLAG_EMPTY);
2782             }
2783         } else {
2784             mRemovedProcesses.add(app);
2785         }
2786 
2787         return needRestart;
2788     }
2789 
2790     @GuardedBy("mService")
addProcessNameLocked(ProcessRecord proc)2791     final void addProcessNameLocked(ProcessRecord proc) {
2792         // We shouldn't already have a process under this name, but just in case we
2793         // need to clean up whatever may be there now.
2794         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
2795         if (old == proc && proc.isPersistent()) {
2796             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
2797             Slog.w(TAG, "Re-adding persistent process " + proc);
2798         } else if (old != null) {
2799             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
2800         }
2801         UidRecord uidRec = mActiveUids.get(proc.uid);
2802         if (uidRec == null) {
2803             uidRec = new UidRecord(proc.uid);
2804             // This is the first appearance of the uid, report it now!
2805             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2806                     "Creating new process uid: " + uidRec);
2807             if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
2808                     UserHandle.getAppId(proc.uid)) >= 0
2809                     || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
2810                 uidRec.setWhitelist = uidRec.curWhitelist = true;
2811             }
2812             uidRec.updateHasInternetPermission();
2813             mActiveUids.put(proc.uid, uidRec);
2814             EventLogTags.writeAmUidRunning(uidRec.uid);
2815             mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState(),
2816                     uidRec.curCapability);
2817         }
2818         proc.uidRecord = uidRec;
2819         uidRec.procRecords.add(proc);
2820 
2821         // Reset render thread tid if it was already set, so new process can set it again.
2822         proc.renderThreadTid = 0;
2823         uidRec.numProcs++;
2824         mProcessNames.put(proc.processName, proc.uid, proc);
2825         if (proc.isolated) {
2826             mIsolatedProcesses.put(proc.uid, proc);
2827         }
2828     }
2829 
2830     @GuardedBy("mService")
getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, HostingRecord hostingRecord)2831     private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
2832             HostingRecord hostingRecord) {
2833         if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
2834             // Allocate an isolated UID from the global range
2835             return mGlobalIsolatedUids;
2836         } else {
2837             return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
2838                     info.processName, hostingRecord.getDefiningUid());
2839         }
2840     }
2841 
2842     @GuardedBy("mService")
newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid, HostingRecord hostingRecord)2843     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
2844             boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
2845         String proc = customProcess != null ? customProcess : info.processName;
2846         final int userId = UserHandle.getUserId(info.uid);
2847         int uid = info.uid;
2848         if (isolated) {
2849             if (isolatedUid == 0) {
2850                 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
2851                 if (uidRange == null) {
2852                     return null;
2853                 }
2854                 uid = uidRange.allocateIsolatedUidLocked(userId);
2855                 if (uid == -1) {
2856                     return null;
2857                 }
2858             } else {
2859                 // Special case for startIsolatedProcess (internal only), where
2860                 // the uid of the isolated process is specified by the caller.
2861                 uid = isolatedUid;
2862             }
2863             mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid);
2864             mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
2865 
2866             // Register the isolated UID with this application so BatteryStats knows to
2867             // attribute resource usage to the application.
2868             //
2869             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
2870             // about the process state of the isolated UID *before* it is registered with the
2871             // owning application.
2872             mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
2873             FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
2874                     FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
2875         }
2876         final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
2877 
2878         if (!mService.mBooted && !mService.mBooting
2879                 && userId == UserHandle.USER_SYSTEM
2880                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
2881             // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
2882             r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
2883             r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
2884             r.setPersistent(true);
2885             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
2886         }
2887         if (isolated && isolatedUid != 0) {
2888             // Special case for startIsolatedProcess (internal only) - assume the process
2889             // is required by the system server to prevent it being killed.
2890             r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
2891         }
2892         addProcessNameLocked(r);
2893         return r;
2894     }
2895 
2896     @GuardedBy("mService")
removeProcessNameLocked(final String name, final int uid)2897     final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
2898         return removeProcessNameLocked(name, uid, null);
2899     }
2900 
2901     @GuardedBy("mService")
removeProcessNameLocked(final String name, final int uid, final ProcessRecord expecting)2902     final ProcessRecord removeProcessNameLocked(final String name, final int uid,
2903             final ProcessRecord expecting) {
2904         ProcessRecord old = mProcessNames.get(name, uid);
2905         // Only actually remove when the currently recorded value matches the
2906         // record that we expected; if it doesn't match then we raced with a
2907         // newly created process and we don't want to destroy the new one.
2908         if ((expecting == null) || (old == expecting)) {
2909             mProcessNames.remove(name, uid);
2910         }
2911         if (old != null && old.uidRecord != null) {
2912             old.uidRecord.numProcs--;
2913             old.uidRecord.procRecords.remove(old);
2914             if (old.uidRecord.numProcs == 0) {
2915                 // No more processes using this uid, tell clients it is gone.
2916                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2917                         "No more processes in " + old.uidRecord);
2918                 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
2919                 EventLogTags.writeAmUidStopped(uid);
2920                 mActiveUids.remove(uid);
2921                 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
2922                         ActivityManager.PROCESS_CAPABILITY_NONE);
2923             }
2924             old.uidRecord = null;
2925         }
2926         mIsolatedProcesses.remove(uid);
2927         mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
2928         // Remove the (expected) ProcessRecord from the app zygote
2929         final ProcessRecord record = expecting != null ? expecting : old;
2930         if (record != null && record.appZygote) {
2931             removeProcessFromAppZygoteLocked(record);
2932         }
2933 
2934         return old;
2935     }
2936 
2937     /** Call setCoreSettings on all LRU processes, with the new settings. */
2938     @GuardedBy("mService")
updateCoreSettingsLocked(Bundle settings)2939     void updateCoreSettingsLocked(Bundle settings) {
2940         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2941             ProcessRecord processRecord = mLruProcesses.get(i);
2942             try {
2943                 if (processRecord.thread != null) {
2944                     processRecord.thread.setCoreSettings(settings);
2945                 }
2946             } catch (RemoteException re) {
2947                 /* ignore */
2948             }
2949         }
2950     }
2951 
2952     /**
2953      * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2954      * procstate lower than maxProcState.
2955      * @param minTargetSdk
2956      * @param maxProcState
2957      */
2958     @GuardedBy("mService")
killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState)2959     void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2960         final ArrayList<ProcessRecord> procs = new ArrayList<>();
2961         final int NP = mProcessNames.getMap().size();
2962         for (int ip = 0; ip < NP; ip++) {
2963             final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2964             final int NA = apps.size();
2965             for (int ia = 0; ia < NA; ia++) {
2966                 final ProcessRecord app = apps.valueAt(ia);
2967                 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2968                         && (maxProcState < 0 || app.setProcState > maxProcState))) {
2969                     procs.add(app);
2970                 }
2971             }
2972         }
2973 
2974         final int N = procs.size();
2975         for (int i = 0; i < N; i++) {
2976             removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER,
2977                     ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except");
2978         }
2979     }
2980 
2981     /**
2982      * Call updateTimePrefs on all LRU processes
2983      * @param timePref The time pref to pass to each process
2984      */
2985     @GuardedBy("mService")
updateAllTimePrefsLocked(int timePref)2986     void updateAllTimePrefsLocked(int timePref) {
2987         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2988             ProcessRecord r = mLruProcesses.get(i);
2989             if (r.thread != null) {
2990                 try {
2991                     r.thread.updateTimePrefs(timePref);
2992                 } catch (RemoteException ex) {
2993                     Slog.w(TAG, "Failed to update preferences for: "
2994                             + r.info.processName);
2995                 }
2996             }
2997         }
2998     }
2999 
setAllHttpProxy()3000     void setAllHttpProxy() {
3001         // Update the HTTP proxy for each application thread.
3002         synchronized (mService) {
3003             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
3004                 ProcessRecord r = mLruProcesses.get(i);
3005                 // Don't dispatch to isolated processes as they can't access ConnectivityManager and
3006                 // don't have network privileges anyway. Exclude system server and update it
3007                 // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
3008                 if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) {
3009                     try {
3010                         r.thread.updateHttpProxy();
3011                     } catch (RemoteException ex) {
3012                         Slog.w(TAG, "Failed to update http proxy for: "
3013                                 + r.info.processName);
3014                     }
3015                 }
3016             }
3017         }
3018         ActivityThread.updateHttpProxy(mService.mContext);
3019     }
3020 
3021     @GuardedBy("mService")
clearAllDnsCacheLocked()3022     void clearAllDnsCacheLocked() {
3023         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3024             ProcessRecord r = mLruProcesses.get(i);
3025             if (r.thread != null) {
3026                 try {
3027                     r.thread.clearDnsCache();
3028                 } catch (RemoteException ex) {
3029                     Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
3030                 }
3031             }
3032         }
3033     }
3034 
3035     @GuardedBy("mService")
handleAllTrustStorageUpdateLocked()3036     void handleAllTrustStorageUpdateLocked() {
3037         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3038             ProcessRecord r = mLruProcesses.get(i);
3039             if (r.thread != null) {
3040                 try {
3041                     r.thread.handleTrustStorageUpdate();
3042                 } catch (RemoteException ex) {
3043                     Slog.w(TAG, "Failed to handle trust storage update for: " +
3044                             r.info.processName);
3045                 }
3046             }
3047         }
3048     }
3049 
3050     @GuardedBy("mService")
updateLruProcessInternalLocked(ProcessRecord app, long now, int index, int lruSeq, String what, Object obj, ProcessRecord srcApp)3051     int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3052             int lruSeq, String what, Object obj, ProcessRecord srcApp) {
3053         app.lastActivityTime = now;
3054 
3055         if (app.hasActivitiesOrRecentTasks()) {
3056             // Don't want to touch dependent processes that are hosting activities.
3057             return index;
3058         }
3059 
3060         int lrui = mLruProcesses.lastIndexOf(app);
3061         if (lrui < 0) {
3062             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3063                     + what + " " + obj + " from " + srcApp);
3064             return index;
3065         }
3066 
3067         if (lrui >= index) {
3068             // Don't want to cause this to move dependent processes *back* in the
3069             // list as if they were less frequently used.
3070             return index;
3071         }
3072 
3073         if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
3074             // Don't want to touch dependent processes that are hosting activities.
3075             return index;
3076         }
3077 
3078         mLruProcesses.remove(lrui);
3079         if (index > 0) {
3080             index--;
3081         }
3082         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3083                 + " in LRU list: " + app);
3084         mLruProcesses.add(index, app);
3085         app.lruSeq = lruSeq;
3086         return index;
3087     }
3088 
3089     /**
3090      * Handle the case where we are inserting a process hosting client activities:
3091      * Make sure any groups have their order match their importance, and take care of
3092      * distributing old clients across other activity processes so they can't spam
3093      * the LRU list.  Processing of the list will be restricted by the indices provided,
3094      * and not extend out of them.
3095      *
3096      * @param topApp The app at the top that has just been inserted in to the list.
3097      * @param topI The position in the list where topApp was inserted; this is the start (at the
3098      *             top) where we are going to do our processing.
3099      * @param bottomI The last position at which we will be processing; this is the end position
3100      *                of whichever section of the LRU list we are in.  Nothing past it will be
3101      *                touched.
3102      * @param endIndex The current end of the top being processed.  Typically topI - 1.  That is,
3103      *                 where we are going to start potentially adjusting other entries in the list.
3104      */
updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI, final int bottomI, int endIndex)3105     private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
3106             final int bottomI, int endIndex) {
3107         if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
3108                 || !topApp.hasClientActivities()) {
3109             // If this is not a special process that has client activities, then there is
3110             // nothing to do.
3111             return;
3112         }
3113 
3114         final int uid = topApp.info.uid;
3115         if (topApp.connectionGroup > 0) {
3116             int endImportance = topApp.connectionImportance;
3117             for (int i = endIndex; i >= bottomI; i--) {
3118                 final ProcessRecord subProc = mLruProcesses.get(i);
3119                 if (subProc.info.uid == uid
3120                         && subProc.connectionGroup == topApp.connectionGroup) {
3121                     if (i == endIndex && subProc.connectionImportance >= endImportance) {
3122                         // This process is already in the group, and its importance
3123                         // is not as strong as the process before it, so keep it
3124                         // correctly positioned in the group.
3125                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3126                                 "Keeping in-place above " + subProc
3127                                         + " endImportance=" + endImportance
3128                                         + " group=" + subProc.connectionGroup
3129                                         + " importance=" + subProc.connectionImportance);
3130                         endIndex--;
3131                         endImportance = subProc.connectionImportance;
3132                     } else {
3133                         // We want to pull this up to be with the rest of the group,
3134                         // and order within the group by importance.
3135                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3136                                 "Pulling up " + subProc
3137                                         + " to position in group with importance="
3138                                         + subProc.connectionImportance);
3139                         boolean moved = false;
3140                         for (int pos = topI; pos > endIndex; pos--) {
3141                             final ProcessRecord posProc = mLruProcesses.get(pos);
3142                             if (subProc.connectionImportance
3143                                     <= posProc.connectionImportance) {
3144                                 mLruProcesses.remove(i);
3145                                 mLruProcesses.add(pos, subProc);
3146                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3147                                         "Moving " + subProc
3148                                                 + " from position " + i + " to above " + posProc
3149                                                 + " @ " + pos);
3150                                 moved = true;
3151                                 endIndex--;
3152                                 break;
3153                             }
3154                         }
3155                         if (!moved) {
3156                             // Goes to the end of the group.
3157                             mLruProcesses.remove(i);
3158                             mLruProcesses.add(endIndex, subProc);
3159                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3160                                     "Moving " + subProc
3161                                             + " from position " + i + " to end of group @ "
3162                                             + endIndex);
3163                             endIndex--;
3164                             endImportance = subProc.connectionImportance;
3165                         }
3166                     }
3167                 }
3168             }
3169 
3170         }
3171         // To keep it from spamming the LRU list (by making a bunch of clients),
3172         // we will distribute other entries owned by it to be in-between other apps.
3173         int i = endIndex;
3174         while (i >= bottomI) {
3175             ProcessRecord subProc = mLruProcesses.get(i);
3176             if (DEBUG_LRU) Slog.d(TAG_LRU,
3177                     "Looking to spread old procs, at " + subProc + " @ " + i);
3178             if (subProc.info.uid != uid) {
3179                 // This is a different app...  if we have gone through some of the
3180                 // target app, pull this up to be before them.  We want to pull up
3181                 // one activity process, but any number of non-activity processes.
3182                 if (i < endIndex) {
3183                     boolean hasActivity = false;
3184                     int connUid = 0;
3185                     int connGroup = 0;
3186                     while (i >= bottomI) {
3187                         mLruProcesses.remove(i);
3188                         mLruProcesses.add(endIndex, subProc);
3189                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3190                                 "Different app, moving to " + endIndex);
3191                         i--;
3192                         if (i < bottomI) {
3193                             break;
3194                         }
3195                         subProc = mLruProcesses.get(i);
3196                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3197                                 "Looking at next app at " + i + ": " + subProc);
3198                         if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
3199                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3200                                     "This is hosting an activity!");
3201                             if (hasActivity) {
3202                                 // Already found an activity, done.
3203                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3204                                         "Already found an activity, done");
3205                                 break;
3206                             }
3207                             hasActivity = true;
3208                         } else if (subProc.hasClientActivities()) {
3209                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3210                                     "This is a client of an activity");
3211                             if (hasActivity) {
3212                                 if (connUid == 0 || connUid != subProc.info.uid) {
3213                                     // Already have an activity that is not from from a client
3214                                     // connection or is a different client connection, done.
3215                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
3216                                             "Already found a different activity: connUid="
3217                                             + connUid + " uid=" + subProc.info.uid);
3218                                     break;
3219                                 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
3220                                     // Previously saw a different group or not from a group,
3221                                     // want to treat these as different things.
3222                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
3223                                             "Already found a different group: connGroup="
3224                                             + connGroup + " group=" + subProc.connectionGroup);
3225                                     break;
3226                                 }
3227                             } else {
3228                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3229                                         "This is an activity client!  uid="
3230                                         + subProc.info.uid + " group=" + subProc.connectionGroup);
3231                                 hasActivity = true;
3232                                 connUid = subProc.info.uid;
3233                                 connGroup = subProc.connectionGroup;
3234                             }
3235                         }
3236                         endIndex--;
3237                     }
3238                 }
3239                 // Find the end of the next group of processes for target app.  This
3240                 // is after any entries of different apps (so we don't change the existing
3241                 // relative order of apps) and then after the next last group of processes
3242                 // of the target app.
3243                 for (endIndex--; endIndex >= bottomI; endIndex--) {
3244                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
3245                     if (endProc.info.uid == uid) {
3246                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3247                                 "Found next group of app: " + endProc + " @ "
3248                                         + endIndex);
3249                         break;
3250                     }
3251                 }
3252                 if (endIndex >= bottomI) {
3253                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
3254                     for (endIndex--; endIndex >= bottomI; endIndex--) {
3255                         final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
3256                         if (nextEndProc.info.uid != uid
3257                                 || nextEndProc.connectionGroup != endProc.connectionGroup) {
3258                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3259                                     "Found next group or app: " + nextEndProc + " @ "
3260                                             + endIndex + " group=" + nextEndProc.connectionGroup);
3261                             break;
3262                         }
3263                     }
3264                 }
3265                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3266                         "Bumping scan position to " + endIndex);
3267                 i = endIndex;
3268             } else {
3269                 i--;
3270             }
3271         }
3272     }
3273 
updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client)3274     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3275             ProcessRecord client) {
3276         final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
3277                 || app.treatLikeActivity;
3278         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3279         if (!activityChange && hasActivity) {
3280             // The process has activities, so we are only allowing activity-based adjustments
3281             // to move it.  It should be kept in the front of the list with other
3282             // processes that have activities, and we don't want those to change their
3283             // order except due to activity operations.
3284             return;
3285         }
3286 
3287         mLruSeq++;
3288         final long now = SystemClock.uptimeMillis();
3289         app.lastActivityTime = now;
3290 
3291         // First a quick reject: if the app is already at the position we will
3292         // put it, then there is nothing to do.
3293         if (hasActivity) {
3294             final int N = mLruProcesses.size();
3295             if (N > 0 && mLruProcesses.get(N - 1) == app) {
3296                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3297                 return;
3298             }
3299         } else {
3300             if (mLruProcessServiceStart > 0
3301                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3302                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3303                 return;
3304             }
3305         }
3306 
3307         int lrui = mLruProcesses.lastIndexOf(app);
3308 
3309         if (app.isPersistent() && lrui >= 0) {
3310             // We don't care about the position of persistent processes, as long as
3311             // they are in the list.
3312             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3313             return;
3314         }
3315 
3316         /* In progress: compute new position first, so we can avoid doing work
3317            if the process is not actually going to move.  Not yet working.
3318         int addIndex;
3319         int nextIndex;
3320         boolean inActivity = false, inService = false;
3321         if (hasActivity) {
3322             // Process has activities, put it at the very tipsy-top.
3323             addIndex = mLruProcesses.size();
3324             nextIndex = mLruProcessServiceStart;
3325             inActivity = true;
3326         } else if (hasService) {
3327             // Process has services, put it at the top of the service list.
3328             addIndex = mLruProcessActivityStart;
3329             nextIndex = mLruProcessServiceStart;
3330             inActivity = true;
3331             inService = true;
3332         } else  {
3333             // Process not otherwise of interest, it goes to the top of the non-service area.
3334             addIndex = mLruProcessServiceStart;
3335             if (client != null) {
3336                 int clientIndex = mLruProcesses.lastIndexOf(client);
3337                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3338                         + app);
3339                 if (clientIndex >= 0 && addIndex > clientIndex) {
3340                     addIndex = clientIndex;
3341                 }
3342             }
3343             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3344         }
3345 
3346         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3347                 + mLruProcessActivityStart + "): " + app);
3348         */
3349 
3350         if (lrui >= 0) {
3351             if (lrui < mLruProcessActivityStart) {
3352                 mLruProcessActivityStart--;
3353             }
3354             if (lrui < mLruProcessServiceStart) {
3355                 mLruProcessServiceStart--;
3356             }
3357             /*
3358             if (addIndex > lrui) {
3359                 addIndex--;
3360             }
3361             if (nextIndex > lrui) {
3362                 nextIndex--;
3363             }
3364             */
3365             mLruProcesses.remove(lrui);
3366         }
3367 
3368         /*
3369         mLruProcesses.add(addIndex, app);
3370         if (inActivity) {
3371             mLruProcessActivityStart++;
3372         }
3373         if (inService) {
3374             mLruProcessActivityStart++;
3375         }
3376         */
3377 
3378         int nextIndex;
3379         int nextActivityIndex = -1;
3380         if (hasActivity) {
3381             final int N = mLruProcesses.size();
3382             nextIndex = mLruProcessServiceStart;
3383             if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
3384                     && mLruProcessActivityStart < (N - 1)) {
3385                 // Process doesn't have activities, but has clients with
3386                 // activities...  move it up, but below the app that is binding to it.
3387                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3388                         "Adding to second-top of LRU activity list: " + app
3389                         + " group=" + app.connectionGroup
3390                         + " importance=" + app.connectionImportance);
3391                 int pos = N - 1;
3392                 while (pos > mLruProcessActivityStart) {
3393                     final ProcessRecord posproc = mLruProcesses.get(pos);
3394                     if (posproc.info.uid == app.info.uid) {
3395                         // Technically this app could have multiple processes with different
3396                         // activities and so we should be looking for the actual process that
3397                         // is bound to the target proc...  but I don't really care, do you?
3398                         break;
3399                     }
3400                     pos--;
3401                 }
3402                 mLruProcesses.add(pos, app);
3403                 // If this process is part of a group, need to pull up any other processes
3404                 // in that group to be with it.
3405                 int endIndex = pos - 1;
3406                 if (endIndex < mLruProcessActivityStart) {
3407                     endIndex = mLruProcessActivityStart;
3408                 }
3409                 nextActivityIndex = endIndex;
3410                 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
3411             } else {
3412                 // Process has activities, put it at the very tipsy-top.
3413                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3414                 mLruProcesses.add(app);
3415                 nextActivityIndex = mLruProcesses.size() - 1;
3416             }
3417         } else if (hasService) {
3418             // Process has services, put it at the top of the service list.
3419             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3420             mLruProcesses.add(mLruProcessActivityStart, app);
3421             nextIndex = mLruProcessServiceStart;
3422             mLruProcessActivityStart++;
3423         } else  {
3424             // Process not otherwise of interest, it goes to the top of the non-service area.
3425             int index = mLruProcessServiceStart;
3426             if (client != null) {
3427                 // If there is a client, don't allow the process to be moved up higher
3428                 // in the list than that client.
3429                 int clientIndex = mLruProcesses.lastIndexOf(client);
3430                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3431                         + " when updating " + app);
3432                 if (clientIndex <= lrui) {
3433                     // Don't allow the client index restriction to push it down farther in the
3434                     // list than it already is.
3435                     clientIndex = lrui;
3436                 }
3437                 if (clientIndex >= 0 && index > clientIndex) {
3438                     index = clientIndex;
3439                 }
3440             }
3441             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3442             mLruProcesses.add(index, app);
3443             nextIndex = index - 1;
3444             mLruProcessActivityStart++;
3445             mLruProcessServiceStart++;
3446             if (index > 1) {
3447                 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
3448             }
3449         }
3450 
3451         app.lruSeq = mLruSeq;
3452 
3453         // If the app is currently using a content provider or service,
3454         // bump those processes as well.
3455         for (int j = app.connections.size() - 1; j >= 0; j--) {
3456             ConnectionRecord cr = app.connections.valueAt(j);
3457             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3458                     && cr.binding.service.app != null
3459                     && cr.binding.service.app.lruSeq != mLruSeq
3460                     && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
3461                     && !cr.binding.service.app.isPersistent()) {
3462                 if (cr.binding.service.app.hasClientActivities()) {
3463                     if (nextActivityIndex >= 0) {
3464                         nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
3465                                 now,
3466                                 nextActivityIndex, mLruSeq,
3467                                 "service connection", cr, app);
3468                     }
3469                 } else {
3470                     nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
3471                             now,
3472                             nextIndex, mLruSeq,
3473                             "service connection", cr, app);
3474                 }
3475             }
3476         }
3477         for (int j = app.conProviders.size() - 1; j >= 0; j--) {
3478             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3479             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
3480                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
3481                         "provider reference", cpr, app);
3482             }
3483         }
3484     }
3485 
getLRURecordForAppLocked(IApplicationThread thread)3486     final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
3487         if (thread == null) {
3488             return null;
3489         }
3490         final IBinder threadBinder = thread.asBinder();
3491         // Find the application record.
3492         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3493             final ProcessRecord rec = mLruProcesses.get(i);
3494             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3495                 return rec;
3496             }
3497         }
3498         return null;
3499     }
3500 
haveBackgroundProcessLocked()3501     boolean haveBackgroundProcessLocked() {
3502         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3503             final ProcessRecord rec = mLruProcesses.get(i);
3504             if (rec.thread != null
3505                     && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
3506                 return true;
3507             }
3508         }
3509         return false;
3510     }
3511 
procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp, int clientTargetSdk)3512     private static int procStateToImportance(int procState, int memAdj,
3513             ActivityManager.RunningAppProcessInfo currApp,
3514             int clientTargetSdk) {
3515         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
3516                 procState, clientTargetSdk);
3517         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
3518             currApp.lru = memAdj;
3519         } else {
3520             currApp.lru = 0;
3521         }
3522         return imp;
3523     }
3524 
3525     @GuardedBy("mService")
fillInProcMemInfoLocked(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, int clientTargetSdk)3526     void fillInProcMemInfoLocked(ProcessRecord app,
3527             ActivityManager.RunningAppProcessInfo outInfo,
3528             int clientTargetSdk) {
3529         outInfo.pid = app.pid;
3530         outInfo.uid = app.info.uid;
3531         if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
3532             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
3533         }
3534         if (app.isPersistent()) {
3535             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
3536         }
3537         if (app.hasActivities()) {
3538             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
3539         }
3540         outInfo.lastTrimLevel = app.trimMemoryLevel;
3541         int adj = app.curAdj;
3542         int procState = app.getCurProcState();
3543         outInfo.importance = procStateToImportance(procState, adj, outInfo,
3544                 clientTargetSdk);
3545         outInfo.importanceReasonCode = app.adjTypeCode;
3546         outInfo.processState = app.getCurProcState();
3547         outInfo.isFocused = (app == mService.getTopAppLocked());
3548         outInfo.lastActivityTime = app.lastActivityTime;
3549     }
3550 
3551     @GuardedBy("mService")
getRunningAppProcessesLocked(boolean allUsers, int userId, boolean allUids, int callingUid, int clientTargetSdk)3552     List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
3553             int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3554         // Lazy instantiation of list
3555         List<ActivityManager.RunningAppProcessInfo> runList = null;
3556 
3557         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3558             ProcessRecord app = mLruProcesses.get(i);
3559             if ((!allUsers && app.userId != userId)
3560                     || (!allUids && app.uid != callingUid)) {
3561                 continue;
3562             }
3563             if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
3564                 // Generate process state info for running application
3565                 ActivityManager.RunningAppProcessInfo currApp =
3566                         new ActivityManager.RunningAppProcessInfo(app.processName,
3567                                 app.pid, app.getPackageList());
3568                 fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
3569                 if (app.adjSource instanceof ProcessRecord) {
3570                     currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
3571                     currApp.importanceReasonImportance =
3572                             ActivityManager.RunningAppProcessInfo.procStateToImportance(
3573                                     app.adjSourceProcState);
3574                 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
3575                     final ActivityServiceConnectionsHolder r =
3576                             (ActivityServiceConnectionsHolder) app.adjSource;
3577                     final int pid = r.getActivityPid();
3578                     if (pid != -1) {
3579                         currApp.importanceReasonPid = pid;
3580                     }
3581                 }
3582                 if (app.adjTarget instanceof ComponentName) {
3583                     currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
3584                 }
3585                 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
3586                 //        + " lru=" + currApp.lru);
3587                 if (runList == null) {
3588                     runList = new ArrayList<>();
3589                 }
3590                 runList.add(currApp);
3591             }
3592         }
3593         return runList;
3594     }
3595 
3596     @GuardedBy("mService")
getLruSizeLocked()3597     int getLruSizeLocked() {
3598         return mLruProcesses.size();
3599     }
3600 
3601     @GuardedBy("mService")
dumpLruListHeaderLocked(PrintWriter pw)3602     void dumpLruListHeaderLocked(PrintWriter pw) {
3603         pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
3604         pw.print(" total, non-act at ");
3605         pw.print(mLruProcesses.size() - mLruProcessActivityStart);
3606         pw.print(", non-svc at ");
3607         pw.print(mLruProcesses.size() - mLruProcessServiceStart);
3608         pw.println("):");
3609     }
3610 
3611     @GuardedBy("mService")
collectProcessesLocked(int start, boolean allPkgs, String[] args)3612     ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
3613         ArrayList<ProcessRecord> procs;
3614         if (args != null && args.length > start
3615                 && args[start].charAt(0) != '-') {
3616             procs = new ArrayList<ProcessRecord>();
3617             int pid = -1;
3618             try {
3619                 pid = Integer.parseInt(args[start]);
3620             } catch (NumberFormatException e) {
3621             }
3622             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3623                 ProcessRecord proc = mLruProcesses.get(i);
3624                 if (proc.pid > 0 && proc.pid == pid) {
3625                     procs.add(proc);
3626                 } else if (allPkgs && proc.pkgList != null
3627                         && proc.pkgList.containsKey(args[start])) {
3628                     procs.add(proc);
3629                 } else if (proc.processName.equals(args[start])) {
3630                     procs.add(proc);
3631                 }
3632             }
3633             if (procs.size() <= 0) {
3634                 return null;
3635             }
3636         } else {
3637             procs = new ArrayList<ProcessRecord>(mLruProcesses);
3638         }
3639         return procs;
3640     }
3641 
3642     @GuardedBy("mService")
updateApplicationInfoLocked(List<String> packagesToUpdate, int userId, boolean updateFrameworkRes)3643     void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3644             boolean updateFrameworkRes) {
3645         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3646             final ProcessRecord app = mLruProcesses.get(i);
3647             if (app.thread == null) {
3648                 continue;
3649             }
3650 
3651             if (userId != UserHandle.USER_ALL && app.userId != userId) {
3652                 continue;
3653             }
3654 
3655             final int packageCount = app.pkgList.size();
3656             for (int j = 0; j < packageCount; j++) {
3657                 final String packageName = app.pkgList.keyAt(j);
3658                 if (!updateFrameworkRes && !packagesToUpdate.contains(packageName)) {
3659                     continue;
3660                 }
3661                 try {
3662                     final ApplicationInfo ai = AppGlobals.getPackageManager()
3663                             .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3664                     if (ai == null) {
3665                         continue;
3666                     }
3667                     app.thread.scheduleApplicationInfoChanged(ai);
3668                     if (ai.packageName.equals(app.info.packageName)) {
3669                         app.info = ai;
3670                     }
3671                 } catch (RemoteException e) {
3672                     Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3673                             packageName, app));
3674                 }
3675             }
3676         }
3677     }
3678 
3679     @GuardedBy("mService")
sendPackageBroadcastLocked(int cmd, String[] packages, int userId)3680     void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
3681         boolean foundProcess = false;
3682         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3683             ProcessRecord r = mLruProcesses.get(i);
3684             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3685                 try {
3686                     for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
3687                         if (packages[index].equals(r.info.packageName)) {
3688                             foundProcess = true;
3689                         }
3690                     }
3691                     r.thread.dispatchPackageBroadcast(cmd, packages);
3692                 } catch (RemoteException ex) {
3693                 }
3694             }
3695         }
3696 
3697         if (!foundProcess) {
3698             try {
3699                 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
3700             } catch (RemoteException ignored) {
3701             }
3702         }
3703     }
3704 
3705     /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3706     @GuardedBy("mService")
getUidProcStateLocked(int uid)3707     int getUidProcStateLocked(int uid) {
3708         UidRecord uidRec = mActiveUids.get(uid);
3709         return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3710     }
3711 
3712     /** Returns the UidRecord for the given uid, if it exists. */
3713     @GuardedBy("mService")
getUidRecordLocked(int uid)3714     UidRecord getUidRecordLocked(int uid) {
3715         return mActiveUids.get(uid);
3716     }
3717 
3718     /**
3719      * Call {@link ActivityManagerService#doStopUidLocked}
3720      * (which will also stop background services) for all idle UIDs.
3721      */
3722     @GuardedBy("mService")
doStopUidForIdleUidsLocked()3723     void doStopUidForIdleUidsLocked() {
3724         final int size = mActiveUids.size();
3725         for (int i = 0; i < size; i++) {
3726             final int uid = mActiveUids.keyAt(i);
3727             if (UserHandle.isCore(uid)) {
3728                 continue;
3729             }
3730             final UidRecord uidRec = mActiveUids.valueAt(i);
3731             if (!uidRec.idle) {
3732                 continue;
3733             }
3734             mService.doStopUidLocked(uidRec.uid, uidRec);
3735         }
3736     }
3737 
3738     /**
3739      * Checks if the uid is coming from background to foreground or vice versa and returns
3740      * appropriate block state based on this.
3741      *
3742      * @return blockState based on whether the uid is coming from background to foreground or
3743      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
3744      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
3745      *         {@link #NETWORK_STATE_NO_CHANGE}.
3746      */
3747     @VisibleForTesting
getBlockStateForUid(UidRecord uidRec)3748     int getBlockStateForUid(UidRecord uidRec) {
3749         // Denotes whether uid's process state is currently allowed network access.
3750         final boolean isAllowed =
3751                 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState())
3752                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState());
3753         // Denotes whether uid's process state was previously allowed network access.
3754         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
3755                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
3756 
3757         // When the uid is coming to foreground, AMS should inform the app thread that it should
3758         // block for the network rules to get updated before launching an activity.
3759         if (!wasAllowed && isAllowed) {
3760             return NETWORK_STATE_BLOCK;
3761         }
3762         // When the uid is going to background, AMS should inform the app thread that if an
3763         // activity launch is blocked for the network rules to get updated, it should be unblocked.
3764         if (wasAllowed && !isAllowed) {
3765             return NETWORK_STATE_UNBLOCK;
3766         }
3767         return NETWORK_STATE_NO_CHANGE;
3768     }
3769 
3770     /**
3771      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
3772      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
3773      * {@link ProcessList#mProcStateSeqCounter} and notifies the app if it needs to block.
3774      */
3775     @VisibleForTesting
3776     @GuardedBy("mService")
incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids)3777     void incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids) {
3778         if (mService.mWaitForNetworkTimeoutMs <= 0) {
3779             return;
3780         }
3781         // Used for identifying which uids need to block for network.
3782         ArrayList<Integer> blockingUids = null;
3783         for (int i = activeUids.size() - 1; i >= 0; --i) {
3784             final UidRecord uidRec = activeUids.valueAt(i);
3785             // If the network is not restricted for uid, then nothing to do here.
3786             if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
3787                 continue;
3788             }
3789             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
3790                 continue;
3791             }
3792             // If process state is not changed, then there's nothing to do.
3793             if (uidRec.setProcState == uidRec.getCurProcState()) {
3794                 continue;
3795             }
3796             final int blockState = getBlockStateForUid(uidRec);
3797             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
3798             // there's nothing the app needs to do in this scenario.
3799             if (blockState == NETWORK_STATE_NO_CHANGE) {
3800                 continue;
3801             }
3802             synchronized (uidRec.networkStateLock) {
3803                 uidRec.curProcStateSeq = ++mProcStateSeqCounter; // TODO: use method
3804                 if (blockState == NETWORK_STATE_BLOCK) {
3805                     if (blockingUids == null) {
3806                         blockingUids = new ArrayList<>();
3807                     }
3808                     blockingUids.add(uidRec.uid);
3809                 } else {
3810                     if (DEBUG_NETWORK) {
3811                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
3812                                 + " threads for uid: " + uidRec);
3813                     }
3814                     if (uidRec.waitingForNetwork) {
3815                         uidRec.networkStateLock.notifyAll();
3816                     }
3817                 }
3818             }
3819         }
3820 
3821         // There are no uids that need to block, so nothing more to do.
3822         if (blockingUids == null) {
3823             return;
3824         }
3825 
3826         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
3827             final ProcessRecord app = mLruProcesses.get(i);
3828             if (!blockingUids.contains(app.uid)) {
3829                 continue;
3830             }
3831             if (!app.killedByAm && app.thread != null) {
3832                 final UidRecord uidRec = getUidRecordLocked(app.uid);
3833                 try {
3834                     if (DEBUG_NETWORK) {
3835                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
3836                                 + uidRec);
3837                     }
3838                     if (uidRec != null) {
3839                         app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
3840                     }
3841                 } catch (RemoteException ignored) {
3842                 }
3843             }
3844         }
3845     }
3846 
3847     /**
3848      * Create a server socket in system_server, zygote will connect to it
3849      * in order to send unsolicited messages to system_server.
3850      */
createSystemServerSocketForZygote()3851     private LocalSocket createSystemServerSocketForZygote() {
3852         // The file system entity for this socket is created with 0666 perms, owned
3853         // by system:system. selinux restricts things so that only zygotes can
3854         // access it.
3855         final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH);
3856         if (socketFile.exists()) {
3857             socketFile.delete();
3858         }
3859 
3860         LocalSocket serverSocket = null;
3861         try {
3862             serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM);
3863             serverSocket.bind(new LocalSocketAddress(
3864                     UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM));
3865             Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666);
3866         } catch (Exception e) {
3867             if (serverSocket != null) {
3868                 try {
3869                     serverSocket.close();
3870                 } catch (IOException ex) {
3871                 }
3872                 serverSocket = null;
3873             }
3874         }
3875         return serverSocket;
3876     }
3877 
3878     /**
3879      * Handle the unsolicited message from zygote.
3880      */
handleZygoteMessages(FileDescriptor fd, int events)3881     private int handleZygoteMessages(FileDescriptor fd, int events) {
3882         final int eventFd = fd.getInt$();
3883         if ((events & EVENT_INPUT) != 0) {
3884             // An incoming message from zygote
3885             try {
3886                 final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0,
3887                         mZygoteUnsolicitedMessage.length);
3888                 if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld(
3889                         mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) {
3890                     mAppExitInfoTracker.handleZygoteSigChld(
3891                             mZygoteSigChldMessage[0] /* pid */,
3892                             mZygoteSigChldMessage[1] /* uid */,
3893                             mZygoteSigChldMessage[2] /* status */);
3894                 }
3895             } catch (Exception e) {
3896                 Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e);
3897             }
3898         }
3899         return EVENT_INPUT;
3900     }
3901 
3902     /**
3903      * Called by ActivityManagerService when a process died.
3904      */
3905     @GuardedBy("mService")
noteProcessDiedLocked(final ProcessRecord app)3906     void noteProcessDiedLocked(final ProcessRecord app) {
3907         if (DEBUG_PROCESSES) {
3908             Slog.i(TAG, "note: " + app + " died, saving the exit info");
3909         }
3910 
3911         Watchdog.getInstance().processDied(app.processName, app.pid);
3912         mAppExitInfoTracker.scheduleNoteProcessDied(app);
3913     }
3914 
3915     /**
3916      * Called by ActivityManagerService when it decides to kill an application process.
3917      */
noteAppKill(final ProcessRecord app, final @Reason int reason, final @SubReason int subReason, final String msg)3918     void noteAppKill(final ProcessRecord app, final @Reason int reason,
3919             final @SubReason int subReason, final String msg) {
3920         if (DEBUG_PROCESSES) {
3921             Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
3922                     + ", sub-reason: " + subReason + ", message: " + msg);
3923         }
3924         mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg);
3925     }
3926 
noteAppKill(final int pid, final int uid, final @Reason int reason, final @SubReason int subReason, final String msg)3927     void noteAppKill(final int pid, final int uid, final @Reason int reason,
3928             final @SubReason int subReason, final String msg) {
3929         if (DEBUG_PROCESSES) {
3930             Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason
3931                     + ", sub-reason: " + subReason + ", message: " + msg);
3932         }
3933 
3934         mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg);
3935     }
3936 
3937     /**
3938      * Schedule to kill the given pids when the device is idle
3939      */
killProcessesWhenImperceptible(int[] pids, String reason, int requester)3940     void killProcessesWhenImperceptible(int[] pids, String reason, int requester) {
3941         if (ArrayUtils.isEmpty(pids)) {
3942             return;
3943         }
3944 
3945         synchronized (mService) {
3946             ProcessRecord app;
3947             for (int i = 0; i < pids.length; i++) {
3948                 synchronized (mService.mPidsSelfLocked) {
3949                     app = mService.mPidsSelfLocked.get(pids[i]);
3950                 }
3951                 if (app != null) {
3952                     mImperceptibleKillRunner.enqueueLocked(app, reason, requester);
3953                 }
3954             }
3955         }
3956     }
3957 
3958     private final class ImperceptibleKillRunner extends IUidObserver.Stub {
3959         private static final String EXTRA_PID = "pid";
3960         private static final String EXTRA_UID = "uid";
3961         private static final String EXTRA_TIMESTAMP = "timestamp";
3962         private static final String EXTRA_REASON = "reason";
3963         private static final String EXTRA_REQUESTER = "requester";
3964 
3965         private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill";
3966 
3967         // uid -> killing information mapping
3968         private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>();
3969 
3970         // The last time the various processes have been killed by us.
3971         private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>();
3972 
3973         // Device idle or not.
3974         private volatile boolean mIdle;
3975         private boolean mUidObserverEnabled;
3976         private Handler mHandler;
3977         private IdlenessReceiver mReceiver;
3978 
3979         private final class H extends Handler {
3980             static final int MSG_DEVICE_IDLE = 0;
3981             static final int MSG_UID_GONE = 1;
3982             static final int MSG_UID_STATE_CHANGED = 2;
3983 
H(Looper looper)3984             H(Looper looper) {
3985                 super(looper);
3986             }
3987 
3988             @Override
handleMessage(Message msg)3989             public void handleMessage(Message msg) {
3990                 switch (msg.what) {
3991                     case MSG_DEVICE_IDLE:
3992                         handleDeviceIdle();
3993                         break;
3994                     case MSG_UID_GONE:
3995                         handleUidGone(msg.arg1 /* uid */);
3996                         break;
3997                     case MSG_UID_STATE_CHANGED:
3998                         handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */);
3999                         break;
4000                 }
4001             }
4002         }
4003 
4004         private final class IdlenessReceiver extends BroadcastReceiver {
4005             @Override
onReceive(Context context, Intent intent)4006             public void onReceive(Context context, Intent intent) {
4007                 final PowerManager pm = mService.mContext.getSystemService(PowerManager.class);
4008                 switch (intent.getAction()) {
4009                     case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
4010                         notifyDeviceIdleness(pm.isLightDeviceIdleMode());
4011                         break;
4012                     case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
4013                         notifyDeviceIdleness(pm.isDeviceIdleMode());
4014                         break;
4015                 }
4016             }
4017         }
4018 
ImperceptibleKillRunner(Looper looper)4019         ImperceptibleKillRunner(Looper looper) {
4020             mHandler = new H(looper);
4021         }
4022 
4023         @GuardedBy("mService")
enqueueLocked(ProcessRecord app, String reason, int requester)4024         boolean enqueueLocked(ProcessRecord app, String reason, int requester) {
4025             // Throttle the killing request for potential bad app to avoid cpu thrashing
4026             Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid);
4027             if (last != null && SystemClock.uptimeMillis() < last + MIN_CRASH_INTERVAL) {
4028                 return false;
4029             }
4030 
4031             final Bundle bundle = new Bundle();
4032             bundle.putInt(EXTRA_PID, app.pid);
4033             bundle.putInt(EXTRA_UID, app.uid);
4034             // Since the pid could be reused, let's get the actual start time of each process
4035             bundle.putLong(EXTRA_TIMESTAMP, app.startTime);
4036             bundle.putString(EXTRA_REASON, reason);
4037             bundle.putInt(EXTRA_REQUESTER, requester);
4038             List<Bundle> list = mWorkItems.get(app.uid);
4039             if (list == null) {
4040                 list = new ArrayList<Bundle>();
4041                 mWorkItems.put(app.uid, list);
4042             }
4043             list.add(bundle);
4044             if (mReceiver == null) {
4045                 mReceiver = new IdlenessReceiver();
4046                 IntentFilter filter = new IntentFilter(
4047                         PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
4048                 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
4049                 mService.mContext.registerReceiver(mReceiver, filter);
4050             }
4051             return true;
4052         }
4053 
notifyDeviceIdleness(boolean idle)4054         void notifyDeviceIdleness(boolean idle) {
4055             // No lock is held regarding mIdle, this function is the only updater and caller
4056             // won't re-entry.
4057             boolean diff = mIdle != idle;
4058             mIdle = idle;
4059             if (diff && idle) {
4060                 synchronized (this) {
4061                     if (mWorkItems.size() > 0) {
4062                         mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE);
4063                     }
4064                 }
4065             }
4066         }
4067 
handleDeviceIdle()4068         private void handleDeviceIdle() {
4069             final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
4070             final boolean logToDropbox = dbox != null
4071                     && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
4072 
4073             synchronized (mService) {
4074                 final int size = mWorkItems.size();
4075                 for (int i = size - 1; mIdle && i >= 0; i--) {
4076                     List<Bundle> list = mWorkItems.valueAt(i);
4077                     final int len = list.size();
4078                     for (int j = len - 1; mIdle && j >= 0; j--) {
4079                         Bundle bundle = list.get(j);
4080                         if (killProcessLocked(
4081                                 bundle.getInt(EXTRA_PID),
4082                                 bundle.getInt(EXTRA_UID),
4083                                 bundle.getLong(EXTRA_TIMESTAMP),
4084                                 bundle.getString(EXTRA_REASON),
4085                                 bundle.getInt(EXTRA_REQUESTER),
4086                                 dbox, logToDropbox)) {
4087                             list.remove(j);
4088                         }
4089                     }
4090                     if (list.size() == 0) {
4091                         mWorkItems.removeAt(i);
4092                     }
4093                 }
4094                 registerUidObserverIfNecessaryLocked();
4095             }
4096         }
4097 
4098         @GuardedBy("mService")
registerUidObserverIfNecessaryLocked()4099         private void registerUidObserverIfNecessaryLocked() {
4100             // If there are still works remaining, register UID observer
4101             if (!mUidObserverEnabled && mWorkItems.size() > 0) {
4102                 mUidObserverEnabled = true;
4103                 mService.registerUidObserver(this,
4104                         ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
4105                         ActivityManager.PROCESS_STATE_UNKNOWN, "android");
4106             } else if (mUidObserverEnabled && mWorkItems.size() == 0) {
4107                 mUidObserverEnabled = false;
4108                 mService.unregisterUidObserver(this);
4109             }
4110         }
4111 
4112         /**
4113          * Kill the given processes, if they are not exempted.
4114          *
4115          * @return True if the process is killed, or it's gone already, or we are not allowed to
4116          *         kill it (one of the packages in this process is being exempted).
4117          */
4118         @GuardedBy("mService")
killProcessLocked(final int pid, final int uid, final long timestamp, final String reason, final int requester, final DropBoxManager dbox, final boolean logToDropbox)4119         private boolean killProcessLocked(final int pid, final int uid, final long timestamp,
4120                 final String reason, final int requester, final DropBoxManager dbox,
4121                 final boolean logToDropbox) {
4122             ProcessRecord app = null;
4123             synchronized (mService.mPidsSelfLocked) {
4124                 app = mService.mPidsSelfLocked.get(pid);
4125             }
4126 
4127             if (app == null || app.pid != pid || app.uid != uid || app.startTime != timestamp) {
4128                 // This process record has been reused for another process, meaning the old process
4129                 // has been gone.
4130                 return true;
4131             }
4132 
4133             final int pkgSize = app.pkgList.size();
4134             for (int ip = 0; ip < pkgSize; ip++) {
4135                 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(
4136                         app.pkgList.keyAt(ip))) {
4137                     // One of the packages in this process is exempted
4138                     return true;
4139                 }
4140             }
4141 
4142             if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(
4143                     app.getReportedProcState())) {
4144                 // We need to reschedule it.
4145                 return false;
4146             }
4147 
4148             app.kill(reason, ApplicationExitInfo.REASON_OTHER,
4149                     ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true);
4150 
4151             if (!app.isolated) {
4152                 mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());
4153             }
4154 
4155             if (logToDropbox) {
4156                 final long now = SystemClock.elapsedRealtime();
4157                 final StringBuilder sb = new StringBuilder();
4158                 mService.appendDropBoxProcessHeaders(app, app.processName, sb);
4159                 sb.append("Reason: " + reason).append("\n");
4160                 sb.append("Requester UID: " + requester).append("\n");
4161                 dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString());
4162             }
4163             return true;
4164         }
4165 
handleUidStateChanged(int uid, int procState)4166         private void handleUidStateChanged(int uid, int procState) {
4167             final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
4168             final boolean logToDropbox = dbox != null
4169                     && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
4170             synchronized (mService) {
4171                 if (mIdle && !mService.mConstants
4172                         .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) {
4173                     List<Bundle> list = mWorkItems.get(uid);
4174                     if (list != null) {
4175                         final int len = list.size();
4176                         for (int j = len - 1; mIdle && j >= 0; j--) {
4177                             Bundle bundle = list.get(j);
4178                             if (killProcessLocked(
4179                                     bundle.getInt(EXTRA_PID),
4180                                     bundle.getInt(EXTRA_UID),
4181                                     bundle.getLong(EXTRA_TIMESTAMP),
4182                                     bundle.getString(EXTRA_REASON),
4183                                     bundle.getInt(EXTRA_REQUESTER),
4184                                     dbox, logToDropbox)) {
4185                                 list.remove(j);
4186                             }
4187                         }
4188                         if (list.size() == 0) {
4189                             mWorkItems.remove(uid);
4190                         }
4191                         registerUidObserverIfNecessaryLocked();
4192                     }
4193                 }
4194             }
4195         }
4196 
handleUidGone(int uid)4197         private void handleUidGone(int uid) {
4198             synchronized (mService) {
4199                 mWorkItems.remove(uid);
4200                 registerUidObserverIfNecessaryLocked();
4201             }
4202         }
4203 
4204         @Override
onUidGone(int uid, boolean disabled)4205         public void onUidGone(int uid, boolean disabled) {
4206             mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget();
4207         }
4208 
4209         @Override
onUidActive(int uid)4210         public void onUidActive(int uid) {
4211         }
4212 
4213         @Override
onUidIdle(int uid, boolean disabled)4214         public void onUidIdle(int uid, boolean disabled) {
4215         }
4216 
4217         @Override
onUidStateChanged(int uid, int procState, long procStateSeq, int capability)4218         public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
4219             mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
4220         }
4221 
4222         @Override
onUidCachedChanged(int uid, boolean cached)4223         public void onUidCachedChanged(int uid, boolean cached) {
4224         }
4225     };
4226 }
4227