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