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