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 com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
     20 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
     21 
     22 import java.io.IOException;
     23 import java.io.OutputStream;
     24 import java.nio.ByteBuffer;
     25 
     26 import android.app.ActivityManager;
     27 import android.os.Build;
     28 import android.os.SystemClock;
     29 import com.android.internal.util.MemInfoReader;
     30 import com.android.server.wm.WindowManagerService;
     31 
     32 import android.content.res.Resources;
     33 import android.graphics.Point;
     34 import android.os.SystemProperties;
     35 import android.net.LocalSocketAddress;
     36 import android.net.LocalSocket;
     37 import android.util.Slog;
     38 import android.view.Display;
     39 
     40 /**
     41  * Activity manager code dealing with processes.
     42  */
     43 final class ProcessList {
     44     private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
     45 
     46     // The minimum time we allow between crashes, for us to consider this
     47     // application to be bad and stop and its services and reject broadcasts.
     48     static final int MIN_CRASH_INTERVAL = 60*1000;
     49 
     50     // OOM adjustments for processes in various states:
     51 
     52     // Uninitialized value for any major or minor adj fields
     53     static final int INVALID_ADJ = -10000;
     54 
     55     // Adjustment used in certain places where we don't know it yet.
     56     // (Generally this is something that is going to be cached, but we
     57     // don't know the exact value in the cached range to assign yet.)
     58     static final int UNKNOWN_ADJ = 1001;
     59 
     60     // This is a process only hosting activities that are not visible,
     61     // so it can be killed without any disruption.
     62     static final int CACHED_APP_MAX_ADJ = 906;
     63     static final int CACHED_APP_MIN_ADJ = 900;
     64 
     65     // The B list of SERVICE_ADJ -- these are the old and decrepit
     66     // services that aren't as shiny and interesting as the ones in the A list.
     67     static final int SERVICE_B_ADJ = 800;
     68 
     69     // This is the process of the previous application that the user was in.
     70     // This process is kept above other things, because it is very common to
     71     // switch back to the previous app.  This is important both for recent
     72     // task switch (toggling between the two top recent apps) as well as normal
     73     // UI flow such as clicking on a URI in the e-mail app to view in the browser,
     74     // and then pressing back to return to e-mail.
     75     static final int PREVIOUS_APP_ADJ = 700;
     76 
     77     // This is a process holding the home application -- we want to try
     78     // avoiding killing it, even if it would normally be in the background,
     79     // because the user interacts with it so much.
     80     static final int HOME_APP_ADJ = 600;
     81 
     82     // This is a process holding an application service -- killing it will not
     83     // have much of an impact as far as the user is concerned.
     84     static final int SERVICE_ADJ = 500;
     85 
     86     // This is a process with a heavy-weight application.  It is in the
     87     // background, but we want to try to avoid killing it.  Value set in
     88     // system/rootdir/init.rc on startup.
     89     static final int HEAVY_WEIGHT_APP_ADJ = 400;
     90 
     91     // This is a process currently hosting a backup operation.  Killing it
     92     // is not entirely fatal but is generally a bad idea.
     93     static final int BACKUP_APP_ADJ = 300;
     94 
     95     // This is a process only hosting components that are perceptible to the
     96     // user, and we really want to avoid killing them, but they are not
     97     // immediately visible. An example is background music playback.
     98     static final int PERCEPTIBLE_APP_ADJ = 200;
     99 
    100     // This is a process only hosting activities that are visible to the
    101     // user, so we'd prefer they don't disappear.
    102     static final int VISIBLE_APP_ADJ = 100;
    103     static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
    104 
    105     // This is the process running the current foreground app.  We'd really
    106     // rather not kill it!
    107     static final int FOREGROUND_APP_ADJ = 0;
    108 
    109     // This is a process that the system or a persistent process has bound to,
    110     // and indicated it is important.
    111     static final int PERSISTENT_SERVICE_ADJ = -700;
    112 
    113     // This is a system persistent process, such as telephony.  Definitely
    114     // don't want to kill it, but doing so is not completely fatal.
    115     static final int PERSISTENT_PROC_ADJ = -800;
    116 
    117     // The system process runs at the default adjustment.
    118     static final int SYSTEM_ADJ = -900;
    119 
    120     // Special code for native processes that are not being managed by the system (so
    121     // don't have an oom adj assigned by the system).
    122     static final int NATIVE_ADJ = -1000;
    123 
    124     // Memory pages are 4K.
    125     static final int PAGE_SIZE = 4*1024;
    126 
    127     // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
    128     static final int SCHED_GROUP_BACKGROUND = 0;
    129     // Activity manager's version of Process.THREAD_GROUP_DEFAULT
    130     static final int SCHED_GROUP_DEFAULT = 1;
    131     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
    132     static final int SCHED_GROUP_TOP_APP = 2;
    133     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
    134     // Disambiguate between actual top app and processes bound to the top app
    135     static final int SCHED_GROUP_TOP_APP_BOUND = 3;
    136 
    137     // The minimum number of cached apps we want to be able to keep around,
    138     // without empty apps being able to push them out of memory.
    139     static final int MIN_CACHED_APPS = 2;
    140 
    141     // The maximum number of cached processes we will keep around before killing them.
    142     // NOTE: this constant is *only* a control to not let us go too crazy with
    143     // keeping around processes on devices with large amounts of RAM.  For devices that
    144     // are tighter on RAM, the out of memory killer is responsible for killing background
    145     // processes as RAM is needed, and we should *never* be relying on this limit to
    146     // kill them.  Also note that this limit only applies to cached background processes;
    147     // we have no limit on the number of service, visible, foreground, or other such
    148     // processes and the number of those processes does not count against the cached
    149     // process limit.
    150     static final int MAX_CACHED_APPS = 32;
    151 
    152     // We allow empty processes to stick around for at most 30 minutes.
    153     static final long MAX_EMPTY_TIME = 30*60*1000;
    154 
    155     // The maximum number of empty app processes we will let sit around.
    156     private static final int MAX_EMPTY_APPS = computeEmptyProcessLimit(MAX_CACHED_APPS);
    157 
    158     // The number of empty apps at which we don't consider it necessary to do
    159     // memory trimming.
    160     static final int TRIM_EMPTY_APPS = MAX_EMPTY_APPS/2;
    161 
    162     // The number of cached at which we don't consider it necessary to do
    163     // memory trimming.
    164     static final int TRIM_CACHED_APPS = (MAX_CACHED_APPS-MAX_EMPTY_APPS)/3;
    165 
    166     // Threshold of number of cached+empty where we consider memory critical.
    167     static final int TRIM_CRITICAL_THRESHOLD = 3;
    168 
    169     // Threshold of number of cached+empty where we consider memory critical.
    170     static final int TRIM_LOW_THRESHOLD = 5;
    171 
    172     // Low Memory Killer Daemon command codes.
    173     // These must be kept in sync with the definitions in lmkd.c
    174     //
    175     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
    176     // LMK_PROCPRIO <pid> <uid> <prio>
    177     // LMK_PROCREMOVE <pid>
    178     static final byte LMK_TARGET = 0;
    179     static final byte LMK_PROCPRIO = 1;
    180     static final byte LMK_PROCREMOVE = 2;
    181 
    182     // These are the various interesting memory levels that we will give to
    183     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
    184     // can't give it a different value for every possible kind of process.
    185     private final int[] mOomAdj = new int[] {
    186             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
    187             BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
    188     };
    189     // These are the low-end OOM level limits.  This is appropriate for an
    190     // HVGA or smaller phone with less than 512MB.  Values are in KB.
    191     private final int[] mOomMinFreeLow = new int[] {
    192             12288, 18432, 24576,
    193             36864, 43008, 49152
    194     };
    195     // These are the high-end OOM level limits.  This is appropriate for a
    196     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
    197     private final int[] mOomMinFreeHigh = new int[] {
    198             73728, 92160, 110592,
    199             129024, 147456, 184320
    200     };
    201     // The actual OOM killer memory levels we are using.
    202     private final int[] mOomMinFree = new int[mOomAdj.length];
    203 
    204     private final long mTotalMemMb;
    205 
    206     private long mCachedRestoreLevel;
    207 
    208     private boolean mHaveDisplaySize;
    209 
    210     private static LocalSocket sLmkdSocket;
    211     private static OutputStream sLmkdOutputStream;
    212 
    213     ProcessList() {
    214         MemInfoReader minfo = new MemInfoReader();
    215         minfo.readMemInfo();
    216         mTotalMemMb = minfo.getTotalSize()/(1024*1024);
    217         updateOomLevels(0, 0, false);
    218     }
    219 
    220     void applyDisplaySize(WindowManagerService wm) {
    221         if (!mHaveDisplaySize) {
    222             Point p = new Point();
    223             wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
    224             if (p.x != 0 && p.y != 0) {
    225                 updateOomLevels(p.x, p.y, true);
    226                 mHaveDisplaySize = true;
    227             }
    228         }
    229     }
    230 
    231     private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
    232         // Scale buckets from avail memory: at 300MB we use the lowest values to
    233         // 700MB or more for the top values.
    234         float scaleMem = ((float)(mTotalMemMb-350))/(700-350);
    235 
    236         // Scale buckets from screen size.
    237         int minSize = 480*800;  //  384000
    238         int maxSize = 1280*800; // 1024000  230400 870400  .264
    239         float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
    240         if (false) {
    241             Slog.i("XXXXXX", "scaleMem=" + scaleMem);
    242             Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
    243                     + " dh=" + displayHeight);
    244         }
    245 
    246         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
    247         if (scale < 0) scale = 0;
    248         else if (scale > 1) scale = 1;
    249         int minfree_adj = Resources.getSystem().getInteger(
    250                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
    251         int minfree_abs = Resources.getSystem().getInteger(
    252                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
    253         if (false) {
    254             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
    255         }
    256 
    257         final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
    258 
    259         for (int i=0; i<mOomAdj.length; i++) {
    260             int low = mOomMinFreeLow[i];
    261             int high = mOomMinFreeHigh[i];
    262             if (is64bit) {
    263                 // Increase the high min-free levels for cached processes for 64-bit
    264                 if (i == 4) high = (high*3)/2;
    265                 else if (i == 5) high = (high*7)/4;
    266             }
    267             mOomMinFree[i] = (int)(low + ((high-low)*scale));
    268         }
    269 
    270         if (minfree_abs >= 0) {
    271             for (int i=0; i<mOomAdj.length; i++) {
    272                 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
    273                         / mOomMinFree[mOomAdj.length - 1]);
    274             }
    275         }
    276 
    277         if (minfree_adj != 0) {
    278             for (int i=0; i<mOomAdj.length; i++) {
    279                 mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
    280                         / mOomMinFree[mOomAdj.length - 1]);
    281                 if (mOomMinFree[i] < 0) {
    282                     mOomMinFree[i] = 0;
    283                 }
    284             }
    285         }
    286 
    287         // The maximum size we will restore a process from cached to background, when under
    288         // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
    289         // before killing background processes.
    290         mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3;
    291 
    292         // Ask the kernel to try to keep enough memory free to allocate 3 full
    293         // screen 32bpp buffers without entering direct reclaim.
    294         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
    295         int reserve_adj = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAdjust);
    296         int reserve_abs = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
    297 
    298         if (reserve_abs >= 0) {
    299             reserve = reserve_abs;
    300         }
    301 
    302         if (reserve_adj != 0) {
    303             reserve += reserve_adj;
    304             if (reserve < 0) {
    305                 reserve = 0;
    306             }
    307         }
    308 
    309         if (write) {
    310             ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1));
    311             buf.putInt(LMK_TARGET);
    312             for (int i=0; i<mOomAdj.length; i++) {
    313                 buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE);
    314                 buf.putInt(mOomAdj[i]);
    315             }
    316 
    317             writeLmkd(buf);
    318             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
    319         }
    320         // GB: 2048,3072,4096,6144,7168,8192
    321         // HC: 8192,10240,12288,14336,16384,20480
    322     }
    323 
    324     public static int computeEmptyProcessLimit(int totalProcessLimit) {
    325         return totalProcessLimit/2;
    326     }
    327 
    328     private static String buildOomTag(String prefix, String space, int val, int base) {
    329         if (val == base) {
    330             if (space == null) return prefix;
    331             return prefix + "  ";
    332         }
    333         return prefix + "+" + Integer.toString(val-base);
    334     }
    335 
    336     public static String makeOomAdjString(int setAdj) {
    337         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
    338             return buildOomTag("cch", "  ", setAdj, ProcessList.CACHED_APP_MIN_ADJ);
    339         } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
    340             return buildOomTag("svcb ", null, setAdj, ProcessList.SERVICE_B_ADJ);
    341         } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
    342             return buildOomTag("prev ", null, setAdj, ProcessList.PREVIOUS_APP_ADJ);
    343         } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
    344             return buildOomTag("home ", null, setAdj, ProcessList.HOME_APP_ADJ);
    345         } else if (setAdj >= ProcessList.SERVICE_ADJ) {
    346             return buildOomTag("svc  ", null, setAdj, ProcessList.SERVICE_ADJ);
    347         } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
    348             return buildOomTag("hvy  ", null, setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
    349         } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
    350             return buildOomTag("bkup ", null, setAdj, ProcessList.BACKUP_APP_ADJ);
    351         } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
    352             return buildOomTag("prcp ", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
    353         } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
    354             return buildOomTag("vis  ", null, setAdj, ProcessList.VISIBLE_APP_ADJ);
    355         } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
    356             return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
    357         } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
    358             return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
    359         } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
    360             return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
    361         } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
    362             return buildOomTag("sys  ", null, setAdj, ProcessList.SYSTEM_ADJ);
    363         } else if (setAdj >= ProcessList.NATIVE_ADJ) {
    364             return buildOomTag("ntv  ", null, setAdj, ProcessList.NATIVE_ADJ);
    365         } else {
    366             return Integer.toString(setAdj);
    367         }
    368     }
    369 
    370     public static String makeProcStateString(int curProcState) {
    371         String procState;
    372         switch (curProcState) {
    373             case -1:
    374                 procState = "N ";
    375                 break;
    376             case ActivityManager.PROCESS_STATE_PERSISTENT:
    377                 procState = "P ";
    378                 break;
    379             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
    380                 procState = "PU";
    381                 break;
    382             case ActivityManager.PROCESS_STATE_TOP:
    383                 procState = "T ";
    384                 break;
    385             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
    386                 procState = "SB";
    387                 break;
    388             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
    389                 procState = "SF";
    390                 break;
    391             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
    392                 procState = "TS";
    393                 break;
    394             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
    395                 procState = "IF";
    396                 break;
    397             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
    398                 procState = "IB";
    399                 break;
    400             case ActivityManager.PROCESS_STATE_BACKUP:
    401                 procState = "BU";
    402                 break;
    403             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
    404                 procState = "HW";
    405                 break;
    406             case ActivityManager.PROCESS_STATE_SERVICE:
    407                 procState = "S ";
    408                 break;
    409             case ActivityManager.PROCESS_STATE_RECEIVER:
    410                 procState = "R ";
    411                 break;
    412             case ActivityManager.PROCESS_STATE_HOME:
    413                 procState = "HO";
    414                 break;
    415             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
    416                 procState = "LA";
    417                 break;
    418             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
    419                 procState = "CA";
    420                 break;
    421             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
    422                 procState = "Ca";
    423                 break;
    424             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
    425                 procState = "CE";
    426                 break;
    427             default:
    428                 procState = "??";
    429                 break;
    430         }
    431         return procState;
    432     }
    433 
    434     public static void appendRamKb(StringBuilder sb, long ramKb) {
    435         for (int j=0, fact=10; j<6; j++, fact*=10) {
    436             if (ramKb < fact) {
    437                 sb.append(' ');
    438             }
    439         }
    440         sb.append(ramKb);
    441     }
    442 
    443     // How long after a state change that it is safe to collect PSS without it being dirty.
    444     public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
    445 
    446     // The minimum time interval after a state change it is safe to collect PSS.
    447     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
    448 
    449     // The maximum amount of time we want to go between PSS collections.
    450     public static final int PSS_MAX_INTERVAL = 30*60*1000;
    451 
    452     // The minimum amount of time between successive PSS requests for *all* processes.
    453     public static final int PSS_ALL_INTERVAL = 10*60*1000;
    454 
    455     // The minimum amount of time between successive PSS requests for a process.
    456     private static final int PSS_SHORT_INTERVAL = 2*60*1000;
    457 
    458     // The amount of time until PSS when a process first becomes top.
    459     private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
    460 
    461     // The amount of time until PSS when a process first goes into the background.
    462     private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
    463 
    464     // The amount of time until PSS when a process first becomes cached.
    465     private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000;
    466 
    467     // The amount of time until PSS when an important process stays in the same state.
    468     private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;
    469 
    470     // The amount of time until PSS when a service process stays in the same state.
    471     private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
    472 
    473     // The amount of time until PSS when a cached process stays in the same state.
    474     private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
    475 
    476     // The minimum time interval after a state change it is safe to collect PSS.
    477     public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
    478 
    479     // The amount of time during testing until PSS when a process first becomes top.
    480     private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
    481 
    482     // The amount of time during testing until PSS when a process first goes into the background.
    483     private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
    484 
    485     // The amount of time during testing until PSS when an important process stays in same state.
    486     private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
    487 
    488     // The amount of time during testing until PSS when a background process stays in same state.
    489     private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
    490 
    491     public static final int PROC_MEM_PERSISTENT = 0;
    492     public static final int PROC_MEM_TOP = 1;
    493     public static final int PROC_MEM_IMPORTANT = 2;
    494     public static final int PROC_MEM_SERVICE = 3;
    495     public static final int PROC_MEM_CACHED = 4;
    496 
    497     private static final int[] sProcStateToProcMem = new int[] {
    498         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
    499         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    500         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
    501         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    502         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    503         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    504         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    505         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    506         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BACKUP
    507         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    508         PROC_MEM_SERVICE,               // ActivityManager.PROCESS_STATE_SERVICE
    509         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_RECEIVER
    510         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_HOME
    511         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    512         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    513         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    514         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    515     };
    516 
    517     private static final long[] sFirstAwakePssTimes = new long[] {
    518         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT
    519         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    520         PSS_FIRST_TOP_INTERVAL,         // ActivityManager.PROCESS_STATE_TOP
    521         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    522         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    523         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    524         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    525         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    526         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BACKUP
    527         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    528         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
    529         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
    530         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_HOME
    531         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    532         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    533         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    534         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    535     };
    536 
    537     private static final long[] sSameAwakePssTimes = new long[] {
    538         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
    539         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    540         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_TOP
    541         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    542         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    543         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    544         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    545         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    546         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BACKUP
    547         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    548         PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_SERVICE
    549         PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
    550         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
    551         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    552         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    553         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    554         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    555     };
    556 
    557     private static final long[] sTestFirstAwakePssTimes = new long[] {
    558         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT
    559         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    560         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_TOP
    561         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    562         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    563         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    564         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    565         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    566         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
    567         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    568         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
    569         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
    570         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
    571         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    572         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    573         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    574         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    575     };
    576 
    577     private static final long[] sTestSameAwakePssTimes = new long[] {
    578         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT
    579         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    580         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP
    581         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    582         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    583         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    584         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    585         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    586         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BACKUP
    587         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    588         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
    589         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_RECEIVER
    590         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HOME
    591         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    592         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    593         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    594         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    595     };
    596 
    597     public static boolean procStatesDifferForMem(int procState1, int procState2) {
    598         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
    599     }
    600 
    601     public static long minTimeFromStateChange(boolean test) {
    602         return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
    603     }
    604 
    605     public static long computeNextPssTime(int procState, boolean first, boolean test,
    606             boolean sleeping, long now) {
    607         final long[] table = test
    608                 ? (first
    609                         ? sTestFirstAwakePssTimes
    610                         : sTestSameAwakePssTimes)
    611                 : (first
    612                         ? sFirstAwakePssTimes
    613                         : sSameAwakePssTimes);
    614         return now + table[procState];
    615     }
    616 
    617     long getMemLevel(int adjustment) {
    618         for (int i=0; i<mOomAdj.length; i++) {
    619             if (adjustment <= mOomAdj[i]) {
    620                 return mOomMinFree[i] * 1024;
    621             }
    622         }
    623         return mOomMinFree[mOomAdj.length-1] * 1024;
    624     }
    625 
    626     /**
    627      * Return the maximum pss size in kb that we consider a process acceptable to
    628      * restore from its cached state for running in the background when RAM is low.
    629      */
    630     long getCachedRestoreThresholdKb() {
    631         return mCachedRestoreLevel;
    632     }
    633 
    634     /**
    635      * Set the out-of-memory badness adjustment for a process.
    636      *
    637      * @param pid The process identifier to set.
    638      * @param uid The uid of the app
    639      * @param amt Adjustment value -- lmkd allows -16 to +15.
    640      *
    641      * {@hide}
    642      */
    643     public static final void setOomAdj(int pid, int uid, int amt) {
    644         if (amt == UNKNOWN_ADJ)
    645             return;
    646 
    647         long start = SystemClock.elapsedRealtime();
    648         ByteBuffer buf = ByteBuffer.allocate(4 * 4);
    649         buf.putInt(LMK_PROCPRIO);
    650         buf.putInt(pid);
    651         buf.putInt(uid);
    652         buf.putInt(amt);
    653         writeLmkd(buf);
    654         long now = SystemClock.elapsedRealtime();
    655         if ((now-start) > 250) {
    656             Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
    657                     + " = " + amt);
    658         }
    659     }
    660 
    661     /*
    662      * {@hide}
    663      */
    664     public static final void remove(int pid) {
    665         ByteBuffer buf = ByteBuffer.allocate(4 * 2);
    666         buf.putInt(LMK_PROCREMOVE);
    667         buf.putInt(pid);
    668         writeLmkd(buf);
    669     }
    670 
    671     private static boolean openLmkdSocket() {
    672         try {
    673             sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
    674             sLmkdSocket.connect(
    675                 new LocalSocketAddress("lmkd",
    676                         LocalSocketAddress.Namespace.RESERVED));
    677             sLmkdOutputStream = sLmkdSocket.getOutputStream();
    678         } catch (IOException ex) {
    679             Slog.w(TAG, "lowmemorykiller daemon socket open failed");
    680             sLmkdSocket = null;
    681             return false;
    682         }
    683 
    684         return true;
    685     }
    686 
    687     private static void writeLmkd(ByteBuffer buf) {
    688 
    689         for (int i = 0; i < 3; i++) {
    690             if (sLmkdSocket == null) {
    691                     if (openLmkdSocket() == false) {
    692                         try {
    693                             Thread.sleep(1000);
    694                         } catch (InterruptedException ie) {
    695                         }
    696                         continue;
    697                     }
    698             }
    699 
    700             try {
    701                 sLmkdOutputStream.write(buf.array(), 0, buf.position());
    702                 return;
    703             } catch (IOException ex) {
    704                 Slog.w(TAG, "Error writing to lowmemorykiller socket");
    705 
    706                 try {
    707                     sLmkdSocket.close();
    708                 } catch (IOException ex2) {
    709                 }
    710 
    711                 sLmkdSocket = null;
    712             }
    713         }
    714     }
    715 }
    716