• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.am;
18 
19 import static android.app.ActivityManager.PROCESS_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.isBadProcess(info.processName, info.uid)) {
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.isBadProcess(info.processName, info.uid)) {
2353                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2354                             UserHandle.getUserId(info.uid), info.uid,
2355                             info.processName);
2356                     mService.mAppErrors.clearBadProcess(info.processName, info.uid);
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         final ProcessRecord record = expecting != null ? expecting : old;
2912         if (record != null && record.uidRecord != null) {
2913             final UidRecord uidRecord = record.uidRecord;
2914             uidRecord.numProcs--;
2915             uidRecord.procRecords.remove(record);
2916             if (uidRecord.numProcs == 0) {
2917                 // No more processes using this uid, tell clients it is gone.
2918                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2919                         "No more processes in " + uidRecord);
2920                 mService.enqueueUidChangeLocked(uidRecord, -1, UidRecord.CHANGE_GONE);
2921                 EventLogTags.writeAmUidStopped(uid);
2922                 mActiveUids.remove(uid);
2923                 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
2924                         ActivityManager.PROCESS_CAPABILITY_NONE);
2925             }
2926             record.uidRecord = null;
2927         }
2928         mIsolatedProcesses.remove(uid);
2929         mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
2930         // Remove the (expected) ProcessRecord from the app zygote
2931         if (record != null && record.appZygote) {
2932             removeProcessFromAppZygoteLocked(record);
2933         }
2934 
2935         return old;
2936     }
2937 
2938     /** Call setCoreSettings on all LRU processes, with the new settings. */
2939     @GuardedBy("mService")
updateCoreSettingsLocked(Bundle settings)2940     void updateCoreSettingsLocked(Bundle settings) {
2941         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2942             ProcessRecord processRecord = mLruProcesses.get(i);
2943             try {
2944                 if (processRecord.thread != null) {
2945                     processRecord.thread.setCoreSettings(settings);
2946                 }
2947             } catch (RemoteException re) {
2948                 /* ignore */
2949             }
2950         }
2951     }
2952 
2953     /**
2954      * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2955      * procstate lower than maxProcState.
2956      * @param minTargetSdk
2957      * @param maxProcState
2958      */
2959     @GuardedBy("mService")
killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState)2960     void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2961         final ArrayList<ProcessRecord> procs = new ArrayList<>();
2962         final int NP = mProcessNames.getMap().size();
2963         for (int ip = 0; ip < NP; ip++) {
2964             final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2965             final int NA = apps.size();
2966             for (int ia = 0; ia < NA; ia++) {
2967                 final ProcessRecord app = apps.valueAt(ia);
2968                 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2969                         && (maxProcState < 0 || app.setProcState > maxProcState))) {
2970                     procs.add(app);
2971                 }
2972             }
2973         }
2974 
2975         final int N = procs.size();
2976         for (int i = 0; i < N; i++) {
2977             removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER,
2978                     ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except");
2979         }
2980     }
2981 
2982     /**
2983      * Call updateTimePrefs on all LRU processes
2984      * @param timePref The time pref to pass to each process
2985      */
2986     @GuardedBy("mService")
updateAllTimePrefsLocked(int timePref)2987     void updateAllTimePrefsLocked(int timePref) {
2988         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2989             ProcessRecord r = mLruProcesses.get(i);
2990             if (r.thread != null) {
2991                 try {
2992                     r.thread.updateTimePrefs(timePref);
2993                 } catch (RemoteException ex) {
2994                     Slog.w(TAG, "Failed to update preferences for: "
2995                             + r.info.processName);
2996                 }
2997             }
2998         }
2999     }
3000 
setAllHttpProxy()3001     void setAllHttpProxy() {
3002         // Update the HTTP proxy for each application thread.
3003         synchronized (mService) {
3004             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
3005                 ProcessRecord r = mLruProcesses.get(i);
3006                 // Don't dispatch to isolated processes as they can't access ConnectivityManager and
3007                 // don't have network privileges anyway. Exclude system server and update it
3008                 // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
3009                 if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) {
3010                     try {
3011                         r.thread.updateHttpProxy();
3012                     } catch (RemoteException ex) {
3013                         Slog.w(TAG, "Failed to update http proxy for: "
3014                                 + r.info.processName);
3015                     }
3016                 }
3017             }
3018         }
3019         ActivityThread.updateHttpProxy(mService.mContext);
3020     }
3021 
3022     @GuardedBy("mService")
clearAllDnsCacheLocked()3023     void clearAllDnsCacheLocked() {
3024         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3025             ProcessRecord r = mLruProcesses.get(i);
3026             if (r.thread != null) {
3027                 try {
3028                     r.thread.clearDnsCache();
3029                 } catch (RemoteException ex) {
3030                     Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
3031                 }
3032             }
3033         }
3034     }
3035 
3036     @GuardedBy("mService")
handleAllTrustStorageUpdateLocked()3037     void handleAllTrustStorageUpdateLocked() {
3038         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3039             ProcessRecord r = mLruProcesses.get(i);
3040             if (r.thread != null) {
3041                 try {
3042                     r.thread.handleTrustStorageUpdate();
3043                 } catch (RemoteException ex) {
3044                     Slog.w(TAG, "Failed to handle trust storage update for: " +
3045                             r.info.processName);
3046                 }
3047             }
3048         }
3049     }
3050 
3051     @GuardedBy("mService")
updateLruProcessInternalLocked(ProcessRecord app, long now, int index, int lruSeq, String what, Object obj, ProcessRecord srcApp)3052     int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3053             int lruSeq, String what, Object obj, ProcessRecord srcApp) {
3054         app.lastActivityTime = now;
3055 
3056         if (app.hasActivitiesOrRecentTasks()) {
3057             // Don't want to touch dependent processes that are hosting activities.
3058             return index;
3059         }
3060 
3061         int lrui = mLruProcesses.lastIndexOf(app);
3062         if (lrui < 0) {
3063             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3064                     + what + " " + obj + " from " + srcApp);
3065             return index;
3066         }
3067 
3068         if (lrui >= index) {
3069             // Don't want to cause this to move dependent processes *back* in the
3070             // list as if they were less frequently used.
3071             return index;
3072         }
3073 
3074         if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
3075             // Don't want to touch dependent processes that are hosting activities.
3076             return index;
3077         }
3078 
3079         mLruProcesses.remove(lrui);
3080         if (index > 0) {
3081             index--;
3082         }
3083         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3084                 + " in LRU list: " + app);
3085         mLruProcesses.add(index, app);
3086         app.lruSeq = lruSeq;
3087         return index;
3088     }
3089 
3090     /**
3091      * Handle the case where we are inserting a process hosting client activities:
3092      * Make sure any groups have their order match their importance, and take care of
3093      * distributing old clients across other activity processes so they can't spam
3094      * the LRU list.  Processing of the list will be restricted by the indices provided,
3095      * and not extend out of them.
3096      *
3097      * @param topApp The app at the top that has just been inserted in to the list.
3098      * @param topI The position in the list where topApp was inserted; this is the start (at the
3099      *             top) where we are going to do our processing.
3100      * @param bottomI The last position at which we will be processing; this is the end position
3101      *                of whichever section of the LRU list we are in.  Nothing past it will be
3102      *                touched.
3103      * @param endIndex The current end of the top being processed.  Typically topI - 1.  That is,
3104      *                 where we are going to start potentially adjusting other entries in the list.
3105      */
updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI, final int bottomI, int endIndex)3106     private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
3107             final int bottomI, int endIndex) {
3108         if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
3109                 || !topApp.hasClientActivities()) {
3110             // If this is not a special process that has client activities, then there is
3111             // nothing to do.
3112             return;
3113         }
3114 
3115         final int uid = topApp.info.uid;
3116         if (topApp.connectionGroup > 0) {
3117             int endImportance = topApp.connectionImportance;
3118             for (int i = endIndex; i >= bottomI; i--) {
3119                 final ProcessRecord subProc = mLruProcesses.get(i);
3120                 if (subProc.info.uid == uid
3121                         && subProc.connectionGroup == topApp.connectionGroup) {
3122                     if (i == endIndex && subProc.connectionImportance >= endImportance) {
3123                         // This process is already in the group, and its importance
3124                         // is not as strong as the process before it, so keep it
3125                         // correctly positioned in the group.
3126                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3127                                 "Keeping in-place above " + subProc
3128                                         + " endImportance=" + endImportance
3129                                         + " group=" + subProc.connectionGroup
3130                                         + " importance=" + subProc.connectionImportance);
3131                         endIndex--;
3132                         endImportance = subProc.connectionImportance;
3133                     } else {
3134                         // We want to pull this up to be with the rest of the group,
3135                         // and order within the group by importance.
3136                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3137                                 "Pulling up " + subProc
3138                                         + " to position in group with importance="
3139                                         + subProc.connectionImportance);
3140                         boolean moved = false;
3141                         for (int pos = topI; pos > endIndex; pos--) {
3142                             final ProcessRecord posProc = mLruProcesses.get(pos);
3143                             if (subProc.connectionImportance
3144                                     <= posProc.connectionImportance) {
3145                                 mLruProcesses.remove(i);
3146                                 mLruProcesses.add(pos, subProc);
3147                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3148                                         "Moving " + subProc
3149                                                 + " from position " + i + " to above " + posProc
3150                                                 + " @ " + pos);
3151                                 moved = true;
3152                                 endIndex--;
3153                                 break;
3154                             }
3155                         }
3156                         if (!moved) {
3157                             // Goes to the end of the group.
3158                             mLruProcesses.remove(i);
3159                             mLruProcesses.add(endIndex, subProc);
3160                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3161                                     "Moving " + subProc
3162                                             + " from position " + i + " to end of group @ "
3163                                             + endIndex);
3164                             endIndex--;
3165                             endImportance = subProc.connectionImportance;
3166                         }
3167                     }
3168                 }
3169             }
3170 
3171         }
3172         // To keep it from spamming the LRU list (by making a bunch of clients),
3173         // we will distribute other entries owned by it to be in-between other apps.
3174         int i = endIndex;
3175         while (i >= bottomI) {
3176             ProcessRecord subProc = mLruProcesses.get(i);
3177             if (DEBUG_LRU) Slog.d(TAG_LRU,
3178                     "Looking to spread old procs, at " + subProc + " @ " + i);
3179             if (subProc.info.uid != uid) {
3180                 // This is a different app...  if we have gone through some of the
3181                 // target app, pull this up to be before them.  We want to pull up
3182                 // one activity process, but any number of non-activity processes.
3183                 if (i < endIndex) {
3184                     boolean hasActivity = false;
3185                     int connUid = 0;
3186                     int connGroup = 0;
3187                     while (i >= bottomI) {
3188                         mLruProcesses.remove(i);
3189                         mLruProcesses.add(endIndex, subProc);
3190                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3191                                 "Different app, moving to " + endIndex);
3192                         i--;
3193                         if (i < bottomI) {
3194                             break;
3195                         }
3196                         subProc = mLruProcesses.get(i);
3197                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3198                                 "Looking at next app at " + i + ": " + subProc);
3199                         if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
3200                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3201                                     "This is hosting an activity!");
3202                             if (hasActivity) {
3203                                 // Already found an activity, done.
3204                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3205                                         "Already found an activity, done");
3206                                 break;
3207                             }
3208                             hasActivity = true;
3209                         } else if (subProc.hasClientActivities()) {
3210                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3211                                     "This is a client of an activity");
3212                             if (hasActivity) {
3213                                 if (connUid == 0 || connUid != subProc.info.uid) {
3214                                     // Already have an activity that is not from from a client
3215                                     // connection or is a different client connection, done.
3216                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
3217                                             "Already found a different activity: connUid="
3218                                             + connUid + " uid=" + subProc.info.uid);
3219                                     break;
3220                                 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
3221                                     // Previously saw a different group or not from a group,
3222                                     // want to treat these as different things.
3223                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
3224                                             "Already found a different group: connGroup="
3225                                             + connGroup + " group=" + subProc.connectionGroup);
3226                                     break;
3227                                 }
3228                             } else {
3229                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3230                                         "This is an activity client!  uid="
3231                                         + subProc.info.uid + " group=" + subProc.connectionGroup);
3232                                 hasActivity = true;
3233                                 connUid = subProc.info.uid;
3234                                 connGroup = subProc.connectionGroup;
3235                             }
3236                         }
3237                         endIndex--;
3238                     }
3239                 }
3240                 // Find the end of the next group of processes for target app.  This
3241                 // is after any entries of different apps (so we don't change the existing
3242                 // relative order of apps) and then after the next last group of processes
3243                 // of the target app.
3244                 for (endIndex--; endIndex >= bottomI; endIndex--) {
3245                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
3246                     if (endProc.info.uid == uid) {
3247                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3248                                 "Found next group of app: " + endProc + " @ "
3249                                         + endIndex);
3250                         break;
3251                     }
3252                 }
3253                 if (endIndex >= bottomI) {
3254                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
3255                     for (endIndex--; endIndex >= bottomI; endIndex--) {
3256                         final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
3257                         if (nextEndProc.info.uid != uid
3258                                 || nextEndProc.connectionGroup != endProc.connectionGroup) {
3259                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3260                                     "Found next group or app: " + nextEndProc + " @ "
3261                                             + endIndex + " group=" + nextEndProc.connectionGroup);
3262                             break;
3263                         }
3264                     }
3265                 }
3266                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3267                         "Bumping scan position to " + endIndex);
3268                 i = endIndex;
3269             } else {
3270                 i--;
3271             }
3272         }
3273     }
3274 
updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client)3275     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3276             ProcessRecord client) {
3277         final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
3278                 || app.treatLikeActivity;
3279         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3280         if (!activityChange && hasActivity) {
3281             // The process has activities, so we are only allowing activity-based adjustments
3282             // to move it.  It should be kept in the front of the list with other
3283             // processes that have activities, and we don't want those to change their
3284             // order except due to activity operations.
3285             return;
3286         }
3287 
3288         mLruSeq++;
3289         final long now = SystemClock.uptimeMillis();
3290         app.lastActivityTime = now;
3291 
3292         // First a quick reject: if the app is already at the position we will
3293         // put it, then there is nothing to do.
3294         if (hasActivity) {
3295             final int N = mLruProcesses.size();
3296             if (N > 0 && mLruProcesses.get(N - 1) == app) {
3297                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3298                 return;
3299             }
3300         } else {
3301             if (mLruProcessServiceStart > 0
3302                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3303                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3304                 return;
3305             }
3306         }
3307 
3308         int lrui = mLruProcesses.lastIndexOf(app);
3309 
3310         if (app.isPersistent() && lrui >= 0) {
3311             // We don't care about the position of persistent processes, as long as
3312             // they are in the list.
3313             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3314             return;
3315         }
3316 
3317         /* In progress: compute new position first, so we can avoid doing work
3318            if the process is not actually going to move.  Not yet working.
3319         int addIndex;
3320         int nextIndex;
3321         boolean inActivity = false, inService = false;
3322         if (hasActivity) {
3323             // Process has activities, put it at the very tipsy-top.
3324             addIndex = mLruProcesses.size();
3325             nextIndex = mLruProcessServiceStart;
3326             inActivity = true;
3327         } else if (hasService) {
3328             // Process has services, put it at the top of the service list.
3329             addIndex = mLruProcessActivityStart;
3330             nextIndex = mLruProcessServiceStart;
3331             inActivity = true;
3332             inService = true;
3333         } else  {
3334             // Process not otherwise of interest, it goes to the top of the non-service area.
3335             addIndex = mLruProcessServiceStart;
3336             if (client != null) {
3337                 int clientIndex = mLruProcesses.lastIndexOf(client);
3338                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3339                         + app);
3340                 if (clientIndex >= 0 && addIndex > clientIndex) {
3341                     addIndex = clientIndex;
3342                 }
3343             }
3344             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3345         }
3346 
3347         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3348                 + mLruProcessActivityStart + "): " + app);
3349         */
3350 
3351         if (lrui >= 0) {
3352             if (lrui < mLruProcessActivityStart) {
3353                 mLruProcessActivityStart--;
3354             }
3355             if (lrui < mLruProcessServiceStart) {
3356                 mLruProcessServiceStart--;
3357             }
3358             /*
3359             if (addIndex > lrui) {
3360                 addIndex--;
3361             }
3362             if (nextIndex > lrui) {
3363                 nextIndex--;
3364             }
3365             */
3366             mLruProcesses.remove(lrui);
3367         }
3368 
3369         /*
3370         mLruProcesses.add(addIndex, app);
3371         if (inActivity) {
3372             mLruProcessActivityStart++;
3373         }
3374         if (inService) {
3375             mLruProcessActivityStart++;
3376         }
3377         */
3378 
3379         int nextIndex;
3380         int nextActivityIndex = -1;
3381         if (hasActivity) {
3382             final int N = mLruProcesses.size();
3383             nextIndex = mLruProcessServiceStart;
3384             if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
3385                     && mLruProcessActivityStart < (N - 1)) {
3386                 // Process doesn't have activities, but has clients with
3387                 // activities...  move it up, but below the app that is binding to it.
3388                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3389                         "Adding to second-top of LRU activity list: " + app
3390                         + " group=" + app.connectionGroup
3391                         + " importance=" + app.connectionImportance);
3392                 int pos = N - 1;
3393                 while (pos > mLruProcessActivityStart) {
3394                     final ProcessRecord posproc = mLruProcesses.get(pos);
3395                     if (posproc.info.uid == app.info.uid) {
3396                         // Technically this app could have multiple processes with different
3397                         // activities and so we should be looking for the actual process that
3398                         // is bound to the target proc...  but I don't really care, do you?
3399                         break;
3400                     }
3401                     pos--;
3402                 }
3403                 mLruProcesses.add(pos, app);
3404                 // If this process is part of a group, need to pull up any other processes
3405                 // in that group to be with it.
3406                 int endIndex = pos - 1;
3407                 if (endIndex < mLruProcessActivityStart) {
3408                     endIndex = mLruProcessActivityStart;
3409                 }
3410                 nextActivityIndex = endIndex;
3411                 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
3412             } else {
3413                 // Process has activities, put it at the very tipsy-top.
3414                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3415                 mLruProcesses.add(app);
3416                 nextActivityIndex = mLruProcesses.size() - 1;
3417             }
3418         } else if (hasService) {
3419             // Process has services, put it at the top of the service list.
3420             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3421             mLruProcesses.add(mLruProcessActivityStart, app);
3422             nextIndex = mLruProcessServiceStart;
3423             mLruProcessActivityStart++;
3424         } else  {
3425             // Process not otherwise of interest, it goes to the top of the non-service area.
3426             int index = mLruProcessServiceStart;
3427             if (client != null) {
3428                 // If there is a client, don't allow the process to be moved up higher
3429                 // in the list than that client.
3430                 int clientIndex = mLruProcesses.lastIndexOf(client);
3431                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3432                         + " when updating " + app);
3433                 if (clientIndex <= lrui) {
3434                     // Don't allow the client index restriction to push it down farther in the
3435                     // list than it already is.
3436                     clientIndex = lrui;
3437                 }
3438                 if (clientIndex >= 0 && index > clientIndex) {
3439                     index = clientIndex;
3440                 }
3441             }
3442             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3443             mLruProcesses.add(index, app);
3444             nextIndex = index - 1;
3445             mLruProcessActivityStart++;
3446             mLruProcessServiceStart++;
3447             if (index > 1) {
3448                 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
3449             }
3450         }
3451 
3452         app.lruSeq = mLruSeq;
3453 
3454         // If the app is currently using a content provider or service,
3455         // bump those processes as well.
3456         for (int j = app.connections.size() - 1; j >= 0; j--) {
3457             ConnectionRecord cr = app.connections.valueAt(j);
3458             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3459                     && cr.binding.service.app != null
3460                     && cr.binding.service.app.lruSeq != mLruSeq
3461                     && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
3462                     && !cr.binding.service.app.isPersistent()) {
3463                 if (cr.binding.service.app.hasClientActivities()) {
3464                     if (nextActivityIndex >= 0) {
3465                         nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
3466                                 now,
3467                                 nextActivityIndex, mLruSeq,
3468                                 "service connection", cr, app);
3469                     }
3470                 } else {
3471                     nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
3472                             now,
3473                             nextIndex, mLruSeq,
3474                             "service connection", cr, app);
3475                 }
3476             }
3477         }
3478         for (int j = app.conProviders.size() - 1; j >= 0; j--) {
3479             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3480             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
3481                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
3482                         "provider reference", cpr, app);
3483             }
3484         }
3485     }
3486 
getLRURecordForAppLocked(IApplicationThread thread)3487     final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
3488         if (thread == null) {
3489             return null;
3490         }
3491         final IBinder threadBinder = thread.asBinder();
3492         // Find the application record.
3493         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3494             final ProcessRecord rec = mLruProcesses.get(i);
3495             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3496                 return rec;
3497             }
3498         }
3499         return null;
3500     }
3501 
haveBackgroundProcessLocked()3502     boolean haveBackgroundProcessLocked() {
3503         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3504             final ProcessRecord rec = mLruProcesses.get(i);
3505             if (rec.thread != null
3506                     && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
3507                 return true;
3508             }
3509         }
3510         return false;
3511     }
3512 
procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp, int clientTargetSdk)3513     private static int procStateToImportance(int procState, int memAdj,
3514             ActivityManager.RunningAppProcessInfo currApp,
3515             int clientTargetSdk) {
3516         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
3517                 procState, clientTargetSdk);
3518         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
3519             currApp.lru = memAdj;
3520         } else {
3521             currApp.lru = 0;
3522         }
3523         return imp;
3524     }
3525 
3526     @GuardedBy("mService")
fillInProcMemInfoLocked(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, int clientTargetSdk)3527     void fillInProcMemInfoLocked(ProcessRecord app,
3528             ActivityManager.RunningAppProcessInfo outInfo,
3529             int clientTargetSdk) {
3530         outInfo.pid = app.pid;
3531         outInfo.uid = app.info.uid;
3532         if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
3533             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
3534         }
3535         if (app.isPersistent()) {
3536             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
3537         }
3538         if (app.hasActivities()) {
3539             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
3540         }
3541         outInfo.lastTrimLevel = app.trimMemoryLevel;
3542         int adj = app.curAdj;
3543         int procState = app.getCurProcState();
3544         outInfo.importance = procStateToImportance(procState, adj, outInfo,
3545                 clientTargetSdk);
3546         outInfo.importanceReasonCode = app.adjTypeCode;
3547         outInfo.processState = app.getCurProcState();
3548         outInfo.isFocused = (app == mService.getTopAppLocked());
3549         outInfo.lastActivityTime = app.lastActivityTime;
3550     }
3551 
3552     @GuardedBy("mService")
getRunningAppProcessesLocked(boolean allUsers, int userId, boolean allUids, int callingUid, int clientTargetSdk)3553     List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
3554             int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3555         // Lazy instantiation of list
3556         List<ActivityManager.RunningAppProcessInfo> runList = null;
3557 
3558         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3559             ProcessRecord app = mLruProcesses.get(i);
3560             if ((!allUsers && app.userId != userId)
3561                     || (!allUids && app.uid != callingUid)) {
3562                 continue;
3563             }
3564             if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
3565                 // Generate process state info for running application
3566                 ActivityManager.RunningAppProcessInfo currApp =
3567                         new ActivityManager.RunningAppProcessInfo(app.processName,
3568                                 app.pid, app.getPackageList());
3569                 fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
3570                 if (app.adjSource instanceof ProcessRecord) {
3571                     currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
3572                     currApp.importanceReasonImportance =
3573                             ActivityManager.RunningAppProcessInfo.procStateToImportance(
3574                                     app.adjSourceProcState);
3575                 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
3576                     final ActivityServiceConnectionsHolder r =
3577                             (ActivityServiceConnectionsHolder) app.adjSource;
3578                     final int pid = r.getActivityPid();
3579                     if (pid != -1) {
3580                         currApp.importanceReasonPid = pid;
3581                     }
3582                 }
3583                 if (app.adjTarget instanceof ComponentName) {
3584                     currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
3585                 }
3586                 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
3587                 //        + " lru=" + currApp.lru);
3588                 if (runList == null) {
3589                     runList = new ArrayList<>();
3590                 }
3591                 runList.add(currApp);
3592             }
3593         }
3594         return runList;
3595     }
3596 
3597     @GuardedBy("mService")
getLruSizeLocked()3598     int getLruSizeLocked() {
3599         return mLruProcesses.size();
3600     }
3601 
3602     @GuardedBy("mService")
dumpLruListHeaderLocked(PrintWriter pw)3603     void dumpLruListHeaderLocked(PrintWriter pw) {
3604         pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
3605         pw.print(" total, non-act at ");
3606         pw.print(mLruProcesses.size() - mLruProcessActivityStart);
3607         pw.print(", non-svc at ");
3608         pw.print(mLruProcesses.size() - mLruProcessServiceStart);
3609         pw.println("):");
3610     }
3611 
3612     @GuardedBy("mService")
collectProcessesLocked(int start, boolean allPkgs, String[] args)3613     ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
3614         ArrayList<ProcessRecord> procs;
3615         if (args != null && args.length > start
3616                 && args[start].charAt(0) != '-') {
3617             procs = new ArrayList<ProcessRecord>();
3618             int pid = -1;
3619             try {
3620                 pid = Integer.parseInt(args[start]);
3621             } catch (NumberFormatException e) {
3622             }
3623             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3624                 ProcessRecord proc = mLruProcesses.get(i);
3625                 if (proc.pid > 0 && proc.pid == pid) {
3626                     procs.add(proc);
3627                 } else if (allPkgs && proc.pkgList != null
3628                         && proc.pkgList.containsKey(args[start])) {
3629                     procs.add(proc);
3630                 } else if (proc.processName.equals(args[start])) {
3631                     procs.add(proc);
3632                 }
3633             }
3634             if (procs.size() <= 0) {
3635                 return null;
3636             }
3637         } else {
3638             procs = new ArrayList<ProcessRecord>(mLruProcesses);
3639         }
3640         return procs;
3641     }
3642 
3643     @GuardedBy("mService")
updateApplicationInfoLocked(List<String> packagesToUpdate, int userId, boolean updateFrameworkRes)3644     void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3645             boolean updateFrameworkRes) {
3646         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3647             final ProcessRecord app = mLruProcesses.get(i);
3648             if (app.thread == null) {
3649                 continue;
3650             }
3651 
3652             if (userId != UserHandle.USER_ALL && app.userId != userId) {
3653                 continue;
3654             }
3655 
3656             final int packageCount = app.pkgList.size();
3657             for (int j = 0; j < packageCount; j++) {
3658                 final String packageName = app.pkgList.keyAt(j);
3659                 if (!updateFrameworkRes && !packagesToUpdate.contains(packageName)) {
3660                     continue;
3661                 }
3662                 try {
3663                     final ApplicationInfo ai = AppGlobals.getPackageManager()
3664                             .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3665                     if (ai == null) {
3666                         continue;
3667                     }
3668                     app.thread.scheduleApplicationInfoChanged(ai);
3669                     if (ai.packageName.equals(app.info.packageName)) {
3670                         app.info = ai;
3671                     }
3672                 } catch (RemoteException e) {
3673                     Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3674                             packageName, app));
3675                 }
3676             }
3677         }
3678     }
3679 
3680     @GuardedBy("mService")
sendPackageBroadcastLocked(int cmd, String[] packages, int userId)3681     void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
3682         boolean foundProcess = false;
3683         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3684             ProcessRecord r = mLruProcesses.get(i);
3685             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3686                 try {
3687                     for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
3688                         if (packages[index].equals(r.info.packageName)) {
3689                             foundProcess = true;
3690                         }
3691                     }
3692                     r.thread.dispatchPackageBroadcast(cmd, packages);
3693                 } catch (RemoteException ex) {
3694                 }
3695             }
3696         }
3697 
3698         if (!foundProcess) {
3699             try {
3700                 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
3701             } catch (RemoteException ignored) {
3702             }
3703         }
3704     }
3705 
3706     /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3707     @GuardedBy("mService")
getUidProcStateLocked(int uid)3708     int getUidProcStateLocked(int uid) {
3709         UidRecord uidRec = mActiveUids.get(uid);
3710         return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3711     }
3712 
3713     /** Returns the UidRecord for the given uid, if it exists. */
3714     @GuardedBy("mService")
getUidRecordLocked(int uid)3715     UidRecord getUidRecordLocked(int uid) {
3716         return mActiveUids.get(uid);
3717     }
3718 
3719     /**
3720      * Call {@link ActivityManagerService#doStopUidLocked}
3721      * (which will also stop background services) for all idle UIDs.
3722      */
3723     @GuardedBy("mService")
doStopUidForIdleUidsLocked()3724     void doStopUidForIdleUidsLocked() {
3725         final int size = mActiveUids.size();
3726         for (int i = 0; i < size; i++) {
3727             final int uid = mActiveUids.keyAt(i);
3728             if (UserHandle.isCore(uid)) {
3729                 continue;
3730             }
3731             final UidRecord uidRec = mActiveUids.valueAt(i);
3732             if (!uidRec.idle) {
3733                 continue;
3734             }
3735             mService.doStopUidLocked(uidRec.uid, uidRec);
3736         }
3737     }
3738 
3739     /**
3740      * Checks if the uid is coming from background to foreground or vice versa and returns
3741      * appropriate block state based on this.
3742      *
3743      * @return blockState based on whether the uid is coming from background to foreground or
3744      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
3745      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
3746      *         {@link #NETWORK_STATE_NO_CHANGE}.
3747      */
3748     @VisibleForTesting
getBlockStateForUid(UidRecord uidRec)3749     int getBlockStateForUid(UidRecord uidRec) {
3750         // Denotes whether uid's process state is currently allowed network access.
3751         final boolean isAllowed =
3752                 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState())
3753                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState());
3754         // Denotes whether uid's process state was previously allowed network access.
3755         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
3756                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
3757 
3758         // When the uid is coming to foreground, AMS should inform the app thread that it should
3759         // block for the network rules to get updated before launching an activity.
3760         if (!wasAllowed && isAllowed) {
3761             return NETWORK_STATE_BLOCK;
3762         }
3763         // When the uid is going to background, AMS should inform the app thread that if an
3764         // activity launch is blocked for the network rules to get updated, it should be unblocked.
3765         if (wasAllowed && !isAllowed) {
3766             return NETWORK_STATE_UNBLOCK;
3767         }
3768         return NETWORK_STATE_NO_CHANGE;
3769     }
3770 
3771     /**
3772      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
3773      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
3774      * {@link ProcessList#mProcStateSeqCounter} and notifies the app if it needs to block.
3775      */
3776     @VisibleForTesting
3777     @GuardedBy("mService")
incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids)3778     void incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids) {
3779         if (mService.mWaitForNetworkTimeoutMs <= 0) {
3780             return;
3781         }
3782         // Used for identifying which uids need to block for network.
3783         ArrayList<Integer> blockingUids = null;
3784         for (int i = activeUids.size() - 1; i >= 0; --i) {
3785             final UidRecord uidRec = activeUids.valueAt(i);
3786             // If the network is not restricted for uid, then nothing to do here.
3787             if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
3788                 continue;
3789             }
3790             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
3791                 continue;
3792             }
3793             // If process state is not changed, then there's nothing to do.
3794             if (uidRec.setProcState == uidRec.getCurProcState()) {
3795                 continue;
3796             }
3797             final int blockState = getBlockStateForUid(uidRec);
3798             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
3799             // there's nothing the app needs to do in this scenario.
3800             if (blockState == NETWORK_STATE_NO_CHANGE) {
3801                 continue;
3802             }
3803             synchronized (uidRec.networkStateLock) {
3804                 uidRec.curProcStateSeq = ++mProcStateSeqCounter; // TODO: use method
3805                 if (blockState == NETWORK_STATE_BLOCK) {
3806                     if (blockingUids == null) {
3807                         blockingUids = new ArrayList<>();
3808                     }
3809                     blockingUids.add(uidRec.uid);
3810                 } else {
3811                     if (DEBUG_NETWORK) {
3812                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
3813                                 + " threads for uid: " + uidRec);
3814                     }
3815                     if (uidRec.waitingForNetwork) {
3816                         uidRec.networkStateLock.notifyAll();
3817                     }
3818                 }
3819             }
3820         }
3821 
3822         // There are no uids that need to block, so nothing more to do.
3823         if (blockingUids == null) {
3824             return;
3825         }
3826 
3827         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
3828             final ProcessRecord app = mLruProcesses.get(i);
3829             if (!blockingUids.contains(app.uid)) {
3830                 continue;
3831             }
3832             if (!app.killedByAm && app.thread != null) {
3833                 final UidRecord uidRec = getUidRecordLocked(app.uid);
3834                 try {
3835                     if (DEBUG_NETWORK) {
3836                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
3837                                 + uidRec);
3838                     }
3839                     if (uidRec != null) {
3840                         app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
3841                     }
3842                 } catch (RemoteException ignored) {
3843                 }
3844             }
3845         }
3846     }
3847 
3848     /**
3849      * Create a server socket in system_server, zygote will connect to it
3850      * in order to send unsolicited messages to system_server.
3851      */
createSystemServerSocketForZygote()3852     private LocalSocket createSystemServerSocketForZygote() {
3853         // The file system entity for this socket is created with 0666 perms, owned
3854         // by system:system. selinux restricts things so that only zygotes can
3855         // access it.
3856         final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH);
3857         if (socketFile.exists()) {
3858             socketFile.delete();
3859         }
3860 
3861         LocalSocket serverSocket = null;
3862         try {
3863             serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM);
3864             serverSocket.bind(new LocalSocketAddress(
3865                     UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM));
3866             Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666);
3867         } catch (Exception e) {
3868             if (serverSocket != null) {
3869                 try {
3870                     serverSocket.close();
3871                 } catch (IOException ex) {
3872                 }
3873                 serverSocket = null;
3874             }
3875         }
3876         return serverSocket;
3877     }
3878 
3879     /**
3880      * Handle the unsolicited message from zygote.
3881      */
handleZygoteMessages(FileDescriptor fd, int events)3882     private int handleZygoteMessages(FileDescriptor fd, int events) {
3883         final int eventFd = fd.getInt$();
3884         if ((events & EVENT_INPUT) != 0) {
3885             // An incoming message from zygote
3886             try {
3887                 final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0,
3888                         mZygoteUnsolicitedMessage.length);
3889                 if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld(
3890                         mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) {
3891                     mAppExitInfoTracker.handleZygoteSigChld(
3892                             mZygoteSigChldMessage[0] /* pid */,
3893                             mZygoteSigChldMessage[1] /* uid */,
3894                             mZygoteSigChldMessage[2] /* status */);
3895                 }
3896             } catch (Exception e) {
3897                 Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e);
3898             }
3899         }
3900         return EVENT_INPUT;
3901     }
3902 
3903     /**
3904      * Called by ActivityManagerService when a process died.
3905      */
3906     @GuardedBy("mService")
noteProcessDiedLocked(final ProcessRecord app)3907     void noteProcessDiedLocked(final ProcessRecord app) {
3908         if (DEBUG_PROCESSES) {
3909             Slog.i(TAG, "note: " + app + " died, saving the exit info");
3910         }
3911 
3912         Watchdog.getInstance().processDied(app.processName, app.pid);
3913         mAppExitInfoTracker.scheduleNoteProcessDied(app);
3914     }
3915 
3916     /**
3917      * Called by ActivityManagerService when it decides to kill an application process.
3918      */
noteAppKill(final ProcessRecord app, final @Reason int reason, final @SubReason int subReason, final String msg)3919     void noteAppKill(final ProcessRecord app, final @Reason int reason,
3920             final @SubReason int subReason, final String msg) {
3921         if (DEBUG_PROCESSES) {
3922             Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
3923                     + ", sub-reason: " + subReason + ", message: " + msg);
3924         }
3925         mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg);
3926     }
3927 
noteAppKill(final int pid, final int uid, final @Reason int reason, final @SubReason int subReason, final String msg)3928     void noteAppKill(final int pid, final int uid, final @Reason int reason,
3929             final @SubReason int subReason, final String msg) {
3930         if (DEBUG_PROCESSES) {
3931             Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason
3932                     + ", sub-reason: " + subReason + ", message: " + msg);
3933         }
3934 
3935         mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg);
3936     }
3937 
3938     /**
3939      * Schedule to kill the given pids when the device is idle
3940      */
killProcessesWhenImperceptible(int[] pids, String reason, int requester)3941     void killProcessesWhenImperceptible(int[] pids, String reason, int requester) {
3942         if (ArrayUtils.isEmpty(pids)) {
3943             return;
3944         }
3945 
3946         synchronized (mService) {
3947             ProcessRecord app;
3948             for (int i = 0; i < pids.length; i++) {
3949                 synchronized (mService.mPidsSelfLocked) {
3950                     app = mService.mPidsSelfLocked.get(pids[i]);
3951                 }
3952                 if (app != null) {
3953                     mImperceptibleKillRunner.enqueueLocked(app, reason, requester);
3954                 }
3955             }
3956         }
3957     }
3958 
3959     private final class ImperceptibleKillRunner extends IUidObserver.Stub {
3960         private static final String EXTRA_PID = "pid";
3961         private static final String EXTRA_UID = "uid";
3962         private static final String EXTRA_TIMESTAMP = "timestamp";
3963         private static final String EXTRA_REASON = "reason";
3964         private static final String EXTRA_REQUESTER = "requester";
3965 
3966         private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill";
3967 
3968         // uid -> killing information mapping
3969         private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>();
3970 
3971         // The last time the various processes have been killed by us.
3972         private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>();
3973 
3974         // Device idle or not.
3975         private volatile boolean mIdle;
3976         private boolean mUidObserverEnabled;
3977         private Handler mHandler;
3978         private IdlenessReceiver mReceiver;
3979 
3980         private final class H extends Handler {
3981             static final int MSG_DEVICE_IDLE = 0;
3982             static final int MSG_UID_GONE = 1;
3983             static final int MSG_UID_STATE_CHANGED = 2;
3984 
H(Looper looper)3985             H(Looper looper) {
3986                 super(looper);
3987             }
3988 
3989             @Override
handleMessage(Message msg)3990             public void handleMessage(Message msg) {
3991                 switch (msg.what) {
3992                     case MSG_DEVICE_IDLE:
3993                         handleDeviceIdle();
3994                         break;
3995                     case MSG_UID_GONE:
3996                         handleUidGone(msg.arg1 /* uid */);
3997                         break;
3998                     case MSG_UID_STATE_CHANGED:
3999                         handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */);
4000                         break;
4001                 }
4002             }
4003         }
4004 
4005         private final class IdlenessReceiver extends BroadcastReceiver {
4006             @Override
onReceive(Context context, Intent intent)4007             public void onReceive(Context context, Intent intent) {
4008                 final PowerManager pm = mService.mContext.getSystemService(PowerManager.class);
4009                 switch (intent.getAction()) {
4010                     case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
4011                         notifyDeviceIdleness(pm.isLightDeviceIdleMode());
4012                         break;
4013                     case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
4014                         notifyDeviceIdleness(pm.isDeviceIdleMode());
4015                         break;
4016                 }
4017             }
4018         }
4019 
ImperceptibleKillRunner(Looper looper)4020         ImperceptibleKillRunner(Looper looper) {
4021             mHandler = new H(looper);
4022         }
4023 
4024         @GuardedBy("mService")
enqueueLocked(ProcessRecord app, String reason, int requester)4025         boolean enqueueLocked(ProcessRecord app, String reason, int requester) {
4026             // Throttle the killing request for potential bad app to avoid cpu thrashing
4027             Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid);
4028             if (last != null && SystemClock.uptimeMillis() < last + MIN_CRASH_INTERVAL) {
4029                 return false;
4030             }
4031 
4032             final Bundle bundle = new Bundle();
4033             bundle.putInt(EXTRA_PID, app.pid);
4034             bundle.putInt(EXTRA_UID, app.uid);
4035             // Since the pid could be reused, let's get the actual start time of each process
4036             bundle.putLong(EXTRA_TIMESTAMP, app.startTime);
4037             bundle.putString(EXTRA_REASON, reason);
4038             bundle.putInt(EXTRA_REQUESTER, requester);
4039             List<Bundle> list = mWorkItems.get(app.uid);
4040             if (list == null) {
4041                 list = new ArrayList<Bundle>();
4042                 mWorkItems.put(app.uid, list);
4043             }
4044             list.add(bundle);
4045             if (mReceiver == null) {
4046                 mReceiver = new IdlenessReceiver();
4047                 IntentFilter filter = new IntentFilter(
4048                         PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
4049                 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
4050                 mService.mContext.registerReceiver(mReceiver, filter);
4051             }
4052             return true;
4053         }
4054 
notifyDeviceIdleness(boolean idle)4055         void notifyDeviceIdleness(boolean idle) {
4056             // No lock is held regarding mIdle, this function is the only updater and caller
4057             // won't re-entry.
4058             boolean diff = mIdle != idle;
4059             mIdle = idle;
4060             if (diff && idle) {
4061                 synchronized (this) {
4062                     if (mWorkItems.size() > 0) {
4063                         mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE);
4064                     }
4065                 }
4066             }
4067         }
4068 
handleDeviceIdle()4069         private void handleDeviceIdle() {
4070             final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
4071             final boolean logToDropbox = dbox != null
4072                     && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
4073 
4074             synchronized (mService) {
4075                 final int size = mWorkItems.size();
4076                 for (int i = size - 1; mIdle && i >= 0; i--) {
4077                     List<Bundle> list = mWorkItems.valueAt(i);
4078                     final int len = list.size();
4079                     for (int j = len - 1; mIdle && j >= 0; j--) {
4080                         Bundle bundle = list.get(j);
4081                         if (killProcessLocked(
4082                                 bundle.getInt(EXTRA_PID),
4083                                 bundle.getInt(EXTRA_UID),
4084                                 bundle.getLong(EXTRA_TIMESTAMP),
4085                                 bundle.getString(EXTRA_REASON),
4086                                 bundle.getInt(EXTRA_REQUESTER),
4087                                 dbox, logToDropbox)) {
4088                             list.remove(j);
4089                         }
4090                     }
4091                     if (list.size() == 0) {
4092                         mWorkItems.removeAt(i);
4093                     }
4094                 }
4095                 registerUidObserverIfNecessaryLocked();
4096             }
4097         }
4098 
4099         @GuardedBy("mService")
registerUidObserverIfNecessaryLocked()4100         private void registerUidObserverIfNecessaryLocked() {
4101             // If there are still works remaining, register UID observer
4102             if (!mUidObserverEnabled && mWorkItems.size() > 0) {
4103                 mUidObserverEnabled = true;
4104                 mService.registerUidObserver(this,
4105                         ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
4106                         ActivityManager.PROCESS_STATE_UNKNOWN, "android");
4107             } else if (mUidObserverEnabled && mWorkItems.size() == 0) {
4108                 mUidObserverEnabled = false;
4109                 mService.unregisterUidObserver(this);
4110             }
4111         }
4112 
4113         /**
4114          * Kill the given processes, if they are not exempted.
4115          *
4116          * @return True if the process is killed, or it's gone already, or we are not allowed to
4117          *         kill it (one of the packages in this process is being exempted).
4118          */
4119         @GuardedBy("mService")
killProcessLocked(final int pid, final int uid, final long timestamp, final String reason, final int requester, final DropBoxManager dbox, final boolean logToDropbox)4120         private boolean killProcessLocked(final int pid, final int uid, final long timestamp,
4121                 final String reason, final int requester, final DropBoxManager dbox,
4122                 final boolean logToDropbox) {
4123             ProcessRecord app = null;
4124             synchronized (mService.mPidsSelfLocked) {
4125                 app = mService.mPidsSelfLocked.get(pid);
4126             }
4127 
4128             if (app == null || app.pid != pid || app.uid != uid || app.startTime != timestamp) {
4129                 // This process record has been reused for another process, meaning the old process
4130                 // has been gone.
4131                 return true;
4132             }
4133 
4134             final int pkgSize = app.pkgList.size();
4135             for (int ip = 0; ip < pkgSize; ip++) {
4136                 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(
4137                         app.pkgList.keyAt(ip))) {
4138                     // One of the packages in this process is exempted
4139                     return true;
4140                 }
4141             }
4142 
4143             if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(
4144                     app.getReportedProcState())) {
4145                 // We need to reschedule it.
4146                 return false;
4147             }
4148 
4149             app.kill(reason, ApplicationExitInfo.REASON_OTHER,
4150                     ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true);
4151 
4152             if (!app.isolated) {
4153                 mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());
4154             }
4155 
4156             if (logToDropbox) {
4157                 final long now = SystemClock.elapsedRealtime();
4158                 final StringBuilder sb = new StringBuilder();
4159                 mService.appendDropBoxProcessHeaders(app, app.processName, sb);
4160                 sb.append("Reason: " + reason).append("\n");
4161                 sb.append("Requester UID: " + requester).append("\n");
4162                 dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString());
4163             }
4164             return true;
4165         }
4166 
handleUidStateChanged(int uid, int procState)4167         private void handleUidStateChanged(int uid, int procState) {
4168             final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
4169             final boolean logToDropbox = dbox != null
4170                     && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
4171             synchronized (mService) {
4172                 if (mIdle && !mService.mConstants
4173                         .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) {
4174                     List<Bundle> list = mWorkItems.get(uid);
4175                     if (list != null) {
4176                         final int len = list.size();
4177                         for (int j = len - 1; mIdle && j >= 0; j--) {
4178                             Bundle bundle = list.get(j);
4179                             if (killProcessLocked(
4180                                     bundle.getInt(EXTRA_PID),
4181                                     bundle.getInt(EXTRA_UID),
4182                                     bundle.getLong(EXTRA_TIMESTAMP),
4183                                     bundle.getString(EXTRA_REASON),
4184                                     bundle.getInt(EXTRA_REQUESTER),
4185                                     dbox, logToDropbox)) {
4186                                 list.remove(j);
4187                             }
4188                         }
4189                         if (list.size() == 0) {
4190                             mWorkItems.remove(uid);
4191                         }
4192                         registerUidObserverIfNecessaryLocked();
4193                     }
4194                 }
4195             }
4196         }
4197 
handleUidGone(int uid)4198         private void handleUidGone(int uid) {
4199             synchronized (mService) {
4200                 mWorkItems.remove(uid);
4201                 registerUidObserverIfNecessaryLocked();
4202             }
4203         }
4204 
4205         @Override
onUidGone(int uid, boolean disabled)4206         public void onUidGone(int uid, boolean disabled) {
4207             mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget();
4208         }
4209 
4210         @Override
onUidActive(int uid)4211         public void onUidActive(int uid) {
4212         }
4213 
4214         @Override
onUidIdle(int uid, boolean disabled)4215         public void onUidIdle(int uid, boolean disabled) {
4216         }
4217 
4218         @Override
onUidStateChanged(int uid, int procState, long procStateSeq, int capability)4219         public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
4220             mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
4221         }
4222 
4223         @Override
onUidCachedChanged(int uid, boolean cached)4224         public void onUidCachedChanged(int uid, boolean cached) {
4225         }
4226     };
4227 }
4228