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