blob: ab5d64c48ac8497fcd5662a9a79efa76dfc5cf35 [file] [log] [blame]
Dianne Hackborn7d608422011-08-07 16:24:18 -07001/*
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
Wale Ogunwalee23149f2015-03-06 15:39:44 -080019import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
20import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
21
Dianne Hackborn7d608422011-08-07 16:24:18 -070022import java.io.IOException;
Todd Poynorbfdd6232013-07-10 19:15:07 -070023import java.io.OutputStream;
24import java.nio.ByteBuffer;
Dianne Hackborn7d608422011-08-07 16:24:18 -070025
Dianne Hackborn8e692572013-09-10 19:06:15 -070026import android.app.ActivityManager;
Dianne Hackborn9d52f792014-09-11 17:46:06 -070027import android.os.Build;
Dianne Hackbornecf1cda2014-08-28 16:58:28 -070028import android.os.SystemClock;
Dianne Hackborn7d608422011-08-07 16:24:18 -070029import com.android.internal.util.MemInfoReader;
30import com.android.server.wm.WindowManagerService;
31
Colin Crossfcdad6f2013-07-25 15:04:40 -070032import android.content.res.Resources;
Dianne Hackborn7d608422011-08-07 16:24:18 -070033import android.graphics.Point;
Colin Cross59d80a52013-07-25 10:45:05 -070034import android.os.SystemProperties;
Todd Poynorbfdd6232013-07-10 19:15:07 -070035import android.net.LocalSocketAddress;
36import android.net.LocalSocket;
Dianne Hackborn7d608422011-08-07 16:24:18 -070037import android.util.Slog;
Craig Mautner59c00972012-07-30 12:10:24 -070038import android.view.Display;
Dianne Hackborn7d608422011-08-07 16:24:18 -070039
40/**
41 * Activity manager code dealing with processes.
42 */
Sudheer Shanka352dc572017-09-22 17:09:38 -070043public final class ProcessList {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080044 private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
45
Dianne Hackborn7d608422011-08-07 16:24:18 -070046 // The minimum time we allow between crashes, for us to consider this
47 // application to be bad and stop and its services and reject broadcasts.
48 static final int MIN_CRASH_INTERVAL = 60*1000;
49
50 // OOM adjustments for processes in various states:
51
Chong Zhangfdcc4d42015-10-14 16:50:12 -070052 // Uninitialized value for any major or minor adj fields
53 static final int INVALID_ADJ = -10000;
54
Dianne Hackbornc8230512013-07-13 21:32:12 -070055 // Adjustment used in certain places where we don't know it yet.
56 // (Generally this is something that is going to be cached, but we
57 // don't know the exact value in the cached range to assign yet.)
Chong Zhangfdcc4d42015-10-14 16:50:12 -070058 static final int UNKNOWN_ADJ = 1001;
Dianne Hackbornc8230512013-07-13 21:32:12 -070059
Dianne Hackborn7d608422011-08-07 16:24:18 -070060 // This is a process only hosting activities that are not visible,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070061 // so it can be killed without any disruption.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070062 static final int CACHED_APP_MAX_ADJ = 906;
63 static final int CACHED_APP_MIN_ADJ = 900;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070064
65 // The B list of SERVICE_ADJ -- these are the old and decrepit
66 // services that aren't as shiny and interesting as the ones in the A list.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070067 static final int SERVICE_B_ADJ = 800;
Dianne Hackbornf35fe232011-11-01 19:25:20 -070068
69 // This is the process of the previous application that the user was in.
70 // This process is kept above other things, because it is very common to
71 // switch back to the previous app. This is important both for recent
72 // task switch (toggling between the two top recent apps) as well as normal
73 // UI flow such as clicking on a URI in the e-mail app to view in the browser,
74 // and then pressing back to return to e-mail.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070075 static final int PREVIOUS_APP_ADJ = 700;
Dianne Hackborn7d608422011-08-07 16:24:18 -070076
77 // This is a process holding the home application -- we want to try
78 // avoiding killing it, even if it would normally be in the background,
79 // because the user interacts with it so much.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070080 static final int HOME_APP_ADJ = 600;
Dianne Hackborn7d608422011-08-07 16:24:18 -070081
Dianne Hackborne02c88a2011-10-28 13:58:15 -070082 // This is a process holding an application service -- killing it will not
83 // have much of an impact as far as the user is concerned.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070084 static final int SERVICE_ADJ = 500;
Dianne Hackborn7d608422011-08-07 16:24:18 -070085
Dianne Hackborn7d608422011-08-07 16:24:18 -070086 // This is a process with a heavy-weight application. It is in the
87 // background, but we want to try to avoid killing it. Value set in
88 // system/rootdir/init.rc on startup.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070089 static final int HEAVY_WEIGHT_APP_ADJ = 400;
Dianne Hackbornc8230512013-07-13 21:32:12 -070090
91 // This is a process currently hosting a backup operation. Killing it
92 // is not entirely fatal but is generally a bad idea.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070093 static final int BACKUP_APP_ADJ = 300;
Dianne Hackborn7d608422011-08-07 16:24:18 -070094
95 // This is a process only hosting components that are perceptible to the
96 // user, and we really want to avoid killing them, but they are not
Dianne Hackborne02c88a2011-10-28 13:58:15 -070097 // immediately visible. An example is background music playback.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070098 static final int PERCEPTIBLE_APP_ADJ = 200;
Dianne Hackborn7d608422011-08-07 16:24:18 -070099
100 // This is a process only hosting activities that are visible to the
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700101 // user, so we'd prefer they don't disappear.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700102 static final int VISIBLE_APP_ADJ = 100;
103 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700104
105 // This is the process running the current foreground app. We'd really
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700106 // rather not kill it!
Dianne Hackborn7d608422011-08-07 16:24:18 -0700107 static final int FOREGROUND_APP_ADJ = 0;
108
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700109 // This is a process that the system or a persistent process has bound to,
110 // and indicated it is important.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700111 static final int PERSISTENT_SERVICE_ADJ = -700;
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700112
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700113 // This is a system persistent process, such as telephony. Definitely
Dianne Hackborn7d608422011-08-07 16:24:18 -0700114 // don't want to kill it, but doing so is not completely fatal.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700115 static final int PERSISTENT_PROC_ADJ = -800;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700116
117 // The system process runs at the default adjustment.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700118 static final int SYSTEM_ADJ = -900;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700119
Dianne Hackborn8e692572013-09-10 19:06:15 -0700120 // Special code for native processes that are not being managed by the system (so
121 // don't have an oom adj assigned by the system).
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700122 static final int NATIVE_ADJ = -1000;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700123
Dianne Hackborn7d608422011-08-07 16:24:18 -0700124 // Memory pages are 4K.
125 static final int PAGE_SIZE = 4*1024;
126
Dianne Hackborna49ad092016-03-03 13:39:10 -0800127 // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
128 static final int SCHED_GROUP_BACKGROUND = 0;
129 // Activity manager's version of Process.THREAD_GROUP_DEFAULT
130 static final int SCHED_GROUP_DEFAULT = 1;
131 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
132 static final int SCHED_GROUP_TOP_APP = 2;
Tim Murray33eb07f2016-06-10 10:03:20 -0700133 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
134 // Disambiguate between actual top app and processes bound to the top app
135 static final int SCHED_GROUP_TOP_APP_BOUND = 3;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800136
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700137 // The minimum number of cached apps we want to be able to keep around,
Dianne Hackborn7d608422011-08-07 16:24:18 -0700138 // without empty apps being able to push them out of memory.
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700139 static final int MIN_CACHED_APPS = 2;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700140
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700141 // We allow empty processes to stick around for at most 30 minutes.
142 static final long MAX_EMPTY_TIME = 30*60*1000;
143
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700144 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700145 static final int TRIM_CRITICAL_THRESHOLD = 3;
146
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700147 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700148 static final int TRIM_LOW_THRESHOLD = 5;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700149
Todd Poynorbfdd6232013-07-10 19:15:07 -0700150 // Low Memory Killer Daemon command codes.
151 // These must be kept in sync with the definitions in lmkd.c
152 //
153 // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700154 // LMK_PROCPRIO <pid> <uid> <prio>
Todd Poynorbfdd6232013-07-10 19:15:07 -0700155 // LMK_PROCREMOVE <pid>
156 static final byte LMK_TARGET = 0;
157 static final byte LMK_PROCPRIO = 1;
158 static final byte LMK_PROCREMOVE = 2;
159
Dianne Hackborn7d608422011-08-07 16:24:18 -0700160 // These are the various interesting memory levels that we will give to
161 // the OOM killer. Note that the OOM killer only supports 6 slots, so we
162 // can't give it a different value for every possible kind of process.
163 private final int[] mOomAdj = new int[] {
164 FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700165 BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
Dianne Hackborn7d608422011-08-07 16:24:18 -0700166 };
167 // These are the low-end OOM level limits. This is appropriate for an
168 // HVGA or smaller phone with less than 512MB. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700169 private final int[] mOomMinFreeLow = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700170 12288, 18432, 24576,
171 36864, 43008, 49152
Dianne Hackborn7d608422011-08-07 16:24:18 -0700172 };
173 // These are the high-end OOM level limits. This is appropriate for a
174 // 1280x800 or larger screen with around 1GB RAM. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700175 private final int[] mOomMinFreeHigh = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700176 73728, 92160, 110592,
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800177 129024, 147456, 184320
Dianne Hackborn7d608422011-08-07 16:24:18 -0700178 };
179 // The actual OOM killer memory levels we are using.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700180 private final int[] mOomMinFree = new int[mOomAdj.length];
Dianne Hackborn7d608422011-08-07 16:24:18 -0700181
182 private final long mTotalMemMb;
183
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700184 private long mCachedRestoreLevel;
185
Dianne Hackborn7d608422011-08-07 16:24:18 -0700186 private boolean mHaveDisplaySize;
187
Todd Poynorbfdd6232013-07-10 19:15:07 -0700188 private static LocalSocket sLmkdSocket;
189 private static OutputStream sLmkdOutputStream;
190
Dianne Hackborn7d608422011-08-07 16:24:18 -0700191 ProcessList() {
192 MemInfoReader minfo = new MemInfoReader();
193 minfo.readMemInfo();
194 mTotalMemMb = minfo.getTotalSize()/(1024*1024);
195 updateOomLevels(0, 0, false);
196 }
197
198 void applyDisplaySize(WindowManagerService wm) {
199 if (!mHaveDisplaySize) {
200 Point p = new Point();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700201 // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
Colin Cross637dbfc2013-07-18 17:15:15 -0700202 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700203 if (p.x != 0 && p.y != 0) {
204 updateOomLevels(p.x, p.y, true);
205 mHaveDisplaySize = true;
206 }
207 }
208 }
209
210 private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
211 // Scale buckets from avail memory: at 300MB we use the lowest values to
212 // 700MB or more for the top values.
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800213 float scaleMem = ((float)(mTotalMemMb-350))/(700-350);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700214
215 // Scale buckets from screen size.
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700216 int minSize = 480*800; // 384000
Dianne Hackborn7d608422011-08-07 16:24:18 -0700217 int maxSize = 1280*800; // 1024000 230400 870400 .264
218 float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700219 if (false) {
220 Slog.i("XXXXXX", "scaleMem=" + scaleMem);
221 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
222 + " dh=" + displayHeight);
223 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700224
Dianne Hackborn7d608422011-08-07 16:24:18 -0700225 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
226 if (scale < 0) scale = 0;
227 else if (scale > 1) scale = 1;
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700228 int minfree_adj = Resources.getSystem().getInteger(
229 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
230 int minfree_abs = Resources.getSystem().getInteger(
231 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
232 if (false) {
233 Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
234 }
Colin Crossfcdad6f2013-07-25 15:04:40 -0700235
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800236 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700237
Dianne Hackborn7d608422011-08-07 16:24:18 -0700238 for (int i=0; i<mOomAdj.length; i++) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700239 int low = mOomMinFreeLow[i];
240 int high = mOomMinFreeHigh[i];
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800241 if (is64bit) {
242 // Increase the high min-free levels for cached processes for 64-bit
243 if (i == 4) high = (high*3)/2;
244 else if (i == 5) high = (high*7)/4;
245 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700246 mOomMinFree[i] = (int)(low + ((high-low)*scale));
Colin Crossfcdad6f2013-07-25 15:04:40 -0700247 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700248
Colin Crossfcdad6f2013-07-25 15:04:40 -0700249 if (minfree_abs >= 0) {
250 for (int i=0; i<mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700251 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
252 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700253 }
254 }
255
256 if (minfree_adj != 0) {
257 for (int i=0; i<mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700258 mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
259 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700260 if (mOomMinFree[i] < 0) {
261 mOomMinFree[i] = 0;
262 }
263 }
264 }
265
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700266 // The maximum size we will restore a process from cached to background, when under
267 // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
268 // before killing background processes.
269 mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3;
270
Colin Cross59d80a52013-07-25 10:45:05 -0700271 // Ask the kernel to try to keep enough memory free to allocate 3 full
272 // screen 32bpp buffers without entering direct reclaim.
273 int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
274 int reserve_adj = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAdjust);
275 int reserve_abs = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
276
277 if (reserve_abs >= 0) {
278 reserve = reserve_abs;
279 }
280
281 if (reserve_adj != 0) {
282 reserve += reserve_adj;
283 if (reserve < 0) {
284 reserve = 0;
285 }
286 }
287
Dianne Hackborn7d608422011-08-07 16:24:18 -0700288 if (write) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700289 ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1));
290 buf.putInt(LMK_TARGET);
291 for (int i=0; i<mOomAdj.length; i++) {
292 buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE);
293 buf.putInt(mOomAdj[i]);
294 }
295
296 writeLmkd(buf);
Colin Cross59d80a52013-07-25 10:45:05 -0700297 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
Dianne Hackborn7d608422011-08-07 16:24:18 -0700298 }
299 // GB: 2048,3072,4096,6144,7168,8192
300 // HC: 8192,10240,12288,14336,16384,20480
301 }
302
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700303 public static int computeEmptyProcessLimit(int totalProcessLimit) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700304 return totalProcessLimit/2;
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700305 }
306
Dianne Hackborn8e692572013-09-10 19:06:15 -0700307 private static String buildOomTag(String prefix, String space, int val, int base) {
308 if (val == base) {
309 if (space == null) return prefix;
310 return prefix + " ";
311 }
312 return prefix + "+" + Integer.toString(val-base);
313 }
314
315 public static String makeOomAdjString(int setAdj) {
316 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
317 return buildOomTag("cch", " ", setAdj, ProcessList.CACHED_APP_MIN_ADJ);
318 } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
319 return buildOomTag("svcb ", null, setAdj, ProcessList.SERVICE_B_ADJ);
320 } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
321 return buildOomTag("prev ", null, setAdj, ProcessList.PREVIOUS_APP_ADJ);
322 } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
323 return buildOomTag("home ", null, setAdj, ProcessList.HOME_APP_ADJ);
324 } else if (setAdj >= ProcessList.SERVICE_ADJ) {
325 return buildOomTag("svc ", null, setAdj, ProcessList.SERVICE_ADJ);
326 } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
327 return buildOomTag("hvy ", null, setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
328 } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
329 return buildOomTag("bkup ", null, setAdj, ProcessList.BACKUP_APP_ADJ);
330 } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
331 return buildOomTag("prcp ", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
332 } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
333 return buildOomTag("vis ", null, setAdj, ProcessList.VISIBLE_APP_ADJ);
334 } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
335 return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700336 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
337 return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700338 } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
339 return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
340 } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
341 return buildOomTag("sys ", null, setAdj, ProcessList.SYSTEM_ADJ);
342 } else if (setAdj >= ProcessList.NATIVE_ADJ) {
343 return buildOomTag("ntv ", null, setAdj, ProcessList.NATIVE_ADJ);
344 } else {
345 return Integer.toString(setAdj);
346 }
347 }
348
Dianne Hackborn8e692572013-09-10 19:06:15 -0700349 public static String makeProcStateString(int curProcState) {
350 String procState;
351 switch (curProcState) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700352 case ActivityManager.PROCESS_STATE_PERSISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700353 procState = "PER ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700354 break;
355 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Dianne Hackborn94846032017-03-31 17:55:23 -0700356 procState = "PERU";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700357 break;
358 case ActivityManager.PROCESS_STATE_TOP:
Dianne Hackbornf4dd3712017-05-11 17:25:23 -0700359 procState = "TOP ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700360 break;
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700361 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700362 procState = "BFGS";
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700363 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700364 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700365 procState = "FGS ";
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700366 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700367 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700368 procState = "IMPF";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700369 break;
370 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700371 procState = "IMPB";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700372 break;
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700373 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
374 procState = "TRNB";
375 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700376 case ActivityManager.PROCESS_STATE_BACKUP:
Dianne Hackborn94846032017-03-31 17:55:23 -0700377 procState = "BKUP";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700378 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700379 case ActivityManager.PROCESS_STATE_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700380 procState = "SVC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700381 break;
382 case ActivityManager.PROCESS_STATE_RECEIVER:
Dianne Hackborn94846032017-03-31 17:55:23 -0700383 procState = "RCVR";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700384 break;
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800385 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
386 procState = "TPSL";
387 break;
Dianne Hackbornf097d422017-12-15 16:32:19 -0800388 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
389 procState = "HVY ";
390 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700391 case ActivityManager.PROCESS_STATE_HOME:
Dianne Hackborn94846032017-03-31 17:55:23 -0700392 procState = "HOME";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700393 break;
394 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700395 procState = "LAST";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700396 break;
397 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700398 procState = "CAC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700399 break;
400 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700401 procState = "CACC";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700402 break;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800403 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
404 procState = "CRE ";
405 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700406 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700407 procState = "CEM ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700408 break;
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800409 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700410 procState = "NONE";
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800411 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700412 default:
413 procState = "??";
414 break;
415 }
416 return procState;
417 }
418
419 public static void appendRamKb(StringBuilder sb, long ramKb) {
420 for (int j=0, fact=10; j<6; j++, fact*=10) {
421 if (ramKb < fact) {
422 sb.append(' ');
423 }
424 }
425 sb.append(ramKb);
426 }
427
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800428 // How long after a state change that it is safe to collect PSS without it being dirty.
429 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
430
431 // The minimum time interval after a state change it is safe to collect PSS.
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700432 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
433
434 // The maximum amount of time we want to go between PSS collections.
435 public static final int PSS_MAX_INTERVAL = 30*60*1000;
436
437 // The minimum amount of time between successive PSS requests for *all* processes.
438 public static final int PSS_ALL_INTERVAL = 10*60*1000;
439
440 // The minimum amount of time between successive PSS requests for a process.
441 private static final int PSS_SHORT_INTERVAL = 2*60*1000;
442
443 // The amount of time until PSS when a process first becomes top.
444 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
445
446 // The amount of time until PSS when a process first goes into the background.
447 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
448
449 // The amount of time until PSS when a process first becomes cached.
450 private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000;
451
452 // The amount of time until PSS when an important process stays in the same state.
453 private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;
454
455 // The amount of time until PSS when a service process stays in the same state.
456 private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
457
458 // The amount of time until PSS when a cached process stays in the same state.
459 private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
460
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800461 // The minimum time interval after a state change it is safe to collect PSS.
462 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
463
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800464 // The amount of time during testing until PSS when a process first becomes top.
465 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
466
467 // The amount of time during testing until PSS when a process first goes into the background.
468 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
469
470 // The amount of time during testing until PSS when an important process stays in same state.
471 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
472
473 // The amount of time during testing until PSS when a background process stays in same state.
474 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
475
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700476 public static final int PROC_MEM_PERSISTENT = 0;
477 public static final int PROC_MEM_TOP = 1;
478 public static final int PROC_MEM_IMPORTANT = 2;
479 public static final int PROC_MEM_SERVICE = 3;
480 public static final int PROC_MEM_CACHED = 4;
481
482 private static final int[] sProcStateToProcMem = new int[] {
483 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
484 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
485 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700486 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700487 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700488 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
489 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700490 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700491 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700492 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
493 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800494 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackbornf097d422017-12-15 16:32:19 -0800495 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700496 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME
497 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
498 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
499 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -0800500 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700501 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
502 };
503
504 private static final long[] sFirstAwakePssTimes = new long[] {
505 PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
506 PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
507 PSS_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700508 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700509 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700510 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
511 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700512 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700513 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700514 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
515 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800516 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
517 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700518 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
519 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
520 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
521 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -0800522 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700523 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
524 };
525
526 private static final long[] sSameAwakePssTimes = new long[] {
527 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
528 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
529 PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700530 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700531 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700532 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
533 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700534 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700535 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700536 PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
537 PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800538 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
539 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700540 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
541 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
542 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
543 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -0800544 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700545 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
546 };
547
Dianne Hackbornf097d422017-12-15 16:32:19 -0800548 private static final long[] sTestFirstPssTimes = new long[] {
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800549 PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
550 PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
551 PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800552 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
553 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800554 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
555 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700556 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800557 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800558 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
559 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800560 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackbornf097d422017-12-15 16:32:19 -0800561 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800562 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
563 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
564 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
565 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -0800566 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800567 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
568 };
569
Dianne Hackbornf097d422017-12-15 16:32:19 -0800570 private static final long[] sTestSamePssTimes = new long[] {
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800571 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
572 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
573 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700574 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700575 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800576 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
577 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700578 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800579 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800580 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
581 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800582 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
583 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800584 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
585 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
586 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
587 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -0800588 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800589 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
590 };
591
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700592 public static boolean procStatesDifferForMem(int procState1, int procState2) {
593 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
594 }
595
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800596 public static long minTimeFromStateChange(boolean test) {
597 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
598 }
599
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800600 public static long computeNextPssTime(int procState, boolean first, boolean test,
601 boolean sleeping, long now) {
602 final long[] table = test
Dianne Hackbornf1cca182013-08-01 10:50:28 -0700603 ? (first
Dianne Hackbornf097d422017-12-15 16:32:19 -0800604 ? sTestFirstPssTimes
605 : sTestSamePssTimes)
Dianne Hackbornf1cca182013-08-01 10:50:28 -0700606 : (first
607 ? sFirstAwakePssTimes
608 : sSameAwakePssTimes);
609 return now + table[procState];
610 }
611
Dianne Hackborn7d608422011-08-07 16:24:18 -0700612 long getMemLevel(int adjustment) {
613 for (int i=0; i<mOomAdj.length; i++) {
614 if (adjustment <= mOomAdj[i]) {
615 return mOomMinFree[i] * 1024;
616 }
617 }
618 return mOomMinFree[mOomAdj.length-1] * 1024;
619 }
620
Todd Poynorbfdd6232013-07-10 19:15:07 -0700621 /**
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700622 * Return the maximum pss size in kb that we consider a process acceptable to
623 * restore from its cached state for running in the background when RAM is low.
624 */
Dianne Hackborncbd9a522013-09-24 23:10:14 -0700625 long getCachedRestoreThresholdKb() {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700626 return mCachedRestoreLevel;
627 }
628
Dianne Hackborn9bef5b62013-09-20 10:40:34 -0700629 /**
Todd Poynorbfdd6232013-07-10 19:15:07 -0700630 * Set the out-of-memory badness adjustment for a process.
Sudheer Shankaf6690102017-10-16 10:20:32 -0700631 * If {@code pid <= 0}, this method will be a no-op.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700632 *
633 * @param pid The process identifier to set.
Colin Crossd908edd2014-06-13 14:56:04 -0700634 * @param uid The uid of the app
Todd Poynorbfdd6232013-07-10 19:15:07 -0700635 * @param amt Adjustment value -- lmkd allows -16 to +15.
636 *
637 * {@hide}
638 */
Colin Crossd908edd2014-06-13 14:56:04 -0700639 public static final void setOomAdj(int pid, int uid, int amt) {
Sudheer Shankaf6690102017-10-16 10:20:32 -0700640 // This indicates that the process is not started yet and so no need to proceed further.
641 if (pid <= 0) {
642 return;
643 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700644 if (amt == UNKNOWN_ADJ)
645 return;
646
Dianne Hackbornecf1cda2014-08-28 16:58:28 -0700647 long start = SystemClock.elapsedRealtime();
Colin Crossd908edd2014-06-13 14:56:04 -0700648 ByteBuffer buf = ByteBuffer.allocate(4 * 4);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700649 buf.putInt(LMK_PROCPRIO);
650 buf.putInt(pid);
Colin Crossd908edd2014-06-13 14:56:04 -0700651 buf.putInt(uid);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700652 buf.putInt(amt);
653 writeLmkd(buf);
Dianne Hackbornecf1cda2014-08-28 16:58:28 -0700654 long now = SystemClock.elapsedRealtime();
655 if ((now-start) > 250) {
656 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
657 + " = " + amt);
658 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700659 }
660
661 /*
662 * {@hide}
663 */
664 public static final void remove(int pid) {
Sudheer Shankaf6690102017-10-16 10:20:32 -0700665 // This indicates that the process is not started yet and so no need to proceed further.
666 if (pid <= 0) {
667 return;
668 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700669 ByteBuffer buf = ByteBuffer.allocate(4 * 2);
670 buf.putInt(LMK_PROCREMOVE);
671 buf.putInt(pid);
672 writeLmkd(buf);
673 }
674
675 private static boolean openLmkdSocket() {
Dianne Hackborn7d608422011-08-07 16:24:18 -0700676 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700677 sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
678 sLmkdSocket.connect(
679 new LocalSocketAddress("lmkd",
680 LocalSocketAddress.Namespace.RESERVED));
681 sLmkdOutputStream = sLmkdSocket.getOutputStream();
682 } catch (IOException ex) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800683 Slog.w(TAG, "lowmemorykiller daemon socket open failed");
Todd Poynorbfdd6232013-07-10 19:15:07 -0700684 sLmkdSocket = null;
685 return false;
686 }
687
688 return true;
689 }
690
691 private static void writeLmkd(ByteBuffer buf) {
692
693 for (int i = 0; i < 3; i++) {
694 if (sLmkdSocket == null) {
695 if (openLmkdSocket() == false) {
696 try {
697 Thread.sleep(1000);
698 } catch (InterruptedException ie) {
699 }
700 continue;
701 }
702 }
703
704 try {
705 sLmkdOutputStream.write(buf.array(), 0, buf.position());
706 return;
707 } catch (IOException ex) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800708 Slog.w(TAG, "Error writing to lowmemorykiller socket");
Todd Poynorbfdd6232013-07-10 19:15:07 -0700709
Dianne Hackborn7d608422011-08-07 16:24:18 -0700710 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700711 sLmkdSocket.close();
712 } catch (IOException ex2) {
Dianne Hackborn7d608422011-08-07 16:24:18 -0700713 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700714
715 sLmkdSocket = null;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700716 }
717 }
718 }
719}