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