• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.am;
18 
19 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
21 import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
22 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
23 import static android.os.Process.SYSTEM_UID;
24 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
25 import static android.os.Process.getFreeMemory;
26 import static android.os.Process.getTotalMemory;
27 import static android.os.Process.killProcessQuiet;
28 import static android.os.Process.startWebView;
29 
30 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
31 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
32 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
33 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
34 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
35 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
36 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS;
37 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG;
38 import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK;
39 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT;
40 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG;
41 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER;
42 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
43 import static com.android.server.am.ActivityManagerService.TAG_LRU;
44 import static com.android.server.am.ActivityManagerService.TAG_PROCESSES;
45 import static com.android.server.am.ActivityManagerService.TAG_PSS;
46 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
47 
48 import android.app.ActivityManager;
49 import android.app.ActivityThread;
50 import android.app.AppGlobals;
51 import android.app.AppProtoEnums;
52 import android.app.IApplicationThread;
53 import android.content.ComponentName;
54 import android.content.Context;
55 import android.content.Intent;
56 import android.content.pm.ApplicationInfo;
57 import android.content.pm.IPackageManager;
58 import android.content.res.Resources;
59 import android.graphics.Point;
60 import android.net.LocalSocket;
61 import android.net.LocalSocketAddress;
62 import android.os.AppZygote;
63 import android.os.Binder;
64 import android.os.Build;
65 import android.os.Bundle;
66 import android.os.Handler;
67 import android.os.IBinder;
68 import android.os.Looper;
69 import android.os.Message;
70 import android.os.Process;
71 import android.os.RemoteException;
72 import android.os.StrictMode;
73 import android.os.SystemClock;
74 import android.os.SystemProperties;
75 import android.os.Trace;
76 import android.os.UserHandle;
77 import android.os.storage.StorageManager;
78 import android.os.storage.StorageManagerInternal;
79 import android.text.TextUtils;
80 import android.util.ArrayMap;
81 import android.util.EventLog;
82 import android.util.LongSparseArray;
83 import android.util.Slog;
84 import android.util.SparseArray;
85 import android.util.SparseBooleanArray;
86 import android.util.StatsLog;
87 import android.view.Display;
88 
89 import com.android.internal.annotations.GuardedBy;
90 import com.android.internal.annotations.VisibleForTesting;
91 import com.android.internal.app.ProcessMap;
92 import com.android.internal.app.procstats.ProcessStats;
93 import com.android.internal.os.Zygote;
94 import com.android.internal.util.ArrayUtils;
95 import com.android.internal.util.MemInfoReader;
96 import com.android.server.LocalServices;
97 import com.android.server.ServiceThread;
98 import com.android.server.Watchdog;
99 import com.android.server.pm.dex.DexManager;
100 import com.android.server.wm.ActivityServiceConnectionsHolder;
101 import com.android.server.wm.WindowManagerService;
102 
103 import dalvik.system.VMRuntime;
104 
105 import libcore.io.IoUtils;
106 
107 import java.io.File;
108 import java.io.IOException;
109 import java.io.InputStream;
110 import java.io.OutputStream;
111 import java.io.PrintWriter;
112 import java.nio.ByteBuffer;
113 import java.util.ArrayList;
114 import java.util.Arrays;
115 import java.util.BitSet;
116 import java.util.List;
117 
118 /**
119  * Activity manager code dealing with processes.
120  *
121  * Method naming convention:
122  * <ul>
123  * <li> Methods suffixed with "LS" should be called within the {@link #sLmkdSocketLock} lock.
124  * </ul>
125  */
126 public final class ProcessList {
127     static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
128 
129     // The minimum time we allow between crashes, for us to consider this
130     // application to be bad and stop and its services and reject broadcasts.
131     static final int MIN_CRASH_INTERVAL = 60 * 1000;
132 
133     // OOM adjustments for processes in various states:
134 
135     // Uninitialized value for any major or minor adj fields
136     static final int INVALID_ADJ = -10000;
137 
138     // Adjustment used in certain places where we don't know it yet.
139     // (Generally this is something that is going to be cached, but we
140     // don't know the exact value in the cached range to assign yet.)
141     static final int UNKNOWN_ADJ = 1001;
142 
143     // This is a process only hosting activities that are not visible,
144     // so it can be killed without any disruption.
145     static final int CACHED_APP_MAX_ADJ = 999;
146     static final int CACHED_APP_MIN_ADJ = 900;
147 
148     // This is the oom_adj level that we allow to die first. This cannot be equal to
149     // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
150     // CACHED_APP_MAX_ADJ.
151     static final int CACHED_APP_LMK_FIRST_ADJ = 950;
152 
153     // Number of levels we have available for different service connection group importance
154     // levels.
155     static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
156 
157     // The B list of SERVICE_ADJ -- these are the old and decrepit
158     // services that aren't as shiny and interesting as the ones in the A list.
159     static final int SERVICE_B_ADJ = 800;
160 
161     // This is the process of the previous application that the user was in.
162     // This process is kept above other things, because it is very common to
163     // switch back to the previous app.  This is important both for recent
164     // task switch (toggling between the two top recent apps) as well as normal
165     // UI flow such as clicking on a URI in the e-mail app to view in the browser,
166     // and then pressing back to return to e-mail.
167     static final int PREVIOUS_APP_ADJ = 700;
168 
169     // This is a process holding the home application -- we want to try
170     // avoiding killing it, even if it would normally be in the background,
171     // because the user interacts with it so much.
172     static final int HOME_APP_ADJ = 600;
173 
174     // This is a process holding an application service -- killing it will not
175     // have much of an impact as far as the user is concerned.
176     static final int SERVICE_ADJ = 500;
177 
178     // This is a process with a heavy-weight application.  It is in the
179     // background, but we want to try to avoid killing it.  Value set in
180     // system/rootdir/init.rc on startup.
181     static final int HEAVY_WEIGHT_APP_ADJ = 400;
182 
183     // This is a process currently hosting a backup operation.  Killing it
184     // is not entirely fatal but is generally a bad idea.
185     static final int BACKUP_APP_ADJ = 300;
186 
187     // This is a process bound by the system (or other app) that's more important than services but
188     // not so perceptible that it affects the user immediately if killed.
189     static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
190 
191     // This is a process only hosting components that are perceptible to the
192     // user, and we really want to avoid killing them, but they are not
193     // immediately visible. An example is background music playback.
194     static final int PERCEPTIBLE_APP_ADJ = 200;
195 
196     // This is a process only hosting activities that are visible to the
197     // user, so we'd prefer they don't disappear.
198     static final int VISIBLE_APP_ADJ = 100;
199     static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
200 
201     // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
202     // like a foreground app for a while.
203     // @see TOP_TO_FGS_GRACE_PERIOD
204     static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
205 
206     // This is the process running the current foreground app.  We'd really
207     // rather not kill it!
208     static final int FOREGROUND_APP_ADJ = 0;
209 
210     // This is a process that the system or a persistent process has bound to,
211     // and indicated it is important.
212     static final int PERSISTENT_SERVICE_ADJ = -700;
213 
214     // This is a system persistent process, such as telephony.  Definitely
215     // don't want to kill it, but doing so is not completely fatal.
216     static final int PERSISTENT_PROC_ADJ = -800;
217 
218     // The system process runs at the default adjustment.
219     static final int SYSTEM_ADJ = -900;
220 
221     // Special code for native processes that are not being managed by the system (so
222     // don't have an oom adj assigned by the system).
223     static final int NATIVE_ADJ = -1000;
224 
225     // Memory pages are 4K.
226     static final int PAGE_SIZE = 4 * 1024;
227 
228     // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
229     static final int SCHED_GROUP_BACKGROUND = 0;
230       // Activity manager's version of Process.THREAD_GROUP_RESTRICTED
231     static final int SCHED_GROUP_RESTRICTED = 1;
232     // Activity manager's version of Process.THREAD_GROUP_DEFAULT
233     static final int SCHED_GROUP_DEFAULT = 2;
234     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
235     public static final int SCHED_GROUP_TOP_APP = 3;
236     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
237     // Disambiguate between actual top app and processes bound to the top app
238     static final int SCHED_GROUP_TOP_APP_BOUND = 4;
239 
240     // The minimum number of cached apps we want to be able to keep around,
241     // without empty apps being able to push them out of memory.
242     static final int MIN_CACHED_APPS = 2;
243 
244     // We allow empty processes to stick around for at most 30 minutes.
245     static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
246 
247     // Threshold of number of cached+empty where we consider memory critical.
248     static final int TRIM_CRITICAL_THRESHOLD = 3;
249 
250     // Threshold of number of cached+empty where we consider memory critical.
251     static final int TRIM_LOW_THRESHOLD = 5;
252 
253     // If true, then we pass the flag to ART to load the app image startup cache.
254     private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
255             "persist.device_config.runtime_native.use_app_image_startup_cache";
256 
257     // Low Memory Killer Daemon command codes.
258     // These must be kept in sync with the definitions in lmkd.c
259     //
260     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
261     // LMK_PROCPRIO <pid> <uid> <prio>
262     // LMK_PROCREMOVE <pid>
263     // LMK_PROCPURGE
264     // LMK_GETKILLCNT
265     static final byte LMK_TARGET = 0;
266     static final byte LMK_PROCPRIO = 1;
267     static final byte LMK_PROCREMOVE = 2;
268     static final byte LMK_PROCPURGE = 3;
269     static final byte LMK_GETKILLCNT = 4;
270 
271     ActivityManagerService mService = null;
272 
273     // To kill process groups asynchronously
274     static KillHandler sKillHandler = null;
275     static ServiceThread sKillThread = null;
276 
277     // These are the various interesting memory levels that we will give to
278     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
279     // can't give it a different value for every possible kind of process.
280     private final int[] mOomAdj = new int[] {
281             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
282             PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
283     };
284     // These are the low-end OOM level limits.  This is appropriate for an
285     // HVGA or smaller phone with less than 512MB.  Values are in KB.
286     private final int[] mOomMinFreeLow = new int[] {
287             12288, 18432, 24576,
288             36864, 43008, 49152
289     };
290     // These are the high-end OOM level limits.  This is appropriate for a
291     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
292     private final int[] mOomMinFreeHigh = new int[] {
293             73728, 92160, 110592,
294             129024, 147456, 184320
295     };
296     // The actual OOM killer memory levels we are using.
297     private final int[] mOomMinFree = new int[mOomAdj.length];
298 
299     private final long mTotalMemMb;
300 
301     private long mCachedRestoreLevel;
302 
303     private boolean mHaveDisplaySize;
304 
305     private static Object sLmkdSocketLock = new Object();
306 
307     @GuardedBy("sLmkdSocketLock")
308     private static LocalSocket sLmkdSocket;
309 
310     @GuardedBy("sLmkdSocketLock")
311     private static OutputStream sLmkdOutputStream;
312 
313     @GuardedBy("sLmkdSocketLock")
314     private static InputStream sLmkdInputStream;
315 
316     /**
317      * Temporary to avoid allocations.  Protected by main lock.
318      */
319     @GuardedBy("mService")
320     final StringBuilder mStringBuilder = new StringBuilder(256);
321 
322     /**
323      * A global counter for generating sequence numbers.
324      * This value will be used when incrementing sequence numbers in individual uidRecords.
325      *
326      * Having a global counter ensures that seq numbers are monotonically increasing for a
327      * particular uid even when the uidRecord is re-created.
328      */
329     @GuardedBy("mService")
330     @VisibleForTesting
331     long mProcStateSeqCounter = 0;
332 
333     /**
334      * A global counter for generating sequence numbers to uniquely identify pending process starts.
335      */
336     @GuardedBy("mService")
337     private long mProcStartSeqCounter = 0;
338 
339     /**
340      * Contains {@link ProcessRecord} objects for pending process starts.
341      *
342      * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
343      */
344     @GuardedBy("mService")
345     final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
346 
347     /**
348      * List of running applications, sorted by recent usage.
349      * The first entry in the list is the least recently used.
350      */
351     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
352 
353     /**
354      * Where in mLruProcesses that the processes hosting activities start.
355      */
356     int mLruProcessActivityStart = 0;
357 
358     /**
359      * Where in mLruProcesses that the processes hosting services start.
360      * This is after (lower index) than mLruProcessesActivityStart.
361      */
362     int mLruProcessServiceStart = 0;
363 
364     /**
365      * Current sequence id for process LRU updating.
366      */
367     int mLruSeq = 0;
368 
369     ActiveUids mActiveUids;
370 
371     /**
372      * The currently running isolated processes.
373      */
374     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
375 
376     /**
377      * The currently running application zygotes.
378      */
379     final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
380 
381     /**
382      * The processes that are forked off an application zygote.
383      */
384     final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses =
385             new ArrayMap<AppZygote, ArrayList<ProcessRecord>>();
386 
387     final class IsolatedUidRange {
388         @VisibleForTesting
389         public final int mFirstUid;
390         @VisibleForTesting
391         public final int mLastUid;
392 
393         @GuardedBy("ProcessList.this.mService")
394         private final SparseBooleanArray mUidUsed = new SparseBooleanArray();
395 
396         @GuardedBy("ProcessList.this.mService")
397         private int mNextUid;
398 
IsolatedUidRange(int firstUid, int lastUid)399         IsolatedUidRange(int firstUid, int lastUid) {
400             mFirstUid = firstUid;
401             mLastUid = lastUid;
402             mNextUid = firstUid;
403         }
404 
405         @GuardedBy("ProcessList.this.mService")
allocateIsolatedUidLocked(int userId)406         int allocateIsolatedUidLocked(int userId) {
407             int uid;
408             int stepsLeft = (mLastUid - mFirstUid + 1);
409             for (int i = 0; i < stepsLeft; ++i) {
410                 if (mNextUid < mFirstUid || mNextUid > mLastUid) {
411                     mNextUid = mFirstUid;
412                 }
413                 uid = UserHandle.getUid(userId, mNextUid);
414                 mNextUid++;
415                 if (!mUidUsed.get(uid, false)) {
416                     mUidUsed.put(uid, true);
417                     return uid;
418                 }
419             }
420             return -1;
421         }
422 
423         @GuardedBy("ProcessList.this.mService")
freeIsolatedUidLocked(int uid)424         void freeIsolatedUidLocked(int uid) {
425             // Strip out userId
426             final int appId = UserHandle.getAppId(uid);
427             mUidUsed.delete(appId);
428         }
429     };
430 
431     /**
432      * A class that allocates ranges of isolated UIDs per application, and keeps track of them.
433      */
434     final class IsolatedUidRangeAllocator {
435         private final int mFirstUid;
436         private final int mNumUidRanges;
437         private final int mNumUidsPerRange;
438         /**
439          * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange)
440          * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that.
441          */
442         @GuardedBy("ProcessList.this.mService")
443         private final BitSet mAvailableUidRanges;
444         @GuardedBy("ProcessList.this.mService")
445         private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>();
446 
IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange)447         IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) {
448             mFirstUid = firstUid;
449             mNumUidsPerRange = numUidsPerRange;
450             mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange;
451             mAvailableUidRanges = new BitSet(mNumUidRanges);
452             // Mark all as available
453             mAvailableUidRanges.set(0, mNumUidRanges);
454         }
455 
456         @GuardedBy("ProcessList.this.mService")
getIsolatedUidRangeLocked(String processName, int uid)457         IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) {
458             return mAppRanges.get(processName, uid);
459         }
460 
461         @GuardedBy("ProcessList.this.mService")
getOrCreateIsolatedUidRangeLocked(String processName, int uid)462         IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) {
463             IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid);
464             if (range == null) {
465                 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
466                 if (uidRangeIndex < 0) {
467                     // No free range
468                     return null;
469                 }
470                 mAvailableUidRanges.clear(uidRangeIndex);
471                 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
472                 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
473                 mAppRanges.put(processName, uid, range);
474             }
475             return range;
476         }
477 
478         @GuardedBy("ProcessList.this.mService")
freeUidRangeLocked(ApplicationInfo info)479         void freeUidRangeLocked(ApplicationInfo info) {
480             // Find the UID range
481             IsolatedUidRange range = mAppRanges.get(info.processName, info.uid);
482             if (range != null) {
483                 // Map back to starting uid
484                 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange;
485                 // Mark it as available in the underlying bitset
486                 mAvailableUidRanges.set(uidRangeIndex);
487                 // And the map
488                 mAppRanges.remove(info.processName, info.uid);
489             }
490         }
491     }
492 
493     /**
494      * The available isolated UIDs for processes that are not spawned from an application zygote.
495      */
496     @VisibleForTesting
497     IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID,
498             Process.LAST_ISOLATED_UID);
499 
500     /**
501      * An allocator for isolated UID ranges for apps that use an application zygote.
502      */
503     @VisibleForTesting
504     IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator =
505             new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
506                     Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE);
507 
508     /**
509      * Processes that are being forcibly torn down.
510      */
511     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
512 
513     /**
514      * All of the applications we currently have running organized by name.
515      * The keys are strings of the application package name (as
516      * returned by the package manager), and the keys are ApplicationRecord
517      * objects.
518      */
519     final MyProcessMap mProcessNames = new MyProcessMap();
520 
521     final class MyProcessMap extends ProcessMap<ProcessRecord> {
522         @Override
put(String name, int uid, ProcessRecord value)523         public ProcessRecord put(String name, int uid, ProcessRecord value) {
524             final ProcessRecord r = super.put(name, uid, value);
525             mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());
526             return r;
527         }
528 
529         @Override
remove(String name, int uid)530         public ProcessRecord remove(String name, int uid) {
531             final ProcessRecord r = super.remove(name, uid);
532             mService.mAtmInternal.onProcessRemoved(name, uid);
533             return r;
534         }
535     }
536 
537     final class KillHandler extends Handler {
538         static final int KILL_PROCESS_GROUP_MSG = 4000;
539 
KillHandler(Looper looper)540         public KillHandler(Looper looper) {
541             super(looper, null, true);
542         }
543 
544         @Override
handleMessage(Message msg)545         public void handleMessage(Message msg) {
546             switch (msg.what) {
547                 case KILL_PROCESS_GROUP_MSG:
548                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
549                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
550                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
551                     break;
552 
553                 default:
554                     super.handleMessage(msg);
555             }
556         }
557     }
558 
559     ////////////////////  END FIELDS  ////////////////////
560 
ProcessList()561     ProcessList() {
562         MemInfoReader minfo = new MemInfoReader();
563         minfo.readMemInfo();
564         mTotalMemMb = minfo.getTotalSize()/(1024*1024);
565         updateOomLevels(0, 0, false);
566     }
567 
init(ActivityManagerService service, ActiveUids activeUids)568     void init(ActivityManagerService service, ActiveUids activeUids) {
569         mService = service;
570         mActiveUids = activeUids;
571 
572         if (sKillHandler == null) {
573             sKillThread = new ServiceThread(TAG + ":kill",
574                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
575             sKillThread.start();
576             sKillHandler = new KillHandler(sKillThread.getLooper());
577         }
578     }
579 
applyDisplaySize(WindowManagerService wm)580     void applyDisplaySize(WindowManagerService wm) {
581         if (!mHaveDisplaySize) {
582             Point p = new Point();
583             // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
584             wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
585             if (p.x != 0 && p.y != 0) {
586                 updateOomLevels(p.x, p.y, true);
587                 mHaveDisplaySize = true;
588             }
589         }
590     }
591 
updateOomLevels(int displayWidth, int displayHeight, boolean write)592     private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
593         // Scale buckets from avail memory: at 300MB we use the lowest values to
594         // 700MB or more for the top values.
595         float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
596 
597         // Scale buckets from screen size.
598         int minSize = 480 * 800;  //  384000
599         int maxSize = 1280 * 800; // 1024000  230400 870400  .264
600         float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
601         if (false) {
602             Slog.i("XXXXXX", "scaleMem=" + scaleMem);
603             Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
604                     + " dh=" + displayHeight);
605         }
606 
607         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
608         if (scale < 0) scale = 0;
609         else if (scale > 1) scale = 1;
610         int minfree_adj = Resources.getSystem().getInteger(
611                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
612         int minfree_abs = Resources.getSystem().getInteger(
613                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
614         if (false) {
615             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
616         }
617 
618         final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
619 
620         for (int i = 0; i < mOomAdj.length; i++) {
621             int low = mOomMinFreeLow[i];
622             int high = mOomMinFreeHigh[i];
623             if (is64bit) {
624                 // Increase the high min-free levels for cached processes for 64-bit
625                 if (i == 4) high = (high * 3) / 2;
626                 else if (i == 5) high = (high * 7) / 4;
627             }
628             mOomMinFree[i] = (int)(low + ((high - low) * scale));
629         }
630 
631         if (minfree_abs >= 0) {
632             for (int i = 0; i < mOomAdj.length; i++) {
633                 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
634                         / mOomMinFree[mOomAdj.length - 1]);
635             }
636         }
637 
638         if (minfree_adj != 0) {
639             for (int i = 0; i < mOomAdj.length; i++) {
640                 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
641                         / mOomMinFree[mOomAdj.length - 1]);
642                 if (mOomMinFree[i] < 0) {
643                     mOomMinFree[i] = 0;
644                 }
645             }
646         }
647 
648         // The maximum size we will restore a process from cached to background, when under
649         // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
650         // before killing background processes.
651         mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
652 
653         // Ask the kernel to try to keep enough memory free to allocate 3 full
654         // screen 32bpp buffers without entering direct reclaim.
655         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
656         int reserve_adj = Resources.getSystem().getInteger(
657                 com.android.internal.R.integer.config_extraFreeKbytesAdjust);
658         int reserve_abs = Resources.getSystem().getInteger(
659                 com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
660 
661         if (reserve_abs >= 0) {
662             reserve = reserve_abs;
663         }
664 
665         if (reserve_adj != 0) {
666             reserve += reserve_adj;
667             if (reserve < 0) {
668                 reserve = 0;
669             }
670         }
671 
672         if (write) {
673             ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
674             buf.putInt(LMK_TARGET);
675             for (int i = 0; i < mOomAdj.length; i++) {
676                 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
677                 buf.putInt(mOomAdj[i]);
678             }
679 
680             writeLmkd(buf, null);
681             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
682         }
683         // GB: 2048,3072,4096,6144,7168,8192
684         // HC: 8192,10240,12288,14336,16384,20480
685     }
686 
computeEmptyProcessLimit(int totalProcessLimit)687     public static int computeEmptyProcessLimit(int totalProcessLimit) {
688         return totalProcessLimit/2;
689     }
690 
buildOomTag(String prefix, String compactPrefix, String space, int val, int base, boolean compact)691     private static String buildOomTag(String prefix, String compactPrefix, String space, int val,
692             int base, boolean compact) {
693         final int diff = val - base;
694         if (diff == 0) {
695             if (compact) {
696                 return compactPrefix;
697             }
698             if (space == null) return prefix;
699             return prefix + space;
700         }
701         if (diff < 10) {
702             return prefix + (compact ? "+" : "+ ") + Integer.toString(diff);
703         }
704         return prefix + "+" + Integer.toString(diff);
705     }
706 
makeOomAdjString(int setAdj, boolean compact)707     public static String makeOomAdjString(int setAdj, boolean compact) {
708         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
709             return buildOomTag("cch", "cch", "   ", setAdj,
710                     ProcessList.CACHED_APP_MIN_ADJ, compact);
711         } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
712             return buildOomTag("svcb  ", "svcb", null, setAdj,
713                     ProcessList.SERVICE_B_ADJ, compact);
714         } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
715             return buildOomTag("prev  ", "prev", null, setAdj,
716                     ProcessList.PREVIOUS_APP_ADJ, compact);
717         } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
718             return buildOomTag("home  ", "home", null, setAdj,
719                     ProcessList.HOME_APP_ADJ, compact);
720         } else if (setAdj >= ProcessList.SERVICE_ADJ) {
721             return buildOomTag("svc   ", "svc", null, setAdj,
722                     ProcessList.SERVICE_ADJ, compact);
723         } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
724             return buildOomTag("hvy   ", "hvy", null, setAdj,
725                     ProcessList.HEAVY_WEIGHT_APP_ADJ, compact);
726         } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
727             return buildOomTag("bkup  ", "bkup", null, setAdj,
728                     ProcessList.BACKUP_APP_ADJ, compact);
729         } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
730             return buildOomTag("prcl  ", "prcl", null, setAdj,
731                     ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact);
732         } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
733             return buildOomTag("prcp  ", "prcp", null, setAdj,
734                     ProcessList.PERCEPTIBLE_APP_ADJ, compact);
735         } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
736             return buildOomTag("vis", "vis", "   ", setAdj,
737                     ProcessList.VISIBLE_APP_ADJ, compact);
738         } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
739             return buildOomTag("fore  ", "fore", null, setAdj,
740                     ProcessList.FOREGROUND_APP_ADJ, compact);
741         } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
742             return buildOomTag("psvc  ", "psvc", null, setAdj,
743                     ProcessList.PERSISTENT_SERVICE_ADJ, compact);
744         } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
745             return buildOomTag("pers  ", "pers", null, setAdj,
746                     ProcessList.PERSISTENT_PROC_ADJ, compact);
747         } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
748             return buildOomTag("sys   ", "sys", null, setAdj,
749                     ProcessList.SYSTEM_ADJ, compact);
750         } else if (setAdj >= ProcessList.NATIVE_ADJ) {
751             return buildOomTag("ntv  ", "ntv", null, setAdj,
752                     ProcessList.NATIVE_ADJ, compact);
753         } else {
754             return Integer.toString(setAdj);
755         }
756     }
757 
makeProcStateString(int curProcState)758     public static String makeProcStateString(int curProcState) {
759         String procState;
760         switch (curProcState) {
761             case ActivityManager.PROCESS_STATE_PERSISTENT:
762                 procState = "PER ";
763                 break;
764             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
765                 procState = "PERU";
766                 break;
767             case ActivityManager.PROCESS_STATE_TOP:
768                 procState = "TOP ";
769                 break;
770             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
771                 procState = "FGSL";
772                 break;
773             case ActivityManager.PROCESS_STATE_BOUND_TOP:
774                 procState = "BTOP";
775                 break;
776             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
777                 procState = "FGS ";
778                 break;
779             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
780                 procState = "BFGS";
781                 break;
782             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
783                 procState = "IMPF";
784                 break;
785             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
786                 procState = "IMPB";
787                 break;
788             case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
789                 procState = "TRNB";
790                 break;
791             case ActivityManager.PROCESS_STATE_BACKUP:
792                 procState = "BKUP";
793                 break;
794             case ActivityManager.PROCESS_STATE_SERVICE:
795                 procState = "SVC ";
796                 break;
797             case ActivityManager.PROCESS_STATE_RECEIVER:
798                 procState = "RCVR";
799                 break;
800             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
801                 procState = "TPSL";
802                 break;
803             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
804                 procState = "HVY ";
805                 break;
806             case ActivityManager.PROCESS_STATE_HOME:
807                 procState = "HOME";
808                 break;
809             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
810                 procState = "LAST";
811                 break;
812             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
813                 procState = "CAC ";
814                 break;
815             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
816                 procState = "CACC";
817                 break;
818             case ActivityManager.PROCESS_STATE_CACHED_RECENT:
819                 procState = "CRE ";
820                 break;
821             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
822                 procState = "CEM ";
823                 break;
824             case ActivityManager.PROCESS_STATE_NONEXISTENT:
825                 procState = "NONE";
826                 break;
827             default:
828                 procState = "??";
829                 break;
830         }
831         return procState;
832     }
833 
makeProcStateProtoEnum(int curProcState)834     public static int makeProcStateProtoEnum(int curProcState) {
835         switch (curProcState) {
836             case ActivityManager.PROCESS_STATE_PERSISTENT:
837                 return AppProtoEnums.PROCESS_STATE_PERSISTENT;
838             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
839                 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
840             case ActivityManager.PROCESS_STATE_TOP:
841                 return AppProtoEnums.PROCESS_STATE_TOP;
842             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
843                 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
844             case ActivityManager.PROCESS_STATE_BOUND_TOP:
845                 return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
846             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
847                 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
848             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
849                 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
850             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
851                 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING;
852             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
853                 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
854             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
855                 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
856             case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
857                 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND;
858             case ActivityManager.PROCESS_STATE_BACKUP:
859                 return AppProtoEnums.PROCESS_STATE_BACKUP;
860             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
861                 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT;
862             case ActivityManager.PROCESS_STATE_SERVICE:
863                 return AppProtoEnums.PROCESS_STATE_SERVICE;
864             case ActivityManager.PROCESS_STATE_RECEIVER:
865                 return AppProtoEnums.PROCESS_STATE_RECEIVER;
866             case ActivityManager.PROCESS_STATE_HOME:
867                 return AppProtoEnums.PROCESS_STATE_HOME;
868             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
869                 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY;
870             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
871                 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY;
872             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
873                 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
874             case ActivityManager.PROCESS_STATE_CACHED_RECENT:
875                 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT;
876             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
877                 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY;
878             case ActivityManager.PROCESS_STATE_NONEXISTENT:
879                 return AppProtoEnums.PROCESS_STATE_NONEXISTENT;
880             case ActivityManager.PROCESS_STATE_UNKNOWN:
881                 return AppProtoEnums.PROCESS_STATE_UNKNOWN;
882             default:
883                 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO;
884         }
885     }
886 
appendRamKb(StringBuilder sb, long ramKb)887     public static void appendRamKb(StringBuilder sb, long ramKb) {
888         for (int j = 0, fact = 10; j < 6; j++, fact *= 10) {
889             if (ramKb < fact) {
890                 sb.append(' ');
891             }
892         }
893         sb.append(ramKb);
894     }
895 
896     // How long after a state change that it is safe to collect PSS without it being dirty.
897     public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
898 
899     // The minimum time interval after a state change it is safe to collect PSS.
900     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
901 
902     // The maximum amount of time we want to go between PSS collections.
903     public static final int PSS_MAX_INTERVAL = 60*60*1000;
904 
905     // The minimum amount of time between successive PSS requests for *all* processes.
906     public static final int PSS_ALL_INTERVAL = 20*60*1000;
907 
908     // The amount of time until PSS when a persistent process first appears.
909     private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;
910 
911     // The amount of time until PSS when a process first becomes top.
912     private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
913 
914     // The amount of time until PSS when a process first goes into the background.
915     private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
916 
917     // The amount of time until PSS when a process first becomes cached.
918     private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;
919 
920     // The amount of time until PSS when an important process stays in the same state.
921     private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;
922 
923     // The amount of time until PSS when the top process stays in the same state.
924     private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;
925 
926     // The amount of time until PSS when an important process stays in the same state.
927     private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;
928 
929     // The amount of time until PSS when a service process stays in the same state.
930     private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;
931 
932     // The amount of time until PSS when a cached process stays in the same state.
933     private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;
934 
935     // The amount of time until PSS when a persistent process first appears.
936     private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
937 
938     // The amount of time until PSS when a process first becomes top.
939     private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000;
940 
941     // The amount of time until PSS when a process first goes into the background.
942     private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000;
943 
944     // The amount of time until PSS when a process first becomes cached.
945     private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000;
946 
947     // The minimum time interval after a state change it is safe to collect PSS.
948     public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
949 
950     // The amount of time during testing until PSS when a process first becomes top.
951     private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
952 
953     // The amount of time during testing until PSS when a process first goes into the background.
954     private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
955 
956     // The amount of time during testing until PSS when an important process stays in same state.
957     private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
958 
959     // The amount of time during testing until PSS when a background process stays in same state.
960     private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
961 
962     public static final int PROC_MEM_PERSISTENT = 0;
963     public static final int PROC_MEM_TOP = 1;
964     public static final int PROC_MEM_IMPORTANT = 2;
965     public static final int PROC_MEM_SERVICE = 3;
966     public static final int PROC_MEM_CACHED = 4;
967     public static final int PROC_MEM_NUM = 5;
968 
969     // Map large set of system process states to
970     private static final int[] sProcStateToProcMem = new int[] {
971         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
972         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
973         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
974         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
975         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
976         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_BOUND_TOP
977         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
978         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
979         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
980         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
981         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BACKUP
982         PROC_MEM_SERVICE,               // ActivityManager.PROCESS_STATE_SERVICE
983         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_RECEIVER
984         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
985         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
986         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_HOME
987         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
988         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
989         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
990         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_RECENT
991         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_EMPTY
992     };
993 
994     private static final long[] sFirstAwakePssTimes = new long[] {
995         PSS_FIRST_PERSISTENT_INTERVAL,  // PROC_MEM_PERSISTENT
996         PSS_FIRST_TOP_INTERVAL,         // PROC_MEM_TOP
997         PSS_FIRST_BACKGROUND_INTERVAL,  // PROC_MEM_IMPORTANT
998         PSS_FIRST_BACKGROUND_INTERVAL,  // PROC_MEM_SERVICE
999         PSS_FIRST_CACHED_INTERVAL,      // PROC_MEM_CACHED
1000     };
1001 
1002     private static final long[] sSameAwakePssTimes = new long[] {
1003         PSS_SAME_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1004         PSS_SAME_TOP_INTERVAL,          // PROC_MEM_TOP
1005         PSS_SAME_IMPORTANT_INTERVAL,    // PROC_MEM_IMPORTANT
1006         PSS_SAME_SERVICE_INTERVAL,      // PROC_MEM_SERVICE
1007         PSS_SAME_CACHED_INTERVAL,       // PROC_MEM_CACHED
1008     };
1009 
1010     private static final long[] sFirstAsleepPssTimes = new long[] {
1011         PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1012         PSS_FIRST_ASLEEP_TOP_INTERVAL,          // PROC_MEM_TOP
1013         PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // PROC_MEM_IMPORTANT
1014         PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // PROC_MEM_SERVICE
1015         PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // PROC_MEM_CACHED
1016     };
1017 
1018     private static final long[] sSameAsleepPssTimes = new long[] {
1019         PSS_SAME_PERSISTENT_INTERVAL,   // PROC_MEM_PERSISTENT
1020         PSS_SAME_TOP_INTERVAL,          // PROC_MEM_TOP
1021         PSS_SAME_IMPORTANT_INTERVAL,    // PROC_MEM_IMPORTANT
1022         PSS_SAME_SERVICE_INTERVAL,      // PROC_MEM_SERVICE
1023         PSS_SAME_CACHED_INTERVAL,       // PROC_MEM_CACHED
1024     };
1025 
1026     private static final long[] sTestFirstPssTimes = new long[] {
1027         PSS_TEST_FIRST_TOP_INTERVAL,        // PROC_MEM_PERSISTENT
1028         PSS_TEST_FIRST_TOP_INTERVAL,        // PROC_MEM_TOP
1029         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1030         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1031         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
1032     };
1033 
1034     private static final long[] sTestSamePssTimes = new long[] {
1035         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_PERSISTENT
1036         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // PROC_MEM_TOP
1037         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // PROC_MEM_IMPORTANT
1038         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_SERVICE
1039         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // PROC_MEM_CACHED
1040     };
1041 
1042     public static final class ProcStateMemTracker {
1043         final int[] mHighestMem = new int[PROC_MEM_NUM];
1044         final float[] mScalingFactor = new float[PROC_MEM_NUM];
1045         int mTotalHighestMem = PROC_MEM_CACHED;
1046 
1047         int mPendingMemState;
1048         int mPendingHighestMemState;
1049         float mPendingScalingFactor;
1050 
ProcStateMemTracker()1051         public ProcStateMemTracker() {
1052             for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
1053                 mHighestMem[i] = PROC_MEM_NUM;
1054                 mScalingFactor[i] = 1.0f;
1055             }
1056             mPendingMemState = -1;
1057         }
1058 
dumpLine(PrintWriter pw)1059         public void dumpLine(PrintWriter pw) {
1060             pw.print("best=");
1061             pw.print(mTotalHighestMem);
1062             pw.print(" (");
1063             boolean needSep = false;
1064             for (int i = 0; i < PROC_MEM_NUM; i++) {
1065                 if (mHighestMem[i] < PROC_MEM_NUM) {
1066                     if (needSep) {
1067                         pw.print(", ");
1068                         needSep = false;
1069                     }
1070                     pw.print(i);
1071                     pw.print("=");
1072                     pw.print(mHighestMem[i]);
1073                     pw.print(" ");
1074                     pw.print(mScalingFactor[i]);
1075                     pw.print("x");
1076                     needSep = true;
1077                 }
1078             }
1079             pw.print(")");
1080             if (mPendingMemState >= 0) {
1081                 pw.print(" / pending state=");
1082                 pw.print(mPendingMemState);
1083                 pw.print(" highest=");
1084                 pw.print(mPendingHighestMemState);
1085                 pw.print(" ");
1086                 pw.print(mPendingScalingFactor);
1087                 pw.print("x");
1088             }
1089             pw.println();
1090         }
1091     }
1092 
procStatesDifferForMem(int procState1, int procState2)1093     public static boolean procStatesDifferForMem(int procState1, int procState2) {
1094         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
1095     }
1096 
minTimeFromStateChange(boolean test)1097     public static long minTimeFromStateChange(boolean test) {
1098         return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
1099     }
1100 
commitNextPssTime(ProcStateMemTracker tracker)1101     public static void commitNextPssTime(ProcStateMemTracker tracker) {
1102         if (tracker.mPendingMemState >= 0) {
1103             tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
1104             tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor;
1105             tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
1106             tracker.mPendingMemState = -1;
1107         }
1108     }
1109 
abortNextPssTime(ProcStateMemTracker tracker)1110     public static void abortNextPssTime(ProcStateMemTracker tracker) {
1111         tracker.mPendingMemState = -1;
1112     }
1113 
computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, boolean sleeping, long now)1114     public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
1115             boolean sleeping, long now) {
1116         boolean first;
1117         float scalingFactor;
1118         final int memState = sProcStateToProcMem[procState];
1119         if (tracker != null) {
1120             final int highestMemState = memState < tracker.mTotalHighestMem
1121                     ? memState : tracker.mTotalHighestMem;
1122             first = highestMemState < tracker.mHighestMem[memState];
1123             tracker.mPendingMemState = memState;
1124             tracker.mPendingHighestMemState = highestMemState;
1125             if (first) {
1126                 tracker.mPendingScalingFactor = scalingFactor = 1.0f;
1127             } else {
1128                 scalingFactor = tracker.mScalingFactor[memState];
1129                 tracker.mPendingScalingFactor = scalingFactor * 1.5f;
1130             }
1131         } else {
1132             first = true;
1133             scalingFactor = 1.0f;
1134         }
1135         final long[] table = test
1136                 ? (first
1137                 ? sTestFirstPssTimes
1138                 : sTestSamePssTimes)
1139                 : (first
1140                 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
1141                 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
1142         long delay = (long)(table[memState] * scalingFactor);
1143         if (delay > PSS_MAX_INTERVAL) {
1144             delay = PSS_MAX_INTERVAL;
1145         }
1146         return now + delay;
1147     }
1148 
1149     long getMemLevel(int adjustment) {
1150         for (int i = 0; i < mOomAdj.length; i++) {
1151             if (adjustment <= mOomAdj[i]) {
1152                 return mOomMinFree[i] * 1024;
1153             }
1154         }
1155         return mOomMinFree[mOomAdj.length - 1] * 1024;
1156     }
1157 
1158     /**
1159      * Return the maximum pss size in kb that we consider a process acceptable to
1160      * restore from its cached state for running in the background when RAM is low.
1161      */
1162     long getCachedRestoreThresholdKb() {
1163         return mCachedRestoreLevel;
1164     }
1165 
1166     /**
1167      * Set the out-of-memory badness adjustment for a process.
1168      * If {@code pid <= 0}, this method will be a no-op.
1169      *
1170      * @param pid The process identifier to set.
1171      * @param uid The uid of the app
1172      * @param amt Adjustment value -- lmkd allows -1000 to +1000
1173      *
1174      * {@hide}
1175      */
1176     public static void setOomAdj(int pid, int uid, int amt) {
1177         // This indicates that the process is not started yet and so no need to proceed further.
1178         if (pid <= 0) {
1179             return;
1180         }
1181         if (amt == UNKNOWN_ADJ)
1182             return;
1183 
1184         long start = SystemClock.elapsedRealtime();
1185         ByteBuffer buf = ByteBuffer.allocate(4 * 4);
1186         buf.putInt(LMK_PROCPRIO);
1187         buf.putInt(pid);
1188         buf.putInt(uid);
1189         buf.putInt(amt);
1190         writeLmkd(buf, null);
1191         long now = SystemClock.elapsedRealtime();
1192         if ((now-start) > 250) {
1193             Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
1194                     + " = " + amt);
1195         }
1196     }
1197 
1198     /*
1199      * {@hide}
1200      */
1201     public static final void remove(int pid) {
1202         // This indicates that the process is not started yet and so no need to proceed further.
1203         if (pid <= 0) {
1204             return;
1205         }
1206         ByteBuffer buf = ByteBuffer.allocate(4 * 2);
1207         buf.putInt(LMK_PROCREMOVE);
1208         buf.putInt(pid);
1209         writeLmkd(buf, null);
1210     }
1211 
1212     /*
1213      * {@hide}
1214      */
1215     public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) {
1216         ByteBuffer buf = ByteBuffer.allocate(4 * 3);
1217         ByteBuffer repl = ByteBuffer.allocate(4 * 2);
1218         buf.putInt(LMK_GETKILLCNT);
1219         buf.putInt(min_oom_adj);
1220         buf.putInt(max_oom_adj);
1221         if (writeLmkd(buf, repl)) {
1222             int i = repl.getInt();
1223             if (i != LMK_GETKILLCNT) {
1224                 Slog.e("ActivityManager", "Failed to get kill count, code mismatch");
1225                 return null;
1226             }
1227             return new Integer(repl.getInt());
1228         }
1229         return null;
1230     }
1231 
1232     @GuardedBy("sLmkdSocketLock")
1233     private static boolean openLmkdSocketLS() {
1234         try {
1235             sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
1236             sLmkdSocket.connect(
1237                 new LocalSocketAddress("lmkd",
1238                         LocalSocketAddress.Namespace.RESERVED));
1239             sLmkdOutputStream = sLmkdSocket.getOutputStream();
1240             sLmkdInputStream = sLmkdSocket.getInputStream();
1241         } catch (IOException ex) {
1242             Slog.w(TAG, "lowmemorykiller daemon socket open failed");
1243             sLmkdSocket = null;
1244             return false;
1245         }
1246 
1247         return true;
1248     }
1249 
1250     // Never call directly, use writeLmkd() instead
1251     @GuardedBy("sLmkdSocketLock")
1252     private static boolean writeLmkdCommandLS(ByteBuffer buf) {
1253         try {
1254             sLmkdOutputStream.write(buf.array(), 0, buf.position());
1255         } catch (IOException ex) {
1256             Slog.w(TAG, "Error writing to lowmemorykiller socket");
1257             IoUtils.closeQuietly(sLmkdSocket);
1258             sLmkdSocket = null;
1259             return false;
1260         }
1261         return true;
1262     }
1263 
1264     // Never call directly, use writeLmkd() instead
1265     @GuardedBy("sLmkdSocketLock")
1266     private static boolean readLmkdReplyLS(ByteBuffer buf) {
1267         int len;
1268         try {
1269             len = sLmkdInputStream.read(buf.array(), 0, buf.array().length);
1270             if (len == buf.array().length) {
1271                 return true;
1272             }
1273         } catch (IOException ex) {
1274             Slog.w(TAG, "Error reading from lowmemorykiller socket");
1275         }
1276 
1277         IoUtils.closeQuietly(sLmkdSocket);
1278         sLmkdSocket = null;
1279         return false;
1280     }
1281 
1282     private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
1283         synchronized (sLmkdSocketLock) {
1284             for (int i = 0; i < 3; i++) {
1285                 if (sLmkdSocket == null) {
1286                     if (openLmkdSocketLS() == false) {
1287                         try {
1288                             Thread.sleep(1000);
1289                         } catch (InterruptedException ie) {
1290                         }
1291                         continue;
1292                     }
1293 
1294                     // Purge any previously registered pids
1295                     ByteBuffer purge_buf = ByteBuffer.allocate(4);
1296                     purge_buf.putInt(LMK_PROCPURGE);
1297                     if (writeLmkdCommandLS(purge_buf) == false) {
1298                         // Write failed, skip the rest and retry
1299                         continue;
1300                     }
1301                 }
1302                 if (writeLmkdCommandLS(buf) && (repl == null || readLmkdReplyLS(repl))) {
1303                     return true;
1304                 }
1305             }
1306         }
1307         return false;
1308     }
1309 
1310     static void killProcessGroup(int uid, int pid) {
1311         /* static; one-time init here */
1312         if (sKillHandler != null) {
1313             sKillHandler.sendMessage(
1314                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
1315         } else {
1316             Slog.w(TAG, "Asked to kill process group before system bringup!");
1317             Process.killProcessGroup(uid, pid);
1318         }
1319     }
1320 
1321     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean
1322             keepIfLarge) {
1323         if (uid == SYSTEM_UID) {
1324             // The system gets to run in any process.  If there are multiple
1325             // processes with the same uid, just pick the first (this
1326             // should never happen).
1327             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
1328             if (procs == null) return null;
1329             final int procCount = procs.size();
1330             for (int i = 0; i < procCount; i++) {
1331                 final int procUid = procs.keyAt(i);
1332                 if (!UserHandle.isCore(procUid) || !UserHandle.isSameUser(procUid, uid)) {
1333                     // Don't use an app process or different user process for system component.
1334                     continue;
1335                 }
1336                 return procs.valueAt(i);
1337             }
1338         }
1339         ProcessRecord proc = mProcessNames.get(processName, uid);
1340         if (false && proc != null && !keepIfLarge
1341                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
1342                 && proc.lastCachedPss >= 4000) {
1343             // Turn this condition on to cause killing to happen regularly, for testing.
1344             if (proc.baseProcessTracker != null) {
1345                 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
1346                 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1347                     ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1348                     StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1349                             proc.info.uid,
1350                             holder.state.getName(),
1351                             holder.state.getPackage(),
1352                             proc.lastCachedPss, holder.appVersion);
1353                 }
1354             }
1355             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
1356         } else if (proc != null && !keepIfLarge
1357                 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
1358                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
1359             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc
1360                     .lastCachedPss);
1361             if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) {
1362                 if (proc.baseProcessTracker != null) {
1363                     proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
1364                             proc.lastCachedPss);
1365                     for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1366                         ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1367                         StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1368                                 proc.info.uid,
1369                                 holder.state.getName(),
1370                                 holder.state.getPackage(),
1371                                 proc.lastCachedPss, holder.appVersion);
1372                     }
1373                 }
1374                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
1375             }
1376         }
1377         return proc;
1378     }
1379 
getMemoryInfo(ActivityManager.MemoryInfo outInfo)1380     void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
1381         final long homeAppMem = getMemLevel(HOME_APP_ADJ);
1382         final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ);
1383         outInfo.availMem = getFreeMemory();
1384         outInfo.totalMem = getTotalMemory();
1385         outInfo.threshold = homeAppMem;
1386         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
1387         outInfo.hiddenAppThreshold = cachedAppMem;
1388         outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ);
1389         outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ);
1390         outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ);
1391     }
1392 
1393     ProcessRecord findAppProcessLocked(IBinder app, String reason) {
1394         final int NP = mProcessNames.getMap().size();
1395         for (int ip = 0; ip < NP; ip++) {
1396             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
1397             final int NA = apps.size();
1398             for (int ia = 0; ia < NA; ia++) {
1399                 ProcessRecord p = apps.valueAt(ia);
1400                 if (p.thread != null && p.thread.asBinder() == app) {
1401                     return p;
1402                 }
1403             }
1404         }
1405 
1406         Slog.w(TAG, "Can't find mystery application for " + reason
1407                 + " from pid=" + Binder.getCallingPid()
1408                 + " uid=" + Binder.getCallingUid() + ": " + app);
1409         return null;
1410     }
1411 
1412     private void checkSlow(long startTime, String where) {
1413         long now = SystemClock.uptimeMillis();
1414         if ((now - startTime) > 50) {
1415             // If we are taking more than 50ms, log about it.
1416             Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where);
1417         }
1418     }
1419 
1420     /**
1421      * @return {@code true} if process start is successful, false otherwise.
1422      * @param app
1423      * @param hostingRecord
1424      * @param disableHiddenApiChecks
1425      * @param abiOverride
1426      */
1427     @GuardedBy("mService")
1428     boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1429             boolean disableHiddenApiChecks, boolean mountExtStorageFull,
1430             String abiOverride) {
1431         if (app.pendingStart) {
1432             return true;
1433         }
1434         long startTime = SystemClock.elapsedRealtime();
1435         if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
1436             checkSlow(startTime, "startProcess: removing from pids map");
1437             mService.mPidsSelfLocked.remove(app);
1438             mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1439             checkSlow(startTime, "startProcess: done removing from pids map");
1440             app.setPid(0);
1441             app.startSeq = 0;
1442         }
1443 
1444         if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
1445                 TAG_PROCESSES,
1446                 "startProcessLocked removing on hold: " + app);
1447         mService.mProcessesOnHold.remove(app);
1448 
1449         checkSlow(startTime, "startProcess: starting to update cpu stats");
1450         mService.updateCpuStats();
1451         checkSlow(startTime, "startProcess: done updating cpu stats");
1452 
1453         try {
1454             try {
1455                 final int userId = UserHandle.getUserId(app.uid);
1456                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
1457             } catch (RemoteException e) {
1458                 throw e.rethrowAsRuntimeException();
1459             }
1460 
1461             int uid = app.uid;
1462             int[] gids = null;
1463             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1464             if (!app.isolated) {
1465                 int[] permGids = null;
1466                 try {
1467                     checkSlow(startTime, "startProcess: getting gids from package manager");
1468                     final IPackageManager pm = AppGlobals.getPackageManager();
1469                     permGids = pm.getPackageGids(app.info.packageName,
1470                             MATCH_DIRECT_BOOT_AUTO, app.userId);
1471                     if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
1472                         mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
1473                     } else {
1474                         StorageManagerInternal storageManagerInternal = LocalServices.getService(
1475                                 StorageManagerInternal.class);
1476                         mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
1477                                 app.info.packageName);
1478                     }
1479                 } catch (RemoteException e) {
1480                     throw e.rethrowAsRuntimeException();
1481                 }
1482 
1483                 /*
1484                  * Add shared application and profile GIDs so applications can share some
1485                  * resources like shared libraries and access user-wide resources
1486                  */
1487                 if (ArrayUtils.isEmpty(permGids)) {
1488                     gids = new int[3];
1489                 } else {
1490                     gids = new int[permGids.length + 3];
1491                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
1492                 }
1493                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
1494                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
1495                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
1496 
1497                 // Replace any invalid GIDs
1498                 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
1499                 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
1500             }
1501             app.mountMode = mountExternal;
1502             checkSlow(startTime, "startProcess: building args");
1503             if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
1504                 uid = 0;
1505             }
1506             int runtimeFlags = 0;
1507             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1508                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
1509                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1510                 // Also turn on CheckJNI for debuggable apps. It's quite
1511                 // awkward to turn on otherwise.
1512                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1513 
1514                 // Check if the developer does not want ART verification
1515                 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(),
1516                         android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) {
1517                     runtimeFlags |= Zygote.DISABLE_VERIFIER;
1518                     Slog.w(TAG_PROCESSES, app + ": ART verification disabled");
1519                 }
1520             }
1521             // Run the app in safe mode if its manifest requests so or the
1522             // system is booted in safe mode.
1523             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1524                     mService.mSafeMode == true) {
1525                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1526             }
1527             if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
1528                 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
1529             }
1530             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1531                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1532             }
1533             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1534             if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1535                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1536             }
1537             String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1538             if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1539                 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1540             }
1541             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1542                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1543             }
1544             if ("1".equals(SystemProperties.get("debug.assert"))) {
1545                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1546             }
1547             if (mService.mNativeDebuggingApp != null
1548                     && mService.mNativeDebuggingApp.equals(app.processName)) {
1549                 // Enable all debug flags required by the native debugger.
1550                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
1551                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1552                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
1553                 mService.mNativeDebuggingApp = null;
1554             }
1555 
1556             if (app.info.isEmbeddedDexUsed()
1557                     || (app.info.isPrivilegedApp()
1558                         && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) {
1559                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1560             }
1561 
1562             if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
1563                 app.info.maybeUpdateHiddenApiEnforcementPolicy(
1564                         mService.mHiddenApiBlacklist.getPolicy());
1565                 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
1566                         app.info.getHiddenApiEnforcementPolicy();
1567                 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
1568                 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
1569                     throw new IllegalStateException("Invalid API policy: " + policy);
1570                 }
1571                 runtimeFlags |= policyBits;
1572             }
1573 
1574             String useAppImageCache = SystemProperties.get(
1575                     PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
1576             // Property defaults to true currently.
1577             if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) {
1578                 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
1579             }
1580 
1581             String invokeWith = null;
1582             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1583                 // Debuggable apps may include a wrapper script with their library directory.
1584                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
1585                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
1586                 try {
1587                     if (new File(wrapperFileName).exists()) {
1588                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
1589                     }
1590                 } finally {
1591                     StrictMode.setThreadPolicy(oldPolicy);
1592                 }
1593             }
1594 
1595             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
1596             if (requiredAbi == null) {
1597                 requiredAbi = Build.SUPPORTED_ABIS[0];
1598             }
1599 
1600             String instructionSet = null;
1601             if (app.info.primaryCpuAbi != null) {
1602                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
1603             }
1604 
1605             app.gids = gids;
1606             app.setRequiredAbi(requiredAbi);
1607             app.instructionSet = instructionSet;
1608 
1609             // the per-user SELinux context must be set
1610             if (TextUtils.isEmpty(app.info.seInfoUser)) {
1611                 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
1612                         new IllegalStateException("SELinux tag not defined for "
1613                                 + app.info.packageName + " (uid " + app.uid + ")"));
1614             }
1615             final String seInfo = app.info.seInfo
1616                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
1617             // Start the process.  It will either succeed and return a result containing
1618             // the PID of the new process, or else throw a RuntimeException.
1619             final String entryPoint = "android.app.ActivityThread";
1620 
1621             return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
1622                     runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
1623                     startTime);
1624         } catch (RuntimeException e) {
1625             Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1626 
1627             // Something went very wrong while trying to start this process; one
1628             // common case is when the package is frozen due to an active
1629             // upgrade. To recover, clean up any active bookkeeping related to
1630             // starting this process. (We already invoked this method once when
1631             // the package was initially frozen through KILL_APPLICATION_MSG, so
1632             // it doesn't hurt to use it again.)
1633             mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1634                     false, false, true, false, false, app.userId, "start failure");
1635             return false;
1636         }
1637     }
1638 
1639     @GuardedBy("mService")
1640     boolean startProcessLocked(HostingRecord hostingRecord,
1641             String entryPoint,
1642             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1643             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1644             long startTime) {
1645         app.pendingStart = true;
1646         app.killedByAm = false;
1647         app.removed = false;
1648         app.killed = false;
1649         if (app.startSeq != 0) {
1650             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
1651                     + " with non-zero startSeq:" + app.startSeq);
1652         }
1653         if (app.pid != 0) {
1654             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
1655                     + " with non-zero pid:" + app.pid);
1656         }
1657         final long startSeq = app.startSeq = ++mProcStartSeqCounter;
1658         app.setStartParams(uid, hostingRecord, seInfo, startTime);
1659         app.setUsingWrapper(invokeWith != null
1660                 || SystemProperties.get("wrap." + app.processName) != null);
1661         mPendingStarts.put(startSeq, app);
1662 
1663         if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
1664             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
1665                     "Posting procStart msg for " + app.toShortString());
1666             mService.mProcStartHandler.post(() -> {
1667                 try {
1668                     final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
1669                             entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
1670                             app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
1671                     synchronized (mService) {
1672                         handleProcessStartedLocked(app, startResult, startSeq);
1673                     }
1674                 } catch (RuntimeException e) {
1675                     synchronized (mService) {
1676                         Slog.e(ActivityManagerService.TAG, "Failure starting process "
1677                                 + app.processName, e);
1678                         mPendingStarts.remove(startSeq);
1679                         app.pendingStart = false;
1680                         mService.forceStopPackageLocked(app.info.packageName,
1681                                 UserHandle.getAppId(app.uid),
1682                                 false, false, true, false, false, app.userId, "start failure");
1683                     }
1684                 }
1685             });
1686             return true;
1687         } else {
1688             try {
1689                 final Process.ProcessStartResult startResult = startProcess(hostingRecord,
1690                         entryPoint, app,
1691                         uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
1692                         invokeWith, startTime);
1693                 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
1694                         startSeq, false);
1695             } catch (RuntimeException e) {
1696                 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1697                         + app.processName, e);
1698                 app.pendingStart = false;
1699                 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1700                         false, false, true, false, false, app.userId, "start failure");
1701             }
1702             return app.pid > 0;
1703         }
1704     }
1705 
1706     @GuardedBy("mService")
1707     public void killAppZygoteIfNeededLocked(AppZygote appZygote) {
1708         final ApplicationInfo appInfo = appZygote.getAppInfo();
1709         ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
1710         if (zygoteProcesses != null && zygoteProcesses.size() == 0) {
1711             // Only remove if no longer in use now
1712             mAppZygotes.remove(appInfo.processName, appInfo.uid);
1713             mAppZygoteProcesses.remove(appZygote);
1714             mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
1715             appZygote.stopZygote();
1716         }
1717     }
1718 
1719     @GuardedBy("mService")
1720     private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
1721         // Free the isolated uid for this process
1722         final IsolatedUidRange appUidRange =
1723                 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName,
1724                         app.hostingRecord.getDefiningUid());
1725         if (appUidRange != null) {
1726             appUidRange.freeIsolatedUidLocked(app.uid);
1727         }
1728 
1729         final AppZygote appZygote = mAppZygotes.get(app.info.processName,
1730                 app.hostingRecord.getDefiningUid());
1731         if (appZygote != null) {
1732             ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
1733             zygoteProcesses.remove(app);
1734             if (zygoteProcesses.size() == 0) {
1735                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG);
1736                 if (app.removed) {
1737                     // If we stopped this process because the package hosting it was removed,
1738                     // there's no point in delaying the app zygote kill.
1739                     killAppZygoteIfNeededLocked(appZygote);
1740                 } else {
1741                     Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
1742                     msg.obj = appZygote;
1743                     mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS);
1744                 }
1745             }
1746         }
1747     }
1748 
1749     private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
1750         synchronized (mService) {
1751             // The UID for the app zygote should be the UID of the application hosting
1752             // the service.
1753             final int uid = app.hostingRecord.getDefiningUid();
1754             AppZygote appZygote = mAppZygotes.get(app.info.processName, uid);
1755             final ArrayList<ProcessRecord> zygoteProcessList;
1756             if (appZygote == null) {
1757                 if (DEBUG_PROCESSES) {
1758                     Slog.d(TAG_PROCESSES, "Creating new app zygote.");
1759                 }
1760                 final IsolatedUidRange uidRange =
1761                         mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(
1762                                 app.info.processName, app.hostingRecord.getDefiningUid());
1763                 final int userId = UserHandle.getUserId(uid);
1764                 // Create the app-zygote and provide it with the UID-range it's allowed
1765                 // to setresuid/setresgid to.
1766                 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
1767                 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
1768                 ApplicationInfo appInfo = new ApplicationInfo(app.info);
1769                 // If this was an external service, the package name and uid in the passed in
1770                 // ApplicationInfo have been changed to match those of the calling package;
1771                 // that is not what we want for the AppZygote though, which needs to have the
1772                 // packageName and uid of the defining application. This is because the
1773                 // preloading only makes sense in the context of the defining application,
1774                 // not the calling one.
1775                 appInfo.packageName = app.hostingRecord.getDefiningPackageName();
1776                 appInfo.uid = uid;
1777                 appZygote = new AppZygote(appInfo, uid, firstUid, lastUid);
1778                 mAppZygotes.put(app.info.processName, uid, appZygote);
1779                 zygoteProcessList = new ArrayList<ProcessRecord>();
1780                 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
1781             } else {
1782                 if (DEBUG_PROCESSES) {
1783                     Slog.d(TAG_PROCESSES, "Reusing existing app zygote.");
1784                 }
1785                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
1786                 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
1787             }
1788             // Note that we already add the app to mAppZygoteProcesses here;
1789             // this is so that another thread can't come in and kill the zygote
1790             // before we've even tried to start the process. If the process launch
1791             // goes wrong, we'll clean this up in removeProcessNameLocked()
1792             zygoteProcessList.add(app);
1793 
1794             return appZygote;
1795         }
1796     }
1797 
1798     private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
1799             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1800             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1801             long startTime) {
1802         try {
1803             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
1804                     app.processName);
1805             checkSlow(startTime, "startProcess: asking zygote to start proc");
1806             final Process.ProcessStartResult startResult;
1807             if (hostingRecord.usesWebviewZygote()) {
1808                 startResult = startWebView(entryPoint,
1809                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1810                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1811                         app.info.dataDir, null, app.info.packageName,
1812                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1813             } else if (hostingRecord.usesAppZygote()) {
1814                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
1815 
1816                 startResult = appZygote.getProcess().start(entryPoint,
1817                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1818                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1819                         app.info.dataDir, null, app.info.packageName,
1820                         /*useUsapPool=*/ false,
1821                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1822             } else {
1823                 startResult = Process.start(entryPoint,
1824                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1825                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1826                         app.info.dataDir, invokeWith, app.info.packageName,
1827                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1828             }
1829             checkSlow(startTime, "startProcess: returned from zygote!");
1830             return startResult;
1831         } finally {
1832             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1833         }
1834     }
1835 
1836     @GuardedBy("mService")
1837     final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {
1838         startProcessLocked(app, hostingRecord, null /* abiOverride */);
1839     }
1840 
1841     @GuardedBy("mService")
1842     final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1843             String abiOverride) {
1844         return startProcessLocked(app, hostingRecord,
1845                 false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
1846     }
1847 
1848     @GuardedBy("mService")
1849     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
1850             boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
1851             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
1852             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
1853         long startTime = SystemClock.elapsedRealtime();
1854         ProcessRecord app;
1855         if (!isolated) {
1856             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
1857             checkSlow(startTime, "startProcess: after getProcessRecord");
1858 
1859             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
1860                 // If we are in the background, then check to see if this process
1861                 // is bad.  If so, we will just silently fail.
1862                 if (mService.mAppErrors.isBadProcessLocked(info)) {
1863                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1864                             + "/" + info.processName);
1865                     return null;
1866                 }
1867             } else {
1868                 // When the user is explicitly starting a process, then clear its
1869                 // crash count so that we won't make it bad until they see at
1870                 // least one crash dialog again, and make the process good again
1871                 // if it had been bad.
1872                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1873                         + "/" + info.processName);
1874                 mService.mAppErrors.resetProcessCrashTimeLocked(info);
1875                 if (mService.mAppErrors.isBadProcessLocked(info)) {
1876                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
1877                             UserHandle.getUserId(info.uid), info.uid,
1878                             info.processName);
1879                     mService.mAppErrors.clearBadProcessLocked(info);
1880                     if (app != null) {
1881                         app.bad = false;
1882                     }
1883                 }
1884             }
1885         } else {
1886             // If this is an isolated process, it can't re-use an existing process.
1887             app = null;
1888         }
1889 
1890         // We don't have to do anything more if:
1891         // (1) There is an existing application record; and
1892         // (2) The caller doesn't think it is dead, OR there is no thread
1893         //     object attached to it so we know it couldn't have crashed; and
1894         // (3) There is a pid assigned to it, so it is either starting or
1895         //     already running.
1896         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
1897                 + " app=" + app + " knownToBeDead=" + knownToBeDead
1898                 + " thread=" + (app != null ? app.thread : null)
1899                 + " pid=" + (app != null ? app.pid : -1));
1900         if (app != null && app.pid > 0) {
1901             if ((!knownToBeDead && !app.killed) || app.thread == null) {
1902                 // We already have the app running, or are waiting for it to
1903                 // come up (we have a pid but not yet its thread), so keep it.
1904                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
1905                 // If this is a new package in the process, add the package to the list
1906                 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
1907                 checkSlow(startTime, "startProcess: done, added package to proc");
1908                 return app;
1909             }
1910 
1911             // An application record is attached to a previous process,
1912             // clean it up now.
1913             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
1914             checkSlow(startTime, "startProcess: bad proc running, killing");
1915             ProcessList.killProcessGroup(app.uid, app.pid);
1916             mService.handleAppDiedLocked(app, true, true);
1917             checkSlow(startTime, "startProcess: done killing old proc");
1918         }
1919 
1920         if (app == null) {
1921             checkSlow(startTime, "startProcess: creating new process record");
1922             app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
1923             if (app == null) {
1924                 Slog.w(TAG, "Failed making new process record for "
1925                         + processName + "/" + info.uid + " isolated=" + isolated);
1926                 return null;
1927             }
1928             app.crashHandler = crashHandler;
1929             app.isolatedEntryPoint = entryPoint;
1930             app.isolatedEntryPointArgs = entryPointArgs;
1931             checkSlow(startTime, "startProcess: done creating new process record");
1932         } else {
1933             // If this is a new package in the process, add the package to the list
1934             app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
1935             checkSlow(startTime, "startProcess: added package to existing proc");
1936         }
1937 
1938         // If the system is not ready yet, then hold off on starting this
1939         // process until it is.
1940         if (!mService.mProcessesReady
1941                 && !mService.isAllowedWhileBooting(info)
1942                 && !allowWhileBooting) {
1943             if (!mService.mProcessesOnHold.contains(app)) {
1944                 mService.mProcessesOnHold.add(app);
1945             }
1946             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
1947                     "System not ready, putting on hold: " + app);
1948             checkSlow(startTime, "startProcess: returning with proc on hold");
1949             return app;
1950         }
1951 
1952         checkSlow(startTime, "startProcess: stepping in to startProcess");
1953         final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
1954         checkSlow(startTime, "startProcess: done starting proc!");
1955         return success ? app : null;
1956     }
1957 
1958     @GuardedBy("mService")
isProcStartValidLocked(ProcessRecord app, long expectedStartSeq)1959     private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
1960         StringBuilder sb = null;
1961         if (app.killedByAm) {
1962             if (sb == null) sb = new StringBuilder();
1963             sb.append("killedByAm=true;");
1964         }
1965         if (mProcessNames.get(app.processName, app.uid) != app) {
1966             if (sb == null) sb = new StringBuilder();
1967             sb.append("No entry in mProcessNames;");
1968         }
1969         if (!app.pendingStart) {
1970             if (sb == null) sb = new StringBuilder();
1971             sb.append("pendingStart=false;");
1972         }
1973         if (app.startSeq > expectedStartSeq) {
1974             if (sb == null) sb = new StringBuilder();
1975             sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
1976         }
1977         return sb == null ? null : sb.toString();
1978     }
1979 
1980     @GuardedBy("mService")
handleProcessStartedLocked(ProcessRecord pending, Process.ProcessStartResult startResult, long expectedStartSeq)1981     private boolean handleProcessStartedLocked(ProcessRecord pending,
1982             Process.ProcessStartResult startResult, long expectedStartSeq) {
1983         // Indicates that this process start has been taken care of.
1984         if (mPendingStarts.get(expectedStartSeq) == null) {
1985             if (pending.pid == startResult.pid) {
1986                 pending.setUsingWrapper(startResult.usingWrapper);
1987                 // TODO: Update already existing clients of usingWrapper
1988             }
1989             return false;
1990         }
1991         return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
1992                 expectedStartSeq, false);
1993     }
1994 
1995     @GuardedBy("mService")
handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, long expectedStartSeq, boolean procAttached)1996     boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
1997             long expectedStartSeq, boolean procAttached) {
1998         mPendingStarts.remove(expectedStartSeq);
1999         final String reason = isProcStartValidLocked(app, expectedStartSeq);
2000         if (reason != null) {
2001             Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
2002                     pid
2003                     + ", " + reason);
2004             app.pendingStart = false;
2005             killProcessQuiet(pid);
2006             Process.killProcessGroup(app.uid, app.pid);
2007             return false;
2008         }
2009         mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2010         checkSlow(app.startTime, "startProcess: done updating battery stats");
2011 
2012         EventLog.writeEvent(EventLogTags.AM_PROC_START,
2013                 UserHandle.getUserId(app.startUid), pid, app.startUid,
2014                 app.processName, app.hostingRecord.getType(),
2015                 app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
2016 
2017         try {
2018             AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
2019                     app.seInfo, app.info.sourceDir, pid);
2020         } catch (RemoteException ex) {
2021             // Ignore
2022         }
2023 
2024         if (app.isPersistent()) {
2025             Watchdog.getInstance().processStarted(app.processName, pid);
2026         }
2027 
2028         checkSlow(app.startTime, "startProcess: building log message");
2029         StringBuilder buf = mStringBuilder;
2030         buf.setLength(0);
2031         buf.append("Start proc ");
2032         buf.append(pid);
2033         buf.append(':');
2034         buf.append(app.processName);
2035         buf.append('/');
2036         UserHandle.formatUid(buf, app.startUid);
2037         if (app.isolatedEntryPoint != null) {
2038             buf.append(" [");
2039             buf.append(app.isolatedEntryPoint);
2040             buf.append("]");
2041         }
2042         buf.append(" for ");
2043         buf.append(app.hostingRecord.getType());
2044         if (app.hostingRecord.getName() != null) {
2045             buf.append(" ");
2046             buf.append(app.hostingRecord.getName());
2047         }
2048         mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
2049         app.setPid(pid);
2050         app.setUsingWrapper(usingWrapper);
2051         app.pendingStart = false;
2052         checkSlow(app.startTime, "startProcess: starting to update pids map");
2053         ProcessRecord oldApp;
2054         synchronized (mService.mPidsSelfLocked) {
2055             oldApp = mService.mPidsSelfLocked.get(pid);
2056         }
2057         // If there is already an app occupying that pid that hasn't been cleaned up
2058         if (oldApp != null && !app.isolated) {
2059             // Clean up anything relating to this pid first
2060             Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
2061                     + " startSeq:" + app.startSeq
2062                     + " pid:" + pid
2063                     + " belongs to another existing app:" + oldApp.processName
2064                     + " startSeq:" + oldApp.startSeq);
2065             mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
2066                     true /*replacingPid*/);
2067         }
2068         mService.mPidsSelfLocked.put(app);
2069         synchronized (mService.mPidsSelfLocked) {
2070             if (!procAttached) {
2071                 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2072                 msg.obj = app;
2073                 mService.mHandler.sendMessageDelayed(msg, usingWrapper
2074                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2075             }
2076         }
2077         checkSlow(app.startTime, "startProcess: done updating pids map");
2078         return true;
2079     }
2080 
removeLruProcessLocked(ProcessRecord app)2081     final void removeLruProcessLocked(ProcessRecord app) {
2082         int lrui = mLruProcesses.lastIndexOf(app);
2083         if (lrui >= 0) {
2084             if (!app.killed) {
2085                 if (app.isPersistent()) {
2086                     Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2087                 } else {
2088                     Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2089                     if (app.pid > 0) {
2090                         killProcessQuiet(app.pid);
2091                         ProcessList.killProcessGroup(app.uid, app.pid);
2092                     } else {
2093                         app.pendingStart = false;
2094                     }
2095                 }
2096             }
2097             if (lrui <= mLruProcessActivityStart) {
2098                 mLruProcessActivityStart--;
2099             }
2100             if (lrui <= mLruProcessServiceStart) {
2101                 mLruProcessServiceStart--;
2102             }
2103             mLruProcesses.remove(lrui);
2104         }
2105     }
2106 
2107     @GuardedBy("mService")
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, String reason)2108     boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
2109             String reason) {
2110         return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
2111                 false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2112                 false /* evenPersistent */, false /* setRemoved */, reason);
2113     }
2114 
2115     @GuardedBy("mService")
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, boolean setRemoved, String reason)2116     final boolean killPackageProcessesLocked(String packageName, int appId,
2117             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
2118             boolean doit, boolean evenPersistent, boolean setRemoved, String reason) {
2119         ArrayList<ProcessRecord> procs = new ArrayList<>();
2120 
2121         // Remove all processes this package may have touched: all with the
2122         // same UID (except for the system or root user), and all whose name
2123         // matches the package name.
2124         final int NP = mProcessNames.getMap().size();
2125         for (int ip = 0; ip < NP; ip++) {
2126             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2127             final int NA = apps.size();
2128             for (int ia = 0; ia < NA; ia++) {
2129                 ProcessRecord app = apps.valueAt(ia);
2130                 if (app.isPersistent() && !evenPersistent) {
2131                     // we don't kill persistent processes
2132                     continue;
2133                 }
2134                 if (app.removed) {
2135                     if (doit) {
2136                         procs.add(app);
2137                     }
2138                     continue;
2139                 }
2140 
2141                 // Skip process if it doesn't meet our oom adj requirement.
2142                 if (app.setAdj < minOomAdj) {
2143                     // Note it is still possible to have a process with oom adj 0 in the killed
2144                     // processes, but it does not mean misjudgment. E.g. a bound service process
2145                     // and its client activity process are both in the background, so they are
2146                     // collected to be killed. If the client activity is killed first, the service
2147                     // may be scheduled to unbind and become an executing service (oom adj 0).
2148                     continue;
2149                 }
2150 
2151                 // If no package is specified, we call all processes under the
2152                 // give user id.
2153                 if (packageName == null) {
2154                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
2155                         continue;
2156                     }
2157                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2158                         continue;
2159                     }
2160                     // Package has been specified, we want to hit all processes
2161                     // that match it.  We need to qualify this by the processes
2162                     // that are running under the specified app and user ID.
2163                 } else {
2164                     final boolean isDep = app.pkgDeps != null
2165                             && app.pkgDeps.contains(packageName);
2166                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2167                         continue;
2168                     }
2169                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
2170                         continue;
2171                     }
2172                     if (!app.pkgList.containsKey(packageName) && !isDep) {
2173                         continue;
2174                     }
2175                 }
2176 
2177                 // Process has passed all conditions, kill it!
2178                 if (!doit) {
2179                     return true;
2180                 }
2181                 if (setRemoved) {
2182                     app.removed = true;
2183                 }
2184                 procs.add(app);
2185             }
2186         }
2187 
2188         int N = procs.size();
2189         for (int i=0; i<N; i++) {
2190             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
2191         }
2192         // See if there are any app zygotes running for this packageName / UID combination,
2193         // and kill it if so.
2194         final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2195         for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2196             for (int i = 0; i < appZygotes.size(); ++i) {
2197                 final int appZygoteUid = appZygotes.keyAt(i);
2198                 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2199                     continue;
2200                 }
2201                 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2202                     continue;
2203                 }
2204                 final AppZygote appZygote = appZygotes.valueAt(i);
2205                 if (packageName != null
2206                         && !packageName.equals(appZygote.getAppInfo().packageName)) {
2207                     continue;
2208                 }
2209                 zygotesToKill.add(appZygote);
2210             }
2211         }
2212         for (AppZygote appZygote : zygotesToKill) {
2213             killAppZygoteIfNeededLocked(appZygote);
2214         }
2215         mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
2216         return N > 0;
2217     }
2218 
2219     @GuardedBy("mService")
removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, String reason)2220     boolean removeProcessLocked(ProcessRecord app,
2221             boolean callerWillRestart, boolean allowRestart, String reason) {
2222         final String name = app.processName;
2223         final int uid = app.uid;
2224         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
2225                 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
2226 
2227         ProcessRecord old = mProcessNames.get(name, uid);
2228         if (old != app) {
2229             // This process is no longer active, so nothing to do.
2230             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
2231             return false;
2232         }
2233         removeProcessNameLocked(name, uid);
2234         mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
2235 
2236         boolean needRestart = false;
2237         if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
2238                 .pendingStart)) {
2239             int pid = app.pid;
2240             if (pid > 0) {
2241                 mService.mPidsSelfLocked.remove(app);
2242                 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2243                 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2244                 if (app.isolated) {
2245                     mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2246                     mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
2247                 }
2248             }
2249             boolean willRestart = false;
2250             if (app.isPersistent() && !app.isolated) {
2251                 if (!callerWillRestart) {
2252                     willRestart = true;
2253                 } else {
2254                     needRestart = true;
2255                 }
2256             }
2257             app.kill(reason, true);
2258             mService.handleAppDiedLocked(app, willRestart, allowRestart);
2259             if (willRestart) {
2260                 removeLruProcessLocked(app);
2261                 mService.addAppLocked(app.info, null, false, null /* ABI override */);
2262             }
2263         } else {
2264             mRemovedProcesses.add(app);
2265         }
2266 
2267         return needRestart;
2268     }
2269 
2270     @GuardedBy("mService")
addProcessNameLocked(ProcessRecord proc)2271     final void addProcessNameLocked(ProcessRecord proc) {
2272         // We shouldn't already have a process under this name, but just in case we
2273         // need to clean up whatever may be there now.
2274         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
2275         if (old == proc && proc.isPersistent()) {
2276             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
2277             Slog.w(TAG, "Re-adding persistent process " + proc);
2278         } else if (old != null) {
2279             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
2280         }
2281         UidRecord uidRec = mActiveUids.get(proc.uid);
2282         if (uidRec == null) {
2283             uidRec = new UidRecord(proc.uid);
2284             // This is the first appearance of the uid, report it now!
2285             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2286                     "Creating new process uid: " + uidRec);
2287             if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
2288                     UserHandle.getAppId(proc.uid)) >= 0
2289                     || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
2290                 uidRec.setWhitelist = uidRec.curWhitelist = true;
2291             }
2292             uidRec.updateHasInternetPermission();
2293             mActiveUids.put(proc.uid, uidRec);
2294             EventLogTags.writeAmUidRunning(uidRec.uid);
2295             mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
2296         }
2297         proc.uidRecord = uidRec;
2298 
2299         // Reset render thread tid if it was already set, so new process can set it again.
2300         proc.renderThreadTid = 0;
2301         uidRec.numProcs++;
2302         mProcessNames.put(proc.processName, proc.uid, proc);
2303         if (proc.isolated) {
2304             mIsolatedProcesses.put(proc.uid, proc);
2305         }
2306     }
2307 
2308     @GuardedBy("mService")
getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, HostingRecord hostingRecord)2309     private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
2310             HostingRecord hostingRecord) {
2311         if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
2312             // Allocate an isolated UID from the global range
2313             return mGlobalIsolatedUids;
2314         } else {
2315             return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
2316                     info.processName, hostingRecord.getDefiningUid());
2317         }
2318     }
2319 
2320     @GuardedBy("mService")
newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid, HostingRecord hostingRecord)2321     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
2322             boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
2323         String proc = customProcess != null ? customProcess : info.processName;
2324         final int userId = UserHandle.getUserId(info.uid);
2325         int uid = info.uid;
2326         if (isolated) {
2327             if (isolatedUid == 0) {
2328                 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
2329                 if (uidRange == null) {
2330                     return null;
2331                 }
2332                 uid = uidRange.allocateIsolatedUidLocked(userId);
2333                 if (uid == -1) {
2334                     return null;
2335                 }
2336             } else {
2337                 // Special case for startIsolatedProcess (internal only), where
2338                 // the uid of the isolated process is specified by the caller.
2339                 uid = isolatedUid;
2340             }
2341             mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
2342 
2343             // Register the isolated UID with this application so BatteryStats knows to
2344             // attribute resource usage to the application.
2345             //
2346             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
2347             // about the process state of the isolated UID *before* it is registered with the
2348             // owning application.
2349             mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
2350             StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
2351                     StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
2352         }
2353         final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
2354 
2355         if (!mService.mBooted && !mService.mBooting
2356                 && userId == UserHandle.USER_SYSTEM
2357                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
2358             // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
2359             r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
2360             r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
2361             r.setPersistent(true);
2362             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
2363         }
2364         if (isolated && isolatedUid != 0) {
2365             // Special case for startIsolatedProcess (internal only) - assume the process
2366             // is required by the system server to prevent it being killed.
2367             r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
2368         }
2369         addProcessNameLocked(r);
2370         return r;
2371     }
2372 
2373     @GuardedBy("mService")
removeProcessNameLocked(final String name, final int uid)2374     final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
2375         return removeProcessNameLocked(name, uid, null);
2376     }
2377 
2378     @GuardedBy("mService")
removeProcessNameLocked(final String name, final int uid, final ProcessRecord expecting)2379     final ProcessRecord removeProcessNameLocked(final String name, final int uid,
2380             final ProcessRecord expecting) {
2381         ProcessRecord old = mProcessNames.get(name, uid);
2382         // Only actually remove when the currently recorded value matches the
2383         // record that we expected; if it doesn't match then we raced with a
2384         // newly created process and we don't want to destroy the new one.
2385         if ((expecting == null) || (old == expecting)) {
2386             mProcessNames.remove(name, uid);
2387         }
2388         if (old != null && old.uidRecord != null) {
2389             old.uidRecord.numProcs--;
2390             if (old.uidRecord.numProcs == 0) {
2391                 // No more processes using this uid, tell clients it is gone.
2392                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2393                         "No more processes in " + old.uidRecord);
2394                 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
2395                 EventLogTags.writeAmUidStopped(uid);
2396                 mActiveUids.remove(uid);
2397                 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
2398             }
2399             old.uidRecord = null;
2400         }
2401         mIsolatedProcesses.remove(uid);
2402         mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
2403         // Remove the (expected) ProcessRecord from the app zygote
2404         final ProcessRecord record = expecting != null ? expecting : old;
2405         if (record != null && record.appZygote) {
2406             removeProcessFromAppZygoteLocked(record);
2407         }
2408 
2409         return old;
2410     }
2411 
2412     /** Call setCoreSettings on all LRU processes, with the new settings. */
2413     @GuardedBy("mService")
updateCoreSettingsLocked(Bundle settings)2414     void updateCoreSettingsLocked(Bundle settings) {
2415         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2416             ProcessRecord processRecord = mLruProcesses.get(i);
2417             try {
2418                 if (processRecord.thread != null) {
2419                     processRecord.thread.setCoreSettings(settings);
2420                 }
2421             } catch (RemoteException re) {
2422                 /* ignore */
2423             }
2424         }
2425     }
2426 
2427     /**
2428      * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2429      * procstate lower than maxProcState.
2430      * @param minTargetSdk
2431      * @param maxProcState
2432      */
2433     @GuardedBy("mService")
killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState)2434     void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2435         final ArrayList<ProcessRecord> procs = new ArrayList<>();
2436         final int NP = mProcessNames.getMap().size();
2437         for (int ip = 0; ip < NP; ip++) {
2438             final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2439             final int NA = apps.size();
2440             for (int ia = 0; ia < NA; ia++) {
2441                 final ProcessRecord app = apps.valueAt(ia);
2442                 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2443                         && (maxProcState < 0 || app.setProcState > maxProcState))) {
2444                     procs.add(app);
2445                 }
2446             }
2447         }
2448 
2449         final int N = procs.size();
2450         for (int i = 0; i < N; i++) {
2451             removeProcessLocked(procs.get(i), false, true, "kill all background except");
2452         }
2453     }
2454 
2455     /**
2456      * Call updateTimePrefs on all LRU processes
2457      * @param timePref The time pref to pass to each process
2458      */
2459     @GuardedBy("mService")
updateAllTimePrefsLocked(int timePref)2460     void updateAllTimePrefsLocked(int timePref) {
2461         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2462             ProcessRecord r = mLruProcesses.get(i);
2463             if (r.thread != null) {
2464                 try {
2465                     r.thread.updateTimePrefs(timePref);
2466                 } catch (RemoteException ex) {
2467                     Slog.w(TAG, "Failed to update preferences for: "
2468                             + r.info.processName);
2469                 }
2470             }
2471         }
2472     }
2473 
setAllHttpProxy()2474     void setAllHttpProxy() {
2475         // Update the HTTP proxy for each application thread.
2476         synchronized (mService) {
2477             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2478                 ProcessRecord r = mLruProcesses.get(i);
2479                 // Don't dispatch to isolated processes as they can't access ConnectivityManager and
2480                 // don't have network privileges anyway. Exclude system server and update it
2481                 // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
2482                 if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) {
2483                     try {
2484                         r.thread.updateHttpProxy();
2485                     } catch (RemoteException ex) {
2486                         Slog.w(TAG, "Failed to update http proxy for: "
2487                                 + r.info.processName);
2488                     }
2489                 }
2490             }
2491         }
2492         ActivityThread.updateHttpProxy(mService.mContext);
2493     }
2494 
2495     @GuardedBy("mService")
clearAllDnsCacheLocked()2496     void clearAllDnsCacheLocked() {
2497         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2498             ProcessRecord r = mLruProcesses.get(i);
2499             if (r.thread != null) {
2500                 try {
2501                     r.thread.clearDnsCache();
2502                 } catch (RemoteException ex) {
2503                     Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2504                 }
2505             }
2506         }
2507     }
2508 
2509     @GuardedBy("mService")
handleAllTrustStorageUpdateLocked()2510     void handleAllTrustStorageUpdateLocked() {
2511         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2512             ProcessRecord r = mLruProcesses.get(i);
2513             if (r.thread != null) {
2514                 try {
2515                     r.thread.handleTrustStorageUpdate();
2516                 } catch (RemoteException ex) {
2517                     Slog.w(TAG, "Failed to handle trust storage update for: " +
2518                             r.info.processName);
2519                 }
2520             }
2521         }
2522     }
2523 
2524     @GuardedBy("mService")
updateLruProcessInternalLocked(ProcessRecord app, long now, int index, int lruSeq, String what, Object obj, ProcessRecord srcApp)2525     int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2526             int lruSeq, String what, Object obj, ProcessRecord srcApp) {
2527         app.lastActivityTime = now;
2528 
2529         if (app.hasActivitiesOrRecentTasks()) {
2530             // Don't want to touch dependent processes that are hosting activities.
2531             return index;
2532         }
2533 
2534         int lrui = mLruProcesses.lastIndexOf(app);
2535         if (lrui < 0) {
2536             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2537                     + what + " " + obj + " from " + srcApp);
2538             return index;
2539         }
2540 
2541         if (lrui >= index) {
2542             // Don't want to cause this to move dependent processes *back* in the
2543             // list as if they were less frequently used.
2544             return index;
2545         }
2546 
2547         if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
2548             // Don't want to touch dependent processes that are hosting activities.
2549             return index;
2550         }
2551 
2552         mLruProcesses.remove(lrui);
2553         if (index > 0) {
2554             index--;
2555         }
2556         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2557                 + " in LRU list: " + app);
2558         mLruProcesses.add(index, app);
2559         app.lruSeq = lruSeq;
2560         return index;
2561     }
2562 
2563     /**
2564      * Handle the case where we are inserting a process hosting client activities:
2565      * Make sure any groups have their order match their importance, and take care of
2566      * distributing old clients across other activity processes so they can't spam
2567      * the LRU list.  Processing of the list will be restricted by the indices provided,
2568      * and not extend out of them.
2569      *
2570      * @param topApp The app at the top that has just been inserted in to the list.
2571      * @param topI The position in the list where topApp was inserted; this is the start (at the
2572      *             top) where we are going to do our processing.
2573      * @param bottomI The last position at which we will be processing; this is the end position
2574      *                of whichever section of the LRU list we are in.  Nothing past it will be
2575      *                touched.
2576      * @param endIndex The current end of the top being processed.  Typically topI - 1.  That is,
2577      *                 where we are going to start potentially adjusting other entries in the list.
2578      */
updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI, final int bottomI, int endIndex)2579     private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
2580             final int bottomI, int endIndex) {
2581         if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
2582                 || !topApp.hasClientActivities()) {
2583             // If this is not a special process that has client activities, then there is
2584             // nothing to do.
2585             return;
2586         }
2587 
2588         final int uid = topApp.info.uid;
2589         if (topApp.connectionGroup > 0) {
2590             int endImportance = topApp.connectionImportance;
2591             for (int i = endIndex; i >= bottomI; i--) {
2592                 final ProcessRecord subProc = mLruProcesses.get(i);
2593                 if (subProc.info.uid == uid
2594                         && subProc.connectionGroup == topApp.connectionGroup) {
2595                     if (i == endIndex && subProc.connectionImportance >= endImportance) {
2596                         // This process is already in the group, and its importance
2597                         // is not as strong as the process before it, so keep it
2598                         // correctly positioned in the group.
2599                         if (DEBUG_LRU) Slog.d(TAG_LRU,
2600                                 "Keeping in-place above " + subProc
2601                                         + " endImportance=" + endImportance
2602                                         + " group=" + subProc.connectionGroup
2603                                         + " importance=" + subProc.connectionImportance);
2604                         endIndex--;
2605                         endImportance = subProc.connectionImportance;
2606                     } else {
2607                         // We want to pull this up to be with the rest of the group,
2608                         // and order within the group by importance.
2609                         if (DEBUG_LRU) Slog.d(TAG_LRU,
2610                                 "Pulling up " + subProc
2611                                         + " to position in group with importance="
2612                                         + subProc.connectionImportance);
2613                         boolean moved = false;
2614                         for (int pos = topI; pos > endIndex; pos--) {
2615                             final ProcessRecord posProc = mLruProcesses.get(pos);
2616                             if (subProc.connectionImportance
2617                                     <= posProc.connectionImportance) {
2618                                 mLruProcesses.remove(i);
2619                                 mLruProcesses.add(pos, subProc);
2620                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2621                                         "Moving " + subProc
2622                                                 + " from position " + i + " to above " + posProc
2623                                                 + " @ " + pos);
2624                                 moved = true;
2625                                 endIndex--;
2626                                 break;
2627                             }
2628                         }
2629                         if (!moved) {
2630                             // Goes to the end of the group.
2631                             mLruProcesses.remove(i);
2632                             mLruProcesses.add(endIndex - 1, subProc);
2633                             if (DEBUG_LRU) Slog.d(TAG_LRU,
2634                                     "Moving " + subProc
2635                                             + " from position " + i + " to end of group @ "
2636                                             + endIndex);
2637                             endIndex--;
2638                             endImportance = subProc.connectionImportance;
2639                         }
2640                     }
2641                 }
2642             }
2643 
2644         }
2645         // To keep it from spamming the LRU list (by making a bunch of clients),
2646         // we will distribute other entries owned by it to be in-between other apps.
2647         int i = endIndex;
2648         while (i >= bottomI) {
2649             ProcessRecord subProc = mLruProcesses.get(i);
2650             if (DEBUG_LRU) Slog.d(TAG_LRU,
2651                     "Looking to spread old procs, at " + subProc + " @ " + i);
2652             if (subProc.info.uid != uid) {
2653                 // This is a different app...  if we have gone through some of the
2654                 // target app, pull this up to be before them.  We want to pull up
2655                 // one activity process, but any number of non-activity processes.
2656                 if (i < endIndex) {
2657                     boolean hasActivity = false;
2658                     int connUid = 0;
2659                     int connGroup = 0;
2660                     while (i >= bottomI) {
2661                         mLruProcesses.remove(i);
2662                         mLruProcesses.add(endIndex, subProc);
2663                         if (DEBUG_LRU) Slog.d(TAG_LRU,
2664                                 "Different app, moving to " + endIndex);
2665                         i--;
2666                         if (i < bottomI) {
2667                             break;
2668                         }
2669                         subProc = mLruProcesses.get(i);
2670                         if (DEBUG_LRU) Slog.d(TAG_LRU,
2671                                 "Looking at next app at " + i + ": " + subProc);
2672                         if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
2673                             if (DEBUG_LRU) Slog.d(TAG_LRU,
2674                                     "This is hosting an activity!");
2675                             if (hasActivity) {
2676                                 // Already found an activity, done.
2677                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2678                                         "Already found an activity, done");
2679                                 break;
2680                             }
2681                             hasActivity = true;
2682                         } else if (subProc.hasClientActivities()) {
2683                             if (DEBUG_LRU) Slog.d(TAG_LRU,
2684                                     "This is a client of an activity");
2685                             if (hasActivity) {
2686                                 if (connUid == 0 || connUid != subProc.info.uid) {
2687                                     // Already have an activity that is not from from a client
2688                                     // connection or is a different client connection, done.
2689                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
2690                                             "Already found a different activity: connUid="
2691                                             + connUid + " uid=" + subProc.info.uid);
2692                                     break;
2693                                 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
2694                                     // Previously saw a different group or not from a group,
2695                                     // want to treat these as different things.
2696                                     if (DEBUG_LRU) Slog.d(TAG_LRU,
2697                                             "Already found a different group: connGroup="
2698                                             + connGroup + " group=" + subProc.connectionGroup);
2699                                     break;
2700                                 }
2701                             } else {
2702                                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2703                                         "This is an activity client!  uid="
2704                                         + subProc.info.uid + " group=" + subProc.connectionGroup);
2705                                 hasActivity = true;
2706                                 connUid = subProc.info.uid;
2707                                 connGroup = subProc.connectionGroup;
2708                             }
2709                         }
2710                         endIndex--;
2711                     }
2712                 }
2713                 // Find the end of the next group of processes for target app.  This
2714                 // is after any entries of different apps (so we don't change the existing
2715                 // relative order of apps) and then after the next last group of processes
2716                 // of the target app.
2717                 for (endIndex--; endIndex >= bottomI; endIndex--) {
2718                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
2719                     if (endProc.info.uid == uid) {
2720                         if (DEBUG_LRU) Slog.d(TAG_LRU,
2721                                 "Found next group of app: " + endProc + " @ "
2722                                         + endIndex);
2723                         break;
2724                     }
2725                 }
2726                 if (endIndex >= bottomI) {
2727                     final ProcessRecord endProc = mLruProcesses.get(endIndex);
2728                     for (endIndex--; endIndex >= bottomI; endIndex--) {
2729                         final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
2730                         if (nextEndProc.info.uid != uid
2731                                 || nextEndProc.connectionGroup != endProc.connectionGroup) {
2732                             if (DEBUG_LRU) Slog.d(TAG_LRU,
2733                                     "Found next group or app: " + nextEndProc + " @ "
2734                                             + endIndex + " group=" + nextEndProc.connectionGroup);
2735                             break;
2736                         }
2737                     }
2738                 }
2739                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2740                         "Bumping scan position to " + endIndex);
2741                 i = endIndex;
2742             } else {
2743                 i--;
2744             }
2745         }
2746     }
2747 
updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client)2748     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2749             ProcessRecord client) {
2750         final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
2751                 || app.treatLikeActivity;
2752         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2753         if (!activityChange && hasActivity) {
2754             // The process has activities, so we are only allowing activity-based adjustments
2755             // to move it.  It should be kept in the front of the list with other
2756             // processes that have activities, and we don't want those to change their
2757             // order except due to activity operations.
2758             return;
2759         }
2760 
2761         mLruSeq++;
2762         final long now = SystemClock.uptimeMillis();
2763         app.lastActivityTime = now;
2764 
2765         // First a quick reject: if the app is already at the position we will
2766         // put it, then there is nothing to do.
2767         if (hasActivity) {
2768             final int N = mLruProcesses.size();
2769             if (N > 0 && mLruProcesses.get(N - 1) == app) {
2770                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2771                 return;
2772             }
2773         } else {
2774             if (mLruProcessServiceStart > 0
2775                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2776                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2777                 return;
2778             }
2779         }
2780 
2781         int lrui = mLruProcesses.lastIndexOf(app);
2782 
2783         if (app.isPersistent() && lrui >= 0) {
2784             // We don't care about the position of persistent processes, as long as
2785             // they are in the list.
2786             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2787             return;
2788         }
2789 
2790         /* In progress: compute new position first, so we can avoid doing work
2791            if the process is not actually going to move.  Not yet working.
2792         int addIndex;
2793         int nextIndex;
2794         boolean inActivity = false, inService = false;
2795         if (hasActivity) {
2796             // Process has activities, put it at the very tipsy-top.
2797             addIndex = mLruProcesses.size();
2798             nextIndex = mLruProcessServiceStart;
2799             inActivity = true;
2800         } else if (hasService) {
2801             // Process has services, put it at the top of the service list.
2802             addIndex = mLruProcessActivityStart;
2803             nextIndex = mLruProcessServiceStart;
2804             inActivity = true;
2805             inService = true;
2806         } else  {
2807             // Process not otherwise of interest, it goes to the top of the non-service area.
2808             addIndex = mLruProcessServiceStart;
2809             if (client != null) {
2810                 int clientIndex = mLruProcesses.lastIndexOf(client);
2811                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2812                         + app);
2813                 if (clientIndex >= 0 && addIndex > clientIndex) {
2814                     addIndex = clientIndex;
2815                 }
2816             }
2817             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2818         }
2819 
2820         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2821                 + mLruProcessActivityStart + "): " + app);
2822         */
2823 
2824         if (lrui >= 0) {
2825             if (lrui < mLruProcessActivityStart) {
2826                 mLruProcessActivityStart--;
2827             }
2828             if (lrui < mLruProcessServiceStart) {
2829                 mLruProcessServiceStart--;
2830             }
2831             /*
2832             if (addIndex > lrui) {
2833                 addIndex--;
2834             }
2835             if (nextIndex > lrui) {
2836                 nextIndex--;
2837             }
2838             */
2839             mLruProcesses.remove(lrui);
2840         }
2841 
2842         /*
2843         mLruProcesses.add(addIndex, app);
2844         if (inActivity) {
2845             mLruProcessActivityStart++;
2846         }
2847         if (inService) {
2848             mLruProcessActivityStart++;
2849         }
2850         */
2851 
2852         int nextIndex;
2853         int nextActivityIndex = -1;
2854         if (hasActivity) {
2855             final int N = mLruProcesses.size();
2856             nextIndex = mLruProcessServiceStart;
2857             if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
2858                     && mLruProcessActivityStart < (N - 1)) {
2859                 // Process doesn't have activities, but has clients with
2860                 // activities...  move it up, but below the app that is binding to it.
2861                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2862                         "Adding to second-top of LRU activity list: " + app
2863                         + " group=" + app.connectionGroup
2864                         + " importance=" + app.connectionImportance);
2865                 int pos = N - 1;
2866                 while (pos > mLruProcessActivityStart) {
2867                     final ProcessRecord posproc = mLruProcesses.get(pos);
2868                     if (posproc.info.uid == app.info.uid) {
2869                         // Technically this app could have multiple processes with different
2870                         // activities and so we should be looking for the actual process that
2871                         // is bound to the target proc...  but I don't really care, do you?
2872                         break;
2873                     }
2874                     pos--;
2875                 }
2876                 mLruProcesses.add(pos, app);
2877                 if (pos == mLruProcessActivityStart) {
2878                     mLruProcessActivityStart++;
2879                 }
2880                 if (pos == mLruProcessServiceStart) {
2881                     // Unless {@code #hasService} is implemented, currently the starting position
2882                     // for activity and service are the same, so the incoming position may equal to
2883                     // the starting position of service.
2884                     mLruProcessServiceStart++;
2885                 }
2886                 // If this process is part of a group, need to pull up any other processes
2887                 // in that group to be with it.
2888                 int endIndex = pos - 1;
2889                 if (endIndex < mLruProcessActivityStart) {
2890                     endIndex = mLruProcessActivityStart;
2891                 }
2892                 nextActivityIndex = endIndex;
2893                 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
2894             } else {
2895                 // Process has activities, put it at the very tipsy-top.
2896                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2897                 mLruProcesses.add(app);
2898                 nextActivityIndex = mLruProcesses.size() - 1;
2899             }
2900         } else if (hasService) {
2901             // Process has services, put it at the top of the service list.
2902             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2903             mLruProcesses.add(mLruProcessActivityStart, app);
2904             nextIndex = mLruProcessServiceStart;
2905             mLruProcessActivityStart++;
2906         } else  {
2907             // Process not otherwise of interest, it goes to the top of the non-service area.
2908             int index = mLruProcessServiceStart;
2909             if (client != null) {
2910                 // If there is a client, don't allow the process to be moved up higher
2911                 // in the list than that client.
2912                 int clientIndex = mLruProcesses.lastIndexOf(client);
2913                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2914                         + " when updating " + app);
2915                 if (clientIndex <= lrui) {
2916                     // Don't allow the client index restriction to push it down farther in the
2917                     // list than it already is.
2918                     clientIndex = lrui;
2919                 }
2920                 if (clientIndex >= 0 && index > clientIndex) {
2921                     index = clientIndex;
2922                 }
2923             }
2924             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2925             mLruProcesses.add(index, app);
2926             nextIndex = index - 1;
2927             mLruProcessActivityStart++;
2928             mLruProcessServiceStart++;
2929             if (index > 1) {
2930                 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
2931             }
2932         }
2933 
2934         app.lruSeq = mLruSeq;
2935 
2936         // If the app is currently using a content provider or service,
2937         // bump those processes as well.
2938         for (int j = app.connections.size() - 1; j >= 0; j--) {
2939             ConnectionRecord cr = app.connections.valueAt(j);
2940             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2941                     && cr.binding.service.app != null
2942                     && cr.binding.service.app.lruSeq != mLruSeq
2943                     && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
2944                     && !cr.binding.service.app.isPersistent()) {
2945                 if (cr.binding.service.app.hasClientActivities()) {
2946                     if (nextActivityIndex >= 0) {
2947                         nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2948                                 now,
2949                                 nextActivityIndex, mLruSeq,
2950                                 "service connection", cr, app);
2951                     }
2952                 } else {
2953                     nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2954                             now,
2955                             nextIndex, mLruSeq,
2956                             "service connection", cr, app);
2957                 }
2958             }
2959         }
2960         for (int j = app.conProviders.size() - 1; j >= 0; j--) {
2961             ContentProviderRecord cpr = app.conProviders.get(j).provider;
2962             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
2963                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
2964                         "provider reference", cpr, app);
2965             }
2966         }
2967     }
2968 
getLRURecordForAppLocked(IApplicationThread thread)2969     final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
2970         final IBinder threadBinder = thread.asBinder();
2971         // Find the application record.
2972         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2973             final ProcessRecord rec = mLruProcesses.get(i);
2974             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2975                 return rec;
2976             }
2977         }
2978         return null;
2979     }
2980 
haveBackgroundProcessLocked()2981     boolean haveBackgroundProcessLocked() {
2982         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2983             final ProcessRecord rec = mLruProcesses.get(i);
2984             if (rec.thread != null
2985                     && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
2986                 return true;
2987             }
2988         }
2989         return false;
2990     }
2991 
procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp, int clientTargetSdk)2992     private static int procStateToImportance(int procState, int memAdj,
2993             ActivityManager.RunningAppProcessInfo currApp,
2994             int clientTargetSdk) {
2995         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
2996                 procState, clientTargetSdk);
2997         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
2998             currApp.lru = memAdj;
2999         } else {
3000             currApp.lru = 0;
3001         }
3002         return imp;
3003     }
3004 
3005     @GuardedBy("mService")
fillInProcMemInfoLocked(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, int clientTargetSdk)3006     void fillInProcMemInfoLocked(ProcessRecord app,
3007             ActivityManager.RunningAppProcessInfo outInfo,
3008             int clientTargetSdk) {
3009         outInfo.pid = app.pid;
3010         outInfo.uid = app.info.uid;
3011         if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
3012             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
3013         }
3014         if (app.isPersistent()) {
3015             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
3016         }
3017         if (app.hasActivities()) {
3018             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
3019         }
3020         outInfo.lastTrimLevel = app.trimMemoryLevel;
3021         int adj = app.curAdj;
3022         int procState = app.getCurProcState();
3023         outInfo.importance = procStateToImportance(procState, adj, outInfo,
3024                 clientTargetSdk);
3025         outInfo.importanceReasonCode = app.adjTypeCode;
3026         outInfo.processState = app.getCurProcState();
3027         outInfo.isFocused = (app == mService.getTopAppLocked());
3028         outInfo.lastActivityTime = app.lastActivityTime;
3029     }
3030 
3031     @GuardedBy("mService")
getRunningAppProcessesLocked(boolean allUsers, int userId, boolean allUids, int callingUid, int clientTargetSdk)3032     List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
3033             int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3034         // Lazy instantiation of list
3035         List<ActivityManager.RunningAppProcessInfo> runList = null;
3036 
3037         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3038             ProcessRecord app = mLruProcesses.get(i);
3039             if ((!allUsers && app.userId != userId)
3040                     || (!allUids && app.uid != callingUid)) {
3041                 continue;
3042             }
3043             if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
3044                 // Generate process state info for running application
3045                 ActivityManager.RunningAppProcessInfo currApp =
3046                         new ActivityManager.RunningAppProcessInfo(app.processName,
3047                                 app.pid, app.getPackageList());
3048                 fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
3049                 if (app.adjSource instanceof ProcessRecord) {
3050                     currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
3051                     currApp.importanceReasonImportance =
3052                             ActivityManager.RunningAppProcessInfo.procStateToImportance(
3053                                     app.adjSourceProcState);
3054                 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
3055                     final ActivityServiceConnectionsHolder r =
3056                             (ActivityServiceConnectionsHolder) app.adjSource;
3057                     final int pid = r.getActivityPid();
3058                     if (pid != -1) {
3059                         currApp.importanceReasonPid = pid;
3060                     }
3061                 }
3062                 if (app.adjTarget instanceof ComponentName) {
3063                     currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
3064                 }
3065                 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
3066                 //        + " lru=" + currApp.lru);
3067                 if (runList == null) {
3068                     runList = new ArrayList<>();
3069                 }
3070                 runList.add(currApp);
3071             }
3072         }
3073         return runList;
3074     }
3075 
3076     @GuardedBy("mService")
getLruSizeLocked()3077     int getLruSizeLocked() {
3078         return mLruProcesses.size();
3079     }
3080 
3081     @GuardedBy("mService")
dumpLruListHeaderLocked(PrintWriter pw)3082     void dumpLruListHeaderLocked(PrintWriter pw) {
3083         pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
3084         pw.print(" total, non-act at ");
3085         pw.print(mLruProcesses.size() - mLruProcessActivityStart);
3086         pw.print(", non-svc at ");
3087         pw.print(mLruProcesses.size() - mLruProcessServiceStart);
3088         pw.println("):");
3089     }
3090 
3091     @GuardedBy("mService")
collectProcessesLocked(int start, boolean allPkgs, String[] args)3092     ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
3093         ArrayList<ProcessRecord> procs;
3094         if (args != null && args.length > start
3095                 && args[start].charAt(0) != '-') {
3096             procs = new ArrayList<ProcessRecord>();
3097             int pid = -1;
3098             try {
3099                 pid = Integer.parseInt(args[start]);
3100             } catch (NumberFormatException e) {
3101             }
3102             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3103                 ProcessRecord proc = mLruProcesses.get(i);
3104                 if (proc.pid > 0 && proc.pid == pid) {
3105                     procs.add(proc);
3106                 } else if (allPkgs && proc.pkgList != null
3107                         && proc.pkgList.containsKey(args[start])) {
3108                     procs.add(proc);
3109                 } else if (proc.processName.equals(args[start])) {
3110                     procs.add(proc);
3111                 }
3112             }
3113             if (procs.size() <= 0) {
3114                 return null;
3115             }
3116         } else {
3117             procs = new ArrayList<ProcessRecord>(mLruProcesses);
3118         }
3119         return procs;
3120     }
3121 
3122     @GuardedBy("mService")
updateApplicationInfoLocked(List<String> packagesToUpdate, int userId, boolean updateFrameworkRes)3123     void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3124             boolean updateFrameworkRes) {
3125         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3126             final ProcessRecord app = mLruProcesses.get(i);
3127             if (app.thread == null) {
3128                 continue;
3129             }
3130 
3131             if (userId != UserHandle.USER_ALL && app.userId != userId) {
3132                 continue;
3133             }
3134 
3135             final int packageCount = app.pkgList.size();
3136             for (int j = 0; j < packageCount; j++) {
3137                 final String packageName = app.pkgList.keyAt(j);
3138                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
3139                     try {
3140                         final ApplicationInfo ai = AppGlobals.getPackageManager()
3141                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3142                         if (ai != null) {
3143                             app.thread.scheduleApplicationInfoChanged(ai);
3144                         }
3145                     } catch (RemoteException e) {
3146                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3147                                 packageName, app));
3148                     }
3149                 }
3150             }
3151         }
3152     }
3153 
3154     @GuardedBy("mService")
sendPackageBroadcastLocked(int cmd, String[] packages, int userId)3155     void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
3156         boolean foundProcess = false;
3157         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3158             ProcessRecord r = mLruProcesses.get(i);
3159             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3160                 try {
3161                     for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
3162                         if (packages[index].equals(r.info.packageName)) {
3163                             foundProcess = true;
3164                         }
3165                     }
3166                     r.thread.dispatchPackageBroadcast(cmd, packages);
3167                 } catch (RemoteException ex) {
3168                 }
3169             }
3170         }
3171 
3172         if (!foundProcess) {
3173             try {
3174                 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
3175             } catch (RemoteException ignored) {
3176             }
3177         }
3178     }
3179 
3180     /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3181     @GuardedBy("mService")
getUidProcStateLocked(int uid)3182     int getUidProcStateLocked(int uid) {
3183         UidRecord uidRec = mActiveUids.get(uid);
3184         return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3185     }
3186 
3187     /** Returns the UidRecord for the given uid, if it exists. */
3188     @GuardedBy("mService")
getUidRecordLocked(int uid)3189     UidRecord getUidRecordLocked(int uid) {
3190         return mActiveUids.get(uid);
3191     }
3192 
3193     /**
3194      * Call {@link ActivityManagerService#doStopUidLocked}
3195      * (which will also stop background services) for all idle UIDs.
3196      */
3197     @GuardedBy("mService")
doStopUidForIdleUidsLocked()3198     void doStopUidForIdleUidsLocked() {
3199         final int size = mActiveUids.size();
3200         for (int i = 0; i < size; i++) {
3201             final int uid = mActiveUids.keyAt(i);
3202             if (UserHandle.isCore(uid)) {
3203                 continue;
3204             }
3205             final UidRecord uidRec = mActiveUids.valueAt(i);
3206             if (!uidRec.idle) {
3207                 continue;
3208             }
3209             mService.doStopUidLocked(uidRec.uid, uidRec);
3210         }
3211     }
3212 }
3213