blob: bf7aef9ecc65a8fc50669b1b2c3ecbd2d3faa647 [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;
Dianne Hackborne17b4452018-01-10 13:15:40 -080024import java.io.PrintWriter;
Todd Poynorbfdd6232013-07-10 19:15:07 -070025import java.nio.ByteBuffer;
Dianne Hackborn7d608422011-08-07 16:24:18 -070026
Dianne Hackborn8e692572013-09-10 19:06:15 -070027import android.app.ActivityManager;
Bookatzdb026a22018-01-10 19:01:56 -080028import android.app.AppProtoEnums;
Dianne Hackborn9d52f792014-09-11 17:46:06 -070029import android.os.Build;
Dianne Hackbornecf1cda2014-08-28 16:58:28 -070030import android.os.SystemClock;
Dianne Hackborn7d608422011-08-07 16:24:18 -070031import com.android.internal.util.MemInfoReader;
32import com.android.server.wm.WindowManagerService;
33
Colin Crossfcdad6f2013-07-25 15:04:40 -070034import android.content.res.Resources;
Dianne Hackborn7d608422011-08-07 16:24:18 -070035import android.graphics.Point;
Colin Cross59d80a52013-07-25 10:45:05 -070036import android.os.SystemProperties;
Todd Poynorbfdd6232013-07-10 19:15:07 -070037import android.net.LocalSocketAddress;
38import android.net.LocalSocket;
Dianne Hackborn7d608422011-08-07 16:24:18 -070039import android.util.Slog;
Craig Mautner59c00972012-07-30 12:10:24 -070040import android.view.Display;
Dianne Hackborn7d608422011-08-07 16:24:18 -070041
42/**
43 * Activity manager code dealing with processes.
44 */
Sudheer Shanka352dc572017-09-22 17:09:38 -070045public final class ProcessList {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080046 private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
47
Dianne Hackborn7d608422011-08-07 16:24:18 -070048 // 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
Chong Zhangfdcc4d42015-10-14 16:50:12 -070054 // Uninitialized value for any major or minor adj fields
55 static final int INVALID_ADJ = -10000;
56
Dianne Hackbornc8230512013-07-13 21:32:12 -070057 // 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.)
Chong Zhangfdcc4d42015-10-14 16:50:12 -070060 static final int UNKNOWN_ADJ = 1001;
Dianne Hackbornc8230512013-07-13 21:32:12 -070061
Dianne Hackborn7d608422011-08-07 16:24:18 -070062 // This is a process only hosting activities that are not visible,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070063 // so it can be killed without any disruption.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070064 static final int CACHED_APP_MAX_ADJ = 906;
65 static final int CACHED_APP_MIN_ADJ = 900;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070066
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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070069 static final int SERVICE_B_ADJ = 800;
Dianne Hackbornf35fe232011-11-01 19:25:20 -070070
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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070077 static final int PREVIOUS_APP_ADJ = 700;
Dianne Hackborn7d608422011-08-07 16:24:18 -070078
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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070082 static final int HOME_APP_ADJ = 600;
Dianne Hackborn7d608422011-08-07 16:24:18 -070083
Dianne Hackborne02c88a2011-10-28 13:58:15 -070084 // 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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070086 static final int SERVICE_ADJ = 500;
Dianne Hackborn7d608422011-08-07 16:24:18 -070087
Dianne Hackborn7d608422011-08-07 16:24:18 -070088 // 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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070091 static final int HEAVY_WEIGHT_APP_ADJ = 400;
Dianne Hackbornc8230512013-07-13 21:32:12 -070092
93 // This is a process currently hosting a backup operation. Killing it
94 // is not entirely fatal but is generally a bad idea.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070095 static final int BACKUP_APP_ADJ = 300;
Dianne Hackborn7d608422011-08-07 16:24:18 -070096
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
Dianne Hackborne02c88a2011-10-28 13:58:15 -070099 // immediately visible. An example is background music playback.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700100 static final int PERCEPTIBLE_APP_ADJ = 200;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700101
102 // This is a process only hosting activities that are visible to the
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700103 // user, so we'd prefer they don't disappear.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700104 static final int VISIBLE_APP_ADJ = 100;
105 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700106
107 // This is the process running the current foreground app. We'd really
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700108 // rather not kill it!
Dianne Hackborn7d608422011-08-07 16:24:18 -0700109 static final int FOREGROUND_APP_ADJ = 0;
110
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700111 // This is a process that the system or a persistent process has bound to,
112 // and indicated it is important.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700113 static final int PERSISTENT_SERVICE_ADJ = -700;
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700114
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700115 // This is a system persistent process, such as telephony. Definitely
Dianne Hackborn7d608422011-08-07 16:24:18 -0700116 // don't want to kill it, but doing so is not completely fatal.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700117 static final int PERSISTENT_PROC_ADJ = -800;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700118
119 // The system process runs at the default adjustment.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700120 static final int SYSTEM_ADJ = -900;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700121
Dianne Hackborn8e692572013-09-10 19:06:15 -0700122 // 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).
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700124 static final int NATIVE_ADJ = -1000;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700125
Dianne Hackborn7d608422011-08-07 16:24:18 -0700126 // Memory pages are 4K.
127 static final int PAGE_SIZE = 4*1024;
128
Dianne Hackborna49ad092016-03-03 13:39:10 -0800129 // 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;
Tim Murray33eb07f2016-06-10 10:03:20 -0700135 // 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;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800138
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700139 // The minimum number of cached apps we want to be able to keep around,
Dianne Hackborn7d608422011-08-07 16:24:18 -0700140 // without empty apps being able to push them out of memory.
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700141 static final int MIN_CACHED_APPS = 2;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700142
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700143 // We allow empty processes to stick around for at most 30 minutes.
144 static final long MAX_EMPTY_TIME = 30*60*1000;
145
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700146 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700147 static final int TRIM_CRITICAL_THRESHOLD = 3;
148
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700149 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700150 static final int TRIM_LOW_THRESHOLD = 5;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700151
Todd Poynorbfdd6232013-07-10 19:15:07 -0700152 // 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)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700156 // LMK_PROCPRIO <pid> <uid> <prio>
Todd Poynorbfdd6232013-07-10 19:15:07 -0700157 // 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
Dianne Hackborn7d608422011-08-07 16:24:18 -0700162 // 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,
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700167 BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
Dianne Hackborn7d608422011-08-07 16:24:18 -0700168 };
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.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700171 private final int[] mOomMinFreeLow = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700172 12288, 18432, 24576,
173 36864, 43008, 49152
Dianne Hackborn7d608422011-08-07 16:24:18 -0700174 };
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.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700177 private final int[] mOomMinFreeHigh = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700178 73728, 92160, 110592,
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800179 129024, 147456, 184320
Dianne Hackborn7d608422011-08-07 16:24:18 -0700180 };
181 // The actual OOM killer memory levels we are using.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700182 private final int[] mOomMinFree = new int[mOomAdj.length];
Dianne Hackborn7d608422011-08-07 16:24:18 -0700183
184 private final long mTotalMemMb;
185
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700186 private long mCachedRestoreLevel;
187
Dianne Hackborn7d608422011-08-07 16:24:18 -0700188 private boolean mHaveDisplaySize;
189
Todd Poynorbfdd6232013-07-10 19:15:07 -0700190 private static LocalSocket sLmkdSocket;
191 private static OutputStream sLmkdOutputStream;
192
Dianne Hackborn7d608422011-08-07 16:24:18 -0700193 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();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700203 // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
Colin Cross637dbfc2013-07-18 17:15:15 -0700204 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700205 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.
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800215 float scaleMem = ((float)(mTotalMemMb-350))/(700-350);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700216
217 // Scale buckets from screen size.
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700218 int minSize = 480*800; // 384000
Dianne Hackborn7d608422011-08-07 16:24:18 -0700219 int maxSize = 1280*800; // 1024000 230400 870400 .264
220 float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700221 if (false) {
222 Slog.i("XXXXXX", "scaleMem=" + scaleMem);
223 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
224 + " dh=" + displayHeight);
225 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700226
Dianne Hackborn7d608422011-08-07 16:24:18 -0700227 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
228 if (scale < 0) scale = 0;
229 else if (scale > 1) scale = 1;
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700230 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 }
Colin Crossfcdad6f2013-07-25 15:04:40 -0700237
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800238 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700239
Dianne Hackborn7d608422011-08-07 16:24:18 -0700240 for (int i=0; i<mOomAdj.length; i++) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700241 int low = mOomMinFreeLow[i];
242 int high = mOomMinFreeHigh[i];
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800243 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 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700248 mOomMinFree[i] = (int)(low + ((high-low)*scale));
Colin Crossfcdad6f2013-07-25 15:04:40 -0700249 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700250
Colin Crossfcdad6f2013-07-25 15:04:40 -0700251 if (minfree_abs >= 0) {
252 for (int i=0; i<mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700253 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
254 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700255 }
256 }
257
258 if (minfree_adj != 0) {
259 for (int i=0; i<mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700260 mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
261 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700262 if (mOomMinFree[i] < 0) {
263 mOomMinFree[i] = 0;
264 }
265 }
266 }
267
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700268 // 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
Colin Cross59d80a52013-07-25 10:45:05 -0700273 // 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
Dianne Hackborn7d608422011-08-07 16:24:18 -0700290 if (write) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700291 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);
Colin Cross59d80a52013-07-25 10:45:05 -0700299 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
Dianne Hackborn7d608422011-08-07 16:24:18 -0700300 }
301 // GB: 2048,3072,4096,6144,7168,8192
302 // HC: 8192,10240,12288,14336,16384,20480
303 }
304
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700305 public static int computeEmptyProcessLimit(int totalProcessLimit) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700306 return totalProcessLimit/2;
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700307 }
308
Dianne Hackborn8e692572013-09-10 19:06:15 -0700309 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);
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700338 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
339 return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700340 } 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
Dianne Hackborn8e692572013-09-10 19:06:15 -0700351 public static String makeProcStateString(int curProcState) {
352 String procState;
353 switch (curProcState) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700354 case ActivityManager.PROCESS_STATE_PERSISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700355 procState = "PER ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700356 break;
357 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Dianne Hackborn94846032017-03-31 17:55:23 -0700358 procState = "PERU";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700359 break;
360 case ActivityManager.PROCESS_STATE_TOP:
Dianne Hackbornf4dd3712017-05-11 17:25:23 -0700361 procState = "TOP ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700362 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700363 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700364 procState = "FGS ";
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700365 break;
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800366 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
367 procState = "BFGS";
368 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700369 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700370 procState = "IMPF";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700371 break;
372 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700373 procState = "IMPB";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700374 break;
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700375 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
376 procState = "TRNB";
377 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700378 case ActivityManager.PROCESS_STATE_BACKUP:
Dianne Hackborn94846032017-03-31 17:55:23 -0700379 procState = "BKUP";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700380 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700381 case ActivityManager.PROCESS_STATE_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700382 procState = "SVC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700383 break;
384 case ActivityManager.PROCESS_STATE_RECEIVER:
Dianne Hackborn94846032017-03-31 17:55:23 -0700385 procState = "RCVR";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700386 break;
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800387 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
388 procState = "TPSL";
389 break;
Dianne Hackbornf097d422017-12-15 16:32:19 -0800390 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
391 procState = "HVY ";
392 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700393 case ActivityManager.PROCESS_STATE_HOME:
Dianne Hackborn94846032017-03-31 17:55:23 -0700394 procState = "HOME";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700395 break;
396 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700397 procState = "LAST";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700398 break;
399 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700400 procState = "CAC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700401 break;
402 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700403 procState = "CACC";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700404 break;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800405 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
406 procState = "CRE ";
407 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700408 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700409 procState = "CEM ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700410 break;
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800411 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700412 procState = "NONE";
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800413 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700414 default:
415 procState = "??";
416 break;
417 }
418 return procState;
419 }
420
Yi Jin148d7f42017-11-28 14:23:56 -0800421 public static int makeProcStateProtoEnum(int curProcState) {
422 switch (curProcState) {
423 case ActivityManager.PROCESS_STATE_PERSISTENT:
Bookatzdb026a22018-01-10 19:01:56 -0800424 return AppProtoEnums.PROCESS_STATE_PERSISTENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800425 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Bookatzdb026a22018-01-10 19:01:56 -0800426 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
Yi Jin148d7f42017-11-28 14:23:56 -0800427 case ActivityManager.PROCESS_STATE_TOP:
Bookatzdb026a22018-01-10 19:01:56 -0800428 return AppProtoEnums.PROCESS_STATE_TOP;
Yi Jin148d7f42017-11-28 14:23:56 -0800429 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800430 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800431 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800432 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800433 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
Bookatzdb026a22018-01-10 19:01:56 -0800434 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING;
Yi Jin148d7f42017-11-28 14:23:56 -0800435 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800436 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800437 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800438 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800439 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800440 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800441 case ActivityManager.PROCESS_STATE_BACKUP:
Bookatzdb026a22018-01-10 19:01:56 -0800442 return AppProtoEnums.PROCESS_STATE_BACKUP;
Yi Jin148d7f42017-11-28 14:23:56 -0800443 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
Bookatzdb026a22018-01-10 19:01:56 -0800444 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT;
Yi Jin148d7f42017-11-28 14:23:56 -0800445 case ActivityManager.PROCESS_STATE_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800446 return AppProtoEnums.PROCESS_STATE_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800447 case ActivityManager.PROCESS_STATE_RECEIVER:
Bookatzdb026a22018-01-10 19:01:56 -0800448 return AppProtoEnums.PROCESS_STATE_RECEIVER;
Yi Jin148d7f42017-11-28 14:23:56 -0800449 case ActivityManager.PROCESS_STATE_HOME:
Bookatzdb026a22018-01-10 19:01:56 -0800450 return AppProtoEnums.PROCESS_STATE_HOME;
Yi Jin148d7f42017-11-28 14:23:56 -0800451 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -0800452 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -0800453 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -0800454 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -0800455 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Bookatzdb026a22018-01-10 19:01:56 -0800456 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800457 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
Bookatzdb026a22018-01-10 19:01:56 -0800458 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800459 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Bookatzdb026a22018-01-10 19:01:56 -0800460 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY;
Yi Jin148d7f42017-11-28 14:23:56 -0800461 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Bookatzdb026a22018-01-10 19:01:56 -0800462 return AppProtoEnums.PROCESS_STATE_NONEXISTENT;
463 case ActivityManager.PROCESS_STATE_UNKNOWN:
464 return AppProtoEnums.PROCESS_STATE_UNKNOWN;
Yi Jin148d7f42017-11-28 14:23:56 -0800465 default:
Bookatzdb026a22018-01-10 19:01:56 -0800466 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO;
Yi Jin148d7f42017-11-28 14:23:56 -0800467 }
468 }
469
Dianne Hackborn8e692572013-09-10 19:06:15 -0700470 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
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800479 // 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.
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700483 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.
Dianne Hackborne17b4452018-01-10 13:15:40 -0800486 public static final int PSS_MAX_INTERVAL = 60*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700487
488 // The minimum amount of time between successive PSS requests for *all* processes.
Dianne Hackborn052e3142017-12-19 16:08:30 -0800489 public static final int PSS_ALL_INTERVAL = 20*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700490
Dianne Hackborn052e3142017-12-19 16:08:30 -0800491 // The amount of time until PSS when a persistent process first appears.
492 private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700493
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.
Dianne Hackborne17b4452018-01-10 13:15:40 -0800501 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.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800504 private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700505
Dianne Hackborn052e3142017-12-19 16:08:30 -0800506 // The amount of time until PSS when the top process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800507 private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;
Dianne Hackborn052e3142017-12-19 16:08:30 -0800508
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700509 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800510 private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700511
512 // The amount of time until PSS when a service process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800513 private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700514
515 // The amount of time until PSS when a cached process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800516 private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700517
Dianne Hackborn052e3142017-12-19 16:08:30 -0800518 // 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
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800530 // 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
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800533 // 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
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700545 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;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800550 public static final int PROC_MEM_NUM = 5;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700551
Dianne Hackborne17b4452018-01-10 13:15:40 -0800552 // Map large set of system process states to
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700553 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
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700557 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800558 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700559 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
560 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700561 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700562 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700563 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
564 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800565 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackbornf097d422017-12-15 16:32:19 -0800566 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700567 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
Dianne Hackborn68a06332017-11-15 17:54:18 -0800571 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700572 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
573 };
574
575 private static final long[] sFirstAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800576 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
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700581 };
582
583 private static final long[] sSameAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800584 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
Dianne Hackborn052e3142017-12-19 16:08:30 -0800589 };
590
591 private static final long[] sFirstAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800592 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
Dianne Hackborn052e3142017-12-19 16:08:30 -0800597 };
598
599 private static final long[] sSameAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800600 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
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700605 };
606
Dianne Hackbornf097d422017-12-15 16:32:19 -0800607 private static final long[] sTestFirstPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800608 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
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800613 };
614
Dianne Hackbornf097d422017-12-15 16:32:19 -0800615 private static final long[] sTestSamePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800616 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
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800621 };
622
Dianne Hackborne17b4452018-01-10 13:15:40 -0800623 public static final class ProcStateMemTracker {
624 final int[] mHighestMem = new int[PROC_MEM_NUM];
Dianne Hackborned0a3222018-02-06 16:01:23 -0800625 final float[] mScalingFactor = new float[PROC_MEM_NUM];
Dianne Hackborne17b4452018-01-10 13:15:40 -0800626 int mTotalHighestMem = PROC_MEM_CACHED;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800627
628 int mPendingMemState;
629 int mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -0800630 float mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800631
632 public ProcStateMemTracker() {
633 for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
634 mHighestMem[i] = PROC_MEM_NUM;
Dianne Hackborned0a3222018-02-06 16:01:23 -0800635 mScalingFactor[i] = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800636 }
637 mPendingMemState = -1;
638 }
639
640 public void dumpLine(PrintWriter pw) {
641 pw.print("best=");
642 pw.print(mTotalHighestMem);
Dianne Hackborned0a3222018-02-06 16:01:23 -0800643 pw.print(" (");
644 boolean needSep = false;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800645 for (int i = 0; i < PROC_MEM_NUM; i++) {
Dianne Hackborned0a3222018-02-06 16:01:23 -0800646 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;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800658 }
Dianne Hackborne17b4452018-01-10 13:15:40 -0800659 }
660 pw.print(")");
661 if (mPendingMemState >= 0) {
662 pw.print(" / pending state=");
663 pw.print(mPendingMemState);
664 pw.print(" highest=");
665 pw.print(mPendingHighestMemState);
Dianne Hackborned0a3222018-02-06 16:01:23 -0800666 pw.print(" ");
667 pw.print(mPendingScalingFactor);
668 pw.print("x");
Dianne Hackborne17b4452018-01-10 13:15:40 -0800669 }
670 pw.println();
671 }
672 }
673
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700674 public static boolean procStatesDifferForMem(int procState1, int procState2) {
675 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
676 }
677
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800678 public static long minTimeFromStateChange(boolean test) {
679 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
680 }
681
Dianne Hackborne17b4452018-01-10 13:15:40 -0800682 public static void commitNextPssTime(ProcStateMemTracker tracker) {
683 if (tracker.mPendingMemState >= 0) {
684 tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -0800685 tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800686 tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800687 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,
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800696 boolean sleeping, long now) {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800697 boolean first;
Dianne Hackborned0a3222018-02-06 16:01:23 -0800698 float scalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800699 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;
Dianne Hackborned0a3222018-02-06 16:01:23 -0800706 if (first) {
707 tracker.mPendingScalingFactor = scalingFactor = 1.0f;
708 } else {
709 scalingFactor = tracker.mScalingFactor[memState];
710 tracker.mPendingScalingFactor = scalingFactor * 1.5f;
711 }
Dianne Hackborne17b4452018-01-10 13:15:40 -0800712 } else {
713 first = true;
Dianne Hackborned0a3222018-02-06 16:01:23 -0800714 scalingFactor = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800715 }
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800716 final long[] table = test
Dianne Hackbornf1cca182013-08-01 10:50:28 -0700717 ? (first
Dianne Hackborne17b4452018-01-10 13:15:40 -0800718 ? sTestFirstPssTimes
719 : sTestSamePssTimes)
Dianne Hackbornf1cca182013-08-01 10:50:28 -0700720 : (first
Dianne Hackborne17b4452018-01-10 13:15:40 -0800721 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
722 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
Dianne Hackborned0a3222018-02-06 16:01:23 -0800723 long delay = (long)(table[memState] * scalingFactor);
Dianne Hackborne17b4452018-01-10 13:15:40 -0800724 if (delay > PSS_MAX_INTERVAL) {
725 delay = PSS_MAX_INTERVAL;
726 }
727 return now + delay;
Dianne Hackbornf1cca182013-08-01 10:50:28 -0700728 }
729
Dianne Hackborn7d608422011-08-07 16:24:18 -0700730 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
Todd Poynorbfdd6232013-07-10 19:15:07 -0700739 /**
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700740 * 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 */
Dianne Hackborncbd9a522013-09-24 23:10:14 -0700743 long getCachedRestoreThresholdKb() {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700744 return mCachedRestoreLevel;
745 }
746
Dianne Hackborn9bef5b62013-09-20 10:40:34 -0700747 /**
Todd Poynorbfdd6232013-07-10 19:15:07 -0700748 * Set the out-of-memory badness adjustment for a process.
Sudheer Shankaf6690102017-10-16 10:20:32 -0700749 * If {@code pid <= 0}, this method will be a no-op.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700750 *
751 * @param pid The process identifier to set.
Colin Crossd908edd2014-06-13 14:56:04 -0700752 * @param uid The uid of the app
Todd Poynorbfdd6232013-07-10 19:15:07 -0700753 * @param amt Adjustment value -- lmkd allows -16 to +15.
754 *
755 * {@hide}
756 */
Colin Crossd908edd2014-06-13 14:56:04 -0700757 public static final void setOomAdj(int pid, int uid, int amt) {
Sudheer Shankaf6690102017-10-16 10:20:32 -0700758 // This indicates that the process is not started yet and so no need to proceed further.
759 if (pid <= 0) {
760 return;
761 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700762 if (amt == UNKNOWN_ADJ)
763 return;
764
Dianne Hackbornecf1cda2014-08-28 16:58:28 -0700765 long start = SystemClock.elapsedRealtime();
Colin Crossd908edd2014-06-13 14:56:04 -0700766 ByteBuffer buf = ByteBuffer.allocate(4 * 4);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700767 buf.putInt(LMK_PROCPRIO);
768 buf.putInt(pid);
Colin Crossd908edd2014-06-13 14:56:04 -0700769 buf.putInt(uid);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700770 buf.putInt(amt);
771 writeLmkd(buf);
Dianne Hackbornecf1cda2014-08-28 16:58:28 -0700772 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 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700777 }
778
779 /*
780 * {@hide}
781 */
782 public static final void remove(int pid) {
Sudheer Shankaf6690102017-10-16 10:20:32 -0700783 // This indicates that the process is not started yet and so no need to proceed further.
784 if (pid <= 0) {
785 return;
786 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700787 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() {
Dianne Hackborn7d608422011-08-07 16:24:18 -0700794 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700795 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) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800801 Slog.w(TAG, "lowmemorykiller daemon socket open failed");
Todd Poynorbfdd6232013-07-10 19:15:07 -0700802 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) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800826 Slog.w(TAG, "Error writing to lowmemorykiller socket");
Todd Poynorbfdd6232013-07-10 19:15:07 -0700827
Dianne Hackborn7d608422011-08-07 16:24:18 -0700828 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700829 sLmkdSocket.close();
830 } catch (IOException ex2) {
Dianne Hackborn7d608422011-08-07 16:24:18 -0700831 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700832
833 sLmkdSocket = null;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700834 }
835 }
836 }
837}