blob: 64ee30af2f3903a355c49b6b66bafc3466e0bcd2 [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
Amith Yamasani98a00922018-08-21 12:50:30 -040019import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
Amith Yamasaniaa746442019-01-10 10:09:12 -080020import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
Amith Yamasani98a00922018-08-21 12:50:30 -040021import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
Amith Yamasani98a00922018-08-21 12:50:30 -040022import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
Amith Yamasani98a00922018-08-21 12:50:30 -040023import static android.os.Process.SYSTEM_UID;
24import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
25import static android.os.Process.getFreeMemory;
26import static android.os.Process.getTotalMemory;
27import static android.os.Process.killProcessQuiet;
28import static android.os.Process.startWebView;
29
30import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
31import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
32import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
33import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080034import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
35import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010036import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS;
37import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG;
Amith Yamasani98a00922018-08-21 12:50:30 -040038import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK;
39import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT;
40import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG;
41import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER;
42import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
43import static com.android.server.am.ActivityManagerService.TAG_LRU;
44import static com.android.server.am.ActivityManagerService.TAG_PROCESSES;
45import static com.android.server.am.ActivityManagerService.TAG_PSS;
46import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080047
Dianne Hackborn8e692572013-09-10 19:06:15 -070048import android.app.ActivityManager;
Amith Yamasani98a00922018-08-21 12:50:30 -040049import android.app.AppGlobals;
Bookatzdb026a22018-01-10 19:01:56 -080050import android.app.AppProtoEnums;
Amith Yamasani98a00922018-08-21 12:50:30 -040051import android.app.IApplicationThread;
52import android.content.ComponentName;
Dianne Hackborna631d562018-11-20 15:58:15 -080053import android.content.Context;
Amith Yamasani98a00922018-08-21 12:50:30 -040054import android.content.Intent;
55import android.content.pm.ApplicationInfo;
56import android.content.pm.IPackageManager;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070057import android.content.res.Resources;
58import android.graphics.Point;
59import android.net.LocalSocket;
60import android.net.LocalSocketAddress;
Amith Yamasani98a00922018-08-21 12:50:30 -040061import android.net.Uri;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010062import android.os.AppZygote;
Amith Yamasani98a00922018-08-21 12:50:30 -040063import android.os.Binder;
Dianne Hackborn9d52f792014-09-11 17:46:06 -070064import android.os.Build;
Amith Yamasani98a00922018-08-21 12:50:30 -040065import android.os.Bundle;
Amith Yamasani98a00922018-08-21 12:50:30 -040066import android.os.Handler;
67import android.os.IBinder;
68import android.os.Looper;
69import android.os.Message;
70import android.os.Process;
71import android.os.RemoteException;
72import android.os.StrictMode;
Dianne Hackbornecf1cda2014-08-28 16:58:28 -070073import android.os.SystemClock;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070074import android.os.SystemProperties;
75import android.os.Trace;
76import android.os.UserHandle;
Jeff Sharkey10ec9d82018-11-28 14:52:45 -070077import android.os.storage.StorageManager;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070078import android.os.storage.StorageManagerInternal;
79import android.text.TextUtils;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010080import android.util.ArrayMap;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070081import android.util.EventLog;
82import android.util.LongSparseArray;
83import android.util.Slog;
84import android.util.SparseArray;
Martijn Coenen01e719b2018-12-05 16:01:38 +010085import android.util.SparseBooleanArray;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070086import android.util.StatsLog;
87import android.view.Display;
Amith Yamasani98a00922018-08-21 12:50:30 -040088
89import com.android.internal.annotations.GuardedBy;
90import com.android.internal.annotations.VisibleForTesting;
91import com.android.internal.app.ProcessMap;
92import com.android.internal.app.procstats.ProcessStats;
93import com.android.internal.os.Zygote;
94import com.android.internal.util.ArrayUtils;
Dianne Hackborn7d608422011-08-07 16:24:18 -070095import com.android.internal.util.MemInfoReader;
Amith Yamasani98a00922018-08-21 12:50:30 -040096import com.android.server.LocalServices;
97import com.android.server.ServiceThread;
98import com.android.server.Watchdog;
99import com.android.server.pm.dex.DexManager;
Wale Ogunwale59507092018-10-29 09:00:30 -0700100import com.android.server.wm.ActivityServiceConnectionsHolder;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700101import com.android.server.wm.WindowManagerService;
102
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700103import dalvik.system.VMRuntime;
104
Sudheer Shanka87915d62018-11-06 10:57:35 -0800105import libcore.io.IoUtils;
106
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700107import java.io.File;
108import java.io.IOException;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700109import java.io.InputStream;
Sudheer Shanka87915d62018-11-06 10:57:35 -0800110import java.io.OutputStream;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700111import java.io.PrintWriter;
112import java.nio.ByteBuffer;
113import java.util.ArrayList;
114import java.util.Arrays;
Martijn Coenen01e719b2018-12-05 16:01:38 +0100115import java.util.BitSet;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700116import java.util.List;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700117
118/**
119 * Activity manager code dealing with processes.
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700120 *
121 * Method naming convention:
122 * <ul>
123 * <li> Methods suffixed with "LS" should be called within the {@link #sLmkdSocketLock} lock.
124 * </ul>
Dianne Hackborn7d608422011-08-07 16:24:18 -0700125 */
Sudheer Shanka352dc572017-09-22 17:09:38 -0700126public final class ProcessList {
Amith Yamasaniaa746442019-01-10 10:09:12 -0800127 static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800128
Dianne Hackborn7d608422011-08-07 16:24:18 -0700129 // The minimum time we allow between crashes, for us to consider this
130 // application to be bad and stop and its services and reject broadcasts.
Amith Yamasani98a00922018-08-21 12:50:30 -0400131 static final int MIN_CRASH_INTERVAL = 60 * 1000;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700132
133 // OOM adjustments for processes in various states:
134
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700135 // Uninitialized value for any major or minor adj fields
136 static final int INVALID_ADJ = -10000;
137
Dianne Hackbornc8230512013-07-13 21:32:12 -0700138 // Adjustment used in certain places where we don't know it yet.
139 // (Generally this is something that is going to be cached, but we
140 // don't know the exact value in the cached range to assign yet.)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700141 static final int UNKNOWN_ADJ = 1001;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700142
Dianne Hackborn7d608422011-08-07 16:24:18 -0700143 // This is a process only hosting activities that are not visible,
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700144 // so it can be killed without any disruption.
Dianne Hackbornb446ce52018-12-10 16:44:35 -0800145 static final int CACHED_APP_MAX_ADJ = 999;
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700146 static final int CACHED_APP_MIN_ADJ = 900;
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700147
Tim Murray0d42abe2019-01-23 09:54:15 -0800148 // This is the oom_adj level that we allow to die first. This cannot be equal to
149 // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
150 // CACHED_APP_MAX_ADJ.
151 static final int CACHED_APP_LMK_FIRST_ADJ = 950;
152
Dianne Hackbornb446ce52018-12-10 16:44:35 -0800153 // Number of levels we have available for different service connection group importance
154 // levels.
155 static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
156
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700157 // The B list of SERVICE_ADJ -- these are the old and decrepit
158 // services that aren't as shiny and interesting as the ones in the A list.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700159 static final int SERVICE_B_ADJ = 800;
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700160
161 // This is the process of the previous application that the user was in.
162 // This process is kept above other things, because it is very common to
163 // switch back to the previous app. This is important both for recent
164 // task switch (toggling between the two top recent apps) as well as normal
165 // UI flow such as clicking on a URI in the e-mail app to view in the browser,
166 // and then pressing back to return to e-mail.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700167 static final int PREVIOUS_APP_ADJ = 700;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700168
169 // This is a process holding the home application -- we want to try
170 // avoiding killing it, even if it would normally be in the background,
171 // because the user interacts with it so much.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700172 static final int HOME_APP_ADJ = 600;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700173
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700174 // This is a process holding an application service -- killing it will not
175 // have much of an impact as far as the user is concerned.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700176 static final int SERVICE_ADJ = 500;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700177
Dianne Hackborn7d608422011-08-07 16:24:18 -0700178 // This is a process with a heavy-weight application. It is in the
179 // background, but we want to try to avoid killing it. Value set in
180 // system/rootdir/init.rc on startup.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700181 static final int HEAVY_WEIGHT_APP_ADJ = 400;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700182
183 // This is a process currently hosting a backup operation. Killing it
184 // is not entirely fatal but is generally a bad idea.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700185 static final int BACKUP_APP_ADJ = 300;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700186
187 // This is a process only hosting components that are perceptible to the
188 // user, and we really want to avoid killing them, but they are not
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700189 // immediately visible. An example is background music playback.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700190 static final int PERCEPTIBLE_APP_ADJ = 200;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700191
192 // This is a process only hosting activities that are visible to the
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700193 // user, so we'd prefer they don't disappear.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700194 static final int VISIBLE_APP_ADJ = 100;
195 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700196
Amith Yamasanib7358302018-09-05 18:52:35 -0700197 // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
198 // like a foreground app for a while.
199 // @see TOP_TO_FGS_GRACE_PERIOD
200 static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
201
Dianne Hackborn7d608422011-08-07 16:24:18 -0700202 // This is the process running the current foreground app. We'd really
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700203 // rather not kill it!
Dianne Hackborn7d608422011-08-07 16:24:18 -0700204 static final int FOREGROUND_APP_ADJ = 0;
205
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700206 // This is a process that the system or a persistent process has bound to,
207 // and indicated it is important.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700208 static final int PERSISTENT_SERVICE_ADJ = -700;
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700209
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700210 // This is a system persistent process, such as telephony. Definitely
Dianne Hackborn7d608422011-08-07 16:24:18 -0700211 // don't want to kill it, but doing so is not completely fatal.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700212 static final int PERSISTENT_PROC_ADJ = -800;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700213
214 // The system process runs at the default adjustment.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700215 static final int SYSTEM_ADJ = -900;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700216
Dianne Hackborn8e692572013-09-10 19:06:15 -0700217 // Special code for native processes that are not being managed by the system (so
218 // don't have an oom adj assigned by the system).
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700219 static final int NATIVE_ADJ = -1000;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700220
Dianne Hackborn7d608422011-08-07 16:24:18 -0700221 // Memory pages are 4K.
Amith Yamasani98a00922018-08-21 12:50:30 -0400222 static final int PAGE_SIZE = 4 * 1024;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700223
Dianne Hackborna49ad092016-03-03 13:39:10 -0800224 // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
225 static final int SCHED_GROUP_BACKGROUND = 0;
Tim Murrayfef10a42018-04-13 10:15:17 -0700226 // Activity manager's version of Process.THREAD_GROUP_RESTRICTED
227 static final int SCHED_GROUP_RESTRICTED = 1;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800228 // Activity manager's version of Process.THREAD_GROUP_DEFAULT
Tim Murrayfef10a42018-04-13 10:15:17 -0700229 static final int SCHED_GROUP_DEFAULT = 2;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800230 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
Wale Ogunwale59507092018-10-29 09:00:30 -0700231 public static final int SCHED_GROUP_TOP_APP = 3;
Tim Murray33eb07f2016-06-10 10:03:20 -0700232 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
233 // Disambiguate between actual top app and processes bound to the top app
Tim Murrayfef10a42018-04-13 10:15:17 -0700234 static final int SCHED_GROUP_TOP_APP_BOUND = 4;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800235
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700236 // The minimum number of cached apps we want to be able to keep around,
Dianne Hackborn7d608422011-08-07 16:24:18 -0700237 // without empty apps being able to push them out of memory.
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700238 static final int MIN_CACHED_APPS = 2;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700239
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700240 // We allow empty processes to stick around for at most 30 minutes.
Amith Yamasani98a00922018-08-21 12:50:30 -0400241 static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700242
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700243 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700244 static final int TRIM_CRITICAL_THRESHOLD = 3;
245
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700246 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700247 static final int TRIM_LOW_THRESHOLD = 5;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700248
Todd Poynorbfdd6232013-07-10 19:15:07 -0700249 // Low Memory Killer Daemon command codes.
250 // These must be kept in sync with the definitions in lmkd.c
251 //
252 // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700253 // LMK_PROCPRIO <pid> <uid> <prio>
Todd Poynorbfdd6232013-07-10 19:15:07 -0700254 // LMK_PROCREMOVE <pid>
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -0700255 // LMK_PROCPURGE
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700256 // LMK_GETKILLCNT
Todd Poynorbfdd6232013-07-10 19:15:07 -0700257 static final byte LMK_TARGET = 0;
258 static final byte LMK_PROCPRIO = 1;
259 static final byte LMK_PROCREMOVE = 2;
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -0700260 static final byte LMK_PROCPURGE = 3;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700261 static final byte LMK_GETKILLCNT = 4;
Todd Poynorbfdd6232013-07-10 19:15:07 -0700262
Amith Yamasani98a00922018-08-21 12:50:30 -0400263 ActivityManagerService mService = null;
264
265 // To kill process groups asynchronously
266 static KillHandler sKillHandler = null;
267 static ServiceThread sKillThread = null;
268
Dianne Hackborn7d608422011-08-07 16:24:18 -0700269 // These are the various interesting memory levels that we will give to
270 // the OOM killer. Note that the OOM killer only supports 6 slots, so we
271 // can't give it a different value for every possible kind of process.
272 private final int[] mOomAdj = new int[] {
273 FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
Tim Murray0d42abe2019-01-23 09:54:15 -0800274 BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
Dianne Hackborn7d608422011-08-07 16:24:18 -0700275 };
276 // These are the low-end OOM level limits. This is appropriate for an
277 // HVGA or smaller phone with less than 512MB. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700278 private final int[] mOomMinFreeLow = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700279 12288, 18432, 24576,
280 36864, 43008, 49152
Dianne Hackborn7d608422011-08-07 16:24:18 -0700281 };
282 // These are the high-end OOM level limits. This is appropriate for a
283 // 1280x800 or larger screen with around 1GB RAM. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700284 private final int[] mOomMinFreeHigh = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700285 73728, 92160, 110592,
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800286 129024, 147456, 184320
Dianne Hackborn7d608422011-08-07 16:24:18 -0700287 };
288 // The actual OOM killer memory levels we are using.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700289 private final int[] mOomMinFree = new int[mOomAdj.length];
Dianne Hackborn7d608422011-08-07 16:24:18 -0700290
291 private final long mTotalMemMb;
292
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700293 private long mCachedRestoreLevel;
294
Dianne Hackborn7d608422011-08-07 16:24:18 -0700295 private boolean mHaveDisplaySize;
296
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700297 private static Object sLmkdSocketLock = new Object();
298
299 @GuardedBy("sLmkdSocketLock")
Todd Poynorbfdd6232013-07-10 19:15:07 -0700300 private static LocalSocket sLmkdSocket;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700301
302 @GuardedBy("sLmkdSocketLock")
Todd Poynorbfdd6232013-07-10 19:15:07 -0700303 private static OutputStream sLmkdOutputStream;
304
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700305 @GuardedBy("sLmkdSocketLock")
306 private static InputStream sLmkdInputStream;
307
Amith Yamasani98a00922018-08-21 12:50:30 -0400308 /**
309 * Temporary to avoid allocations. Protected by main lock.
310 */
311 @GuardedBy("mService")
312 final StringBuilder mStringBuilder = new StringBuilder(256);
313
314 /**
315 * A global counter for generating sequence numbers.
316 * This value will be used when incrementing sequence numbers in individual uidRecords.
317 *
318 * Having a global counter ensures that seq numbers are monotonically increasing for a
319 * particular uid even when the uidRecord is re-created.
320 */
321 @GuardedBy("mService")
322 @VisibleForTesting
323 long mProcStateSeqCounter = 0;
324
325 /**
326 * A global counter for generating sequence numbers to uniquely identify pending process starts.
327 */
328 @GuardedBy("mService")
329 private long mProcStartSeqCounter = 0;
330
331 /**
332 * Contains {@link ProcessRecord} objects for pending process starts.
333 *
334 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
335 */
336 @GuardedBy("mService")
337 final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
338
339 /**
340 * List of running applications, sorted by recent usage.
341 * The first entry in the list is the least recently used.
342 */
343 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
344
345 /**
346 * Where in mLruProcesses that the processes hosting activities start.
347 */
348 int mLruProcessActivityStart = 0;
349
350 /**
351 * Where in mLruProcesses that the processes hosting services start.
352 * This is after (lower index) than mLruProcessesActivityStart.
353 */
354 int mLruProcessServiceStart = 0;
355
356 /**
357 * Current sequence id for process LRU updating.
358 */
359 int mLruSeq = 0;
360
Amith Yamasaniaa746442019-01-10 10:09:12 -0800361 ActiveUids mActiveUids;
362
Amith Yamasani98a00922018-08-21 12:50:30 -0400363 /**
364 * The currently running isolated processes.
365 */
366 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
367
368 /**
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100369 * The currently running application zygotes.
370 */
371 final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
372
373 /**
374 * The processes that are forked off an application zygote.
375 */
376 final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses =
377 new ArrayMap<AppZygote, ArrayList<ProcessRecord>>();
378
Martijn Coenen01e719b2018-12-05 16:01:38 +0100379 final class IsolatedUidRange {
380 @VisibleForTesting
381 public final int mFirstUid;
382 @VisibleForTesting
383 public final int mLastUid;
384
385 @GuardedBy("ProcessList.this.mService")
386 private final SparseBooleanArray mUidUsed = new SparseBooleanArray();
387
388 @GuardedBy("ProcessList.this.mService")
389 private int mNextUid;
390
391 IsolatedUidRange(int firstUid, int lastUid) {
392 mFirstUid = firstUid;
393 mLastUid = lastUid;
394 mNextUid = firstUid;
395 }
396
397 @GuardedBy("ProcessList.this.mService")
398 int allocateIsolatedUidLocked(int userId) {
399 int uid;
400 int stepsLeft = (mLastUid - mFirstUid + 1);
401 for (int i = 0; i < stepsLeft; ++i) {
402 if (mNextUid < mFirstUid || mNextUid > mLastUid) {
403 mNextUid = mFirstUid;
404 }
405 uid = UserHandle.getUid(userId, mNextUid);
406 mNextUid++;
407 if (!mUidUsed.get(uid, false)) {
408 mUidUsed.put(uid, true);
409 return uid;
410 }
411 }
412 return -1;
413 }
414
415 @GuardedBy("ProcessList.this.mService")
416 void freeIsolatedUidLocked(int uid) {
417 // Strip out userId
418 final int appId = UserHandle.getAppId(uid);
419 mUidUsed.delete(appId);
420 }
421 };
422
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100423 /**
Martijn Coenen01e719b2018-12-05 16:01:38 +0100424 * A class that allocates ranges of isolated UIDs per application, and keeps track of them.
Amith Yamasani98a00922018-08-21 12:50:30 -0400425 */
Martijn Coenen01e719b2018-12-05 16:01:38 +0100426 final class IsolatedUidRangeAllocator {
427 private final int mFirstUid;
428 private final int mNumUidRanges;
429 private final int mNumUidsPerRange;
430 /**
431 * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange)
432 * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that.
433 */
434 @GuardedBy("ProcessList.this.mService")
435 private final BitSet mAvailableUidRanges;
436 @GuardedBy("ProcessList.this.mService")
437 private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>();
438
439 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) {
440 mFirstUid = firstUid;
441 mNumUidsPerRange = numUidsPerRange;
442 mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange;
443 mAvailableUidRanges = new BitSet(mNumUidRanges);
444 // Mark all as available
445 mAvailableUidRanges.set(0, mNumUidRanges);
446 }
447
448 @GuardedBy("ProcessList.this.mService")
449 IsolatedUidRange getIsolatedUidRangeLocked(ApplicationInfo info) {
450 return mAppRanges.get(info.processName, info.uid);
451 }
452
453 @GuardedBy("ProcessList.this.mService")
454 IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info) {
455 IsolatedUidRange range = getIsolatedUidRangeLocked(info);
456 if (range == null) {
457 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
458 if (uidRangeIndex < 0) {
459 // No free range
460 return null;
461 }
462 mAvailableUidRanges.clear(uidRangeIndex);
463 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
464 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
465 mAppRanges.put(info.processName, info.uid, range);
466 }
467 return range;
468 }
469
470 @GuardedBy("ProcessList.this.mService")
471 void freeUidRangeLocked(ApplicationInfo info) {
472 // Find the UID range
473 IsolatedUidRange range = mAppRanges.get(info.processName, info.uid);
474 if (range != null) {
475 // Map back to starting uid
476 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange;
477 // Mark it as available in the underlying bitset
478 mAvailableUidRanges.set(uidRangeIndex);
479 // And the map
480 mAppRanges.remove(info.processName, info.uid);
481 }
482 }
483 }
484
485 /**
486 * The available isolated UIDs for processes that are not spawned from an application zygote.
487 */
488 @VisibleForTesting
489 IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID,
490 Process.LAST_ISOLATED_UID);
491
492 /**
493 * An allocator for isolated UID ranges for apps that use an application zygote.
494 */
495 @VisibleForTesting
496 IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator =
497 new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
498 Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE);
Amith Yamasani98a00922018-08-21 12:50:30 -0400499
500 /**
501 * Processes that are being forcibly torn down.
502 */
503 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
504
505 /**
506 * All of the applications we currently have running organized by name.
507 * The keys are strings of the application package name (as
508 * returned by the package manager), and the keys are ApplicationRecord
509 * objects.
510 */
511 final MyProcessMap mProcessNames = new MyProcessMap();
512
513 final class MyProcessMap extends ProcessMap<ProcessRecord> {
514 @Override
515 public ProcessRecord put(String name, int uid, ProcessRecord value) {
516 final ProcessRecord r = super.put(name, uid, value);
517 mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());
518 return r;
519 }
520
521 @Override
522 public ProcessRecord remove(String name, int uid) {
523 final ProcessRecord r = super.remove(name, uid);
524 mService.mAtmInternal.onProcessRemoved(name, uid);
525 return r;
526 }
527 }
528
529 final class KillHandler extends Handler {
530 static final int KILL_PROCESS_GROUP_MSG = 4000;
531
532 public KillHandler(Looper looper) {
533 super(looper, null, true);
534 }
535
536 @Override
537 public void handleMessage(Message msg) {
538 switch (msg.what) {
539 case KILL_PROCESS_GROUP_MSG:
540 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
541 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
542 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
543 break;
544
545 default:
546 super.handleMessage(msg);
547 }
548 }
549 }
550
551 //////////////////// END FIELDS ////////////////////
552
Dianne Hackborn7d608422011-08-07 16:24:18 -0700553 ProcessList() {
554 MemInfoReader minfo = new MemInfoReader();
555 minfo.readMemInfo();
556 mTotalMemMb = minfo.getTotalSize()/(1024*1024);
557 updateOomLevels(0, 0, false);
558 }
559
Amith Yamasaniaa746442019-01-10 10:09:12 -0800560 void init(ActivityManagerService service, ActiveUids activeUids) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400561 mService = service;
Amith Yamasaniaa746442019-01-10 10:09:12 -0800562 mActiveUids = activeUids;
563
Amith Yamasani98a00922018-08-21 12:50:30 -0400564 if (sKillHandler == null) {
565 sKillThread = new ServiceThread(TAG + ":kill",
566 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
567 sKillThread.start();
568 sKillHandler = new KillHandler(sKillThread.getLooper());
569 }
570 }
571
Dianne Hackborn7d608422011-08-07 16:24:18 -0700572 void applyDisplaySize(WindowManagerService wm) {
573 if (!mHaveDisplaySize) {
574 Point p = new Point();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700575 // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
Colin Cross637dbfc2013-07-18 17:15:15 -0700576 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700577 if (p.x != 0 && p.y != 0) {
578 updateOomLevels(p.x, p.y, true);
579 mHaveDisplaySize = true;
580 }
581 }
582 }
583
584 private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
585 // Scale buckets from avail memory: at 300MB we use the lowest values to
586 // 700MB or more for the top values.
Amith Yamasani98a00922018-08-21 12:50:30 -0400587 float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700588
589 // Scale buckets from screen size.
Amith Yamasani98a00922018-08-21 12:50:30 -0400590 int minSize = 480 * 800; // 384000
591 int maxSize = 1280 * 800; // 1024000 230400 870400 .264
592 float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700593 if (false) {
594 Slog.i("XXXXXX", "scaleMem=" + scaleMem);
595 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
596 + " dh=" + displayHeight);
597 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700598
Dianne Hackborn7d608422011-08-07 16:24:18 -0700599 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
600 if (scale < 0) scale = 0;
601 else if (scale > 1) scale = 1;
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700602 int minfree_adj = Resources.getSystem().getInteger(
603 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
604 int minfree_abs = Resources.getSystem().getInteger(
605 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
606 if (false) {
607 Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
608 }
Colin Crossfcdad6f2013-07-25 15:04:40 -0700609
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800610 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700611
Amith Yamasani98a00922018-08-21 12:50:30 -0400612 for (int i = 0; i < mOomAdj.length; i++) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700613 int low = mOomMinFreeLow[i];
614 int high = mOomMinFreeHigh[i];
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800615 if (is64bit) {
616 // Increase the high min-free levels for cached processes for 64-bit
Amith Yamasani98a00922018-08-21 12:50:30 -0400617 if (i == 4) high = (high * 3) / 2;
618 else if (i == 5) high = (high * 7) / 4;
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800619 }
Amith Yamasani98a00922018-08-21 12:50:30 -0400620 mOomMinFree[i] = (int)(low + ((high - low) * scale));
Colin Crossfcdad6f2013-07-25 15:04:40 -0700621 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700622
Colin Crossfcdad6f2013-07-25 15:04:40 -0700623 if (minfree_abs >= 0) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400624 for (int i = 0; i < mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700625 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
626 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700627 }
628 }
629
630 if (minfree_adj != 0) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400631 for (int i = 0; i < mOomAdj.length; i++) {
632 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700633 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700634 if (mOomMinFree[i] < 0) {
635 mOomMinFree[i] = 0;
636 }
637 }
638 }
639
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700640 // The maximum size we will restore a process from cached to background, when under
641 // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
642 // before killing background processes.
Amith Yamasani98a00922018-08-21 12:50:30 -0400643 mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700644
Colin Cross59d80a52013-07-25 10:45:05 -0700645 // Ask the kernel to try to keep enough memory free to allocate 3 full
646 // screen 32bpp buffers without entering direct reclaim.
647 int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
Amith Yamasani98a00922018-08-21 12:50:30 -0400648 int reserve_adj = Resources.getSystem().getInteger(
649 com.android.internal.R.integer.config_extraFreeKbytesAdjust);
650 int reserve_abs = Resources.getSystem().getInteger(
651 com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
Colin Cross59d80a52013-07-25 10:45:05 -0700652
653 if (reserve_abs >= 0) {
654 reserve = reserve_abs;
655 }
656
657 if (reserve_adj != 0) {
658 reserve += reserve_adj;
659 if (reserve < 0) {
660 reserve = 0;
661 }
662 }
663
Dianne Hackborn7d608422011-08-07 16:24:18 -0700664 if (write) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400665 ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
Todd Poynorbfdd6232013-07-10 19:15:07 -0700666 buf.putInt(LMK_TARGET);
Amith Yamasani98a00922018-08-21 12:50:30 -0400667 for (int i = 0; i < mOomAdj.length; i++) {
668 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700669 buf.putInt(mOomAdj[i]);
670 }
671
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700672 writeLmkd(buf, null);
Colin Cross59d80a52013-07-25 10:45:05 -0700673 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
Dianne Hackborn7d608422011-08-07 16:24:18 -0700674 }
675 // GB: 2048,3072,4096,6144,7168,8192
676 // HC: 8192,10240,12288,14336,16384,20480
677 }
678
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700679 public static int computeEmptyProcessLimit(int totalProcessLimit) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700680 return totalProcessLimit/2;
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700681 }
682
Dianne Hackborn8e692572013-09-10 19:06:15 -0700683 private static String buildOomTag(String prefix, String space, int val, int base) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800684 final int diff = val - base;
685 if (diff == 0) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700686 if (space == null) return prefix;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800687 return prefix + space;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700688 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800689 if (diff < 10) {
690 return prefix + "+ " + Integer.toString(diff);
691 }
692 return prefix + "+" + Integer.toString(diff);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700693 }
694
695 public static String makeOomAdjString(int setAdj) {
696 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800697 return buildOomTag("cch", " ", setAdj, ProcessList.CACHED_APP_MIN_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700698 } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800699 return buildOomTag("svcb ", null, setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700700 } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800701 return buildOomTag("prev ", null, setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700702 } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800703 return buildOomTag("home ", null, setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700704 } else if (setAdj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800705 return buildOomTag("svc ", null, setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700706 } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800707 return buildOomTag("hvy ", null, setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700708 } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800709 return buildOomTag("bkup ", null, setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700710 } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800711 return buildOomTag("prcp ", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700712 } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800713 return buildOomTag("vis", " ", setAdj, ProcessList.VISIBLE_APP_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700714 } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800715 return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700716 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800717 return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700718 } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800719 return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700720 } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800721 return buildOomTag("sys ", null, setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700722 } else if (setAdj >= ProcessList.NATIVE_ADJ) {
723 return buildOomTag("ntv ", null, setAdj, ProcessList.NATIVE_ADJ);
724 } else {
725 return Integer.toString(setAdj);
726 }
727 }
728
Dianne Hackborn8e692572013-09-10 19:06:15 -0700729 public static String makeProcStateString(int curProcState) {
730 String procState;
731 switch (curProcState) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700732 case ActivityManager.PROCESS_STATE_PERSISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700733 procState = "PER ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700734 break;
735 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Dianne Hackborn94846032017-03-31 17:55:23 -0700736 procState = "PERU";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700737 break;
738 case ActivityManager.PROCESS_STATE_TOP:
Dianne Hackbornf4dd3712017-05-11 17:25:23 -0700739 procState = "TOP ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700740 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700741 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700742 procState = "FGS ";
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700743 break;
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800744 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
745 procState = "BFGS";
746 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700747 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700748 procState = "IMPF";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700749 break;
750 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700751 procState = "IMPB";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700752 break;
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700753 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
754 procState = "TRNB";
755 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700756 case ActivityManager.PROCESS_STATE_BACKUP:
Dianne Hackborn94846032017-03-31 17:55:23 -0700757 procState = "BKUP";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700758 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700759 case ActivityManager.PROCESS_STATE_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700760 procState = "SVC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700761 break;
762 case ActivityManager.PROCESS_STATE_RECEIVER:
Dianne Hackborn94846032017-03-31 17:55:23 -0700763 procState = "RCVR";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700764 break;
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800765 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
766 procState = "TPSL";
767 break;
Dianne Hackbornf097d422017-12-15 16:32:19 -0800768 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
769 procState = "HVY ";
770 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700771 case ActivityManager.PROCESS_STATE_HOME:
Dianne Hackborn94846032017-03-31 17:55:23 -0700772 procState = "HOME";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700773 break;
774 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700775 procState = "LAST";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700776 break;
777 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700778 procState = "CAC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700779 break;
780 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700781 procState = "CACC";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700782 break;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800783 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
784 procState = "CRE ";
785 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700786 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700787 procState = "CEM ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700788 break;
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800789 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700790 procState = "NONE";
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800791 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700792 default:
793 procState = "??";
794 break;
795 }
796 return procState;
797 }
798
Yi Jin148d7f42017-11-28 14:23:56 -0800799 public static int makeProcStateProtoEnum(int curProcState) {
800 switch (curProcState) {
801 case ActivityManager.PROCESS_STATE_PERSISTENT:
Bookatzdb026a22018-01-10 19:01:56 -0800802 return AppProtoEnums.PROCESS_STATE_PERSISTENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800803 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Bookatzdb026a22018-01-10 19:01:56 -0800804 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
Yi Jin148d7f42017-11-28 14:23:56 -0800805 case ActivityManager.PROCESS_STATE_TOP:
Bookatzdb026a22018-01-10 19:01:56 -0800806 return AppProtoEnums.PROCESS_STATE_TOP;
Yi Jin148d7f42017-11-28 14:23:56 -0800807 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800808 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800809 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800810 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800811 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
Bookatzdb026a22018-01-10 19:01:56 -0800812 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING;
Yi Jin148d7f42017-11-28 14:23:56 -0800813 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800814 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800815 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800816 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800817 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800818 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800819 case ActivityManager.PROCESS_STATE_BACKUP:
Bookatzdb026a22018-01-10 19:01:56 -0800820 return AppProtoEnums.PROCESS_STATE_BACKUP;
Yi Jin148d7f42017-11-28 14:23:56 -0800821 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
Bookatzdb026a22018-01-10 19:01:56 -0800822 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT;
Yi Jin148d7f42017-11-28 14:23:56 -0800823 case ActivityManager.PROCESS_STATE_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800824 return AppProtoEnums.PROCESS_STATE_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800825 case ActivityManager.PROCESS_STATE_RECEIVER:
Bookatzdb026a22018-01-10 19:01:56 -0800826 return AppProtoEnums.PROCESS_STATE_RECEIVER;
Yi Jin148d7f42017-11-28 14:23:56 -0800827 case ActivityManager.PROCESS_STATE_HOME:
Bookatzdb026a22018-01-10 19:01:56 -0800828 return AppProtoEnums.PROCESS_STATE_HOME;
Yi Jin148d7f42017-11-28 14:23:56 -0800829 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -0800830 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -0800831 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -0800832 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -0800833 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Bookatzdb026a22018-01-10 19:01:56 -0800834 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800835 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
Bookatzdb026a22018-01-10 19:01:56 -0800836 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800837 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Bookatzdb026a22018-01-10 19:01:56 -0800838 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY;
Yi Jin148d7f42017-11-28 14:23:56 -0800839 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Bookatzdb026a22018-01-10 19:01:56 -0800840 return AppProtoEnums.PROCESS_STATE_NONEXISTENT;
841 case ActivityManager.PROCESS_STATE_UNKNOWN:
842 return AppProtoEnums.PROCESS_STATE_UNKNOWN;
Yi Jin148d7f42017-11-28 14:23:56 -0800843 default:
Bookatzdb026a22018-01-10 19:01:56 -0800844 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO;
Yi Jin148d7f42017-11-28 14:23:56 -0800845 }
846 }
847
Dianne Hackborn8e692572013-09-10 19:06:15 -0700848 public static void appendRamKb(StringBuilder sb, long ramKb) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400849 for (int j = 0, fact = 10; j < 6; j++, fact *= 10) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700850 if (ramKb < fact) {
851 sb.append(' ');
852 }
853 }
854 sb.append(ramKb);
855 }
856
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800857 // How long after a state change that it is safe to collect PSS without it being dirty.
858 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
859
860 // The minimum time interval after a state change it is safe to collect PSS.
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700861 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
862
863 // The maximum amount of time we want to go between PSS collections.
Dianne Hackborne17b4452018-01-10 13:15:40 -0800864 public static final int PSS_MAX_INTERVAL = 60*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700865
866 // The minimum amount of time between successive PSS requests for *all* processes.
Dianne Hackborn052e3142017-12-19 16:08:30 -0800867 public static final int PSS_ALL_INTERVAL = 20*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700868
Dianne Hackborn052e3142017-12-19 16:08:30 -0800869 // The amount of time until PSS when a persistent process first appears.
870 private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700871
872 // The amount of time until PSS when a process first becomes top.
873 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
874
875 // The amount of time until PSS when a process first goes into the background.
876 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
877
878 // The amount of time until PSS when a process first becomes cached.
Dianne Hackborne17b4452018-01-10 13:15:40 -0800879 private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;
880
881 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800882 private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700883
Dianne Hackborn052e3142017-12-19 16:08:30 -0800884 // The amount of time until PSS when the top process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800885 private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;
Dianne Hackborn052e3142017-12-19 16:08:30 -0800886
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700887 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800888 private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700889
890 // The amount of time until PSS when a service process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800891 private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700892
893 // The amount of time until PSS when a cached process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800894 private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700895
Dianne Hackborn052e3142017-12-19 16:08:30 -0800896 // The amount of time until PSS when a persistent process first appears.
897 private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
898
899 // The amount of time until PSS when a process first becomes top.
900 private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000;
901
902 // The amount of time until PSS when a process first goes into the background.
903 private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000;
904
905 // The amount of time until PSS when a process first becomes cached.
906 private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000;
907
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800908 // The minimum time interval after a state change it is safe to collect PSS.
909 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
910
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800911 // The amount of time during testing until PSS when a process first becomes top.
912 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
913
914 // The amount of time during testing until PSS when a process first goes into the background.
915 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
916
917 // The amount of time during testing until PSS when an important process stays in same state.
918 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
919
920 // The amount of time during testing until PSS when a background process stays in same state.
921 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
922
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700923 public static final int PROC_MEM_PERSISTENT = 0;
924 public static final int PROC_MEM_TOP = 1;
925 public static final int PROC_MEM_IMPORTANT = 2;
926 public static final int PROC_MEM_SERVICE = 3;
927 public static final int PROC_MEM_CACHED = 4;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800928 public static final int PROC_MEM_NUM = 5;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700929
Dianne Hackborne17b4452018-01-10 13:15:40 -0800930 // Map large set of system process states to
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700931 private static final int[] sProcStateToProcMem = new int[] {
932 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
933 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
934 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700935 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800936 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700937 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
938 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700939 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700940 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700941 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
942 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800943 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackbornf097d422017-12-15 16:32:19 -0800944 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700945 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME
946 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
947 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
948 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -0800949 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700950 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
951 };
952
953 private static final long[] sFirstAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800954 PSS_FIRST_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
955 PSS_FIRST_TOP_INTERVAL, // PROC_MEM_TOP
956 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
957 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
958 PSS_FIRST_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700959 };
960
961 private static final long[] sSameAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800962 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
963 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP
964 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
965 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE
966 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn052e3142017-12-19 16:08:30 -0800967 };
968
969 private static final long[] sFirstAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800970 PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
971 PSS_FIRST_ASLEEP_TOP_INTERVAL, // PROC_MEM_TOP
972 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
973 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
974 PSS_FIRST_ASLEEP_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn052e3142017-12-19 16:08:30 -0800975 };
976
977 private static final long[] sSameAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800978 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
979 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP
980 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
981 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE
982 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700983 };
984
Dianne Hackbornf097d422017-12-15 16:32:19 -0800985 private static final long[] sTestFirstPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800986 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_PERSISTENT
987 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_TOP
988 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
989 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
990 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800991 };
992
Dianne Hackbornf097d422017-12-15 16:32:19 -0800993 private static final long[] sTestSamePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800994 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_PERSISTENT
995 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_TOP
996 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
997 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
998 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800999 };
1000
Dianne Hackborne17b4452018-01-10 13:15:40 -08001001 public static final class ProcStateMemTracker {
1002 final int[] mHighestMem = new int[PROC_MEM_NUM];
Dianne Hackborned0a3222018-02-06 16:01:23 -08001003 final float[] mScalingFactor = new float[PROC_MEM_NUM];
Dianne Hackborne17b4452018-01-10 13:15:40 -08001004 int mTotalHighestMem = PROC_MEM_CACHED;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001005
1006 int mPendingMemState;
1007 int mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001008 float mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001009
1010 public ProcStateMemTracker() {
1011 for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
1012 mHighestMem[i] = PROC_MEM_NUM;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001013 mScalingFactor[i] = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001014 }
1015 mPendingMemState = -1;
1016 }
1017
1018 public void dumpLine(PrintWriter pw) {
1019 pw.print("best=");
1020 pw.print(mTotalHighestMem);
Dianne Hackborned0a3222018-02-06 16:01:23 -08001021 pw.print(" (");
1022 boolean needSep = false;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001023 for (int i = 0; i < PROC_MEM_NUM; i++) {
Dianne Hackborned0a3222018-02-06 16:01:23 -08001024 if (mHighestMem[i] < PROC_MEM_NUM) {
1025 if (needSep) {
1026 pw.print(", ");
1027 needSep = false;
1028 }
1029 pw.print(i);
1030 pw.print("=");
1031 pw.print(mHighestMem[i]);
1032 pw.print(" ");
1033 pw.print(mScalingFactor[i]);
1034 pw.print("x");
1035 needSep = true;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001036 }
Dianne Hackborne17b4452018-01-10 13:15:40 -08001037 }
1038 pw.print(")");
1039 if (mPendingMemState >= 0) {
1040 pw.print(" / pending state=");
1041 pw.print(mPendingMemState);
1042 pw.print(" highest=");
1043 pw.print(mPendingHighestMemState);
Dianne Hackborned0a3222018-02-06 16:01:23 -08001044 pw.print(" ");
1045 pw.print(mPendingScalingFactor);
1046 pw.print("x");
Dianne Hackborne17b4452018-01-10 13:15:40 -08001047 }
1048 pw.println();
1049 }
1050 }
1051
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001052 public static boolean procStatesDifferForMem(int procState1, int procState2) {
1053 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
1054 }
1055
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -08001056 public static long minTimeFromStateChange(boolean test) {
1057 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
1058 }
1059
Dianne Hackborne17b4452018-01-10 13:15:40 -08001060 public static void commitNextPssTime(ProcStateMemTracker tracker) {
1061 if (tracker.mPendingMemState >= 0) {
1062 tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001063 tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001064 tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001065 tracker.mPendingMemState = -1;
1066 }
1067 }
1068
1069 public static void abortNextPssTime(ProcStateMemTracker tracker) {
1070 tracker.mPendingMemState = -1;
1071 }
1072
1073 public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001074 boolean sleeping, long now) {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001075 boolean first;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001076 float scalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001077 final int memState = sProcStateToProcMem[procState];
1078 if (tracker != null) {
1079 final int highestMemState = memState < tracker.mTotalHighestMem
1080 ? memState : tracker.mTotalHighestMem;
1081 first = highestMemState < tracker.mHighestMem[memState];
1082 tracker.mPendingMemState = memState;
1083 tracker.mPendingHighestMemState = highestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001084 if (first) {
1085 tracker.mPendingScalingFactor = scalingFactor = 1.0f;
1086 } else {
1087 scalingFactor = tracker.mScalingFactor[memState];
1088 tracker.mPendingScalingFactor = scalingFactor * 1.5f;
1089 }
Dianne Hackborne17b4452018-01-10 13:15:40 -08001090 } else {
1091 first = true;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001092 scalingFactor = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001093 }
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001094 final long[] table = test
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001095 ? (first
Dianne Hackborne17b4452018-01-10 13:15:40 -08001096 ? sTestFirstPssTimes
1097 : sTestSamePssTimes)
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001098 : (first
Dianne Hackborne17b4452018-01-10 13:15:40 -08001099 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
1100 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
Dianne Hackborned0a3222018-02-06 16:01:23 -08001101 long delay = (long)(table[memState] * scalingFactor);
Dianne Hackborne17b4452018-01-10 13:15:40 -08001102 if (delay > PSS_MAX_INTERVAL) {
1103 delay = PSS_MAX_INTERVAL;
1104 }
1105 return now + delay;
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001106 }
1107
Dianne Hackborn7d608422011-08-07 16:24:18 -07001108 long getMemLevel(int adjustment) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001109 for (int i = 0; i < mOomAdj.length; i++) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07001110 if (adjustment <= mOomAdj[i]) {
1111 return mOomMinFree[i] * 1024;
1112 }
1113 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001114 return mOomMinFree[mOomAdj.length - 1] * 1024;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001115 }
1116
Todd Poynorbfdd6232013-07-10 19:15:07 -07001117 /**
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001118 * Return the maximum pss size in kb that we consider a process acceptable to
1119 * restore from its cached state for running in the background when RAM is low.
1120 */
Dianne Hackborncbd9a522013-09-24 23:10:14 -07001121 long getCachedRestoreThresholdKb() {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001122 return mCachedRestoreLevel;
1123 }
1124
Dianne Hackborn9bef5b62013-09-20 10:40:34 -07001125 /**
Todd Poynorbfdd6232013-07-10 19:15:07 -07001126 * Set the out-of-memory badness adjustment for a process.
Sudheer Shankaf6690102017-10-16 10:20:32 -07001127 * If {@code pid <= 0}, this method will be a no-op.
Todd Poynorbfdd6232013-07-10 19:15:07 -07001128 *
1129 * @param pid The process identifier to set.
Colin Crossd908edd2014-06-13 14:56:04 -07001130 * @param uid The uid of the app
Todd Poynorbfdd6232013-07-10 19:15:07 -07001131 * @param amt Adjustment value -- lmkd allows -16 to +15.
1132 *
1133 * {@hide}
1134 */
Colin Crossd908edd2014-06-13 14:56:04 -07001135 public static final void setOomAdj(int pid, int uid, int amt) {
Sudheer Shankaf6690102017-10-16 10:20:32 -07001136 // This indicates that the process is not started yet and so no need to proceed further.
1137 if (pid <= 0) {
1138 return;
1139 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001140 if (amt == UNKNOWN_ADJ)
1141 return;
1142
Dianne Hackbornecf1cda2014-08-28 16:58:28 -07001143 long start = SystemClock.elapsedRealtime();
Colin Crossd908edd2014-06-13 14:56:04 -07001144 ByteBuffer buf = ByteBuffer.allocate(4 * 4);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001145 buf.putInt(LMK_PROCPRIO);
1146 buf.putInt(pid);
Colin Crossd908edd2014-06-13 14:56:04 -07001147 buf.putInt(uid);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001148 buf.putInt(amt);
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001149 writeLmkd(buf, null);
Dianne Hackbornecf1cda2014-08-28 16:58:28 -07001150 long now = SystemClock.elapsedRealtime();
1151 if ((now-start) > 250) {
1152 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
1153 + " = " + amt);
1154 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001155 }
1156
1157 /*
1158 * {@hide}
1159 */
1160 public static final void remove(int pid) {
Sudheer Shankaf6690102017-10-16 10:20:32 -07001161 // This indicates that the process is not started yet and so no need to proceed further.
1162 if (pid <= 0) {
1163 return;
1164 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001165 ByteBuffer buf = ByteBuffer.allocate(4 * 2);
1166 buf.putInt(LMK_PROCREMOVE);
1167 buf.putInt(pid);
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001168 writeLmkd(buf, null);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001169 }
1170
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001171 /*
1172 * {@hide}
1173 */
1174 public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) {
1175 ByteBuffer buf = ByteBuffer.allocate(4 * 3);
1176 ByteBuffer repl = ByteBuffer.allocate(4 * 2);
1177 buf.putInt(LMK_GETKILLCNT);
1178 buf.putInt(min_oom_adj);
1179 buf.putInt(max_oom_adj);
1180 if (writeLmkd(buf, repl)) {
1181 int i = repl.getInt();
1182 if (i != LMK_GETKILLCNT) {
1183 Slog.e("ActivityManager", "Failed to get kill count, code mismatch");
1184 return null;
1185 }
1186 return new Integer(repl.getInt());
1187 }
1188 return null;
1189 }
1190
1191 @GuardedBy("sLmkdSocketLock")
1192 private static boolean openLmkdSocketLS() {
Dianne Hackborn7d608422011-08-07 16:24:18 -07001193 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -07001194 sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
1195 sLmkdSocket.connect(
1196 new LocalSocketAddress("lmkd",
1197 LocalSocketAddress.Namespace.RESERVED));
1198 sLmkdOutputStream = sLmkdSocket.getOutputStream();
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001199 sLmkdInputStream = sLmkdSocket.getInputStream();
Todd Poynorbfdd6232013-07-10 19:15:07 -07001200 } catch (IOException ex) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001201 Slog.w(TAG, "lowmemorykiller daemon socket open failed");
Todd Poynorbfdd6232013-07-10 19:15:07 -07001202 sLmkdSocket = null;
1203 return false;
1204 }
1205
1206 return true;
1207 }
1208
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001209 // Never call directly, use writeLmkd() instead
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001210 @GuardedBy("sLmkdSocketLock")
1211 private static boolean writeLmkdCommandLS(ByteBuffer buf) {
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001212 try {
1213 sLmkdOutputStream.write(buf.array(), 0, buf.position());
1214 } catch (IOException ex) {
1215 Slog.w(TAG, "Error writing to lowmemorykiller socket");
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001216 IoUtils.closeQuietly(sLmkdSocket);
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001217 sLmkdSocket = null;
1218 return false;
1219 }
1220 return true;
1221 }
1222
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001223 // Never call directly, use writeLmkd() instead
1224 @GuardedBy("sLmkdSocketLock")
1225 private static boolean readLmkdReplyLS(ByteBuffer buf) {
1226 int len;
1227 try {
1228 len = sLmkdInputStream.read(buf.array(), 0, buf.array().length);
1229 if (len == buf.array().length) {
1230 return true;
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001231 }
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001232 } catch (IOException ex) {
1233 Slog.w(TAG, "Error reading from lowmemorykiller socket");
1234 }
1235
1236 IoUtils.closeQuietly(sLmkdSocket);
1237 sLmkdSocket = null;
1238 return false;
1239 }
1240
1241 private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
1242 synchronized (sLmkdSocketLock) {
1243 for (int i = 0; i < 3; i++) {
1244 if (sLmkdSocket == null) {
1245 if (openLmkdSocketLS() == false) {
1246 try {
1247 Thread.sleep(1000);
1248 } catch (InterruptedException ie) {
1249 }
1250 continue;
1251 }
1252
1253 // Purge any previously registered pids
1254 ByteBuffer purge_buf = ByteBuffer.allocate(4);
1255 purge_buf.putInt(LMK_PROCPURGE);
1256 if (writeLmkdCommandLS(purge_buf) == false) {
1257 // Write failed, skip the rest and retry
1258 continue;
1259 }
1260 }
1261 if (writeLmkdCommandLS(buf) && (repl == null || readLmkdReplyLS(repl))) {
1262 return true;
1263 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07001264 }
1265 }
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001266 return false;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001267 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001268
1269 static void killProcessGroup(int uid, int pid) {
1270 /* static; one-time init here */
1271 if (sKillHandler != null) {
1272 sKillHandler.sendMessage(
1273 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
1274 } else {
1275 Slog.w(TAG, "Asked to kill process group before system bringup!");
1276 Process.killProcessGroup(uid, pid);
1277 }
1278 }
1279
1280 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean
1281 keepIfLarge) {
1282 if (uid == SYSTEM_UID) {
1283 // The system gets to run in any process. If there are multiple
1284 // processes with the same uid, just pick the first (this
1285 // should never happen).
1286 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
1287 if (procs == null) return null;
1288 final int procCount = procs.size();
1289 for (int i = 0; i < procCount; i++) {
1290 final int procUid = procs.keyAt(i);
1291 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
1292 // Don't use an app process or different user process for system component.
1293 continue;
1294 }
1295 return procs.valueAt(i);
1296 }
1297 }
1298 ProcessRecord proc = mProcessNames.get(processName, uid);
1299 if (false && proc != null && !keepIfLarge
1300 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
1301 && proc.lastCachedPss >= 4000) {
1302 // Turn this condition on to cause killing to happen regularly, for testing.
1303 if (proc.baseProcessTracker != null) {
1304 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
1305 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1306 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1307 StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1308 proc.info.uid,
1309 holder.state.getName(),
1310 holder.state.getPackage(),
1311 proc.lastCachedPss, holder.appVersion);
1312 }
1313 }
1314 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
1315 } else if (proc != null && !keepIfLarge
1316 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
1317 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
1318 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc
1319 .lastCachedPss);
1320 if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) {
1321 if (proc.baseProcessTracker != null) {
1322 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
1323 proc.lastCachedPss);
1324 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1325 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1326 StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1327 proc.info.uid,
1328 holder.state.getName(),
1329 holder.state.getPackage(),
1330 proc.lastCachedPss, holder.appVersion);
1331 }
1332 }
1333 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
1334 }
1335 }
1336 return proc;
1337 }
1338
1339 void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
1340 final long homeAppMem = getMemLevel(HOME_APP_ADJ);
1341 final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ);
1342 outInfo.availMem = getFreeMemory();
1343 outInfo.totalMem = getTotalMemory();
1344 outInfo.threshold = homeAppMem;
1345 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
1346 outInfo.hiddenAppThreshold = cachedAppMem;
1347 outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ);
1348 outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ);
1349 outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ);
1350 }
1351
1352 ProcessRecord findAppProcessLocked(IBinder app, String reason) {
1353 final int NP = mProcessNames.getMap().size();
1354 for (int ip = 0; ip < NP; ip++) {
1355 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
1356 final int NA = apps.size();
1357 for (int ia = 0; ia < NA; ia++) {
1358 ProcessRecord p = apps.valueAt(ia);
1359 if (p.thread != null && p.thread.asBinder() == app) {
1360 return p;
1361 }
1362 }
1363 }
1364
1365 Slog.w(TAG, "Can't find mystery application for " + reason
1366 + " from pid=" + Binder.getCallingPid()
1367 + " uid=" + Binder.getCallingUid() + ": " + app);
1368 return null;
1369 }
1370
1371 private void checkSlow(long startTime, String where) {
1372 long now = SystemClock.uptimeMillis();
1373 if ((now - startTime) > 50) {
1374 // If we are taking more than 50ms, log about it.
1375 Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where);
1376 }
1377 }
1378
1379 /**
1380 * @return {@code true} if process start is successful, false otherwise.
1381 * @param app
1382 * @param hostingType
1383 * @param hostingNameStr
1384 * @param disableHiddenApiChecks
1385 * @param abiOverride
1386 */
1387 @GuardedBy("mService")
1388 boolean startProcessLocked(ProcessRecord app, String hostingType,
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001389 String hostingNameStr, boolean disableHiddenApiChecks, boolean mountExtStorageFull,
1390 String abiOverride) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001391 if (app.pendingStart) {
1392 return true;
1393 }
1394 long startTime = SystemClock.elapsedRealtime();
1395 if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
1396 checkSlow(startTime, "startProcess: removing from pids map");
Wale Ogunwale0b940842018-12-03 06:58:11 -08001397 mService.mPidsSelfLocked.remove(app.pid);
1398 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04001399 checkSlow(startTime, "startProcess: done removing from pids map");
1400 app.setPid(0);
1401 }
1402
1403 if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
1404 TAG_PROCESSES,
1405 "startProcessLocked removing on hold: " + app);
1406 mService.mProcessesOnHold.remove(app);
1407
1408 checkSlow(startTime, "startProcess: starting to update cpu stats");
1409 mService.updateCpuStats();
1410 checkSlow(startTime, "startProcess: done updating cpu stats");
1411
1412 try {
1413 try {
1414 final int userId = UserHandle.getUserId(app.uid);
1415 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
1416 } catch (RemoteException e) {
1417 throw e.rethrowAsRuntimeException();
1418 }
1419
1420 int uid = app.uid;
1421 int[] gids = null;
1422 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1423 if (!app.isolated) {
1424 int[] permGids = null;
1425 try {
1426 checkSlow(startTime, "startProcess: getting gids from package manager");
1427 final IPackageManager pm = AppGlobals.getPackageManager();
1428 permGids = pm.getPackageGids(app.info.packageName,
1429 MATCH_DIRECT_BOOT_AUTO, app.userId);
Jeff Sharkey10ec9d82018-11-28 14:52:45 -07001430 if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001431 mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
1432 } else {
1433 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1434 StorageManagerInternal.class);
1435 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
1436 app.info.packageName);
1437 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001438 } catch (RemoteException e) {
1439 throw e.rethrowAsRuntimeException();
1440 }
1441
1442 /*
1443 * Add shared application and profile GIDs so applications can share some
1444 * resources like shared libraries and access user-wide resources
1445 */
1446 if (ArrayUtils.isEmpty(permGids)) {
1447 gids = new int[3];
1448 } else {
1449 gids = new int[permGids.length + 3];
1450 System.arraycopy(permGids, 0, gids, 3, permGids.length);
1451 }
1452 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
1453 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
1454 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
1455
1456 // Replace any invalid GIDs
1457 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
1458 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
1459 }
Sudheer Shanka87915d62018-11-06 10:57:35 -08001460 app.mountMode = mountExternal;
Amith Yamasani98a00922018-08-21 12:50:30 -04001461 checkSlow(startTime, "startProcess: building args");
1462 if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
1463 uid = 0;
1464 }
1465 int runtimeFlags = 0;
1466 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1467 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
1468 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1469 // Also turn on CheckJNI for debuggable apps. It's quite
1470 // awkward to turn on otherwise.
1471 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1472 }
1473 // Run the app in safe mode if its manifest requests so or the
1474 // system is booted in safe mode.
1475 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1476 mService.mSafeMode == true) {
1477 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1478 }
1479 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1480 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1481 }
1482 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1483 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1484 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1485 }
1486 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1487 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1488 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1489 }
1490 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1491 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1492 }
1493 if ("1".equals(SystemProperties.get("debug.assert"))) {
1494 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1495 }
1496 if (mService.mNativeDebuggingApp != null
1497 && mService.mNativeDebuggingApp.equals(app.processName)) {
1498 // Enable all debug flags required by the native debugger.
1499 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
1500 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1501 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
1502 mService.mNativeDebuggingApp = null;
1503 }
1504
Victor Hsiehf12af2f2019-01-03 10:11:03 -08001505 if (app.info.isCodeIntegrityPreferred()
Victor Hsiehe7b5a8d2018-11-16 10:27:06 -08001506 || (app.info.isPrivilegedApp()
1507 && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001508 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1509 }
1510
1511 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
1512 app.info.maybeUpdateHiddenApiEnforcementPolicy(
David Brazdil06ae4b82018-11-02 18:01:45 +00001513 mService.mHiddenApiBlacklist.getPolicy());
Amith Yamasani98a00922018-08-21 12:50:30 -04001514 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
1515 app.info.getHiddenApiEnforcementPolicy();
1516 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
1517 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
1518 throw new IllegalStateException("Invalid API policy: " + policy);
1519 }
1520 runtimeFlags |= policyBits;
1521 }
1522
1523 String invokeWith = null;
1524 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1525 // Debuggable apps may include a wrapper script with their library directory.
1526 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
1527 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
1528 try {
1529 if (new File(wrapperFileName).exists()) {
1530 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
1531 }
1532 } finally {
1533 StrictMode.setThreadPolicy(oldPolicy);
1534 }
1535 }
1536
1537 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
1538 if (requiredAbi == null) {
1539 requiredAbi = Build.SUPPORTED_ABIS[0];
1540 }
1541
1542 String instructionSet = null;
1543 if (app.info.primaryCpuAbi != null) {
1544 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
1545 }
1546
1547 app.gids = gids;
1548 app.setRequiredAbi(requiredAbi);
1549 app.instructionSet = instructionSet;
1550
1551 // the per-user SELinux context must be set
1552 if (TextUtils.isEmpty(app.info.seInfoUser)) {
1553 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
1554 new IllegalStateException("SELinux tag not defined for "
1555 + app.info.packageName + " (uid " + app.uid + ")"));
1556 }
1557 final String seInfo = app.info.seInfo
1558 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
1559 // Start the process. It will either succeed and return a result containing
1560 // the PID of the new process, or else throw a RuntimeException.
1561 final String entryPoint = "android.app.ActivityThread";
1562
1563 return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
1564 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
1565 startTime);
1566 } catch (RuntimeException e) {
1567 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1568
1569 // Something went very wrong while trying to start this process; one
1570 // common case is when the package is frozen due to an active
1571 // upgrade. To recover, clean up any active bookkeeping related to
1572 // starting this process. (We already invoked this method once when
1573 // the package was initially frozen through KILL_APPLICATION_MSG, so
1574 // it doesn't hurt to use it again.)
1575 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1576 false, false, true, false, false, app.userId, "start failure");
1577 return false;
1578 }
1579 }
1580
1581 @GuardedBy("mService")
1582 boolean startProcessLocked(String hostingType, String hostingNameStr,
1583 String entryPoint,
1584 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1585 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1586 long startTime) {
1587 app.pendingStart = true;
1588 app.killedByAm = false;
1589 app.removed = false;
1590 app.killed = false;
1591 final long startSeq = app.startSeq = ++mProcStartSeqCounter;
1592 app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
1593 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
1594 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
1595 "Posting procStart msg for " + app.toShortString());
1596 mService.mProcStartHandler.post(() -> {
1597 try {
1598 synchronized (mService) {
1599 final String reason = isProcStartValidLocked(app, startSeq);
1600 if (reason != null) {
1601 Slog.w(TAG_PROCESSES, app + " not valid anymore,"
1602 + " don't start process, " + reason);
1603 app.pendingStart = false;
1604 return;
1605 }
1606 app.setUsingWrapper(invokeWith != null
1607 || SystemProperties.get("wrap." + app.processName) != null);
1608 mPendingStarts.put(startSeq, app);
1609 }
1610 final Process.ProcessStartResult startResult = startProcess(app.hostingType,
1611 entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
1612 app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
1613 synchronized (mService) {
1614 handleProcessStartedLocked(app, startResult, startSeq);
1615 }
1616 } catch (RuntimeException e) {
1617 synchronized (mService) {
1618 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1619 + app.processName, e);
1620 mPendingStarts.remove(startSeq);
1621 app.pendingStart = false;
1622 mService.forceStopPackageLocked(app.info.packageName,
1623 UserHandle.getAppId(app.uid),
1624 false, false, true, false, false, app.userId, "start failure");
1625 }
1626 }
1627 });
1628 return true;
1629 } else {
1630 try {
1631 final Process.ProcessStartResult startResult = startProcess(hostingType,
1632 entryPoint, app,
1633 uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
1634 invokeWith, startTime);
1635 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
1636 startSeq, false);
1637 } catch (RuntimeException e) {
1638 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1639 + app.processName, e);
1640 app.pendingStart = false;
1641 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1642 false, false, true, false, false, app.userId, "start failure");
1643 }
1644 return app.pid > 0;
1645 }
1646 }
1647
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001648 @GuardedBy("mService")
1649 public void killAppZygoteIfNeededLocked(AppZygote appZygote) {
1650 final ApplicationInfo appInfo = appZygote.getAppInfo();
1651 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
1652 if (zygoteProcesses.size() == 0) { // Only remove if no longer in use now
1653 mAppZygotes.remove(appInfo.processName, appInfo.uid);
1654 mAppZygoteProcesses.remove(appZygote);
Martijn Coenen01e719b2018-12-05 16:01:38 +01001655 mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001656 appZygote.stopZygote();
1657 }
1658 }
1659
1660 @GuardedBy("mService")
1661 private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01001662 // Free the isolated uid for this process
1663 final IsolatedUidRange appUidRange =
1664 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info);
1665 if (appUidRange != null) {
1666 appUidRange.freeIsolatedUidLocked(app.uid);
1667 }
1668
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001669 final AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid);
1670 if (appZygote != null) {
1671 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
1672 zygoteProcesses.remove(app);
1673 if (zygoteProcesses.size() == 0) {
1674 Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
1675 msg.obj = appZygote;
1676 mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS);
1677 }
1678 }
1679 }
1680
1681 private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
1682 synchronized (mService) {
1683 AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid);
1684 final ArrayList<ProcessRecord> zygoteProcessList;
1685 if (appZygote == null) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01001686 final IsolatedUidRange uidRange =
1687 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info);
Martijn Coenen86f08a52019-01-03 16:23:01 +01001688 final int userId = UserHandle.getUserId(app.info.uid);
1689 // Create the app-zygote and provide it with the UID-range it's allowed
1690 // to setresuid/setresgid to.
1691 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
1692 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
1693 appZygote = new AppZygote(app.info, app.info.uid, firstUid, lastUid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001694 mAppZygotes.put(app.info.processName, app.info.uid, appZygote);
1695 zygoteProcessList = new ArrayList<ProcessRecord>();
1696 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
1697 } else {
1698 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
1699 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
1700 }
1701 // Note that we already add the app to mAppZygoteProcesses here;
1702 // this is so that another thread can't come in and kill the zygote
1703 // before we've even tried to start the process. If the process launch
1704 // goes wrong, we'll clean this up in removeProcessNameLocked()
1705 zygoteProcessList.add(app);
1706
1707 return appZygote;
1708 }
1709 }
1710
Amith Yamasani98a00922018-08-21 12:50:30 -04001711 private Process.ProcessStartResult startProcess(String hostingType, String entryPoint,
1712 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1713 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1714 long startTime) {
1715 try {
1716 final String[] packageNames = mService.mContext.getPackageManager()
1717 .getPackagesForUid(uid);
1718 final String[] visibleVolIds = LocalServices.getService(StorageManagerInternal.class)
1719 .getVisibleVolumesForUser(UserHandle.getUserId(uid));
1720 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
1721 app.processName);
1722 checkSlow(startTime, "startProcess: asking zygote to start proc");
1723 final Process.ProcessStartResult startResult;
1724 if (hostingType.equals("webview_service")) {
1725 startResult = startWebView(entryPoint,
1726 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1727 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1728 app.info.dataDir, null, app.info.packageName,
1729 packageNames, visibleVolIds,
1730 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001731 } else if (hostingType.equals("app_zygote")) {
1732 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
1733
1734 startResult = appZygote.getProcess().start(entryPoint,
1735 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1736 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1737 app.info.dataDir, null, app.info.packageName,
Chris Wailesba4c2eb2019-01-11 17:13:00 -08001738 packageNames, visibleVolIds, /*useBlastulaPool=*/ false,
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001739 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
Amith Yamasani98a00922018-08-21 12:50:30 -04001740 } else {
1741 startResult = Process.start(entryPoint,
1742 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1743 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1744 app.info.dataDir, invokeWith, app.info.packageName,
1745 packageNames, visibleVolIds,
1746 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1747 }
1748 checkSlow(startTime, "startProcess: returned from zygote!");
1749 return startResult;
1750 } finally {
1751 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1752 }
1753 }
1754
1755 @GuardedBy("mService")
1756 final void startProcessLocked(ProcessRecord app,
1757 String hostingType, String hostingNameStr) {
1758 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
1759 }
1760
1761 @GuardedBy("mService")
1762 final boolean startProcessLocked(ProcessRecord app,
1763 String hostingType, String hostingNameStr, String abiOverride) {
1764 return startProcessLocked(app, hostingType, hostingNameStr,
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001765 false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
Amith Yamasani98a00922018-08-21 12:50:30 -04001766 }
1767
1768 @GuardedBy("mService")
1769 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
1770 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
1771 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
1772 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
1773 long startTime = SystemClock.elapsedRealtime();
1774 ProcessRecord app;
1775 if (!isolated) {
1776 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
1777 checkSlow(startTime, "startProcess: after getProcessRecord");
1778
1779 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
1780 // If we are in the background, then check to see if this process
1781 // is bad. If so, we will just silently fail.
1782 if (mService.mAppErrors.isBadProcessLocked(info)) {
1783 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1784 + "/" + info.processName);
1785 return null;
1786 }
1787 } else {
1788 // When the user is explicitly starting a process, then clear its
1789 // crash count so that we won't make it bad until they see at
1790 // least one crash dialog again, and make the process good again
1791 // if it had been bad.
1792 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1793 + "/" + info.processName);
1794 mService.mAppErrors.resetProcessCrashTimeLocked(info);
1795 if (mService.mAppErrors.isBadProcessLocked(info)) {
1796 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
1797 UserHandle.getUserId(info.uid), info.uid,
1798 info.processName);
1799 mService.mAppErrors.clearBadProcessLocked(info);
1800 if (app != null) {
1801 app.bad = false;
1802 }
1803 }
1804 }
1805 } else {
1806 // If this is an isolated process, it can't re-use an existing process.
1807 app = null;
1808 }
1809
1810 // We don't have to do anything more if:
1811 // (1) There is an existing application record; and
1812 // (2) The caller doesn't think it is dead, OR there is no thread
1813 // object attached to it so we know it couldn't have crashed; and
1814 // (3) There is a pid assigned to it, so it is either starting or
1815 // already running.
1816 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
1817 + " app=" + app + " knownToBeDead=" + knownToBeDead
1818 + " thread=" + (app != null ? app.thread : null)
1819 + " pid=" + (app != null ? app.pid : -1));
1820 if (app != null && app.pid > 0) {
1821 if ((!knownToBeDead && !app.killed) || app.thread == null) {
1822 // We already have the app running, or are waiting for it to
1823 // come up (we have a pid but not yet its thread), so keep it.
1824 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
1825 // If this is a new package in the process, add the package to the list
1826 app.addPackage(info.packageName, info.versionCode, mService.mProcessStats);
1827 checkSlow(startTime, "startProcess: done, added package to proc");
1828 return app;
1829 }
1830
1831 // An application record is attached to a previous process,
1832 // clean it up now.
1833 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
1834 checkSlow(startTime, "startProcess: bad proc running, killing");
1835 ProcessList.killProcessGroup(app.uid, app.pid);
1836 mService.handleAppDiedLocked(app, true, true);
1837 checkSlow(startTime, "startProcess: done killing old proc");
1838 }
1839
1840 String hostingNameStr = hostingName != null
1841 ? hostingName.flattenToShortString() : null;
1842
1843 if (app == null) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01001844 final boolean fromAppZygote = "app_zygote".equals(hostingType);
Amith Yamasani98a00922018-08-21 12:50:30 -04001845 checkSlow(startTime, "startProcess: creating new process record");
Martijn Coenen01e719b2018-12-05 16:01:38 +01001846 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, fromAppZygote);
Amith Yamasani98a00922018-08-21 12:50:30 -04001847 if (app == null) {
1848 Slog.w(TAG, "Failed making new process record for "
1849 + processName + "/" + info.uid + " isolated=" + isolated);
1850 return null;
1851 }
1852 app.crashHandler = crashHandler;
1853 app.isolatedEntryPoint = entryPoint;
1854 app.isolatedEntryPointArgs = entryPointArgs;
1855 checkSlow(startTime, "startProcess: done creating new process record");
1856 } else {
1857 // If this is a new package in the process, add the package to the list
1858 app.addPackage(info.packageName, info.versionCode, mService.mProcessStats);
1859 checkSlow(startTime, "startProcess: added package to existing proc");
1860 }
1861
1862 // If the system is not ready yet, then hold off on starting this
1863 // process until it is.
1864 if (!mService.mProcessesReady
1865 && !mService.isAllowedWhileBooting(info)
1866 && !allowWhileBooting) {
1867 if (!mService.mProcessesOnHold.contains(app)) {
1868 mService.mProcessesOnHold.add(app);
1869 }
1870 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
1871 "System not ready, putting on hold: " + app);
1872 checkSlow(startTime, "startProcess: returning with proc on hold");
1873 return app;
1874 }
1875
1876 checkSlow(startTime, "startProcess: stepping in to startProcess");
1877 final boolean success = startProcessLocked(app, hostingType, hostingNameStr,
1878 abiOverride);
1879 checkSlow(startTime, "startProcess: done starting proc!");
1880 return success ? app : null;
1881 }
1882
1883 @GuardedBy("mService")
1884 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
1885 StringBuilder sb = null;
1886 if (app.killedByAm) {
1887 if (sb == null) sb = new StringBuilder();
1888 sb.append("killedByAm=true;");
1889 }
1890 if (mProcessNames.get(app.processName, app.uid) != app) {
1891 if (sb == null) sb = new StringBuilder();
1892 sb.append("No entry in mProcessNames;");
1893 }
1894 if (!app.pendingStart) {
1895 if (sb == null) sb = new StringBuilder();
1896 sb.append("pendingStart=false;");
1897 }
1898 if (app.startSeq > expectedStartSeq) {
1899 if (sb == null) sb = new StringBuilder();
1900 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
1901 }
1902 return sb == null ? null : sb.toString();
1903 }
1904
1905 @GuardedBy("mService")
1906 private boolean handleProcessStartedLocked(ProcessRecord pending,
1907 Process.ProcessStartResult startResult, long expectedStartSeq) {
1908 // Indicates that this process start has been taken care of.
1909 if (mPendingStarts.get(expectedStartSeq) == null) {
1910 if (pending.pid == startResult.pid) {
1911 pending.setUsingWrapper(startResult.usingWrapper);
1912 // TODO: Update already existing clients of usingWrapper
1913 }
1914 return false;
1915 }
1916 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
1917 expectedStartSeq, false);
1918 }
1919
1920 @GuardedBy("mService")
1921 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
1922 long expectedStartSeq, boolean procAttached) {
1923 mPendingStarts.remove(expectedStartSeq);
1924 final String reason = isProcStartValidLocked(app, expectedStartSeq);
1925 if (reason != null) {
1926 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
1927 pid
1928 + ", " + reason);
1929 app.pendingStart = false;
1930 killProcessQuiet(pid);
1931 Process.killProcessGroup(app.uid, app.pid);
1932 return false;
1933 }
1934 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
1935 checkSlow(app.startTime, "startProcess: done updating battery stats");
1936
1937 EventLog.writeEvent(EventLogTags.AM_PROC_START,
1938 UserHandle.getUserId(app.startUid), pid, app.startUid,
1939 app.processName, app.hostingType,
1940 app.hostingNameStr != null ? app.hostingNameStr : "");
1941
1942 try {
1943 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
1944 app.seInfo, app.info.sourceDir, pid);
1945 } catch (RemoteException ex) {
1946 // Ignore
1947 }
1948
1949 if (app.isPersistent()) {
1950 Watchdog.getInstance().processStarted(app.processName, pid);
1951 }
1952
1953 checkSlow(app.startTime, "startProcess: building log message");
1954 StringBuilder buf = mStringBuilder;
1955 buf.setLength(0);
1956 buf.append("Start proc ");
1957 buf.append(pid);
1958 buf.append(':');
1959 buf.append(app.processName);
1960 buf.append('/');
1961 UserHandle.formatUid(buf, app.startUid);
1962 if (app.isolatedEntryPoint != null) {
1963 buf.append(" [");
1964 buf.append(app.isolatedEntryPoint);
1965 buf.append("]");
1966 }
1967 buf.append(" for ");
1968 buf.append(app.hostingType);
1969 if (app.hostingNameStr != null) {
1970 buf.append(" ");
1971 buf.append(app.hostingNameStr);
1972 }
1973 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
1974 app.setPid(pid);
1975 app.setUsingWrapper(usingWrapper);
1976 app.pendingStart = false;
1977 checkSlow(app.startTime, "startProcess: starting to update pids map");
1978 ProcessRecord oldApp;
1979 synchronized (mService.mPidsSelfLocked) {
1980 oldApp = mService.mPidsSelfLocked.get(pid);
1981 }
1982 // If there is already an app occupying that pid that hasn't been cleaned up
1983 if (oldApp != null && !app.isolated) {
1984 // Clean up anything relating to this pid first
1985 Slog.w(TAG, "Reusing pid " + pid
1986 + " while app is still mapped to it");
1987 mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
1988 true /*replacingPid*/);
1989 }
Wale Ogunwale0b940842018-12-03 06:58:11 -08001990 mService.mPidsSelfLocked.put(pid, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04001991 synchronized (mService.mPidsSelfLocked) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001992 if (!procAttached) {
1993 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1994 msg.obj = app;
1995 mService.mHandler.sendMessageDelayed(msg, usingWrapper
1996 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
1997 }
1998 }
1999 checkSlow(app.startTime, "startProcess: done updating pids map");
2000 return true;
2001 }
2002
2003 final void removeLruProcessLocked(ProcessRecord app) {
2004 int lrui = mLruProcesses.lastIndexOf(app);
2005 if (lrui >= 0) {
2006 if (!app.killed) {
2007 if (app.isPersistent()) {
2008 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2009 } else {
2010 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2011 if (app.pid > 0) {
2012 killProcessQuiet(app.pid);
2013 ProcessList.killProcessGroup(app.uid, app.pid);
2014 } else {
2015 app.pendingStart = false;
2016 }
2017 }
2018 }
2019 if (lrui <= mLruProcessActivityStart) {
2020 mLruProcessActivityStart--;
2021 }
2022 if (lrui <= mLruProcessServiceStart) {
2023 mLruProcessServiceStart--;
2024 }
2025 mLruProcesses.remove(lrui);
2026 }
2027 }
2028
2029 void killAllBackgroundProcessesLocked() {
2030 final ArrayList<ProcessRecord> procs = new ArrayList<>();
2031 final int NP = mProcessNames.getMap().size();
2032 for (int ip = 0; ip < NP; ip++) {
2033 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2034 final int NA = apps.size();
2035 for (int ia = 0; ia < NA; ia++) {
2036 final ProcessRecord app = apps.valueAt(ia);
2037 if (app.isPersistent()) {
2038 // We don't kill persistent processes.
2039 continue;
2040 }
2041 if (app.removed) {
2042 procs.add(app);
2043 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
2044 app.removed = true;
2045 procs.add(app);
2046 }
2047 }
2048 }
2049
2050 final int N = procs.size();
2051 for (int i = 0; i < N; i++) {
2052 removeProcessLocked(procs.get(i), false, true, "kill all background");
2053 }
2054 }
2055
2056 @GuardedBy("mService")
2057 final boolean killPackageProcessesLocked(String packageName, int appId,
2058 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
2059 boolean doit, boolean evenPersistent, String reason) {
2060 ArrayList<ProcessRecord> procs = new ArrayList<>();
2061
2062 // Remove all processes this package may have touched: all with the
2063 // same UID (except for the system or root user), and all whose name
2064 // matches the package name.
2065 final int NP = mProcessNames.getMap().size();
2066 for (int ip = 0; ip < NP; ip++) {
2067 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2068 final int NA = apps.size();
2069 for (int ia = 0; ia < NA; ia++) {
2070 ProcessRecord app = apps.valueAt(ia);
2071 if (app.isPersistent() && !evenPersistent) {
2072 // we don't kill persistent processes
2073 continue;
2074 }
2075 if (app.removed) {
2076 if (doit) {
2077 procs.add(app);
2078 }
2079 continue;
2080 }
2081
2082 // Skip process if it doesn't meet our oom adj requirement.
2083 if (app.setAdj < minOomAdj) {
2084 continue;
2085 }
2086
2087 // If no package is specified, we call all processes under the
2088 // give user id.
2089 if (packageName == null) {
2090 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2091 continue;
2092 }
2093 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2094 continue;
2095 }
2096 // Package has been specified, we want to hit all processes
2097 // that match it. We need to qualify this by the processes
2098 // that are running under the specified app and user ID.
2099 } else {
2100 final boolean isDep = app.pkgDeps != null
2101 && app.pkgDeps.contains(packageName);
2102 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2103 continue;
2104 }
2105 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2106 continue;
2107 }
2108 if (!app.pkgList.containsKey(packageName) && !isDep) {
2109 continue;
2110 }
2111 }
2112
2113 // Process has passed all conditions, kill it!
2114 if (!doit) {
2115 return true;
2116 }
2117 app.removed = true;
2118 procs.add(app);
2119 }
2120 }
2121
2122 int N = procs.size();
2123 for (int i=0; i<N; i++) {
2124 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
2125 }
2126 mService.updateOomAdjLocked();
2127 return N > 0;
2128 }
2129 @GuardedBy("mService")
2130 boolean removeProcessLocked(ProcessRecord app,
2131 boolean callerWillRestart, boolean allowRestart, String reason) {
2132 final String name = app.processName;
2133 final int uid = app.uid;
2134 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
2135 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
2136
2137 ProcessRecord old = mProcessNames.get(name, uid);
2138 if (old != app) {
2139 // This process is no longer active, so nothing to do.
2140 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
2141 return false;
2142 }
2143 removeProcessNameLocked(name, uid);
2144 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
2145
2146 boolean needRestart = false;
2147 if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
2148 .pendingStart)) {
2149 int pid = app.pid;
2150 if (pid > 0) {
Wale Ogunwale0b940842018-12-03 06:58:11 -08002151 mService.mPidsSelfLocked.remove(pid);
2152 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002153 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2154 if (app.isolated) {
2155 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2156 mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
2157 }
2158 }
2159 boolean willRestart = false;
2160 if (app.isPersistent() && !app.isolated) {
2161 if (!callerWillRestart) {
2162 willRestart = true;
2163 } else {
2164 needRestart = true;
2165 }
2166 }
2167 app.kill(reason, true);
2168 mService.handleAppDiedLocked(app, willRestart, allowRestart);
2169 if (willRestart) {
2170 removeLruProcessLocked(app);
2171 mService.addAppLocked(app.info, null, false, null /* ABI override */);
2172 }
2173 } else {
2174 mRemovedProcesses.add(app);
2175 }
2176
2177 return needRestart;
2178 }
2179
2180 @GuardedBy("mService")
2181 final void addProcessNameLocked(ProcessRecord proc) {
2182 // We shouldn't already have a process under this name, but just in case we
2183 // need to clean up whatever may be there now.
2184 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
2185 if (old == proc && proc.isPersistent()) {
2186 // We are re-adding a persistent process. Whatevs! Just leave it there.
2187 Slog.w(TAG, "Re-adding persistent process " + proc);
2188 } else if (old != null) {
2189 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
2190 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08002191 UidRecord uidRec = mActiveUids.get(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002192 if (uidRec == null) {
Wale Ogunwalebff2df42018-10-18 17:09:19 -07002193 uidRec = new UidRecord(proc.uid, mService.mAtmInternal);
Amith Yamasani98a00922018-08-21 12:50:30 -04002194 // This is the first appearance of the uid, report it now!
2195 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2196 "Creating new process uid: " + uidRec);
2197 if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
2198 UserHandle.getAppId(proc.uid)) >= 0
2199 || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
2200 uidRec.setWhitelist = uidRec.curWhitelist = true;
2201 }
2202 uidRec.updateHasInternetPermission();
Amith Yamasaniaa746442019-01-10 10:09:12 -08002203 mActiveUids.put(proc.uid, uidRec);
Amith Yamasani98a00922018-08-21 12:50:30 -04002204 EventLogTags.writeAmUidRunning(uidRec.uid);
Wale Ogunwalebff2df42018-10-18 17:09:19 -07002205 mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
Amith Yamasani98a00922018-08-21 12:50:30 -04002206 }
2207 proc.uidRecord = uidRec;
2208
2209 // Reset render thread tid if it was already set, so new process can set it again.
2210 proc.renderThreadTid = 0;
2211 uidRec.numProcs++;
2212 mProcessNames.put(proc.processName, proc.uid, proc);
2213 if (proc.isolated) {
2214 mIsolatedProcesses.put(proc.uid, proc);
2215 }
2216 }
2217
2218 @GuardedBy("mService")
Martijn Coenen01e719b2018-12-05 16:01:38 +01002219 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
2220 boolean fromAppZygote) {
2221 if (!fromAppZygote) {
2222 // Allocate an isolated UID from the global range
2223 return mGlobalIsolatedUids;
2224 } else {
2225 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(info);
2226 }
2227 }
2228
2229 @GuardedBy("mService")
Amith Yamasani98a00922018-08-21 12:50:30 -04002230 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
Martijn Coenen01e719b2018-12-05 16:01:38 +01002231 boolean isolated, int isolatedUid, boolean fromAppZygote) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002232 String proc = customProcess != null ? customProcess : info.processName;
2233 final int userId = UserHandle.getUserId(info.uid);
2234 int uid = info.uid;
2235 if (isolated) {
2236 if (isolatedUid == 0) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01002237 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, fromAppZygote);
2238 if (uidRange == null) {
2239 return null;
2240 }
2241 uid = uidRange.allocateIsolatedUidLocked(userId);
2242 if (uid == -1) {
2243 return null;
Amith Yamasani98a00922018-08-21 12:50:30 -04002244 }
2245 } else {
2246 // Special case for startIsolatedProcess (internal only), where
2247 // the uid of the isolated process is specified by the caller.
2248 uid = isolatedUid;
2249 }
2250 mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
2251
2252 // Register the isolated UID with this application so BatteryStats knows to
2253 // attribute resource usage to the application.
2254 //
2255 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
2256 // about the process state of the isolated UID *before* it is registered with the
2257 // owning application.
2258 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
2259 StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
2260 StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
2261 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002262 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002263
2264 if (!mService.mBooted && !mService.mBooting
2265 && userId == UserHandle.USER_SYSTEM
2266 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
2267 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
2268 r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
2269 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
2270 r.setPersistent(true);
2271 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
2272 }
2273 if (isolated && isolatedUid != 0) {
2274 // Special case for startIsolatedProcess (internal only) - assume the process
2275 // is required by the system server to prevent it being killed.
2276 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
2277 }
2278 addProcessNameLocked(r);
2279 return r;
2280 }
2281
2282 @GuardedBy("mService")
2283 final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
2284 return removeProcessNameLocked(name, uid, null);
2285 }
2286
2287 @GuardedBy("mService")
2288 final ProcessRecord removeProcessNameLocked(final String name, final int uid,
2289 final ProcessRecord expecting) {
2290 ProcessRecord old = mProcessNames.get(name, uid);
2291 // Only actually remove when the currently recorded value matches the
2292 // record that we expected; if it doesn't match then we raced with a
2293 // newly created process and we don't want to destroy the new one.
2294 if ((expecting == null) || (old == expecting)) {
2295 mProcessNames.remove(name, uid);
2296 }
2297 if (old != null && old.uidRecord != null) {
2298 old.uidRecord.numProcs--;
2299 if (old.uidRecord.numProcs == 0) {
2300 // No more processes using this uid, tell clients it is gone.
2301 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2302 "No more processes in " + old.uidRecord);
2303 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
2304 EventLogTags.writeAmUidStopped(uid);
Amith Yamasaniaa746442019-01-10 10:09:12 -08002305 mActiveUids.remove(uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002306 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
2307 }
2308 old.uidRecord = null;
2309 }
2310 mIsolatedProcesses.remove(uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +01002311 mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002312 // Remove the (expected) ProcessRecord from the app zygote
2313 final ProcessRecord record = expecting != null ? expecting : old;
Martijn Coenen01e719b2018-12-05 16:01:38 +01002314 if (record != null && record.appZygote) {
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002315 removeProcessFromAppZygoteLocked(record);
2316 }
2317
Amith Yamasani98a00922018-08-21 12:50:30 -04002318 return old;
2319 }
2320
2321 /** Call setCoreSettings on all LRU processes, with the new settings. */
2322 @GuardedBy("mService")
2323 void updateCoreSettingsLocked(Bundle settings) {
2324 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2325 ProcessRecord processRecord = mLruProcesses.get(i);
2326 try {
2327 if (processRecord.thread != null) {
2328 processRecord.thread.setCoreSettings(settings);
2329 }
2330 } catch (RemoteException re) {
2331 /* ignore */
2332 }
2333 }
2334 }
2335
2336 /**
2337 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2338 * procstate lower than maxProcState.
2339 * @param minTargetSdk
2340 * @param maxProcState
2341 */
2342 @GuardedBy("mService")
2343 void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2344 final ArrayList<ProcessRecord> procs = new ArrayList<>();
2345 final int NP = mProcessNames.getMap().size();
2346 for (int ip = 0; ip < NP; ip++) {
2347 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2348 final int NA = apps.size();
2349 for (int ia = 0; ia < NA; ia++) {
2350 final ProcessRecord app = apps.valueAt(ia);
2351 if (app.removed) {
2352 procs.add(app);
2353 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2354 && (maxProcState < 0 || app.setProcState > maxProcState)) {
2355 app.removed = true;
2356 procs.add(app);
2357 }
2358 }
2359 }
2360
2361 final int N = procs.size();
2362 for (int i = 0; i < N; i++) {
2363 removeProcessLocked(procs.get(i), false, true, "kill all background except");
2364 }
2365 }
2366
2367 /**
2368 * Call updateTimePrefs on all LRU processes
2369 * @param timePref The time pref to pass to each process
2370 */
2371 @GuardedBy("mService")
2372 void updateAllTimePrefsLocked(int timePref) {
2373 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2374 ProcessRecord r = mLruProcesses.get(i);
2375 if (r.thread != null) {
2376 try {
2377 r.thread.updateTimePrefs(timePref);
2378 } catch (RemoteException ex) {
2379 Slog.w(TAG, "Failed to update preferences for: "
2380 + r.info.processName);
2381 }
2382 }
2383 }
2384 }
2385
2386 @GuardedBy("mService")
2387 void setAllHttpProxyLocked(String host, String port, String exclList, Uri pacFileUrl) {
2388 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2389 ProcessRecord r = mLruProcesses.get(i);
2390 // Don't dispatch to isolated processes as they can't access
2391 // ConnectivityManager and don't have network privileges anyway.
2392 if (r.thread != null && !r.isolated) {
2393 try {
2394 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2395 } catch (RemoteException ex) {
2396 Slog.w(TAG, "Failed to update http proxy for: " +
2397 r.info.processName);
2398 }
2399 }
2400 }
2401 }
2402
2403 @GuardedBy("mService")
2404 void clearAllDnsCacheLocked() {
2405 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2406 ProcessRecord r = mLruProcesses.get(i);
2407 if (r.thread != null) {
2408 try {
2409 r.thread.clearDnsCache();
2410 } catch (RemoteException ex) {
2411 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2412 }
2413 }
2414 }
2415 }
2416
2417 @GuardedBy("mService")
2418 void handleAllTrustStorageUpdateLocked() {
2419 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2420 ProcessRecord r = mLruProcesses.get(i);
2421 if (r.thread != null) {
2422 try {
2423 r.thread.handleTrustStorageUpdate();
2424 } catch (RemoteException ex) {
2425 Slog.w(TAG, "Failed to handle trust storage update for: " +
2426 r.info.processName);
2427 }
2428 }
2429 }
2430 }
2431
2432 @GuardedBy("mService")
2433 int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
Dianne Hackborna631d562018-11-20 15:58:15 -08002434 int lruSeq, String what, Object obj, ProcessRecord srcApp) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002435 app.lastActivityTime = now;
2436
2437 if (app.hasActivitiesOrRecentTasks()) {
2438 // Don't want to touch dependent processes that are hosting activities.
2439 return index;
2440 }
2441
2442 int lrui = mLruProcesses.lastIndexOf(app);
2443 if (lrui < 0) {
2444 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2445 + what + " " + obj + " from " + srcApp);
2446 return index;
2447 }
2448
2449 if (lrui >= index) {
2450 // Don't want to cause this to move dependent processes *back* in the
2451 // list as if they were less frequently used.
2452 return index;
2453 }
2454
Dianne Hackborna631d562018-11-20 15:58:15 -08002455 if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002456 // Don't want to touch dependent processes that are hosting activities.
2457 return index;
2458 }
2459
2460 mLruProcesses.remove(lrui);
2461 if (index > 0) {
2462 index--;
2463 }
2464 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2465 + " in LRU list: " + app);
2466 mLruProcesses.add(index, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002467 app.lruSeq = lruSeq;
Amith Yamasani98a00922018-08-21 12:50:30 -04002468 return index;
2469 }
2470
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002471 /**
2472 * Handle the case where we are inserting a process hosting client activities:
2473 * Make sure any groups have their order match their importance, and take care of
2474 * distributing old clients across other activity processes so they can't spam
2475 * the LRU list. Processing of the list will be restricted by the indices provided,
2476 * and not extend out of them.
2477 *
2478 * @param topApp The app at the top that has just been inserted in to the list.
2479 * @param topI The position in the list where topApp was inserted; this is the start (at the
2480 * top) where we are going to do our processing.
2481 * @param bottomI The last position at which we will be processing; this is the end position
2482 * of whichever section of the LRU list we are in. Nothing past it will be
2483 * touched.
2484 * @param endIndex The current end of the top being processed. Typically topI - 1. That is,
2485 * where we are going to start potentially adjusting other entries in the list.
2486 */
2487 private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
2488 final int bottomI, int endIndex) {
2489 if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
2490 || !topApp.hasClientActivities()) {
2491 // If this is not a special process that has client activities, then there is
2492 // nothing to do.
2493 return;
2494 }
2495
2496 final int uid = topApp.info.uid;
2497 if (topApp.connectionGroup > 0) {
2498 int endImportance = topApp.connectionImportance;
2499 for (int i = endIndex; i >= bottomI; i--) {
2500 final ProcessRecord subProc = mLruProcesses.get(i);
2501 if (subProc.info.uid == uid
2502 && subProc.connectionGroup == topApp.connectionGroup) {
2503 if (i == endIndex && subProc.connectionImportance >= endImportance) {
2504 // This process is already in the group, and its importance
2505 // is not as strong as the process before it, so keep it
2506 // correctly positioned in the group.
2507 if (DEBUG_LRU) Slog.d(TAG_LRU,
2508 "Keeping in-place above " + subProc
2509 + " endImportance=" + endImportance
2510 + " group=" + subProc.connectionGroup
2511 + " importance=" + subProc.connectionImportance);
2512 endIndex--;
2513 endImportance = subProc.connectionImportance;
2514 } else {
2515 // We want to pull this up to be with the rest of the group,
2516 // and order within the group by importance.
2517 if (DEBUG_LRU) Slog.d(TAG_LRU,
2518 "Pulling up " + subProc
2519 + " to position in group with importance="
2520 + subProc.connectionImportance);
2521 boolean moved = false;
2522 for (int pos = topI; pos > endIndex; pos--) {
2523 final ProcessRecord posProc = mLruProcesses.get(pos);
2524 if (subProc.connectionImportance
2525 <= posProc.connectionImportance) {
2526 mLruProcesses.remove(i);
2527 mLruProcesses.add(pos, subProc);
2528 if (DEBUG_LRU) Slog.d(TAG_LRU,
2529 "Moving " + subProc
2530 + " from position " + i + " to above " + posProc
2531 + " @ " + pos);
2532 moved = true;
2533 endIndex--;
2534 break;
2535 }
2536 }
2537 if (!moved) {
2538 // Goes to the end of the group.
2539 mLruProcesses.remove(i);
2540 mLruProcesses.add(endIndex - 1, subProc);
2541 if (DEBUG_LRU) Slog.d(TAG_LRU,
2542 "Moving " + subProc
2543 + " from position " + i + " to end of group @ "
2544 + endIndex);
2545 endIndex--;
2546 endImportance = subProc.connectionImportance;
2547 }
2548 }
2549 }
2550 }
2551
2552 }
2553 // To keep it from spamming the LRU list (by making a bunch of clients),
2554 // we will distribute other entries owned by it to be in-between other apps.
2555 int i = endIndex;
2556 while (i >= bottomI) {
2557 ProcessRecord subProc = mLruProcesses.get(i);
2558 if (DEBUG_LRU) Slog.d(TAG_LRU,
2559 "Looking to spread old procs, at " + subProc + " @ " + i);
2560 if (subProc.info.uid != uid) {
2561 // This is a different app... if we have gone through some of the
2562 // target app, pull this up to be before them. We want to pull up
2563 // one activity process, but any number of non-activity processes.
2564 if (i < endIndex) {
2565 boolean hasActivity = false;
2566 int connUid = 0;
2567 int connGroup = 0;
2568 while (i >= bottomI) {
2569 mLruProcesses.remove(i);
2570 mLruProcesses.add(endIndex, subProc);
2571 if (DEBUG_LRU) Slog.d(TAG_LRU,
2572 "Different app, moving to " + endIndex);
2573 i--;
2574 if (i < bottomI) {
2575 break;
2576 }
2577 subProc = mLruProcesses.get(i);
2578 if (DEBUG_LRU) Slog.d(TAG_LRU,
2579 "Looking at next app at " + i + ": " + subProc);
2580 if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
2581 if (DEBUG_LRU) Slog.d(TAG_LRU,
2582 "This is hosting an activity!");
2583 if (hasActivity) {
2584 // Already found an activity, done.
2585 if (DEBUG_LRU) Slog.d(TAG_LRU,
2586 "Already found an activity, done");
2587 break;
2588 }
2589 hasActivity = true;
2590 } else if (subProc.hasClientActivities()) {
2591 if (DEBUG_LRU) Slog.d(TAG_LRU,
2592 "This is a client of an activity");
2593 if (hasActivity) {
2594 if (connUid == 0 || connUid != subProc.info.uid) {
2595 // Already have an activity that is not from from a client
2596 // connection or is a different client connection, done.
2597 if (DEBUG_LRU) Slog.d(TAG_LRU,
2598 "Already found a different activity: connUid="
2599 + connUid + " uid=" + subProc.info.uid);
2600 break;
2601 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
2602 // Previously saw a different group or not from a group,
2603 // want to treat these as different things.
2604 if (DEBUG_LRU) Slog.d(TAG_LRU,
2605 "Already found a different group: connGroup="
2606 + connGroup + " group=" + subProc.connectionGroup);
2607 break;
2608 }
2609 } else {
2610 if (DEBUG_LRU) Slog.d(TAG_LRU,
2611 "This is an activity client! uid="
2612 + subProc.info.uid + " group=" + subProc.connectionGroup);
2613 hasActivity = true;
2614 connUid = subProc.info.uid;
2615 connGroup = subProc.connectionGroup;
2616 }
2617 }
2618 endIndex--;
2619 }
2620 }
2621 // Find the end of the next group of processes for target app. This
2622 // is after any entries of different apps (so we don't change the existing
2623 // relative order of apps) and then after the next last group of processes
2624 // of the target app.
2625 for (endIndex--; endIndex >= bottomI; endIndex--) {
2626 final ProcessRecord endProc = mLruProcesses.get(endIndex);
2627 if (endProc.info.uid == uid) {
2628 if (DEBUG_LRU) Slog.d(TAG_LRU,
2629 "Found next group of app: " + endProc + " @ "
2630 + endIndex);
2631 break;
2632 }
2633 }
2634 if (endIndex >= bottomI) {
2635 final ProcessRecord endProc = mLruProcesses.get(endIndex);
2636 for (endIndex--; endIndex >= bottomI; endIndex--) {
2637 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
2638 if (nextEndProc.info.uid != uid
2639 || nextEndProc.connectionGroup != endProc.connectionGroup) {
2640 if (DEBUG_LRU) Slog.d(TAG_LRU,
2641 "Found next group or app: " + nextEndProc + " @ "
2642 + endIndex + " group=" + nextEndProc.connectionGroup);
2643 break;
2644 }
2645 }
2646 }
2647 if (DEBUG_LRU) Slog.d(TAG_LRU,
2648 "Bumping scan position to " + endIndex);
2649 i = endIndex;
2650 } else {
2651 i--;
2652 }
2653 }
2654 }
2655
Amith Yamasani98a00922018-08-21 12:50:30 -04002656 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2657 ProcessRecord client) {
2658 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
2659 || app.treatLikeActivity;
2660 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2661 if (!activityChange && hasActivity) {
2662 // The process has activities, so we are only allowing activity-based adjustments
2663 // to move it. It should be kept in the front of the list with other
2664 // processes that have activities, and we don't want those to change their
2665 // order except due to activity operations.
2666 return;
2667 }
2668
2669 mLruSeq++;
2670 final long now = SystemClock.uptimeMillis();
2671 app.lastActivityTime = now;
2672
2673 // First a quick reject: if the app is already at the position we will
2674 // put it, then there is nothing to do.
2675 if (hasActivity) {
2676 final int N = mLruProcesses.size();
2677 if (N > 0 && mLruProcesses.get(N - 1) == app) {
2678 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2679 return;
2680 }
2681 } else {
2682 if (mLruProcessServiceStart > 0
2683 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2684 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2685 return;
2686 }
2687 }
2688
2689 int lrui = mLruProcesses.lastIndexOf(app);
2690
2691 if (app.isPersistent() && lrui >= 0) {
2692 // We don't care about the position of persistent processes, as long as
2693 // they are in the list.
2694 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2695 return;
2696 }
2697
2698 /* In progress: compute new position first, so we can avoid doing work
2699 if the process is not actually going to move. Not yet working.
2700 int addIndex;
2701 int nextIndex;
2702 boolean inActivity = false, inService = false;
2703 if (hasActivity) {
2704 // Process has activities, put it at the very tipsy-top.
2705 addIndex = mLruProcesses.size();
2706 nextIndex = mLruProcessServiceStart;
2707 inActivity = true;
2708 } else if (hasService) {
2709 // Process has services, put it at the top of the service list.
2710 addIndex = mLruProcessActivityStart;
2711 nextIndex = mLruProcessServiceStart;
2712 inActivity = true;
2713 inService = true;
2714 } else {
2715 // Process not otherwise of interest, it goes to the top of the non-service area.
2716 addIndex = mLruProcessServiceStart;
2717 if (client != null) {
2718 int clientIndex = mLruProcesses.lastIndexOf(client);
2719 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2720 + app);
2721 if (clientIndex >= 0 && addIndex > clientIndex) {
2722 addIndex = clientIndex;
2723 }
2724 }
2725 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2726 }
2727
2728 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2729 + mLruProcessActivityStart + "): " + app);
2730 */
2731
2732 if (lrui >= 0) {
2733 if (lrui < mLruProcessActivityStart) {
2734 mLruProcessActivityStart--;
2735 }
2736 if (lrui < mLruProcessServiceStart) {
2737 mLruProcessServiceStart--;
2738 }
2739 /*
2740 if (addIndex > lrui) {
2741 addIndex--;
2742 }
2743 if (nextIndex > lrui) {
2744 nextIndex--;
2745 }
2746 */
2747 mLruProcesses.remove(lrui);
2748 }
2749
2750 /*
2751 mLruProcesses.add(addIndex, app);
2752 if (inActivity) {
2753 mLruProcessActivityStart++;
2754 }
2755 if (inService) {
2756 mLruProcessActivityStart++;
2757 }
2758 */
2759
2760 int nextIndex;
Dianne Hackborna631d562018-11-20 15:58:15 -08002761 int nextActivityIndex = -1;
Amith Yamasani98a00922018-08-21 12:50:30 -04002762 if (hasActivity) {
2763 final int N = mLruProcesses.size();
Dianne Hackborna631d562018-11-20 15:58:15 -08002764 nextIndex = mLruProcessServiceStart;
2765 if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
Amith Yamasani98a00922018-08-21 12:50:30 -04002766 && mLruProcessActivityStart < (N - 1)) {
2767 // Process doesn't have activities, but has clients with
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002768 // activities... move it up, but below the app that is binding to it.
Amith Yamasani98a00922018-08-21 12:50:30 -04002769 if (DEBUG_LRU) Slog.d(TAG_LRU,
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002770 "Adding to second-top of LRU activity list: " + app
2771 + " group=" + app.connectionGroup
2772 + " importance=" + app.connectionImportance);
2773 int pos = N - 1;
2774 while (pos > mLruProcessActivityStart) {
2775 final ProcessRecord posproc = mLruProcesses.get(pos);
2776 if (posproc.info.uid == app.info.uid) {
2777 // Technically this app could have multiple processes with different
2778 // activities and so we should be looking for the actual process that
2779 // is bound to the target proc... but I don't really care, do you?
2780 break;
2781 }
2782 pos--;
2783 }
2784 mLruProcesses.add(pos, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002785 // If this process is part of a group, need to pull up any other processes
2786 // in that group to be with it.
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002787 int endIndex = pos - 1;
2788 if (endIndex < mLruProcessActivityStart) {
2789 endIndex = mLruProcessActivityStart;
Dianne Hackborna631d562018-11-20 15:58:15 -08002790 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002791 nextActivityIndex = endIndex;
2792 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
Amith Yamasani98a00922018-08-21 12:50:30 -04002793 } else {
2794 // Process has activities, put it at the very tipsy-top.
2795 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2796 mLruProcesses.add(app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002797 nextActivityIndex = mLruProcesses.size() - 1;
Amith Yamasani98a00922018-08-21 12:50:30 -04002798 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002799 } else if (hasService) {
2800 // Process has services, put it at the top of the service list.
2801 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2802 mLruProcesses.add(mLruProcessActivityStart, app);
2803 nextIndex = mLruProcessServiceStart;
2804 mLruProcessActivityStart++;
2805 } else {
2806 // Process not otherwise of interest, it goes to the top of the non-service area.
2807 int index = mLruProcessServiceStart;
2808 if (client != null) {
2809 // If there is a client, don't allow the process to be moved up higher
2810 // in the list than that client.
2811 int clientIndex = mLruProcesses.lastIndexOf(client);
2812 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2813 + " when updating " + app);
2814 if (clientIndex <= lrui) {
2815 // Don't allow the client index restriction to push it down farther in the
2816 // list than it already is.
2817 clientIndex = lrui;
2818 }
2819 if (clientIndex >= 0 && index > clientIndex) {
2820 index = clientIndex;
2821 }
2822 }
2823 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2824 mLruProcesses.add(index, app);
2825 nextIndex = index - 1;
2826 mLruProcessActivityStart++;
2827 mLruProcessServiceStart++;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002828 if (index > 1) {
2829 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
2830 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002831 }
2832
Dianne Hackborna631d562018-11-20 15:58:15 -08002833 app.lruSeq = mLruSeq;
2834
Amith Yamasani98a00922018-08-21 12:50:30 -04002835 // If the app is currently using a content provider or service,
2836 // bump those processes as well.
2837 for (int j = app.connections.size() - 1; j >= 0; j--) {
2838 ConnectionRecord cr = app.connections.valueAt(j);
2839 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2840 && cr.binding.service.app != null
2841 && cr.binding.service.app.lruSeq != mLruSeq
Dianne Hackborna631d562018-11-20 15:58:15 -08002842 && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
Amith Yamasani98a00922018-08-21 12:50:30 -04002843 && !cr.binding.service.app.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08002844 if (cr.binding.service.app.hasClientActivities()) {
2845 if (nextActivityIndex >= 0) {
2846 nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2847 now,
2848 nextActivityIndex, mLruSeq,
2849 "service connection", cr, app);
2850 }
2851 } else {
2852 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2853 now,
2854 nextIndex, mLruSeq,
2855 "service connection", cr, app);
2856 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002857 }
2858 }
2859 for (int j = app.conProviders.size() - 1; j >= 0; j--) {
2860 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2861 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08002862 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
Amith Yamasani98a00922018-08-21 12:50:30 -04002863 "provider reference", cpr, app);
2864 }
2865 }
2866 }
2867
2868 final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
2869 final IBinder threadBinder = thread.asBinder();
2870 // Find the application record.
2871 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2872 final ProcessRecord rec = mLruProcesses.get(i);
2873 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2874 return rec;
2875 }
2876 }
2877 return null;
2878 }
2879
2880 boolean haveBackgroundProcessLocked() {
2881 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2882 final ProcessRecord rec = mLruProcesses.get(i);
2883 if (rec.thread != null
2884 && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
2885 return true;
2886 }
2887 }
2888 return false;
2889 }
2890
2891 private static int procStateToImportance(int procState, int memAdj,
2892 ActivityManager.RunningAppProcessInfo currApp,
2893 int clientTargetSdk) {
2894 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
2895 procState, clientTargetSdk);
2896 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
2897 currApp.lru = memAdj;
2898 } else {
2899 currApp.lru = 0;
2900 }
2901 return imp;
2902 }
2903
2904 @GuardedBy("mService")
2905 void fillInProcMemInfoLocked(ProcessRecord app,
2906 ActivityManager.RunningAppProcessInfo outInfo,
2907 int clientTargetSdk) {
2908 outInfo.pid = app.pid;
2909 outInfo.uid = app.info.uid;
2910 if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
2911 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
2912 }
2913 if (app.isPersistent()) {
2914 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
2915 }
2916 if (app.hasActivities()) {
2917 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
2918 }
2919 outInfo.lastTrimLevel = app.trimMemoryLevel;
2920 int adj = app.curAdj;
2921 int procState = app.getCurProcState();
2922 outInfo.importance = procStateToImportance(procState, adj, outInfo,
2923 clientTargetSdk);
2924 outInfo.importanceReasonCode = app.adjTypeCode;
2925 outInfo.processState = app.getCurProcState();
2926 outInfo.isFocused = (app == mService.getTopAppLocked());
2927 outInfo.lastActivityTime = app.lastActivityTime;
2928 }
2929
2930 @GuardedBy("mService")
2931 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
2932 int userId, boolean allUids, int callingUid, int clientTargetSdk) {
2933 // Lazy instantiation of list
2934 List<ActivityManager.RunningAppProcessInfo> runList = null;
2935
2936 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2937 ProcessRecord app = mLruProcesses.get(i);
2938 if ((!allUsers && app.userId != userId)
2939 || (!allUids && app.uid != callingUid)) {
2940 continue;
2941 }
2942 if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
2943 // Generate process state info for running application
2944 ActivityManager.RunningAppProcessInfo currApp =
2945 new ActivityManager.RunningAppProcessInfo(app.processName,
2946 app.pid, app.getPackageList());
2947 fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
2948 if (app.adjSource instanceof ProcessRecord) {
2949 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
2950 currApp.importanceReasonImportance =
2951 ActivityManager.RunningAppProcessInfo.procStateToImportance(
2952 app.adjSourceProcState);
Wale Ogunwale59507092018-10-29 09:00:30 -07002953 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
2954 final ActivityServiceConnectionsHolder r =
2955 (ActivityServiceConnectionsHolder) app.adjSource;
2956 final int pid = r.getActivityPid();
2957 if (pid != -1) {
2958 currApp.importanceReasonPid = pid;
2959 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002960 }
2961 if (app.adjTarget instanceof ComponentName) {
2962 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
2963 }
2964 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
2965 // + " lru=" + currApp.lru);
2966 if (runList == null) {
2967 runList = new ArrayList<>();
2968 }
2969 runList.add(currApp);
2970 }
2971 }
2972 return runList;
2973 }
2974
2975 @GuardedBy("mService")
2976 int getLruSizeLocked() {
2977 return mLruProcesses.size();
2978 }
2979
2980 @GuardedBy("mService")
2981 void dumpLruListHeaderLocked(PrintWriter pw) {
2982 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
2983 pw.print(" total, non-act at ");
2984 pw.print(mLruProcesses.size() - mLruProcessActivityStart);
2985 pw.print(", non-svc at ");
2986 pw.print(mLruProcesses.size() - mLruProcessServiceStart);
2987 pw.println("):");
2988 }
2989
2990 @GuardedBy("mService")
2991 ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
2992 ArrayList<ProcessRecord> procs;
2993 if (args != null && args.length > start
2994 && args[start].charAt(0) != '-') {
2995 procs = new ArrayList<ProcessRecord>();
2996 int pid = -1;
2997 try {
2998 pid = Integer.parseInt(args[start]);
2999 } catch (NumberFormatException e) {
3000 }
3001 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3002 ProcessRecord proc = mLruProcesses.get(i);
3003 if (proc.pid > 0 && proc.pid == pid) {
3004 procs.add(proc);
3005 } else if (allPkgs && proc.pkgList != null
3006 && proc.pkgList.containsKey(args[start])) {
3007 procs.add(proc);
3008 } else if (proc.processName.equals(args[start])) {
3009 procs.add(proc);
3010 }
3011 }
3012 if (procs.size() <= 0) {
3013 return null;
3014 }
3015 } else {
3016 procs = new ArrayList<ProcessRecord>(mLruProcesses);
3017 }
3018 return procs;
3019 }
3020
3021 @GuardedBy("mService")
3022 void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3023 boolean updateFrameworkRes) {
3024 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3025 final ProcessRecord app = mLruProcesses.get(i);
3026 if (app.thread == null) {
3027 continue;
3028 }
3029
3030 if (userId != UserHandle.USER_ALL && app.userId != userId) {
3031 continue;
3032 }
3033
3034 final int packageCount = app.pkgList.size();
3035 for (int j = 0; j < packageCount; j++) {
3036 final String packageName = app.pkgList.keyAt(j);
3037 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
3038 try {
3039 final ApplicationInfo ai = AppGlobals.getPackageManager()
3040 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3041 if (ai != null) {
3042 app.thread.scheduleApplicationInfoChanged(ai);
3043 }
3044 } catch (RemoteException e) {
3045 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3046 packageName, app));
3047 }
3048 }
3049 }
3050 }
3051 }
3052
3053 @GuardedBy("mService")
3054 void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
3055 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3056 ProcessRecord r = mLruProcesses.get(i);
3057 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3058 try {
3059 r.thread.dispatchPackageBroadcast(cmd, packages);
3060 } catch (RemoteException ex) {
3061 }
3062 }
3063 }
3064 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08003065
3066 /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3067 @GuardedBy("mService")
3068 int getUidProcStateLocked(int uid) {
3069 UidRecord uidRec = mActiveUids.get(uid);
3070 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3071 }
3072
3073 /** Returns the UidRecord for the given uid, if it exists. */
3074 @GuardedBy("mService")
3075 UidRecord getUidRecordLocked(int uid) {
3076 return mActiveUids.get(uid);
3077 }
3078
3079 /**
3080 * Call {@link ActivityManagerService#doStopUidLocked}
3081 * (which will also stop background services) for all idle UIDs.
3082 */
3083 @GuardedBy("mService")
3084 void doStopUidForIdleUidsLocked() {
3085 final int size = mActiveUids.size();
3086 for (int i = 0; i < size; i++) {
3087 final int uid = mActiveUids.keyAt(i);
3088 if (UserHandle.isCore(uid)) {
3089 continue;
3090 }
3091 final UidRecord uidRec = mActiveUids.valueAt(i);
3092 if (!uidRec.idle) {
3093 continue;
3094 }
3095 mService.doStopUidLocked(uidRec.uid, uidRec);
3096 }
3097 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07003098}