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_ENABLE_PTRACE;
1831                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1832                 // Also turn on CheckJNI for debuggable apps. It's quite
1833                 // awkward to turn on otherwise.
1834                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1835 
1836                 // Check if the developer does not want ART verification
1837                 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(),
1838                         android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) {
1839                     runtimeFlags |= Zygote.DISABLE_VERIFIER;
1840                     Slog.w(TAG_PROCESSES, app + ": ART verification disabled");
1841                 }
1842             }
1843             // Run the app in safe mode if its manifest requests so or the
1844             // system is booted in safe mode.
1845             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) {
1846                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1847             }
1848             if (isProfileableByShell) {
1849                 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
1850             }
1851             if (isProfileable) {
1852                 runtimeFlags |= Zygote.PROFILEABLE;
1853             }
1854             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1855                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1856             }
1857             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1858             if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1859                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1860             }
1861             String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1862             if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1863                 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1864             }
1865             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1866                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1867             }
1868             if ("1".equals(SystemProperties.get("debug.assert"))) {
1869                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1870             }
1871             if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) {
1872                 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER;
1873             }
1874             if (mService.mNativeDebuggingApp != null
1875                     && mService.mNativeDebuggingApp.equals(app.processName)) {
1876                 // Enable all debug flags required by the native debugger.
1877                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
1878                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1879                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
1880                 mService.mNativeDebuggingApp = null;
1881             }
1882 
1883             if (app.info.isEmbeddedDexUsed()) {
1884                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1885             }
1886 
1887             if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
1888                 app.info.maybeUpdateHiddenApiEnforcementPolicy(
1889                         mService.mHiddenApiBlacklist.getPolicy());
1890                 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
1891                         app.info.getHiddenApiEnforcementPolicy();
1892                 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
1893                 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
1894                     throw new IllegalStateException("Invalid API policy: " + policy);
1895                 }
1896                 runtimeFlags |= policyBits;
1897 
1898                 if (disableTestApiChecks) {
1899                     runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY;
1900                 }
1901             }
1902 
1903             String useAppImageCache = SystemProperties.get(
1904                     PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
1905             // Property defaults to true currently.
1906             if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) {
1907                 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
1908             }
1909 
1910             String invokeWith = null;
1911             if (debuggableFlag) {
1912                 // Debuggable apps may include a wrapper script with their library directory.
1913                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
1914                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
1915                 try {
1916                     if (new File(wrapperFileName).exists()) {
1917                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
1918                     }
1919                 } finally {
1920                     StrictMode.setThreadPolicy(oldPolicy);
1921                 }
1922             }
1923 
1924             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
1925             if (requiredAbi == null) {
1926                 requiredAbi = Build.SUPPORTED_ABIS[0];
1927             }
1928 
1929             String instructionSet = null;
1930             if (app.info.primaryCpuAbi != null) {
1931                 // If ABI override is specified, use the isa derived from the value of ABI override.
1932                 // Otherwise, use the isa derived from primary ABI
1933                 instructionSet = VMRuntime.getInstructionSet(requiredAbi);
1934             }
1935 
1936             app.setGids(gids);
1937             app.setRequiredAbi(requiredAbi);
1938             app.setInstructionSet(instructionSet);
1939 
1940             // If this was an external service, the package name and uid in the passed in
1941             // ApplicationInfo have been changed to match those of the calling package;
1942             // that will incorrectly apply compat feature overrides for the calling package instead
1943             // of the defining one.
1944             ApplicationInfo definingAppInfo;
1945             if (hostingRecord.getDefiningPackageName() != null) {
1946                 definingAppInfo = new ApplicationInfo(app.info);
1947                 definingAppInfo.packageName = hostingRecord.getDefiningPackageName();
1948                 definingAppInfo.uid = uid;
1949             } else {
1950                 definingAppInfo = app.info;
1951             }
1952 
1953             runtimeFlags |= Zygote.getMemorySafetyRuntimeFlags(
1954                     definingAppInfo, app.processInfo, instructionSet, mPlatformCompat);
1955 
1956             // the per-user SELinux context must be set
1957             if (TextUtils.isEmpty(app.info.seInfoUser)) {
1958                 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
1959                         new IllegalStateException("SELinux tag not defined for "
1960                                 + app.info.packageName + " (uid " + app.uid + ")"));
1961             }
1962 
1963             String seInfo = updateSeInfo(app);
1964 
1965             // Start the process.  It will either succeed and return a result containing
1966             // the PID of the new process, or else throw a RuntimeException.
1967             final String entryPoint = "android.app.ActivityThread";
1968 
1969             return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
1970                     runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
1971                     instructionSet, invokeWith, startUptime, startElapsedTime);
1972         } catch (RuntimeException e) {
1973             Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1974 
1975             // Something went very wrong while trying to start this process; one
1976             // common case is when the package is frozen due to an active
1977             // upgrade. To recover, clean up any active bookkeeping related to
1978             // starting this process. (We already invoked this method once when
1979             // the package was initially frozen through KILL_APPLICATION_MSG, so
1980             // it doesn't hurt to use it again.)
1981             mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1982                     false, false, true, false, false, app.userId, "start failure");
1983             return false;
1984         }
1985     }
1986 
1987     @VisibleForTesting
1988     @GuardedBy("mService")
1989     String updateSeInfo(ProcessRecord app) {
1990         String extraInfo = "";
1991         // By the time the first the SDK sandbox process is started, device config service
1992         // should be available.
1993         if (app.isSdkSandbox
1994                 && getProcessListSettingsListener().applySdkSandboxRestrictionsNext()) {
1995             extraInfo = APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS;
1996         }
1997 
1998         return app.info.seInfo
1999                 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser) + extraInfo;
2000     }
2001 
2002 
2003     @GuardedBy("mService")
2004     boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
2005             int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
2006             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
2007             long startUptime, long startElapsedTime) {
2008         app.setPendingStart(true);
2009         app.setRemoved(false);
2010         synchronized (mProcLock) {
2011             app.setKilledByAm(false);
2012             app.setKilled(false);
2013         }
2014         if (app.getStartSeq() != 0) {
2015             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
2016                     + " with non-zero startSeq:" + app.getStartSeq());
2017         }
2018         if (app.getPid() != 0) {
2019             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
2020                     + " with non-zero pid:" + app.getPid());
2021         }
2022         app.setDisabledCompatChanges(null);
2023         if (mPlatformCompat != null) {
2024             app.setDisabledCompatChanges(mPlatformCompat.getDisabledChanges(app.info));
2025         }
2026         final long startSeq = ++mProcStartSeqCounter;
2027         app.setStartSeq(startSeq);
2028         app.setStartParams(uid, hostingRecord, seInfo, startUptime, startElapsedTime);
2029         app.setUsingWrapper(invokeWith != null
2030                 || Zygote.getWrapProperty(app.processName) != null);
2031         mPendingStarts.put(startSeq, app);
2032 
2033         if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
2034             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
2035                     "Posting procStart msg for " + app.toShortString());
2036             mService.mProcStartHandler.post(() -> handleProcessStart(
2037                     app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
2038                     requiredAbi, instructionSet, invokeWith, startSeq));
2039             return true;
2040         } else {
2041             try {
2042                 final Process.ProcessStartResult startResult = startProcess(hostingRecord,
2043                         entryPoint, app,
2044                         uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
2045                         requiredAbi, instructionSet, invokeWith, startUptime);
2046                 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
2047                         startSeq, false);
2048             } catch (RuntimeException e) {
2049                 Slog.e(ActivityManagerService.TAG, "Failure starting process "
2050                         + app.processName, e);
2051                 app.setPendingStart(false);
2052                 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
2053                         false, false, true, false, false, app.userId, "start failure");
2054             }
2055             return app.getPid() > 0;
2056         }
2057     }
2058 
2059     /**
2060      * Main handler routine to start the given process from the ProcStartHandler.
2061      *
2062      * <p>Note: this function doesn't hold the global AM lock intentionally.</p>
2063      */
2064     private void handleProcessStart(final ProcessRecord app, final String entryPoint,
2065             final int[] gids, final int runtimeFlags, int zygotePolicyFlags,
2066             final int mountExternal, final String requiredAbi, final String instructionSet,
2067             final String invokeWith, final long startSeq) {
2068         final Runnable startRunnable = () -> {
2069             try {
2070                 final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(),
2071                         entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags,
2072                         mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith,
2073                         app.getStartTime());
2074 
2075                 synchronized (mService) {
2076                     handleProcessStartedLocked(app, startResult, startSeq);
2077                 }
2078             } catch (RuntimeException e) {
2079                 synchronized (mService) {
2080                     Slog.e(ActivityManagerService.TAG, "Failure starting process "
2081                             + app.processName, e);
2082                     mPendingStarts.remove(startSeq);
2083                     app.setPendingStart(false);
2084                     mService.forceStopPackageLocked(app.info.packageName,
2085                             UserHandle.getAppId(app.uid),
2086                             false, false, true, false, false, app.userId, "start failure");
2087                 }
2088             }
2089         };
2090         // Use local reference since we are not using locks here
2091         final ProcessRecord predecessor = app.mPredecessor;
2092         if (predecessor != null && predecessor.getDyingPid() > 0) {
2093             handleProcessStartWithPredecessor(predecessor, startRunnable);
2094         } else {
2095             // Kick off the process start for real.
2096             startRunnable.run();
2097         }
2098     }
2099 
2100     /**
2101      * Handle the case where the given process is killed but still not gone, but we'd need to start
2102      * the new instance of it.
2103      */
2104     private void handleProcessStartWithPredecessor(final ProcessRecord predecessor,
2105             final Runnable successorStartRunnable) {
2106         // If there is a preceding instance of the process, wait for its death with a timeout.
2107         if (predecessor.mSuccessorStartRunnable != null) {
2108             // It's been watched already, this shouldn't happen.
2109             Slog.wtf(TAG, "We've been watching for the death of " + predecessor);
2110             return;
2111         }
2112         predecessor.mSuccessorStartRunnable = successorStartRunnable;
2113         mService.mProcStartHandler.sendMessageDelayed(mService.mProcStartHandler.obtainMessage(
2114                 ProcStartHandler.MSG_PROCESS_KILL_TIMEOUT, predecessor),
2115                 mService.mConstants.mProcessKillTimeoutMs);
2116     }
2117 
2118     static final class ProcStartHandler extends Handler {
2119         static final int MSG_PROCESS_DIED = 1;
2120         static final int MSG_PROCESS_KILL_TIMEOUT = 2;
2121 
2122         private final ActivityManagerService mService;
2123 
2124         ProcStartHandler(ActivityManagerService service, Looper looper) {
2125             super(looper);
2126             mService = service;
2127         }
2128 
2129         @Override
2130         public void handleMessage(Message msg) {
2131             switch (msg.what) {
2132                 case MSG_PROCESS_DIED:
2133                     mService.mProcessList.handlePredecessorProcDied((ProcessRecord) msg.obj);
2134                     break;
2135                 case MSG_PROCESS_KILL_TIMEOUT:
2136                     synchronized (mService) {
2137                         mService.handleProcessStartOrKillTimeoutLocked((ProcessRecord) msg.obj,
2138                                 /* isKillTimeout */ true);
2139                     }
2140                     break;
2141             }
2142         }
2143     }
2144 
2145     /**
2146      * Called when the dying process we're waiting for is really gone.
2147      */
2148     private void handlePredecessorProcDied(ProcessRecord app) {
2149         if (DEBUG_PROCESSES) {
2150             Slog.i(TAG, app.toString() + " is really gone now");
2151         }
2152 
2153         // Now kick off the subsequent process start if there is any.
2154         final Runnable start = app.mSuccessorStartRunnable;
2155         if (start != null) {
2156             app.mSuccessorStartRunnable = null;
2157             start.run();
2158         }
2159     }
2160 
2161     @GuardedBy("mService")
2162     public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) {
2163         final ApplicationInfo appInfo = appZygote.getAppInfo();
2164         ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
2165         if (zygoteProcesses != null && (force || zygoteProcesses.size() == 0)) {
2166             // Only remove if no longer in use now, or forced kill
2167             mAppZygotes.remove(appInfo.processName, appInfo.uid);
2168             mAppZygoteProcesses.remove(appZygote);
2169             mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
2170             appZygote.stopZygote();
2171         }
2172     }
2173 
2174     @GuardedBy("mService")
2175     private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
2176         // Free the isolated uid for this process
2177         final IsolatedUidRange appUidRange =
2178                 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName,
2179                         app.getHostingRecord().getDefiningUid());
2180         if (appUidRange != null) {
2181             appUidRange.freeIsolatedUidLocked(app.uid);
2182         }
2183 
2184         final AppZygote appZygote = mAppZygotes.get(app.info.processName,
2185                 app.getHostingRecord().getDefiningUid());
2186         if (appZygote != null) {
2187             ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
2188             zygoteProcesses.remove(app);
2189             if (zygoteProcesses.size() == 0) {
2190                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG);
2191                 if (app.isRemoved()) {
2192                     // If we stopped this process because the package hosting it was removed,
2193                     // there's no point in delaying the app zygote kill.
2194                     killAppZygoteIfNeededLocked(appZygote, false /* force */);
2195                 } else {
2196                     Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
2197                     msg.obj = appZygote;
2198                     mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS);
2199                 }
2200             }
2201         }
2202     }
2203 
2204     private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
2205         synchronized (mService) {
2206             // The UID for the app zygote should be the UID of the application hosting
2207             // the service.
2208             final int uid = app.getHostingRecord().getDefiningUid();
2209             AppZygote appZygote = mAppZygotes.get(app.info.processName, uid);
2210             final ArrayList<ProcessRecord> zygoteProcessList;
2211             if (appZygote == null) {
2212                 if (DEBUG_PROCESSES) {
2213                     Slog.d(TAG_PROCESSES, "Creating new app zygote.");
2214                 }
2215                 final IsolatedUidRange uidRange =
2216                         mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(
2217                                 app.info.processName, app.getHostingRecord().getDefiningUid());
2218                 final int userId = UserHandle.getUserId(uid);
2219                 // Create the app-zygote and provide it with the UID-range it's allowed
2220                 // to setresuid/setresgid to.
2221                 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
2222                 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
2223                 ApplicationInfo appInfo = new ApplicationInfo(app.info);
2224                 // If this was an external service, the package name and uid in the passed in
2225                 // ApplicationInfo have been changed to match those of the calling package;
2226                 // that is not what we want for the AppZygote though, which needs to have the
2227                 // packageName and uid of the defining application. This is because the
2228                 // preloading only makes sense in the context of the defining application,
2229                 // not the calling one.
2230                 appInfo.packageName = app.getHostingRecord().getDefiningPackageName();
2231                 appInfo.uid = uid;
2232                 appZygote = new AppZygote(appInfo, app.processInfo, uid, firstUid, lastUid);
2233                 mAppZygotes.put(app.info.processName, uid, appZygote);
2234                 zygoteProcessList = new ArrayList<ProcessRecord>();
2235                 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
2236             } else {
2237                 if (DEBUG_PROCESSES) {
2238                     Slog.d(TAG_PROCESSES, "Reusing existing app zygote.");
2239                 }
2240                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
2241                 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
2242             }
2243             // Note that we already add the app to mAppZygoteProcesses here;
2244             // this is so that another thread can't come in and kill the zygote
2245             // before we've even tried to start the process. If the process launch
2246             // goes wrong, we'll clean this up in removeProcessNameLocked()
2247             zygoteProcessList.add(app);
2248 
2249             return appZygote;
2250         }
2251     }
2252 
2253     private Map<String, Pair<String, Long>> getPackageAppDataInfoMap(PackageManagerInternal pmInt,
2254             String[] packages, int uid) {
2255         Map<String, Pair<String, Long>> result = new ArrayMap<>(packages.length);
2256         int userId = UserHandle.getUserId(uid);
2257         for (String packageName : packages) {
2258             final PackageStateInternal packageState = pmInt.getPackageStateInternal(packageName);
2259             if (packageState == null) {
2260                 Slog.w(TAG, "Unknown package:" + packageName);
2261                 continue;
2262             }
2263             String volumeUuid = packageState.getVolumeUuid();
2264             long inode = packageState.getUserStateOrDefault(userId).getCeDataInode();
2265             if (inode == 0) {
2266                 Slog.w(TAG, packageName + " inode == 0 (b/152760674)");
2267                 return null;
2268             }
2269             result.put(packageName, Pair.create(volumeUuid, inode));
2270         }
2271 
2272         return result;
2273     }
2274 
2275     private boolean needsStorageDataIsolation(StorageManagerInternal storageManagerInternal,
2276             ProcessRecord app) {
2277         final int mountMode = app.getMountMode();
2278         return mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid)
2279                 && !storageManagerInternal.isExternalStorageService(app.uid)
2280                 // Special mounting mode doesn't need to have data isolation as they won't
2281                 // access /mnt/user anyway.
2282                 && mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE
2283                 && mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH
2284                 && mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER
2285                 && mountMode != Zygote.MOUNT_EXTERNAL_NONE;
2286     }
2287 
2288     private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
2289             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
2290             int mountExternal, String seInfo, String requiredAbi, String instructionSet,
2291             String invokeWith, long startTime) {
2292         try {
2293             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
2294                     app.processName);
2295             checkSlow(startTime, "startProcess: asking zygote to start proc");
2296             final boolean isTopApp = hostingRecord.isTopApp();
2297             if (isTopApp) {
2298                 // Use has-foreground-activities as a temporary hint so the current scheduling
2299                 // group won't be lost when the process is attaching. The actual state will be
2300                 // refreshed when computing oom-adj.
2301                 app.mState.setHasForegroundActivities(true);
2302             }
2303 
2304             Map<String, Pair<String, Long>> pkgDataInfoMap;
2305             Map<String, Pair<String, Long>> allowlistedAppDataInfoMap;
2306             boolean bindMountAppStorageDirs = false;
2307             boolean bindMountAppsData = mAppDataIsolationEnabled
2308                     && (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid)
2309                         || app.isSdkSandbox)
2310                     && mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info);
2311 
2312             // Get all packages belongs to the same shared uid. sharedPackages is empty array
2313             // if it doesn't have shared uid.
2314             final PackageManagerInternal pmInt = mService.getPackageManagerInternal();
2315 
2316             // In the case of sdk sandbox, the pkgDataInfoMap of only the client app associated with
2317             // the sandbox is required to handle app visibility restrictions for the sandbox.
2318             final String[] targetPackagesList;
2319             if (app.isSdkSandbox) {
2320                 targetPackagesList = new String[]{app.sdkSandboxClientAppPackage};
2321             } else {
2322                 final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage(
2323                         app.info.packageName, app.userId);
2324                 targetPackagesList = sharedPackages.length == 0
2325                         ? new String[]{app.info.packageName} : sharedPackages;
2326             }
2327 
2328             final boolean hasAppStorage = hasAppStorage(pmInt, app.info.packageName);
2329 
2330             pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, targetPackagesList, uid);
2331             if (pkgDataInfoMap == null) {
2332                 // TODO(b/152760674): Handle inode == 0 case properly, now we just give it a
2333                 // tmp free pass.
2334                 bindMountAppsData = false;
2335             }
2336 
2337             // Remove all packages in pkgDataInfoMap from mAppDataIsolationAllowlistedApps, so
2338             // it won't be mounted twice.
2339             final Set<String> allowlistedApps = new ArraySet<>(mAppDataIsolationAllowlistedApps);
2340             for (String pkg : targetPackagesList) {
2341                 allowlistedApps.remove(pkg);
2342             }
2343 
2344             allowlistedAppDataInfoMap = getPackageAppDataInfoMap(pmInt,
2345                     allowlistedApps.toArray(new String[0]), uid);
2346             if (allowlistedAppDataInfoMap == null) {
2347                 // TODO(b/152760674): Handle inode == 0 case properly, now we just give it a
2348                 // tmp free pass.
2349                 bindMountAppsData = false;
2350             }
2351 
2352             if (!hasAppStorage && !app.isSdkSandbox) {
2353                 bindMountAppsData = false;
2354                 pkgDataInfoMap = null;
2355                 allowlistedAppDataInfoMap = null;
2356             }
2357 
2358             int userId = UserHandle.getUserId(uid);
2359             StorageManagerInternal storageManagerInternal = LocalServices.getService(
2360                     StorageManagerInternal.class);
2361             if (needsStorageDataIsolation(storageManagerInternal, app)) {
2362                 // We will run prepareStorageDirs() after we trigger zygote fork, so it won't
2363                 // slow down app starting speed as those dirs might not be cached.
2364                 if (pkgDataInfoMap != null && storageManagerInternal.isFuseMounted(userId)) {
2365                     bindMountAppStorageDirs = true;
2366                 } else {
2367                     // Fuse is not mounted or inode == 0,
2368                     // so we won't mount it in zygote, but resume the mount after unlocking device.
2369                     app.setBindMountPending(true);
2370                     bindMountAppStorageDirs = false;
2371                 }
2372             }
2373 
2374             // If it's an isolated process, it should not even mount its own app data directories,
2375             // since it has no access to them anyway.
2376             if (app.isolated) {
2377                 pkgDataInfoMap = null;
2378                 allowlistedAppDataInfoMap = null;
2379             }
2380 
2381             AppStateTracker ast = mService.mServices.mAppStateTracker;
2382             if (ast != null) {
2383                 final boolean inBgRestricted = ast.isAppBackgroundRestricted(
2384                         app.info.uid, app.info.packageName);
2385                 if (inBgRestricted) {
2386                     synchronized (mService) {
2387                         mAppsInBackgroundRestricted.add(app);
2388                     }
2389                 }
2390                 app.mState.setBackgroundRestricted(inBgRestricted);
2391             }
2392 
2393             final Process.ProcessStartResult startResult;
2394             boolean regularZygote = false;
2395             app.mProcessGroupCreated = false;
2396             app.mSkipProcessGroupCreation = false;
2397             if (hostingRecord.usesWebviewZygote()) {
2398                 startResult = startWebView(entryPoint,
2399                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2400                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2401                         app.info.dataDir, null, app.info.packageName,
2402                         app.getDisabledCompatChanges(),
2403                         new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
2404             } else if (hostingRecord.usesAppZygote()) {
2405                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
2406 
2407                 // We can't isolate app data and storage data as parent zygote already did that.
2408                 startResult = appZygote.getProcess().start(entryPoint,
2409                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2410                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2411                         app.info.dataDir, null, app.info.packageName,
2412                         /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
2413                         app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,
2414                         false, false,
2415                         new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
2416             } else {
2417                 regularZygote = true;
2418                 startResult = Process.start(entryPoint,
2419                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2420                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2421                         app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
2422                         isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
2423                         allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
2424                         new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
2425                 // By now the process group should have been created by zygote.
2426                 app.mProcessGroupCreated = true;
2427             }
2428 
2429             if (!regularZygote) {
2430                 // webview and app zygote don't have the permission to create the nodes
2431                 synchronized (app) {
2432                     if (!app.mSkipProcessGroupCreation) {
2433                         // If we're not told to skip the process group creation, go create it.
2434                         final int res = Process.createProcessGroup(uid, startResult.pid);
2435                         if (res < 0) {
2436                             if (res == -OsConstants.ESRCH) {
2437                                 Slog.e(ActivityManagerService.TAG,
2438                                         "Unable to create process group for "
2439                                         + app.processName + " (" + startResult.pid + ")");
2440                             } else {
2441                                 throw new AssertionError("Unable to create process group for "
2442                                     + app.processName + " (" + startResult.pid + ")");
2443                             }
2444                         } else {
2445                             app.mProcessGroupCreated = true;
2446                         }
2447                     }
2448                 }
2449             }
2450 
2451             // This runs after Process.start() as this method may block app process starting time
2452             // if dir is not cached. Running this method after Process.start() can make it
2453             // cache the dir asynchronously, so zygote can use it without waiting for it.
2454             if (bindMountAppStorageDirs) {
2455                 storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
2456                         app.processName);
2457             }
2458             checkSlow(startTime, "startProcess: returned from zygote!");
2459             return startResult;
2460         } finally {
2461             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2462         }
2463     }
2464 
2465     private boolean hasAppStorage(PackageManagerInternal pmInt, String packageName) {
2466         final AndroidPackage pkg = pmInt.getPackage(packageName);
2467         if (pkg == null) {
2468             Slog.w(TAG, "Unknown package " + packageName);
2469             return false;
2470         }
2471         final PackageManager.Property noAppStorageProp =
2472                     pkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE);
2473         return noAppStorageProp == null || !noAppStorageProp.getBoolean();
2474     }
2475 
2476     @GuardedBy("mService")
2477     void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, int zygotePolicyFlags) {
2478         startProcessLocked(app, hostingRecord, zygotePolicyFlags, null /* abiOverride */);
2479     }
2480 
2481     @GuardedBy("mService")
2482     boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
2483             int zygotePolicyFlags, String abiOverride) {
2484         return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
2485                 false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
2486                 abiOverride);
2487     }
2488 
2489     @GuardedBy("mService")
2490     ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2491             boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
2492             int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
2493             boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
2494             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2495         long startTime = SystemClock.uptimeMillis();
2496         ProcessRecord app;
2497         if (!isolated) {
2498             app = getProcessRecordLocked(processName, info.uid);
2499             checkSlow(startTime, "startProcess: after getProcessRecord");
2500 
2501             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2502                 // If we are in the background, then check to see if this process
2503                 // is bad.  If so, we will just silently fail.
2504                 if (mService.mAppErrors.isBadProcess(processName, info.uid)) {
2505                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2506                             + "/" + processName);
2507                     return null;
2508                 }
2509             } else {
2510                 // When the user is explicitly starting a process, then clear its
2511                 // crash count so that we won't make it bad until they see at
2512                 // least one crash dialog again, and make the process good again
2513                 // if it had been bad.
2514                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2515                         + "/" + processName);
2516                 mService.mAppErrors.resetProcessCrashTime(processName, info.uid);
2517                 if (mService.mAppErrors.isBadProcess(processName, info.uid)) {
2518                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2519                             UserHandle.getUserId(info.uid), info.uid,
2520                             info.processName);
2521                     mService.mAppErrors.clearBadProcess(processName, info.uid);
2522                     if (app != null) {
2523                         app.mErrorState.setBad(false);
2524                     }
2525                 }
2526             }
2527         } else {
2528             // If this is an isolated process, it can't re-use an existing process.
2529             app = null;
2530         }
2531 
2532         // We don't have to do anything more if:
2533         // (1) There is an existing application record; and
2534         // (2) The caller doesn't think it is dead, OR there is no thread
2535         //     object attached to it so we know it couldn't have crashed; and
2536         // (3) There is a pid assigned to it, so it is either starting or
2537         //     already running.
2538         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
2539                 + " app=" + app + " knownToBeDead=" + knownToBeDead
2540                 + " thread=" + (app != null ? app.getThread() : null)
2541                 + " pid=" + (app != null ? app.getPid() : -1));
2542         ProcessRecord predecessor = null;
2543         if (app != null && app.getPid() > 0) {
2544             if ((!knownToBeDead && !app.isKilled()) || app.getThread() == null) {
2545                 // We already have the app running, or are waiting for it to
2546                 // come up (we have a pid but not yet its thread), so keep it.
2547                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
2548                 // If this is a new package in the process, add the package to the list
2549                 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
2550                 checkSlow(startTime, "startProcess: done, added package to proc");
2551                 return app;
2552             }
2553 
2554             // An application record is attached to a previous process,
2555             // clean it up now.
2556             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
2557             checkSlow(startTime, "startProcess: bad proc running, killing");
2558             ProcessList.killProcessGroup(app.uid, app.getPid());
2559             checkSlow(startTime, "startProcess: done killing old proc");
2560 
2561             if (!app.isKilled()) {
2562                 // Throw a wtf if it's not killed
2563                 Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");
2564             } else {
2565                 Slog.w(TAG_PROCESSES, app.toString() + " is attached to a previous process");
2566             }
2567             // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup
2568             // routine of it yet, but we'd set it as the predecessor of the new process.
2569             predecessor = app;
2570             app = null;
2571         } else if (!isolated) {
2572             // This app may have been removed from process name maps, probably because we killed it
2573             // and did the cleanup before the actual death notification. Check the dying processes.
2574             predecessor = mDyingProcesses.get(processName, info.uid);
2575             if (predecessor != null) {
2576                 // The process record could have existed but its pid is set to 0. In this case,
2577                 // the 'app' and 'predecessor' could end up pointing to the same instance;
2578                 // so make sure we check this case here.
2579                 if (app != null && app != predecessor) {
2580                     app.mPredecessor = predecessor;
2581                     predecessor.mSuccessor = app;
2582                 } else {
2583                     app = null;
2584                 }
2585                 Slog.w(TAG_PROCESSES, predecessor.toString() + " is attached to a previous process "
2586                         + predecessor.getDyingPid());
2587             }
2588         }
2589 
2590         if (app == null) {
2591             checkSlow(startTime, "startProcess: creating new process record");
2592             app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox,
2593                     sdkSandboxUid, sdkSandboxClientAppPackage, hostingRecord);
2594             if (app == null) {
2595                 Slog.w(TAG, "Failed making new process record for "
2596                         + processName + "/" + info.uid + " isolated=" + isolated);
2597                 return null;
2598             }
2599             app.mErrorState.setCrashHandler(crashHandler);
2600             app.setIsolatedEntryPoint(entryPoint);
2601             app.setIsolatedEntryPointArgs(entryPointArgs);
2602             if (predecessor != null) {
2603                 app.mPredecessor = predecessor;
2604                 predecessor.mSuccessor = app;
2605             }
2606             checkSlow(startTime, "startProcess: done creating new process record");
2607         } else {
2608             // If this is a new package in the process, add the package to the list
2609             app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
2610             checkSlow(startTime, "startProcess: added package to existing proc");
2611         }
2612 
2613         // If the system is not ready yet, then hold off on starting this
2614         // process until it is.
2615         if (!mService.mProcessesReady
2616                 && !mService.isAllowedWhileBooting(info)
2617                 && !allowWhileBooting) {
2618             if (!mService.mProcessesOnHold.contains(app)) {
2619                 mService.mProcessesOnHold.add(app);
2620             }
2621             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
2622                     "System not ready, putting on hold: " + app);
2623             checkSlow(startTime, "startProcess: returning with proc on hold");
2624             return app;
2625         }
2626 
2627         checkSlow(startTime, "startProcess: stepping in to startProcess");
2628         final boolean success =
2629                 startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
2630         checkSlow(startTime, "startProcess: done starting proc!");
2631         return success ? app : null;
2632     }
2633 
2634     @GuardedBy("mService")
2635     String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
2636         StringBuilder sb = null;
2637         if (app.isKilledByAm()) {
2638             if (sb == null) sb = new StringBuilder();
2639             sb.append("killedByAm=true;");
2640         }
2641         if (mProcessNames.get(app.processName, app.uid) != app) {
2642             if (sb == null) sb = new StringBuilder();
2643             sb.append("No entry in mProcessNames;");
2644         }
2645         if (!app.isPendingStart()) {
2646             if (sb == null) sb = new StringBuilder();
2647             sb.append("pendingStart=false;");
2648         }
2649         if (app.getStartSeq() > expectedStartSeq) {
2650             if (sb == null) sb = new StringBuilder();
2651             sb.append("seq=" + app.getStartSeq() + ",expected=" + expectedStartSeq + ";");
2652         }
2653         try {
2654             AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, app.userId);
2655         } catch (RemoteException e) {
2656             // unexpected; ignore
2657         } catch (SecurityException e) {
2658             if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
2659                 if (sb == null) sb = new StringBuilder();
2660                 sb.append("Package is frozen;");
2661             } else {
2662                 // we're not being started async and so should throw to the caller.
2663                 throw e;
2664             }
2665         }
2666         return sb == null ? null : sb.toString();
2667     }
2668 
2669     @GuardedBy("mService")
2670     private boolean handleProcessStartedLocked(ProcessRecord pending,
2671             Process.ProcessStartResult startResult, long expectedStartSeq) {
2672         // Indicates that this process start has been taken care of.
2673         if (mPendingStarts.get(expectedStartSeq) == null) {
2674             if (pending.getPid() == startResult.pid) {
2675                 pending.setUsingWrapper(startResult.usingWrapper);
2676                 // TODO: Update already existing clients of usingWrapper
2677             }
2678             return false;
2679         }
2680         return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
2681                 expectedStartSeq, false);
2682     }
2683 
2684     @GuardedBy("mService")
2685     boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
2686             long expectedStartSeq, boolean procAttached) {
2687         mPendingStarts.remove(expectedStartSeq);
2688         final String reason = isProcStartValidLocked(app, expectedStartSeq);
2689         if (reason != null) {
2690             Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
2691                     pid
2692                     + ", " + reason);
2693             app.setPendingStart(false);
2694             killProcessQuiet(pid);
2695             final int appPid = app.getPid();
2696             if (appPid != 0) {
2697                 Process.killProcessGroup(app.uid, appPid);
2698             }
2699             noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2700                     ApplicationExitInfo.SUBREASON_INVALID_START, reason);
2701             return false;
2702         }
2703         mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2704         checkSlow(app.getStartTime(), "startProcess: done updating battery stats");
2705 
2706         EventLog.writeEvent(EventLogTags.AM_PROC_START,
2707                 UserHandle.getUserId(app.getStartUid()), pid, app.getStartUid(),
2708                 app.processName, app.getHostingRecord().getType(),
2709                 app.getHostingRecord().getName() != null ? app.getHostingRecord().getName() : "");
2710 
2711         try {
2712             AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.info.packageName,
2713                     app.processName, app.uid, app.getSeInfo(), app.info.sourceDir, pid);
2714         } catch (RemoteException ex) {
2715             // Ignore
2716         }
2717 
2718         Watchdog.getInstance().processStarted(app.processName, pid);
2719 
2720         checkSlow(app.getStartTime(), "startProcess: building log message");
2721         StringBuilder buf = mStringBuilder;
2722         buf.setLength(0);
2723         buf.append("Start proc ");
2724         buf.append(pid);
2725         buf.append(':');
2726         buf.append(app.processName);
2727         buf.append('/');
2728         UserHandle.formatUid(buf, app.getStartUid());
2729         if (app.getIsolatedEntryPoint() != null) {
2730             buf.append(" [");
2731             buf.append(app.getIsolatedEntryPoint());
2732             buf.append("]");
2733         }
2734         buf.append(" for ");
2735         buf.append(app.getHostingRecord().getType());
2736         if (app.getHostingRecord().getName() != null) {
2737             buf.append(" ");
2738             buf.append(app.getHostingRecord().getName());
2739         }
2740         mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.getStartUid());
2741         synchronized (mProcLock) {
2742             app.setPid(pid);
2743             app.setUsingWrapper(usingWrapper);
2744             app.setPendingStart(false);
2745         }
2746         checkSlow(app.getStartTime(), "startProcess: starting to update pids map");
2747         ProcessRecord oldApp;
2748         synchronized (mService.mPidsSelfLocked) {
2749             oldApp = mService.mPidsSelfLocked.get(pid);
2750         }
2751         // If there is already an app occupying that pid that hasn't been cleaned up
2752         if (oldApp != null && !app.isolated) {
2753             // Clean up anything relating to this pid first
2754             Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
2755                     + " startSeq:" + app.getStartSeq()
2756                     + " pid:" + pid
2757                     + " belongs to another existing app:" + oldApp.processName
2758                     + " startSeq:" + oldApp.getStartSeq());
2759             mService.cleanUpApplicationRecordLocked(oldApp, pid, false, false, -1,
2760                     true /*replacingPid*/, false /* fromBinderDied */);
2761         }
2762         mService.addPidLocked(app);
2763         synchronized (mService.mPidsSelfLocked) {
2764             if (!procAttached) {
2765                 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2766                 msg.obj = app;
2767                 mService.mHandler.sendMessageDelayed(msg, usingWrapper
2768                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2769             }
2770         }
2771         checkSlow(app.getStartTime(), "startProcess: done updating pids map");
2772         return true;
2773     }
2774 
2775     @GuardedBy("mService")
2776     void removeLruProcessLocked(ProcessRecord app) {
2777         int lrui = mLruProcesses.lastIndexOf(app);
2778         if (lrui >= 0) {
2779             synchronized (mProcLock) {
2780                 if (!app.isKilled()) {
2781                     if (app.isPersistent()) {
2782                         Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2783                     } else {
2784                         Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2785                         if (app.getPid() > 0) {
2786                             killProcessQuiet(app.getPid());
2787                             ProcessList.killProcessGroup(app.uid, app.getPid());
2788                             noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2789                                     ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed");
2790                         } else {
2791                             app.setPendingStart(false);
2792                         }
2793                     }
2794                 }
2795                 if (lrui < mLruProcessActivityStart) {
2796                     mLruProcessActivityStart--;
2797                 }
2798                 if (lrui < mLruProcessServiceStart) {
2799                     mLruProcessServiceStart--;
2800                 }
2801                 mLruProcesses.remove(lrui);
2802             }
2803         }
2804         mService.removeOomAdjTargetLocked(app, true);
2805     }
2806 
2807     @GuardedBy({"mService", "mProcLock"})
2808     boolean killPackageProcessesLSP(String packageName, int appId, int userId, int minOomAdj,
2809             int reasonCode, int subReason, String reason) {
2810         return killPackageProcessesLSP(packageName, appId, userId, minOomAdj,
2811                 false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2812                 false /* evenPersistent */, false /* setRemoved */, false /* uninstalling */,
2813                 reasonCode, subReason, reason);
2814     }
2815 
2816     @GuardedBy("mService")
2817     void killAppZygotesLocked(String packageName, int appId, int userId, boolean force) {
2818         // See if there are any app zygotes running for this packageName / UID combination,
2819         // and kill it if so.
2820         final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2821         for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2822             for (int i = 0; i < appZygotes.size(); ++i) {
2823                 final int appZygoteUid = appZygotes.keyAt(i);
2824                 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2825                     continue;
2826                 }
2827                 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2828                     continue;
2829                 }
2830                 final AppZygote appZygote = appZygotes.valueAt(i);
2831                 if (packageName != null
2832                         && !packageName.equals(appZygote.getAppInfo().packageName)) {
2833                     continue;
2834                 }
2835                 zygotesToKill.add(appZygote);
2836             }
2837         }
2838         for (AppZygote appZygote : zygotesToKill) {
2839             killAppZygoteIfNeededLocked(appZygote, force);
2840         }
2841     }
2842 
2843     private static boolean freezePackageCgroup(int packageUID, boolean freeze) {
2844         try {
2845             Process.freezeCgroupUid(packageUID, freeze);
2846         } catch (RuntimeException e) {
2847             final String logtxt = freeze ? "freeze" : "unfreeze";
2848             Slog.e(TAG, "Unable to " + logtxt + " cgroup uid: " + packageUID + ": " + e);
2849             return false;
2850         }
2851         return true;
2852     }
2853 
2854     private static void freezeBinderAndPackageCgroup(ArrayList<Pair<ProcessRecord, Boolean>> procs,
2855                                                      int packageUID) {
2856         // Freeze all binder processes under the target UID (whose cgroup is about to be frozen).
2857         // Since we're going to kill these, we don't need to unfreze them later.
2858         // The procs list may not include all processes under the UID cgroup, but unincluded
2859         // processes (forks) should not be Binder users.
2860         int N = procs.size();
2861         for (int i = 0; i < N; i++) {
2862             final int uid = procs.get(i).first.uid;
2863             final int pid = procs.get(i).first.getPid();
2864             int nRetries = 0;
2865             // We only freeze the cgroup of the target package, so we do not need to freeze the
2866             // Binder interfaces of dependant processes in other UIDs.
2867             if (pid > 0 && uid == packageUID) {
2868                 try {
2869                     int rc;
2870                     do {
2871                         rc = CachedAppOptimizer.freezeBinder(pid, true, 10 /* timeout_ms */);
2872                     } while (rc == -EAGAIN && nRetries++ < 1);
2873                     if (rc != 0) Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + rc);
2874                 } catch (RuntimeException e) {
2875                     Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + e);
2876                 }
2877             }
2878         }
2879 
2880         // We freeze the entire UID (parent) cgroup so that newly-specialized processes also freeze
2881         // despite being added to a new child cgroup. The cgroups of package dependant processes are
2882         // not frozen, since it's possible this would freeze processes with no dependency on the
2883         // package being killed here.
2884         freezePackageCgroup(packageUID, true);
2885     }
2886 
2887     @GuardedBy({"mService", "mProcLock"})
2888     boolean killPackageProcessesLSP(String packageName, int appId,
2889             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
2890             boolean doit, boolean evenPersistent, boolean setRemoved, boolean uninstalling,
2891             int reasonCode, int subReason, String reason) {
2892         final PackageManagerInternal pm = mService.getPackageManagerInternal();
2893         final ArrayList<Pair<ProcessRecord, Boolean>> procs = new ArrayList<>();
2894 
2895         // Remove all processes this package may have touched: all with the
2896         // same UID (except for the system or root user), and all whose name
2897         // matches the package name.
2898         final int NP = mProcessNames.getMap().size();
2899         for (int ip = 0; ip < NP; ip++) {
2900             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2901             final int NA = apps.size();
2902             for (int ia = 0; ia < NA; ia++) {
2903                 ProcessRecord app = apps.valueAt(ia);
2904                 if (app.isPersistent() && !evenPersistent) {
2905                     // we don't kill persistent processes
2906                     continue;
2907                 }
2908                 if (app.isRemoved()) {
2909                     if (doit) {
2910                         boolean shouldAllowRestart = false;
2911                         if (!uninstalling && packageName != null) {
2912                             // This package has a dependency on the given package being stopped,
2913                             // while it's not being frozen nor uninstalled, allow to restart it.
2914                             shouldAllowRestart = !app.getPkgList().containsKey(packageName)
2915                                     && app.getPkgDeps() != null
2916                                     && app.getPkgDeps().contains(packageName)
2917                                     && app.info != null
2918                                     && !pm.isPackageFrozen(app.info.packageName, app.uid,
2919                                             app.userId);
2920                         }
2921                         procs.add(new Pair<>(app, shouldAllowRestart));
2922                     }
2923                     continue;
2924                 }
2925 
2926                 // Skip process if it doesn't meet our oom adj requirement.
2927                 if (app.mState.getSetAdj() < minOomAdj) {
2928                     // Note it is still possible to have a process with oom adj 0 in the killed
2929                     // processes, but it does not mean misjudgment. E.g. a bound service process
2930                     // and its client activity process are both in the background, so they are
2931                     // collected to be killed. If the client activity is killed first, the service
2932                     // may be scheduled to unbind and become an executing service (oom adj 0).
2933                     continue;
2934                 }
2935 
2936                 boolean shouldAllowRestart = false;
2937 
2938                 // If no package is specified, we call all processes under the
2939                 // given user id.
2940                 if (packageName == null) {
2941                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
2942                         continue;
2943                     }
2944                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2945                         continue;
2946                     }
2947                     // Package has been specified, we want to hit all processes
2948                     // that match it.  We need to qualify this by the processes
2949                     // that are running under the specified app and user ID.
2950                 } else {
2951                     final boolean isDep = app.getPkgDeps() != null
2952                             && app.getPkgDeps().contains(packageName);
2953                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2954                         continue;
2955                     }
2956                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
2957                         continue;
2958                     }
2959                     final boolean isInPkgList = app.getPkgList().containsKey(packageName);
2960                     if (!isInPkgList && !isDep) {
2961                         continue;
2962                     }
2963                     if (!isInPkgList && isDep && !uninstalling && app.info != null
2964                             && !pm.isPackageFrozen(app.info.packageName, app.uid, app.userId)) {
2965                         // This package has a dependency on the given package being stopped,
2966                         // while it's not being frozen nor uninstalled, allow to restart it.
2967                         shouldAllowRestart = true;
2968                     }
2969                 }
2970 
2971                 // Process has passed all conditions, kill it!
2972                 if (!doit) {
2973                     return true;
2974                 }
2975                 if (setRemoved) {
2976                     app.setRemoved(true);
2977                 }
2978                 procs.add(new Pair<>(app, shouldAllowRestart));
2979             }
2980         }
2981 
2982         final int packageUID = UserHandle.getUid(userId, appId);
2983         final boolean doFreeze = appId >= Process.FIRST_APPLICATION_UID
2984                               && appId <= Process.LAST_APPLICATION_UID;
2985         if (doFreeze) {
2986             freezeBinderAndPackageCgroup(procs, packageUID);
2987         }
2988 
2989         int N = procs.size();
2990         for (int i=0; i<N; i++) {
2991             final Pair<ProcessRecord, Boolean> proc = procs.get(i);
2992             removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second,
2993                     reasonCode, subReason, reason, !doFreeze /* async */);
2994         }
2995         killAppZygotesLocked(packageName, appId, userId, false /* force */);
2996         mService.updateOomAdjLocked(OOM_ADJ_REASON_PROCESS_END);
2997         if (doFreeze) {
2998             freezePackageCgroup(packageUID, false);
2999         }
3000         return N > 0;
3001     }
3002 
3003     @GuardedBy("mService")
3004     boolean removeProcessLocked(ProcessRecord app,
3005             boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) {
3006         return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode,
3007                 ApplicationExitInfo.SUBREASON_UNKNOWN, reason, true);
3008     }
3009 
3010     @GuardedBy("mService")
3011     boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
3012             boolean allowRestart, int reasonCode, int subReason, String reason) {
3013         return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode, subReason,
3014                 reason, true);
3015     }
3016 
3017     @GuardedBy("mService")
3018     boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
3019             boolean allowRestart, int reasonCode, int subReason, String reason, boolean async) {
3020         final String name = app.processName;
3021         final int uid = app.uid;
3022         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
3023                 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
3024 
3025         ProcessRecord old = mProcessNames.get(name, uid);
3026         if (old != app) {
3027             // This process is no longer active, so nothing to do.
3028             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
3029             return false;
3030         }
3031         removeProcessNameLocked(name, uid);
3032         mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
3033 
3034         boolean needRestart = false;
3035         final int pid = app.getPid();
3036         if ((pid > 0 && pid != ActivityManagerService.MY_PID)
3037                 || (pid == 0 && app.isPendingStart())) {
3038             if (pid > 0) {
3039                 mService.removePidLocked(pid, app);
3040                 app.setBindMountPending(false);
3041                 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3042                 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3043                 if (app.isolated) {
3044                     mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3045                     mService.getPackageManagerInternal().removeIsolatedUid(app.uid);
3046                 }
3047             }
3048             boolean willRestart = false;
3049             if (app.isPersistent() && !app.isolated) {
3050                 if (!callerWillRestart) {
3051                     willRestart = true;
3052                 } else {
3053                     needRestart = true;
3054                 }
3055             }
3056             app.killLocked(reason, reasonCode, subReason, true, async);
3057             mService.handleAppDiedLocked(app, pid, willRestart, allowRestart,
3058                     false /* fromBinderDied */);
3059             if (willRestart) {
3060                 removeLruProcessLocked(app);
3061                 mService.addAppLocked(app.info, null, false, null /* ABI override */,
3062                         ZYGOTE_POLICY_FLAG_EMPTY);
3063             }
3064         } else {
3065             mRemovedProcesses.add(app);
3066         }
3067 
3068         return needRestart;
3069     }
3070 
3071     @GuardedBy("mService")
3072     void addProcessNameLocked(ProcessRecord proc) {
3073         // We shouldn't already have a process under this name, but just in case we
3074         // need to clean up whatever may be there now.
3075         synchronized (mProcLock) {
3076             ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
3077             if (old == proc && proc.isPersistent()) {
3078                 // We are re-adding a persistent process.  Whatevs!  Just leave it there.
3079                 Slog.w(TAG, "Re-adding persistent process " + proc);
3080             } else if (old != null) {
3081                 if (old.isKilled()) {
3082                     // The old process has been killed, we probably haven't had
3083                     // a chance to clean up the old record, just log a warning
3084                     Slog.w(TAG, "Existing proc " + old + " was killed "
3085                             + (SystemClock.uptimeMillis() - old.getKillTime())
3086                             + "ms ago when adding " + proc);
3087                 } else {
3088                     Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
3089                 }
3090             }
3091             UidRecord uidRec = mActiveUids.get(proc.uid);
3092             if (uidRec == null) {
3093                 uidRec = new UidRecord(proc.uid, mService);
3094                 // This is the first appearance of the uid, report it now!
3095                 if (DEBUG_UID_OBSERVERS) {
3096                     Slog.i(TAG_UID_OBSERVERS, "Creating new process uid: " + uidRec);
3097                 }
3098                 if (Arrays.binarySearch(mService.mDeviceIdleTempAllowlist,
3099                             UserHandle.getAppId(proc.uid)) >= 0
3100                         || mService.mPendingTempAllowlist.indexOfKey(proc.uid) >= 0) {
3101                     uidRec.setCurAllowListed(true);
3102                     uidRec.setSetAllowListed(true);
3103                 }
3104                 uidRec.updateHasInternetPermission();
3105                 mActiveUids.put(proc.uid, uidRec);
3106                 EventLogTags.writeAmUidRunning(uidRec.getUid());
3107                 mService.noteUidProcessState(uidRec.getUid(), uidRec.getCurProcState(),
3108                         uidRec.getCurCapability());
3109             }
3110             proc.setUidRecord(uidRec);
3111             uidRec.addProcess(proc);
3112 
3113             // Reset render thread tid if it was already set, so new process can set it again.
3114             proc.setRenderThreadTid(0);
3115             mProcessNames.put(proc.processName, proc.uid, proc);
3116         }
3117         if (proc.isolated) {
3118             mIsolatedProcesses.put(proc.uid, proc);
3119         }
3120         if (proc.isSdkSandbox) {
3121             ArrayList<ProcessRecord> sdkSandboxes = mSdkSandboxes.get(proc.uid);
3122             if (sdkSandboxes == null) {
3123                 sdkSandboxes = new ArrayList<>();
3124             }
3125             sdkSandboxes.add(proc);
3126             mSdkSandboxes.put(Process.getAppUidForSdkSandboxUid(proc.uid), sdkSandboxes);
3127         }
3128     }
3129 
3130     @GuardedBy("mService")
3131     private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
3132             HostingRecord hostingRecord) {
3133         if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
3134             // Allocate an isolated UID from the global range
3135             return mGlobalIsolatedUids;
3136         } else {
3137             return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
3138                     info.processName, hostingRecord.getDefiningUid());
3139         }
3140     }
3141 
3142     ProcessRecord getSharedIsolatedProcess(String processName, int uid, String packageName) {
3143         for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
3144             final ProcessRecord app = mIsolatedProcesses.valueAt(i);
3145             if (app.info.uid == uid && app.info.packageName.equals(packageName)
3146                     && app.processName.equals(processName)) {
3147                 return app;
3148             }
3149         }
3150         return null;
3151     }
3152     @Nullable
3153     @GuardedBy("mService")
3154     List<Integer> getIsolatedProcessesLocked(int uid) {
3155         List<Integer> ret = null;
3156         for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
3157             final ProcessRecord app = mIsolatedProcesses.valueAt(i);
3158             if (app.info.uid == uid) {
3159                 if (ret == null) {
3160                     ret = new ArrayList<>();
3161                 }
3162                 ret.add(app.getPid());
3163             }
3164         }
3165         return ret;
3166     }
3167 
3168     /**
3169      * Returns the associated SDK sandbox processes for a UID. Note that this does
3170      * NOT return a copy, so callers should not modify the result, or use it outside
3171      * of the lock scope.
3172      *
3173      * @param uid UID to return sansdbox processes for
3174      */
3175     @Nullable
3176     @GuardedBy("mService")
3177     List<ProcessRecord> getSdkSandboxProcessesForAppLocked(int uid) {
3178         return mSdkSandboxes.get(uid);
3179     }
3180 
3181     @GuardedBy("mService")
3182     ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
3183             boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid,
3184             String sdkSandboxClientAppPackage, HostingRecord hostingRecord) {
3185         String proc = customProcess != null ? customProcess : info.processName;
3186         final int userId = UserHandle.getUserId(info.uid);
3187         int uid = info.uid;
3188         if (isSdkSandbox) {
3189             uid = sdkSandboxUid;
3190         }
3191         if (Process.isSdkSandboxUid(uid) && (!isSdkSandbox || sdkSandboxClientAppPackage == null)) {
3192             Slog.e(TAG, "Abort creating new sandbox process as required parameters are missing.");
3193             return null;
3194         }
3195         if (isolated) {
3196             if (isolatedUid == 0) {
3197                 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
3198                 if (uidRange == null) {
3199                     return null;
3200                 }
3201                 uid = uidRange.allocateIsolatedUidLocked(userId);
3202                 if (uid == -1) {
3203                     return null;
3204                 }
3205             } else {
3206                 // Special case for startIsolatedProcess (internal only), where
3207                 // the uid of the isolated process is specified by the caller.
3208                 uid = isolatedUid;
3209             }
3210             mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid);
3211             mService.getPackageManagerInternal().addIsolatedUid(uid, info.uid);
3212 
3213             // Register the isolated UID with this application so BatteryStats knows to
3214             // attribute resource usage to the application.
3215             //
3216             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
3217             // about the process state of the isolated UID *before* it is registered with the
3218             // owning application.
3219             mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
3220             FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
3221                     FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
3222         }
3223         final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,
3224                 sdkSandboxClientAppPackage,
3225                 hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());
3226         final ProcessStateRecord state = r.mState;
3227 
3228         if (!isolated && !isSdkSandbox
3229                 && userId == UserHandle.USER_SYSTEM
3230                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK
3231                 && (TextUtils.equals(proc, info.processName))) {
3232             // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
3233             state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
3234             state.setSetSchedGroup(ProcessList.SCHED_GROUP_DEFAULT);
3235             r.setPersistent(true);
3236             state.setMaxAdj(ProcessList.PERSISTENT_PROC_ADJ);
3237         }
3238         if (isolated && isolatedUid != 0) {
3239             // Special case for startIsolatedProcess (internal only) - assume the process
3240             // is required by the system server to prevent it being killed.
3241             state.setMaxAdj(ProcessList.PERSISTENT_SERVICE_ADJ);
3242         }
3243         addProcessNameLocked(r);
3244         return r;
3245     }
3246 
3247     @GuardedBy("mService")
3248     ProcessRecord removeProcessNameLocked(final String name, final int uid) {
3249         return removeProcessNameLocked(name, uid, null);
3250     }
3251 
3252     @GuardedBy("mService")
3253     ProcessRecord removeProcessNameLocked(final String name, final int uid,
3254             final ProcessRecord expecting) {
3255         ProcessRecord old = mProcessNames.get(name, uid);
3256         final ProcessRecord record = expecting != null ? expecting : old;
3257         synchronized (mProcLock) {
3258             // Only actually remove when the currently recorded value matches the
3259             // record that we expected; if it doesn't match then we raced with a
3260             // newly created process and we don't want to destroy the new one.
3261             if ((expecting == null) || (old == expecting)) {
3262                 mProcessNames.remove(name, uid);
3263             }
3264             if (record != null) {
3265                 final UidRecord uidRecord = record.getUidRecord();
3266                 if (uidRecord != null) {
3267                     uidRecord.removeProcess(record);
3268                     if (uidRecord.getNumOfProcs() == 0) {
3269                         // No more processes using this uid, tell clients it is gone.
3270                         if (DEBUG_UID_OBSERVERS) {
3271                             Slog.i(TAG_UID_OBSERVERS, "No more processes in " + uidRecord);
3272                         }
3273                         mService.enqueueUidChangeLocked(uidRecord, -1,
3274                                 UidRecord.CHANGE_GONE | UidRecord.CHANGE_PROCSTATE);
3275                         EventLogTags.writeAmUidStopped(uid);
3276                         mActiveUids.remove(uid);
3277                         mService.mFgsStartTempAllowList.removeUid(record.info.uid);
3278                         mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
3279                                 ActivityManager.PROCESS_CAPABILITY_NONE);
3280                     }
3281                     record.setUidRecord(null);
3282                 }
3283             }
3284         }
3285         mIsolatedProcesses.remove(uid);
3286         mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
3287         // Remove the (expected) ProcessRecord from the app zygote
3288         if (record != null && record.appZygote) {
3289             removeProcessFromAppZygoteLocked(record);
3290         }
3291         if (record != null && record.isSdkSandbox) {
3292             final int appUid = Process.getAppUidForSdkSandboxUid(uid);
3293             final ArrayList<ProcessRecord> sdkSandboxesForUid = mSdkSandboxes.get(appUid);
3294             if (sdkSandboxesForUid != null) {
3295                 sdkSandboxesForUid.remove(record);
3296                 if (sdkSandboxesForUid.size() == 0) {
3297                     mSdkSandboxes.remove(appUid);
3298                 }
3299             }
3300         }
3301         mAppsInBackgroundRestricted.remove(record);
3302 
3303         return old;
3304     }
3305 
3306     /** Call setCoreSettings on all LRU processes, with the new settings. */
3307     @GuardedBy(anyOf = {"mService", "mProcLock"})
3308     void updateCoreSettingsLOSP(Bundle settings) {
3309         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3310             ProcessRecord processRecord = mLruProcesses.get(i);
3311             final IApplicationThread thread = processRecord.getThread();
3312             try {
3313                 if (thread != null) {
3314                     thread.setCoreSettings(settings);
3315                 }
3316             } catch (RemoteException re) {
3317                 /* ignore */
3318             }
3319         }
3320     }
3321 
3322     /**
3323      * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
3324      * procstate lower than maxProcState.
3325      * @param minTargetSdk
3326      * @param maxProcState
3327      */
3328     @GuardedBy({"mService", "mProcLock"})
3329     void killAllBackgroundProcessesExceptLSP(int minTargetSdk, int maxProcState) {
3330         final ArrayList<ProcessRecord> procs = new ArrayList<>();
3331         final int NP = mProcessNames.getMap().size();
3332         for (int ip = 0; ip < NP; ip++) {
3333             final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3334             final int NA = apps.size();
3335             for (int ia = 0; ia < NA; ia++) {
3336                 final ProcessRecord app = apps.valueAt(ia);
3337                 if (app.isRemoved()
3338                         || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
3339                         && (maxProcState < 0 || app.mState.getSetProcState() > maxProcState))) {
3340                     procs.add(app);
3341                 }
3342             }
3343         }
3344 
3345         final int N = procs.size();
3346         for (int i = 0; i < N; i++) {
3347             removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER,
3348                     ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except");
3349         }
3350     }
3351 
3352     /**
3353      * Call updateTimePrefs on all LRU processes
3354      * @param timePref The time pref to pass to each process
3355      */
3356     @GuardedBy(anyOf = {"mService", "mProcLock"})
3357     void updateAllTimePrefsLOSP(int timePref) {
3358         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3359             ProcessRecord r = mLruProcesses.get(i);
3360             final IApplicationThread thread = r.getThread();
3361             if (thread != null) {
3362                 try {
3363                     thread.updateTimePrefs(timePref);
3364                 } catch (RemoteException ex) {
3365                     Slog.w(TAG, "Failed to update preferences for: "
3366                             + r.info.processName);
3367                 }
3368             }
3369         }
3370     }
3371 
3372     void setAllHttpProxy() {
3373         // Update the HTTP proxy for each application thread.
3374         synchronized (mProcLock) {
3375             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
3376                 ProcessRecord r = mLruProcesses.get(i);
3377                 IApplicationThread thread = r.getThread();
3378                 // Don't dispatch to isolated processes as they can't access ConnectivityManager and
3379                 // don't have network privileges anyway. Exclude system server and update it
3380                 // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
3381                 if (r.getPid() != ActivityManagerService.MY_PID && thread != null && !r.isolated) {
3382                     try {
3383                         thread.updateHttpProxy();
3384                     } catch (RemoteException ex) {
3385                         Slog.w(TAG, "Failed to update http proxy for: "
3386                                 + r.info.processName);
3387                     }
3388                 }
3389             }
3390         }
3391         ActivityThread.updateHttpProxy(mService.mContext);
3392     }
3393 
3394     @GuardedBy(anyOf = {"mService", "mProcLock"})
3395     void clearAllDnsCacheLOSP() {
3396         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3397             ProcessRecord r = mLruProcesses.get(i);
3398             final IApplicationThread thread = r.getThread();
3399             if (thread != null) {
3400                 try {
3401                     thread.clearDnsCache();
3402                 } catch (RemoteException ex) {
3403                     Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
3404                 }
3405             }
3406         }
3407     }
3408 
3409     @GuardedBy(anyOf = {"mService", "mProcLock"})
3410     void handleAllTrustStorageUpdateLOSP() {
3411         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3412             ProcessRecord r = mLruProcesses.get(i);
3413             final IApplicationThread thread = r.getThread();
3414             if (thread != null) {
3415                 try {
3416                     thread.handleTrustStorageUpdate();
3417                 } catch (RemoteException ex) {
3418                     Slog.w(TAG, "Failed to handle trust storage update for: " +
3419                             r.info.processName);
3420                 }
3421             }
3422         }
3423     }
3424 
3425     @GuardedBy({"mService", "mProcLock"})
3426     private int updateLruProcessInternalLSP(ProcessRecord app, long now, int index,
3427             int lruSeq, String what, Object obj, ProcessRecord srcApp) {
3428         app.setLastActivityTime(now);
3429 
3430         if (app.hasActivitiesOrRecentTasks()) {
3431             // Don't want to touch dependent processes that are hosting activities.
3432             return index;
3433         }
3434 
3435         int lrui = mLruProcesses.lastIndexOf(app);
3436         if (lrui < 0) {
3437             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3438                     + what + " " + obj + " from " + srcApp);
3439             return index;
3440         }
3441 
3442         if (lrui >= index) {
3443             // Don't want to cause this to move dependent processes *back* in the
3444             // list as if they were less frequently used.
3445             return index;
3446         }
3447 
3448         if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
3449             // Don't want to touch dependent processes that are hosting activities.
3450             return index;
3451         }
3452 
3453         mLruProcesses.remove(lrui);
3454         if (index > 0) {
3455             index--;
3456         }
3457         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3458                 + " in LRU list: " + app);
3459         mLruProcesses.add(index, app);
3460         app.setLruSeq(lruSeq);
3461         return index;
3462     }
3463 
3464     /**
3465      * Handle the case where we are inserting a process hosting client activities:
3466      * Make sure any groups have their order match their importance, and take care of
3467      * distributing old clients across other activity processes so they can't spam
3468      * the LRU list.  Processing of the list will be restricted by the indices provided,
3469      * and not extend out of them.
3470      *
3471      * @param topApp The app at the top that has just been inserted in to the list.
3472      * @param topI The position in the list where topApp was inserted; this is the start (at the
3473      *             top) where we are going to do our processing.
3474      * @param bottomI The last position at which we will be processing; this is the end position
3475      *                of whichever section of the LRU list we are in.  Nothing past it will be
3476      *                touched.
3477      * @param endIndex The current end of the top being processed.  Typically topI - 1.  That is,
3478      *                 where we are going to start potentially adjusting other entries in the list.
3479      */
3480     @GuardedBy({"mService", "mProcLock"})
3481     private void updateClientActivitiesOrderingLSP(final ProcessRecord topApp, final int topI,
3482             final int bottomI, int endIndex) {
3483         final ProcessServiceRecord topPsr = topApp.mServices;
3484         if (topApp.hasActivitiesOrRecentTasks() || topPsr.isTreatedLikeActivity()
3485                 || !topPsr.hasClientActivities()) {
3486             // If this is not a special process that has client activities, then there is
3487             // nothing to do.
3488             return;
3489         }
3490 
3491         final int uid = topApp.info.uid;
3492         final int topConnectionGroup = topPsr.getConnectionGroup();
3493         if (topConnectionGroup > 0) {
3494             int endImportance = topPsr.getConnectionImportance();
3495             for (int i = endIndex; i >= bottomI; i--) {
3496                 final ProcessRecord subProc = mLruProcesses.get(i);
3497                 final ProcessServiceRecord subPsr = subProc.mServices;
3498                 final int subConnectionGroup = subPsr.getConnectionGroup();
3499                 final int subConnectionImportance = subPsr.getConnectionImportance();
3500                 if (subProc.info.uid == uid
3501                         && subConnectionGroup == topConnectionGroup) {
3502                     if (i == endIndex && subConnectionImportance >= endImportance) {
3503                         // This process is already in the group, and its importance
3504                         // is not as strong as the process before it, so keep it
3505                         // correctly positioned in the group.
3506                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3507                                 "Keeping in-place above " + subProc
3508                                         + " endImportance=" + endImportance
3509                                         + " group=" + subConnectionGroup
3510                                         + " importance=" + subConnectionImportance);
3511                         endIndex--;
3512                         endImportance = subConnectionImportance;
3513                     } else {
3514                         // We want to pull this up to be with the rest of the group,
3515                         // and order within the group by importance.
3516                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3517                                 "Pulling up " + subProc
3518                                         + " to position in group with importance="
3519                                         + subConnectionImportance);
3520                         boolean moved = false;
3521                         for (int pos = topI; pos > endIndex; pos--) {
3522                             final ProcessRecord posProc = mLruProcesses.get(pos);
3523                             if (subConnectionImportance
3524                                     <= posProc.mServices.getConnectionImportance()) {
3525                                 mLruProcesses.remove(i);
3526                                 mLruProcesses.add(pos, subProc);
3527                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3528                                         "Moving " + subProc
3529                                                 + " from position " + i + " to above " + posProc
3530                                                 + " @ " + pos);
3531                                 moved = true;
3532                                 endIndex--;
3533                                 break;
3534                             }
3535                         }
3536                         if (!moved) {
3537                             // Goes to the end of the group.
3538                             mLruProcesses.remove(i);
3539                             mLruProcesses.add(endIndex, subProc);
3540                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3541                                     "Moving " + subProc
3542                                             + " from position " + i + " to end of group @ "
3543                                             + endIndex);
3544                             endIndex--;
3545                             endImportance = subConnectionImportance;
3546                         }
3547                     }
3548                 }
3549             }
3550 
3551         }
3552         // To keep it from spamming the LRU list (by making a bunch of clients),
3553         // we will distribute other entries owned by it to be in-between other apps.
3554         int i = endIndex;
3555         while (i >= bottomI) {
3556             ProcessRecord subProc = mLruProcesses.get(i);
3557             final ProcessServiceRecord subPsr = subProc.mServices;
3558             final int subConnectionGroup = subPsr.getConnectionGroup();
3559             if (DEBUG_LRU) Slog.d(TAG_LRU,
3560                     "Looking to spread old procs, at " + subProc + " @ " + i);
3561             if (subProc.info.uid != uid) {
3562                 // This is a different app...  if we have gone through some of the
3563                 // target app, pull this up to be before them.  We want to pull up
3564                 // one activity process, but any number of non-activity processes.
3565                 if (i < endIndex) {
3566                     boolean hasActivity = false;
3567                     int connUid = 0;
3568                     int connGroup = 0;
3569                     while (i >= bottomI) {
3570                         mLruProcesses.remove(i);
3571                         mLruProcesses.add(endIndex, subProc);
3572                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3573                                 "Different app, moving to " + endIndex);
3574                         i--;
3575                         if (i < bottomI) {
3576                             break;
3577                         }
3578                         subProc = mLruProcesses.get(i);
3579                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3580                                 "Looking at next app at " + i + ": " + subProc);
3581                         if (subProc.hasActivitiesOrRecentTasks()
3582                                 || subPsr.isTreatedLikeActivity()) {
3583                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3584                                     "This is hosting an activity!");
3585                             if (hasActivity) {
3586                                 // Already found an activity, done.
3587                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3588                                         "Already found an activity, done");
3589                                 break;
3590                             }
3591                             hasActivity = true;
3592                         } else if (subPsr.hasClientActivities()) {
3593                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3594                                     "This is a client of an activity");
3595                             if (hasActivity) {
3596                                 if (connUid == 0 || connUid != subProc.info.uid) {
3597                                     // Already have an activity that is not from from a client
3598                                     // connection or is a different client connection, done.
3599                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
3600                                             "Already found a different activity: connUid="
3601                                             + connUid + " uid=" + subProc.info.uid);
3602                                     break;
3603                                 } else if (connGroup == 0 || connGroup != subConnectionGroup) {
3604                                     // Previously saw a different group or not from a group,
3605                                     // want to treat these as different things.
3606                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
3607                                             "Already found a different group: connGroup="
3608                                             + connGroup + " group=" + subConnectionGroup);
3609                                     break;
3610                                 }
3611                             } else {
3612                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3613                                         "This is an activity client!  uid="
3614                                         + subProc.info.uid + " group=" + subConnectionGroup);
3615                                 hasActivity = true;
3616                                 connUid = subProc.info.uid;
3617                                 connGroup = subConnectionGroup;
3618                             }
3619                         }
3620                         endIndex--;
3621                     }
3622                 }
3623                 // Find the end of the next group of processes for target app.  This
3624                 // is after any entries of different apps (so we don't change the existing
3625                 // relative order of apps) and then after the next last group of processes
3626                 // of the target app.
3627                 for (endIndex--; endIndex >= bottomI; endIndex--) {
3628                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
3629                     if (endProc.info.uid == uid) {
3630                         if (DEBUG_LRU) Slog.d(TAG_LRU,
3631                                 "Found next group of app: " + endProc + " @ "
3632                                         + endIndex);
3633                         break;
3634                     }
3635                 }
3636                 if (endIndex >= bottomI) {
3637                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
3638                     final ProcessServiceRecord endPsr = endProc.mServices;
3639                     final int endConnectionGroup = endPsr.getConnectionGroup();
3640                     for (endIndex--; endIndex >= bottomI; endIndex--) {
3641                         final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
3642                         final int nextConnectionGroup = nextEndProc.mServices.getConnectionGroup();
3643                         if (nextEndProc.info.uid != uid
3644                                 || nextConnectionGroup != endConnectionGroup) {
3645                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3646                                     "Found next group or app: " + nextEndProc + " @ "
3647                                             + endIndex + " group=" + nextConnectionGroup);
3648                             break;
3649                         }
3650                     }
3651                 }
3652                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3653                         "Bumping scan position to " + endIndex);
3654                 i = endIndex;
3655             } else {
3656                 i--;
3657             }
3658         }
3659     }
3660 
3661     @GuardedBy("mService")
3662     void updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client) {
3663         final ProcessServiceRecord psr = app.mServices;
3664         final boolean hasActivity = app.hasActivitiesOrRecentTasks() || psr.hasClientActivities()
3665                 || psr.isTreatedLikeActivity();
3666         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3667         if (!activityChange && hasActivity) {
3668             // The process has activities, so we are only allowing activity-based adjustments
3669             // to move it.  It should be kept in the front of the list with other
3670             // processes that have activities, and we don't want those to change their
3671             // order except due to activity operations.
3672             return;
3673         }
3674 
3675         if (app.getPid() == 0 && !app.isPendingStart()) {
3676             // This process has been killed and its cleanup is done, don't proceed the LRU update.
3677             return;
3678         }
3679 
3680         synchronized (mProcLock) {
3681             updateLruProcessLSP(app, client, hasActivity, hasService);
3682         }
3683     }
3684 
3685     @GuardedBy({"mService", "mProcLock"})
3686     private void updateLruProcessLSP(ProcessRecord app, ProcessRecord client,
3687             boolean hasActivity, boolean hasService) {
3688         mLruSeq++;
3689         final long now = SystemClock.uptimeMillis();
3690         final ProcessServiceRecord psr = app.mServices;
3691         app.setLastActivityTime(now);
3692 
3693         // First a quick reject: if the app is already at the position we will
3694         // put it, then there is nothing to do.
3695         if (hasActivity) {
3696             final int N = mLruProcesses.size();
3697             if (N > 0 && mLruProcesses.get(N - 1) == app) {
3698                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3699                 return;
3700             }
3701         } else {
3702             if (mLruProcessServiceStart > 0
3703                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3704                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3705                 return;
3706             }
3707         }
3708 
3709         int lrui = mLruProcesses.lastIndexOf(app);
3710 
3711         if (app.isPersistent() && lrui >= 0) {
3712             // We don't care about the position of persistent processes, as long as
3713             // they are in the list.
3714             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3715             return;
3716         }
3717 
3718         /* In progress: compute new position first, so we can avoid doing work
3719            if the process is not actually going to move.  Not yet working.
3720         int addIndex;
3721         int nextIndex;
3722         boolean inActivity = false, inService = false;
3723         if (hasActivity) {
3724             // Process has activities, put it at the very tipsy-top.
3725             addIndex = mLruProcesses.size();
3726             nextIndex = mLruProcessServiceStart;
3727             inActivity = true;
3728         } else if (hasService) {
3729             // Process has services, put it at the top of the service list.
3730             addIndex = mLruProcessActivityStart;
3731             nextIndex = mLruProcessServiceStart;
3732             inActivity = true;
3733             inService = true;
3734         } else  {
3735             // Process not otherwise of interest, it goes to the top of the non-service area.
3736             addIndex = mLruProcessServiceStart;
3737             if (client != null) {
3738                 int clientIndex = mLruProcesses.lastIndexOf(client);
3739                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3740                         + app);
3741                 if (clientIndex >= 0 && addIndex > clientIndex) {
3742                     addIndex = clientIndex;
3743                 }
3744             }
3745             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3746         }
3747 
3748         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3749                 + mLruProcessActivityStart + "): " + app);
3750         */
3751 
3752         if (lrui >= 0) {
3753             if (lrui < mLruProcessActivityStart) {
3754                 mLruProcessActivityStart--;
3755             }
3756             if (lrui < mLruProcessServiceStart) {
3757                 mLruProcessServiceStart--;
3758             }
3759             /*
3760             if (addIndex > lrui) {
3761                 addIndex--;
3762             }
3763             if (nextIndex > lrui) {
3764                 nextIndex--;
3765             }
3766             */
3767             mLruProcesses.remove(lrui);
3768         }
3769 
3770         /*
3771         mLruProcesses.add(addIndex, app);
3772         if (inActivity) {
3773             mLruProcessActivityStart++;
3774         }
3775         if (inService) {
3776             mLruProcessActivityStart++;
3777         }
3778         */
3779 
3780         int nextIndex;
3781         int nextActivityIndex = -1;
3782         if (hasActivity) {
3783             final int N = mLruProcesses.size();
3784             nextIndex = mLruProcessServiceStart;
3785             if (!app.hasActivitiesOrRecentTasks() && !psr.isTreatedLikeActivity()
3786                     && mLruProcessActivityStart < (N - 1)) {
3787                 // Process doesn't have activities, but has clients with
3788                 // activities...  move it up, but below the app that is binding to it.
3789                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3790                         "Adding to second-top of LRU activity list: " + app
3791                         + " group=" + psr.getConnectionGroup()
3792                         + " importance=" + psr.getConnectionImportance());
3793                 int pos = N - 1;
3794                 while (pos > mLruProcessActivityStart) {
3795                     final ProcessRecord posproc = mLruProcesses.get(pos);
3796                     if (posproc.info.uid == app.info.uid) {
3797                         // Technically this app could have multiple processes with different
3798                         // activities and so we should be looking for the actual process that
3799                         // is bound to the target proc...  but I don't really care, do you?
3800                         break;
3801                     }
3802                     pos--;
3803                 }
3804                 mLruProcesses.add(pos, app);
3805                 // If this process is part of a group, need to pull up any other processes
3806                 // in that group to be with it.
3807                 int endIndex = pos - 1;
3808                 if (endIndex < mLruProcessActivityStart) {
3809                     endIndex = mLruProcessActivityStart;
3810                 }
3811                 nextActivityIndex = endIndex;
3812                 updateClientActivitiesOrderingLSP(app, pos, mLruProcessActivityStart, endIndex);
3813             } else {
3814                 // Process has activities, put it at the very tipsy-top.
3815                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3816                 mLruProcesses.add(app);
3817                 nextActivityIndex = mLruProcesses.size() - 1;
3818             }
3819         } else if (hasService) {
3820             // Process has services, put it at the top of the service list.
3821             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3822             mLruProcesses.add(mLruProcessActivityStart, app);
3823             nextIndex = mLruProcessServiceStart;
3824             mLruProcessActivityStart++;
3825         } else  {
3826             // Process not otherwise of interest, it goes to the top of the non-service area.
3827             int index = mLruProcessServiceStart;
3828             if (client != null) {
3829                 // If there is a client, don't allow the process to be moved up higher
3830                 // in the list than that client.
3831                 int clientIndex = mLruProcesses.lastIndexOf(client);
3832                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3833                         + " when updating " + app);
3834                 if (clientIndex <= lrui) {
3835                     // Don't allow the client index restriction to push it down farther in the
3836                     // list than it already is.
3837                     clientIndex = lrui;
3838                 }
3839                 if (clientIndex >= 0 && index > clientIndex) {
3840                     index = clientIndex;
3841                 }
3842             }
3843             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3844             mLruProcesses.add(index, app);
3845             nextIndex = index - 1;
3846             mLruProcessActivityStart++;
3847             mLruProcessServiceStart++;
3848             if (index > 1) {
3849                 updateClientActivitiesOrderingLSP(app, mLruProcessServiceStart - 1, 0, index - 1);
3850             }
3851         }
3852 
3853         app.setLruSeq(mLruSeq);
3854 
3855         // If the app is currently using a content provider or service,
3856         // bump those processes as well.
3857         for (int j = psr.numberOfConnections() - 1; j >= 0; j--) {
3858             ConnectionRecord cr = psr.getConnectionAt(j);
3859             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3860                     && cr.binding.service.app != null
3861                     && cr.binding.service.app.getLruSeq() != mLruSeq
3862                     && cr.notHasFlag(Context.BIND_REDUCTION_FLAGS)
3863                     && !cr.binding.service.app.isPersistent()) {
3864                 if (cr.binding.service.app.mServices.hasClientActivities()) {
3865                     if (nextActivityIndex >= 0) {
3866                         nextActivityIndex = updateLruProcessInternalLSP(cr.binding.service.app,
3867                                 now,
3868                                 nextActivityIndex, mLruSeq,
3869                                 "service connection", cr, app);
3870                     }
3871                 } else {
3872                     nextIndex = updateLruProcessInternalLSP(cr.binding.service.app,
3873                             now,
3874                             nextIndex, mLruSeq,
3875                             "service connection", cr, app);
3876                 }
3877             }
3878         }
3879         final ProcessProviderRecord ppr = app.mProviders;
3880         for (int j = ppr.numberOfProviderConnections() - 1; j >= 0; j--) {
3881             ContentProviderRecord cpr = ppr.getProviderConnectionAt(j).provider;
3882             if (cpr.proc != null && cpr.proc.getLruSeq() != mLruSeq && !cpr.proc.isPersistent()) {
3883                 nextIndex = updateLruProcessInternalLSP(cpr.proc, now, nextIndex, mLruSeq,
3884                         "provider reference", cpr, app);
3885             }
3886         }
3887     }
3888 
3889     @GuardedBy(anyOf = {"mService", "mProcLock"})
3890     ProcessRecord getLRURecordForAppLOSP(IApplicationThread thread) {
3891         if (thread == null) {
3892             return null;
3893         }
3894         return getLRURecordForAppLOSP(thread.asBinder());
3895     }
3896 
3897     @GuardedBy(anyOf = {"mService", "mProcLock"})
3898     ProcessRecord getLRURecordForAppLOSP(IBinder threadBinder) {
3899         if (threadBinder == null) {
3900             return null;
3901         }
3902         // Find the application record.
3903         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3904             final ProcessRecord rec = mLruProcesses.get(i);
3905             final IApplicationThread t = rec.getThread();
3906             if (t != null && t.asBinder() == threadBinder) {
3907                 return rec;
3908             }
3909         }
3910         return null;
3911     }
3912 
3913     @GuardedBy(anyOf = {"mService", "mProcLock"})
3914     boolean haveBackgroundProcessLOSP() {
3915         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3916             final ProcessRecord rec = mLruProcesses.get(i);
3917             if (rec.getThread() != null
3918                     && rec.mState.getSetProcState() >= PROCESS_STATE_CACHED_ACTIVITY) {
3919                 return true;
3920             }
3921         }
3922         return false;
3923     }
3924 
3925     private static int procStateToImportance(int procState, int memAdj,
3926             ActivityManager.RunningAppProcessInfo currApp,
3927             int clientTargetSdk) {
3928         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
3929                 procState, clientTargetSdk);
3930         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
3931             currApp.lru = memAdj;
3932         } else {
3933             currApp.lru = 0;
3934         }
3935         return imp;
3936     }
3937 
3938     @GuardedBy(anyOf = {"mService", "mProcLock"})
3939     void fillInProcMemInfoLOSP(ProcessRecord app,
3940             ActivityManager.RunningAppProcessInfo outInfo,
3941             int clientTargetSdk) {
3942         outInfo.pid = app.getPid();
3943         outInfo.uid = app.info.uid;
3944         if (app.getWindowProcessController().isHeavyWeightProcess()) {
3945             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
3946         }
3947         if (app.isPersistent()) {
3948             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
3949         }
3950         if (app.hasActivities()) {
3951             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
3952         }
3953         outInfo.lastTrimLevel = app.mProfile.getTrimMemoryLevel();
3954         final ProcessStateRecord state = app.mState;
3955         int adj = state.getCurAdj();
3956         int procState = state.getCurProcState();
3957         outInfo.importance = procStateToImportance(procState, adj, outInfo,
3958                 clientTargetSdk);
3959         outInfo.importanceReasonCode = state.getAdjTypeCode();
3960         outInfo.processState = procState;
3961         outInfo.isFocused = (app == mService.getTopApp());
3962         outInfo.lastActivityTime = app.getLastActivityTime();
3963     }
3964 
3965     @GuardedBy(anyOf = {"mService", "mProcLock"})
3966     List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLOSP(boolean allUsers,
3967             int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3968         // Lazy instantiation of list
3969         List<ActivityManager.RunningAppProcessInfo> runList = null;
3970 
3971         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3972             ProcessRecord app = mLruProcesses.get(i);
3973             final ProcessStateRecord state = app.mState;
3974             final ProcessErrorStateRecord errState = app.mErrorState;
3975             if ((!allUsers && app.userId != userId)
3976                     || (!allUids && app.uid != callingUid)) {
3977                 continue;
3978             }
3979             if ((app.getThread() != null)
3980                     && (!errState.isCrashing() && !errState.isNotResponding())) {
3981                 // Generate process state info for running application
3982                 ActivityManager.RunningAppProcessInfo currApp =
3983                         new ActivityManager.RunningAppProcessInfo(app.processName,
3984                                 app.getPid(), app.getPackageList());
3985                 if (app.getPkgDeps() != null) {
3986                     final int size = app.getPkgDeps().size();
3987                     currApp.pkgDeps = app.getPkgDeps().toArray(new String[size]);
3988                 }
3989                 fillInProcMemInfoLOSP(app, currApp, clientTargetSdk);
3990                 if (state.getAdjSource() instanceof ProcessRecord) {
3991                     currApp.importanceReasonPid = ((ProcessRecord) state.getAdjSource()).getPid();
3992                     currApp.importanceReasonImportance =
3993                             ActivityManager.RunningAppProcessInfo.procStateToImportance(
3994                                     state.getAdjSourceProcState());
3995                 } else if (state.getAdjSource() instanceof ActivityServiceConnectionsHolder) {
3996                     final ActivityServiceConnectionsHolder r =
3997                             (ActivityServiceConnectionsHolder) state.getAdjSource();
3998                     final int pid = r.getActivityPid();
3999                     if (pid != -1) {
4000                         currApp.importanceReasonPid = pid;
4001                     }
4002                 }
4003                 if (state.getAdjTarget() instanceof ComponentName) {
4004                     currApp.importanceReasonComponent = (ComponentName) state.getAdjTarget();
4005                 }
4006                 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
4007                 //        + " lru=" + currApp.lru);
4008                 if (runList == null) {
4009                     runList = new ArrayList<>();
4010                 }
4011                 runList.add(currApp);
4012             }
4013         }
4014         return runList;
4015     }
4016 
4017     @GuardedBy(anyOf = {"mService", "mProcLock"})
4018     int getLruSizeLOSP() {
4019         return mLruProcesses.size();
4020     }
4021 
4022     /**
4023      * Return the reference to the LRU list, call this function for read-only access
4024      */
4025     @GuardedBy(anyOf = {"mService", "mProcLock"})
4026     ArrayList<ProcessRecord> getLruProcessesLOSP() {
4027         return mLruProcesses;
4028     }
4029 
4030     /**
4031      * Return the reference to the LRU list, call this function for read/write access
4032      */
4033     @GuardedBy({"mService", "mProcLock"})
4034     ArrayList<ProcessRecord> getLruProcessesLSP() {
4035         return mLruProcesses;
4036     }
4037 
4038     /**
4039      * For test only
4040      */
4041     @VisibleForTesting
4042     @GuardedBy({"mService", "mProcLock"})
4043     void setLruProcessServiceStartLSP(int pos) {
4044         mLruProcessServiceStart = pos;
4045     }
4046 
4047     @GuardedBy(anyOf = {"mService", "mProcLock"})
4048     int getLruProcessServiceStartLOSP() {
4049         return mLruProcessServiceStart;
4050     }
4051 
4052     /**
4053      * Iterate the whole LRU list, invoke the given {@code callback} with each of the ProcessRecord
4054      * in that list.
4055      *
4056      * @param iterateForward If {@code true}, iterate the LRU list from the least recent used
4057      *                       to most recent used ProcessRecord.
4058      * @param callback The callback interface to accept the current ProcessRecord.
4059      */
4060     @GuardedBy(anyOf = {"mService", "mProcLock"})
4061     void forEachLruProcessesLOSP(boolean iterateForward,
4062             @NonNull Consumer<ProcessRecord> callback) {
4063         if (iterateForward) {
4064             for (int i = 0, size = mLruProcesses.size(); i < size; i++) {
4065                 callback.accept(mLruProcesses.get(i));
4066             }
4067         } else {
4068             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4069                 callback.accept(mLruProcesses.get(i));
4070             }
4071         }
4072     }
4073 
4074     /**
4075      * Search in the LRU list, invoke the given {@code callback} with each of the ProcessRecord
4076      * in that list; if the callback returns a non-null object, halt the search, return that
4077      * object as the return value of this search function.
4078      *
4079      * @param iterateForward If {@code true}, iterate the LRU list from the least recent used
4080      *                       to most recent used ProcessRecord.
4081      * @param callback The callback interface to accept the current ProcessRecord; if it returns
4082      *                 a non-null object, the search will be halted and this object will be used
4083      *                 as the return value of this search function.
4084      */
4085     @GuardedBy(anyOf = {"mService", "mProcLock"})
4086     <R> R searchEachLruProcessesLOSP(boolean iterateForward,
4087             @NonNull Function<ProcessRecord, R> callback) {
4088         if (iterateForward) {
4089             for (int i = 0, size = mLruProcesses.size(); i < size; i++) {
4090                 R r;
4091                 if ((r = callback.apply(mLruProcesses.get(i))) != null) {
4092                     return r;
4093                 }
4094             }
4095         } else {
4096             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4097                 R r;
4098                 if ((r = callback.apply(mLruProcesses.get(i))) != null) {
4099                     return r;
4100                 }
4101             }
4102         }
4103         return null;
4104     }
4105 
4106     @GuardedBy(anyOf = {"mService", "mProcLock"})
4107     boolean isInLruListLOSP(ProcessRecord app) {
4108         return mLruProcesses.contains(app);
4109     }
4110 
4111     @GuardedBy(anyOf = {"mService", "mProcLock"})
4112     int getLruSeqLOSP() {
4113         return mLruSeq;
4114     }
4115 
4116     @GuardedBy(anyOf = {"mService", "mProcLock"})
4117     MyProcessMap getProcessNamesLOSP() {
4118         return mProcessNames;
4119     }
4120 
4121     @GuardedBy("mService")
4122     void dumpLruListHeaderLocked(PrintWriter pw) {
4123         pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
4124         pw.print(" total, non-act at ");
4125         pw.print(mLruProcesses.size() - mLruProcessActivityStart);
4126         pw.print(", non-svc at ");
4127         pw.print(mLruProcesses.size() - mLruProcessServiceStart);
4128         pw.println("):");
4129     }
4130 
4131     @GuardedBy("mService")
4132     private void dumpLruEntryLocked(PrintWriter pw, int index, ProcessRecord proc, String prefix) {
4133         pw.print(prefix);
4134         pw.print('#');
4135         if (index < 10) {
4136             pw.print(' ');
4137         }
4138         pw.print(index);
4139         pw.print(": ");
4140         pw.print(makeOomAdjString(proc.mState.getSetAdj(), false));
4141         pw.print(' ');
4142         pw.print(makeProcStateString(proc.mState.getCurProcState()));
4143         pw.print(' ');
4144         ActivityManager.printCapabilitiesSummary(pw, proc.mState.getCurCapability());
4145         pw.print(' ');
4146         pw.print(proc.toShortString());
4147         final ProcessServiceRecord psr = proc.mServices;
4148         if (proc.hasActivitiesOrRecentTasks() || psr.hasClientActivities()
4149                 || psr.isTreatedLikeActivity()) {
4150             pw.print(" act:");
4151             boolean printed = false;
4152             if (proc.hasActivities()) {
4153                 pw.print("activities");
4154                 printed = true;
4155             }
4156             if (proc.hasRecentTasks()) {
4157                 if (printed) {
4158                     pw.print("|");
4159                 }
4160                 pw.print("recents");
4161                 printed = true;
4162             }
4163             if (psr.hasClientActivities()) {
4164                 if (printed) {
4165                     pw.print("|");
4166                 }
4167                 pw.print("client");
4168                 printed = true;
4169             }
4170             if (psr.isTreatedLikeActivity()) {
4171                 if (printed) {
4172                     pw.print("|");
4173                 }
4174                 pw.print("treated");
4175             }
4176         }
4177         pw.println();
4178     }
4179 
4180     @GuardedBy("mService")
4181     boolean dumpLruLocked(PrintWriter pw, String dumpPackage, String prefix) {
4182         final int lruSize = mLruProcesses.size();
4183         final String innerPrefix;
4184         if (prefix == null) {
4185             pw.println("ACTIVITY MANAGER LRU PROCESSES (dumpsys activity lru)");
4186             innerPrefix = "  ";
4187         } else {
4188             boolean haveAny = false;
4189             for (int i = lruSize - 1; i >= 0; i--) {
4190                 final ProcessRecord r = mLruProcesses.get(i);
4191                 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4192                     continue;
4193                 }
4194                 haveAny = true;
4195                 break;
4196             }
4197             if (!haveAny) {
4198                 return false;
4199             }
4200             pw.print(prefix);
4201             pw.println("Raw LRU list (dumpsys activity lru):");
4202             innerPrefix = prefix + "  ";
4203         }
4204         int i;
4205         boolean first = true;
4206         for (i = lruSize - 1; i >= mLruProcessActivityStart; i--) {
4207             final ProcessRecord r = mLruProcesses.get(i);
4208             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4209                 continue;
4210             }
4211             if (first) {
4212                 pw.print(innerPrefix);
4213                 pw.println("Activities:");
4214                 first = false;
4215             }
4216             dumpLruEntryLocked(pw, i, r, innerPrefix);
4217         }
4218         first = true;
4219         for (; i >= mLruProcessServiceStart; i--) {
4220             final ProcessRecord r = mLruProcesses.get(i);
4221             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4222                 continue;
4223             }
4224             if (first) {
4225                 pw.print(innerPrefix);
4226                 pw.println("Services:");
4227                 first = false;
4228             }
4229             dumpLruEntryLocked(pw, i, r, innerPrefix);
4230         }
4231         first = true;
4232         for (; i >= 0; i--) {
4233             final ProcessRecord r = mLruProcesses.get(i);
4234             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4235                 continue;
4236             }
4237             if (first) {
4238                 pw.print(innerPrefix);
4239                 pw.println("Other:");
4240                 first = false;
4241             }
4242             dumpLruEntryLocked(pw, i, r, innerPrefix);
4243         }
4244         return true;
4245     }
4246 
4247     @GuardedBy({"mService", "mProcLock"})
4248     void dumpProcessesLSP(FileDescriptor fd, PrintWriter pw, String[] args,
4249             int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
4250         boolean needSep = false;
4251         int numPers = 0;
4252 
4253         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
4254 
4255         if (dumpAll || dumpPackage != null) {
4256             final int numOfNames = mProcessNames.getMap().size();
4257             for (int ip = 0; ip < numOfNames; ip++) {
4258                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
4259                 for (int ia = 0, size = procs.size(); ia < size; ia++) {
4260                     ProcessRecord r = procs.valueAt(ia);
4261                     if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4262                         continue;
4263                     }
4264                     if (!needSep) {
4265                         pw.println("  All known processes:");
4266                         needSep = true;
4267                     }
4268                     pw.print(r.isPersistent() ? "  *PERS*" : "  *APP*");
4269                     pw.print(" UID "); pw.print(procs.keyAt(ia));
4270                     pw.print(" "); pw.println(r);
4271                     r.dump(pw, "    ");
4272                     if (r.isPersistent()) {
4273                         numPers++;
4274                     }
4275                 }
4276             }
4277         }
4278 
4279         if (mIsolatedProcesses.size() > 0) {
4280             boolean printed = false;
4281             for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
4282                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
4283                 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4284                     continue;
4285                 }
4286                 if (!printed) {
4287                     if (needSep) {
4288                         pw.println();
4289                     }
4290                     pw.println("  Isolated process list (sorted by uid):");
4291                     printed = true;
4292                     needSep = true;
4293                 }
4294                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
4295                 pw.println(r);
4296             }
4297         }
4298 
4299         needSep = mService.dumpActiveInstruments(pw, dumpPackage, needSep);
4300 
4301         if (dumpOomLocked(fd, pw, needSep, args, opti, dumpAll, dumpPackage, false)) {
4302             needSep = true;
4303         }
4304 
4305         if (mActiveUids.size() > 0) {
4306             needSep |= mActiveUids.dump(pw, dumpPackage, dumpAppId,
4307                     "UID states:", needSep);
4308         }
4309 
4310         if (dumpAll) {
4311             needSep |= mService.mUidObserverController.dumpValidateUids(pw,
4312                     dumpPackage, dumpAppId, "UID validation:", needSep);
4313         }
4314 
4315         if (needSep) {
4316             pw.println();
4317         }
4318         if (dumpLruLocked(pw, dumpPackage, "  ")) {
4319             needSep = true;
4320         }
4321 
4322         if (getLruSizeLOSP() > 0) {
4323             if (needSep) {
4324                 pw.println();
4325             }
4326             dumpLruListHeaderLocked(pw);
4327             dumpProcessOomList(pw, mService, mLruProcesses, "    ", "Proc", "PERS", false,
4328                     dumpPackage);
4329             needSep = true;
4330         }
4331 
4332         mService.dumpOtherProcessesInfoLSP(fd, pw, dumpAll, dumpPackage, dumpAppId, numPers,
4333                 needSep);
4334     }
4335 
4336     @GuardedBy({"mService", "mProcLock"})
4337     void writeProcessesToProtoLSP(ProtoOutputStream proto, String dumpPackage) {
4338         int numPers = 0;
4339 
4340         final int numOfNames = mProcessNames.getMap().size();
4341         for (int ip = 0; ip < numOfNames; ip++) {
4342             SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
4343             for (int ia = 0, size = procs.size(); ia < size; ia++) {
4344                 ProcessRecord r = procs.valueAt(ia);
4345                 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4346                     continue;
4347                 }
4348                 r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.PROCS,
4349                         mLruProcesses.indexOf(r)
4350                 );
4351                 if (r.isPersistent()) {
4352                     numPers++;
4353                 }
4354             }
4355         }
4356 
4357         for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) {
4358             ProcessRecord r = mIsolatedProcesses.valueAt(i);
4359             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4360                 continue;
4361             }
4362             r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS,
4363                     mLruProcesses.indexOf(r)
4364             );
4365         }
4366 
4367         final int dumpAppId = mService.getAppId(dumpPackage);
4368         mActiveUids.dumpProto(proto, dumpPackage, dumpAppId,
4369                 ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
4370 
4371         if (getLruSizeLOSP() > 0) {
4372             long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
4373             int total = getLruSizeLOSP();
4374             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
4375             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT,
4376                     total - mLruProcessActivityStart);
4377             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT,
4378                     total - mLruProcessServiceStart);
4379             writeProcessOomListToProto(proto,
4380                     ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, mService,
4381                     mLruProcesses, true, dumpPackage);
4382             proto.end(lruToken);
4383         }
4384 
4385         mService.writeOtherProcessesInfoToProtoLSP(proto, dumpPackage, dumpAppId, numPers);
4386     }
4387 
4388     private static ArrayList<Pair<ProcessRecord, Integer>> sortProcessOomList(
4389             List<ProcessRecord> origList, String dumpPackage) {
4390         ArrayList<Pair<ProcessRecord, Integer>> list =
4391                 new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
4392         for (int i = 0, size = origList.size(); i < size; i++) {
4393             ProcessRecord r = origList.get(i);
4394             if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) {
4395                 continue;
4396             }
4397             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
4398         }
4399 
4400         Comparator<Pair<ProcessRecord, Integer>> comparator =
4401                 new Comparator<Pair<ProcessRecord, Integer>>() {
4402             @Override
4403             public int compare(Pair<ProcessRecord, Integer> object1,
4404                     Pair<ProcessRecord, Integer> object2) {
4405                 final int adj = object2.first.mState.getSetAdj() - object1.first.mState.getSetAdj();
4406                 if (adj != 0) {
4407                     return adj;
4408                 }
4409                 final int procState = object2.first.mState.getSetProcState()
4410                         - object1.first.mState.getSetProcState();
4411                 if (procState != 0) {
4412                     return procState;
4413                 }
4414                 final int val = object2.second - object1.second;
4415                 if (val != 0) {
4416                     return val;
4417                 }
4418                 return 0;
4419             }
4420         };
4421 
4422         Collections.sort(list, comparator);
4423         return list;
4424     }
4425 
4426     private static boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
4427             ActivityManagerService service, List<ProcessRecord> origList,
4428             boolean inclDetails, String dumpPackage) {
4429         ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
4430         if (list.isEmpty()) return false;
4431 
4432         final long curUptime = SystemClock.uptimeMillis();
4433 
4434         for (int i = list.size() - 1; i >= 0; i--) {
4435             ProcessRecord r = list.get(i).first;
4436             final ProcessStateRecord state = r.mState;
4437             final ProcessServiceRecord psr = r.mServices;
4438             long token = proto.start(fieldId);
4439             String oomAdj = makeOomAdjString(state.getSetAdj(), true);
4440             proto.write(ProcessOomProto.PERSISTENT, r.isPersistent());
4441             proto.write(ProcessOomProto.NUM, (origList.size() - 1) - list.get(i).second);
4442             proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
4443             int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
4444             switch (state.getSetSchedGroup()) {
4445                 case SCHED_GROUP_BACKGROUND:
4446                     schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
4447                     break;
4448                 case SCHED_GROUP_DEFAULT:
4449                     schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
4450                     break;
4451                 case SCHED_GROUP_TOP_APP:
4452                     schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
4453                     break;
4454                 case SCHED_GROUP_TOP_APP_BOUND:
4455                     schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
4456                     break;
4457             }
4458             if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
4459                 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
4460             }
4461             if (state.hasForegroundActivities()) {
4462                 proto.write(ProcessOomProto.ACTIVITIES, true);
4463             } else if (psr.hasForegroundServices()) {
4464                 proto.write(ProcessOomProto.SERVICES, true);
4465             }
4466             proto.write(ProcessOomProto.STATE,
4467                     makeProcStateProtoEnum(state.getCurProcState()));
4468             proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.mProfile.getTrimMemoryLevel());
4469             r.dumpDebug(proto, ProcessOomProto.PROC);
4470             proto.write(ProcessOomProto.ADJ_TYPE, state.getAdjType());
4471             if (state.getAdjSource() != null || state.getAdjTarget() != null) {
4472                 if (state.getAdjTarget() instanceof  ComponentName) {
4473                     ComponentName cn = (ComponentName) state.getAdjTarget();
4474                     cn.dumpDebug(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
4475                 } else if (state.getAdjTarget() != null) {
4476                     proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, state.getAdjTarget().toString());
4477                 }
4478                 if (state.getAdjSource() instanceof ProcessRecord) {
4479                     ProcessRecord p = (ProcessRecord) state.getAdjSource();
4480                     p.dumpDebug(proto, ProcessOomProto.ADJ_SOURCE_PROC);
4481                 } else if (state.getAdjSource() != null) {
4482                     proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, state.getAdjSource().toString());
4483                 }
4484             }
4485             if (inclDetails) {
4486                 long detailToken = proto.start(ProcessOomProto.DETAIL);
4487                 proto.write(ProcessOomProto.Detail.MAX_ADJ, state.getMaxAdj());
4488                 proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, state.getCurRawAdj());
4489                 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, state.getSetRawAdj());
4490                 proto.write(ProcessOomProto.Detail.CUR_ADJ, state.getCurAdj());
4491                 proto.write(ProcessOomProto.Detail.SET_ADJ, state.getSetAdj());
4492                 proto.write(ProcessOomProto.Detail.CURRENT_STATE,
4493                         makeProcStateProtoEnum(state.getCurProcState()));
4494                 proto.write(ProcessOomProto.Detail.SET_STATE,
4495                         makeProcStateProtoEnum(state.getSetProcState()));
4496                 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
4497                         r.mProfile.getLastPss() * 1024, new StringBuilder()));
4498                 proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
4499                         r.mProfile.getLastSwapPss() * 1024, new StringBuilder()));
4500                 proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
4501                         r.mProfile.getLastCachedPss() * 1024, new StringBuilder()));
4502                 proto.write(ProcessOomProto.Detail.CACHED, state.isCached());
4503                 proto.write(ProcessOomProto.Detail.EMPTY, state.isEmpty());
4504                 proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, psr.hasAboveClient());
4505 
4506                 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
4507                     long lastCpuTime = r.mProfile.mLastCpuTime.get();
4508                     long uptimeSince = curUptime - service.mLastPowerCheckUptime;
4509                     if (lastCpuTime != 0 && uptimeSince > 0) {
4510                         long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime;
4511                         long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
4512                         proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
4513                         proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
4514                         proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
4515                                 (100.0 * timeUsed) / uptimeSince);
4516                         proto.end(cpuTimeToken);
4517                     }
4518                 }
4519                 proto.end(detailToken);
4520             }
4521             proto.end(token);
4522         }
4523 
4524         return true;
4525     }
4526 
4527     private static boolean dumpProcessOomList(PrintWriter pw,
4528             ActivityManagerService service, List<ProcessRecord> origList,
4529             String prefix, String normalLabel, String persistentLabel,
4530             boolean inclDetails, String dumpPackage) {
4531 
4532         ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
4533         if (list.isEmpty()) return false;
4534 
4535         final long curUptime = SystemClock.uptimeMillis();
4536         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
4537 
4538         for (int i = list.size() - 1; i >= 0; i--) {
4539             ProcessRecord r = list.get(i).first;
4540             final ProcessStateRecord state = r.mState;
4541             final ProcessServiceRecord psr = r.mServices;
4542             String oomAdj = makeOomAdjString(state.getSetAdj(), false);
4543             char schedGroup;
4544             switch (state.getSetSchedGroup()) {
4545                 case SCHED_GROUP_BACKGROUND:
4546                     schedGroup = 'b';
4547                     break;
4548                 case SCHED_GROUP_DEFAULT:
4549                     schedGroup = 'F';
4550                     break;
4551                 case SCHED_GROUP_TOP_APP:
4552                     schedGroup = 'T';
4553                     break;
4554                 case SCHED_GROUP_RESTRICTED:
4555                     schedGroup = 'R';
4556                     break;
4557                 case SCHED_GROUP_TOP_APP_BOUND:
4558                     schedGroup = 'B';
4559                     break;
4560                 default:
4561                     schedGroup = '?';
4562                     break;
4563             }
4564             char foreground;
4565             if (state.hasForegroundActivities()) {
4566                 foreground = 'A';
4567             } else if (psr.hasForegroundServices()) {
4568                 foreground = 'S';
4569             } else {
4570                 foreground = ' ';
4571             }
4572             String procState = makeProcStateString(state.getCurProcState());
4573             pw.print(prefix);
4574             pw.print(r.isPersistent() ? persistentLabel : normalLabel);
4575             pw.print(" #");
4576             int num = (origList.size() - 1) - list.get(i).second;
4577             if (num < 10) pw.print(' ');
4578             pw.print(num);
4579             pw.print(": ");
4580             pw.print(oomAdj);
4581             pw.print(' ');
4582             pw.print(schedGroup);
4583             pw.print('/');
4584             pw.print(foreground);
4585             pw.print('/');
4586             pw.print(procState);
4587             pw.print(' ');
4588             ActivityManager.printCapabilitiesSummary(pw, state.getCurCapability());
4589             pw.print(' ');
4590             pw.print(" t:");
4591             if (r.mProfile.getTrimMemoryLevel() < 10) pw.print(' ');
4592             pw.print(r.mProfile.getTrimMemoryLevel());
4593             pw.print(' ');
4594             pw.print(r.toShortString());
4595             pw.print(" (");
4596             pw.print(state.getAdjType());
4597             pw.println(')');
4598             if (state.getAdjSource() != null || state.getAdjTarget() != null) {
4599                 pw.print(prefix);
4600                 pw.print("    ");
4601                 if (state.getAdjTarget() instanceof ComponentName) {
4602                     pw.print(((ComponentName) state.getAdjTarget()).flattenToShortString());
4603                 } else if (state.getAdjTarget() != null) {
4604                     pw.print(state.getAdjTarget().toString());
4605                 } else {
4606                     pw.print("{null}");
4607                 }
4608                 pw.print("<=");
4609                 if (state.getAdjSource() instanceof ProcessRecord) {
4610                     pw.print("Proc{");
4611                     pw.print(((ProcessRecord) state.getAdjSource()).toShortString());
4612                     pw.println("}");
4613                 } else if (state.getAdjSource() != null) {
4614                     pw.println(state.getAdjSource().toString());
4615                 } else {
4616                     pw.println("{null}");
4617                 }
4618             }
4619             if (inclDetails) {
4620                 pw.print(prefix);
4621                 pw.print("    ");
4622                 pw.print("oom: max="); pw.print(state.getMaxAdj());
4623                 pw.print(" curRaw="); pw.print(state.getCurRawAdj());
4624                 pw.print(" setRaw="); pw.print(state.getSetRawAdj());
4625                 pw.print(" cur="); pw.print(state.getCurAdj());
4626                 pw.print(" set="); pw.println(state.getSetAdj());
4627                 pw.print(prefix);
4628                 pw.print("    ");
4629                 pw.print("state: cur="); pw.print(makeProcStateString(state.getCurProcState()));
4630                 pw.print(" set="); pw.print(makeProcStateString(state.getSetProcState()));
4631                 pw.print(" lastPss=");
4632                 DebugUtils.printSizeValue(pw, r.mProfile.getLastPss() * 1024);
4633                 pw.print(" lastSwapPss=");
4634                 DebugUtils.printSizeValue(pw, r.mProfile.getLastSwapPss() * 1024);
4635                 pw.print(" lastCachedPss=");
4636                 DebugUtils.printSizeValue(pw, r.mProfile.getLastCachedPss() * 1024);
4637                 pw.println();
4638                 pw.print(prefix);
4639                 pw.print("    ");
4640                 pw.print("cached="); pw.print(state.isCached());
4641                 pw.print(" empty="); pw.print(state.isEmpty());
4642                 pw.print(" hasAboveClient="); pw.println(psr.hasAboveClient());
4643 
4644                 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
4645                     long lastCpuTime = r.mProfile.mLastCpuTime.get();
4646                     if (lastCpuTime != 0 && uptimeSince > 0) {
4647                         long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime;
4648                         pw.print(prefix);
4649                         pw.print("    ");
4650                         pw.print("run cpu over ");
4651                         TimeUtils.formatDuration(uptimeSince, pw);
4652                         pw.print(" used ");
4653                         TimeUtils.formatDuration(timeUsed, pw);
4654                         pw.print(" (");
4655                         pw.print((timeUsed * 100) / uptimeSince);
4656                         pw.println("%)");
4657                     }
4658                 }
4659             }
4660         }
4661         return true;
4662     }
4663 
4664     private void printOomLevel(PrintWriter pw, String name, int adj) {
4665         pw.print("    ");
4666         if (adj >= 0) {
4667             pw.print(' ');
4668             if (adj < 10) pw.print(' ');
4669         } else {
4670             if (adj > -10) pw.print(' ');
4671         }
4672         pw.print(adj);
4673         pw.print(": ");
4674         pw.print(name);
4675         pw.print(" (");
4676         pw.print(ActivityManagerService.stringifySize(getMemLevel(adj), 1024));
4677         pw.println(")");
4678     }
4679 
4680     @GuardedBy("mService")
4681     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String[] args,
4682             int opti, boolean dumpAll, String dumpPackage, boolean inclGc) {
4683         if (getLruSizeLOSP() > 0) {
4684             if (needSep) pw.println();
4685             needSep = true;
4686             pw.println("  OOM levels:");
4687             printOomLevel(pw, "SYSTEM_ADJ", SYSTEM_ADJ);
4688             printOomLevel(pw, "PERSISTENT_PROC_ADJ", PERSISTENT_PROC_ADJ);
4689             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", PERSISTENT_SERVICE_ADJ);
4690             printOomLevel(pw, "FOREGROUND_APP_ADJ", FOREGROUND_APP_ADJ);
4691             printOomLevel(pw, "VISIBLE_APP_ADJ", VISIBLE_APP_ADJ);
4692             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", PERCEPTIBLE_APP_ADJ);
4693             printOomLevel(pw, "PERCEPTIBLE_MEDIUM_APP_ADJ", PERCEPTIBLE_MEDIUM_APP_ADJ);
4694             printOomLevel(pw, "PERCEPTIBLE_LOW_APP_ADJ", PERCEPTIBLE_LOW_APP_ADJ);
4695             printOomLevel(pw, "BACKUP_APP_ADJ", BACKUP_APP_ADJ);
4696             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", HEAVY_WEIGHT_APP_ADJ);
4697             printOomLevel(pw, "SERVICE_ADJ", SERVICE_ADJ);
4698             printOomLevel(pw, "HOME_APP_ADJ", HOME_APP_ADJ);
4699             printOomLevel(pw, "PREVIOUS_APP_ADJ", PREVIOUS_APP_ADJ);
4700             printOomLevel(pw, "SERVICE_B_ADJ", SERVICE_B_ADJ);
4701             printOomLevel(pw, "CACHED_APP_MIN_ADJ", CACHED_APP_MIN_ADJ);
4702             printOomLevel(pw, "CACHED_APP_MAX_ADJ", CACHED_APP_MAX_ADJ);
4703 
4704             if (needSep) pw.println();
4705             pw.print("  Process OOM control ("); pw.print(getLruSizeLOSP());
4706             pw.print(" total, non-act at ");
4707             pw.print(getLruSizeLOSP() - mLruProcessActivityStart);
4708             pw.print(", non-svc at ");
4709             pw.print(getLruSizeLOSP() - mLruProcessServiceStart);
4710             pw.println("):");
4711             dumpProcessOomList(pw, mService, mLruProcesses,
4712                     "    ", "Proc", "PERS", true, dumpPackage);
4713             needSep = true;
4714         }
4715 
4716         synchronized (mService.mAppProfiler.mProfilerLock) {
4717             mService.mAppProfiler.dumpProcessesToGc(pw, needSep, dumpPackage);
4718         }
4719 
4720         pw.println();
4721         mService.mAtmInternal.dumpForOom(pw);
4722 
4723         return true;
4724     }
4725 
4726     void registerProcessObserver(IProcessObserver observer) {
4727         mProcessObservers.register(observer);
4728     }
4729 
4730     void unregisterProcessObserver(IProcessObserver observer) {
4731         mProcessObservers.unregister(observer);
4732     }
4733 
4734     void dispatchProcessesChanged() {
4735         int numOfChanges;
4736         synchronized (mProcessChangeLock) {
4737             numOfChanges = mPendingProcessChanges.size();
4738             if (mActiveProcessChanges.length < numOfChanges) {
4739                 mActiveProcessChanges = new ProcessChangeItem[numOfChanges];
4740             }
4741             mPendingProcessChanges.toArray(mActiveProcessChanges);
4742             mPendingProcessChanges.clear();
4743             if (DEBUG_PROCESS_OBSERVERS) {
4744                 Slog.i(TAG_PROCESS_OBSERVERS,
4745                         "*** Delivering " + numOfChanges + " process changes");
4746             }
4747         }
4748 
4749         int i = mProcessObservers.beginBroadcast();
4750         while (i > 0) {
4751             i--;
4752             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4753             if (observer != null) {
4754                 try {
4755                     for (int j = 0; j < numOfChanges; j++) {
4756                         ProcessChangeItem item = mActiveProcessChanges[j];
4757                         if ((item.changes & ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4758                             if (DEBUG_PROCESS_OBSERVERS) {
4759                                 Slog.i(TAG_PROCESS_OBSERVERS,
4760                                         "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4761                                         + item.uid + ": " + item.foregroundActivities);
4762                             }
4763                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4764                                     item.foregroundActivities);
4765                         }
4766                         if ((item.changes & ProcessChangeItem.CHANGE_FOREGROUND_SERVICES) != 0) {
4767                             if (DEBUG_PROCESS_OBSERVERS) {
4768                                 Slog.i(TAG_PROCESS_OBSERVERS,
4769                                         "FOREGROUND SERVICES CHANGED pid=" + item.pid + " uid="
4770                                         + item.uid + ": " + item.foregroundServiceTypes);
4771                             }
4772                             observer.onForegroundServicesChanged(item.pid, item.uid,
4773                                     item.foregroundServiceTypes);
4774                         }
4775                     }
4776                 } catch (RemoteException e) {
4777                 }
4778             }
4779         }
4780         mProcessObservers.finishBroadcast();
4781 
4782         synchronized (mProcessChangeLock) {
4783             for (int j = 0; j < numOfChanges; j++) {
4784                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4785             }
4786         }
4787     }
4788 
4789     @GuardedBy("mService")
4790     ProcessChangeItem enqueueProcessChangeItemLocked(int pid, int uid) {
4791         synchronized (mProcessChangeLock) {
4792             int i = mPendingProcessChanges.size() - 1;
4793             ActivityManagerService.ProcessChangeItem item = null;
4794             while (i >= 0) {
4795                 item = mPendingProcessChanges.get(i);
4796                 if (item.pid == pid) {
4797                     if (DEBUG_PROCESS_OBSERVERS) {
4798                         Slog.i(TAG_PROCESS_OBSERVERS, "Re-using existing item: " + item);
4799                     }
4800                     break;
4801                 }
4802                 i--;
4803             }
4804 
4805             if (i < 0) {
4806                 // No existing item in pending changes; need a new one.
4807                 final int num = mAvailProcessChanges.size();
4808                 if (num > 0) {
4809                     item = mAvailProcessChanges.remove(num - 1);
4810                     if (DEBUG_PROCESS_OBSERVERS) {
4811                         Slog.i(TAG_PROCESS_OBSERVERS, "Retrieving available item: " + item);
4812                     }
4813                 } else {
4814                     item = new ActivityManagerService.ProcessChangeItem();
4815                     if (DEBUG_PROCESS_OBSERVERS) {
4816                         Slog.i(TAG_PROCESS_OBSERVERS, "Allocating new item: " + item);
4817                     }
4818                 }
4819                 item.changes = 0;
4820                 item.pid = pid;
4821                 item.uid = uid;
4822                 if (mPendingProcessChanges.size() == 0) {
4823                     if (DEBUG_PROCESS_OBSERVERS) {
4824                         Slog.i(TAG_PROCESS_OBSERVERS, "*** Enqueueing dispatch processes changed!");
4825                     }
4826                     mService.mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG)
4827                             .sendToTarget();
4828                 }
4829                 mPendingProcessChanges.add(item);
4830             }
4831 
4832             return item;
4833         }
4834     }
4835 
4836     @GuardedBy("mService")
4837     void scheduleDispatchProcessDiedLocked(int pid, int uid) {
4838         synchronized (mProcessChangeLock) {
4839             for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
4840                 ProcessChangeItem item = mPendingProcessChanges.get(i);
4841                 if (pid > 0 && item.pid == pid) {
4842                     mPendingProcessChanges.remove(i);
4843                     mAvailProcessChanges.add(item);
4844                 }
4845             }
4846             mService.mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, pid, uid,
4847                     null).sendToTarget();
4848         }
4849     }
4850 
4851     void dispatchProcessDied(int pid, int uid) {
4852         int i = mProcessObservers.beginBroadcast();
4853         while (i > 0) {
4854             i--;
4855             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4856             if (observer != null) {
4857                 try {
4858                     observer.onProcessDied(pid, uid);
4859                 } catch (RemoteException e) {
4860                 }
4861             }
4862         }
4863         mProcessObservers.finishBroadcast();
4864     }
4865 
4866     @GuardedBy(anyOf = {"mService", "mProcLock"})
4867     ArrayList<ProcessRecord> collectProcessesLOSP(int start, boolean allPkgs, String[] args) {
4868         ArrayList<ProcessRecord> procs;
4869         if (args != null && args.length > start
4870                 && args[start].charAt(0) != '-') {
4871             procs = new ArrayList<ProcessRecord>();
4872             int pid = -1;
4873             try {
4874                 pid = Integer.parseInt(args[start]);
4875             } catch (NumberFormatException e) {
4876             }
4877             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4878                 ProcessRecord proc = mLruProcesses.get(i);
4879                 if (proc.getPid() > 0 && proc.getPid() == pid) {
4880                     procs.add(proc);
4881                 } else if (allPkgs && proc.getPkgList() != null
4882                         && proc.getPkgList().containsKey(args[start])) {
4883                     procs.add(proc);
4884                 } else if (proc.processName.equals(args[start])) {
4885                     procs.add(proc);
4886                 }
4887             }
4888             if (procs.size() <= 0) {
4889                 return null;
4890             }
4891         } else {
4892             procs = new ArrayList<ProcessRecord>(mLruProcesses);
4893         }
4894         return procs;
4895     }
4896 
4897     @GuardedBy(anyOf = {"mService", "mProcLock"})
4898     void updateApplicationInfoLOSP(List<String> packagesToUpdate, int userId,
4899             boolean updateFrameworkRes) {
4900         final ArrayList<WindowProcessController> targetProcesses = new ArrayList<>();
4901         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4902             final ProcessRecord app = mLruProcesses.get(i);
4903             if (app.getThread() == null) {
4904                 continue;
4905             }
4906 
4907             if (userId != UserHandle.USER_ALL && app.userId != userId) {
4908                 continue;
4909             }
4910 
4911             app.getPkgList().forEachPackage(packageName -> {
4912                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
4913                     try {
4914                         final ApplicationInfo ai = AppGlobals.getPackageManager()
4915                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
4916                         if (ai != null) {
4917                             if (ai.packageName.equals(app.info.packageName)) {
4918                                 app.info = ai;
4919                                 PlatformCompatCache.getInstance()
4920                                         .onApplicationInfoChanged(ai);
4921                             }
4922                             app.getThread().scheduleApplicationInfoChanged(ai);
4923                             targetProcesses.add(app.getWindowProcessController());
4924                         }
4925                     } catch (RemoteException e) {
4926                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
4927                                     packageName, app));
4928                     }
4929                 }
4930             });
4931         }
4932 
4933         mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes);
4934     }
4935 
4936     @GuardedBy("mService")
4937     void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
4938         boolean foundProcess = false;
4939         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4940             ProcessRecord r = mLruProcesses.get(i);
4941             final IApplicationThread thread = r.getThread();
4942             if (thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
4943                 try {
4944                     for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
4945                         if (packages[index].equals(r.info.packageName)) {
4946                             foundProcess = true;
4947                         }
4948                     }
4949                     thread.dispatchPackageBroadcast(cmd, packages);
4950                 } catch (RemoteException ex) {
4951                 }
4952             }
4953         }
4954 
4955         if (!foundProcess) {
4956             try {
4957                 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
4958             } catch (RemoteException ignored) {
4959             }
4960         }
4961     }
4962 
4963     /**
4964      * Returns the uid's process state or {@link ActivityManager#PROCESS_STATE_NONEXISTENT}
4965      * if not running
4966      */
4967     @GuardedBy(anyOf = {"mService", "mProcLock"})
4968     int getUidProcStateLOSP(int uid) {
4969         UidRecord uidRec = mActiveUids.get(uid);
4970         return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
4971     }
4972 
4973     /**
4974      * Returns the uid's process capability or {@link ActivityManager#PROCESS_CAPABILITY_NONE}
4975      * if not running
4976      */
4977     @GuardedBy(anyOf = {"mService", "mProcLock"})
4978     @ProcessCapability int getUidProcessCapabilityLOSP(int uid) {
4979         UidRecord uidRec = mActiveUids.get(uid);
4980         return uidRec == null ? PROCESS_CAPABILITY_NONE : uidRec.getCurCapability();
4981     }
4982 
4983     /** Returns the UidRecord for the given uid, if it exists. */
4984     @GuardedBy(anyOf = {"mService", "mProcLock"})
4985     UidRecord getUidRecordLOSP(int uid) {
4986         return mActiveUids.get(uid);
4987     }
4988 
4989     /**
4990      * Call {@link ActivityManagerService#doStopUidLocked}
4991      * (which will also stop background services) for all idle UIDs.
4992      */
4993     @GuardedBy("mService")
4994     void doStopUidForIdleUidsLocked() {
4995         final int size = mActiveUids.size();
4996         for (int i = 0; i < size; i++) {
4997             final int uid = mActiveUids.keyAt(i);
4998             if (UserHandle.isCore(uid)) {
4999                 continue;
5000             }
5001             final UidRecord uidRec = mActiveUids.valueAt(i);
5002             if (!uidRec.isIdle()) {
5003                 continue;
5004             }
5005             mService.doStopUidLocked(uidRec.getUid(), uidRec);
5006         }
5007     }
5008 
5009     /**
5010      * Checks if the uid is coming from background to foreground or vice versa and returns
5011      * appropriate block state based on this.
5012      *
5013      * @return blockState based on whether the uid is coming from background to foreground or
5014      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
5015      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
5016      *         {@link #NETWORK_STATE_NO_CHANGE}.
5017      */
5018     @VisibleForTesting
5019     @GuardedBy(anyOf = {"mService", "mProcLock"})
5020     int getBlockStateForUid(UidRecord uidRec) {
5021         // Denotes whether uid's process state is currently allowed network access.
5022         final boolean isAllowed =
5023                 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState(),
5024                         uidRec.getCurCapability())
5025                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState(),
5026                         uidRec.getCurCapability());
5027         // Denotes whether uid's process state was previously allowed network access.
5028         final boolean wasAllowed =
5029                 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getSetProcState(),
5030                         uidRec.getSetCapability())
5031                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getSetProcState(),
5032                         uidRec.getSetCapability());
5033 
5034         // When the uid is coming to foreground, AMS should inform the app thread that it should
5035         // block for the network rules to get updated before launching an activity.
5036         if (!wasAllowed && isAllowed) {
5037             return NETWORK_STATE_BLOCK;
5038         }
5039         // When the uid is going to background, AMS should inform the app thread that if an
5040         // activity launch is blocked for the network rules to get updated, it should be unblocked.
5041         if (wasAllowed && !isAllowed) {
5042             return NETWORK_STATE_UNBLOCK;
5043         }
5044         return NETWORK_STATE_NO_CHANGE;
5045     }
5046 
5047     /**
5048      * Increments the {@link UidRecord#curProcStateSeq} for all uids using global seq counter
5049      * {@link ProcessList#mProcStateSeqCounter} and checks if any uid is coming
5050      * from background to foreground or vice versa and if so, notifies the app if it needs to block.
5051      */
5052     @VisibleForTesting
5053     @GuardedBy(anyOf = {"mService", "mProcLock"})
5054     void incrementProcStateSeqAndNotifyAppsLOSP(ActiveUids activeUids) {
5055         for (int i = activeUids.size() - 1; i >= 0; --i) {
5056             final UidRecord uidRec = activeUids.valueAt(i);
5057             uidRec.curProcStateSeq = getNextProcStateSeq();
5058         }
5059         if (mService.mConstants.mNetworkAccessTimeoutMs <= 0) {
5060             return;
5061         }
5062         // Used for identifying which uids need to block for network.
5063         ArrayList<Integer> blockingUids = null;
5064         for (int i = activeUids.size() - 1; i >= 0; --i) {
5065             final UidRecord uidRec = activeUids.valueAt(i);
5066             // If the network is not restricted for uid, then nothing to do here.
5067             if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.getUid())) {
5068                 continue;
5069             }
5070             if (!UserHandle.isApp(uidRec.getUid()) || !uidRec.hasInternetPermission) {
5071                 continue;
5072             }
5073             // If process state and capabilities are not changed, then there's nothing to do.
5074             if (uidRec.getSetProcState() == uidRec.getCurProcState()
5075                     && uidRec.getSetCapability() == uidRec.getCurCapability()) {
5076                 continue;
5077             }
5078             final int blockState = getBlockStateForUid(uidRec);
5079             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
5080             // there's nothing the app needs to do in this scenario.
5081             if (blockState == NETWORK_STATE_NO_CHANGE) {
5082                 continue;
5083             }
5084             synchronized (uidRec.networkStateLock) {
5085                 if (blockState == NETWORK_STATE_BLOCK) {
5086                     if (blockingUids == null) {
5087                         blockingUids = new ArrayList<>();
5088                     }
5089                     blockingUids.add(uidRec.getUid());
5090                 } else {
5091                     if (DEBUG_NETWORK) {
5092                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
5093                                 + " threads for uid: " + uidRec);
5094                     }
5095                     if (uidRec.procStateSeqWaitingForNetwork != 0) {
5096                         uidRec.networkStateLock.notifyAll();
5097                     }
5098                 }
5099             }
5100         }
5101 
5102         // There are no uids that need to block, so nothing more to do.
5103         if (blockingUids == null) {
5104             return;
5105         }
5106 
5107         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
5108             final ProcessRecord app = mLruProcesses.get(i);
5109             if (!blockingUids.contains(app.uid)) {
5110                 continue;
5111             }
5112             final IApplicationThread thread = app.getThread();
5113             if (!app.isKilledByAm() && thread != null) {
5114                 final UidRecord uidRec = getUidRecordLOSP(app.uid);
5115                 try {
5116                     if (DEBUG_NETWORK) {
5117                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
5118                                 + uidRec);
5119                     }
5120                     if (uidRec != null) {
5121                         thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
5122                     }
5123                 } catch (RemoteException ignored) {
5124                 }
5125             }
5126         }
5127     }
5128 
5129     long getNextProcStateSeq() {
5130         return ++mProcStateSeqCounter;
5131     }
5132 
5133     /**
5134      * Create a server socket in system_server, zygote will connect to it
5135      * in order to send unsolicited messages to system_server.
5136      */
5137     private LocalSocket createSystemServerSocketForZygote() {
5138         // The file system entity for this socket is created with 0666 perms, owned
5139         // by system:system. selinux restricts things so that only zygotes can
5140         // access it.
5141         final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH);
5142         if (socketFile.exists()) {
5143             socketFile.delete();
5144         }
5145 
5146         LocalSocket serverSocket = null;
5147         try {
5148             serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM);
5149             serverSocket.bind(new LocalSocketAddress(
5150                     UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM));
5151             Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666);
5152         } catch (Exception e) {
5153             if (serverSocket != null) {
5154                 try {
5155                     serverSocket.close();
5156                 } catch (IOException ex) {
5157                 }
5158                 serverSocket = null;
5159             }
5160         }
5161         return serverSocket;
5162     }
5163 
5164     /**
5165      * Handle the unsolicited message from zygote.
5166      */
5167     private int handleZygoteMessages(FileDescriptor fd, int events) {
5168         final int eventFd = fd.getInt$();
5169         if ((events & EVENT_INPUT) != 0) {
5170             // An incoming message from zygote
5171             try {
5172                 final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0,
5173                         mZygoteUnsolicitedMessage.length);
5174                 if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld(
5175                         mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) {
5176                     mAppExitInfoTracker.handleZygoteSigChld(
5177                             mZygoteSigChldMessage[0] /* pid */,
5178                             mZygoteSigChldMessage[1] /* uid */,
5179                             mZygoteSigChldMessage[2] /* status */);
5180                 }
5181             } catch (Exception e) {
5182                 Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e);
5183             }
5184         }
5185         return EVENT_INPUT;
5186     }
5187 
5188     /**
5189      * Handle the death notification if it's a dying app.
5190      *
5191      * @return {@code true} if it's a dying app that we were tracking.
5192      */
5193     @GuardedBy("mService")
5194     boolean handleDyingAppDeathLocked(ProcessRecord app, int pid) {
5195         if (mProcessNames.get(app.processName, app.uid) != app
5196                 && mDyingProcesses.get(app.processName, app.uid) == app) {
5197             // App has been removed already, meaning cleanup has done.
5198             Slog.v(TAG, "Got obituary of " + pid + ":" + app.processName);
5199             app.unlinkDeathRecipient();
5200             // It's really gone now, let's remove from the dying process list.
5201             mDyingProcesses.remove(app.processName, app.uid);
5202             app.setDyingPid(0);
5203             handlePrecedingAppDiedLocked(app);
5204             // Remove from the LRU list if it's still there.
5205             removeLruProcessLocked(app);
5206             return true;
5207         }
5208         return false;
5209     }
5210 
5211     /**
5212      * Handle the case where the given app is a preceding instance of another process instance.
5213      *
5214      * @return {@code false} if this given app should not be allowed to restart.
5215      */
5216     @GuardedBy("mService")
5217     boolean handlePrecedingAppDiedLocked(ProcessRecord app) {
5218         if (app.mSuccessor != null) {
5219             // We don't allow restart with this ProcessRecord now,
5220             // because we have created a new one already.
5221             // If it's persistent, add the successor to mPersistentStartingProcesses
5222             if (app.isPersistent() && !app.isRemoved()) {
5223                 if (mService.mPersistentStartingProcesses.indexOf(app.mSuccessor) < 0) {
5224                     mService.mPersistentStartingProcesses.add(app.mSuccessor);
5225                 }
5226             }
5227             // clean up the field so the successor's proc starter could proceed.
5228             app.mSuccessor.mPredecessor = null;
5229             app.mSuccessor = null;
5230             // Remove any pending timeout msg.
5231             mService.mProcStartHandler.removeMessages(
5232                     ProcStartHandler.MSG_PROCESS_KILL_TIMEOUT, app);
5233             // Kick off the proc start for the succeeding instance
5234             mService.mProcStartHandler.obtainMessage(
5235                     ProcStartHandler.MSG_PROCESS_DIED, app).sendToTarget();
5236             return false;
5237         }
5238         return true;
5239     }
5240 
5241     @GuardedBy("mService")
5242     void updateBackgroundRestrictedForUidPackageLocked(int uid, String packageName,
5243             boolean restricted) {
5244         final UidRecord uidRec = getUidRecordLOSP(uid);
5245         if (uidRec != null) {
5246             final long nowElapsed = SystemClock.elapsedRealtime();
5247             uidRec.forEachProcess(app -> {
5248                 if (TextUtils.equals(app.info.packageName, packageName)) {
5249                     app.mState.setBackgroundRestricted(restricted);
5250                     if (restricted) {
5251                         mAppsInBackgroundRestricted.add(app);
5252                         final long future = killAppIfBgRestrictedAndCachedIdleLocked(
5253                                 app, nowElapsed);
5254                         if (future > 0
5255                                 && (mService.mDeterministicUidIdle
5256                                         || !mService.mHandler.hasMessages(IDLE_UIDS_MSG))) {
5257                             mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
5258                                     future - nowElapsed);
5259                         }
5260                     } else {
5261                         mAppsInBackgroundRestricted.remove(app);
5262                     }
5263                     if (!app.isKilledByAm()) {
5264                         mService.enqueueOomAdjTargetLocked(app);
5265                     }
5266                 }
5267             });
5268             /* Will be a no-op if nothing pending */
5269             mService.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_RESTRICTION_CHANGE);
5270         }
5271     }
5272 
5273     /**
5274      * Kill the given app if it's in cached idle and background restricted mode.
5275      *
5276      * @return A future timestamp when the app should be killed at, or a 0 if it shouldn't
5277      * be killed or it has been killed.
5278      */
5279     @GuardedBy("mService")
5280     long killAppIfBgRestrictedAndCachedIdleLocked(ProcessRecord app, long nowElapsed) {
5281         final UidRecord uidRec = app.getUidRecord();
5282         final long lastCanKillTime = app.mState.getLastCanKillOnBgRestrictedAndIdleTime();
5283         if (!mService.mConstants.mKillBgRestrictedAndCachedIdle
5284                 || app.isKilled() || app.getThread() == null || uidRec == null || !uidRec.isIdle()
5285                 || !app.isCached() || app.mState.shouldNotKillOnBgRestrictedAndIdle()
5286                 || !app.mState.isBackgroundRestricted() || lastCanKillTime == 0) {
5287             return 0;
5288         }
5289         final long future = lastCanKillTime
5290                 + mService.mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs;
5291         if (future <= nowElapsed) {
5292             app.killLocked("cached idle & background restricted",
5293                     ApplicationExitInfo.REASON_OTHER,
5294                     ApplicationExitInfo.SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY,
5295                     true);
5296             return 0;
5297         }
5298         return future;
5299     }
5300 
5301     /**
5302      * Called by {@link ActivityManagerService#enqueueUidChangeLocked} only, it doesn't schedule
5303      * the standy killing checks because it should have been scheduled before enqueueing UID idle
5304      * changed.
5305      */
5306     @GuardedBy("mService")
5307     void killAppIfBgRestrictedAndCachedIdleLocked(UidRecord uidRec) {
5308         final long nowElapsed = SystemClock.elapsedRealtime();
5309         uidRec.forEachProcess(app -> killAppIfBgRestrictedAndCachedIdleLocked(app, nowElapsed));
5310     }
5311 
5312     /**
5313      * Called by ActivityManagerService when a process died.
5314      */
5315     @GuardedBy("mService")
5316     void noteProcessDiedLocked(final ProcessRecord app) {
5317         if (DEBUG_PROCESSES) {
5318             Slog.i(TAG, "note: " + app + " died, saving the exit info");
5319         }
5320 
5321         Watchdog.getInstance().processDied(app.processName, app.getPid());
5322         if (app.getDeathRecipient() == null
5323                 && mDyingProcesses.get(app.processName, app.uid) == app) {
5324             // If we've done unlinkDeathRecipient before calling into this, remove from dying list.
5325             mDyingProcesses.remove(app.processName, app.uid);
5326             app.setDyingPid(0);
5327         }
5328         mAppExitInfoTracker.scheduleNoteProcessDied(app);
5329     }
5330 
5331     /**
5332      * Called by ActivityManagerService when a recoverable native crash occurs.
5333      */
5334     @GuardedBy("mService")
5335     void noteAppRecoverableCrash(final ProcessRecord app) {
5336         if (DEBUG_PROCESSES) {
5337             Slog.i(TAG, "note: " + app + " has a recoverable native crash");
5338         }
5339         mAppExitInfoTracker.scheduleNoteAppRecoverableCrash(app);
5340     }
5341 
5342     /**
5343      * Called by ActivityManagerService when it decides to kill an application process.
5344      */
5345     @GuardedBy("mService")
5346     void noteAppKill(final ProcessRecord app, final @Reason int reason,
5347             final @SubReason int subReason, final String msg) {
5348         if (DEBUG_PROCESSES) {
5349             Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
5350                     + ", sub-reason: " + subReason + ", message: " + msg);
5351         }
5352         if (app.getPid() > 0 && !app.isolated && app.getDeathRecipient() != null) {
5353             // We are killing it, put it into the dying process list.
5354             mDyingProcesses.put(app.processName, app.uid, app);
5355             app.setDyingPid(app.getPid());
5356         }
5357         mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg);
5358     }
5359 
5360     @GuardedBy("mService")
5361     void noteAppKill(final int pid, final int uid, final @Reason int reason,
5362             final @SubReason int subReason, final String msg) {
5363         if (DEBUG_PROCESSES) {
5364             Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason
5365                     + ", sub-reason: " + subReason + ", message: " + msg);
5366         }
5367 
5368         final ProcessRecord app;
5369         synchronized (mService.mPidsSelfLocked) {
5370             app = mService.mPidsSelfLocked.get(pid);
5371         }
5372         if (app != null && app.uid == uid && !app.isolated && app.getDeathRecipient() != null) {
5373             // We are killing it, put it into the dying process list.
5374             mDyingProcesses.put(app.processName, uid, app);
5375             app.setDyingPid(app.getPid());
5376         }
5377         mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg);
5378     }
5379 
5380     /**
5381      * Schedule to kill the given pids when the device is idle
5382      */
5383     void killProcessesWhenImperceptible(int[] pids, String reason, int requester) {
5384         if (ArrayUtils.isEmpty(pids)) {
5385             return;
5386         }
5387 
5388         synchronized (mService) {
5389             ProcessRecord app;
5390             for (int i = 0; i < pids.length; i++) {
5391                 synchronized (mService.mPidsSelfLocked) {
5392                     app = mService.mPidsSelfLocked.get(pids[i]);
5393                 }
5394                 if (app != null) {
5395                     mImperceptibleKillRunner.enqueueLocked(app, reason, requester);
5396                 }
5397             }
5398         }
5399     }
5400 
5401     /**
5402      * Get the number of foreground services in all processes and number of processes that have
5403      * foreground service within.
5404      */
5405     Pair<Integer, Integer> getNumForegroundServices() {
5406         int numForegroundServices = 0;
5407         int procs = 0;
5408         synchronized (mService) {
5409             for (int i = 0, size = mLruProcesses.size(); i < size; i++) {
5410                 ProcessRecord pr = mLruProcesses.get(i);
5411                 int numFgs = pr.mServices.getNumForegroundServices();
5412                 if (numFgs > 0) {
5413                     numForegroundServices += numFgs;
5414                     procs++;
5415                 }
5416             }
5417         }
5418         return new Pair<>(numForegroundServices, procs);
5419     }
5420 
5421     private final class ImperceptibleKillRunner extends UidObserver {
5422         private static final String EXTRA_PID = "pid";
5423         private static final String EXTRA_UID = "uid";
5424         private static final String EXTRA_TIMESTAMP = "timestamp";
5425         private static final String EXTRA_REASON = "reason";
5426         private static final String EXTRA_REQUESTER = "requester";
5427 
5428         private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill";
5429         private static final boolean LOG_TO_DROPBOX = false;
5430 
5431         // uid -> killing information mapping
5432         private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>();
5433 
5434         // The last time the various processes have been killed by us.
5435         private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>();
5436 
5437         // Device idle or not.
5438         private volatile boolean mIdle;
5439         private boolean mUidObserverEnabled;
5440         private Handler mHandler;
5441         private IdlenessReceiver mReceiver;
5442 
5443         private final class H extends Handler {
5444             static final int MSG_DEVICE_IDLE = 0;
5445             static final int MSG_UID_GONE = 1;
5446             static final int MSG_UID_STATE_CHANGED = 2;
5447 
5448             H(Looper looper) {
5449                 super(looper);
5450             }
5451 
5452             @Override
5453             public void handleMessage(Message msg) {
5454                 switch (msg.what) {
5455                     case MSG_DEVICE_IDLE:
5456                         handleDeviceIdle();
5457                         break;
5458                     case MSG_UID_GONE:
5459                         handleUidGone(msg.arg1 /* uid */);
5460                         break;
5461                     case MSG_UID_STATE_CHANGED:
5462                         handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */);
5463                         break;
5464                 }
5465             }
5466         }
5467 
5468         private final class IdlenessReceiver extends BroadcastReceiver {
5469             @Override
5470             public void onReceive(Context context, Intent intent) {
5471                 final PowerManager pm = mService.mContext.getSystemService(PowerManager.class);
5472                 switch (intent.getAction()) {
5473                     case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
5474                         notifyDeviceIdleness(pm.isLightDeviceIdleMode());
5475                         break;
5476                     case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
5477                         notifyDeviceIdleness(pm.isDeviceIdleMode());
5478                         break;
5479                 }
5480             }
5481         }
5482 
5483         ImperceptibleKillRunner(Looper looper) {
5484             mHandler = new H(looper);
5485         }
5486 
5487         @GuardedBy("mService")
5488         boolean enqueueLocked(ProcessRecord app, String reason, int requester) {
5489             // Throttle the killing request for potential bad app to avoid cpu thrashing
5490             Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid);
5491             if ((last != null) && (SystemClock.uptimeMillis()
5492                     < (last + ActivityManagerConstants.MIN_CRASH_INTERVAL))) {
5493                 return false;
5494             }
5495 
5496             final Bundle bundle = new Bundle();
5497             bundle.putInt(EXTRA_PID, app.getPid());
5498             bundle.putInt(EXTRA_UID, app.uid);
5499             // Since the pid could be reused, let's get the actual start time of each process
5500             bundle.putLong(EXTRA_TIMESTAMP, app.getStartTime());
5501             bundle.putString(EXTRA_REASON, reason);
5502             bundle.putInt(EXTRA_REQUESTER, requester);
5503             List<Bundle> list = mWorkItems.get(app.uid);
5504             if (list == null) {
5505                 list = new ArrayList<Bundle>();
5506                 mWorkItems.put(app.uid, list);
5507             }
5508             list.add(bundle);
5509             if (mReceiver == null) {
5510                 mReceiver = new IdlenessReceiver();
5511                 IntentFilter filter = new IntentFilter(
5512                         PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
5513                 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
5514                 mService.mContext.registerReceiver(mReceiver, filter);
5515             }
5516             return true;
5517         }
5518 
5519         void notifyDeviceIdleness(boolean idle) {
5520             // No lock is held regarding mIdle, this function is the only updater and caller
5521             // won't re-entry.
5522             boolean diff = mIdle != idle;
5523             mIdle = idle;
5524             if (diff && idle) {
5525                 synchronized (mService) {
5526                     if (mWorkItems.size() > 0) {
5527                         mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE);
5528                     }
5529                 }
5530             }
5531         }
5532 
5533         private void handleDeviceIdle() {
5534             final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
5535             final boolean logToDropbox = LOG_TO_DROPBOX && dbox != null
5536                     && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
5537 
5538             synchronized (mService) {
5539                 final int size = mWorkItems.size();
5540                 for (int i = size - 1; mIdle && i >= 0; i--) {
5541                     List<Bundle> list = mWorkItems.valueAt(i);
5542                     final int len = list.size();
5543                     for (int j = len - 1; mIdle && j >= 0; j--) {
5544                         Bundle bundle = list.get(j);
5545                         if (killProcessLocked(
5546                                 bundle.getInt(EXTRA_PID),
5547                                 bundle.getInt(EXTRA_UID),
5548                                 bundle.getLong(EXTRA_TIMESTAMP),
5549                                 bundle.getString(EXTRA_REASON),
5550                                 bundle.getInt(EXTRA_REQUESTER),
5551                                 dbox, logToDropbox)) {
5552                             list.remove(j);
5553                         }
5554                     }
5555                     if (list.size() == 0) {
5556                         mWorkItems.removeAt(i);
5557                     }
5558                 }
5559                 registerUidObserverIfNecessaryLocked();
5560             }
5561         }
5562 
5563         @GuardedBy("mService")
5564         private void registerUidObserverIfNecessaryLocked() {
5565             // If there are still works remaining, register UID observer
5566             if (!mUidObserverEnabled && mWorkItems.size() > 0) {
5567                 mUidObserverEnabled = true;
5568                 mService.registerUidObserver(this,
5569                         ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
5570                         ActivityManager.PROCESS_STATE_UNKNOWN, "android");
5571             } else if (mUidObserverEnabled && mWorkItems.size() == 0) {
5572                 mUidObserverEnabled = false;
5573                 mService.unregisterUidObserver(this);
5574             }
5575         }
5576 
5577         /**
5578          * Kill the given processes, if they are not exempted.
5579          *
5580          * @return True if the process is killed, or it's gone already, or we are not allowed to
5581          *         kill it (one of the packages in this process is being exempted).
5582          */
5583         @GuardedBy("mService")
5584         private boolean killProcessLocked(final int pid, final int uid, final long timestamp,
5585                 final String reason, final int requester, final DropBoxManager dbox,
5586                 final boolean logToDropbox) {
5587             ProcessRecord app = null;
5588             synchronized (mService.mPidsSelfLocked) {
5589                 app = mService.mPidsSelfLocked.get(pid);
5590             }
5591 
5592             if (app == null || app.getPid() != pid || app.uid != uid
5593                     || app.getStartTime() != timestamp) {
5594                 // This process record has been reused for another process, meaning the old process
5595                 // has been gone.
5596                 return true;
5597             }
5598 
5599             if (app.getPkgList().searchEachPackage(pkgName -> {
5600                 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(pkgName)) {
5601                     // One of the packages in this process is exempted
5602                     return Boolean.TRUE;
5603                 }
5604                 return null;
5605             }) != null) {
5606                 return true;
5607             }
5608 
5609             if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(
5610                     app.mState.getReportedProcState())) {
5611                 // We need to reschedule it.
5612                 return false;
5613             }
5614 
5615             app.killLocked(reason, ApplicationExitInfo.REASON_OTHER,
5616                     ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true);
5617 
5618             if (!app.isolated) {
5619                 mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());
5620             }
5621 
5622             if (logToDropbox) {
5623                 final long now = SystemClock.elapsedRealtime();
5624                 final StringBuilder sb = new StringBuilder();
5625                 mService.appendDropBoxProcessHeaders(app, app.processName, null, sb);
5626                 sb.append("Reason: " + reason).append("\n");
5627                 sb.append("Requester UID: " + requester).append("\n");
5628                 dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString());
5629             }
5630             return true;
5631         }
5632 
5633         private void handleUidStateChanged(int uid, int procState) {
5634             final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
5635             final boolean logToDropbox = dbox != null
5636                     && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
5637             synchronized (mService) {
5638                 if (mIdle && !mService.mConstants
5639                         .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) {
5640                     List<Bundle> list = mWorkItems.get(uid);
5641                     if (list != null) {
5642                         final int len = list.size();
5643                         for (int j = len - 1; mIdle && j >= 0; j--) {
5644                             Bundle bundle = list.get(j);
5645                             if (killProcessLocked(
5646                                     bundle.getInt(EXTRA_PID),
5647                                     bundle.getInt(EXTRA_UID),
5648                                     bundle.getLong(EXTRA_TIMESTAMP),
5649                                     bundle.getString(EXTRA_REASON),
5650                                     bundle.getInt(EXTRA_REQUESTER),
5651                                     dbox, logToDropbox)) {
5652                                 list.remove(j);
5653                             }
5654                         }
5655                         if (list.size() == 0) {
5656                             mWorkItems.remove(uid);
5657                         }
5658                         registerUidObserverIfNecessaryLocked();
5659                     }
5660                 }
5661             }
5662         }
5663 
5664         private void handleUidGone(int uid) {
5665             synchronized (mService) {
5666                 mWorkItems.remove(uid);
5667                 registerUidObserverIfNecessaryLocked();
5668             }
5669         }
5670 
5671         @Override
5672         public void onUidGone(int uid, boolean disabled) {
5673             mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget();
5674         }
5675 
5676         @Override
5677         public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
5678             mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
5679         }
5680     };
5681 }
5682