Home | History | Annotate | Download | only in am
      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 
    399         IsolatedUidRange(int firstUid, int lastUid) {
    400             mFirstUid = firstUid;
    401             mLastUid = lastUid;
    402             mNextUid = firstUid;
    403         }
    404 
    405         @GuardedBy("ProcessList.this.mService")
    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")
    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 
    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")
    457         IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) {
    458             return mAppRanges.get(processName, uid);
    459         }
    460 
    461         @GuardedBy("ProcessList.this.mService")
    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")
    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
    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
    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 
    540         public KillHandler(Looper looper) {
    541             super(looper, null, true);
    542         }
    543 
    544         @Override
    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 
    561     ProcessList() {
    562         MemInfoReader minfo = new MemInfoReader();
    563         minfo.readMemInfo();
    564         mTotalMemMb = minfo.getTotalSize()/(1024*1024);
    565         updateOomLevels(0, 0, false);
    566     }
    567 
    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 
    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 
    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 
    687     public static int computeEmptyProcessLimit(int totalProcessLimit) {
    688         return totalProcessLimit/2;
    689     }
    690 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   1093     public static boolean procStatesDifferForMem(int procState1, int procState2) {
   1094         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
   1095     }
   1096 
   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 
   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 
   1110     public static void abortNextPssTime(ProcStateMemTracker tracker) {
   1111         tracker.mPendingMemState = -1;
   1112     }
   1113 
   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.isApp(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 
   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")
   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")
   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")
   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 
   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")
   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")
   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")
   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")
   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")
   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")
   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")
   2374     final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
   2375         return removeProcessNameLocked(name, uid, null);
   2376     }
   2377 
   2378     @GuardedBy("mService")
   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")
   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")
   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")
   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 
   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")
   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")
   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")
   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      */
   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 
   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 
   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 
   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 
   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")
   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")
   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")
   3077     int getLruSizeLocked() {
   3078         return mLruProcesses.size();
   3079     }
   3080 
   3081     @GuardedBy("mService")
   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")
   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")
   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")
   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")
   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")
   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")
   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