blob: d02fd7387f598e0e56e6bdd6f9d7e4f98603ffa4 [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;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010061import android.os.AppZygote;
Amith Yamasani98a00922018-08-21 12:50:30 -040062import android.os.Binder;
Dianne Hackborn9d52f792014-09-11 17:46:06 -070063import android.os.Build;
Amith Yamasani98a00922018-08-21 12:50:30 -040064import android.os.Bundle;
Amith Yamasani98a00922018-08-21 12:50:30 -040065import android.os.Handler;
66import android.os.IBinder;
67import android.os.Looper;
68import android.os.Message;
69import android.os.Process;
70import android.os.RemoteException;
71import android.os.StrictMode;
Dianne Hackbornecf1cda2014-08-28 16:58:28 -070072import android.os.SystemClock;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070073import android.os.SystemProperties;
74import android.os.Trace;
75import android.os.UserHandle;
Jeff Sharkey10ec9d82018-11-28 14:52:45 -070076import android.os.storage.StorageManager;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070077import android.os.storage.StorageManagerInternal;
78import android.text.TextUtils;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010079import android.util.ArrayMap;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070080import android.util.EventLog;
81import android.util.LongSparseArray;
82import android.util.Slog;
83import android.util.SparseArray;
Martijn Coenen01e719b2018-12-05 16:01:38 +010084import android.util.SparseBooleanArray;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070085import android.util.StatsLog;
86import android.view.Display;
Amith Yamasani98a00922018-08-21 12:50:30 -040087
88import com.android.internal.annotations.GuardedBy;
89import com.android.internal.annotations.VisibleForTesting;
90import com.android.internal.app.ProcessMap;
91import com.android.internal.app.procstats.ProcessStats;
92import com.android.internal.os.Zygote;
93import com.android.internal.util.ArrayUtils;
Dianne Hackborn7d608422011-08-07 16:24:18 -070094import com.android.internal.util.MemInfoReader;
Amith Yamasani98a00922018-08-21 12:50:30 -040095import com.android.server.LocalServices;
96import com.android.server.ServiceThread;
97import com.android.server.Watchdog;
98import com.android.server.pm.dex.DexManager;
Wale Ogunwale59507092018-10-29 09:00:30 -070099import com.android.server.wm.ActivityServiceConnectionsHolder;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700100import com.android.server.wm.WindowManagerService;
101
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700102import dalvik.system.VMRuntime;
103
Sudheer Shanka87915d62018-11-06 10:57:35 -0800104import libcore.io.IoUtils;
105
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700106import java.io.File;
107import java.io.IOException;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700108import java.io.InputStream;
Sudheer Shanka87915d62018-11-06 10:57:35 -0800109import java.io.OutputStream;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700110import java.io.PrintWriter;
111import java.nio.ByteBuffer;
112import java.util.ArrayList;
113import java.util.Arrays;
Martijn Coenen01e719b2018-12-05 16:01:38 +0100114import java.util.BitSet;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700115import java.util.List;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700116
117/**
118 * Activity manager code dealing with processes.
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700119 *
120 * Method naming convention:
121 * <ul>
122 * <li> Methods suffixed with "LS" should be called within the {@link #sLmkdSocketLock} lock.
123 * </ul>
Dianne Hackborn7d608422011-08-07 16:24:18 -0700124 */
Sudheer Shanka352dc572017-09-22 17:09:38 -0700125public final class ProcessList {
Amith Yamasaniaa746442019-01-10 10:09:12 -0800126 static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800127
Dianne Hackborn7d608422011-08-07 16:24:18 -0700128 // The minimum time we allow between crashes, for us to consider this
129 // application to be bad and stop and its services and reject broadcasts.
Amith Yamasani98a00922018-08-21 12:50:30 -0400130 static final int MIN_CRASH_INTERVAL = 60 * 1000;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700131
132 // OOM adjustments for processes in various states:
133
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700134 // Uninitialized value for any major or minor adj fields
135 static final int INVALID_ADJ = -10000;
136
Dianne Hackbornc8230512013-07-13 21:32:12 -0700137 // Adjustment used in certain places where we don't know it yet.
138 // (Generally this is something that is going to be cached, but we
139 // don't know the exact value in the cached range to assign yet.)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700140 static final int UNKNOWN_ADJ = 1001;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700141
Dianne Hackborn7d608422011-08-07 16:24:18 -0700142 // This is a process only hosting activities that are not visible,
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700143 // so it can be killed without any disruption.
Dianne Hackbornb446ce52018-12-10 16:44:35 -0800144 static final int CACHED_APP_MAX_ADJ = 999;
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700145 static final int CACHED_APP_MIN_ADJ = 900;
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700146
Tim Murray0d42abe2019-01-23 09:54:15 -0800147 // This is the oom_adj level that we allow to die first. This cannot be equal to
148 // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
149 // CACHED_APP_MAX_ADJ.
150 static final int CACHED_APP_LMK_FIRST_ADJ = 950;
151
Dianne Hackbornb446ce52018-12-10 16:44:35 -0800152 // Number of levels we have available for different service connection group importance
153 // levels.
154 static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
155
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700156 // The B list of SERVICE_ADJ -- these are the old and decrepit
157 // services that aren't as shiny and interesting as the ones in the A list.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700158 static final int SERVICE_B_ADJ = 800;
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700159
160 // This is the process of the previous application that the user was in.
161 // This process is kept above other things, because it is very common to
162 // switch back to the previous app. This is important both for recent
163 // task switch (toggling between the two top recent apps) as well as normal
164 // UI flow such as clicking on a URI in the e-mail app to view in the browser,
165 // and then pressing back to return to e-mail.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700166 static final int PREVIOUS_APP_ADJ = 700;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700167
168 // This is a process holding the home application -- we want to try
169 // avoiding killing it, even if it would normally be in the background,
170 // because the user interacts with it so much.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700171 static final int HOME_APP_ADJ = 600;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700172
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700173 // This is a process holding an application service -- killing it will not
174 // have much of an impact as far as the user is concerned.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700175 static final int SERVICE_ADJ = 500;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700176
Dianne Hackborn7d608422011-08-07 16:24:18 -0700177 // This is a process with a heavy-weight application. It is in the
178 // background, but we want to try to avoid killing it. Value set in
179 // system/rootdir/init.rc on startup.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700180 static final int HEAVY_WEIGHT_APP_ADJ = 400;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700181
182 // This is a process currently hosting a backup operation. Killing it
183 // is not entirely fatal but is generally a bad idea.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700184 static final int BACKUP_APP_ADJ = 300;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700185
Amith Yamasani0567ec62019-01-23 11:11:02 -0800186 // This is a process bound by the system that's more important than services but not so
187 // perceptible that it affects the user immediately if killed.
188 static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
189
Dianne Hackborn7d608422011-08-07 16:24:18 -0700190 // This is a process only hosting components that are perceptible to the
191 // user, and we really want to avoid killing them, but they are not
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700192 // immediately visible. An example is background music playback.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700193 static final int PERCEPTIBLE_APP_ADJ = 200;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700194
195 // This is a process only hosting activities that are visible to the
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700196 // user, so we'd prefer they don't disappear.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700197 static final int VISIBLE_APP_ADJ = 100;
198 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700199
Amith Yamasanib7358302018-09-05 18:52:35 -0700200 // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
201 // like a foreground app for a while.
202 // @see TOP_TO_FGS_GRACE_PERIOD
203 static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
204
Dianne Hackborn7d608422011-08-07 16:24:18 -0700205 // This is the process running the current foreground app. We'd really
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700206 // rather not kill it!
Dianne Hackborn7d608422011-08-07 16:24:18 -0700207 static final int FOREGROUND_APP_ADJ = 0;
208
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700209 // This is a process that the system or a persistent process has bound to,
210 // and indicated it is important.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700211 static final int PERSISTENT_SERVICE_ADJ = -700;
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700212
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700213 // This is a system persistent process, such as telephony. Definitely
Dianne Hackborn7d608422011-08-07 16:24:18 -0700214 // don't want to kill it, but doing so is not completely fatal.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700215 static final int PERSISTENT_PROC_ADJ = -800;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700216
217 // The system process runs at the default adjustment.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700218 static final int SYSTEM_ADJ = -900;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700219
Dianne Hackborn8e692572013-09-10 19:06:15 -0700220 // Special code for native processes that are not being managed by the system (so
221 // don't have an oom adj assigned by the system).
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700222 static final int NATIVE_ADJ = -1000;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700223
Dianne Hackborn7d608422011-08-07 16:24:18 -0700224 // Memory pages are 4K.
Amith Yamasani98a00922018-08-21 12:50:30 -0400225 static final int PAGE_SIZE = 4 * 1024;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700226
Dianne Hackborna49ad092016-03-03 13:39:10 -0800227 // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
228 static final int SCHED_GROUP_BACKGROUND = 0;
Tim Murrayfef10a42018-04-13 10:15:17 -0700229 // Activity manager's version of Process.THREAD_GROUP_RESTRICTED
230 static final int SCHED_GROUP_RESTRICTED = 1;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800231 // Activity manager's version of Process.THREAD_GROUP_DEFAULT
Tim Murrayfef10a42018-04-13 10:15:17 -0700232 static final int SCHED_GROUP_DEFAULT = 2;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800233 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
Wale Ogunwale59507092018-10-29 09:00:30 -0700234 public static final int SCHED_GROUP_TOP_APP = 3;
Tim Murray33eb07f2016-06-10 10:03:20 -0700235 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
236 // Disambiguate between actual top app and processes bound to the top app
Tim Murrayfef10a42018-04-13 10:15:17 -0700237 static final int SCHED_GROUP_TOP_APP_BOUND = 4;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800238
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700239 // The minimum number of cached apps we want to be able to keep around,
Dianne Hackborn7d608422011-08-07 16:24:18 -0700240 // without empty apps being able to push them out of memory.
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700241 static final int MIN_CACHED_APPS = 2;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700242
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700243 // We allow empty processes to stick around for at most 30 minutes.
Amith Yamasani98a00922018-08-21 12:50:30 -0400244 static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700245
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_CRITICAL_THRESHOLD = 3;
248
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700249 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700250 static final int TRIM_LOW_THRESHOLD = 5;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700251
Mathieu Chartier77bd1232019-03-05 13:53:11 -0800252 // If true, then we pass the flag to ART to load the app image startup cache.
253 private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
254 "persist.device_config.runtime_native.use_app_image_startup_cache";
255
Todd Poynorbfdd6232013-07-10 19:15:07 -0700256 // Low Memory Killer Daemon command codes.
257 // These must be kept in sync with the definitions in lmkd.c
258 //
259 // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700260 // LMK_PROCPRIO <pid> <uid> <prio>
Todd Poynorbfdd6232013-07-10 19:15:07 -0700261 // LMK_PROCREMOVE <pid>
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -0700262 // LMK_PROCPURGE
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700263 // LMK_GETKILLCNT
Todd Poynorbfdd6232013-07-10 19:15:07 -0700264 static final byte LMK_TARGET = 0;
265 static final byte LMK_PROCPRIO = 1;
266 static final byte LMK_PROCREMOVE = 2;
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -0700267 static final byte LMK_PROCPURGE = 3;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700268 static final byte LMK_GETKILLCNT = 4;
Todd Poynorbfdd6232013-07-10 19:15:07 -0700269
Amith Yamasani98a00922018-08-21 12:50:30 -0400270 ActivityManagerService mService = null;
271
272 // To kill process groups asynchronously
273 static KillHandler sKillHandler = null;
274 static ServiceThread sKillThread = null;
275
Dianne Hackborn7d608422011-08-07 16:24:18 -0700276 // These are the various interesting memory levels that we will give to
277 // the OOM killer. Note that the OOM killer only supports 6 slots, so we
278 // can't give it a different value for every possible kind of process.
279 private final int[] mOomAdj = new int[] {
280 FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
Tim Murray0d42abe2019-01-23 09:54:15 -0800281 BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
Dianne Hackborn7d608422011-08-07 16:24:18 -0700282 };
283 // These are the low-end OOM level limits. This is appropriate for an
284 // HVGA or smaller phone with less than 512MB. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700285 private final int[] mOomMinFreeLow = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700286 12288, 18432, 24576,
287 36864, 43008, 49152
Dianne Hackborn7d608422011-08-07 16:24:18 -0700288 };
289 // These are the high-end OOM level limits. This is appropriate for a
290 // 1280x800 or larger screen with around 1GB RAM. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700291 private final int[] mOomMinFreeHigh = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700292 73728, 92160, 110592,
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800293 129024, 147456, 184320
Dianne Hackborn7d608422011-08-07 16:24:18 -0700294 };
295 // The actual OOM killer memory levels we are using.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700296 private final int[] mOomMinFree = new int[mOomAdj.length];
Dianne Hackborn7d608422011-08-07 16:24:18 -0700297
298 private final long mTotalMemMb;
299
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700300 private long mCachedRestoreLevel;
301
Dianne Hackborn7d608422011-08-07 16:24:18 -0700302 private boolean mHaveDisplaySize;
303
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700304 private static Object sLmkdSocketLock = new Object();
305
306 @GuardedBy("sLmkdSocketLock")
Todd Poynorbfdd6232013-07-10 19:15:07 -0700307 private static LocalSocket sLmkdSocket;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700308
309 @GuardedBy("sLmkdSocketLock")
Todd Poynorbfdd6232013-07-10 19:15:07 -0700310 private static OutputStream sLmkdOutputStream;
311
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700312 @GuardedBy("sLmkdSocketLock")
313 private static InputStream sLmkdInputStream;
314
Amith Yamasani98a00922018-08-21 12:50:30 -0400315 /**
316 * Temporary to avoid allocations. Protected by main lock.
317 */
318 @GuardedBy("mService")
319 final StringBuilder mStringBuilder = new StringBuilder(256);
320
321 /**
322 * A global counter for generating sequence numbers.
323 * This value will be used when incrementing sequence numbers in individual uidRecords.
324 *
325 * Having a global counter ensures that seq numbers are monotonically increasing for a
326 * particular uid even when the uidRecord is re-created.
327 */
328 @GuardedBy("mService")
329 @VisibleForTesting
330 long mProcStateSeqCounter = 0;
331
332 /**
333 * A global counter for generating sequence numbers to uniquely identify pending process starts.
334 */
335 @GuardedBy("mService")
336 private long mProcStartSeqCounter = 0;
337
338 /**
339 * Contains {@link ProcessRecord} objects for pending process starts.
340 *
341 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
342 */
343 @GuardedBy("mService")
344 final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
345
346 /**
347 * List of running applications, sorted by recent usage.
348 * The first entry in the list is the least recently used.
349 */
350 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
351
352 /**
353 * Where in mLruProcesses that the processes hosting activities start.
354 */
355 int mLruProcessActivityStart = 0;
356
357 /**
358 * Where in mLruProcesses that the processes hosting services start.
359 * This is after (lower index) than mLruProcessesActivityStart.
360 */
361 int mLruProcessServiceStart = 0;
362
363 /**
364 * Current sequence id for process LRU updating.
365 */
366 int mLruSeq = 0;
367
Amith Yamasaniaa746442019-01-10 10:09:12 -0800368 ActiveUids mActiveUids;
369
Amith Yamasani98a00922018-08-21 12:50:30 -0400370 /**
371 * The currently running isolated processes.
372 */
373 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
374
375 /**
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100376 * The currently running application zygotes.
377 */
378 final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
379
380 /**
381 * The processes that are forked off an application zygote.
382 */
383 final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses =
384 new ArrayMap<AppZygote, ArrayList<ProcessRecord>>();
385
Martijn Coenen01e719b2018-12-05 16:01:38 +0100386 final class IsolatedUidRange {
387 @VisibleForTesting
388 public final int mFirstUid;
389 @VisibleForTesting
390 public final int mLastUid;
391
392 @GuardedBy("ProcessList.this.mService")
393 private final SparseBooleanArray mUidUsed = new SparseBooleanArray();
394
395 @GuardedBy("ProcessList.this.mService")
396 private int mNextUid;
397
398 IsolatedUidRange(int firstUid, int lastUid) {
399 mFirstUid = firstUid;
400 mLastUid = lastUid;
401 mNextUid = firstUid;
402 }
403
404 @GuardedBy("ProcessList.this.mService")
405 int allocateIsolatedUidLocked(int userId) {
406 int uid;
407 int stepsLeft = (mLastUid - mFirstUid + 1);
408 for (int i = 0; i < stepsLeft; ++i) {
409 if (mNextUid < mFirstUid || mNextUid > mLastUid) {
410 mNextUid = mFirstUid;
411 }
412 uid = UserHandle.getUid(userId, mNextUid);
413 mNextUid++;
414 if (!mUidUsed.get(uid, false)) {
415 mUidUsed.put(uid, true);
416 return uid;
417 }
418 }
419 return -1;
420 }
421
422 @GuardedBy("ProcessList.this.mService")
423 void freeIsolatedUidLocked(int uid) {
424 // Strip out userId
425 final int appId = UserHandle.getAppId(uid);
426 mUidUsed.delete(appId);
427 }
428 };
429
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100430 /**
Martijn Coenen01e719b2018-12-05 16:01:38 +0100431 * A class that allocates ranges of isolated UIDs per application, and keeps track of them.
Amith Yamasani98a00922018-08-21 12:50:30 -0400432 */
Martijn Coenen01e719b2018-12-05 16:01:38 +0100433 final class IsolatedUidRangeAllocator {
434 private final int mFirstUid;
435 private final int mNumUidRanges;
436 private final int mNumUidsPerRange;
437 /**
438 * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange)
439 * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that.
440 */
441 @GuardedBy("ProcessList.this.mService")
442 private final BitSet mAvailableUidRanges;
443 @GuardedBy("ProcessList.this.mService")
444 private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>();
445
446 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) {
447 mFirstUid = firstUid;
448 mNumUidsPerRange = numUidsPerRange;
449 mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange;
450 mAvailableUidRanges = new BitSet(mNumUidRanges);
451 // Mark all as available
452 mAvailableUidRanges.set(0, mNumUidRanges);
453 }
454
455 @GuardedBy("ProcessList.this.mService")
456 IsolatedUidRange getIsolatedUidRangeLocked(ApplicationInfo info) {
457 return mAppRanges.get(info.processName, info.uid);
458 }
459
460 @GuardedBy("ProcessList.this.mService")
461 IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info) {
462 IsolatedUidRange range = getIsolatedUidRangeLocked(info);
463 if (range == null) {
464 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
465 if (uidRangeIndex < 0) {
466 // No free range
467 return null;
468 }
469 mAvailableUidRanges.clear(uidRangeIndex);
470 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
471 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
472 mAppRanges.put(info.processName, info.uid, range);
473 }
474 return range;
475 }
476
477 @GuardedBy("ProcessList.this.mService")
478 void freeUidRangeLocked(ApplicationInfo info) {
479 // Find the UID range
480 IsolatedUidRange range = mAppRanges.get(info.processName, info.uid);
481 if (range != null) {
482 // Map back to starting uid
483 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange;
484 // Mark it as available in the underlying bitset
485 mAvailableUidRanges.set(uidRangeIndex);
486 // And the map
487 mAppRanges.remove(info.processName, info.uid);
488 }
489 }
490 }
491
492 /**
493 * The available isolated UIDs for processes that are not spawned from an application zygote.
494 */
495 @VisibleForTesting
496 IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID,
497 Process.LAST_ISOLATED_UID);
498
499 /**
500 * An allocator for isolated UID ranges for apps that use an application zygote.
501 */
502 @VisibleForTesting
503 IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator =
504 new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
505 Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE);
Amith Yamasani98a00922018-08-21 12:50:30 -0400506
507 /**
508 * Processes that are being forcibly torn down.
509 */
510 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
511
512 /**
513 * All of the applications we currently have running organized by name.
514 * The keys are strings of the application package name (as
515 * returned by the package manager), and the keys are ApplicationRecord
516 * objects.
517 */
518 final MyProcessMap mProcessNames = new MyProcessMap();
519
520 final class MyProcessMap extends ProcessMap<ProcessRecord> {
521 @Override
522 public ProcessRecord put(String name, int uid, ProcessRecord value) {
523 final ProcessRecord r = super.put(name, uid, value);
524 mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());
525 return r;
526 }
527
528 @Override
529 public ProcessRecord remove(String name, int uid) {
530 final ProcessRecord r = super.remove(name, uid);
531 mService.mAtmInternal.onProcessRemoved(name, uid);
532 return r;
533 }
534 }
535
536 final class KillHandler extends Handler {
537 static final int KILL_PROCESS_GROUP_MSG = 4000;
538
539 public KillHandler(Looper looper) {
540 super(looper, null, true);
541 }
542
543 @Override
544 public void handleMessage(Message msg) {
545 switch (msg.what) {
546 case KILL_PROCESS_GROUP_MSG:
547 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
548 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
549 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
550 break;
551
552 default:
553 super.handleMessage(msg);
554 }
555 }
556 }
557
558 //////////////////// END FIELDS ////////////////////
559
Dianne Hackborn7d608422011-08-07 16:24:18 -0700560 ProcessList() {
561 MemInfoReader minfo = new MemInfoReader();
562 minfo.readMemInfo();
563 mTotalMemMb = minfo.getTotalSize()/(1024*1024);
564 updateOomLevels(0, 0, false);
565 }
566
Amith Yamasaniaa746442019-01-10 10:09:12 -0800567 void init(ActivityManagerService service, ActiveUids activeUids) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400568 mService = service;
Amith Yamasaniaa746442019-01-10 10:09:12 -0800569 mActiveUids = activeUids;
570
Amith Yamasani98a00922018-08-21 12:50:30 -0400571 if (sKillHandler == null) {
572 sKillThread = new ServiceThread(TAG + ":kill",
573 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
574 sKillThread.start();
575 sKillHandler = new KillHandler(sKillThread.getLooper());
576 }
577 }
578
Dianne Hackborn7d608422011-08-07 16:24:18 -0700579 void applyDisplaySize(WindowManagerService wm) {
580 if (!mHaveDisplaySize) {
581 Point p = new Point();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700582 // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
Colin Cross637dbfc2013-07-18 17:15:15 -0700583 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700584 if (p.x != 0 && p.y != 0) {
585 updateOomLevels(p.x, p.y, true);
586 mHaveDisplaySize = true;
587 }
588 }
589 }
590
591 private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
592 // Scale buckets from avail memory: at 300MB we use the lowest values to
593 // 700MB or more for the top values.
Amith Yamasani98a00922018-08-21 12:50:30 -0400594 float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700595
596 // Scale buckets from screen size.
Amith Yamasani98a00922018-08-21 12:50:30 -0400597 int minSize = 480 * 800; // 384000
598 int maxSize = 1280 * 800; // 1024000 230400 870400 .264
599 float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700600 if (false) {
601 Slog.i("XXXXXX", "scaleMem=" + scaleMem);
602 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
603 + " dh=" + displayHeight);
604 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700605
Dianne Hackborn7d608422011-08-07 16:24:18 -0700606 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
607 if (scale < 0) scale = 0;
608 else if (scale > 1) scale = 1;
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700609 int minfree_adj = Resources.getSystem().getInteger(
610 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
611 int minfree_abs = Resources.getSystem().getInteger(
612 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
613 if (false) {
614 Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
615 }
Colin Crossfcdad6f2013-07-25 15:04:40 -0700616
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800617 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700618
Amith Yamasani98a00922018-08-21 12:50:30 -0400619 for (int i = 0; i < mOomAdj.length; i++) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700620 int low = mOomMinFreeLow[i];
621 int high = mOomMinFreeHigh[i];
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800622 if (is64bit) {
623 // Increase the high min-free levels for cached processes for 64-bit
Amith Yamasani98a00922018-08-21 12:50:30 -0400624 if (i == 4) high = (high * 3) / 2;
625 else if (i == 5) high = (high * 7) / 4;
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800626 }
Amith Yamasani98a00922018-08-21 12:50:30 -0400627 mOomMinFree[i] = (int)(low + ((high - low) * scale));
Colin Crossfcdad6f2013-07-25 15:04:40 -0700628 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700629
Colin Crossfcdad6f2013-07-25 15:04:40 -0700630 if (minfree_abs >= 0) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400631 for (int i = 0; i < mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700632 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
633 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700634 }
635 }
636
637 if (minfree_adj != 0) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400638 for (int i = 0; i < mOomAdj.length; i++) {
639 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700640 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700641 if (mOomMinFree[i] < 0) {
642 mOomMinFree[i] = 0;
643 }
644 }
645 }
646
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700647 // The maximum size we will restore a process from cached to background, when under
648 // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
649 // before killing background processes.
Amith Yamasani98a00922018-08-21 12:50:30 -0400650 mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700651
Colin Cross59d80a52013-07-25 10:45:05 -0700652 // Ask the kernel to try to keep enough memory free to allocate 3 full
653 // screen 32bpp buffers without entering direct reclaim.
654 int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
Amith Yamasani98a00922018-08-21 12:50:30 -0400655 int reserve_adj = Resources.getSystem().getInteger(
656 com.android.internal.R.integer.config_extraFreeKbytesAdjust);
657 int reserve_abs = Resources.getSystem().getInteger(
658 com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
Colin Cross59d80a52013-07-25 10:45:05 -0700659
660 if (reserve_abs >= 0) {
661 reserve = reserve_abs;
662 }
663
664 if (reserve_adj != 0) {
665 reserve += reserve_adj;
666 if (reserve < 0) {
667 reserve = 0;
668 }
669 }
670
Dianne Hackborn7d608422011-08-07 16:24:18 -0700671 if (write) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400672 ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
Todd Poynorbfdd6232013-07-10 19:15:07 -0700673 buf.putInt(LMK_TARGET);
Amith Yamasani98a00922018-08-21 12:50:30 -0400674 for (int i = 0; i < mOomAdj.length; i++) {
675 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700676 buf.putInt(mOomAdj[i]);
677 }
678
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700679 writeLmkd(buf, null);
Colin Cross59d80a52013-07-25 10:45:05 -0700680 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
Dianne Hackborn7d608422011-08-07 16:24:18 -0700681 }
682 // GB: 2048,3072,4096,6144,7168,8192
683 // HC: 8192,10240,12288,14336,16384,20480
684 }
685
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700686 public static int computeEmptyProcessLimit(int totalProcessLimit) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700687 return totalProcessLimit/2;
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700688 }
689
Dianne Hackborn311473c2019-02-04 15:34:51 -0800690 private static String buildOomTag(String prefix, String compactPrefix, String space, int val,
691 int base, boolean compact) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800692 final int diff = val - base;
693 if (diff == 0) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800694 if (compact) {
695 return compactPrefix;
696 }
Dianne Hackborn8e692572013-09-10 19:06:15 -0700697 if (space == null) return prefix;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800698 return prefix + space;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700699 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800700 if (diff < 10) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800701 return prefix + (compact ? "+" : "+ ") + Integer.toString(diff);
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800702 }
703 return prefix + "+" + Integer.toString(diff);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700704 }
705
Dianne Hackborn311473c2019-02-04 15:34:51 -0800706 public static String makeOomAdjString(int setAdj, boolean compact) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700707 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800708 return buildOomTag("cch", "cch", " ", setAdj,
709 ProcessList.CACHED_APP_MIN_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700710 } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800711 return buildOomTag("svcb ", "svcb", null, setAdj,
712 ProcessList.SERVICE_B_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700713 } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800714 return buildOomTag("prev ", "prev", null, setAdj,
715 ProcessList.PREVIOUS_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700716 } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800717 return buildOomTag("home ", "home", null, setAdj,
718 ProcessList.HOME_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700719 } else if (setAdj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800720 return buildOomTag("svc ", "svc", null, setAdj,
721 ProcessList.SERVICE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700722 } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800723 return buildOomTag("hvy ", "hvy", null, setAdj,
724 ProcessList.HEAVY_WEIGHT_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700725 } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800726 return buildOomTag("bkup ", "bkup", null, setAdj,
727 ProcessList.BACKUP_APP_ADJ, compact);
Amith Yamasani0567ec62019-01-23 11:11:02 -0800728 } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
729 return buildOomTag("prcl ", "prcl", null, setAdj,
730 ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700731 } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800732 return buildOomTag("prcp ", "prcp", null, setAdj,
733 ProcessList.PERCEPTIBLE_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700734 } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800735 return buildOomTag("vis", "vis", " ", setAdj,
736 ProcessList.VISIBLE_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700737 } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800738 return buildOomTag("fore ", "fore", null, setAdj,
739 ProcessList.FOREGROUND_APP_ADJ, compact);
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700740 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800741 return buildOomTag("psvc ", "psvc", null, setAdj,
742 ProcessList.PERSISTENT_SERVICE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700743 } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800744 return buildOomTag("pers ", "pers", null, setAdj,
745 ProcessList.PERSISTENT_PROC_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700746 } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800747 return buildOomTag("sys ", "sys", null, setAdj,
748 ProcessList.SYSTEM_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700749 } else if (setAdj >= ProcessList.NATIVE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800750 return buildOomTag("ntv ", "ntv", null, setAdj,
751 ProcessList.NATIVE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700752 } else {
753 return Integer.toString(setAdj);
754 }
755 }
756
Dianne Hackborn8e692572013-09-10 19:06:15 -0700757 public static String makeProcStateString(int curProcState) {
758 String procState;
759 switch (curProcState) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700760 case ActivityManager.PROCESS_STATE_PERSISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700761 procState = "PER ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700762 break;
763 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Dianne Hackborn94846032017-03-31 17:55:23 -0700764 procState = "PERU";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700765 break;
766 case ActivityManager.PROCESS_STATE_TOP:
Dianne Hackbornf4dd3712017-05-11 17:25:23 -0700767 procState = "TOP ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700768 break;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800769 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
770 procState = "FGSL";
771 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700772 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700773 procState = "FGS ";
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700774 break;
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800775 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
776 procState = "BFGS";
777 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700778 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700779 procState = "IMPF";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700780 break;
781 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700782 procState = "IMPB";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700783 break;
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700784 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
785 procState = "TRNB";
786 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700787 case ActivityManager.PROCESS_STATE_BACKUP:
Dianne Hackborn94846032017-03-31 17:55:23 -0700788 procState = "BKUP";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700789 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700790 case ActivityManager.PROCESS_STATE_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700791 procState = "SVC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700792 break;
793 case ActivityManager.PROCESS_STATE_RECEIVER:
Dianne Hackborn94846032017-03-31 17:55:23 -0700794 procState = "RCVR";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700795 break;
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800796 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
797 procState = "TPSL";
798 break;
Dianne Hackbornf097d422017-12-15 16:32:19 -0800799 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
800 procState = "HVY ";
801 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700802 case ActivityManager.PROCESS_STATE_HOME:
Dianne Hackborn94846032017-03-31 17:55:23 -0700803 procState = "HOME";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700804 break;
805 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700806 procState = "LAST";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700807 break;
808 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700809 procState = "CAC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700810 break;
811 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700812 procState = "CACC";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700813 break;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800814 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
815 procState = "CRE ";
816 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700817 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700818 procState = "CEM ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700819 break;
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800820 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700821 procState = "NONE";
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800822 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700823 default:
824 procState = "??";
825 break;
826 }
827 return procState;
828 }
829
Yi Jin148d7f42017-11-28 14:23:56 -0800830 public static int makeProcStateProtoEnum(int curProcState) {
831 switch (curProcState) {
832 case ActivityManager.PROCESS_STATE_PERSISTENT:
Bookatzdb026a22018-01-10 19:01:56 -0800833 return AppProtoEnums.PROCESS_STATE_PERSISTENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800834 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Bookatzdb026a22018-01-10 19:01:56 -0800835 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
Yi Jin148d7f42017-11-28 14:23:56 -0800836 case ActivityManager.PROCESS_STATE_TOP:
Bookatzdb026a22018-01-10 19:01:56 -0800837 return AppProtoEnums.PROCESS_STATE_TOP;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800838 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
Yi Jin148d7f42017-11-28 14:23:56 -0800839 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800840 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800841 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
842 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800843 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
Bookatzdb026a22018-01-10 19:01:56 -0800844 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING;
Yi Jin148d7f42017-11-28 14:23:56 -0800845 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800846 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800847 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800848 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800849 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800850 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800851 case ActivityManager.PROCESS_STATE_BACKUP:
Bookatzdb026a22018-01-10 19:01:56 -0800852 return AppProtoEnums.PROCESS_STATE_BACKUP;
Yi Jin148d7f42017-11-28 14:23:56 -0800853 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
Bookatzdb026a22018-01-10 19:01:56 -0800854 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT;
Yi Jin148d7f42017-11-28 14:23:56 -0800855 case ActivityManager.PROCESS_STATE_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800856 return AppProtoEnums.PROCESS_STATE_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800857 case ActivityManager.PROCESS_STATE_RECEIVER:
Bookatzdb026a22018-01-10 19:01:56 -0800858 return AppProtoEnums.PROCESS_STATE_RECEIVER;
Yi Jin148d7f42017-11-28 14:23:56 -0800859 case ActivityManager.PROCESS_STATE_HOME:
Bookatzdb026a22018-01-10 19:01:56 -0800860 return AppProtoEnums.PROCESS_STATE_HOME;
Yi Jin148d7f42017-11-28 14:23:56 -0800861 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -0800862 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -0800863 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -0800864 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -0800865 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Bookatzdb026a22018-01-10 19:01:56 -0800866 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800867 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
Bookatzdb026a22018-01-10 19:01:56 -0800868 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800869 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Bookatzdb026a22018-01-10 19:01:56 -0800870 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY;
Yi Jin148d7f42017-11-28 14:23:56 -0800871 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Bookatzdb026a22018-01-10 19:01:56 -0800872 return AppProtoEnums.PROCESS_STATE_NONEXISTENT;
873 case ActivityManager.PROCESS_STATE_UNKNOWN:
874 return AppProtoEnums.PROCESS_STATE_UNKNOWN;
Yi Jin148d7f42017-11-28 14:23:56 -0800875 default:
Bookatzdb026a22018-01-10 19:01:56 -0800876 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO;
Yi Jin148d7f42017-11-28 14:23:56 -0800877 }
878 }
879
Dianne Hackborn8e692572013-09-10 19:06:15 -0700880 public static void appendRamKb(StringBuilder sb, long ramKb) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400881 for (int j = 0, fact = 10; j < 6; j++, fact *= 10) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700882 if (ramKb < fact) {
883 sb.append(' ');
884 }
885 }
886 sb.append(ramKb);
887 }
888
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800889 // How long after a state change that it is safe to collect PSS without it being dirty.
890 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
891
892 // The minimum time interval after a state change it is safe to collect PSS.
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700893 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
894
895 // The maximum amount of time we want to go between PSS collections.
Dianne Hackborne17b4452018-01-10 13:15:40 -0800896 public static final int PSS_MAX_INTERVAL = 60*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700897
898 // The minimum amount of time between successive PSS requests for *all* processes.
Dianne Hackborn052e3142017-12-19 16:08:30 -0800899 public static final int PSS_ALL_INTERVAL = 20*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700900
Dianne Hackborn052e3142017-12-19 16:08:30 -0800901 // The amount of time until PSS when a persistent process first appears.
902 private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700903
904 // The amount of time until PSS when a process first becomes top.
905 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
906
907 // The amount of time until PSS when a process first goes into the background.
908 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
909
910 // The amount of time until PSS when a process first becomes cached.
Dianne Hackborne17b4452018-01-10 13:15:40 -0800911 private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;
912
913 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800914 private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700915
Dianne Hackborn052e3142017-12-19 16:08:30 -0800916 // The amount of time until PSS when the top process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800917 private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;
Dianne Hackborn052e3142017-12-19 16:08:30 -0800918
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700919 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800920 private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700921
922 // The amount of time until PSS when a service process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800923 private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700924
925 // The amount of time until PSS when a cached process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800926 private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700927
Dianne Hackborn052e3142017-12-19 16:08:30 -0800928 // The amount of time until PSS when a persistent process first appears.
929 private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
930
931 // The amount of time until PSS when a process first becomes top.
932 private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000;
933
934 // The amount of time until PSS when a process first goes into the background.
935 private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000;
936
937 // The amount of time until PSS when a process first becomes cached.
938 private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000;
939
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800940 // The minimum time interval after a state change it is safe to collect PSS.
941 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
942
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800943 // The amount of time during testing until PSS when a process first becomes top.
944 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
945
946 // The amount of time during testing until PSS when a process first goes into the background.
947 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
948
949 // The amount of time during testing until PSS when an important process stays in same state.
950 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
951
952 // The amount of time during testing until PSS when a background process stays in same state.
953 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
954
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700955 public static final int PROC_MEM_PERSISTENT = 0;
956 public static final int PROC_MEM_TOP = 1;
957 public static final int PROC_MEM_IMPORTANT = 2;
958 public static final int PROC_MEM_SERVICE = 3;
959 public static final int PROC_MEM_CACHED = 4;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800960 public static final int PROC_MEM_NUM = 5;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700961
Dianne Hackborne17b4452018-01-10 13:15:40 -0800962 // Map large set of system process states to
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700963 private static final int[] sProcStateToProcMem = new int[] {
964 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
965 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
966 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP
Amith Yamasania0a30a12019-01-22 11:38:06 -0800967 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700968 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800969 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700970 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
971 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700972 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700973 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700974 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
975 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800976 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackbornf097d422017-12-15 16:32:19 -0800977 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700978 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME
979 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
980 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
981 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -0800982 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700983 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
984 };
985
986 private static final long[] sFirstAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800987 PSS_FIRST_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
988 PSS_FIRST_TOP_INTERVAL, // PROC_MEM_TOP
989 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
990 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
991 PSS_FIRST_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700992 };
993
994 private static final long[] sSameAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800995 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
996 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP
997 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
998 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE
999 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn052e3142017-12-19 16:08:30 -08001000 };
1001
1002 private static final long[] sFirstAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001003 PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1004 PSS_FIRST_ASLEEP_TOP_INTERVAL, // PROC_MEM_TOP
1005 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1006 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1007 PSS_FIRST_ASLEEP_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn052e3142017-12-19 16:08:30 -08001008 };
1009
1010 private static final long[] sSameAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001011 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1012 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP
1013 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
1014 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE
1015 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001016 };
1017
Dianne Hackbornf097d422017-12-15 16:32:19 -08001018 private static final long[] sTestFirstPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001019 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_PERSISTENT
1020 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_TOP
1021 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1022 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1023 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001024 };
1025
Dianne Hackbornf097d422017-12-15 16:32:19 -08001026 private static final long[] sTestSamePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001027 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_PERSISTENT
1028 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_TOP
1029 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
1030 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1031 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001032 };
1033
Dianne Hackborne17b4452018-01-10 13:15:40 -08001034 public static final class ProcStateMemTracker {
1035 final int[] mHighestMem = new int[PROC_MEM_NUM];
Dianne Hackborned0a3222018-02-06 16:01:23 -08001036 final float[] mScalingFactor = new float[PROC_MEM_NUM];
Dianne Hackborne17b4452018-01-10 13:15:40 -08001037 int mTotalHighestMem = PROC_MEM_CACHED;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001038
1039 int mPendingMemState;
1040 int mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001041 float mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001042
1043 public ProcStateMemTracker() {
1044 for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
1045 mHighestMem[i] = PROC_MEM_NUM;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001046 mScalingFactor[i] = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001047 }
1048 mPendingMemState = -1;
1049 }
1050
1051 public void dumpLine(PrintWriter pw) {
1052 pw.print("best=");
1053 pw.print(mTotalHighestMem);
Dianne Hackborned0a3222018-02-06 16:01:23 -08001054 pw.print(" (");
1055 boolean needSep = false;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001056 for (int i = 0; i < PROC_MEM_NUM; i++) {
Dianne Hackborned0a3222018-02-06 16:01:23 -08001057 if (mHighestMem[i] < PROC_MEM_NUM) {
1058 if (needSep) {
1059 pw.print(", ");
1060 needSep = false;
1061 }
1062 pw.print(i);
1063 pw.print("=");
1064 pw.print(mHighestMem[i]);
1065 pw.print(" ");
1066 pw.print(mScalingFactor[i]);
1067 pw.print("x");
1068 needSep = true;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001069 }
Dianne Hackborne17b4452018-01-10 13:15:40 -08001070 }
1071 pw.print(")");
1072 if (mPendingMemState >= 0) {
1073 pw.print(" / pending state=");
1074 pw.print(mPendingMemState);
1075 pw.print(" highest=");
1076 pw.print(mPendingHighestMemState);
Dianne Hackborned0a3222018-02-06 16:01:23 -08001077 pw.print(" ");
1078 pw.print(mPendingScalingFactor);
1079 pw.print("x");
Dianne Hackborne17b4452018-01-10 13:15:40 -08001080 }
1081 pw.println();
1082 }
1083 }
1084
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001085 public static boolean procStatesDifferForMem(int procState1, int procState2) {
1086 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
1087 }
1088
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -08001089 public static long minTimeFromStateChange(boolean test) {
1090 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
1091 }
1092
Dianne Hackborne17b4452018-01-10 13:15:40 -08001093 public static void commitNextPssTime(ProcStateMemTracker tracker) {
1094 if (tracker.mPendingMemState >= 0) {
1095 tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001096 tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001097 tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001098 tracker.mPendingMemState = -1;
1099 }
1100 }
1101
1102 public static void abortNextPssTime(ProcStateMemTracker tracker) {
1103 tracker.mPendingMemState = -1;
1104 }
1105
1106 public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001107 boolean sleeping, long now) {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001108 boolean first;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001109 float scalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001110 final int memState = sProcStateToProcMem[procState];
1111 if (tracker != null) {
1112 final int highestMemState = memState < tracker.mTotalHighestMem
1113 ? memState : tracker.mTotalHighestMem;
1114 first = highestMemState < tracker.mHighestMem[memState];
1115 tracker.mPendingMemState = memState;
1116 tracker.mPendingHighestMemState = highestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001117 if (first) {
1118 tracker.mPendingScalingFactor = scalingFactor = 1.0f;
1119 } else {
1120 scalingFactor = tracker.mScalingFactor[memState];
1121 tracker.mPendingScalingFactor = scalingFactor * 1.5f;
1122 }
Dianne Hackborne17b4452018-01-10 13:15:40 -08001123 } else {
1124 first = true;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001125 scalingFactor = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001126 }
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001127 final long[] table = test
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001128 ? (first
Dianne Hackborne17b4452018-01-10 13:15:40 -08001129 ? sTestFirstPssTimes
1130 : sTestSamePssTimes)
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001131 : (first
Dianne Hackborne17b4452018-01-10 13:15:40 -08001132 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
1133 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
Dianne Hackborned0a3222018-02-06 16:01:23 -08001134 long delay = (long)(table[memState] * scalingFactor);
Dianne Hackborne17b4452018-01-10 13:15:40 -08001135 if (delay > PSS_MAX_INTERVAL) {
1136 delay = PSS_MAX_INTERVAL;
1137 }
1138 return now + delay;
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001139 }
1140
Dianne Hackborn7d608422011-08-07 16:24:18 -07001141 long getMemLevel(int adjustment) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001142 for (int i = 0; i < mOomAdj.length; i++) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07001143 if (adjustment <= mOomAdj[i]) {
1144 return mOomMinFree[i] * 1024;
1145 }
1146 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001147 return mOomMinFree[mOomAdj.length - 1] * 1024;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001148 }
1149
Todd Poynorbfdd6232013-07-10 19:15:07 -07001150 /**
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001151 * Return the maximum pss size in kb that we consider a process acceptable to
1152 * restore from its cached state for running in the background when RAM is low.
1153 */
Dianne Hackborncbd9a522013-09-24 23:10:14 -07001154 long getCachedRestoreThresholdKb() {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001155 return mCachedRestoreLevel;
1156 }
1157
Dianne Hackborn9bef5b62013-09-20 10:40:34 -07001158 /**
Todd Poynorbfdd6232013-07-10 19:15:07 -07001159 * Set the out-of-memory badness adjustment for a process.
Sudheer Shankaf6690102017-10-16 10:20:32 -07001160 * If {@code pid <= 0}, this method will be a no-op.
Todd Poynorbfdd6232013-07-10 19:15:07 -07001161 *
1162 * @param pid The process identifier to set.
Colin Crossd908edd2014-06-13 14:56:04 -07001163 * @param uid The uid of the app
Rafal Slawikda8c0ab2019-03-07 13:54:40 +00001164 * @param amt Adjustment value -- lmkd allows -1000 to +1000
Todd Poynorbfdd6232013-07-10 19:15:07 -07001165 *
1166 * {@hide}
1167 */
Rafal Slawikda8c0ab2019-03-07 13:54:40 +00001168 public static void setOomAdj(int pid, int uid, int amt) {
Sudheer Shankaf6690102017-10-16 10:20:32 -07001169 // This indicates that the process is not started yet and so no need to proceed further.
1170 if (pid <= 0) {
1171 return;
1172 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001173 if (amt == UNKNOWN_ADJ)
1174 return;
1175
Dianne Hackbornecf1cda2014-08-28 16:58:28 -07001176 long start = SystemClock.elapsedRealtime();
Colin Crossd908edd2014-06-13 14:56:04 -07001177 ByteBuffer buf = ByteBuffer.allocate(4 * 4);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001178 buf.putInt(LMK_PROCPRIO);
1179 buf.putInt(pid);
Colin Crossd908edd2014-06-13 14:56:04 -07001180 buf.putInt(uid);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001181 buf.putInt(amt);
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001182 writeLmkd(buf, null);
Dianne Hackbornecf1cda2014-08-28 16:58:28 -07001183 long now = SystemClock.elapsedRealtime();
1184 if ((now-start) > 250) {
1185 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
1186 + " = " + amt);
1187 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001188 }
1189
1190 /*
1191 * {@hide}
1192 */
1193 public static final void remove(int pid) {
Sudheer Shankaf6690102017-10-16 10:20:32 -07001194 // This indicates that the process is not started yet and so no need to proceed further.
1195 if (pid <= 0) {
1196 return;
1197 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001198 ByteBuffer buf = ByteBuffer.allocate(4 * 2);
1199 buf.putInt(LMK_PROCREMOVE);
1200 buf.putInt(pid);
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001201 writeLmkd(buf, null);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001202 }
1203
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001204 /*
1205 * {@hide}
1206 */
1207 public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) {
1208 ByteBuffer buf = ByteBuffer.allocate(4 * 3);
1209 ByteBuffer repl = ByteBuffer.allocate(4 * 2);
1210 buf.putInt(LMK_GETKILLCNT);
1211 buf.putInt(min_oom_adj);
1212 buf.putInt(max_oom_adj);
1213 if (writeLmkd(buf, repl)) {
1214 int i = repl.getInt();
1215 if (i != LMK_GETKILLCNT) {
1216 Slog.e("ActivityManager", "Failed to get kill count, code mismatch");
1217 return null;
1218 }
1219 return new Integer(repl.getInt());
1220 }
1221 return null;
1222 }
1223
1224 @GuardedBy("sLmkdSocketLock")
1225 private static boolean openLmkdSocketLS() {
Dianne Hackborn7d608422011-08-07 16:24:18 -07001226 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -07001227 sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
1228 sLmkdSocket.connect(
1229 new LocalSocketAddress("lmkd",
1230 LocalSocketAddress.Namespace.RESERVED));
1231 sLmkdOutputStream = sLmkdSocket.getOutputStream();
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001232 sLmkdInputStream = sLmkdSocket.getInputStream();
Todd Poynorbfdd6232013-07-10 19:15:07 -07001233 } catch (IOException ex) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001234 Slog.w(TAG, "lowmemorykiller daemon socket open failed");
Todd Poynorbfdd6232013-07-10 19:15:07 -07001235 sLmkdSocket = null;
1236 return false;
1237 }
1238
1239 return true;
1240 }
1241
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001242 // Never call directly, use writeLmkd() instead
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001243 @GuardedBy("sLmkdSocketLock")
1244 private static boolean writeLmkdCommandLS(ByteBuffer buf) {
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001245 try {
1246 sLmkdOutputStream.write(buf.array(), 0, buf.position());
1247 } catch (IOException ex) {
1248 Slog.w(TAG, "Error writing to lowmemorykiller socket");
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001249 IoUtils.closeQuietly(sLmkdSocket);
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001250 sLmkdSocket = null;
1251 return false;
1252 }
1253 return true;
1254 }
1255
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001256 // Never call directly, use writeLmkd() instead
1257 @GuardedBy("sLmkdSocketLock")
1258 private static boolean readLmkdReplyLS(ByteBuffer buf) {
1259 int len;
1260 try {
1261 len = sLmkdInputStream.read(buf.array(), 0, buf.array().length);
1262 if (len == buf.array().length) {
1263 return true;
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001264 }
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001265 } catch (IOException ex) {
1266 Slog.w(TAG, "Error reading from lowmemorykiller socket");
1267 }
1268
1269 IoUtils.closeQuietly(sLmkdSocket);
1270 sLmkdSocket = null;
1271 return false;
1272 }
1273
1274 private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
1275 synchronized (sLmkdSocketLock) {
1276 for (int i = 0; i < 3; i++) {
1277 if (sLmkdSocket == null) {
1278 if (openLmkdSocketLS() == false) {
1279 try {
1280 Thread.sleep(1000);
1281 } catch (InterruptedException ie) {
1282 }
1283 continue;
1284 }
1285
1286 // Purge any previously registered pids
1287 ByteBuffer purge_buf = ByteBuffer.allocate(4);
1288 purge_buf.putInt(LMK_PROCPURGE);
1289 if (writeLmkdCommandLS(purge_buf) == false) {
1290 // Write failed, skip the rest and retry
1291 continue;
1292 }
1293 }
1294 if (writeLmkdCommandLS(buf) && (repl == null || readLmkdReplyLS(repl))) {
1295 return true;
1296 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07001297 }
1298 }
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001299 return false;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001300 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001301
1302 static void killProcessGroup(int uid, int pid) {
1303 /* static; one-time init here */
1304 if (sKillHandler != null) {
1305 sKillHandler.sendMessage(
1306 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
1307 } else {
1308 Slog.w(TAG, "Asked to kill process group before system bringup!");
1309 Process.killProcessGroup(uid, pid);
1310 }
1311 }
1312
1313 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean
1314 keepIfLarge) {
1315 if (uid == SYSTEM_UID) {
1316 // The system gets to run in any process. If there are multiple
1317 // processes with the same uid, just pick the first (this
1318 // should never happen).
1319 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
1320 if (procs == null) return null;
1321 final int procCount = procs.size();
1322 for (int i = 0; i < procCount; i++) {
1323 final int procUid = procs.keyAt(i);
1324 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
1325 // Don't use an app process or different user process for system component.
1326 continue;
1327 }
1328 return procs.valueAt(i);
1329 }
1330 }
1331 ProcessRecord proc = mProcessNames.get(processName, uid);
1332 if (false && proc != null && !keepIfLarge
1333 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
1334 && proc.lastCachedPss >= 4000) {
1335 // Turn this condition on to cause killing to happen regularly, for testing.
1336 if (proc.baseProcessTracker != null) {
1337 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
1338 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1339 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1340 StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1341 proc.info.uid,
1342 holder.state.getName(),
1343 holder.state.getPackage(),
1344 proc.lastCachedPss, holder.appVersion);
1345 }
1346 }
1347 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
1348 } else if (proc != null && !keepIfLarge
1349 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
1350 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
1351 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc
1352 .lastCachedPss);
1353 if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) {
1354 if (proc.baseProcessTracker != null) {
1355 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
1356 proc.lastCachedPss);
1357 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1358 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1359 StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1360 proc.info.uid,
1361 holder.state.getName(),
1362 holder.state.getPackage(),
1363 proc.lastCachedPss, holder.appVersion);
1364 }
1365 }
1366 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
1367 }
1368 }
1369 return proc;
1370 }
1371
1372 void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
1373 final long homeAppMem = getMemLevel(HOME_APP_ADJ);
1374 final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ);
1375 outInfo.availMem = getFreeMemory();
1376 outInfo.totalMem = getTotalMemory();
1377 outInfo.threshold = homeAppMem;
1378 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
1379 outInfo.hiddenAppThreshold = cachedAppMem;
1380 outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ);
1381 outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ);
1382 outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ);
1383 }
1384
1385 ProcessRecord findAppProcessLocked(IBinder app, String reason) {
1386 final int NP = mProcessNames.getMap().size();
1387 for (int ip = 0; ip < NP; ip++) {
1388 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
1389 final int NA = apps.size();
1390 for (int ia = 0; ia < NA; ia++) {
1391 ProcessRecord p = apps.valueAt(ia);
1392 if (p.thread != null && p.thread.asBinder() == app) {
1393 return p;
1394 }
1395 }
1396 }
1397
1398 Slog.w(TAG, "Can't find mystery application for " + reason
1399 + " from pid=" + Binder.getCallingPid()
1400 + " uid=" + Binder.getCallingUid() + ": " + app);
1401 return null;
1402 }
1403
1404 private void checkSlow(long startTime, String where) {
1405 long now = SystemClock.uptimeMillis();
1406 if ((now - startTime) > 50) {
1407 // If we are taking more than 50ms, log about it.
1408 Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where);
1409 }
1410 }
1411
1412 /**
1413 * @return {@code true} if process start is successful, false otherwise.
1414 * @param app
1415 * @param hostingType
1416 * @param hostingNameStr
1417 * @param disableHiddenApiChecks
1418 * @param abiOverride
1419 */
1420 @GuardedBy("mService")
1421 boolean startProcessLocked(ProcessRecord app, String hostingType,
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001422 String hostingNameStr, boolean disableHiddenApiChecks, boolean mountExtStorageFull,
1423 String abiOverride) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001424 if (app.pendingStart) {
1425 return true;
1426 }
1427 long startTime = SystemClock.elapsedRealtime();
1428 if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
1429 checkSlow(startTime, "startProcess: removing from pids map");
Wale Ogunwale0b940842018-12-03 06:58:11 -08001430 mService.mPidsSelfLocked.remove(app.pid);
1431 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04001432 checkSlow(startTime, "startProcess: done removing from pids map");
1433 app.setPid(0);
1434 }
1435
1436 if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
1437 TAG_PROCESSES,
1438 "startProcessLocked removing on hold: " + app);
1439 mService.mProcessesOnHold.remove(app);
1440
1441 checkSlow(startTime, "startProcess: starting to update cpu stats");
1442 mService.updateCpuStats();
1443 checkSlow(startTime, "startProcess: done updating cpu stats");
1444
1445 try {
1446 try {
1447 final int userId = UserHandle.getUserId(app.uid);
1448 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
1449 } catch (RemoteException e) {
1450 throw e.rethrowAsRuntimeException();
1451 }
1452
1453 int uid = app.uid;
1454 int[] gids = null;
1455 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1456 if (!app.isolated) {
1457 int[] permGids = null;
1458 try {
1459 checkSlow(startTime, "startProcess: getting gids from package manager");
1460 final IPackageManager pm = AppGlobals.getPackageManager();
1461 permGids = pm.getPackageGids(app.info.packageName,
1462 MATCH_DIRECT_BOOT_AUTO, app.userId);
Jeff Sharkey10ec9d82018-11-28 14:52:45 -07001463 if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001464 mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
1465 } else {
1466 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1467 StorageManagerInternal.class);
1468 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
1469 app.info.packageName);
1470 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001471 } catch (RemoteException e) {
1472 throw e.rethrowAsRuntimeException();
1473 }
1474
1475 /*
1476 * Add shared application and profile GIDs so applications can share some
1477 * resources like shared libraries and access user-wide resources
1478 */
1479 if (ArrayUtils.isEmpty(permGids)) {
1480 gids = new int[3];
1481 } else {
1482 gids = new int[permGids.length + 3];
1483 System.arraycopy(permGids, 0, gids, 3, permGids.length);
1484 }
1485 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
1486 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
1487 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
1488
1489 // Replace any invalid GIDs
1490 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
1491 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
1492 }
Sudheer Shanka87915d62018-11-06 10:57:35 -08001493 app.mountMode = mountExternal;
Amith Yamasani98a00922018-08-21 12:50:30 -04001494 checkSlow(startTime, "startProcess: building args");
1495 if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
1496 uid = 0;
1497 }
1498 int runtimeFlags = 0;
1499 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1500 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
1501 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1502 // Also turn on CheckJNI for debuggable apps. It's quite
1503 // awkward to turn on otherwise.
1504 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
Alex Buynytskyy5d5921ee2019-01-22 15:22:55 -08001505
1506 // Check if the developer does not want ART verification
1507 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(),
1508 android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) {
1509 runtimeFlags |= Zygote.DISABLE_VERIFIER;
1510 Slog.w(TAG_PROCESSES, app + ": ART verification disabled");
1511 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001512 }
1513 // Run the app in safe mode if its manifest requests so or the
1514 // system is booted in safe mode.
1515 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1516 mService.mSafeMode == true) {
1517 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1518 }
Yabin Cui4d8546d2019-01-29 16:29:20 -08001519 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
1520 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
1521 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001522 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1523 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1524 }
1525 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1526 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1527 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1528 }
1529 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1530 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1531 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1532 }
1533 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1534 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1535 }
1536 if ("1".equals(SystemProperties.get("debug.assert"))) {
1537 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1538 }
1539 if (mService.mNativeDebuggingApp != null
1540 && mService.mNativeDebuggingApp.equals(app.processName)) {
1541 // Enable all debug flags required by the native debugger.
1542 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
1543 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1544 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
1545 mService.mNativeDebuggingApp = null;
1546 }
1547
Victor Hsiehfa9df0b2019-01-29 12:48:36 -08001548 if (app.info.isEmbeddedDexUsed()
Victor Hsiehe7b5a8d2018-11-16 10:27:06 -08001549 || (app.info.isPrivilegedApp()
1550 && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001551 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1552 }
1553
1554 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
1555 app.info.maybeUpdateHiddenApiEnforcementPolicy(
David Brazdil06ae4b82018-11-02 18:01:45 +00001556 mService.mHiddenApiBlacklist.getPolicy());
Amith Yamasani98a00922018-08-21 12:50:30 -04001557 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
1558 app.info.getHiddenApiEnforcementPolicy();
1559 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
1560 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
1561 throw new IllegalStateException("Invalid API policy: " + policy);
1562 }
1563 runtimeFlags |= policyBits;
1564 }
1565
Mathieu Chartier77bd1232019-03-05 13:53:11 -08001566 String useAppImageCache = SystemProperties.get(
1567 PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
1568 // Property defaults to true currently.
1569 if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) {
1570 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
1571 }
1572
Amith Yamasani98a00922018-08-21 12:50:30 -04001573 String invokeWith = null;
1574 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1575 // Debuggable apps may include a wrapper script with their library directory.
1576 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
1577 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
1578 try {
1579 if (new File(wrapperFileName).exists()) {
1580 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
1581 }
1582 } finally {
1583 StrictMode.setThreadPolicy(oldPolicy);
1584 }
1585 }
1586
1587 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
1588 if (requiredAbi == null) {
1589 requiredAbi = Build.SUPPORTED_ABIS[0];
1590 }
1591
1592 String instructionSet = null;
1593 if (app.info.primaryCpuAbi != null) {
1594 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
1595 }
1596
1597 app.gids = gids;
1598 app.setRequiredAbi(requiredAbi);
1599 app.instructionSet = instructionSet;
1600
1601 // the per-user SELinux context must be set
1602 if (TextUtils.isEmpty(app.info.seInfoUser)) {
1603 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
1604 new IllegalStateException("SELinux tag not defined for "
1605 + app.info.packageName + " (uid " + app.uid + ")"));
1606 }
1607 final String seInfo = app.info.seInfo
1608 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
1609 // Start the process. It will either succeed and return a result containing
1610 // the PID of the new process, or else throw a RuntimeException.
1611 final String entryPoint = "android.app.ActivityThread";
1612
1613 return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
1614 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
1615 startTime);
1616 } catch (RuntimeException e) {
1617 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1618
1619 // Something went very wrong while trying to start this process; one
1620 // common case is when the package is frozen due to an active
1621 // upgrade. To recover, clean up any active bookkeeping related to
1622 // starting this process. (We already invoked this method once when
1623 // the package was initially frozen through KILL_APPLICATION_MSG, so
1624 // it doesn't hurt to use it again.)
1625 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1626 false, false, true, false, false, app.userId, "start failure");
1627 return false;
1628 }
1629 }
1630
1631 @GuardedBy("mService")
1632 boolean startProcessLocked(String hostingType, String hostingNameStr,
1633 String entryPoint,
1634 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1635 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1636 long startTime) {
1637 app.pendingStart = true;
1638 app.killedByAm = false;
1639 app.removed = false;
1640 app.killed = false;
1641 final long startSeq = app.startSeq = ++mProcStartSeqCounter;
1642 app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
1643 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
1644 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
1645 "Posting procStart msg for " + app.toShortString());
1646 mService.mProcStartHandler.post(() -> {
1647 try {
1648 synchronized (mService) {
1649 final String reason = isProcStartValidLocked(app, startSeq);
1650 if (reason != null) {
1651 Slog.w(TAG_PROCESSES, app + " not valid anymore,"
1652 + " don't start process, " + reason);
1653 app.pendingStart = false;
1654 return;
1655 }
1656 app.setUsingWrapper(invokeWith != null
1657 || SystemProperties.get("wrap." + app.processName) != null);
1658 mPendingStarts.put(startSeq, app);
1659 }
1660 final Process.ProcessStartResult startResult = startProcess(app.hostingType,
1661 entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
1662 app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
1663 synchronized (mService) {
1664 handleProcessStartedLocked(app, startResult, startSeq);
1665 }
1666 } catch (RuntimeException e) {
1667 synchronized (mService) {
1668 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1669 + app.processName, e);
1670 mPendingStarts.remove(startSeq);
1671 app.pendingStart = false;
1672 mService.forceStopPackageLocked(app.info.packageName,
1673 UserHandle.getAppId(app.uid),
1674 false, false, true, false, false, app.userId, "start failure");
1675 }
1676 }
1677 });
1678 return true;
1679 } else {
1680 try {
1681 final Process.ProcessStartResult startResult = startProcess(hostingType,
1682 entryPoint, app,
1683 uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
1684 invokeWith, startTime);
1685 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
1686 startSeq, false);
1687 } catch (RuntimeException e) {
1688 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1689 + app.processName, e);
1690 app.pendingStart = false;
1691 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1692 false, false, true, false, false, app.userId, "start failure");
1693 }
1694 return app.pid > 0;
1695 }
1696 }
1697
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001698 @GuardedBy("mService")
1699 public void killAppZygoteIfNeededLocked(AppZygote appZygote) {
1700 final ApplicationInfo appInfo = appZygote.getAppInfo();
1701 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
Martijn Coenenb27a8ea2019-02-12 10:23:47 +01001702 if (zygoteProcesses != null && zygoteProcesses.size() == 0) {
1703 // Only remove if no longer in use now
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001704 mAppZygotes.remove(appInfo.processName, appInfo.uid);
1705 mAppZygoteProcesses.remove(appZygote);
Martijn Coenen01e719b2018-12-05 16:01:38 +01001706 mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001707 appZygote.stopZygote();
1708 }
1709 }
1710
1711 @GuardedBy("mService")
1712 private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01001713 // Free the isolated uid for this process
1714 final IsolatedUidRange appUidRange =
1715 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info);
1716 if (appUidRange != null) {
1717 appUidRange.freeIsolatedUidLocked(app.uid);
1718 }
1719
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001720 final AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid);
1721 if (appZygote != null) {
1722 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
1723 zygoteProcesses.remove(app);
1724 if (zygoteProcesses.size() == 0) {
Martijn Coenenb27a8ea2019-02-12 10:23:47 +01001725 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG);
Martijn Coenen378b2702019-02-20 10:33:41 +01001726 if (app.removed) {
1727 // If we stopped this process because the package hosting it was removed,
1728 // there's no point in delaying the app zygote kill.
1729 killAppZygoteIfNeededLocked(appZygote);
1730 } else {
1731 Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
1732 msg.obj = appZygote;
1733 mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS);
1734 }
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001735 }
1736 }
1737 }
1738
1739 private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
1740 synchronized (mService) {
1741 AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid);
1742 final ArrayList<ProcessRecord> zygoteProcessList;
1743 if (appZygote == null) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01001744 final IsolatedUidRange uidRange =
1745 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info);
Martijn Coenen86f08a52019-01-03 16:23:01 +01001746 final int userId = UserHandle.getUserId(app.info.uid);
1747 // Create the app-zygote and provide it with the UID-range it's allowed
1748 // to setresuid/setresgid to.
1749 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
1750 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
1751 appZygote = new AppZygote(app.info, app.info.uid, firstUid, lastUid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001752 mAppZygotes.put(app.info.processName, app.info.uid, appZygote);
1753 zygoteProcessList = new ArrayList<ProcessRecord>();
1754 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
1755 } else {
1756 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
1757 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
1758 }
1759 // Note that we already add the app to mAppZygoteProcesses here;
1760 // this is so that another thread can't come in and kill the zygote
1761 // before we've even tried to start the process. If the process launch
1762 // goes wrong, we'll clean this up in removeProcessNameLocked()
1763 zygoteProcessList.add(app);
1764
1765 return appZygote;
1766 }
1767 }
1768
Amith Yamasani98a00922018-08-21 12:50:30 -04001769 private Process.ProcessStartResult startProcess(String hostingType, String entryPoint,
1770 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1771 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1772 long startTime) {
1773 try {
1774 final String[] packageNames = mService.mContext.getPackageManager()
1775 .getPackagesForUid(uid);
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001776 final StorageManagerInternal storageManagerInternal =
1777 LocalServices.getService(StorageManagerInternal.class);
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001778 final String sandboxId = storageManagerInternal.getSandboxId(app.info.packageName);
Amith Yamasani98a00922018-08-21 12:50:30 -04001779 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
1780 app.processName);
1781 checkSlow(startTime, "startProcess: asking zygote to start proc");
1782 final Process.ProcessStartResult startResult;
1783 if (hostingType.equals("webview_service")) {
1784 startResult = startWebView(entryPoint,
1785 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1786 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1787 app.info.dataDir, null, app.info.packageName,
Sudheer Shankae51005d2019-02-24 10:24:09 -08001788 packageNames, sandboxId,
Amith Yamasani98a00922018-08-21 12:50:30 -04001789 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001790 } else if (hostingType.equals("app_zygote")) {
1791 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
1792
1793 startResult = appZygote.getProcess().start(entryPoint,
1794 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1795 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1796 app.info.dataDir, null, app.info.packageName,
Chris Wailes7e797b62019-02-22 18:29:22 -08001797 packageNames, sandboxId, /*useUnspecializedAppProcessPool=*/ false,
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001798 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
Amith Yamasani98a00922018-08-21 12:50:30 -04001799 } else {
1800 startResult = Process.start(entryPoint,
1801 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1802 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1803 app.info.dataDir, invokeWith, app.info.packageName,
Sudheer Shankae51005d2019-02-24 10:24:09 -08001804 packageNames, sandboxId,
Amith Yamasani98a00922018-08-21 12:50:30 -04001805 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
1806 }
1807 checkSlow(startTime, "startProcess: returned from zygote!");
1808 return startResult;
1809 } finally {
1810 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1811 }
1812 }
1813
1814 @GuardedBy("mService")
1815 final void startProcessLocked(ProcessRecord app,
1816 String hostingType, String hostingNameStr) {
1817 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
1818 }
1819
1820 @GuardedBy("mService")
1821 final boolean startProcessLocked(ProcessRecord app,
1822 String hostingType, String hostingNameStr, String abiOverride) {
1823 return startProcessLocked(app, hostingType, hostingNameStr,
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001824 false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
Amith Yamasani98a00922018-08-21 12:50:30 -04001825 }
1826
1827 @GuardedBy("mService")
1828 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
1829 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
1830 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
1831 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
1832 long startTime = SystemClock.elapsedRealtime();
1833 ProcessRecord app;
1834 if (!isolated) {
1835 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
1836 checkSlow(startTime, "startProcess: after getProcessRecord");
1837
1838 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
1839 // If we are in the background, then check to see if this process
1840 // is bad. If so, we will just silently fail.
1841 if (mService.mAppErrors.isBadProcessLocked(info)) {
1842 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1843 + "/" + info.processName);
1844 return null;
1845 }
1846 } else {
1847 // When the user is explicitly starting a process, then clear its
1848 // crash count so that we won't make it bad until they see at
1849 // least one crash dialog again, and make the process good again
1850 // if it had been bad.
1851 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1852 + "/" + info.processName);
1853 mService.mAppErrors.resetProcessCrashTimeLocked(info);
1854 if (mService.mAppErrors.isBadProcessLocked(info)) {
1855 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
1856 UserHandle.getUserId(info.uid), info.uid,
1857 info.processName);
1858 mService.mAppErrors.clearBadProcessLocked(info);
1859 if (app != null) {
1860 app.bad = false;
1861 }
1862 }
1863 }
1864 } else {
1865 // If this is an isolated process, it can't re-use an existing process.
1866 app = null;
1867 }
1868
1869 // We don't have to do anything more if:
1870 // (1) There is an existing application record; and
1871 // (2) The caller doesn't think it is dead, OR there is no thread
1872 // object attached to it so we know it couldn't have crashed; and
1873 // (3) There is a pid assigned to it, so it is either starting or
1874 // already running.
1875 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
1876 + " app=" + app + " knownToBeDead=" + knownToBeDead
1877 + " thread=" + (app != null ? app.thread : null)
1878 + " pid=" + (app != null ? app.pid : -1));
1879 if (app != null && app.pid > 0) {
1880 if ((!knownToBeDead && !app.killed) || app.thread == null) {
1881 // We already have the app running, or are waiting for it to
1882 // come up (we have a pid but not yet its thread), so keep it.
1883 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
1884 // If this is a new package in the process, add the package to the list
1885 app.addPackage(info.packageName, info.versionCode, mService.mProcessStats);
1886 checkSlow(startTime, "startProcess: done, added package to proc");
1887 return app;
1888 }
1889
1890 // An application record is attached to a previous process,
1891 // clean it up now.
1892 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
1893 checkSlow(startTime, "startProcess: bad proc running, killing");
1894 ProcessList.killProcessGroup(app.uid, app.pid);
1895 mService.handleAppDiedLocked(app, true, true);
1896 checkSlow(startTime, "startProcess: done killing old proc");
1897 }
1898
1899 String hostingNameStr = hostingName != null
1900 ? hostingName.flattenToShortString() : null;
1901
1902 if (app == null) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01001903 final boolean fromAppZygote = "app_zygote".equals(hostingType);
Amith Yamasani98a00922018-08-21 12:50:30 -04001904 checkSlow(startTime, "startProcess: creating new process record");
Martijn Coenen01e719b2018-12-05 16:01:38 +01001905 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, fromAppZygote);
Amith Yamasani98a00922018-08-21 12:50:30 -04001906 if (app == null) {
1907 Slog.w(TAG, "Failed making new process record for "
1908 + processName + "/" + info.uid + " isolated=" + isolated);
1909 return null;
1910 }
1911 app.crashHandler = crashHandler;
1912 app.isolatedEntryPoint = entryPoint;
1913 app.isolatedEntryPointArgs = entryPointArgs;
1914 checkSlow(startTime, "startProcess: done creating new process record");
1915 } else {
1916 // If this is a new package in the process, add the package to the list
1917 app.addPackage(info.packageName, info.versionCode, mService.mProcessStats);
1918 checkSlow(startTime, "startProcess: added package to existing proc");
1919 }
1920
1921 // If the system is not ready yet, then hold off on starting this
1922 // process until it is.
1923 if (!mService.mProcessesReady
1924 && !mService.isAllowedWhileBooting(info)
1925 && !allowWhileBooting) {
1926 if (!mService.mProcessesOnHold.contains(app)) {
1927 mService.mProcessesOnHold.add(app);
1928 }
1929 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
1930 "System not ready, putting on hold: " + app);
1931 checkSlow(startTime, "startProcess: returning with proc on hold");
1932 return app;
1933 }
1934
1935 checkSlow(startTime, "startProcess: stepping in to startProcess");
1936 final boolean success = startProcessLocked(app, hostingType, hostingNameStr,
1937 abiOverride);
1938 checkSlow(startTime, "startProcess: done starting proc!");
1939 return success ? app : null;
1940 }
1941
1942 @GuardedBy("mService")
1943 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
1944 StringBuilder sb = null;
1945 if (app.killedByAm) {
1946 if (sb == null) sb = new StringBuilder();
1947 sb.append("killedByAm=true;");
1948 }
1949 if (mProcessNames.get(app.processName, app.uid) != app) {
1950 if (sb == null) sb = new StringBuilder();
1951 sb.append("No entry in mProcessNames;");
1952 }
1953 if (!app.pendingStart) {
1954 if (sb == null) sb = new StringBuilder();
1955 sb.append("pendingStart=false;");
1956 }
1957 if (app.startSeq > expectedStartSeq) {
1958 if (sb == null) sb = new StringBuilder();
1959 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
1960 }
1961 return sb == null ? null : sb.toString();
1962 }
1963
1964 @GuardedBy("mService")
1965 private boolean handleProcessStartedLocked(ProcessRecord pending,
1966 Process.ProcessStartResult startResult, long expectedStartSeq) {
1967 // Indicates that this process start has been taken care of.
1968 if (mPendingStarts.get(expectedStartSeq) == null) {
1969 if (pending.pid == startResult.pid) {
1970 pending.setUsingWrapper(startResult.usingWrapper);
1971 // TODO: Update already existing clients of usingWrapper
1972 }
1973 return false;
1974 }
1975 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
1976 expectedStartSeq, false);
1977 }
1978
1979 @GuardedBy("mService")
1980 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
1981 long expectedStartSeq, boolean procAttached) {
1982 mPendingStarts.remove(expectedStartSeq);
1983 final String reason = isProcStartValidLocked(app, expectedStartSeq);
1984 if (reason != null) {
1985 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
1986 pid
1987 + ", " + reason);
1988 app.pendingStart = false;
1989 killProcessQuiet(pid);
1990 Process.killProcessGroup(app.uid, app.pid);
1991 return false;
1992 }
1993 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
1994 checkSlow(app.startTime, "startProcess: done updating battery stats");
1995
1996 EventLog.writeEvent(EventLogTags.AM_PROC_START,
1997 UserHandle.getUserId(app.startUid), pid, app.startUid,
1998 app.processName, app.hostingType,
1999 app.hostingNameStr != null ? app.hostingNameStr : "");
2000
2001 try {
2002 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
2003 app.seInfo, app.info.sourceDir, pid);
2004 } catch (RemoteException ex) {
2005 // Ignore
2006 }
2007
2008 if (app.isPersistent()) {
2009 Watchdog.getInstance().processStarted(app.processName, pid);
2010 }
2011
2012 checkSlow(app.startTime, "startProcess: building log message");
2013 StringBuilder buf = mStringBuilder;
2014 buf.setLength(0);
2015 buf.append("Start proc ");
2016 buf.append(pid);
2017 buf.append(':');
2018 buf.append(app.processName);
2019 buf.append('/');
2020 UserHandle.formatUid(buf, app.startUid);
2021 if (app.isolatedEntryPoint != null) {
2022 buf.append(" [");
2023 buf.append(app.isolatedEntryPoint);
2024 buf.append("]");
2025 }
2026 buf.append(" for ");
2027 buf.append(app.hostingType);
2028 if (app.hostingNameStr != null) {
2029 buf.append(" ");
2030 buf.append(app.hostingNameStr);
2031 }
2032 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
2033 app.setPid(pid);
2034 app.setUsingWrapper(usingWrapper);
2035 app.pendingStart = false;
2036 checkSlow(app.startTime, "startProcess: starting to update pids map");
2037 ProcessRecord oldApp;
2038 synchronized (mService.mPidsSelfLocked) {
2039 oldApp = mService.mPidsSelfLocked.get(pid);
2040 }
2041 // If there is already an app occupying that pid that hasn't been cleaned up
2042 if (oldApp != null && !app.isolated) {
2043 // Clean up anything relating to this pid first
2044 Slog.w(TAG, "Reusing pid " + pid
2045 + " while app is still mapped to it");
2046 mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
2047 true /*replacingPid*/);
2048 }
Wale Ogunwale0b940842018-12-03 06:58:11 -08002049 mService.mPidsSelfLocked.put(pid, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002050 synchronized (mService.mPidsSelfLocked) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002051 if (!procAttached) {
2052 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2053 msg.obj = app;
2054 mService.mHandler.sendMessageDelayed(msg, usingWrapper
2055 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2056 }
2057 }
2058 checkSlow(app.startTime, "startProcess: done updating pids map");
2059 return true;
2060 }
2061
2062 final void removeLruProcessLocked(ProcessRecord app) {
2063 int lrui = mLruProcesses.lastIndexOf(app);
2064 if (lrui >= 0) {
2065 if (!app.killed) {
2066 if (app.isPersistent()) {
2067 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2068 } else {
2069 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2070 if (app.pid > 0) {
2071 killProcessQuiet(app.pid);
2072 ProcessList.killProcessGroup(app.uid, app.pid);
2073 } else {
2074 app.pendingStart = false;
2075 }
2076 }
2077 }
2078 if (lrui <= mLruProcessActivityStart) {
2079 mLruProcessActivityStart--;
2080 }
2081 if (lrui <= mLruProcessServiceStart) {
2082 mLruProcessServiceStart--;
2083 }
2084 mLruProcesses.remove(lrui);
2085 }
2086 }
2087
Riddle Hsuaaef7312019-01-24 19:00:58 +08002088 @GuardedBy("mService")
2089 boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
2090 String reason) {
2091 return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
2092 false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2093 false /* evenPersistent */, false /* setRemoved */, reason);
Amith Yamasani98a00922018-08-21 12:50:30 -04002094 }
2095
2096 @GuardedBy("mService")
2097 final boolean killPackageProcessesLocked(String packageName, int appId,
2098 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
Riddle Hsuaaef7312019-01-24 19:00:58 +08002099 boolean doit, boolean evenPersistent, boolean setRemoved, String reason) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002100 ArrayList<ProcessRecord> procs = new ArrayList<>();
2101
2102 // Remove all processes this package may have touched: all with the
2103 // same UID (except for the system or root user), and all whose name
2104 // matches the package name.
2105 final int NP = mProcessNames.getMap().size();
2106 for (int ip = 0; ip < NP; ip++) {
2107 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2108 final int NA = apps.size();
2109 for (int ia = 0; ia < NA; ia++) {
2110 ProcessRecord app = apps.valueAt(ia);
2111 if (app.isPersistent() && !evenPersistent) {
2112 // we don't kill persistent processes
2113 continue;
2114 }
2115 if (app.removed) {
2116 if (doit) {
2117 procs.add(app);
2118 }
2119 continue;
2120 }
2121
2122 // Skip process if it doesn't meet our oom adj requirement.
2123 if (app.setAdj < minOomAdj) {
Riddle Hsu4405d8a2019-03-06 22:09:32 +08002124 // Note it is still possible to have a process with oom adj 0 in the killed
2125 // processes, but it does not mean misjudgment. E.g. a bound service process
2126 // and its client activity process are both in the background, so they are
2127 // collected to be killed. If the client activity is killed first, the service
2128 // may be scheduled to unbind and become an executing service (oom adj 0).
Amith Yamasani98a00922018-08-21 12:50:30 -04002129 continue;
2130 }
2131
2132 // If no package is specified, we call all processes under the
2133 // give user id.
2134 if (packageName == null) {
2135 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2136 continue;
2137 }
2138 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2139 continue;
2140 }
2141 // Package has been specified, we want to hit all processes
2142 // that match it. We need to qualify this by the processes
2143 // that are running under the specified app and user ID.
2144 } else {
2145 final boolean isDep = app.pkgDeps != null
2146 && app.pkgDeps.contains(packageName);
2147 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2148 continue;
2149 }
2150 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2151 continue;
2152 }
2153 if (!app.pkgList.containsKey(packageName) && !isDep) {
2154 continue;
2155 }
2156 }
2157
2158 // Process has passed all conditions, kill it!
2159 if (!doit) {
2160 return true;
2161 }
Riddle Hsuaaef7312019-01-24 19:00:58 +08002162 if (setRemoved) {
2163 app.removed = true;
2164 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002165 procs.add(app);
2166 }
2167 }
2168
2169 int N = procs.size();
2170 for (int i=0; i<N; i++) {
2171 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
2172 }
Martijn Coenen378b2702019-02-20 10:33:41 +01002173 // See if there are any app zygotes running for this packageName / UID combination,
2174 // and kill it if so.
2175 final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2176 for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2177 for (int i = 0; i < appZygotes.size(); ++i) {
2178 final int appZygoteUid = appZygotes.keyAt(i);
2179 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2180 continue;
2181 }
2182 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2183 continue;
2184 }
2185 final AppZygote appZygote = appZygotes.valueAt(i);
2186 if (packageName != null
2187 && !packageName.equals(appZygote.getAppInfo().packageName)) {
2188 continue;
2189 }
2190 zygotesToKill.add(appZygote);
2191 }
2192 }
2193 for (AppZygote appZygote : zygotesToKill) {
2194 killAppZygoteIfNeededLocked(appZygote);
2195 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002196 mService.updateOomAdjLocked();
2197 return N > 0;
2198 }
2199 @GuardedBy("mService")
2200 boolean removeProcessLocked(ProcessRecord app,
2201 boolean callerWillRestart, boolean allowRestart, String reason) {
2202 final String name = app.processName;
2203 final int uid = app.uid;
2204 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
2205 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
2206
2207 ProcessRecord old = mProcessNames.get(name, uid);
2208 if (old != app) {
2209 // This process is no longer active, so nothing to do.
2210 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
2211 return false;
2212 }
2213 removeProcessNameLocked(name, uid);
2214 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
2215
2216 boolean needRestart = false;
2217 if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
2218 .pendingStart)) {
2219 int pid = app.pid;
2220 if (pid > 0) {
Wale Ogunwale0b940842018-12-03 06:58:11 -08002221 mService.mPidsSelfLocked.remove(pid);
2222 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002223 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2224 if (app.isolated) {
2225 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2226 mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
2227 }
2228 }
2229 boolean willRestart = false;
2230 if (app.isPersistent() && !app.isolated) {
2231 if (!callerWillRestart) {
2232 willRestart = true;
2233 } else {
2234 needRestart = true;
2235 }
2236 }
2237 app.kill(reason, true);
2238 mService.handleAppDiedLocked(app, willRestart, allowRestart);
2239 if (willRestart) {
2240 removeLruProcessLocked(app);
2241 mService.addAppLocked(app.info, null, false, null /* ABI override */);
2242 }
2243 } else {
2244 mRemovedProcesses.add(app);
2245 }
2246
2247 return needRestart;
2248 }
2249
2250 @GuardedBy("mService")
2251 final void addProcessNameLocked(ProcessRecord proc) {
2252 // We shouldn't already have a process under this name, but just in case we
2253 // need to clean up whatever may be there now.
2254 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
2255 if (old == proc && proc.isPersistent()) {
2256 // We are re-adding a persistent process. Whatevs! Just leave it there.
2257 Slog.w(TAG, "Re-adding persistent process " + proc);
2258 } else if (old != null) {
2259 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
2260 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08002261 UidRecord uidRec = mActiveUids.get(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002262 if (uidRec == null) {
Riddle Hsud7088f82019-01-30 13:04:50 +08002263 uidRec = new UidRecord(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002264 // This is the first appearance of the uid, report it now!
2265 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2266 "Creating new process uid: " + uidRec);
2267 if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
2268 UserHandle.getAppId(proc.uid)) >= 0
2269 || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
2270 uidRec.setWhitelist = uidRec.curWhitelist = true;
2271 }
2272 uidRec.updateHasInternetPermission();
Amith Yamasaniaa746442019-01-10 10:09:12 -08002273 mActiveUids.put(proc.uid, uidRec);
Amith Yamasani98a00922018-08-21 12:50:30 -04002274 EventLogTags.writeAmUidRunning(uidRec.uid);
Wale Ogunwalebff2df42018-10-18 17:09:19 -07002275 mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
Amith Yamasani98a00922018-08-21 12:50:30 -04002276 }
2277 proc.uidRecord = uidRec;
2278
2279 // Reset render thread tid if it was already set, so new process can set it again.
2280 proc.renderThreadTid = 0;
2281 uidRec.numProcs++;
2282 mProcessNames.put(proc.processName, proc.uid, proc);
2283 if (proc.isolated) {
2284 mIsolatedProcesses.put(proc.uid, proc);
2285 }
2286 }
2287
2288 @GuardedBy("mService")
Martijn Coenen01e719b2018-12-05 16:01:38 +01002289 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
2290 boolean fromAppZygote) {
2291 if (!fromAppZygote) {
2292 // Allocate an isolated UID from the global range
2293 return mGlobalIsolatedUids;
2294 } else {
2295 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(info);
2296 }
2297 }
2298
2299 @GuardedBy("mService")
Amith Yamasani98a00922018-08-21 12:50:30 -04002300 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
Martijn Coenen01e719b2018-12-05 16:01:38 +01002301 boolean isolated, int isolatedUid, boolean fromAppZygote) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002302 String proc = customProcess != null ? customProcess : info.processName;
2303 final int userId = UserHandle.getUserId(info.uid);
2304 int uid = info.uid;
2305 if (isolated) {
2306 if (isolatedUid == 0) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01002307 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, fromAppZygote);
2308 if (uidRange == null) {
2309 return null;
2310 }
2311 uid = uidRange.allocateIsolatedUidLocked(userId);
2312 if (uid == -1) {
2313 return null;
Amith Yamasani98a00922018-08-21 12:50:30 -04002314 }
2315 } else {
2316 // Special case for startIsolatedProcess (internal only), where
2317 // the uid of the isolated process is specified by the caller.
2318 uid = isolatedUid;
2319 }
2320 mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
2321
2322 // Register the isolated UID with this application so BatteryStats knows to
2323 // attribute resource usage to the application.
2324 //
2325 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
2326 // about the process state of the isolated UID *before* it is registered with the
2327 // owning application.
2328 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
2329 StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
2330 StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
2331 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002332 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002333
2334 if (!mService.mBooted && !mService.mBooting
2335 && userId == UserHandle.USER_SYSTEM
2336 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
2337 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
2338 r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
2339 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
2340 r.setPersistent(true);
2341 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
2342 }
2343 if (isolated && isolatedUid != 0) {
2344 // Special case for startIsolatedProcess (internal only) - assume the process
2345 // is required by the system server to prevent it being killed.
2346 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
2347 }
2348 addProcessNameLocked(r);
2349 return r;
2350 }
2351
2352 @GuardedBy("mService")
2353 final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
2354 return removeProcessNameLocked(name, uid, null);
2355 }
2356
2357 @GuardedBy("mService")
2358 final ProcessRecord removeProcessNameLocked(final String name, final int uid,
2359 final ProcessRecord expecting) {
2360 ProcessRecord old = mProcessNames.get(name, uid);
2361 // Only actually remove when the currently recorded value matches the
2362 // record that we expected; if it doesn't match then we raced with a
2363 // newly created process and we don't want to destroy the new one.
2364 if ((expecting == null) || (old == expecting)) {
2365 mProcessNames.remove(name, uid);
2366 }
2367 if (old != null && old.uidRecord != null) {
2368 old.uidRecord.numProcs--;
2369 if (old.uidRecord.numProcs == 0) {
2370 // No more processes using this uid, tell clients it is gone.
2371 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2372 "No more processes in " + old.uidRecord);
2373 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
2374 EventLogTags.writeAmUidStopped(uid);
Amith Yamasaniaa746442019-01-10 10:09:12 -08002375 mActiveUids.remove(uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002376 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
2377 }
2378 old.uidRecord = null;
2379 }
2380 mIsolatedProcesses.remove(uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +01002381 mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002382 // Remove the (expected) ProcessRecord from the app zygote
2383 final ProcessRecord record = expecting != null ? expecting : old;
Martijn Coenen01e719b2018-12-05 16:01:38 +01002384 if (record != null && record.appZygote) {
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002385 removeProcessFromAppZygoteLocked(record);
2386 }
2387
Amith Yamasani98a00922018-08-21 12:50:30 -04002388 return old;
2389 }
2390
2391 /** Call setCoreSettings on all LRU processes, with the new settings. */
2392 @GuardedBy("mService")
2393 void updateCoreSettingsLocked(Bundle settings) {
2394 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2395 ProcessRecord processRecord = mLruProcesses.get(i);
2396 try {
2397 if (processRecord.thread != null) {
2398 processRecord.thread.setCoreSettings(settings);
2399 }
2400 } catch (RemoteException re) {
2401 /* ignore */
2402 }
2403 }
2404 }
2405
2406 /**
2407 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2408 * procstate lower than maxProcState.
2409 * @param minTargetSdk
2410 * @param maxProcState
2411 */
2412 @GuardedBy("mService")
2413 void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2414 final ArrayList<ProcessRecord> procs = new ArrayList<>();
2415 final int NP = mProcessNames.getMap().size();
2416 for (int ip = 0; ip < NP; ip++) {
2417 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2418 final int NA = apps.size();
2419 for (int ia = 0; ia < NA; ia++) {
2420 final ProcessRecord app = apps.valueAt(ia);
Riddle Hsuaaef7312019-01-24 19:00:58 +08002421 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2422 && (maxProcState < 0 || app.setProcState > maxProcState))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002423 procs.add(app);
2424 }
2425 }
2426 }
2427
2428 final int N = procs.size();
2429 for (int i = 0; i < N; i++) {
2430 removeProcessLocked(procs.get(i), false, true, "kill all background except");
2431 }
2432 }
2433
2434 /**
2435 * Call updateTimePrefs on all LRU processes
2436 * @param timePref The time pref to pass to each process
2437 */
2438 @GuardedBy("mService")
2439 void updateAllTimePrefsLocked(int timePref) {
2440 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2441 ProcessRecord r = mLruProcesses.get(i);
2442 if (r.thread != null) {
2443 try {
2444 r.thread.updateTimePrefs(timePref);
2445 } catch (RemoteException ex) {
2446 Slog.w(TAG, "Failed to update preferences for: "
2447 + r.info.processName);
2448 }
2449 }
2450 }
2451 }
2452
2453 @GuardedBy("mService")
Irina Dumitrescu18622d32018-12-05 16:19:47 +00002454 void setAllHttpProxyLocked() {
Amith Yamasani98a00922018-08-21 12:50:30 -04002455 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2456 ProcessRecord r = mLruProcesses.get(i);
2457 // Don't dispatch to isolated processes as they can't access
2458 // ConnectivityManager and don't have network privileges anyway.
2459 if (r.thread != null && !r.isolated) {
2460 try {
Irina Dumitrescu18622d32018-12-05 16:19:47 +00002461 r.thread.updateHttpProxy();
Amith Yamasani98a00922018-08-21 12:50:30 -04002462 } catch (RemoteException ex) {
2463 Slog.w(TAG, "Failed to update http proxy for: " +
2464 r.info.processName);
2465 }
2466 }
2467 }
2468 }
2469
2470 @GuardedBy("mService")
2471 void clearAllDnsCacheLocked() {
2472 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2473 ProcessRecord r = mLruProcesses.get(i);
2474 if (r.thread != null) {
2475 try {
2476 r.thread.clearDnsCache();
2477 } catch (RemoteException ex) {
2478 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2479 }
2480 }
2481 }
2482 }
2483
2484 @GuardedBy("mService")
2485 void handleAllTrustStorageUpdateLocked() {
2486 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2487 ProcessRecord r = mLruProcesses.get(i);
2488 if (r.thread != null) {
2489 try {
2490 r.thread.handleTrustStorageUpdate();
2491 } catch (RemoteException ex) {
2492 Slog.w(TAG, "Failed to handle trust storage update for: " +
2493 r.info.processName);
2494 }
2495 }
2496 }
2497 }
2498
2499 @GuardedBy("mService")
2500 int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
Dianne Hackborna631d562018-11-20 15:58:15 -08002501 int lruSeq, String what, Object obj, ProcessRecord srcApp) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002502 app.lastActivityTime = now;
2503
2504 if (app.hasActivitiesOrRecentTasks()) {
2505 // Don't want to touch dependent processes that are hosting activities.
2506 return index;
2507 }
2508
2509 int lrui = mLruProcesses.lastIndexOf(app);
2510 if (lrui < 0) {
2511 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2512 + what + " " + obj + " from " + srcApp);
2513 return index;
2514 }
2515
2516 if (lrui >= index) {
2517 // Don't want to cause this to move dependent processes *back* in the
2518 // list as if they were less frequently used.
2519 return index;
2520 }
2521
Dianne Hackborna631d562018-11-20 15:58:15 -08002522 if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002523 // Don't want to touch dependent processes that are hosting activities.
2524 return index;
2525 }
2526
2527 mLruProcesses.remove(lrui);
2528 if (index > 0) {
2529 index--;
2530 }
2531 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2532 + " in LRU list: " + app);
2533 mLruProcesses.add(index, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002534 app.lruSeq = lruSeq;
Amith Yamasani98a00922018-08-21 12:50:30 -04002535 return index;
2536 }
2537
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002538 /**
2539 * Handle the case where we are inserting a process hosting client activities:
2540 * Make sure any groups have their order match their importance, and take care of
2541 * distributing old clients across other activity processes so they can't spam
2542 * the LRU list. Processing of the list will be restricted by the indices provided,
2543 * and not extend out of them.
2544 *
2545 * @param topApp The app at the top that has just been inserted in to the list.
2546 * @param topI The position in the list where topApp was inserted; this is the start (at the
2547 * top) where we are going to do our processing.
2548 * @param bottomI The last position at which we will be processing; this is the end position
2549 * of whichever section of the LRU list we are in. Nothing past it will be
2550 * touched.
2551 * @param endIndex The current end of the top being processed. Typically topI - 1. That is,
2552 * where we are going to start potentially adjusting other entries in the list.
2553 */
2554 private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
2555 final int bottomI, int endIndex) {
2556 if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
2557 || !topApp.hasClientActivities()) {
2558 // If this is not a special process that has client activities, then there is
2559 // nothing to do.
2560 return;
2561 }
2562
2563 final int uid = topApp.info.uid;
2564 if (topApp.connectionGroup > 0) {
2565 int endImportance = topApp.connectionImportance;
2566 for (int i = endIndex; i >= bottomI; i--) {
2567 final ProcessRecord subProc = mLruProcesses.get(i);
2568 if (subProc.info.uid == uid
2569 && subProc.connectionGroup == topApp.connectionGroup) {
2570 if (i == endIndex && subProc.connectionImportance >= endImportance) {
2571 // This process is already in the group, and its importance
2572 // is not as strong as the process before it, so keep it
2573 // correctly positioned in the group.
2574 if (DEBUG_LRU) Slog.d(TAG_LRU,
2575 "Keeping in-place above " + subProc
2576 + " endImportance=" + endImportance
2577 + " group=" + subProc.connectionGroup
2578 + " importance=" + subProc.connectionImportance);
2579 endIndex--;
2580 endImportance = subProc.connectionImportance;
2581 } else {
2582 // We want to pull this up to be with the rest of the group,
2583 // and order within the group by importance.
2584 if (DEBUG_LRU) Slog.d(TAG_LRU,
2585 "Pulling up " + subProc
2586 + " to position in group with importance="
2587 + subProc.connectionImportance);
2588 boolean moved = false;
2589 for (int pos = topI; pos > endIndex; pos--) {
2590 final ProcessRecord posProc = mLruProcesses.get(pos);
2591 if (subProc.connectionImportance
2592 <= posProc.connectionImportance) {
2593 mLruProcesses.remove(i);
2594 mLruProcesses.add(pos, subProc);
2595 if (DEBUG_LRU) Slog.d(TAG_LRU,
2596 "Moving " + subProc
2597 + " from position " + i + " to above " + posProc
2598 + " @ " + pos);
2599 moved = true;
2600 endIndex--;
2601 break;
2602 }
2603 }
2604 if (!moved) {
2605 // Goes to the end of the group.
2606 mLruProcesses.remove(i);
2607 mLruProcesses.add(endIndex - 1, subProc);
2608 if (DEBUG_LRU) Slog.d(TAG_LRU,
2609 "Moving " + subProc
2610 + " from position " + i + " to end of group @ "
2611 + endIndex);
2612 endIndex--;
2613 endImportance = subProc.connectionImportance;
2614 }
2615 }
2616 }
2617 }
2618
2619 }
2620 // To keep it from spamming the LRU list (by making a bunch of clients),
2621 // we will distribute other entries owned by it to be in-between other apps.
2622 int i = endIndex;
2623 while (i >= bottomI) {
2624 ProcessRecord subProc = mLruProcesses.get(i);
2625 if (DEBUG_LRU) Slog.d(TAG_LRU,
2626 "Looking to spread old procs, at " + subProc + " @ " + i);
2627 if (subProc.info.uid != uid) {
2628 // This is a different app... if we have gone through some of the
2629 // target app, pull this up to be before them. We want to pull up
2630 // one activity process, but any number of non-activity processes.
2631 if (i < endIndex) {
2632 boolean hasActivity = false;
2633 int connUid = 0;
2634 int connGroup = 0;
2635 while (i >= bottomI) {
2636 mLruProcesses.remove(i);
2637 mLruProcesses.add(endIndex, subProc);
2638 if (DEBUG_LRU) Slog.d(TAG_LRU,
2639 "Different app, moving to " + endIndex);
2640 i--;
2641 if (i < bottomI) {
2642 break;
2643 }
2644 subProc = mLruProcesses.get(i);
2645 if (DEBUG_LRU) Slog.d(TAG_LRU,
2646 "Looking at next app at " + i + ": " + subProc);
2647 if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
2648 if (DEBUG_LRU) Slog.d(TAG_LRU,
2649 "This is hosting an activity!");
2650 if (hasActivity) {
2651 // Already found an activity, done.
2652 if (DEBUG_LRU) Slog.d(TAG_LRU,
2653 "Already found an activity, done");
2654 break;
2655 }
2656 hasActivity = true;
2657 } else if (subProc.hasClientActivities()) {
2658 if (DEBUG_LRU) Slog.d(TAG_LRU,
2659 "This is a client of an activity");
2660 if (hasActivity) {
2661 if (connUid == 0 || connUid != subProc.info.uid) {
2662 // Already have an activity that is not from from a client
2663 // connection or is a different client connection, done.
2664 if (DEBUG_LRU) Slog.d(TAG_LRU,
2665 "Already found a different activity: connUid="
2666 + connUid + " uid=" + subProc.info.uid);
2667 break;
2668 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
2669 // Previously saw a different group or not from a group,
2670 // want to treat these as different things.
2671 if (DEBUG_LRU) Slog.d(TAG_LRU,
2672 "Already found a different group: connGroup="
2673 + connGroup + " group=" + subProc.connectionGroup);
2674 break;
2675 }
2676 } else {
2677 if (DEBUG_LRU) Slog.d(TAG_LRU,
2678 "This is an activity client! uid="
2679 + subProc.info.uid + " group=" + subProc.connectionGroup);
2680 hasActivity = true;
2681 connUid = subProc.info.uid;
2682 connGroup = subProc.connectionGroup;
2683 }
2684 }
2685 endIndex--;
2686 }
2687 }
2688 // Find the end of the next group of processes for target app. This
2689 // is after any entries of different apps (so we don't change the existing
2690 // relative order of apps) and then after the next last group of processes
2691 // of the target app.
2692 for (endIndex--; endIndex >= bottomI; endIndex--) {
2693 final ProcessRecord endProc = mLruProcesses.get(endIndex);
2694 if (endProc.info.uid == uid) {
2695 if (DEBUG_LRU) Slog.d(TAG_LRU,
2696 "Found next group of app: " + endProc + " @ "
2697 + endIndex);
2698 break;
2699 }
2700 }
2701 if (endIndex >= bottomI) {
2702 final ProcessRecord endProc = mLruProcesses.get(endIndex);
2703 for (endIndex--; endIndex >= bottomI; endIndex--) {
2704 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
2705 if (nextEndProc.info.uid != uid
2706 || nextEndProc.connectionGroup != endProc.connectionGroup) {
2707 if (DEBUG_LRU) Slog.d(TAG_LRU,
2708 "Found next group or app: " + nextEndProc + " @ "
2709 + endIndex + " group=" + nextEndProc.connectionGroup);
2710 break;
2711 }
2712 }
2713 }
2714 if (DEBUG_LRU) Slog.d(TAG_LRU,
2715 "Bumping scan position to " + endIndex);
2716 i = endIndex;
2717 } else {
2718 i--;
2719 }
2720 }
2721 }
2722
Amith Yamasani98a00922018-08-21 12:50:30 -04002723 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2724 ProcessRecord client) {
2725 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
2726 || app.treatLikeActivity;
2727 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2728 if (!activityChange && hasActivity) {
2729 // The process has activities, so we are only allowing activity-based adjustments
2730 // to move it. It should be kept in the front of the list with other
2731 // processes that have activities, and we don't want those to change their
2732 // order except due to activity operations.
2733 return;
2734 }
2735
2736 mLruSeq++;
2737 final long now = SystemClock.uptimeMillis();
2738 app.lastActivityTime = now;
2739
2740 // First a quick reject: if the app is already at the position we will
2741 // put it, then there is nothing to do.
2742 if (hasActivity) {
2743 final int N = mLruProcesses.size();
2744 if (N > 0 && mLruProcesses.get(N - 1) == app) {
2745 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2746 return;
2747 }
2748 } else {
2749 if (mLruProcessServiceStart > 0
2750 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2751 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2752 return;
2753 }
2754 }
2755
2756 int lrui = mLruProcesses.lastIndexOf(app);
2757
2758 if (app.isPersistent() && lrui >= 0) {
2759 // We don't care about the position of persistent processes, as long as
2760 // they are in the list.
2761 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2762 return;
2763 }
2764
2765 /* In progress: compute new position first, so we can avoid doing work
2766 if the process is not actually going to move. Not yet working.
2767 int addIndex;
2768 int nextIndex;
2769 boolean inActivity = false, inService = false;
2770 if (hasActivity) {
2771 // Process has activities, put it at the very tipsy-top.
2772 addIndex = mLruProcesses.size();
2773 nextIndex = mLruProcessServiceStart;
2774 inActivity = true;
2775 } else if (hasService) {
2776 // Process has services, put it at the top of the service list.
2777 addIndex = mLruProcessActivityStart;
2778 nextIndex = mLruProcessServiceStart;
2779 inActivity = true;
2780 inService = true;
2781 } else {
2782 // Process not otherwise of interest, it goes to the top of the non-service area.
2783 addIndex = mLruProcessServiceStart;
2784 if (client != null) {
2785 int clientIndex = mLruProcesses.lastIndexOf(client);
2786 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2787 + app);
2788 if (clientIndex >= 0 && addIndex > clientIndex) {
2789 addIndex = clientIndex;
2790 }
2791 }
2792 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2793 }
2794
2795 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2796 + mLruProcessActivityStart + "): " + app);
2797 */
2798
2799 if (lrui >= 0) {
2800 if (lrui < mLruProcessActivityStart) {
2801 mLruProcessActivityStart--;
2802 }
2803 if (lrui < mLruProcessServiceStart) {
2804 mLruProcessServiceStart--;
2805 }
2806 /*
2807 if (addIndex > lrui) {
2808 addIndex--;
2809 }
2810 if (nextIndex > lrui) {
2811 nextIndex--;
2812 }
2813 */
2814 mLruProcesses.remove(lrui);
2815 }
2816
2817 /*
2818 mLruProcesses.add(addIndex, app);
2819 if (inActivity) {
2820 mLruProcessActivityStart++;
2821 }
2822 if (inService) {
2823 mLruProcessActivityStart++;
2824 }
2825 */
2826
2827 int nextIndex;
Dianne Hackborna631d562018-11-20 15:58:15 -08002828 int nextActivityIndex = -1;
Amith Yamasani98a00922018-08-21 12:50:30 -04002829 if (hasActivity) {
2830 final int N = mLruProcesses.size();
Dianne Hackborna631d562018-11-20 15:58:15 -08002831 nextIndex = mLruProcessServiceStart;
2832 if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
Amith Yamasani98a00922018-08-21 12:50:30 -04002833 && mLruProcessActivityStart < (N - 1)) {
2834 // Process doesn't have activities, but has clients with
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002835 // activities... move it up, but below the app that is binding to it.
Amith Yamasani98a00922018-08-21 12:50:30 -04002836 if (DEBUG_LRU) Slog.d(TAG_LRU,
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002837 "Adding to second-top of LRU activity list: " + app
2838 + " group=" + app.connectionGroup
2839 + " importance=" + app.connectionImportance);
2840 int pos = N - 1;
2841 while (pos > mLruProcessActivityStart) {
2842 final ProcessRecord posproc = mLruProcesses.get(pos);
2843 if (posproc.info.uid == app.info.uid) {
2844 // Technically this app could have multiple processes with different
2845 // activities and so we should be looking for the actual process that
2846 // is bound to the target proc... but I don't really care, do you?
2847 break;
2848 }
2849 pos--;
2850 }
2851 mLruProcesses.add(pos, app);
Riddle Hsu282cf6e2019-03-05 23:18:13 +08002852 if (pos == mLruProcessActivityStart) {
2853 mLruProcessActivityStart++;
2854 }
2855 if (pos == mLruProcessServiceStart) {
2856 // Unless {@code #hasService} is implemented, currently the starting position
2857 // for activity and service are the same, so the incoming position may equal to
2858 // the starting position of service.
2859 mLruProcessServiceStart++;
2860 }
Dianne Hackborna631d562018-11-20 15:58:15 -08002861 // If this process is part of a group, need to pull up any other processes
2862 // in that group to be with it.
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002863 int endIndex = pos - 1;
2864 if (endIndex < mLruProcessActivityStart) {
2865 endIndex = mLruProcessActivityStart;
Dianne Hackborna631d562018-11-20 15:58:15 -08002866 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002867 nextActivityIndex = endIndex;
2868 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
Amith Yamasani98a00922018-08-21 12:50:30 -04002869 } else {
2870 // Process has activities, put it at the very tipsy-top.
2871 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2872 mLruProcesses.add(app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002873 nextActivityIndex = mLruProcesses.size() - 1;
Amith Yamasani98a00922018-08-21 12:50:30 -04002874 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002875 } else if (hasService) {
2876 // Process has services, put it at the top of the service list.
2877 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2878 mLruProcesses.add(mLruProcessActivityStart, app);
2879 nextIndex = mLruProcessServiceStart;
2880 mLruProcessActivityStart++;
2881 } else {
2882 // Process not otherwise of interest, it goes to the top of the non-service area.
2883 int index = mLruProcessServiceStart;
2884 if (client != null) {
2885 // If there is a client, don't allow the process to be moved up higher
2886 // in the list than that client.
2887 int clientIndex = mLruProcesses.lastIndexOf(client);
2888 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2889 + " when updating " + app);
2890 if (clientIndex <= lrui) {
2891 // Don't allow the client index restriction to push it down farther in the
2892 // list than it already is.
2893 clientIndex = lrui;
2894 }
2895 if (clientIndex >= 0 && index > clientIndex) {
2896 index = clientIndex;
2897 }
2898 }
2899 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2900 mLruProcesses.add(index, app);
2901 nextIndex = index - 1;
2902 mLruProcessActivityStart++;
2903 mLruProcessServiceStart++;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002904 if (index > 1) {
2905 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
2906 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002907 }
2908
Dianne Hackborna631d562018-11-20 15:58:15 -08002909 app.lruSeq = mLruSeq;
2910
Amith Yamasani98a00922018-08-21 12:50:30 -04002911 // If the app is currently using a content provider or service,
2912 // bump those processes as well.
2913 for (int j = app.connections.size() - 1; j >= 0; j--) {
2914 ConnectionRecord cr = app.connections.valueAt(j);
2915 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2916 && cr.binding.service.app != null
2917 && cr.binding.service.app.lruSeq != mLruSeq
Dianne Hackborna631d562018-11-20 15:58:15 -08002918 && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
Amith Yamasani98a00922018-08-21 12:50:30 -04002919 && !cr.binding.service.app.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08002920 if (cr.binding.service.app.hasClientActivities()) {
2921 if (nextActivityIndex >= 0) {
2922 nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2923 now,
2924 nextActivityIndex, mLruSeq,
2925 "service connection", cr, app);
2926 }
2927 } else {
2928 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2929 now,
2930 nextIndex, mLruSeq,
2931 "service connection", cr, app);
2932 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002933 }
2934 }
2935 for (int j = app.conProviders.size() - 1; j >= 0; j--) {
2936 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2937 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08002938 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
Amith Yamasani98a00922018-08-21 12:50:30 -04002939 "provider reference", cpr, app);
2940 }
2941 }
2942 }
2943
2944 final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
2945 final IBinder threadBinder = thread.asBinder();
2946 // Find the application record.
2947 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2948 final ProcessRecord rec = mLruProcesses.get(i);
2949 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2950 return rec;
2951 }
2952 }
2953 return null;
2954 }
2955
2956 boolean haveBackgroundProcessLocked() {
2957 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2958 final ProcessRecord rec = mLruProcesses.get(i);
2959 if (rec.thread != null
2960 && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
2961 return true;
2962 }
2963 }
2964 return false;
2965 }
2966
2967 private static int procStateToImportance(int procState, int memAdj,
2968 ActivityManager.RunningAppProcessInfo currApp,
2969 int clientTargetSdk) {
2970 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
2971 procState, clientTargetSdk);
2972 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
2973 currApp.lru = memAdj;
2974 } else {
2975 currApp.lru = 0;
2976 }
2977 return imp;
2978 }
2979
2980 @GuardedBy("mService")
2981 void fillInProcMemInfoLocked(ProcessRecord app,
2982 ActivityManager.RunningAppProcessInfo outInfo,
2983 int clientTargetSdk) {
2984 outInfo.pid = app.pid;
2985 outInfo.uid = app.info.uid;
2986 if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
2987 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
2988 }
2989 if (app.isPersistent()) {
2990 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
2991 }
2992 if (app.hasActivities()) {
2993 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
2994 }
2995 outInfo.lastTrimLevel = app.trimMemoryLevel;
2996 int adj = app.curAdj;
2997 int procState = app.getCurProcState();
2998 outInfo.importance = procStateToImportance(procState, adj, outInfo,
2999 clientTargetSdk);
3000 outInfo.importanceReasonCode = app.adjTypeCode;
3001 outInfo.processState = app.getCurProcState();
3002 outInfo.isFocused = (app == mService.getTopAppLocked());
3003 outInfo.lastActivityTime = app.lastActivityTime;
3004 }
3005
3006 @GuardedBy("mService")
3007 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
3008 int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3009 // Lazy instantiation of list
3010 List<ActivityManager.RunningAppProcessInfo> runList = null;
3011
3012 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3013 ProcessRecord app = mLruProcesses.get(i);
3014 if ((!allUsers && app.userId != userId)
3015 || (!allUids && app.uid != callingUid)) {
3016 continue;
3017 }
3018 if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
3019 // Generate process state info for running application
3020 ActivityManager.RunningAppProcessInfo currApp =
3021 new ActivityManager.RunningAppProcessInfo(app.processName,
3022 app.pid, app.getPackageList());
3023 fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
3024 if (app.adjSource instanceof ProcessRecord) {
3025 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
3026 currApp.importanceReasonImportance =
3027 ActivityManager.RunningAppProcessInfo.procStateToImportance(
3028 app.adjSourceProcState);
Wale Ogunwale59507092018-10-29 09:00:30 -07003029 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
3030 final ActivityServiceConnectionsHolder r =
3031 (ActivityServiceConnectionsHolder) app.adjSource;
3032 final int pid = r.getActivityPid();
3033 if (pid != -1) {
3034 currApp.importanceReasonPid = pid;
3035 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003036 }
3037 if (app.adjTarget instanceof ComponentName) {
3038 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
3039 }
3040 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
3041 // + " lru=" + currApp.lru);
3042 if (runList == null) {
3043 runList = new ArrayList<>();
3044 }
3045 runList.add(currApp);
3046 }
3047 }
3048 return runList;
3049 }
3050
3051 @GuardedBy("mService")
3052 int getLruSizeLocked() {
3053 return mLruProcesses.size();
3054 }
3055
3056 @GuardedBy("mService")
3057 void dumpLruListHeaderLocked(PrintWriter pw) {
3058 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
3059 pw.print(" total, non-act at ");
3060 pw.print(mLruProcesses.size() - mLruProcessActivityStart);
3061 pw.print(", non-svc at ");
3062 pw.print(mLruProcesses.size() - mLruProcessServiceStart);
3063 pw.println("):");
3064 }
3065
3066 @GuardedBy("mService")
3067 ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
3068 ArrayList<ProcessRecord> procs;
3069 if (args != null && args.length > start
3070 && args[start].charAt(0) != '-') {
3071 procs = new ArrayList<ProcessRecord>();
3072 int pid = -1;
3073 try {
3074 pid = Integer.parseInt(args[start]);
3075 } catch (NumberFormatException e) {
3076 }
3077 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3078 ProcessRecord proc = mLruProcesses.get(i);
3079 if (proc.pid > 0 && proc.pid == pid) {
3080 procs.add(proc);
3081 } else if (allPkgs && proc.pkgList != null
3082 && proc.pkgList.containsKey(args[start])) {
3083 procs.add(proc);
3084 } else if (proc.processName.equals(args[start])) {
3085 procs.add(proc);
3086 }
3087 }
3088 if (procs.size() <= 0) {
3089 return null;
3090 }
3091 } else {
3092 procs = new ArrayList<ProcessRecord>(mLruProcesses);
3093 }
3094 return procs;
3095 }
3096
3097 @GuardedBy("mService")
3098 void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3099 boolean updateFrameworkRes) {
3100 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3101 final ProcessRecord app = mLruProcesses.get(i);
3102 if (app.thread == null) {
3103 continue;
3104 }
3105
3106 if (userId != UserHandle.USER_ALL && app.userId != userId) {
3107 continue;
3108 }
3109
3110 final int packageCount = app.pkgList.size();
3111 for (int j = 0; j < packageCount; j++) {
3112 final String packageName = app.pkgList.keyAt(j);
3113 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
3114 try {
3115 final ApplicationInfo ai = AppGlobals.getPackageManager()
3116 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3117 if (ai != null) {
3118 app.thread.scheduleApplicationInfoChanged(ai);
3119 }
3120 } catch (RemoteException e) {
3121 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3122 packageName, app));
3123 }
3124 }
3125 }
3126 }
3127 }
3128
3129 @GuardedBy("mService")
3130 void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
3131 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3132 ProcessRecord r = mLruProcesses.get(i);
3133 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3134 try {
3135 r.thread.dispatchPackageBroadcast(cmd, packages);
3136 } catch (RemoteException ex) {
3137 }
3138 }
3139 }
3140 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08003141
3142 /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3143 @GuardedBy("mService")
3144 int getUidProcStateLocked(int uid) {
3145 UidRecord uidRec = mActiveUids.get(uid);
3146 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3147 }
3148
3149 /** Returns the UidRecord for the given uid, if it exists. */
3150 @GuardedBy("mService")
3151 UidRecord getUidRecordLocked(int uid) {
3152 return mActiveUids.get(uid);
3153 }
3154
3155 /**
3156 * Call {@link ActivityManagerService#doStopUidLocked}
3157 * (which will also stop background services) for all idle UIDs.
3158 */
3159 @GuardedBy("mService")
3160 void doStopUidForIdleUidsLocked() {
3161 final int size = mActiveUids.size();
3162 for (int i = 0; i < size; i++) {
3163 final int uid = mActiveUids.keyAt(i);
3164 if (UserHandle.isCore(uid)) {
3165 continue;
3166 }
3167 final UidRecord uidRec = mActiveUids.valueAt(i);
3168 if (!uidRec.idle) {
3169 continue;
3170 }
3171 mService.doStopUidLocked(uidRec.uid, uidRec);
3172 }
3173 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07003174}