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