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     // We allow empty processes to stick around for at most 30 minutes.
    142     static final long MAX_EMPTY_TIME = 30*60*1000;
    143 
    144     // Threshold of number of cached+empty where we consider memory critical.
    145     static final int TRIM_CRITICAL_THRESHOLD = 3;
    146 
    147     // Threshold of number of cached+empty where we consider memory critical.
    148     static final int TRIM_LOW_THRESHOLD = 5;
    149 
    150     // Low Memory Killer Daemon command codes.
    151     // These must be kept in sync with the definitions in lmkd.c
    152     //
    153     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
    154     // LMK_PROCPRIO <pid> <uid> <prio>
    155     // LMK_PROCREMOVE <pid>
    156     static final byte LMK_TARGET = 0;
    157     static final byte LMK_PROCPRIO = 1;
    158     static final byte LMK_PROCREMOVE = 2;
    159 
    160     // These are the various interesting memory levels that we will give to
    161     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
    162     // can't give it a different value for every possible kind of process.
    163     private final int[] mOomAdj = new int[] {
    164             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
    165             BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
    166     };
    167     // These are the low-end OOM level limits.  This is appropriate for an
    168     // HVGA or smaller phone with less than 512MB.  Values are in KB.
    169     private final int[] mOomMinFreeLow = new int[] {
    170             12288, 18432, 24576,
    171             36864, 43008, 49152
    172     };
    173     // These are the high-end OOM level limits.  This is appropriate for a
    174     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
    175     private final int[] mOomMinFreeHigh = new int[] {
    176             73728, 92160, 110592,
    177             129024, 147456, 184320
    178     };
    179     // The actual OOM killer memory levels we are using.
    180     private final int[] mOomMinFree = new int[mOomAdj.length];
    181 
    182     private final long mTotalMemMb;
    183 
    184     private long mCachedRestoreLevel;
    185 
    186     private boolean mHaveDisplaySize;
    187 
    188     private static LocalSocket sLmkdSocket;
    189     private static OutputStream sLmkdOutputStream;
    190 
    191     ProcessList() {
    192         MemInfoReader minfo = new MemInfoReader();
    193         minfo.readMemInfo();
    194         mTotalMemMb = minfo.getTotalSize()/(1024*1024);
    195         updateOomLevels(0, 0, false);
    196     }
    197 
    198     void applyDisplaySize(WindowManagerService wm) {
    199         if (!mHaveDisplaySize) {
    200             Point p = new Point();
    201             // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
    202             wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
    203             if (p.x != 0 && p.y != 0) {
    204                 updateOomLevels(p.x, p.y, true);
    205                 mHaveDisplaySize = true;
    206             }
    207         }
    208     }
    209 
    210     private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
    211         // Scale buckets from avail memory: at 300MB we use the lowest values to
    212         // 700MB or more for the top values.
    213         float scaleMem = ((float)(mTotalMemMb-350))/(700-350);
    214 
    215         // Scale buckets from screen size.
    216         int minSize = 480*800;  //  384000
    217         int maxSize = 1280*800; // 1024000  230400 870400  .264
    218         float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
    219         if (false) {
    220             Slog.i("XXXXXX", "scaleMem=" + scaleMem);
    221             Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
    222                     + " dh=" + displayHeight);
    223         }
    224 
    225         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
    226         if (scale < 0) scale = 0;
    227         else if (scale > 1) scale = 1;
    228         int minfree_adj = Resources.getSystem().getInteger(
    229                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
    230         int minfree_abs = Resources.getSystem().getInteger(
    231                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
    232         if (false) {
    233             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
    234         }
    235 
    236         final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
    237 
    238         for (int i=0; i<mOomAdj.length; i++) {
    239             int low = mOomMinFreeLow[i];
    240             int high = mOomMinFreeHigh[i];
    241             if (is64bit) {
    242                 // Increase the high min-free levels for cached processes for 64-bit
    243                 if (i == 4) high = (high*3)/2;
    244                 else if (i == 5) high = (high*7)/4;
    245             }
    246             mOomMinFree[i] = (int)(low + ((high-low)*scale));
    247         }
    248 
    249         if (minfree_abs >= 0) {
    250             for (int i=0; i<mOomAdj.length; i++) {
    251                 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
    252                         / mOomMinFree[mOomAdj.length - 1]);
    253             }
    254         }
    255 
    256         if (minfree_adj != 0) {
    257             for (int i=0; i<mOomAdj.length; i++) {
    258                 mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
    259                         / mOomMinFree[mOomAdj.length - 1]);
    260                 if (mOomMinFree[i] < 0) {
    261                     mOomMinFree[i] = 0;
    262                 }
    263             }
    264         }
    265 
    266         // The maximum size we will restore a process from cached to background, when under
    267         // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
    268         // before killing background processes.
    269         mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3;
    270 
    271         // Ask the kernel to try to keep enough memory free to allocate 3 full
    272         // screen 32bpp buffers without entering direct reclaim.
    273         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
    274         int reserve_adj = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAdjust);
    275         int reserve_abs = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
    276 
    277         if (reserve_abs >= 0) {
    278             reserve = reserve_abs;
    279         }
    280 
    281         if (reserve_adj != 0) {
    282             reserve += reserve_adj;
    283             if (reserve < 0) {
    284                 reserve = 0;
    285             }
    286         }
    287 
    288         if (write) {
    289             ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1));
    290             buf.putInt(LMK_TARGET);
    291             for (int i=0; i<mOomAdj.length; i++) {
    292                 buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE);
    293                 buf.putInt(mOomAdj[i]);
    294             }
    295 
    296             writeLmkd(buf);
    297             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
    298         }
    299         // GB: 2048,3072,4096,6144,7168,8192
    300         // HC: 8192,10240,12288,14336,16384,20480
    301     }
    302 
    303     public static int computeEmptyProcessLimit(int totalProcessLimit) {
    304         return totalProcessLimit/2;
    305     }
    306 
    307     private static String buildOomTag(String prefix, String space, int val, int base) {
    308         if (val == base) {
    309             if (space == null) return prefix;
    310             return prefix + "  ";
    311         }
    312         return prefix + "+" + Integer.toString(val-base);
    313     }
    314 
    315     public static String makeOomAdjString(int setAdj) {
    316         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
    317             return buildOomTag("cch", "  ", setAdj, ProcessList.CACHED_APP_MIN_ADJ);
    318         } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
    319             return buildOomTag("svcb ", null, setAdj, ProcessList.SERVICE_B_ADJ);
    320         } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
    321             return buildOomTag("prev ", null, setAdj, ProcessList.PREVIOUS_APP_ADJ);
    322         } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
    323             return buildOomTag("home ", null, setAdj, ProcessList.HOME_APP_ADJ);
    324         } else if (setAdj >= ProcessList.SERVICE_ADJ) {
    325             return buildOomTag("svc  ", null, setAdj, ProcessList.SERVICE_ADJ);
    326         } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
    327             return buildOomTag("hvy  ", null, setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
    328         } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
    329             return buildOomTag("bkup ", null, setAdj, ProcessList.BACKUP_APP_ADJ);
    330         } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
    331             return buildOomTag("prcp ", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
    332         } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
    333             return buildOomTag("vis  ", null, setAdj, ProcessList.VISIBLE_APP_ADJ);
    334         } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
    335             return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
    336         } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
    337             return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
    338         } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
    339             return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
    340         } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
    341             return buildOomTag("sys  ", null, setAdj, ProcessList.SYSTEM_ADJ);
    342         } else if (setAdj >= ProcessList.NATIVE_ADJ) {
    343             return buildOomTag("ntv  ", null, setAdj, ProcessList.NATIVE_ADJ);
    344         } else {
    345             return Integer.toString(setAdj);
    346         }
    347     }
    348 
    349     public static String makeProcStateString(int curProcState) {
    350         String procState;
    351         switch (curProcState) {
    352             case ActivityManager.PROCESS_STATE_PERSISTENT:
    353                 procState = "PER ";
    354                 break;
    355             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
    356                 procState = "PERU";
    357                 break;
    358             case ActivityManager.PROCESS_STATE_TOP:
    359                 procState = "TOP ";
    360                 break;
    361             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
    362                 procState = "BFGS";
    363                 break;
    364             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
    365                 procState = "FGS ";
    366                 break;
    367             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
    368                 procState = "TPSL";
    369                 break;
    370             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
    371                 procState = "IMPF";
    372                 break;
    373             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
    374                 procState = "IMPB";
    375                 break;
    376             case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
    377                 procState = "TRNB";
    378                 break;
    379             case ActivityManager.PROCESS_STATE_BACKUP:
    380                 procState = "BKUP";
    381                 break;
    382             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
    383                 procState = "HVY ";
    384                 break;
    385             case ActivityManager.PROCESS_STATE_SERVICE:
    386                 procState = "SVC ";
    387                 break;
    388             case ActivityManager.PROCESS_STATE_RECEIVER:
    389                 procState = "RCVR";
    390                 break;
    391             case ActivityManager.PROCESS_STATE_HOME:
    392                 procState = "HOME";
    393                 break;
    394             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
    395                 procState = "LAST";
    396                 break;
    397             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
    398                 procState = "CAC ";
    399                 break;
    400             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
    401                 procState = "CACC";
    402                 break;
    403             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
    404                 procState = "CEM ";
    405                 break;
    406             case ActivityManager.PROCESS_STATE_NONEXISTENT:
    407                 procState = "NONE";
    408                 break;
    409             default:
    410                 procState = "??";
    411                 break;
    412         }
    413         return procState;
    414     }
    415 
    416     public static void appendRamKb(StringBuilder sb, long ramKb) {
    417         for (int j=0, fact=10; j<6; j++, fact*=10) {
    418             if (ramKb < fact) {
    419                 sb.append(' ');
    420             }
    421         }
    422         sb.append(ramKb);
    423     }
    424 
    425     // How long after a state change that it is safe to collect PSS without it being dirty.
    426     public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
    427 
    428     // The minimum time interval after a state change it is safe to collect PSS.
    429     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
    430 
    431     // The maximum amount of time we want to go between PSS collections.
    432     public static final int PSS_MAX_INTERVAL = 30*60*1000;
    433 
    434     // The minimum amount of time between successive PSS requests for *all* processes.
    435     public static final int PSS_ALL_INTERVAL = 10*60*1000;
    436 
    437     // The minimum amount of time between successive PSS requests for a process.
    438     private static final int PSS_SHORT_INTERVAL = 2*60*1000;
    439 
    440     // The amount of time until PSS when a process first becomes top.
    441     private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
    442 
    443     // The amount of time until PSS when a process first goes into the background.
    444     private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
    445 
    446     // The amount of time until PSS when a process first becomes cached.
    447     private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000;
    448 
    449     // The amount of time until PSS when an important process stays in the same state.
    450     private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;
    451 
    452     // The amount of time until PSS when a service process stays in the same state.
    453     private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
    454 
    455     // The amount of time until PSS when a cached process stays in the same state.
    456     private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
    457 
    458     // The minimum time interval after a state change it is safe to collect PSS.
    459     public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
    460 
    461     // The amount of time during testing until PSS when a process first becomes top.
    462     private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
    463 
    464     // The amount of time during testing until PSS when a process first goes into the background.
    465     private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
    466 
    467     // The amount of time during testing until PSS when an important process stays in same state.
    468     private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
    469 
    470     // The amount of time during testing until PSS when a background process stays in same state.
    471     private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
    472 
    473     public static final int PROC_MEM_PERSISTENT = 0;
    474     public static final int PROC_MEM_TOP = 1;
    475     public static final int PROC_MEM_IMPORTANT = 2;
    476     public static final int PROC_MEM_SERVICE = 3;
    477     public static final int PROC_MEM_CACHED = 4;
    478 
    479     private static final int[] sProcStateToProcMem = new int[] {
    480         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
    481         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    482         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
    483         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    484         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    485         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    486         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    487         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    488         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
    489         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BACKUP
    490         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    491         PROC_MEM_SERVICE,               // ActivityManager.PROCESS_STATE_SERVICE
    492         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_RECEIVER
    493         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_HOME
    494         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    495         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    496         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    497         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    498     };
    499 
    500     private static final long[] sFirstAwakePssTimes = new long[] {
    501         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT
    502         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    503         PSS_FIRST_TOP_INTERVAL,         // ActivityManager.PROCESS_STATE_TOP
    504         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    505         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    506         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    507         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    508         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    509         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
    510         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BACKUP
    511         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    512         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
    513         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
    514         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_HOME
    515         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    516         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    517         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    518         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    519     };
    520 
    521     private static final long[] sSameAwakePssTimes = new long[] {
    522         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
    523         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    524         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_TOP
    525         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    526         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    527         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    528         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    529         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    530         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
    531         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BACKUP
    532         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    533         PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_SERVICE
    534         PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
    535         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
    536         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    537         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    538         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    539         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    540     };
    541 
    542     private static final long[] sTestFirstAwakePssTimes = new long[] {
    543         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT
    544         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    545         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_TOP
    546         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    547         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    548         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    549         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    550         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    551         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
    552         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
    553         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    554         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
    555         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
    556         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
    557         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    558         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    559         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    560         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    561     };
    562 
    563     private static final long[] sTestSameAwakePssTimes = new long[] {
    564         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT
    565         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT_UI
    566         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP
    567         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
    568         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
    569         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
    570         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
    571         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
    572         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
    573         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BACKUP
    574         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
    575         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
    576         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_RECEIVER
    577         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HOME
    578         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
    579         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
    580         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
    581         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    582     };
    583 
    584     public static boolean procStatesDifferForMem(int procState1, int procState2) {
    585         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
    586     }
    587 
    588     public static long minTimeFromStateChange(boolean test) {
    589         return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
    590     }
    591 
    592     public static long computeNextPssTime(int procState, boolean first, boolean test,
    593             boolean sleeping, long now) {
    594         final long[] table = test
    595                 ? (first
    596                         ? sTestFirstAwakePssTimes
    597                         : sTestSameAwakePssTimes)
    598                 : (first
    599                         ? sFirstAwakePssTimes
    600                         : sSameAwakePssTimes);
    601         return now + table[procState];
    602     }
    603 
    604     long getMemLevel(int adjustment) {
    605         for (int i=0; i<mOomAdj.length; i++) {
    606             if (adjustment <= mOomAdj[i]) {
    607                 return mOomMinFree[i] * 1024;
    608             }
    609         }
    610         return mOomMinFree[mOomAdj.length-1] * 1024;
    611     }
    612 
    613     /**
    614      * Return the maximum pss size in kb that we consider a process acceptable to
    615      * restore from its cached state for running in the background when RAM is low.
    616      */
    617     long getCachedRestoreThresholdKb() {
    618         return mCachedRestoreLevel;
    619     }
    620 
    621     /**
    622      * Set the out-of-memory badness adjustment for a process.
    623      *
    624      * @param pid The process identifier to set.
    625      * @param uid The uid of the app
    626      * @param amt Adjustment value -- lmkd allows -16 to +15.
    627      *
    628      * {@hide}
    629      */
    630     public static final void setOomAdj(int pid, int uid, int amt) {
    631         if (amt == UNKNOWN_ADJ)
    632             return;
    633 
    634         long start = SystemClock.elapsedRealtime();
    635         ByteBuffer buf = ByteBuffer.allocate(4 * 4);
    636         buf.putInt(LMK_PROCPRIO);
    637         buf.putInt(pid);
    638         buf.putInt(uid);
    639         buf.putInt(amt);
    640         writeLmkd(buf);
    641         long now = SystemClock.elapsedRealtime();
    642         if ((now-start) > 250) {
    643             Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
    644                     + " = " + amt);
    645         }
    646     }
    647 
    648     /*
    649      * {@hide}
    650      */
    651     public static final void remove(int pid) {
    652         ByteBuffer buf = ByteBuffer.allocate(4 * 2);
    653         buf.putInt(LMK_PROCREMOVE);
    654         buf.putInt(pid);
    655         writeLmkd(buf);
    656     }
    657 
    658     private static boolean openLmkdSocket() {
    659         try {
    660             sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
    661             sLmkdSocket.connect(
    662                 new LocalSocketAddress("lmkd",
    663                         LocalSocketAddress.Namespace.RESERVED));
    664             sLmkdOutputStream = sLmkdSocket.getOutputStream();
    665         } catch (IOException ex) {
    666             Slog.w(TAG, "lowmemorykiller daemon socket open failed");
    667             sLmkdSocket = null;
    668             return false;
    669         }
    670 
    671         return true;
    672     }
    673 
    674     private static void writeLmkd(ByteBuffer buf) {
    675 
    676         for (int i = 0; i < 3; i++) {
    677             if (sLmkdSocket == null) {
    678                     if (openLmkdSocket() == false) {
    679                         try {
    680                             Thread.sleep(1000);
    681                         } catch (InterruptedException ie) {
    682                         }
    683                         continue;
    684                     }
    685             }
    686 
    687             try {
    688                 sLmkdOutputStream.write(buf.array(), 0, buf.position());
    689                 return;
    690             } catch (IOException ex) {
    691                 Slog.w(TAG, "Error writing to lowmemorykiller socket");
    692 
    693                 try {
    694                     sLmkdSocket.close();
    695                 } catch (IOException ex2) {
    696                 }
    697 
    698                 sLmkdSocket = null;
    699             }
    700         }
    701     }
    702 }
    703