• Home
  • History
  • Annotate
  • 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.isBadProcessLocked(info)) {
2340                      if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2341                              + "/" + info.processName);
2342                      return null;
2343                  }
2344              } else {
2345                  // When the user is explicitly starting a process, then clear its
2346                  // crash count so that we won't make it bad until they see at
2347                  // least one crash dialog again, and make the process good again
2348                  // if it had been bad.
2349                  if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2350                          + "/" + info.processName);
2351                  mService.mAppErrors.resetProcessCrashTimeLocked(info);
2352                  if (mService.mAppErrors.isBadProcessLocked(info)) {
2353                      EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2354                              UserHandle.getUserId(info.uid), info.uid,
2355                              info.processName);
2356                      mService.mAppErrors.clearBadProcessLocked(info);
2357                      if (app != null) {
2358                          app.bad = false;
2359                      }
2360                  }
2361              }
2362          } else {
2363              // If this is an isolated process, it can't re-use an existing process.
2364              app = null;
2365          }
2366  
2367          // We don't have to do anything more if:
2368          // (1) There is an existing application record; and
2369          // (2) The caller doesn't think it is dead, OR there is no thread
2370          //     object attached to it so we know it couldn't have crashed; and
2371          // (3) There is a pid assigned to it, so it is either starting or
2372          //     already running.
2373          if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
2374                  + " app=" + app + " knownToBeDead=" + knownToBeDead
2375                  + " thread=" + (app != null ? app.thread : null)
2376                  + " pid=" + (app != null ? app.pid : -1));
2377          ProcessRecord precedence = null;
2378          if (app != null && app.pid > 0) {
2379              if ((!knownToBeDead && !app.killed) || app.thread == null) {
2380                  // We already have the app running, or are waiting for it to
2381                  // come up (we have a pid but not yet its thread), so keep it.
2382                  if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
2383                  // If this is a new package in the process, add the package to the list
2384                  app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
2385                  checkSlow(startTime, "startProcess: done, added package to proc");
2386                  return app;
2387              }
2388  
2389              // An application record is attached to a previous process,
2390              // clean it up now.
2391              if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
2392              checkSlow(startTime, "startProcess: bad proc running, killing");
2393              ProcessList.killProcessGroup(app.uid, app.pid);
2394              checkSlow(startTime, "startProcess: done killing old proc");
2395  
2396              Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");
2397              // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup
2398              // routine of it yet, but we'd set it as the precedence of the new process.
2399              precedence = app;
2400              app = null;
2401          }
2402  
2403          if (app == null) {
2404              checkSlow(startTime, "startProcess: creating new process record");
2405              app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
2406              if (app == null) {
2407                  Slog.w(TAG, "Failed making new process record for "
2408                          + processName + "/" + info.uid + " isolated=" + isolated);
2409                  return null;
2410              }
2411              app.crashHandler = crashHandler;
2412              app.isolatedEntryPoint = entryPoint;
2413              app.isolatedEntryPointArgs = entryPointArgs;
2414              if (precedence != null) {
2415                  app.mPrecedence = precedence;
2416                  precedence.mSuccessor = app;
2417              }
2418              checkSlow(startTime, "startProcess: done creating new process record");
2419          } else {
2420              // If this is a new package in the process, add the package to the list
2421              app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
2422              checkSlow(startTime, "startProcess: added package to existing proc");
2423          }
2424  
2425          // If the system is not ready yet, then hold off on starting this
2426          // process until it is.
2427          if (!mService.mProcessesReady
2428                  && !mService.isAllowedWhileBooting(info)
2429                  && !allowWhileBooting) {
2430              if (!mService.mProcessesOnHold.contains(app)) {
2431                  mService.mProcessesOnHold.add(app);
2432              }
2433              if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
2434                      "System not ready, putting on hold: " + app);
2435              checkSlow(startTime, "startProcess: returning with proc on hold");
2436              return app;
2437          }
2438  
2439          checkSlow(startTime, "startProcess: stepping in to startProcess");
2440          final boolean success =
2441                  startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
2442          checkSlow(startTime, "startProcess: done starting proc!");
2443          return success ? app : null;
2444      }
2445  
2446      @GuardedBy("mService")
2447      private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
2448          StringBuilder sb = null;
2449          if (app.killedByAm) {
2450              if (sb == null) sb = new StringBuilder();
2451              sb.append("killedByAm=true;");
2452          }
2453          if (mProcessNames.get(app.processName, app.uid) != app) {
2454              if (sb == null) sb = new StringBuilder();
2455              sb.append("No entry in mProcessNames;");
2456          }
2457          if (!app.pendingStart) {
2458              if (sb == null) sb = new StringBuilder();
2459              sb.append("pendingStart=false;");
2460          }
2461          if (app.startSeq > expectedStartSeq) {
2462              if (sb == null) sb = new StringBuilder();
2463              sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
2464          }
2465          try {
2466              AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, app.userId);
2467          } catch (RemoteException e) {
2468              // unexpected; ignore
2469          } catch (SecurityException e) {
2470              if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
2471                  if (sb == null) sb = new StringBuilder();
2472                  sb.append("Package is frozen;");
2473              } else {
2474                  // we're not being started async and so should throw to the caller.
2475                  throw e;
2476              }
2477          }
2478          return sb == null ? null : sb.toString();
2479      }
2480  
2481      @GuardedBy("mService")
handleProcessStartedLocked(ProcessRecord pending, Process.ProcessStartResult startResult, long expectedStartSeq)2482      private boolean handleProcessStartedLocked(ProcessRecord pending,
2483              Process.ProcessStartResult startResult, long expectedStartSeq) {
2484          // Indicates that this process start has been taken care of.
2485          if (mPendingStarts.get(expectedStartSeq) == null) {
2486              if (pending.pid == startResult.pid) {
2487                  pending.setUsingWrapper(startResult.usingWrapper);
2488                  // TODO: Update already existing clients of usingWrapper
2489              }
2490              return false;
2491          }
2492          return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
2493                  expectedStartSeq, false);
2494      }
2495  
2496      @GuardedBy("mService")
handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, long expectedStartSeq, boolean procAttached)2497      boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
2498              long expectedStartSeq, boolean procAttached) {
2499          mPendingStarts.remove(expectedStartSeq);
2500          final String reason = isProcStartValidLocked(app, expectedStartSeq);
2501          if (reason != null) {
2502              Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
2503                      pid
2504                      + ", " + reason);
2505              app.pendingStart = false;
2506              killProcessQuiet(pid);
2507              Process.killProcessGroup(app.uid, app.pid);
2508              noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2509                      ApplicationExitInfo.SUBREASON_INVALID_START, reason);
2510              return false;
2511          }
2512          mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2513          checkSlow(app.startTime, "startProcess: done updating battery stats");
2514  
2515          EventLog.writeEvent(EventLogTags.AM_PROC_START,
2516                  UserHandle.getUserId(app.startUid), pid, app.startUid,
2517                  app.processName, app.hostingRecord.getType(),
2518                  app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
2519  
2520          try {
2521              AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
2522                      app.seInfo, app.info.sourceDir, pid);
2523          } catch (RemoteException ex) {
2524              // Ignore
2525          }
2526  
2527          Watchdog.getInstance().processStarted(app.processName, pid);
2528  
2529          checkSlow(app.startTime, "startProcess: building log message");
2530          StringBuilder buf = mStringBuilder;
2531          buf.setLength(0);
2532          buf.append("Start proc ");
2533          buf.append(pid);
2534          buf.append(':');
2535          buf.append(app.processName);
2536          buf.append('/');
2537          UserHandle.formatUid(buf, app.startUid);
2538          if (app.isolatedEntryPoint != null) {
2539              buf.append(" [");
2540              buf.append(app.isolatedEntryPoint);
2541              buf.append("]");
2542          }
2543          buf.append(" for ");
2544          buf.append(app.hostingRecord.getType());
2545          if (app.hostingRecord.getName() != null) {
2546              buf.append(" ");
2547              buf.append(app.hostingRecord.getName());
2548          }
2549          mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
2550          app.setPid(pid);
2551          app.setUsingWrapper(usingWrapper);
2552          app.pendingStart = false;
2553          checkSlow(app.startTime, "startProcess: starting to update pids map");
2554          ProcessRecord oldApp;
2555          synchronized (mService.mPidsSelfLocked) {
2556              oldApp = mService.mPidsSelfLocked.get(pid);
2557          }
2558          // If there is already an app occupying that pid that hasn't been cleaned up
2559          if (oldApp != null && !app.isolated) {
2560              // Clean up anything relating to this pid first
2561              Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
2562                      + " startSeq:" + app.startSeq
2563                      + " pid:" + pid
2564                      + " belongs to another existing app:" + oldApp.processName
2565                      + " startSeq:" + oldApp.startSeq);
2566              mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
2567                      true /*replacingPid*/);
2568          }
2569          mService.addPidLocked(app);
2570          synchronized (mService.mPidsSelfLocked) {
2571              if (!procAttached) {
2572                  Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2573                  msg.obj = app;
2574                  mService.mHandler.sendMessageDelayed(msg, usingWrapper
2575                          ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2576              }
2577          }
2578          checkSlow(app.startTime, "startProcess: done updating pids map");
2579          return true;
2580      }
2581  
removeLruProcessLocked(ProcessRecord app)2582      final void removeLruProcessLocked(ProcessRecord app) {
2583          int lrui = mLruProcesses.lastIndexOf(app);
2584          if (lrui >= 0) {
2585              if (!app.killed) {
2586                  if (app.isPersistent()) {
2587                      Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2588                  } else {
2589                      Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2590                      if (app.pid > 0) {
2591                          killProcessQuiet(app.pid);
2592                          ProcessList.killProcessGroup(app.uid, app.pid);
2593                          noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2594                                  ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed");
2595                      } else {
2596                          app.pendingStart = false;
2597                      }
2598                  }
2599              }
2600              if (lrui < mLruProcessActivityStart) {
2601                  mLruProcessActivityStart--;
2602              }
2603              if (lrui < mLruProcessServiceStart) {
2604                  mLruProcessServiceStart--;
2605              }
2606              mLruProcesses.remove(lrui);
2607          }
2608      }
2609  
2610      @GuardedBy("mService")
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, int reasonCode, int subReason, String reason)2611      boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
2612              int reasonCode, int subReason, String reason) {
2613          return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
2614                  false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2615                  false /* evenPersistent */, false /* setRemoved */, reasonCode,
2616                  subReason, reason);
2617      }
2618  
2619      @GuardedBy("mService")
killAppZygotesLocked(String packageName, int appId, int userId, boolean force)2620      void killAppZygotesLocked(String packageName, int appId, int userId, boolean force) {
2621          // See if there are any app zygotes running for this packageName / UID combination,
2622          // and kill it if so.
2623          final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2624          for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2625              for (int i = 0; i < appZygotes.size(); ++i) {
2626                  final int appZygoteUid = appZygotes.keyAt(i);
2627                  if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2628                      continue;
2629                  }
2630                  if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2631                      continue;
2632                  }
2633                  final AppZygote appZygote = appZygotes.valueAt(i);
2634                  if (packageName != null
2635                          && !packageName.equals(appZygote.getAppInfo().packageName)) {
2636                      continue;
2637                  }
2638                  zygotesToKill.add(appZygote);
2639              }
2640          }
2641          for (AppZygote appZygote : zygotesToKill) {
2642              killAppZygoteIfNeededLocked(appZygote, force);
2643          }
2644      }
2645  
2646      @GuardedBy("mService")
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode, int subReason, String reason)2647      final boolean killPackageProcessesLocked(String packageName, int appId,
2648              int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
2649              boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode,
2650              int subReason, String reason) {
2651          ArrayList<ProcessRecord> procs = new ArrayList<>();
2652  
2653          // Remove all processes this package may have touched: all with the
2654          // same UID (except for the system or root user), and all whose name
2655          // matches the package name.
2656          final int NP = mProcessNames.getMap().size();
2657          for (int ip = 0; ip < NP; ip++) {
2658              SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2659              final int NA = apps.size();
2660              for (int ia = 0; ia < NA; ia++) {
2661                  ProcessRecord app = apps.valueAt(ia);
2662                  if (app.isPersistent() && !evenPersistent) {
2663                      // we don't kill persistent processes
2664                      continue;
2665                  }
2666                  if (app.removed) {
2667                      if (doit) {
2668                          procs.add(app);
2669                      }
2670                      continue;
2671                  }
2672  
2673                  // Skip process if it doesn't meet our oom adj requirement.
2674                  if (app.setAdj < minOomAdj) {
2675                      // Note it is still possible to have a process with oom adj 0 in the killed
2676                      // processes, but it does not mean misjudgment. E.g. a bound service process
2677                      // and its client activity process are both in the background, so they are
2678                      // collected to be killed. If the client activity is killed first, the service
2679                      // may be scheduled to unbind and become an executing service (oom adj 0).
2680                      continue;
2681                  }
2682  
2683                  // If no package is specified, we call all processes under the
2684                  // give user id.
2685                  if (packageName == null) {
2686                      if (userId != UserHandle.USER_ALL && app.userId != userId) {
2687                          continue;
2688                      }
2689                      if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2690                          continue;
2691                      }
2692                      // Package has been specified, we want to hit all processes
2693                      // that match it.  We need to qualify this by the processes
2694                      // that are running under the specified app and user ID.
2695                  } else {
2696                      final boolean isDep = app.pkgDeps != null
2697                              && app.pkgDeps.contains(packageName);
2698                      if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2699                          continue;
2700                      }
2701                      if (userId != UserHandle.USER_ALL && app.userId != userId) {
2702                          continue;
2703                      }
2704                      if (!app.pkgList.containsKey(packageName) && !isDep) {
2705                          continue;
2706                      }
2707                  }
2708  
2709                  // Process has passed all conditions, kill it!
2710                  if (!doit) {
2711                      return true;
2712                  }
2713                  if (setRemoved) {
2714                      app.removed = true;
2715                  }
2716                  procs.add(app);
2717              }
2718          }
2719  
2720          int N = procs.size();
2721          for (int i=0; i<N; i++) {
2722              removeProcessLocked(procs.get(i), callerWillRestart, allowRestart,
2723                      reasonCode, subReason, reason);
2724          }
2725          killAppZygotesLocked(packageName, appId, userId, false /* force */);
2726          mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
2727          return N > 0;
2728      }
2729  
2730      @GuardedBy("mService")
removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason)2731      boolean removeProcessLocked(ProcessRecord app,
2732              boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) {
2733          return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode,
2734                  ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
2735      }
2736  
2737      @GuardedBy("mService")
removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, int reasonCode, int subReason, String reason)2738      boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
2739              boolean allowRestart, int reasonCode, int subReason, String reason) {
2740          final String name = app.processName;
2741          final int uid = app.uid;
2742          if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
2743                  "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
2744  
2745          ProcessRecord old = mProcessNames.get(name, uid);
2746          if (old != app) {
2747              // This process is no longer active, so nothing to do.
2748              Slog.w(TAG, "Ignoring remove of inactive process: " + app);
2749              return false;
2750          }
2751          removeProcessNameLocked(name, uid);
2752          mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
2753  
2754          boolean needRestart = false;
2755          if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
2756                  .pendingStart)) {
2757              int pid = app.pid;
2758              if (pid > 0) {
2759                  mService.removePidLocked(app);
2760                  app.bindMountPending = false;
2761                  mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2762                  mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2763                  if (app.isolated) {
2764                      mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2765                      mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
2766                  }
2767              }
2768              boolean willRestart = false;
2769              if (app.isPersistent() && !app.isolated) {
2770                  if (!callerWillRestart) {
2771                      willRestart = true;
2772                  } else {
2773                      needRestart = true;
2774                  }
2775              }
2776              app.kill(reason, reasonCode, subReason, true);
2777              mService.handleAppDiedLocked(app, willRestart, allowRestart);
2778              if (willRestart) {
2779                  removeLruProcessLocked(app);
2780                  mService.addAppLocked(app.info, null, false, null /* ABI override */,
2781                          ZYGOTE_POLICY_FLAG_EMPTY);
2782              }
2783          } else {
2784              mRemovedProcesses.add(app);
2785          }
2786  
2787          return needRestart;
2788      }
2789  
2790      @GuardedBy("mService")
addProcessNameLocked(ProcessRecord proc)2791      final void addProcessNameLocked(ProcessRecord proc) {
2792          // We shouldn't already have a process under this name, but just in case we
2793          // need to clean up whatever may be there now.
2794          ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
2795          if (old == proc && proc.isPersistent()) {
2796              // We are re-adding a persistent process.  Whatevs!  Just leave it there.
2797              Slog.w(TAG, "Re-adding persistent process " + proc);
2798          } else if (old != null) {
2799              Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
2800          }
2801          UidRecord uidRec = mActiveUids.get(proc.uid);
2802          if (uidRec == null) {
2803              uidRec = new UidRecord(proc.uid);
2804              // This is the first appearance of the uid, report it now!
2805              if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2806                      "Creating new process uid: " + uidRec);
2807              if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
2808                      UserHandle.getAppId(proc.uid)) >= 0
2809                      || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
2810                  uidRec.setWhitelist = uidRec.curWhitelist = true;
2811              }
2812              uidRec.updateHasInternetPermission();
2813              mActiveUids.put(proc.uid, uidRec);
2814              EventLogTags.writeAmUidRunning(uidRec.uid);
2815              mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState(),
2816                      uidRec.curCapability);
2817          }
2818          proc.uidRecord = uidRec;
2819          uidRec.procRecords.add(proc);
2820  
2821          // Reset render thread tid if it was already set, so new process can set it again.
2822          proc.renderThreadTid = 0;
2823          uidRec.numProcs++;
2824          mProcessNames.put(proc.processName, proc.uid, proc);
2825          if (proc.isolated) {
2826              mIsolatedProcesses.put(proc.uid, proc);
2827          }
2828      }
2829  
2830      @GuardedBy("mService")
getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, HostingRecord hostingRecord)2831      private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
2832              HostingRecord hostingRecord) {
2833          if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
2834              // Allocate an isolated UID from the global range
2835              return mGlobalIsolatedUids;
2836          } else {
2837              return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
2838                      info.processName, hostingRecord.getDefiningUid());
2839          }
2840      }
2841  
2842      @GuardedBy("mService")
newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid, HostingRecord hostingRecord)2843      final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
2844              boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
2845          String proc = customProcess != null ? customProcess : info.processName;
2846          final int userId = UserHandle.getUserId(info.uid);
2847          int uid = info.uid;
2848          if (isolated) {
2849              if (isolatedUid == 0) {
2850                  IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
2851                  if (uidRange == null) {
2852                      return null;
2853                  }
2854                  uid = uidRange.allocateIsolatedUidLocked(userId);
2855                  if (uid == -1) {
2856                      return null;
2857                  }
2858              } else {
2859                  // Special case for startIsolatedProcess (internal only), where
2860                  // the uid of the isolated process is specified by the caller.
2861                  uid = isolatedUid;
2862              }
2863              mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid);
2864              mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
2865  
2866              // Register the isolated UID with this application so BatteryStats knows to
2867              // attribute resource usage to the application.
2868              //
2869              // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
2870              // about the process state of the isolated UID *before* it is registered with the
2871              // owning application.
2872              mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
2873              FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
2874                      FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
2875          }
2876          final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
2877  
2878          if (!mService.mBooted && !mService.mBooting
2879                  && userId == UserHandle.USER_SYSTEM
2880                  && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
2881              // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
2882              r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
2883              r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
2884              r.setPersistent(true);
2885              r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
2886          }
2887          if (isolated && isolatedUid != 0) {
2888              // Special case for startIsolatedProcess (internal only) - assume the process
2889              // is required by the system server to prevent it being killed.
2890              r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
2891          }
2892          addProcessNameLocked(r);
2893          return r;
2894      }
2895  
2896      @GuardedBy("mService")
removeProcessNameLocked(final String name, final int uid)2897      final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
2898          return removeProcessNameLocked(name, uid, null);
2899      }
2900  
2901      @GuardedBy("mService")
removeProcessNameLocked(final String name, final int uid, final ProcessRecord expecting)2902      final ProcessRecord removeProcessNameLocked(final String name, final int uid,
2903              final ProcessRecord expecting) {
2904          ProcessRecord old = mProcessNames.get(name, uid);
2905          // Only actually remove when the currently recorded value matches the
2906          // record that we expected; if it doesn't match then we raced with a
2907          // newly created process and we don't want to destroy the new one.
2908          if ((expecting == null) || (old == expecting)) {
2909              mProcessNames.remove(name, uid);
2910          }
2911          if (old != null && old.uidRecord != null) {
2912              old.uidRecord.numProcs--;
2913              old.uidRecord.procRecords.remove(old);
2914              if (old.uidRecord.numProcs == 0) {
2915                  // No more processes using this uid, tell clients it is gone.
2916                  if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2917                          "No more processes in " + old.uidRecord);
2918                  mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
2919                  EventLogTags.writeAmUidStopped(uid);
2920                  mActiveUids.remove(uid);
2921                  mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
2922                          ActivityManager.PROCESS_CAPABILITY_NONE);
2923              }
2924              old.uidRecord = null;
2925          }
2926          mIsolatedProcesses.remove(uid);
2927          mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
2928          // Remove the (expected) ProcessRecord from the app zygote
2929          final ProcessRecord record = expecting != null ? expecting : old;
2930          if (record != null && record.appZygote) {
2931              removeProcessFromAppZygoteLocked(record);
2932          }
2933  
2934          return old;
2935      }
2936  
2937      /** Call setCoreSettings on all LRU processes, with the new settings. */
2938      @GuardedBy("mService")
updateCoreSettingsLocked(Bundle settings)2939      void updateCoreSettingsLocked(Bundle settings) {
2940          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2941              ProcessRecord processRecord = mLruProcesses.get(i);
2942              try {
2943                  if (processRecord.thread != null) {
2944                      processRecord.thread.setCoreSettings(settings);
2945                  }
2946              } catch (RemoteException re) {
2947                  /* ignore */
2948              }
2949          }
2950      }
2951  
2952      /**
2953       * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2954       * procstate lower than maxProcState.
2955       * @param minTargetSdk
2956       * @param maxProcState
2957       */
2958      @GuardedBy("mService")
killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState)2959      void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2960          final ArrayList<ProcessRecord> procs = new ArrayList<>();
2961          final int NP = mProcessNames.getMap().size();
2962          for (int ip = 0; ip < NP; ip++) {
2963              final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2964              final int NA = apps.size();
2965              for (int ia = 0; ia < NA; ia++) {
2966                  final ProcessRecord app = apps.valueAt(ia);
2967                  if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2968                          && (maxProcState < 0 || app.setProcState > maxProcState))) {
2969                      procs.add(app);
2970                  }
2971              }
2972          }
2973  
2974          final int N = procs.size();
2975          for (int i = 0; i < N; i++) {
2976              removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER,
2977                      ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except");
2978          }
2979      }
2980  
2981      /**
2982       * Call updateTimePrefs on all LRU processes
2983       * @param timePref The time pref to pass to each process
2984       */
2985      @GuardedBy("mService")
updateAllTimePrefsLocked(int timePref)2986      void updateAllTimePrefsLocked(int timePref) {
2987          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2988              ProcessRecord r = mLruProcesses.get(i);
2989              if (r.thread != null) {
2990                  try {
2991                      r.thread.updateTimePrefs(timePref);
2992                  } catch (RemoteException ex) {
2993                      Slog.w(TAG, "Failed to update preferences for: "
2994                              + r.info.processName);
2995                  }
2996              }
2997          }
2998      }
2999  
setAllHttpProxy()3000      void setAllHttpProxy() {
3001          // Update the HTTP proxy for each application thread.
3002          synchronized (mService) {
3003              for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
3004                  ProcessRecord r = mLruProcesses.get(i);
3005                  // Don't dispatch to isolated processes as they can't access ConnectivityManager and
3006                  // don't have network privileges anyway. Exclude system server and update it
3007                  // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
3008                  if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) {
3009                      try {
3010                          r.thread.updateHttpProxy();
3011                      } catch (RemoteException ex) {
3012                          Slog.w(TAG, "Failed to update http proxy for: "
3013                                  + r.info.processName);
3014                      }
3015                  }
3016              }
3017          }
3018          ActivityThread.updateHttpProxy(mService.mContext);
3019      }
3020  
3021      @GuardedBy("mService")
clearAllDnsCacheLocked()3022      void clearAllDnsCacheLocked() {
3023          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3024              ProcessRecord r = mLruProcesses.get(i);
3025              if (r.thread != null) {
3026                  try {
3027                      r.thread.clearDnsCache();
3028                  } catch (RemoteException ex) {
3029                      Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
3030                  }
3031              }
3032          }
3033      }
3034  
3035      @GuardedBy("mService")
handleAllTrustStorageUpdateLocked()3036      void handleAllTrustStorageUpdateLocked() {
3037          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3038              ProcessRecord r = mLruProcesses.get(i);
3039              if (r.thread != null) {
3040                  try {
3041                      r.thread.handleTrustStorageUpdate();
3042                  } catch (RemoteException ex) {
3043                      Slog.w(TAG, "Failed to handle trust storage update for: " +
3044                              r.info.processName);
3045                  }
3046              }
3047          }
3048      }
3049  
3050      @GuardedBy("mService")
updateLruProcessInternalLocked(ProcessRecord app, long now, int index, int lruSeq, String what, Object obj, ProcessRecord srcApp)3051      int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3052              int lruSeq, String what, Object obj, ProcessRecord srcApp) {
3053          app.lastActivityTime = now;
3054  
3055          if (app.hasActivitiesOrRecentTasks()) {
3056              // Don't want to touch dependent processes that are hosting activities.
3057              return index;
3058          }
3059  
3060          int lrui = mLruProcesses.lastIndexOf(app);
3061          if (lrui < 0) {
3062              Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3063                      + what + " " + obj + " from " + srcApp);
3064              return index;
3065          }
3066  
3067          if (lrui >= index) {
3068              // Don't want to cause this to move dependent processes *back* in the
3069              // list as if they were less frequently used.
3070              return index;
3071          }
3072  
3073          if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
3074              // Don't want to touch dependent processes that are hosting activities.
3075              return index;
3076          }
3077  
3078          mLruProcesses.remove(lrui);
3079          if (index > 0) {
3080              index--;
3081          }
3082          if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3083                  + " in LRU list: " + app);
3084          mLruProcesses.add(index, app);
3085          app.lruSeq = lruSeq;
3086          return index;
3087      }
3088  
3089      /**
3090       * Handle the case where we are inserting a process hosting client activities:
3091       * Make sure any groups have their order match their importance, and take care of
3092       * distributing old clients across other activity processes so they can't spam
3093       * the LRU list.  Processing of the list will be restricted by the indices provided,
3094       * and not extend out of them.
3095       *
3096       * @param topApp The app at the top that has just been inserted in to the list.
3097       * @param topI The position in the list where topApp was inserted; this is the start (at the
3098       *             top) where we are going to do our processing.
3099       * @param bottomI The last position at which we will be processing; this is the end position
3100       *                of whichever section of the LRU list we are in.  Nothing past it will be
3101       *                touched.
3102       * @param endIndex The current end of the top being processed.  Typically topI - 1.  That is,
3103       *                 where we are going to start potentially adjusting other entries in the list.
3104       */
updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI, final int bottomI, int endIndex)3105      private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
3106              final int bottomI, int endIndex) {
3107          if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
3108                  || !topApp.hasClientActivities()) {
3109              // If this is not a special process that has client activities, then there is
3110              // nothing to do.
3111              return;
3112          }
3113  
3114          final int uid = topApp.info.uid;
3115          if (topApp.connectionGroup > 0) {
3116              int endImportance = topApp.connectionImportance;
3117              for (int i = endIndex; i >= bottomI; i--) {
3118                  final ProcessRecord subProc = mLruProcesses.get(i);
3119                  if (subProc.info.uid == uid
3120                          && subProc.connectionGroup == topApp.connectionGroup) {
3121                      if (i == endIndex && subProc.connectionImportance >= endImportance) {
3122                          // This process is already in the group, and its importance
3123                          // is not as strong as the process before it, so keep it
3124                          // correctly positioned in the group.
3125                          if (DEBUG_LRU) Slog.d(TAG_LRU,
3126                                  "Keeping in-place above " + subProc
3127                                          + " endImportance=" + endImportance
3128                                          + " group=" + subProc.connectionGroup
3129                                          + " importance=" + subProc.connectionImportance);
3130                          endIndex--;
3131                          endImportance = subProc.connectionImportance;
3132                      } else {
3133                          // We want to pull this up to be with the rest of the group,
3134                          // and order within the group by importance.
3135                          if (DEBUG_LRU) Slog.d(TAG_LRU,
3136                                  "Pulling up " + subProc
3137                                          + " to position in group with importance="
3138                                          + subProc.connectionImportance);
3139                          boolean moved = false;
3140                          for (int pos = topI; pos > endIndex; pos--) {
3141                              final ProcessRecord posProc = mLruProcesses.get(pos);
3142                              if (subProc.connectionImportance
3143                                      <= posProc.connectionImportance) {
3144                                  mLruProcesses.remove(i);
3145                                  mLruProcesses.add(pos, subProc);
3146                                  if (DEBUG_LRU) Slog.d(TAG_LRU,
3147                                          "Moving " + subProc
3148                                                  + " from position " + i + " to above " + posProc
3149                                                  + " @ " + pos);
3150                                  moved = true;
3151                                  endIndex--;
3152                                  break;
3153                              }
3154                          }
3155                          if (!moved) {
3156                              // Goes to the end of the group.
3157                              mLruProcesses.remove(i);
3158                              mLruProcesses.add(endIndex, subProc);
3159                              if (DEBUG_LRU) Slog.d(TAG_LRU,
3160                                      "Moving " + subProc
3161                                              + " from position " + i + " to end of group @ "
3162                                              + endIndex);
3163                              endIndex--;
3164                              endImportance = subProc.connectionImportance;
3165                          }
3166                      }
3167                  }
3168              }
3169  
3170          }
3171          // To keep it from spamming the LRU list (by making a bunch of clients),
3172          // we will distribute other entries owned by it to be in-between other apps.
3173          int i = endIndex;
3174          while (i >= bottomI) {
3175              ProcessRecord subProc = mLruProcesses.get(i);
3176              if (DEBUG_LRU) Slog.d(TAG_LRU,
3177                      "Looking to spread old procs, at " + subProc + " @ " + i);
3178              if (subProc.info.uid != uid) {
3179                  // This is a different app...  if we have gone through some of the
3180                  // target app, pull this up to be before them.  We want to pull up
3181                  // one activity process, but any number of non-activity processes.
3182                  if (i < endIndex) {
3183                      boolean hasActivity = false;
3184                      int connUid = 0;
3185                      int connGroup = 0;
3186                      while (i >= bottomI) {
3187                          mLruProcesses.remove(i);
3188                          mLruProcesses.add(endIndex, subProc);
3189                          if (DEBUG_LRU) Slog.d(TAG_LRU,
3190                                  "Different app, moving to " + endIndex);
3191                          i--;
3192                          if (i < bottomI) {
3193                              break;
3194                          }
3195                          subProc = mLruProcesses.get(i);
3196                          if (DEBUG_LRU) Slog.d(TAG_LRU,
3197                                  "Looking at next app at " + i + ": " + subProc);
3198                          if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
3199                              if (DEBUG_LRU) Slog.d(TAG_LRU,
3200                                      "This is hosting an activity!");
3201                              if (hasActivity) {
3202                                  // Already found an activity, done.
3203                                  if (DEBUG_LRU) Slog.d(TAG_LRU,
3204                                          "Already found an activity, done");
3205                                  break;
3206                              }
3207                              hasActivity = true;
3208                          } else if (subProc.hasClientActivities()) {
3209                              if (DEBUG_LRU) Slog.d(TAG_LRU,
3210                                      "This is a client of an activity");
3211                              if (hasActivity) {
3212                                  if (connUid == 0 || connUid != subProc.info.uid) {
3213                                      // Already have an activity that is not from from a client
3214                                      // connection or is a different client connection, done.
3215                                      if (DEBUG_LRU) Slog.d(TAG_LRU,
3216                                              "Already found a different activity: connUid="
3217                                              + connUid + " uid=" + subProc.info.uid);
3218                                      break;
3219                                  } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
3220                                      // Previously saw a different group or not from a group,
3221                                      // want to treat these as different things.
3222                                      if (DEBUG_LRU) Slog.d(TAG_LRU,
3223                                              "Already found a different group: connGroup="
3224                                              + connGroup + " group=" + subProc.connectionGroup);
3225                                      break;
3226                                  }
3227                              } else {
3228                                  if (DEBUG_LRU) Slog.d(TAG_LRU,
3229                                          "This is an activity client!  uid="
3230                                          + subProc.info.uid + " group=" + subProc.connectionGroup);
3231                                  hasActivity = true;
3232                                  connUid = subProc.info.uid;
3233                                  connGroup = subProc.connectionGroup;
3234                              }
3235                          }
3236                          endIndex--;
3237                      }
3238                  }
3239                  // Find the end of the next group of processes for target app.  This
3240                  // is after any entries of different apps (so we don't change the existing
3241                  // relative order of apps) and then after the next last group of processes
3242                  // of the target app.
3243                  for (endIndex--; endIndex >= bottomI; endIndex--) {
3244                      final ProcessRecord endProc = mLruProcesses.get(endIndex);
3245                      if (endProc.info.uid == uid) {
3246                          if (DEBUG_LRU) Slog.d(TAG_LRU,
3247                                  "Found next group of app: " + endProc + " @ "
3248                                          + endIndex);
3249                          break;
3250                      }
3251                  }
3252                  if (endIndex >= bottomI) {
3253                      final ProcessRecord endProc = mLruProcesses.get(endIndex);
3254                      for (endIndex--; endIndex >= bottomI; endIndex--) {
3255                          final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
3256                          if (nextEndProc.info.uid != uid
3257                                  || nextEndProc.connectionGroup != endProc.connectionGroup) {
3258                              if (DEBUG_LRU) Slog.d(TAG_LRU,
3259                                      "Found next group or app: " + nextEndProc + " @ "
3260                                              + endIndex + " group=" + nextEndProc.connectionGroup);
3261                              break;
3262                          }
3263                      }
3264                  }
3265                  if (DEBUG_LRU) Slog.d(TAG_LRU,
3266                          "Bumping scan position to " + endIndex);
3267                  i = endIndex;
3268              } else {
3269                  i--;
3270              }
3271          }
3272      }
3273  
updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client)3274      final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3275              ProcessRecord client) {
3276          final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
3277                  || app.treatLikeActivity;
3278          final boolean hasService = false; // not impl yet. app.services.size() > 0;
3279          if (!activityChange && hasActivity) {
3280              // The process has activities, so we are only allowing activity-based adjustments
3281              // to move it.  It should be kept in the front of the list with other
3282              // processes that have activities, and we don't want those to change their
3283              // order except due to activity operations.
3284              return;
3285          }
3286  
3287          mLruSeq++;
3288          final long now = SystemClock.uptimeMillis();
3289          app.lastActivityTime = now;
3290  
3291          // First a quick reject: if the app is already at the position we will
3292          // put it, then there is nothing to do.
3293          if (hasActivity) {
3294              final int N = mLruProcesses.size();
3295              if (N > 0 && mLruProcesses.get(N - 1) == app) {
3296                  if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3297                  return;
3298              }
3299          } else {
3300              if (mLruProcessServiceStart > 0
3301                      && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3302                  if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3303                  return;
3304              }
3305          }
3306  
3307          int lrui = mLruProcesses.lastIndexOf(app);
3308  
3309          if (app.isPersistent() && lrui >= 0) {
3310              // We don't care about the position of persistent processes, as long as
3311              // they are in the list.
3312              if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3313              return;
3314          }
3315  
3316          /* In progress: compute new position first, so we can avoid doing work
3317             if the process is not actually going to move.  Not yet working.
3318          int addIndex;
3319          int nextIndex;
3320          boolean inActivity = false, inService = false;
3321          if (hasActivity) {
3322              // Process has activities, put it at the very tipsy-top.
3323              addIndex = mLruProcesses.size();
3324              nextIndex = mLruProcessServiceStart;
3325              inActivity = true;
3326          } else if (hasService) {
3327              // Process has services, put it at the top of the service list.
3328              addIndex = mLruProcessActivityStart;
3329              nextIndex = mLruProcessServiceStart;
3330              inActivity = true;
3331              inService = true;
3332          } else  {
3333              // Process not otherwise of interest, it goes to the top of the non-service area.
3334              addIndex = mLruProcessServiceStart;
3335              if (client != null) {
3336                  int clientIndex = mLruProcesses.lastIndexOf(client);
3337                  if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3338                          + app);
3339                  if (clientIndex >= 0 && addIndex > clientIndex) {
3340                      addIndex = clientIndex;
3341                  }
3342              }
3343              nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3344          }
3345  
3346          Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3347                  + mLruProcessActivityStart + "): " + app);
3348          */
3349  
3350          if (lrui >= 0) {
3351              if (lrui < mLruProcessActivityStart) {
3352                  mLruProcessActivityStart--;
3353              }
3354              if (lrui < mLruProcessServiceStart) {
3355                  mLruProcessServiceStart--;
3356              }
3357              /*
3358              if (addIndex > lrui) {
3359                  addIndex--;
3360              }
3361              if (nextIndex > lrui) {
3362                  nextIndex--;
3363              }
3364              */
3365              mLruProcesses.remove(lrui);
3366          }
3367  
3368          /*
3369          mLruProcesses.add(addIndex, app);
3370          if (inActivity) {
3371              mLruProcessActivityStart++;
3372          }
3373          if (inService) {
3374              mLruProcessActivityStart++;
3375          }
3376          */
3377  
3378          int nextIndex;
3379          int nextActivityIndex = -1;
3380          if (hasActivity) {
3381              final int N = mLruProcesses.size();
3382              nextIndex = mLruProcessServiceStart;
3383              if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
3384                      && mLruProcessActivityStart < (N - 1)) {
3385                  // Process doesn't have activities, but has clients with
3386                  // activities...  move it up, but below the app that is binding to it.
3387                  if (DEBUG_LRU) Slog.d(TAG_LRU,
3388                          "Adding to second-top of LRU activity list: " + app
3389                          + " group=" + app.connectionGroup
3390                          + " importance=" + app.connectionImportance);
3391                  int pos = N - 1;
3392                  while (pos > mLruProcessActivityStart) {
3393                      final ProcessRecord posproc = mLruProcesses.get(pos);
3394                      if (posproc.info.uid == app.info.uid) {
3395                          // Technically this app could have multiple processes with different
3396                          // activities and so we should be looking for the actual process that
3397                          // is bound to the target proc...  but I don't really care, do you?
3398                          break;
3399                      }
3400                      pos--;
3401                  }
3402                  mLruProcesses.add(pos, app);
3403                  // If this process is part of a group, need to pull up any other processes
3404                  // in that group to be with it.
3405                  int endIndex = pos - 1;
3406                  if (endIndex < mLruProcessActivityStart) {
3407                      endIndex = mLruProcessActivityStart;
3408                  }
3409                  nextActivityIndex = endIndex;
3410                  updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
3411              } else {
3412                  // Process has activities, put it at the very tipsy-top.
3413                  if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3414                  mLruProcesses.add(app);
3415                  nextActivityIndex = mLruProcesses.size() - 1;
3416              }
3417          } else if (hasService) {
3418              // Process has services, put it at the top of the service list.
3419              if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3420              mLruProcesses.add(mLruProcessActivityStart, app);
3421              nextIndex = mLruProcessServiceStart;
3422              mLruProcessActivityStart++;
3423          } else  {
3424              // Process not otherwise of interest, it goes to the top of the non-service area.
3425              int index = mLruProcessServiceStart;
3426              if (client != null) {
3427                  // If there is a client, don't allow the process to be moved up higher
3428                  // in the list than that client.
3429                  int clientIndex = mLruProcesses.lastIndexOf(client);
3430                  if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3431                          + " when updating " + app);
3432                  if (clientIndex <= lrui) {
3433                      // Don't allow the client index restriction to push it down farther in the
3434                      // list than it already is.
3435                      clientIndex = lrui;
3436                  }
3437                  if (clientIndex >= 0 && index > clientIndex) {
3438                      index = clientIndex;
3439                  }
3440              }
3441              if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3442              mLruProcesses.add(index, app);
3443              nextIndex = index - 1;
3444              mLruProcessActivityStart++;
3445              mLruProcessServiceStart++;
3446              if (index > 1) {
3447                  updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
3448              }
3449          }
3450  
3451          app.lruSeq = mLruSeq;
3452  
3453          // If the app is currently using a content provider or service,
3454          // bump those processes as well.
3455          for (int j = app.connections.size() - 1; j >= 0; j--) {
3456              ConnectionRecord cr = app.connections.valueAt(j);
3457              if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3458                      && cr.binding.service.app != null
3459                      && cr.binding.service.app.lruSeq != mLruSeq
3460                      && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
3461                      && !cr.binding.service.app.isPersistent()) {
3462                  if (cr.binding.service.app.hasClientActivities()) {
3463                      if (nextActivityIndex >= 0) {
3464                          nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
3465                                  now,
3466                                  nextActivityIndex, mLruSeq,
3467                                  "service connection", cr, app);
3468                      }
3469                  } else {
3470                      nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
3471                              now,
3472                              nextIndex, mLruSeq,
3473                              "service connection", cr, app);
3474                  }
3475              }
3476          }
3477          for (int j = app.conProviders.size() - 1; j >= 0; j--) {
3478              ContentProviderRecord cpr = app.conProviders.get(j).provider;
3479              if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
3480                  nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
3481                          "provider reference", cpr, app);
3482              }
3483          }
3484      }
3485  
getLRURecordForAppLocked(IApplicationThread thread)3486      final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
3487          if (thread == null) {
3488              return null;
3489          }
3490          final IBinder threadBinder = thread.asBinder();
3491          // Find the application record.
3492          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3493              final ProcessRecord rec = mLruProcesses.get(i);
3494              if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3495                  return rec;
3496              }
3497          }
3498          return null;
3499      }
3500  
haveBackgroundProcessLocked()3501      boolean haveBackgroundProcessLocked() {
3502          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3503              final ProcessRecord rec = mLruProcesses.get(i);
3504              if (rec.thread != null
3505                      && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
3506                  return true;
3507              }
3508          }
3509          return false;
3510      }
3511  
procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp, int clientTargetSdk)3512      private static int procStateToImportance(int procState, int memAdj,
3513              ActivityManager.RunningAppProcessInfo currApp,
3514              int clientTargetSdk) {
3515          int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
3516                  procState, clientTargetSdk);
3517          if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
3518              currApp.lru = memAdj;
3519          } else {
3520              currApp.lru = 0;
3521          }
3522          return imp;
3523      }
3524  
3525      @GuardedBy("mService")
fillInProcMemInfoLocked(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, int clientTargetSdk)3526      void fillInProcMemInfoLocked(ProcessRecord app,
3527              ActivityManager.RunningAppProcessInfo outInfo,
3528              int clientTargetSdk) {
3529          outInfo.pid = app.pid;
3530          outInfo.uid = app.info.uid;
3531          if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
3532              outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
3533          }
3534          if (app.isPersistent()) {
3535              outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
3536          }
3537          if (app.hasActivities()) {
3538              outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
3539          }
3540          outInfo.lastTrimLevel = app.trimMemoryLevel;
3541          int adj = app.curAdj;
3542          int procState = app.getCurProcState();
3543          outInfo.importance = procStateToImportance(procState, adj, outInfo,
3544                  clientTargetSdk);
3545          outInfo.importanceReasonCode = app.adjTypeCode;
3546          outInfo.processState = app.getCurProcState();
3547          outInfo.isFocused = (app == mService.getTopAppLocked());
3548          outInfo.lastActivityTime = app.lastActivityTime;
3549      }
3550  
3551      @GuardedBy("mService")
getRunningAppProcessesLocked(boolean allUsers, int userId, boolean allUids, int callingUid, int clientTargetSdk)3552      List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
3553              int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3554          // Lazy instantiation of list
3555          List<ActivityManager.RunningAppProcessInfo> runList = null;
3556  
3557          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3558              ProcessRecord app = mLruProcesses.get(i);
3559              if ((!allUsers && app.userId != userId)
3560                      || (!allUids && app.uid != callingUid)) {
3561                  continue;
3562              }
3563              if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
3564                  // Generate process state info for running application
3565                  ActivityManager.RunningAppProcessInfo currApp =
3566                          new ActivityManager.RunningAppProcessInfo(app.processName,
3567                                  app.pid, app.getPackageList());
3568                  fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
3569                  if (app.adjSource instanceof ProcessRecord) {
3570                      currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
3571                      currApp.importanceReasonImportance =
3572                              ActivityManager.RunningAppProcessInfo.procStateToImportance(
3573                                      app.adjSourceProcState);
3574                  } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
3575                      final ActivityServiceConnectionsHolder r =
3576                              (ActivityServiceConnectionsHolder) app.adjSource;
3577                      final int pid = r.getActivityPid();
3578                      if (pid != -1) {
3579                          currApp.importanceReasonPid = pid;
3580                      }
3581                  }
3582                  if (app.adjTarget instanceof ComponentName) {
3583                      currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
3584                  }
3585                  //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
3586                  //        + " lru=" + currApp.lru);
3587                  if (runList == null) {
3588                      runList = new ArrayList<>();
3589                  }
3590                  runList.add(currApp);
3591              }
3592          }
3593          return runList;
3594      }
3595  
3596      @GuardedBy("mService")
getLruSizeLocked()3597      int getLruSizeLocked() {
3598          return mLruProcesses.size();
3599      }
3600  
3601      @GuardedBy("mService")
dumpLruListHeaderLocked(PrintWriter pw)3602      void dumpLruListHeaderLocked(PrintWriter pw) {
3603          pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
3604          pw.print(" total, non-act at ");
3605          pw.print(mLruProcesses.size() - mLruProcessActivityStart);
3606          pw.print(", non-svc at ");
3607          pw.print(mLruProcesses.size() - mLruProcessServiceStart);
3608          pw.println("):");
3609      }
3610  
3611      @GuardedBy("mService")
collectProcessesLocked(int start, boolean allPkgs, String[] args)3612      ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
3613          ArrayList<ProcessRecord> procs;
3614          if (args != null && args.length > start
3615                  && args[start].charAt(0) != '-') {
3616              procs = new ArrayList<ProcessRecord>();
3617              int pid = -1;
3618              try {
3619                  pid = Integer.parseInt(args[start]);
3620              } catch (NumberFormatException e) {
3621              }
3622              for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3623                  ProcessRecord proc = mLruProcesses.get(i);
3624                  if (proc.pid > 0 && proc.pid == pid) {
3625                      procs.add(proc);
3626                  } else if (allPkgs && proc.pkgList != null
3627                          && proc.pkgList.containsKey(args[start])) {
3628                      procs.add(proc);
3629                  } else if (proc.processName.equals(args[start])) {
3630                      procs.add(proc);
3631                  }
3632              }
3633              if (procs.size() <= 0) {
3634                  return null;
3635              }
3636          } else {
3637              procs = new ArrayList<ProcessRecord>(mLruProcesses);
3638          }
3639          return procs;
3640      }
3641  
3642      @GuardedBy("mService")
updateApplicationInfoLocked(List<String> packagesToUpdate, int userId, boolean updateFrameworkRes)3643      void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3644              boolean updateFrameworkRes) {
3645          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3646              final ProcessRecord app = mLruProcesses.get(i);
3647              if (app.thread == null) {
3648                  continue;
3649              }
3650  
3651              if (userId != UserHandle.USER_ALL && app.userId != userId) {
3652                  continue;
3653              }
3654  
3655              final int packageCount = app.pkgList.size();
3656              for (int j = 0; j < packageCount; j++) {
3657                  final String packageName = app.pkgList.keyAt(j);
3658                  if (!updateFrameworkRes && !packagesToUpdate.contains(packageName)) {
3659                      continue;
3660                  }
3661                  try {
3662                      final ApplicationInfo ai = AppGlobals.getPackageManager()
3663                              .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3664                      if (ai == null) {
3665                          continue;
3666                      }
3667                      app.thread.scheduleApplicationInfoChanged(ai);
3668                      if (ai.packageName.equals(app.info.packageName)) {
3669                          app.info = ai;
3670                      }
3671                  } catch (RemoteException e) {
3672                      Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3673                              packageName, app));
3674                  }
3675              }
3676          }
3677      }
3678  
3679      @GuardedBy("mService")
sendPackageBroadcastLocked(int cmd, String[] packages, int userId)3680      void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
3681          boolean foundProcess = false;
3682          for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3683              ProcessRecord r = mLruProcesses.get(i);
3684              if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3685                  try {
3686                      for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
3687                          if (packages[index].equals(r.info.packageName)) {
3688                              foundProcess = true;
3689                          }
3690                      }
3691                      r.thread.dispatchPackageBroadcast(cmd, packages);
3692                  } catch (RemoteException ex) {
3693                  }
3694              }
3695          }
3696  
3697          if (!foundProcess) {
3698              try {
3699                  AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
3700              } catch (RemoteException ignored) {
3701              }
3702          }
3703      }
3704  
3705      /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3706      @GuardedBy("mService")
getUidProcStateLocked(int uid)3707      int getUidProcStateLocked(int uid) {
3708          UidRecord uidRec = mActiveUids.get(uid);
3709          return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3710      }
3711  
3712      /** Returns the UidRecord for the given uid, if it exists. */
3713      @GuardedBy("mService")
getUidRecordLocked(int uid)3714      UidRecord getUidRecordLocked(int uid) {
3715          return mActiveUids.get(uid);
3716      }
3717  
3718      /**
3719       * Call {@link ActivityManagerService#doStopUidLocked}
3720       * (which will also stop background services) for all idle UIDs.
3721       */
3722      @GuardedBy("mService")
doStopUidForIdleUidsLocked()3723      void doStopUidForIdleUidsLocked() {
3724          final int size = mActiveUids.size();
3725          for (int i = 0; i < size; i++) {
3726              final int uid = mActiveUids.keyAt(i);
3727              if (UserHandle.isCore(uid)) {
3728                  continue;
3729              }
3730              final UidRecord uidRec = mActiveUids.valueAt(i);
3731              if (!uidRec.idle) {
3732                  continue;
3733              }
3734              mService.doStopUidLocked(uidRec.uid, uidRec);
3735          }
3736      }
3737  
3738      /**
3739       * Checks if the uid is coming from background to foreground or vice versa and returns
3740       * appropriate block state based on this.
3741       *
3742       * @return blockState based on whether the uid is coming from background to foreground or
3743       *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
3744       *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
3745       *         {@link #NETWORK_STATE_NO_CHANGE}.
3746       */
3747      @VisibleForTesting
getBlockStateForUid(UidRecord uidRec)3748      int getBlockStateForUid(UidRecord uidRec) {
3749          // Denotes whether uid's process state is currently allowed network access.
3750          final boolean isAllowed =
3751                  isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState())
3752                  || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState());
3753          // Denotes whether uid's process state was previously allowed network access.
3754          final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
3755                  || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
3756  
3757          // When the uid is coming to foreground, AMS should inform the app thread that it should
3758          // block for the network rules to get updated before launching an activity.
3759          if (!wasAllowed && isAllowed) {
3760              return NETWORK_STATE_BLOCK;
3761          }
3762          // When the uid is going to background, AMS should inform the app thread that if an
3763          // activity launch is blocked for the network rules to get updated, it should be unblocked.
3764          if (wasAllowed && !isAllowed) {
3765              return NETWORK_STATE_UNBLOCK;
3766          }
3767          return NETWORK_STATE_NO_CHANGE;
3768      }
3769  
3770      /**
3771       * Checks if any uid is coming from background to foreground or vice versa and if so, increments
3772       * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
3773       * {@link ProcessList#mProcStateSeqCounter} and notifies the app if it needs to block.
3774       */
3775      @VisibleForTesting
3776      @GuardedBy("mService")
incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids)3777      void incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids) {
3778          if (mService.mWaitForNetworkTimeoutMs <= 0) {
3779              return;
3780          }
3781          // Used for identifying which uids need to block for network.
3782          ArrayList<Integer> blockingUids = null;
3783          for (int i = activeUids.size() - 1; i >= 0; --i) {
3784              final UidRecord uidRec = activeUids.valueAt(i);
3785              // If the network is not restricted for uid, then nothing to do here.
3786              if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
3787                  continue;
3788              }
3789              if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
3790                  continue;
3791              }
3792              // If process state is not changed, then there's nothing to do.
3793              if (uidRec.setProcState == uidRec.getCurProcState()) {
3794                  continue;
3795              }
3796              final int blockState = getBlockStateForUid(uidRec);
3797              // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
3798              // there's nothing the app needs to do in this scenario.
3799              if (blockState == NETWORK_STATE_NO_CHANGE) {
3800                  continue;
3801              }
3802              synchronized (uidRec.networkStateLock) {
3803                  uidRec.curProcStateSeq = ++mProcStateSeqCounter; // TODO: use method
3804                  if (blockState == NETWORK_STATE_BLOCK) {
3805                      if (blockingUids == null) {
3806                          blockingUids = new ArrayList<>();
3807                      }
3808                      blockingUids.add(uidRec.uid);
3809                  } else {
3810                      if (DEBUG_NETWORK) {
3811                          Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
3812                                  + " threads for uid: " + uidRec);
3813                      }
3814                      if (uidRec.waitingForNetwork) {
3815                          uidRec.networkStateLock.notifyAll();
3816                      }
3817                  }
3818              }
3819          }
3820  
3821          // There are no uids that need to block, so nothing more to do.
3822          if (blockingUids == null) {
3823              return;
3824          }
3825  
3826          for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
3827              final ProcessRecord app = mLruProcesses.get(i);
3828              if (!blockingUids.contains(app.uid)) {
3829                  continue;
3830              }
3831              if (!app.killedByAm && app.thread != null) {
3832                  final UidRecord uidRec = getUidRecordLocked(app.uid);
3833                  try {
3834                      if (DEBUG_NETWORK) {
3835                          Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
3836                                  + uidRec);
3837                      }
3838                      if (uidRec != null) {
3839                          app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
3840                      }
3841                  } catch (RemoteException ignored) {
3842                  }
3843              }
3844          }
3845      }
3846  
3847      /**
3848       * Create a server socket in system_server, zygote will connect to it
3849       * in order to send unsolicited messages to system_server.
3850       */
createSystemServerSocketForZygote()3851      private LocalSocket createSystemServerSocketForZygote() {
3852          // The file system entity for this socket is created with 0666 perms, owned
3853          // by system:system. selinux restricts things so that only zygotes can
3854          // access it.
3855          final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH);
3856          if (socketFile.exists()) {
3857              socketFile.delete();
3858          }
3859  
3860          LocalSocket serverSocket = null;
3861          try {
3862              serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM);
3863              serverSocket.bind(new LocalSocketAddress(
3864                      UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM));
3865              Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666);
3866          } catch (Exception e) {
3867              if (serverSocket != null) {
3868                  try {
3869                      serverSocket.close();
3870                  } catch (IOException ex) {
3871                  }
3872                  serverSocket = null;
3873              }
3874          }
3875          return serverSocket;
3876      }
3877  
3878      /**
3879       * Handle the unsolicited message from zygote.
3880       */
handleZygoteMessages(FileDescriptor fd, int events)3881      private int handleZygoteMessages(FileDescriptor fd, int events) {
3882          final int eventFd = fd.getInt$();
3883          if ((events & EVENT_INPUT) != 0) {
3884              // An incoming message from zygote
3885              try {
3886                  final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0,
3887                          mZygoteUnsolicitedMessage.length);
3888                  if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld(
3889                          mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) {
3890                      mAppExitInfoTracker.handleZygoteSigChld(
3891                              mZygoteSigChldMessage[0] /* pid */,
3892                              mZygoteSigChldMessage[1] /* uid */,
3893                              mZygoteSigChldMessage[2] /* status */);
3894                  }
3895              } catch (Exception e) {
3896                  Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e);
3897              }
3898          }
3899          return EVENT_INPUT;
3900      }
3901  
3902      /**
3903       * Called by ActivityManagerService when a process died.
3904       */
3905      @GuardedBy("mService")
noteProcessDiedLocked(final ProcessRecord app)3906      void noteProcessDiedLocked(final ProcessRecord app) {
3907          if (DEBUG_PROCESSES) {
3908              Slog.i(TAG, "note: " + app + " died, saving the exit info");
3909          }
3910  
3911          Watchdog.getInstance().processDied(app.processName, app.pid);
3912          mAppExitInfoTracker.scheduleNoteProcessDied(app);
3913      }
3914  
3915      /**
3916       * Called by ActivityManagerService when it decides to kill an application process.
3917       */
noteAppKill(final ProcessRecord app, final @Reason int reason, final @SubReason int subReason, final String msg)3918      void noteAppKill(final ProcessRecord app, final @Reason int reason,
3919              final @SubReason int subReason, final String msg) {
3920          if (DEBUG_PROCESSES) {
3921              Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
3922                      + ", sub-reason: " + subReason + ", message: " + msg);
3923          }
3924          mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg);
3925      }
3926  
noteAppKill(final int pid, final int uid, final @Reason int reason, final @SubReason int subReason, final String msg)3927      void noteAppKill(final int pid, final int uid, final @Reason int reason,
3928              final @SubReason int subReason, final String msg) {
3929          if (DEBUG_PROCESSES) {
3930              Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason
3931                      + ", sub-reason: " + subReason + ", message: " + msg);
3932          }
3933  
3934          mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg);
3935      }
3936  
3937      /**
3938       * Schedule to kill the given pids when the device is idle
3939       */
killProcessesWhenImperceptible(int[] pids, String reason, int requester)3940      void killProcessesWhenImperceptible(int[] pids, String reason, int requester) {
3941          if (ArrayUtils.isEmpty(pids)) {
3942              return;
3943          }
3944  
3945          synchronized (mService) {
3946              ProcessRecord app;
3947              for (int i = 0; i < pids.length; i++) {
3948                  synchronized (mService.mPidsSelfLocked) {
3949                      app = mService.mPidsSelfLocked.get(pids[i]);
3950                  }
3951                  if (app != null) {
3952                      mImperceptibleKillRunner.enqueueLocked(app, reason, requester);
3953                  }
3954              }
3955          }
3956      }
3957  
3958      private final class ImperceptibleKillRunner extends IUidObserver.Stub {
3959          private static final String EXTRA_PID = "pid";
3960          private static final String EXTRA_UID = "uid";
3961          private static final String EXTRA_TIMESTAMP = "timestamp";
3962          private static final String EXTRA_REASON = "reason";
3963          private static final String EXTRA_REQUESTER = "requester";
3964  
3965          private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill";
3966  
3967          // uid -> killing information mapping
3968          private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>();
3969  
3970          // The last time the various processes have been killed by us.
3971          private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>();
3972  
3973          // Device idle or not.
3974          private volatile boolean mIdle;
3975          private boolean mUidObserverEnabled;
3976          private Handler mHandler;
3977          private IdlenessReceiver mReceiver;
3978  
3979          private final class H extends Handler {
3980              static final int MSG_DEVICE_IDLE = 0;
3981              static final int MSG_UID_GONE = 1;
3982              static final int MSG_UID_STATE_CHANGED = 2;
3983  
H(Looper looper)3984              H(Looper looper) {
3985                  super(looper);
3986              }
3987  
3988              @Override
handleMessage(Message msg)3989              public void handleMessage(Message msg) {
3990                  switch (msg.what) {
3991                      case MSG_DEVICE_IDLE:
3992                          handleDeviceIdle();
3993                          break;
3994                      case MSG_UID_GONE:
3995                          handleUidGone(msg.arg1 /* uid */);
3996                          break;
3997                      case MSG_UID_STATE_CHANGED:
3998                          handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */);
3999                          break;
4000                  }
4001              }
4002          }
4003  
4004          private final class IdlenessReceiver extends BroadcastReceiver {
4005              @Override
onReceive(Context context, Intent intent)4006              public void onReceive(Context context, Intent intent) {
4007                  final PowerManager pm = mService.mContext.getSystemService(PowerManager.class);
4008                  switch (intent.getAction()) {
4009                      case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
4010                          notifyDeviceIdleness(pm.isLightDeviceIdleMode());
4011                          break;
4012                      case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
4013                          notifyDeviceIdleness(pm.isDeviceIdleMode());
4014                          break;
4015                  }
4016              }
4017          }
4018  
ImperceptibleKillRunner(Looper looper)4019          ImperceptibleKillRunner(Looper looper) {
4020              mHandler = new H(looper);
4021          }
4022  
4023          @GuardedBy("mService")
enqueueLocked(ProcessRecord app, String reason, int requester)4024          boolean enqueueLocked(ProcessRecord app, String reason, int requester) {
4025              // Throttle the killing request for potential bad app to avoid cpu thrashing
4026              Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid);
4027              if (last != null && SystemClock.uptimeMillis() < last + MIN_CRASH_INTERVAL) {
4028                  return false;
4029              }
4030  
4031              final Bundle bundle = new Bundle();
4032              bundle.putInt(EXTRA_PID, app.pid);
4033              bundle.putInt(EXTRA_UID, app.uid);
4034              // Since the pid could be reused, let's get the actual start time of each process
4035              bundle.putLong(EXTRA_TIMESTAMP, app.startTime);
4036              bundle.putString(EXTRA_REASON, reason);
4037              bundle.putInt(EXTRA_REQUESTER, requester);
4038              List<Bundle> list = mWorkItems.get(app.uid);
4039              if (list == null) {
4040                  list = new ArrayList<Bundle>();
4041                  mWorkItems.put(app.uid, list);
4042              }
4043              list.add(bundle);
4044              if (mReceiver == null) {
4045                  mReceiver = new IdlenessReceiver();
4046                  IntentFilter filter = new IntentFilter(
4047                          PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
4048                  filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
4049                  mService.mContext.registerReceiver(mReceiver, filter);
4050              }
4051              return true;
4052          }
4053  
notifyDeviceIdleness(boolean idle)4054          void notifyDeviceIdleness(boolean idle) {
4055              // No lock is held regarding mIdle, this function is the only updater and caller
4056              // won't re-entry.
4057              boolean diff = mIdle != idle;
4058              mIdle = idle;
4059              if (diff && idle) {
4060                  synchronized (this) {
4061                      if (mWorkItems.size() > 0) {
4062                          mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE);
4063                      }
4064                  }
4065              }
4066          }
4067  
handleDeviceIdle()4068          private void handleDeviceIdle() {
4069              final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
4070              final boolean logToDropbox = dbox != null
4071                      && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
4072  
4073              synchronized (mService) {
4074                  final int size = mWorkItems.size();
4075                  for (int i = size - 1; mIdle && i >= 0; i--) {
4076                      List<Bundle> list = mWorkItems.valueAt(i);
4077                      final int len = list.size();
4078                      for (int j = len - 1; mIdle && j >= 0; j--) {
4079                          Bundle bundle = list.get(j);
4080                          if (killProcessLocked(
4081                                  bundle.getInt(EXTRA_PID),
4082                                  bundle.getInt(EXTRA_UID),
4083                                  bundle.getLong(EXTRA_TIMESTAMP),
4084                                  bundle.getString(EXTRA_REASON),
4085                                  bundle.getInt(EXTRA_REQUESTER),
4086                                  dbox, logToDropbox)) {
4087                              list.remove(j);
4088                          }
4089                      }
4090                      if (list.size() == 0) {
4091                          mWorkItems.removeAt(i);
4092                      }
4093                  }
4094                  registerUidObserverIfNecessaryLocked();
4095              }
4096          }
4097  
4098          @GuardedBy("mService")
registerUidObserverIfNecessaryLocked()4099          private void registerUidObserverIfNecessaryLocked() {
4100              // If there are still works remaining, register UID observer
4101              if (!mUidObserverEnabled && mWorkItems.size() > 0) {
4102                  mUidObserverEnabled = true;
4103                  mService.registerUidObserver(this,
4104                          ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
4105                          ActivityManager.PROCESS_STATE_UNKNOWN, "android");
4106              } else if (mUidObserverEnabled && mWorkItems.size() == 0) {
4107                  mUidObserverEnabled = false;
4108                  mService.unregisterUidObserver(this);
4109              }
4110          }
4111  
4112          /**
4113           * Kill the given processes, if they are not exempted.
4114           *
4115           * @return True if the process is killed, or it's gone already, or we are not allowed to
4116           *         kill it (one of the packages in this process is being exempted).
4117           */
4118          @GuardedBy("mService")
killProcessLocked(final int pid, final int uid, final long timestamp, final String reason, final int requester, final DropBoxManager dbox, final boolean logToDropbox)4119          private boolean killProcessLocked(final int pid, final int uid, final long timestamp,
4120                  final String reason, final int requester, final DropBoxManager dbox,
4121                  final boolean logToDropbox) {
4122              ProcessRecord app = null;
4123              synchronized (mService.mPidsSelfLocked) {
4124                  app = mService.mPidsSelfLocked.get(pid);
4125              }
4126  
4127              if (app == null || app.pid != pid || app.uid != uid || app.startTime != timestamp) {
4128                  // This process record has been reused for another process, meaning the old process
4129                  // has been gone.
4130                  return true;
4131              }
4132  
4133              final int pkgSize = app.pkgList.size();
4134              for (int ip = 0; ip < pkgSize; ip++) {
4135                  if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(
4136                          app.pkgList.keyAt(ip))) {
4137                      // One of the packages in this process is exempted
4138                      return true;
4139                  }
4140              }
4141  
4142              if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(
4143                      app.getReportedProcState())) {
4144                  // We need to reschedule it.
4145                  return false;
4146              }
4147  
4148              app.kill(reason, ApplicationExitInfo.REASON_OTHER,
4149                      ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true);
4150  
4151              if (!app.isolated) {
4152                  mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());
4153              }
4154  
4155              if (logToDropbox) {
4156                  final long now = SystemClock.elapsedRealtime();
4157                  final StringBuilder sb = new StringBuilder();
4158                  mService.appendDropBoxProcessHeaders(app, app.processName, sb);
4159                  sb.append("Reason: " + reason).append("\n");
4160                  sb.append("Requester UID: " + requester).append("\n");
4161                  dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString());
4162              }
4163              return true;
4164          }
4165  
handleUidStateChanged(int uid, int procState)4166          private void handleUidStateChanged(int uid, int procState) {
4167              final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
4168              final boolean logToDropbox = dbox != null
4169                      && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
4170              synchronized (mService) {
4171                  if (mIdle && !mService.mConstants
4172                          .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) {
4173                      List<Bundle> list = mWorkItems.get(uid);
4174                      if (list != null) {
4175                          final int len = list.size();
4176                          for (int j = len - 1; mIdle && j >= 0; j--) {
4177                              Bundle bundle = list.get(j);
4178                              if (killProcessLocked(
4179                                      bundle.getInt(EXTRA_PID),
4180                                      bundle.getInt(EXTRA_UID),
4181                                      bundle.getLong(EXTRA_TIMESTAMP),
4182                                      bundle.getString(EXTRA_REASON),
4183                                      bundle.getInt(EXTRA_REQUESTER),
4184                                      dbox, logToDropbox)) {
4185                                  list.remove(j);
4186                              }
4187                          }
4188                          if (list.size() == 0) {
4189                              mWorkItems.remove(uid);
4190                          }
4191                          registerUidObserverIfNecessaryLocked();
4192                      }
4193                  }
4194              }
4195          }
4196  
handleUidGone(int uid)4197          private void handleUidGone(int uid) {
4198              synchronized (mService) {
4199                  mWorkItems.remove(uid);
4200                  registerUidObserverIfNecessaryLocked();
4201              }
4202          }
4203  
4204          @Override
onUidGone(int uid, boolean disabled)4205          public void onUidGone(int uid, boolean disabled) {
4206              mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget();
4207          }
4208  
4209          @Override
onUidActive(int uid)4210          public void onUidActive(int uid) {
4211          }
4212  
4213          @Override
onUidIdle(int uid, boolean disabled)4214          public void onUidIdle(int uid, boolean disabled) {
4215          }
4216  
4217          @Override
onUidStateChanged(int uid, int procState, long procStateSeq, int capability)4218          public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
4219              mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
4220          }
4221  
4222          @Override
onUidCachedChanged(int uid, boolean cached)4223          public void onUidCachedChanged(int uid, boolean cached) {
4224          }
4225      };
4226  }
4227