blob: a2670d8dd4248754354624f040150d55cfb6b387 [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;
Irina Dumitrescu34a27c42019-04-15 19:20:38 +010049import android.app.ActivityThread;
Amith Yamasani98a00922018-08-21 12:50:30 -040050import android.app.AppGlobals;
Bookatzdb026a22018-01-10 19:01:56 -080051import android.app.AppProtoEnums;
Amith Yamasani98a00922018-08-21 12:50:30 -040052import android.app.IApplicationThread;
53import android.content.ComponentName;
Dianne Hackborna631d562018-11-20 15:58:15 -080054import android.content.Context;
Amith Yamasani98a00922018-08-21 12:50:30 -040055import android.content.Intent;
56import android.content.pm.ApplicationInfo;
57import android.content.pm.IPackageManager;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070058import android.content.res.Resources;
59import android.graphics.Point;
60import android.net.LocalSocket;
61import android.net.LocalSocketAddress;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010062import android.os.AppZygote;
Amith Yamasani98a00922018-08-21 12:50:30 -040063import android.os.Binder;
Dianne Hackborn9d52f792014-09-11 17:46:06 -070064import android.os.Build;
Amith Yamasani98a00922018-08-21 12:50:30 -040065import android.os.Bundle;
Amith Yamasani98a00922018-08-21 12:50:30 -040066import android.os.Handler;
67import android.os.IBinder;
68import android.os.Looper;
69import android.os.Message;
70import android.os.Process;
71import android.os.RemoteException;
72import android.os.StrictMode;
Dianne Hackbornecf1cda2014-08-28 16:58:28 -070073import android.os.SystemClock;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070074import android.os.SystemProperties;
75import android.os.Trace;
76import android.os.UserHandle;
Jeff Sharkey10ec9d82018-11-28 14:52:45 -070077import android.os.storage.StorageManager;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070078import android.os.storage.StorageManagerInternal;
79import android.text.TextUtils;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010080import android.util.ArrayMap;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070081import android.util.EventLog;
82import android.util.LongSparseArray;
83import android.util.Slog;
84import android.util.SparseArray;
Martijn Coenen01e719b2018-12-05 16:01:38 +010085import android.util.SparseBooleanArray;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070086import android.util.StatsLog;
87import android.view.Display;
Amith Yamasani98a00922018-08-21 12:50:30 -040088
89import com.android.internal.annotations.GuardedBy;
90import com.android.internal.annotations.VisibleForTesting;
91import com.android.internal.app.ProcessMap;
92import com.android.internal.app.procstats.ProcessStats;
93import com.android.internal.os.Zygote;
94import com.android.internal.util.ArrayUtils;
Dianne Hackborn7d608422011-08-07 16:24:18 -070095import com.android.internal.util.MemInfoReader;
Amith Yamasani98a00922018-08-21 12:50:30 -040096import com.android.server.LocalServices;
97import com.android.server.ServiceThread;
98import com.android.server.Watchdog;
99import com.android.server.pm.dex.DexManager;
Wale Ogunwale59507092018-10-29 09:00:30 -0700100import com.android.server.wm.ActivityServiceConnectionsHolder;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700101import com.android.server.wm.WindowManagerService;
102
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700103import dalvik.system.VMRuntime;
104
Sudheer Shanka87915d62018-11-06 10:57:35 -0800105import libcore.io.IoUtils;
106
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700107import java.io.File;
108import java.io.IOException;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700109import java.io.InputStream;
Sudheer Shanka87915d62018-11-06 10:57:35 -0800110import java.io.OutputStream;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700111import java.io.PrintWriter;
112import java.nio.ByteBuffer;
113import java.util.ArrayList;
114import java.util.Arrays;
Martijn Coenen01e719b2018-12-05 16:01:38 +0100115import java.util.BitSet;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700116import java.util.List;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700117
118/**
119 * Activity manager code dealing with processes.
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700120 *
121 * Method naming convention:
122 * <ul>
123 * <li> Methods suffixed with "LS" should be called within the {@link #sLmkdSocketLock} lock.
124 * </ul>
Dianne Hackborn7d608422011-08-07 16:24:18 -0700125 */
Sudheer Shanka352dc572017-09-22 17:09:38 -0700126public final class ProcessList {
Amith Yamasaniaa746442019-01-10 10:09:12 -0800127 static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800128
Dianne Hackborn7d608422011-08-07 16:24:18 -0700129 // The minimum time we allow between crashes, for us to consider this
130 // application to be bad and stop and its services and reject broadcasts.
Amith Yamasani98a00922018-08-21 12:50:30 -0400131 static final int MIN_CRASH_INTERVAL = 60 * 1000;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700132
133 // OOM adjustments for processes in various states:
134
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700135 // Uninitialized value for any major or minor adj fields
136 static final int INVALID_ADJ = -10000;
137
Dianne Hackbornc8230512013-07-13 21:32:12 -0700138 // Adjustment used in certain places where we don't know it yet.
139 // (Generally this is something that is going to be cached, but we
140 // don't know the exact value in the cached range to assign yet.)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700141 static final int UNKNOWN_ADJ = 1001;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700142
Dianne Hackborn7d608422011-08-07 16:24:18 -0700143 // This is a process only hosting activities that are not visible,
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700144 // so it can be killed without any disruption.
Dianne Hackbornb446ce52018-12-10 16:44:35 -0800145 static final int CACHED_APP_MAX_ADJ = 999;
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700146 static final int CACHED_APP_MIN_ADJ = 900;
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700147
Tim Murray0d42abe2019-01-23 09:54:15 -0800148 // This is the oom_adj level that we allow to die first. This cannot be equal to
149 // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
150 // CACHED_APP_MAX_ADJ.
151 static final int CACHED_APP_LMK_FIRST_ADJ = 950;
152
Dianne Hackbornb446ce52018-12-10 16:44:35 -0800153 // Number of levels we have available for different service connection group importance
154 // levels.
155 static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
156
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700157 // The B list of SERVICE_ADJ -- these are the old and decrepit
158 // services that aren't as shiny and interesting as the ones in the A list.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700159 static final int SERVICE_B_ADJ = 800;
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700160
161 // This is the process of the previous application that the user was in.
162 // This process is kept above other things, because it is very common to
163 // switch back to the previous app. This is important both for recent
164 // task switch (toggling between the two top recent apps) as well as normal
165 // UI flow such as clicking on a URI in the e-mail app to view in the browser,
166 // and then pressing back to return to e-mail.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700167 static final int PREVIOUS_APP_ADJ = 700;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700168
169 // This is a process holding the home application -- we want to try
170 // avoiding killing it, even if it would normally be in the background,
171 // because the user interacts with it so much.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700172 static final int HOME_APP_ADJ = 600;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700173
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700174 // This is a process holding an application service -- killing it will not
175 // have much of an impact as far as the user is concerned.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700176 static final int SERVICE_ADJ = 500;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700177
Dianne Hackborn7d608422011-08-07 16:24:18 -0700178 // This is a process with a heavy-weight application. It is in the
179 // background, but we want to try to avoid killing it. Value set in
180 // system/rootdir/init.rc on startup.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700181 static final int HEAVY_WEIGHT_APP_ADJ = 400;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700182
183 // This is a process currently hosting a backup operation. Killing it
184 // is not entirely fatal but is generally a bad idea.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700185 static final int BACKUP_APP_ADJ = 300;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700186
Amith Yamasani5016a782019-06-17 16:20:24 -0700187 // This is a process bound by the system (or other app) that's more important than services but
188 // not so perceptible that it affects the user immediately if killed.
Amith Yamasani0567ec62019-01-23 11:11:02 -0800189 static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
190
Dianne Hackborn7d608422011-08-07 16:24:18 -0700191 // This is a process only hosting components that are perceptible to the
192 // user, and we really want to avoid killing them, but they are not
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700193 // immediately visible. An example is background music playback.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700194 static final int PERCEPTIBLE_APP_ADJ = 200;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700195
196 // This is a process only hosting activities that are visible to the
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700197 // user, so we'd prefer they don't disappear.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700198 static final int VISIBLE_APP_ADJ = 100;
199 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700200
Amith Yamasanib7358302018-09-05 18:52:35 -0700201 // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
202 // like a foreground app for a while.
203 // @see TOP_TO_FGS_GRACE_PERIOD
204 static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
205
Dianne Hackborn7d608422011-08-07 16:24:18 -0700206 // This is the process running the current foreground app. We'd really
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700207 // rather not kill it!
Dianne Hackborn7d608422011-08-07 16:24:18 -0700208 static final int FOREGROUND_APP_ADJ = 0;
209
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700210 // This is a process that the system or a persistent process has bound to,
211 // and indicated it is important.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700212 static final int PERSISTENT_SERVICE_ADJ = -700;
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700213
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700214 // This is a system persistent process, such as telephony. Definitely
Dianne Hackborn7d608422011-08-07 16:24:18 -0700215 // don't want to kill it, but doing so is not completely fatal.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700216 static final int PERSISTENT_PROC_ADJ = -800;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700217
218 // The system process runs at the default adjustment.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700219 static final int SYSTEM_ADJ = -900;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700220
Dianne Hackborn8e692572013-09-10 19:06:15 -0700221 // Special code for native processes that are not being managed by the system (so
222 // don't have an oom adj assigned by the system).
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700223 static final int NATIVE_ADJ = -1000;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700224
Dianne Hackborn7d608422011-08-07 16:24:18 -0700225 // Memory pages are 4K.
Amith Yamasani98a00922018-08-21 12:50:30 -0400226 static final int PAGE_SIZE = 4 * 1024;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700227
Dianne Hackborna49ad092016-03-03 13:39:10 -0800228 // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
229 static final int SCHED_GROUP_BACKGROUND = 0;
Tim Murrayfef10a42018-04-13 10:15:17 -0700230 // Activity manager's version of Process.THREAD_GROUP_RESTRICTED
231 static final int SCHED_GROUP_RESTRICTED = 1;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800232 // Activity manager's version of Process.THREAD_GROUP_DEFAULT
Tim Murrayfef10a42018-04-13 10:15:17 -0700233 static final int SCHED_GROUP_DEFAULT = 2;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800234 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
Wale Ogunwale59507092018-10-29 09:00:30 -0700235 public static final int SCHED_GROUP_TOP_APP = 3;
Tim Murray33eb07f2016-06-10 10:03:20 -0700236 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
237 // Disambiguate between actual top app and processes bound to the top app
Tim Murrayfef10a42018-04-13 10:15:17 -0700238 static final int SCHED_GROUP_TOP_APP_BOUND = 4;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800239
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700240 // The minimum number of cached apps we want to be able to keep around,
Dianne Hackborn7d608422011-08-07 16:24:18 -0700241 // without empty apps being able to push them out of memory.
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700242 static final int MIN_CACHED_APPS = 2;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700243
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700244 // We allow empty processes to stick around for at most 30 minutes.
Amith Yamasani98a00922018-08-21 12:50:30 -0400245 static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700246
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700247 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700248 static final int TRIM_CRITICAL_THRESHOLD = 3;
249
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700250 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700251 static final int TRIM_LOW_THRESHOLD = 5;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700252
Mathieu Chartier77bd1232019-03-05 13:53:11 -0800253 // If true, then we pass the flag to ART to load the app image startup cache.
254 private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
255 "persist.device_config.runtime_native.use_app_image_startup_cache";
256
Todd Poynorbfdd6232013-07-10 19:15:07 -0700257 // Low Memory Killer Daemon command codes.
258 // These must be kept in sync with the definitions in lmkd.c
259 //
260 // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700261 // LMK_PROCPRIO <pid> <uid> <prio>
Todd Poynorbfdd6232013-07-10 19:15:07 -0700262 // LMK_PROCREMOVE <pid>
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -0700263 // LMK_PROCPURGE
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700264 // LMK_GETKILLCNT
Todd Poynorbfdd6232013-07-10 19:15:07 -0700265 static final byte LMK_TARGET = 0;
266 static final byte LMK_PROCPRIO = 1;
267 static final byte LMK_PROCREMOVE = 2;
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -0700268 static final byte LMK_PROCPURGE = 3;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700269 static final byte LMK_GETKILLCNT = 4;
Todd Poynorbfdd6232013-07-10 19:15:07 -0700270
Amith Yamasani98a00922018-08-21 12:50:30 -0400271 ActivityManagerService mService = null;
272
273 // To kill process groups asynchronously
274 static KillHandler sKillHandler = null;
275 static ServiceThread sKillThread = null;
276
Dianne Hackborn7d608422011-08-07 16:24:18 -0700277 // These are the various interesting memory levels that we will give to
278 // the OOM killer. Note that the OOM killer only supports 6 slots, so we
279 // can't give it a different value for every possible kind of process.
280 private final int[] mOomAdj = new int[] {
281 FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
Amith Yamasani5016a782019-06-17 16:20:24 -0700282 PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
Dianne Hackborn7d608422011-08-07 16:24:18 -0700283 };
284 // These are the low-end OOM level limits. This is appropriate for an
285 // HVGA or smaller phone with less than 512MB. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700286 private final int[] mOomMinFreeLow = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700287 12288, 18432, 24576,
288 36864, 43008, 49152
Dianne Hackborn7d608422011-08-07 16:24:18 -0700289 };
290 // These are the high-end OOM level limits. This is appropriate for a
291 // 1280x800 or larger screen with around 1GB RAM. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700292 private final int[] mOomMinFreeHigh = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700293 73728, 92160, 110592,
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800294 129024, 147456, 184320
Dianne Hackborn7d608422011-08-07 16:24:18 -0700295 };
296 // The actual OOM killer memory levels we are using.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700297 private final int[] mOomMinFree = new int[mOomAdj.length];
Dianne Hackborn7d608422011-08-07 16:24:18 -0700298
299 private final long mTotalMemMb;
300
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700301 private long mCachedRestoreLevel;
302
Dianne Hackborn7d608422011-08-07 16:24:18 -0700303 private boolean mHaveDisplaySize;
304
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700305 private static Object sLmkdSocketLock = new Object();
306
307 @GuardedBy("sLmkdSocketLock")
Todd Poynorbfdd6232013-07-10 19:15:07 -0700308 private static LocalSocket sLmkdSocket;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700309
310 @GuardedBy("sLmkdSocketLock")
Todd Poynorbfdd6232013-07-10 19:15:07 -0700311 private static OutputStream sLmkdOutputStream;
312
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700313 @GuardedBy("sLmkdSocketLock")
314 private static InputStream sLmkdInputStream;
315
Amith Yamasani98a00922018-08-21 12:50:30 -0400316 /**
317 * Temporary to avoid allocations. Protected by main lock.
318 */
319 @GuardedBy("mService")
320 final StringBuilder mStringBuilder = new StringBuilder(256);
321
322 /**
323 * A global counter for generating sequence numbers.
324 * This value will be used when incrementing sequence numbers in individual uidRecords.
325 *
326 * Having a global counter ensures that seq numbers are monotonically increasing for a
327 * particular uid even when the uidRecord is re-created.
328 */
329 @GuardedBy("mService")
330 @VisibleForTesting
331 long mProcStateSeqCounter = 0;
332
333 /**
334 * A global counter for generating sequence numbers to uniquely identify pending process starts.
335 */
336 @GuardedBy("mService")
337 private long mProcStartSeqCounter = 0;
338
339 /**
340 * Contains {@link ProcessRecord} objects for pending process starts.
341 *
342 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
343 */
344 @GuardedBy("mService")
345 final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
346
347 /**
348 * List of running applications, sorted by recent usage.
349 * The first entry in the list is the least recently used.
350 */
351 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
352
353 /**
354 * Where in mLruProcesses that the processes hosting activities start.
355 */
356 int mLruProcessActivityStart = 0;
357
358 /**
359 * Where in mLruProcesses that the processes hosting services start.
360 * This is after (lower index) than mLruProcessesActivityStart.
361 */
362 int mLruProcessServiceStart = 0;
363
364 /**
365 * Current sequence id for process LRU updating.
366 */
367 int mLruSeq = 0;
368
Amith Yamasaniaa746442019-01-10 10:09:12 -0800369 ActiveUids mActiveUids;
370
Amith Yamasani98a00922018-08-21 12:50:30 -0400371 /**
372 * The currently running isolated processes.
373 */
374 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
375
376 /**
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100377 * The currently running application zygotes.
378 */
379 final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
380
381 /**
382 * The processes that are forked off an application zygote.
383 */
384 final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses =
385 new ArrayMap<AppZygote, ArrayList<ProcessRecord>>();
386
Martijn Coenen01e719b2018-12-05 16:01:38 +0100387 final class IsolatedUidRange {
388 @VisibleForTesting
389 public final int mFirstUid;
390 @VisibleForTesting
391 public final int mLastUid;
392
393 @GuardedBy("ProcessList.this.mService")
394 private final SparseBooleanArray mUidUsed = new SparseBooleanArray();
395
396 @GuardedBy("ProcessList.this.mService")
397 private int mNextUid;
398
399 IsolatedUidRange(int firstUid, int lastUid) {
400 mFirstUid = firstUid;
401 mLastUid = lastUid;
402 mNextUid = firstUid;
403 }
404
405 @GuardedBy("ProcessList.this.mService")
406 int allocateIsolatedUidLocked(int userId) {
407 int uid;
408 int stepsLeft = (mLastUid - mFirstUid + 1);
409 for (int i = 0; i < stepsLeft; ++i) {
410 if (mNextUid < mFirstUid || mNextUid > mLastUid) {
411 mNextUid = mFirstUid;
412 }
413 uid = UserHandle.getUid(userId, mNextUid);
414 mNextUid++;
415 if (!mUidUsed.get(uid, false)) {
416 mUidUsed.put(uid, true);
417 return uid;
418 }
419 }
420 return -1;
421 }
422
423 @GuardedBy("ProcessList.this.mService")
424 void freeIsolatedUidLocked(int uid) {
425 // Strip out userId
426 final int appId = UserHandle.getAppId(uid);
427 mUidUsed.delete(appId);
428 }
429 };
430
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100431 /**
Martijn Coenen01e719b2018-12-05 16:01:38 +0100432 * A class that allocates ranges of isolated UIDs per application, and keeps track of them.
Amith Yamasani98a00922018-08-21 12:50:30 -0400433 */
Martijn Coenen01e719b2018-12-05 16:01:38 +0100434 final class IsolatedUidRangeAllocator {
435 private final int mFirstUid;
436 private final int mNumUidRanges;
437 private final int mNumUidsPerRange;
438 /**
439 * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange)
440 * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that.
441 */
442 @GuardedBy("ProcessList.this.mService")
443 private final BitSet mAvailableUidRanges;
444 @GuardedBy("ProcessList.this.mService")
445 private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>();
446
447 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) {
448 mFirstUid = firstUid;
449 mNumUidsPerRange = numUidsPerRange;
450 mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange;
451 mAvailableUidRanges = new BitSet(mNumUidRanges);
452 // Mark all as available
453 mAvailableUidRanges.set(0, mNumUidRanges);
454 }
455
456 @GuardedBy("ProcessList.this.mService")
Martijn Coenen572ed7f2019-03-28 19:50:44 +0100457 IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) {
458 return mAppRanges.get(processName, uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +0100459 }
460
461 @GuardedBy("ProcessList.this.mService")
Martijn Coenen572ed7f2019-03-28 19:50:44 +0100462 IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) {
463 IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +0100464 if (range == null) {
465 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
466 if (uidRangeIndex < 0) {
467 // No free range
468 return null;
469 }
470 mAvailableUidRanges.clear(uidRangeIndex);
471 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
472 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
Martijn Coenen572ed7f2019-03-28 19:50:44 +0100473 mAppRanges.put(processName, uid, range);
Martijn Coenen01e719b2018-12-05 16:01:38 +0100474 }
475 return range;
476 }
477
478 @GuardedBy("ProcessList.this.mService")
479 void freeUidRangeLocked(ApplicationInfo info) {
480 // Find the UID range
481 IsolatedUidRange range = mAppRanges.get(info.processName, info.uid);
482 if (range != null) {
483 // Map back to starting uid
484 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange;
485 // Mark it as available in the underlying bitset
486 mAvailableUidRanges.set(uidRangeIndex);
487 // And the map
488 mAppRanges.remove(info.processName, info.uid);
489 }
490 }
491 }
492
493 /**
494 * The available isolated UIDs for processes that are not spawned from an application zygote.
495 */
496 @VisibleForTesting
497 IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID,
498 Process.LAST_ISOLATED_UID);
499
500 /**
501 * An allocator for isolated UID ranges for apps that use an application zygote.
502 */
503 @VisibleForTesting
504 IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator =
505 new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
506 Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE);
Amith Yamasani98a00922018-08-21 12:50:30 -0400507
508 /**
509 * Processes that are being forcibly torn down.
510 */
511 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
512
513 /**
514 * All of the applications we currently have running organized by name.
515 * The keys are strings of the application package name (as
516 * returned by the package manager), and the keys are ApplicationRecord
517 * objects.
518 */
519 final MyProcessMap mProcessNames = new MyProcessMap();
520
521 final class MyProcessMap extends ProcessMap<ProcessRecord> {
522 @Override
523 public ProcessRecord put(String name, int uid, ProcessRecord value) {
524 final ProcessRecord r = super.put(name, uid, value);
525 mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());
526 return r;
527 }
528
529 @Override
530 public ProcessRecord remove(String name, int uid) {
531 final ProcessRecord r = super.remove(name, uid);
532 mService.mAtmInternal.onProcessRemoved(name, uid);
533 return r;
534 }
535 }
536
537 final class KillHandler extends Handler {
538 static final int KILL_PROCESS_GROUP_MSG = 4000;
539
540 public KillHandler(Looper looper) {
541 super(looper, null, true);
542 }
543
544 @Override
545 public void handleMessage(Message msg) {
546 switch (msg.what) {
547 case KILL_PROCESS_GROUP_MSG:
548 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
549 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
550 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
551 break;
552
553 default:
554 super.handleMessage(msg);
555 }
556 }
557 }
558
559 //////////////////// END FIELDS ////////////////////
560
Dianne Hackborn7d608422011-08-07 16:24:18 -0700561 ProcessList() {
562 MemInfoReader minfo = new MemInfoReader();
563 minfo.readMemInfo();
564 mTotalMemMb = minfo.getTotalSize()/(1024*1024);
565 updateOomLevels(0, 0, false);
566 }
567
Amith Yamasaniaa746442019-01-10 10:09:12 -0800568 void init(ActivityManagerService service, ActiveUids activeUids) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400569 mService = service;
Amith Yamasaniaa746442019-01-10 10:09:12 -0800570 mActiveUids = activeUids;
571
Amith Yamasani98a00922018-08-21 12:50:30 -0400572 if (sKillHandler == null) {
573 sKillThread = new ServiceThread(TAG + ":kill",
574 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
575 sKillThread.start();
576 sKillHandler = new KillHandler(sKillThread.getLooper());
577 }
578 }
579
Dianne Hackborn7d608422011-08-07 16:24:18 -0700580 void applyDisplaySize(WindowManagerService wm) {
581 if (!mHaveDisplaySize) {
582 Point p = new Point();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700583 // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
Colin Cross637dbfc2013-07-18 17:15:15 -0700584 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700585 if (p.x != 0 && p.y != 0) {
586 updateOomLevels(p.x, p.y, true);
587 mHaveDisplaySize = true;
588 }
589 }
590 }
591
592 private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
593 // Scale buckets from avail memory: at 300MB we use the lowest values to
594 // 700MB or more for the top values.
Amith Yamasani98a00922018-08-21 12:50:30 -0400595 float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700596
597 // Scale buckets from screen size.
Amith Yamasani98a00922018-08-21 12:50:30 -0400598 int minSize = 480 * 800; // 384000
599 int maxSize = 1280 * 800; // 1024000 230400 870400 .264
600 float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700601 if (false) {
602 Slog.i("XXXXXX", "scaleMem=" + scaleMem);
603 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
604 + " dh=" + displayHeight);
605 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700606
Dianne Hackborn7d608422011-08-07 16:24:18 -0700607 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
608 if (scale < 0) scale = 0;
609 else if (scale > 1) scale = 1;
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700610 int minfree_adj = Resources.getSystem().getInteger(
611 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
612 int minfree_abs = Resources.getSystem().getInteger(
613 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
614 if (false) {
615 Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
616 }
Colin Crossfcdad6f2013-07-25 15:04:40 -0700617
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800618 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700619
Amith Yamasani98a00922018-08-21 12:50:30 -0400620 for (int i = 0; i < mOomAdj.length; i++) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700621 int low = mOomMinFreeLow[i];
622 int high = mOomMinFreeHigh[i];
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800623 if (is64bit) {
624 // Increase the high min-free levels for cached processes for 64-bit
Amith Yamasani98a00922018-08-21 12:50:30 -0400625 if (i == 4) high = (high * 3) / 2;
626 else if (i == 5) high = (high * 7) / 4;
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800627 }
Amith Yamasani98a00922018-08-21 12:50:30 -0400628 mOomMinFree[i] = (int)(low + ((high - low) * scale));
Colin Crossfcdad6f2013-07-25 15:04:40 -0700629 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700630
Colin Crossfcdad6f2013-07-25 15:04:40 -0700631 if (minfree_abs >= 0) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400632 for (int i = 0; i < mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700633 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
634 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700635 }
636 }
637
638 if (minfree_adj != 0) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400639 for (int i = 0; i < mOomAdj.length; i++) {
640 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700641 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700642 if (mOomMinFree[i] < 0) {
643 mOomMinFree[i] = 0;
644 }
645 }
646 }
647
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700648 // The maximum size we will restore a process from cached to background, when under
649 // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
650 // before killing background processes.
Amith Yamasani98a00922018-08-21 12:50:30 -0400651 mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700652
Colin Cross59d80a52013-07-25 10:45:05 -0700653 // Ask the kernel to try to keep enough memory free to allocate 3 full
654 // screen 32bpp buffers without entering direct reclaim.
655 int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
Amith Yamasani98a00922018-08-21 12:50:30 -0400656 int reserve_adj = Resources.getSystem().getInteger(
657 com.android.internal.R.integer.config_extraFreeKbytesAdjust);
658 int reserve_abs = Resources.getSystem().getInteger(
659 com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
Colin Cross59d80a52013-07-25 10:45:05 -0700660
661 if (reserve_abs >= 0) {
662 reserve = reserve_abs;
663 }
664
665 if (reserve_adj != 0) {
666 reserve += reserve_adj;
667 if (reserve < 0) {
668 reserve = 0;
669 }
670 }
671
Dianne Hackborn7d608422011-08-07 16:24:18 -0700672 if (write) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400673 ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
Todd Poynorbfdd6232013-07-10 19:15:07 -0700674 buf.putInt(LMK_TARGET);
Amith Yamasani98a00922018-08-21 12:50:30 -0400675 for (int i = 0; i < mOomAdj.length; i++) {
676 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700677 buf.putInt(mOomAdj[i]);
678 }
679
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700680 writeLmkd(buf, null);
Colin Cross59d80a52013-07-25 10:45:05 -0700681 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
Dianne Hackborn7d608422011-08-07 16:24:18 -0700682 }
683 // GB: 2048,3072,4096,6144,7168,8192
684 // HC: 8192,10240,12288,14336,16384,20480
685 }
686
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700687 public static int computeEmptyProcessLimit(int totalProcessLimit) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700688 return totalProcessLimit/2;
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700689 }
690
Dianne Hackborn311473c2019-02-04 15:34:51 -0800691 private static String buildOomTag(String prefix, String compactPrefix, String space, int val,
692 int base, boolean compact) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800693 final int diff = val - base;
694 if (diff == 0) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800695 if (compact) {
696 return compactPrefix;
697 }
Dianne Hackborn8e692572013-09-10 19:06:15 -0700698 if (space == null) return prefix;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800699 return prefix + space;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700700 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800701 if (diff < 10) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800702 return prefix + (compact ? "+" : "+ ") + Integer.toString(diff);
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800703 }
704 return prefix + "+" + Integer.toString(diff);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700705 }
706
Dianne Hackborn311473c2019-02-04 15:34:51 -0800707 public static String makeOomAdjString(int setAdj, boolean compact) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700708 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800709 return buildOomTag("cch", "cch", " ", setAdj,
710 ProcessList.CACHED_APP_MIN_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700711 } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800712 return buildOomTag("svcb ", "svcb", null, setAdj,
713 ProcessList.SERVICE_B_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700714 } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800715 return buildOomTag("prev ", "prev", null, setAdj,
716 ProcessList.PREVIOUS_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700717 } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800718 return buildOomTag("home ", "home", null, setAdj,
719 ProcessList.HOME_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700720 } else if (setAdj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800721 return buildOomTag("svc ", "svc", null, setAdj,
722 ProcessList.SERVICE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700723 } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800724 return buildOomTag("hvy ", "hvy", null, setAdj,
725 ProcessList.HEAVY_WEIGHT_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700726 } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800727 return buildOomTag("bkup ", "bkup", null, setAdj,
728 ProcessList.BACKUP_APP_ADJ, compact);
Amith Yamasani0567ec62019-01-23 11:11:02 -0800729 } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
730 return buildOomTag("prcl ", "prcl", null, setAdj,
731 ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700732 } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800733 return buildOomTag("prcp ", "prcp", null, setAdj,
734 ProcessList.PERCEPTIBLE_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700735 } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800736 return buildOomTag("vis", "vis", " ", setAdj,
737 ProcessList.VISIBLE_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700738 } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800739 return buildOomTag("fore ", "fore", null, setAdj,
740 ProcessList.FOREGROUND_APP_ADJ, compact);
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700741 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800742 return buildOomTag("psvc ", "psvc", null, setAdj,
743 ProcessList.PERSISTENT_SERVICE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700744 } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800745 return buildOomTag("pers ", "pers", null, setAdj,
746 ProcessList.PERSISTENT_PROC_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700747 } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800748 return buildOomTag("sys ", "sys", null, setAdj,
749 ProcessList.SYSTEM_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700750 } else if (setAdj >= ProcessList.NATIVE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800751 return buildOomTag("ntv ", "ntv", null, setAdj,
752 ProcessList.NATIVE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700753 } else {
754 return Integer.toString(setAdj);
755 }
756 }
757
Dianne Hackborn8e692572013-09-10 19:06:15 -0700758 public static String makeProcStateString(int curProcState) {
759 String procState;
760 switch (curProcState) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700761 case ActivityManager.PROCESS_STATE_PERSISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700762 procState = "PER ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700763 break;
764 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Dianne Hackborn94846032017-03-31 17:55:23 -0700765 procState = "PERU";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700766 break;
767 case ActivityManager.PROCESS_STATE_TOP:
Dianne Hackbornf4dd3712017-05-11 17:25:23 -0700768 procState = "TOP ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700769 break;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800770 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
771 procState = "FGSL";
772 break;
Amith Yamasanif235d0b2019-03-20 22:49:43 -0700773 case ActivityManager.PROCESS_STATE_BOUND_TOP:
774 procState = "BTOP";
775 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700776 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700777 procState = "FGS ";
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700778 break;
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800779 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
780 procState = "BFGS";
781 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700782 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700783 procState = "IMPF";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700784 break;
785 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700786 procState = "IMPB";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700787 break;
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700788 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
789 procState = "TRNB";
790 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700791 case ActivityManager.PROCESS_STATE_BACKUP:
Dianne Hackborn94846032017-03-31 17:55:23 -0700792 procState = "BKUP";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700793 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700794 case ActivityManager.PROCESS_STATE_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700795 procState = "SVC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700796 break;
797 case ActivityManager.PROCESS_STATE_RECEIVER:
Dianne Hackborn94846032017-03-31 17:55:23 -0700798 procState = "RCVR";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700799 break;
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800800 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
801 procState = "TPSL";
802 break;
Dianne Hackbornf097d422017-12-15 16:32:19 -0800803 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
804 procState = "HVY ";
805 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700806 case ActivityManager.PROCESS_STATE_HOME:
Dianne Hackborn94846032017-03-31 17:55:23 -0700807 procState = "HOME";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700808 break;
809 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700810 procState = "LAST";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700811 break;
812 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700813 procState = "CAC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700814 break;
815 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700816 procState = "CACC";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700817 break;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800818 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
819 procState = "CRE ";
820 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700821 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700822 procState = "CEM ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700823 break;
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800824 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700825 procState = "NONE";
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800826 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700827 default:
828 procState = "??";
829 break;
830 }
831 return procState;
832 }
833
Yi Jin148d7f42017-11-28 14:23:56 -0800834 public static int makeProcStateProtoEnum(int curProcState) {
835 switch (curProcState) {
836 case ActivityManager.PROCESS_STATE_PERSISTENT:
Bookatzdb026a22018-01-10 19:01:56 -0800837 return AppProtoEnums.PROCESS_STATE_PERSISTENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800838 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Bookatzdb026a22018-01-10 19:01:56 -0800839 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
Yi Jin148d7f42017-11-28 14:23:56 -0800840 case ActivityManager.PROCESS_STATE_TOP:
Bookatzdb026a22018-01-10 19:01:56 -0800841 return AppProtoEnums.PROCESS_STATE_TOP;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800842 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
Amith Yamasanif235d0b2019-03-20 22:49:43 -0700843 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
844 case ActivityManager.PROCESS_STATE_BOUND_TOP:
845 return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
Yi Jin148d7f42017-11-28 14:23:56 -0800846 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800847 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800848 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
849 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800850 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
Bookatzdb026a22018-01-10 19:01:56 -0800851 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING;
Yi Jin148d7f42017-11-28 14:23:56 -0800852 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800853 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800854 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800855 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800856 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -0800857 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -0800858 case ActivityManager.PROCESS_STATE_BACKUP:
Bookatzdb026a22018-01-10 19:01:56 -0800859 return AppProtoEnums.PROCESS_STATE_BACKUP;
Yi Jin148d7f42017-11-28 14:23:56 -0800860 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
Bookatzdb026a22018-01-10 19:01:56 -0800861 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT;
Yi Jin148d7f42017-11-28 14:23:56 -0800862 case ActivityManager.PROCESS_STATE_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -0800863 return AppProtoEnums.PROCESS_STATE_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -0800864 case ActivityManager.PROCESS_STATE_RECEIVER:
Bookatzdb026a22018-01-10 19:01:56 -0800865 return AppProtoEnums.PROCESS_STATE_RECEIVER;
Yi Jin148d7f42017-11-28 14:23:56 -0800866 case ActivityManager.PROCESS_STATE_HOME:
Bookatzdb026a22018-01-10 19:01:56 -0800867 return AppProtoEnums.PROCESS_STATE_HOME;
Yi Jin148d7f42017-11-28 14:23:56 -0800868 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -0800869 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -0800870 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -0800871 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -0800872 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Bookatzdb026a22018-01-10 19:01:56 -0800873 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800874 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
Bookatzdb026a22018-01-10 19:01:56 -0800875 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT;
Yi Jin148d7f42017-11-28 14:23:56 -0800876 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Bookatzdb026a22018-01-10 19:01:56 -0800877 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY;
Yi Jin148d7f42017-11-28 14:23:56 -0800878 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Bookatzdb026a22018-01-10 19:01:56 -0800879 return AppProtoEnums.PROCESS_STATE_NONEXISTENT;
880 case ActivityManager.PROCESS_STATE_UNKNOWN:
881 return AppProtoEnums.PROCESS_STATE_UNKNOWN;
Yi Jin148d7f42017-11-28 14:23:56 -0800882 default:
Bookatzdb026a22018-01-10 19:01:56 -0800883 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO;
Yi Jin148d7f42017-11-28 14:23:56 -0800884 }
885 }
886
Dianne Hackborn8e692572013-09-10 19:06:15 -0700887 public static void appendRamKb(StringBuilder sb, long ramKb) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400888 for (int j = 0, fact = 10; j < 6; j++, fact *= 10) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700889 if (ramKb < fact) {
890 sb.append(' ');
891 }
892 }
893 sb.append(ramKb);
894 }
895
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800896 // How long after a state change that it is safe to collect PSS without it being dirty.
897 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
898
899 // The minimum time interval after a state change it is safe to collect PSS.
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700900 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
901
902 // The maximum amount of time we want to go between PSS collections.
Dianne Hackborne17b4452018-01-10 13:15:40 -0800903 public static final int PSS_MAX_INTERVAL = 60*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700904
905 // The minimum amount of time between successive PSS requests for *all* processes.
Dianne Hackborn052e3142017-12-19 16:08:30 -0800906 public static final int PSS_ALL_INTERVAL = 20*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700907
Dianne Hackborn052e3142017-12-19 16:08:30 -0800908 // The amount of time until PSS when a persistent process first appears.
909 private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700910
911 // The amount of time until PSS when a process first becomes top.
912 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
913
914 // The amount of time until PSS when a process first goes into the background.
915 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
916
917 // The amount of time until PSS when a process first becomes cached.
Dianne Hackborne17b4452018-01-10 13:15:40 -0800918 private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;
919
920 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800921 private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700922
Dianne Hackborn052e3142017-12-19 16:08:30 -0800923 // The amount of time until PSS when the top process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800924 private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;
Dianne Hackborn052e3142017-12-19 16:08:30 -0800925
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700926 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800927 private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700928
929 // The amount of time until PSS when a service process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800930 private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700931
932 // The amount of time until PSS when a cached process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -0800933 private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700934
Dianne Hackborn052e3142017-12-19 16:08:30 -0800935 // The amount of time until PSS when a persistent process first appears.
936 private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
937
938 // The amount of time until PSS when a process first becomes top.
939 private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000;
940
941 // The amount of time until PSS when a process first goes into the background.
942 private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000;
943
944 // The amount of time until PSS when a process first becomes cached.
945 private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000;
946
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800947 // The minimum time interval after a state change it is safe to collect PSS.
948 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
949
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800950 // The amount of time during testing until PSS when a process first becomes top.
951 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
952
953 // The amount of time during testing until PSS when a process first goes into the background.
954 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
955
956 // The amount of time during testing until PSS when an important process stays in same state.
957 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
958
959 // The amount of time during testing until PSS when a background process stays in same state.
960 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
961
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700962 public static final int PROC_MEM_PERSISTENT = 0;
963 public static final int PROC_MEM_TOP = 1;
964 public static final int PROC_MEM_IMPORTANT = 2;
965 public static final int PROC_MEM_SERVICE = 3;
966 public static final int PROC_MEM_CACHED = 4;
Dianne Hackborne17b4452018-01-10 13:15:40 -0800967 public static final int PROC_MEM_NUM = 5;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700968
Dianne Hackborne17b4452018-01-10 13:15:40 -0800969 // Map large set of system process states to
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700970 private static final int[] sProcStateToProcMem = new int[] {
971 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
972 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
973 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP
Amith Yamasania0a30a12019-01-22 11:38:06 -0800974 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700975 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Amith Yamasanif235d0b2019-03-20 22:49:43 -0700976 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_BOUND_TOP
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800977 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700978 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
979 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700980 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700981 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700982 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
983 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800984 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackbornf097d422017-12-15 16:32:19 -0800985 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700986 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME
987 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
988 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
989 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -0800990 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700991 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
992 };
993
994 private static final long[] sFirstAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -0800995 PSS_FIRST_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
996 PSS_FIRST_TOP_INTERVAL, // PROC_MEM_TOP
997 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
998 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
999 PSS_FIRST_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001000 };
1001
1002 private static final long[] sSameAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001003 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1004 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP
1005 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
1006 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE
1007 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn052e3142017-12-19 16:08:30 -08001008 };
1009
1010 private static final long[] sFirstAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001011 PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1012 PSS_FIRST_ASLEEP_TOP_INTERVAL, // PROC_MEM_TOP
1013 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1014 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1015 PSS_FIRST_ASLEEP_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn052e3142017-12-19 16:08:30 -08001016 };
1017
1018 private static final long[] sSameAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001019 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1020 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP
1021 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
1022 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE
1023 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001024 };
1025
Dianne Hackbornf097d422017-12-15 16:32:19 -08001026 private static final long[] sTestFirstPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001027 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_PERSISTENT
1028 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_TOP
1029 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1030 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1031 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001032 };
1033
Dianne Hackbornf097d422017-12-15 16:32:19 -08001034 private static final long[] sTestSamePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001035 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_PERSISTENT
1036 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_TOP
1037 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
1038 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1039 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001040 };
1041
Dianne Hackborne17b4452018-01-10 13:15:40 -08001042 public static final class ProcStateMemTracker {
1043 final int[] mHighestMem = new int[PROC_MEM_NUM];
Dianne Hackborned0a3222018-02-06 16:01:23 -08001044 final float[] mScalingFactor = new float[PROC_MEM_NUM];
Dianne Hackborne17b4452018-01-10 13:15:40 -08001045 int mTotalHighestMem = PROC_MEM_CACHED;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001046
1047 int mPendingMemState;
1048 int mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001049 float mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001050
1051 public ProcStateMemTracker() {
1052 for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
1053 mHighestMem[i] = PROC_MEM_NUM;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001054 mScalingFactor[i] = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001055 }
1056 mPendingMemState = -1;
1057 }
1058
1059 public void dumpLine(PrintWriter pw) {
1060 pw.print("best=");
1061 pw.print(mTotalHighestMem);
Dianne Hackborned0a3222018-02-06 16:01:23 -08001062 pw.print(" (");
1063 boolean needSep = false;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001064 for (int i = 0; i < PROC_MEM_NUM; i++) {
Dianne Hackborned0a3222018-02-06 16:01:23 -08001065 if (mHighestMem[i] < PROC_MEM_NUM) {
1066 if (needSep) {
1067 pw.print(", ");
1068 needSep = false;
1069 }
1070 pw.print(i);
1071 pw.print("=");
1072 pw.print(mHighestMem[i]);
1073 pw.print(" ");
1074 pw.print(mScalingFactor[i]);
1075 pw.print("x");
1076 needSep = true;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001077 }
Dianne Hackborne17b4452018-01-10 13:15:40 -08001078 }
1079 pw.print(")");
1080 if (mPendingMemState >= 0) {
1081 pw.print(" / pending state=");
1082 pw.print(mPendingMemState);
1083 pw.print(" highest=");
1084 pw.print(mPendingHighestMemState);
Dianne Hackborned0a3222018-02-06 16:01:23 -08001085 pw.print(" ");
1086 pw.print(mPendingScalingFactor);
1087 pw.print("x");
Dianne Hackborne17b4452018-01-10 13:15:40 -08001088 }
1089 pw.println();
1090 }
1091 }
1092
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001093 public static boolean procStatesDifferForMem(int procState1, int procState2) {
1094 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
1095 }
1096
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -08001097 public static long minTimeFromStateChange(boolean test) {
1098 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
1099 }
1100
Dianne Hackborne17b4452018-01-10 13:15:40 -08001101 public static void commitNextPssTime(ProcStateMemTracker tracker) {
1102 if (tracker.mPendingMemState >= 0) {
1103 tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001104 tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001105 tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001106 tracker.mPendingMemState = -1;
1107 }
1108 }
1109
1110 public static void abortNextPssTime(ProcStateMemTracker tracker) {
1111 tracker.mPendingMemState = -1;
1112 }
1113
1114 public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001115 boolean sleeping, long now) {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001116 boolean first;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001117 float scalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001118 final int memState = sProcStateToProcMem[procState];
1119 if (tracker != null) {
1120 final int highestMemState = memState < tracker.mTotalHighestMem
1121 ? memState : tracker.mTotalHighestMem;
1122 first = highestMemState < tracker.mHighestMem[memState];
1123 tracker.mPendingMemState = memState;
1124 tracker.mPendingHighestMemState = highestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001125 if (first) {
1126 tracker.mPendingScalingFactor = scalingFactor = 1.0f;
1127 } else {
1128 scalingFactor = tracker.mScalingFactor[memState];
1129 tracker.mPendingScalingFactor = scalingFactor * 1.5f;
1130 }
Dianne Hackborne17b4452018-01-10 13:15:40 -08001131 } else {
1132 first = true;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001133 scalingFactor = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001134 }
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001135 final long[] table = test
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001136 ? (first
Dianne Hackborne17b4452018-01-10 13:15:40 -08001137 ? sTestFirstPssTimes
1138 : sTestSamePssTimes)
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001139 : (first
Dianne Hackborne17b4452018-01-10 13:15:40 -08001140 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
1141 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
Dianne Hackborned0a3222018-02-06 16:01:23 -08001142 long delay = (long)(table[memState] * scalingFactor);
Dianne Hackborne17b4452018-01-10 13:15:40 -08001143 if (delay > PSS_MAX_INTERVAL) {
1144 delay = PSS_MAX_INTERVAL;
1145 }
1146 return now + delay;
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001147 }
1148
Dianne Hackborn7d608422011-08-07 16:24:18 -07001149 long getMemLevel(int adjustment) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001150 for (int i = 0; i < mOomAdj.length; i++) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07001151 if (adjustment <= mOomAdj[i]) {
1152 return mOomMinFree[i] * 1024;
1153 }
1154 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001155 return mOomMinFree[mOomAdj.length - 1] * 1024;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001156 }
1157
Todd Poynorbfdd6232013-07-10 19:15:07 -07001158 /**
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001159 * Return the maximum pss size in kb that we consider a process acceptable to
1160 * restore from its cached state for running in the background when RAM is low.
1161 */
Dianne Hackborncbd9a522013-09-24 23:10:14 -07001162 long getCachedRestoreThresholdKb() {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001163 return mCachedRestoreLevel;
1164 }
1165
Dianne Hackborn9bef5b62013-09-20 10:40:34 -07001166 /**
Todd Poynorbfdd6232013-07-10 19:15:07 -07001167 * Set the out-of-memory badness adjustment for a process.
Sudheer Shankaf6690102017-10-16 10:20:32 -07001168 * If {@code pid <= 0}, this method will be a no-op.
Todd Poynorbfdd6232013-07-10 19:15:07 -07001169 *
1170 * @param pid The process identifier to set.
Colin Crossd908edd2014-06-13 14:56:04 -07001171 * @param uid The uid of the app
Rafal Slawikda8c0ab2019-03-07 13:54:40 +00001172 * @param amt Adjustment value -- lmkd allows -1000 to +1000
Todd Poynorbfdd6232013-07-10 19:15:07 -07001173 *
1174 * {@hide}
1175 */
Rafal Slawikda8c0ab2019-03-07 13:54:40 +00001176 public static void setOomAdj(int pid, int uid, int amt) {
Sudheer Shankaf6690102017-10-16 10:20:32 -07001177 // This indicates that the process is not started yet and so no need to proceed further.
1178 if (pid <= 0) {
1179 return;
1180 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001181 if (amt == UNKNOWN_ADJ)
1182 return;
1183
Dianne Hackbornecf1cda2014-08-28 16:58:28 -07001184 long start = SystemClock.elapsedRealtime();
Colin Crossd908edd2014-06-13 14:56:04 -07001185 ByteBuffer buf = ByteBuffer.allocate(4 * 4);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001186 buf.putInt(LMK_PROCPRIO);
1187 buf.putInt(pid);
Colin Crossd908edd2014-06-13 14:56:04 -07001188 buf.putInt(uid);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001189 buf.putInt(amt);
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001190 writeLmkd(buf, null);
Dianne Hackbornecf1cda2014-08-28 16:58:28 -07001191 long now = SystemClock.elapsedRealtime();
1192 if ((now-start) > 250) {
1193 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
1194 + " = " + amt);
1195 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001196 }
1197
1198 /*
1199 * {@hide}
1200 */
1201 public static final void remove(int pid) {
Sudheer Shankaf6690102017-10-16 10:20:32 -07001202 // This indicates that the process is not started yet and so no need to proceed further.
1203 if (pid <= 0) {
1204 return;
1205 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001206 ByteBuffer buf = ByteBuffer.allocate(4 * 2);
1207 buf.putInt(LMK_PROCREMOVE);
1208 buf.putInt(pid);
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001209 writeLmkd(buf, null);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001210 }
1211
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001212 /*
1213 * {@hide}
1214 */
1215 public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) {
1216 ByteBuffer buf = ByteBuffer.allocate(4 * 3);
1217 ByteBuffer repl = ByteBuffer.allocate(4 * 2);
1218 buf.putInt(LMK_GETKILLCNT);
1219 buf.putInt(min_oom_adj);
1220 buf.putInt(max_oom_adj);
1221 if (writeLmkd(buf, repl)) {
1222 int i = repl.getInt();
1223 if (i != LMK_GETKILLCNT) {
1224 Slog.e("ActivityManager", "Failed to get kill count, code mismatch");
1225 return null;
1226 }
1227 return new Integer(repl.getInt());
1228 }
1229 return null;
1230 }
1231
1232 @GuardedBy("sLmkdSocketLock")
1233 private static boolean openLmkdSocketLS() {
Dianne Hackborn7d608422011-08-07 16:24:18 -07001234 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -07001235 sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
1236 sLmkdSocket.connect(
1237 new LocalSocketAddress("lmkd",
1238 LocalSocketAddress.Namespace.RESERVED));
1239 sLmkdOutputStream = sLmkdSocket.getOutputStream();
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001240 sLmkdInputStream = sLmkdSocket.getInputStream();
Todd Poynorbfdd6232013-07-10 19:15:07 -07001241 } catch (IOException ex) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -08001242 Slog.w(TAG, "lowmemorykiller daemon socket open failed");
Todd Poynorbfdd6232013-07-10 19:15:07 -07001243 sLmkdSocket = null;
1244 return false;
1245 }
1246
1247 return true;
1248 }
1249
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001250 // Never call directly, use writeLmkd() instead
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001251 @GuardedBy("sLmkdSocketLock")
1252 private static boolean writeLmkdCommandLS(ByteBuffer buf) {
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001253 try {
1254 sLmkdOutputStream.write(buf.array(), 0, buf.position());
1255 } catch (IOException ex) {
1256 Slog.w(TAG, "Error writing to lowmemorykiller socket");
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001257 IoUtils.closeQuietly(sLmkdSocket);
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001258 sLmkdSocket = null;
1259 return false;
1260 }
1261 return true;
1262 }
1263
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001264 // Never call directly, use writeLmkd() instead
1265 @GuardedBy("sLmkdSocketLock")
1266 private static boolean readLmkdReplyLS(ByteBuffer buf) {
1267 int len;
1268 try {
1269 len = sLmkdInputStream.read(buf.array(), 0, buf.array().length);
1270 if (len == buf.array().length) {
1271 return true;
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001272 }
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001273 } catch (IOException ex) {
1274 Slog.w(TAG, "Error reading from lowmemorykiller socket");
1275 }
1276
1277 IoUtils.closeQuietly(sLmkdSocket);
1278 sLmkdSocket = null;
1279 return false;
1280 }
1281
1282 private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
1283 synchronized (sLmkdSocketLock) {
1284 for (int i = 0; i < 3; i++) {
1285 if (sLmkdSocket == null) {
1286 if (openLmkdSocketLS() == false) {
1287 try {
1288 Thread.sleep(1000);
1289 } catch (InterruptedException ie) {
1290 }
1291 continue;
1292 }
1293
1294 // Purge any previously registered pids
1295 ByteBuffer purge_buf = ByteBuffer.allocate(4);
1296 purge_buf.putInt(LMK_PROCPURGE);
1297 if (writeLmkdCommandLS(purge_buf) == false) {
1298 // Write failed, skip the rest and retry
1299 continue;
1300 }
1301 }
1302 if (writeLmkdCommandLS(buf) && (repl == null || readLmkdReplyLS(repl))) {
1303 return true;
1304 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07001305 }
1306 }
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001307 return false;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001308 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001309
1310 static void killProcessGroup(int uid, int pid) {
1311 /* static; one-time init here */
1312 if (sKillHandler != null) {
1313 sKillHandler.sendMessage(
1314 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
1315 } else {
1316 Slog.w(TAG, "Asked to kill process group before system bringup!");
1317 Process.killProcessGroup(uid, pid);
1318 }
1319 }
1320
1321 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean
1322 keepIfLarge) {
1323 if (uid == SYSTEM_UID) {
1324 // The system gets to run in any process. If there are multiple
1325 // processes with the same uid, just pick the first (this
1326 // should never happen).
1327 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
1328 if (procs == null) return null;
1329 final int procCount = procs.size();
1330 for (int i = 0; i < procCount; i++) {
1331 final int procUid = procs.keyAt(i);
1332 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
1333 // Don't use an app process or different user process for system component.
1334 continue;
1335 }
1336 return procs.valueAt(i);
1337 }
1338 }
1339 ProcessRecord proc = mProcessNames.get(processName, uid);
1340 if (false && proc != null && !keepIfLarge
1341 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
1342 && proc.lastCachedPss >= 4000) {
1343 // Turn this condition on to cause killing to happen regularly, for testing.
1344 if (proc.baseProcessTracker != null) {
1345 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
1346 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1347 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1348 StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1349 proc.info.uid,
1350 holder.state.getName(),
1351 holder.state.getPackage(),
1352 proc.lastCachedPss, holder.appVersion);
1353 }
1354 }
1355 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
1356 } else if (proc != null && !keepIfLarge
1357 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
1358 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
1359 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc
1360 .lastCachedPss);
1361 if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) {
1362 if (proc.baseProcessTracker != null) {
1363 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
1364 proc.lastCachedPss);
1365 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1366 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1367 StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1368 proc.info.uid,
1369 holder.state.getName(),
1370 holder.state.getPackage(),
1371 proc.lastCachedPss, holder.appVersion);
1372 }
1373 }
1374 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
1375 }
1376 }
1377 return proc;
1378 }
1379
1380 void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
1381 final long homeAppMem = getMemLevel(HOME_APP_ADJ);
1382 final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ);
1383 outInfo.availMem = getFreeMemory();
1384 outInfo.totalMem = getTotalMemory();
1385 outInfo.threshold = homeAppMem;
1386 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
1387 outInfo.hiddenAppThreshold = cachedAppMem;
1388 outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ);
1389 outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ);
1390 outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ);
1391 }
1392
1393 ProcessRecord findAppProcessLocked(IBinder app, String reason) {
1394 final int NP = mProcessNames.getMap().size();
1395 for (int ip = 0; ip < NP; ip++) {
1396 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
1397 final int NA = apps.size();
1398 for (int ia = 0; ia < NA; ia++) {
1399 ProcessRecord p = apps.valueAt(ia);
1400 if (p.thread != null && p.thread.asBinder() == app) {
1401 return p;
1402 }
1403 }
1404 }
1405
1406 Slog.w(TAG, "Can't find mystery application for " + reason
1407 + " from pid=" + Binder.getCallingPid()
1408 + " uid=" + Binder.getCallingUid() + ": " + app);
1409 return null;
1410 }
1411
1412 private void checkSlow(long startTime, String where) {
1413 long now = SystemClock.uptimeMillis();
1414 if ((now - startTime) > 50) {
1415 // If we are taking more than 50ms, log about it.
1416 Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where);
1417 }
1418 }
1419
1420 /**
1421 * @return {@code true} if process start is successful, false otherwise.
Amith Yamasani98a00922018-08-21 12:50:30 -04001422 */
1423 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01001424 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
Artur Satayev19305b42019-10-28 15:25:14 +00001425 boolean disableHiddenApiChecks, boolean disableTestApiChecks,
1426 boolean mountExtStorageFull, String abiOverride) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001427 if (app.pendingStart) {
1428 return true;
1429 }
1430 long startTime = SystemClock.elapsedRealtime();
1431 if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
1432 checkSlow(startTime, "startProcess: removing from pids map");
Hui Yu6dabda82019-05-07 14:02:57 -07001433 mService.mPidsSelfLocked.remove(app);
Wale Ogunwale0b940842018-12-03 06:58:11 -08001434 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04001435 checkSlow(startTime, "startProcess: done removing from pids map");
1436 app.setPid(0);
Hui Yu6dabda82019-05-07 14:02:57 -07001437 app.startSeq = 0;
Amith Yamasani98a00922018-08-21 12:50:30 -04001438 }
1439
1440 if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
1441 TAG_PROCESSES,
1442 "startProcessLocked removing on hold: " + app);
1443 mService.mProcessesOnHold.remove(app);
1444
1445 checkSlow(startTime, "startProcess: starting to update cpu stats");
1446 mService.updateCpuStats();
1447 checkSlow(startTime, "startProcess: done updating cpu stats");
1448
1449 try {
1450 try {
1451 final int userId = UserHandle.getUserId(app.uid);
1452 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
1453 } catch (RemoteException e) {
1454 throw e.rethrowAsRuntimeException();
1455 }
1456
1457 int uid = app.uid;
1458 int[] gids = null;
1459 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1460 if (!app.isolated) {
1461 int[] permGids = null;
1462 try {
1463 checkSlow(startTime, "startProcess: getting gids from package manager");
1464 final IPackageManager pm = AppGlobals.getPackageManager();
1465 permGids = pm.getPackageGids(app.info.packageName,
1466 MATCH_DIRECT_BOOT_AUTO, app.userId);
Jeff Sharkey10ec9d82018-11-28 14:52:45 -07001467 if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001468 mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
1469 } else {
1470 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1471 StorageManagerInternal.class);
1472 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
1473 app.info.packageName);
1474 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001475 } catch (RemoteException e) {
1476 throw e.rethrowAsRuntimeException();
1477 }
1478
1479 /*
1480 * Add shared application and profile GIDs so applications can share some
1481 * resources like shared libraries and access user-wide resources
1482 */
1483 if (ArrayUtils.isEmpty(permGids)) {
1484 gids = new int[3];
1485 } else {
1486 gids = new int[permGids.length + 3];
1487 System.arraycopy(permGids, 0, gids, 3, permGids.length);
1488 }
1489 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
1490 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
1491 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
1492
1493 // Replace any invalid GIDs
1494 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
1495 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
1496 }
Sudheer Shanka87915d62018-11-06 10:57:35 -08001497 app.mountMode = mountExternal;
Amith Yamasani98a00922018-08-21 12:50:30 -04001498 checkSlow(startTime, "startProcess: building args");
1499 if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
1500 uid = 0;
1501 }
1502 int runtimeFlags = 0;
1503 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1504 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
1505 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1506 // Also turn on CheckJNI for debuggable apps. It's quite
1507 // awkward to turn on otherwise.
1508 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
Alex Buynytskyy5d5921ee2019-01-22 15:22:55 -08001509
1510 // Check if the developer does not want ART verification
1511 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(),
1512 android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) {
1513 runtimeFlags |= Zygote.DISABLE_VERIFIER;
1514 Slog.w(TAG_PROCESSES, app + ": ART verification disabled");
1515 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001516 }
1517 // Run the app in safe mode if its manifest requests so or the
1518 // system is booted in safe mode.
1519 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1520 mService.mSafeMode == true) {
1521 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1522 }
Yabin Cui4d8546d2019-01-29 16:29:20 -08001523 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
1524 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
1525 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001526 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1527 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1528 }
1529 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1530 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1531 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1532 }
1533 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1534 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1535 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1536 }
1537 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1538 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1539 }
1540 if ("1".equals(SystemProperties.get("debug.assert"))) {
1541 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1542 }
randy.jeong3ea95802019-05-29 10:43:39 +09001543 if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) {
1544 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER;
1545 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001546 if (mService.mNativeDebuggingApp != null
1547 && mService.mNativeDebuggingApp.equals(app.processName)) {
1548 // Enable all debug flags required by the native debugger.
1549 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
1550 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1551 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
1552 mService.mNativeDebuggingApp = null;
1553 }
1554
Victor Hsiehfa9df0b2019-01-29 12:48:36 -08001555 if (app.info.isEmbeddedDexUsed()
Victor Hsiehe7b5a8d2018-11-16 10:27:06 -08001556 || (app.info.isPrivilegedApp()
1557 && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001558 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1559 }
1560
1561 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
1562 app.info.maybeUpdateHiddenApiEnforcementPolicy(
David Brazdil06ae4b82018-11-02 18:01:45 +00001563 mService.mHiddenApiBlacklist.getPolicy());
Amith Yamasani98a00922018-08-21 12:50:30 -04001564 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
1565 app.info.getHiddenApiEnforcementPolicy();
1566 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
1567 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
1568 throw new IllegalStateException("Invalid API policy: " + policy);
1569 }
1570 runtimeFlags |= policyBits;
Artur Satayev19305b42019-10-28 15:25:14 +00001571
1572 if (disableTestApiChecks) {
1573 runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY;
1574 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001575 }
1576
Mathieu Chartier77bd1232019-03-05 13:53:11 -08001577 String useAppImageCache = SystemProperties.get(
1578 PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
1579 // Property defaults to true currently.
1580 if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) {
1581 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
1582 }
1583
Amith Yamasani98a00922018-08-21 12:50:30 -04001584 String invokeWith = null;
1585 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1586 // Debuggable apps may include a wrapper script with their library directory.
1587 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
1588 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
1589 try {
1590 if (new File(wrapperFileName).exists()) {
1591 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
1592 }
1593 } finally {
1594 StrictMode.setThreadPolicy(oldPolicy);
1595 }
1596 }
1597
1598 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
1599 if (requiredAbi == null) {
1600 requiredAbi = Build.SUPPORTED_ABIS[0];
1601 }
1602
1603 String instructionSet = null;
1604 if (app.info.primaryCpuAbi != null) {
1605 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
1606 }
1607
1608 app.gids = gids;
1609 app.setRequiredAbi(requiredAbi);
1610 app.instructionSet = instructionSet;
1611
1612 // the per-user SELinux context must be set
1613 if (TextUtils.isEmpty(app.info.seInfoUser)) {
1614 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
1615 new IllegalStateException("SELinux tag not defined for "
1616 + app.info.packageName + " (uid " + app.uid + ")"));
1617 }
1618 final String seInfo = app.info.seInfo
1619 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
1620 // Start the process. It will either succeed and return a result containing
1621 // the PID of the new process, or else throw a RuntimeException.
1622 final String entryPoint = "android.app.ActivityThread";
1623
Martijn Coenene8431c22019-03-28 14:09:38 +01001624 return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
Amith Yamasani98a00922018-08-21 12:50:30 -04001625 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
1626 startTime);
1627 } catch (RuntimeException e) {
1628 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1629
1630 // Something went very wrong while trying to start this process; one
1631 // common case is when the package is frozen due to an active
1632 // upgrade. To recover, clean up any active bookkeeping related to
1633 // starting this process. (We already invoked this method once when
1634 // the package was initially frozen through KILL_APPLICATION_MSG, so
1635 // it doesn't hurt to use it again.)
1636 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1637 false, false, true, false, false, app.userId, "start failure");
1638 return false;
1639 }
1640 }
1641
1642 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01001643 boolean startProcessLocked(HostingRecord hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04001644 String entryPoint,
1645 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1646 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1647 long startTime) {
1648 app.pendingStart = true;
1649 app.killedByAm = false;
1650 app.removed = false;
1651 app.killed = false;
Hui Yu6dabda82019-05-07 14:02:57 -07001652 if (app.startSeq != 0) {
1653 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
1654 + " with non-zero startSeq:" + app.startSeq);
1655 }
1656 if (app.pid != 0) {
1657 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
1658 + " with non-zero pid:" + app.pid);
1659 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001660 final long startSeq = app.startSeq = ++mProcStartSeqCounter;
Martijn Coenene8431c22019-03-28 14:09:38 +01001661 app.setStartParams(uid, hostingRecord, seInfo, startTime);
Amith Yamasani4b76bc12019-04-24 11:46:43 -07001662 app.setUsingWrapper(invokeWith != null
1663 || SystemProperties.get("wrap." + app.processName) != null);
1664 mPendingStarts.put(startSeq, app);
1665
Amith Yamasani98a00922018-08-21 12:50:30 -04001666 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
1667 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
1668 "Posting procStart msg for " + app.toShortString());
1669 mService.mProcStartHandler.post(() -> {
1670 try {
Martijn Coenene8431c22019-03-28 14:09:38 +01001671 final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04001672 entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
1673 app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
1674 synchronized (mService) {
1675 handleProcessStartedLocked(app, startResult, startSeq);
1676 }
1677 } catch (RuntimeException e) {
1678 synchronized (mService) {
1679 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1680 + app.processName, e);
1681 mPendingStarts.remove(startSeq);
1682 app.pendingStart = false;
1683 mService.forceStopPackageLocked(app.info.packageName,
1684 UserHandle.getAppId(app.uid),
1685 false, false, true, false, false, app.userId, "start failure");
1686 }
1687 }
1688 });
1689 return true;
1690 } else {
1691 try {
Martijn Coenene8431c22019-03-28 14:09:38 +01001692 final Process.ProcessStartResult startResult = startProcess(hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04001693 entryPoint, app,
1694 uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
1695 invokeWith, startTime);
1696 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
1697 startSeq, false);
1698 } catch (RuntimeException e) {
1699 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1700 + app.processName, e);
1701 app.pendingStart = false;
1702 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1703 false, false, true, false, false, app.userId, "start failure");
1704 }
1705 return app.pid > 0;
1706 }
1707 }
1708
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001709 @GuardedBy("mService")
1710 public void killAppZygoteIfNeededLocked(AppZygote appZygote) {
1711 final ApplicationInfo appInfo = appZygote.getAppInfo();
1712 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
Martijn Coenenb27a8ea2019-02-12 10:23:47 +01001713 if (zygoteProcesses != null && zygoteProcesses.size() == 0) {
1714 // Only remove if no longer in use now
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001715 mAppZygotes.remove(appInfo.processName, appInfo.uid);
1716 mAppZygoteProcesses.remove(appZygote);
Martijn Coenen01e719b2018-12-05 16:01:38 +01001717 mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001718 appZygote.stopZygote();
1719 }
1720 }
1721
1722 @GuardedBy("mService")
1723 private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01001724 // Free the isolated uid for this process
1725 final IsolatedUidRange appUidRange =
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001726 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName,
1727 app.hostingRecord.getDefiningUid());
Martijn Coenen01e719b2018-12-05 16:01:38 +01001728 if (appUidRange != null) {
1729 appUidRange.freeIsolatedUidLocked(app.uid);
1730 }
1731
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001732 final AppZygote appZygote = mAppZygotes.get(app.info.processName,
1733 app.hostingRecord.getDefiningUid());
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001734 if (appZygote != null) {
1735 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
1736 zygoteProcesses.remove(app);
1737 if (zygoteProcesses.size() == 0) {
Martijn Coenenb27a8ea2019-02-12 10:23:47 +01001738 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG);
Martijn Coenen378b2702019-02-20 10:33:41 +01001739 if (app.removed) {
1740 // If we stopped this process because the package hosting it was removed,
1741 // there's no point in delaying the app zygote kill.
1742 killAppZygoteIfNeededLocked(appZygote);
1743 } else {
1744 Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
1745 msg.obj = appZygote;
1746 mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS);
1747 }
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001748 }
1749 }
1750 }
1751
1752 private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
1753 synchronized (mService) {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001754 // The UID for the app zygote should be the UID of the application hosting
1755 // the service.
1756 final int uid = app.hostingRecord.getDefiningUid();
1757 AppZygote appZygote = mAppZygotes.get(app.info.processName, uid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001758 final ArrayList<ProcessRecord> zygoteProcessList;
1759 if (appZygote == null) {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001760 if (DEBUG_PROCESSES) {
1761 Slog.d(TAG_PROCESSES, "Creating new app zygote.");
1762 }
Martijn Coenen01e719b2018-12-05 16:01:38 +01001763 final IsolatedUidRange uidRange =
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001764 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(
1765 app.info.processName, app.hostingRecord.getDefiningUid());
1766 final int userId = UserHandle.getUserId(uid);
Martijn Coenen86f08a52019-01-03 16:23:01 +01001767 // Create the app-zygote and provide it with the UID-range it's allowed
1768 // to setresuid/setresgid to.
1769 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
1770 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001771 ApplicationInfo appInfo = new ApplicationInfo(app.info);
1772 // If this was an external service, the package name and uid in the passed in
1773 // ApplicationInfo have been changed to match those of the calling package;
1774 // that is not what we want for the AppZygote though, which needs to have the
1775 // packageName and uid of the defining application. This is because the
1776 // preloading only makes sense in the context of the defining application,
1777 // not the calling one.
1778 appInfo.packageName = app.hostingRecord.getDefiningPackageName();
1779 appInfo.uid = uid;
1780 appZygote = new AppZygote(appInfo, uid, firstUid, lastUid);
1781 mAppZygotes.put(app.info.processName, uid, appZygote);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001782 zygoteProcessList = new ArrayList<ProcessRecord>();
1783 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
1784 } else {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001785 if (DEBUG_PROCESSES) {
1786 Slog.d(TAG_PROCESSES, "Reusing existing app zygote.");
1787 }
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001788 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
1789 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
1790 }
1791 // Note that we already add the app to mAppZygoteProcesses here;
1792 // this is so that another thread can't come in and kill the zygote
1793 // before we've even tried to start the process. If the process launch
1794 // goes wrong, we'll clean this up in removeProcessNameLocked()
1795 zygoteProcessList.add(app);
1796
1797 return appZygote;
1798 }
1799 }
1800
Martijn Coenene8431c22019-03-28 14:09:38 +01001801 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
Amith Yamasani98a00922018-08-21 12:50:30 -04001802 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1803 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1804 long startTime) {
1805 try {
Amith Yamasani98a00922018-08-21 12:50:30 -04001806 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
1807 app.processName);
1808 checkSlow(startTime, "startProcess: asking zygote to start proc");
1809 final Process.ProcessStartResult startResult;
Martijn Coenene8431c22019-03-28 14:09:38 +01001810 if (hostingRecord.usesWebviewZygote()) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001811 startResult = startWebView(entryPoint,
1812 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1813 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1814 app.info.dataDir, null, app.info.packageName,
Chris Wailes35fdbc52019-04-17 17:55:48 -07001815 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
Martijn Coenene8431c22019-03-28 14:09:38 +01001816 } else if (hostingRecord.usesAppZygote()) {
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001817 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
1818
1819 startResult = appZygote.getProcess().start(entryPoint,
1820 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1821 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1822 app.info.dataDir, null, app.info.packageName,
Chris Wailesbed19762019-06-07 16:49:46 -07001823 /*useUsapPool=*/ false,
Chris Wailes35fdbc52019-04-17 17:55:48 -07001824 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
Amith Yamasani98a00922018-08-21 12:50:30 -04001825 } else {
1826 startResult = Process.start(entryPoint,
1827 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
1828 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
1829 app.info.dataDir, invokeWith, app.info.packageName,
Chris Wailes35fdbc52019-04-17 17:55:48 -07001830 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
Amith Yamasani98a00922018-08-21 12:50:30 -04001831 }
1832 checkSlow(startTime, "startProcess: returned from zygote!");
1833 return startResult;
1834 } finally {
1835 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1836 }
1837 }
1838
1839 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01001840 final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {
1841 startProcessLocked(app, hostingRecord, null /* abiOverride */);
Amith Yamasani98a00922018-08-21 12:50:30 -04001842 }
1843
1844 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01001845 final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1846 String abiOverride) {
1847 return startProcessLocked(app, hostingRecord,
Artur Satayev19305b42019-10-28 15:25:14 +00001848 false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
1849 false /* mountExtStorageFull */, abiOverride);
Amith Yamasani98a00922018-08-21 12:50:30 -04001850 }
1851
1852 @GuardedBy("mService")
1853 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
Martijn Coenene8431c22019-03-28 14:09:38 +01001854 boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04001855 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
1856 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
1857 long startTime = SystemClock.elapsedRealtime();
1858 ProcessRecord app;
1859 if (!isolated) {
1860 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
1861 checkSlow(startTime, "startProcess: after getProcessRecord");
1862
1863 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
1864 // If we are in the background, then check to see if this process
1865 // is bad. If so, we will just silently fail.
1866 if (mService.mAppErrors.isBadProcessLocked(info)) {
1867 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1868 + "/" + info.processName);
1869 return null;
1870 }
1871 } else {
1872 // When the user is explicitly starting a process, then clear its
1873 // crash count so that we won't make it bad until they see at
1874 // least one crash dialog again, and make the process good again
1875 // if it had been bad.
1876 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1877 + "/" + info.processName);
1878 mService.mAppErrors.resetProcessCrashTimeLocked(info);
1879 if (mService.mAppErrors.isBadProcessLocked(info)) {
1880 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
1881 UserHandle.getUserId(info.uid), info.uid,
1882 info.processName);
1883 mService.mAppErrors.clearBadProcessLocked(info);
1884 if (app != null) {
1885 app.bad = false;
1886 }
1887 }
1888 }
1889 } else {
1890 // If this is an isolated process, it can't re-use an existing process.
1891 app = null;
1892 }
1893
1894 // We don't have to do anything more if:
1895 // (1) There is an existing application record; and
1896 // (2) The caller doesn't think it is dead, OR there is no thread
1897 // object attached to it so we know it couldn't have crashed; and
1898 // (3) There is a pid assigned to it, so it is either starting or
1899 // already running.
1900 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
1901 + " app=" + app + " knownToBeDead=" + knownToBeDead
1902 + " thread=" + (app != null ? app.thread : null)
1903 + " pid=" + (app != null ? app.pid : -1));
1904 if (app != null && app.pid > 0) {
1905 if ((!knownToBeDead && !app.killed) || app.thread == null) {
1906 // We already have the app running, or are waiting for it to
1907 // come up (we have a pid but not yet its thread), so keep it.
1908 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
1909 // If this is a new package in the process, add the package to the list
Dianne Hackborn6f30f182019-05-23 15:41:41 -07001910 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
Amith Yamasani98a00922018-08-21 12:50:30 -04001911 checkSlow(startTime, "startProcess: done, added package to proc");
1912 return app;
1913 }
1914
1915 // An application record is attached to a previous process,
1916 // clean it up now.
1917 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
1918 checkSlow(startTime, "startProcess: bad proc running, killing");
1919 ProcessList.killProcessGroup(app.uid, app.pid);
1920 mService.handleAppDiedLocked(app, true, true);
1921 checkSlow(startTime, "startProcess: done killing old proc");
1922 }
1923
Amith Yamasani98a00922018-08-21 12:50:30 -04001924 if (app == null) {
1925 checkSlow(startTime, "startProcess: creating new process record");
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001926 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
Amith Yamasani98a00922018-08-21 12:50:30 -04001927 if (app == null) {
1928 Slog.w(TAG, "Failed making new process record for "
1929 + processName + "/" + info.uid + " isolated=" + isolated);
1930 return null;
1931 }
1932 app.crashHandler = crashHandler;
1933 app.isolatedEntryPoint = entryPoint;
1934 app.isolatedEntryPointArgs = entryPointArgs;
1935 checkSlow(startTime, "startProcess: done creating new process record");
1936 } else {
1937 // If this is a new package in the process, add the package to the list
Dianne Hackborn6f30f182019-05-23 15:41:41 -07001938 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
Amith Yamasani98a00922018-08-21 12:50:30 -04001939 checkSlow(startTime, "startProcess: added package to existing proc");
1940 }
1941
1942 // If the system is not ready yet, then hold off on starting this
1943 // process until it is.
1944 if (!mService.mProcessesReady
1945 && !mService.isAllowedWhileBooting(info)
1946 && !allowWhileBooting) {
1947 if (!mService.mProcessesOnHold.contains(app)) {
1948 mService.mProcessesOnHold.add(app);
1949 }
1950 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
1951 "System not ready, putting on hold: " + app);
1952 checkSlow(startTime, "startProcess: returning with proc on hold");
1953 return app;
1954 }
1955
1956 checkSlow(startTime, "startProcess: stepping in to startProcess");
Martijn Coenene8431c22019-03-28 14:09:38 +01001957 final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
Amith Yamasani98a00922018-08-21 12:50:30 -04001958 checkSlow(startTime, "startProcess: done starting proc!");
1959 return success ? app : null;
1960 }
1961
1962 @GuardedBy("mService")
1963 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
1964 StringBuilder sb = null;
1965 if (app.killedByAm) {
1966 if (sb == null) sb = new StringBuilder();
1967 sb.append("killedByAm=true;");
1968 }
1969 if (mProcessNames.get(app.processName, app.uid) != app) {
1970 if (sb == null) sb = new StringBuilder();
1971 sb.append("No entry in mProcessNames;");
1972 }
1973 if (!app.pendingStart) {
1974 if (sb == null) sb = new StringBuilder();
1975 sb.append("pendingStart=false;");
1976 }
1977 if (app.startSeq > expectedStartSeq) {
1978 if (sb == null) sb = new StringBuilder();
1979 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
1980 }
1981 return sb == null ? null : sb.toString();
1982 }
1983
1984 @GuardedBy("mService")
1985 private boolean handleProcessStartedLocked(ProcessRecord pending,
1986 Process.ProcessStartResult startResult, long expectedStartSeq) {
1987 // Indicates that this process start has been taken care of.
1988 if (mPendingStarts.get(expectedStartSeq) == null) {
1989 if (pending.pid == startResult.pid) {
1990 pending.setUsingWrapper(startResult.usingWrapper);
1991 // TODO: Update already existing clients of usingWrapper
1992 }
1993 return false;
1994 }
1995 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
1996 expectedStartSeq, false);
1997 }
1998
1999 @GuardedBy("mService")
2000 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
2001 long expectedStartSeq, boolean procAttached) {
2002 mPendingStarts.remove(expectedStartSeq);
2003 final String reason = isProcStartValidLocked(app, expectedStartSeq);
2004 if (reason != null) {
2005 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
2006 pid
2007 + ", " + reason);
2008 app.pendingStart = false;
2009 killProcessQuiet(pid);
2010 Process.killProcessGroup(app.uid, app.pid);
2011 return false;
2012 }
2013 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2014 checkSlow(app.startTime, "startProcess: done updating battery stats");
2015
2016 EventLog.writeEvent(EventLogTags.AM_PROC_START,
2017 UserHandle.getUserId(app.startUid), pid, app.startUid,
Martijn Coenene8431c22019-03-28 14:09:38 +01002018 app.processName, app.hostingRecord.getType(),
2019 app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
Amith Yamasani98a00922018-08-21 12:50:30 -04002020
2021 try {
2022 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
2023 app.seInfo, app.info.sourceDir, pid);
2024 } catch (RemoteException ex) {
2025 // Ignore
2026 }
2027
2028 if (app.isPersistent()) {
2029 Watchdog.getInstance().processStarted(app.processName, pid);
2030 }
2031
2032 checkSlow(app.startTime, "startProcess: building log message");
2033 StringBuilder buf = mStringBuilder;
2034 buf.setLength(0);
2035 buf.append("Start proc ");
2036 buf.append(pid);
2037 buf.append(':');
2038 buf.append(app.processName);
2039 buf.append('/');
2040 UserHandle.formatUid(buf, app.startUid);
2041 if (app.isolatedEntryPoint != null) {
2042 buf.append(" [");
2043 buf.append(app.isolatedEntryPoint);
2044 buf.append("]");
2045 }
2046 buf.append(" for ");
Martijn Coenene8431c22019-03-28 14:09:38 +01002047 buf.append(app.hostingRecord.getType());
2048 if (app.hostingRecord.getName() != null) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002049 buf.append(" ");
Martijn Coenene8431c22019-03-28 14:09:38 +01002050 buf.append(app.hostingRecord.getName());
Amith Yamasani98a00922018-08-21 12:50:30 -04002051 }
2052 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
2053 app.setPid(pid);
2054 app.setUsingWrapper(usingWrapper);
2055 app.pendingStart = false;
2056 checkSlow(app.startTime, "startProcess: starting to update pids map");
2057 ProcessRecord oldApp;
2058 synchronized (mService.mPidsSelfLocked) {
2059 oldApp = mService.mPidsSelfLocked.get(pid);
2060 }
2061 // If there is already an app occupying that pid that hasn't been cleaned up
2062 if (oldApp != null && !app.isolated) {
2063 // Clean up anything relating to this pid first
Hui Yu6dabda82019-05-07 14:02:57 -07002064 Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
2065 + " startSeq:" + app.startSeq
2066 + " pid:" + pid
2067 + " belongs to another existing app:" + oldApp.processName
2068 + " startSeq:" + oldApp.startSeq);
Amith Yamasani98a00922018-08-21 12:50:30 -04002069 mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
2070 true /*replacingPid*/);
2071 }
Hui Yu6dabda82019-05-07 14:02:57 -07002072 mService.mPidsSelfLocked.put(app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002073 synchronized (mService.mPidsSelfLocked) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002074 if (!procAttached) {
2075 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2076 msg.obj = app;
2077 mService.mHandler.sendMessageDelayed(msg, usingWrapper
2078 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2079 }
2080 }
2081 checkSlow(app.startTime, "startProcess: done updating pids map");
2082 return true;
2083 }
2084
2085 final void removeLruProcessLocked(ProcessRecord app) {
2086 int lrui = mLruProcesses.lastIndexOf(app);
2087 if (lrui >= 0) {
2088 if (!app.killed) {
2089 if (app.isPersistent()) {
2090 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2091 } else {
2092 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2093 if (app.pid > 0) {
2094 killProcessQuiet(app.pid);
2095 ProcessList.killProcessGroup(app.uid, app.pid);
2096 } else {
2097 app.pendingStart = false;
2098 }
2099 }
2100 }
Jing Ji6bd77ab2019-08-20 16:49:08 -07002101 if (lrui < mLruProcessActivityStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002102 mLruProcessActivityStart--;
2103 }
Jing Ji6bd77ab2019-08-20 16:49:08 -07002104 if (lrui < mLruProcessServiceStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002105 mLruProcessServiceStart--;
2106 }
2107 mLruProcesses.remove(lrui);
2108 }
2109 }
2110
Riddle Hsuaaef7312019-01-24 19:00:58 +08002111 @GuardedBy("mService")
2112 boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
2113 String reason) {
2114 return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
2115 false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2116 false /* evenPersistent */, false /* setRemoved */, reason);
Amith Yamasani98a00922018-08-21 12:50:30 -04002117 }
2118
2119 @GuardedBy("mService")
2120 final boolean killPackageProcessesLocked(String packageName, int appId,
2121 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
Riddle Hsuaaef7312019-01-24 19:00:58 +08002122 boolean doit, boolean evenPersistent, boolean setRemoved, String reason) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002123 ArrayList<ProcessRecord> procs = new ArrayList<>();
2124
2125 // Remove all processes this package may have touched: all with the
2126 // same UID (except for the system or root user), and all whose name
2127 // matches the package name.
2128 final int NP = mProcessNames.getMap().size();
2129 for (int ip = 0; ip < NP; ip++) {
2130 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2131 final int NA = apps.size();
2132 for (int ia = 0; ia < NA; ia++) {
2133 ProcessRecord app = apps.valueAt(ia);
2134 if (app.isPersistent() && !evenPersistent) {
2135 // we don't kill persistent processes
2136 continue;
2137 }
2138 if (app.removed) {
2139 if (doit) {
2140 procs.add(app);
2141 }
2142 continue;
2143 }
2144
2145 // Skip process if it doesn't meet our oom adj requirement.
2146 if (app.setAdj < minOomAdj) {
Riddle Hsu4405d8a2019-03-06 22:09:32 +08002147 // Note it is still possible to have a process with oom adj 0 in the killed
2148 // processes, but it does not mean misjudgment. E.g. a bound service process
2149 // and its client activity process are both in the background, so they are
2150 // collected to be killed. If the client activity is killed first, the service
2151 // may be scheduled to unbind and become an executing service (oom adj 0).
Amith Yamasani98a00922018-08-21 12:50:30 -04002152 continue;
2153 }
2154
2155 // If no package is specified, we call all processes under the
2156 // give user id.
2157 if (packageName == null) {
2158 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2159 continue;
2160 }
2161 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2162 continue;
2163 }
2164 // Package has been specified, we want to hit all processes
2165 // that match it. We need to qualify this by the processes
2166 // that are running under the specified app and user ID.
2167 } else {
2168 final boolean isDep = app.pkgDeps != null
2169 && app.pkgDeps.contains(packageName);
2170 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2171 continue;
2172 }
2173 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2174 continue;
2175 }
2176 if (!app.pkgList.containsKey(packageName) && !isDep) {
2177 continue;
2178 }
2179 }
2180
2181 // Process has passed all conditions, kill it!
2182 if (!doit) {
2183 return true;
2184 }
Riddle Hsuaaef7312019-01-24 19:00:58 +08002185 if (setRemoved) {
2186 app.removed = true;
2187 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002188 procs.add(app);
2189 }
2190 }
2191
2192 int N = procs.size();
2193 for (int i=0; i<N; i++) {
2194 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
2195 }
Martijn Coenen378b2702019-02-20 10:33:41 +01002196 // See if there are any app zygotes running for this packageName / UID combination,
2197 // and kill it if so.
2198 final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2199 for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2200 for (int i = 0; i < appZygotes.size(); ++i) {
2201 final int appZygoteUid = appZygotes.keyAt(i);
2202 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2203 continue;
2204 }
2205 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2206 continue;
2207 }
2208 final AppZygote appZygote = appZygotes.valueAt(i);
2209 if (packageName != null
2210 && !packageName.equals(appZygote.getAppInfo().packageName)) {
2211 continue;
2212 }
2213 zygotesToKill.add(appZygote);
2214 }
2215 }
2216 for (AppZygote appZygote : zygotesToKill) {
2217 killAppZygoteIfNeededLocked(appZygote);
2218 }
Amith Yamasanid2775cd2019-04-12 15:47:54 -07002219 mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
Amith Yamasani98a00922018-08-21 12:50:30 -04002220 return N > 0;
2221 }
Amith Yamasanid2775cd2019-04-12 15:47:54 -07002222
Amith Yamasani98a00922018-08-21 12:50:30 -04002223 @GuardedBy("mService")
2224 boolean removeProcessLocked(ProcessRecord app,
2225 boolean callerWillRestart, boolean allowRestart, String reason) {
2226 final String name = app.processName;
2227 final int uid = app.uid;
2228 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
2229 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
2230
2231 ProcessRecord old = mProcessNames.get(name, uid);
2232 if (old != app) {
2233 // This process is no longer active, so nothing to do.
2234 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
2235 return false;
2236 }
2237 removeProcessNameLocked(name, uid);
2238 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
2239
2240 boolean needRestart = false;
2241 if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
2242 .pendingStart)) {
2243 int pid = app.pid;
2244 if (pid > 0) {
Hui Yu6dabda82019-05-07 14:02:57 -07002245 mService.mPidsSelfLocked.remove(app);
Wale Ogunwale0b940842018-12-03 06:58:11 -08002246 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002247 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2248 if (app.isolated) {
2249 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2250 mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
2251 }
2252 }
2253 boolean willRestart = false;
2254 if (app.isPersistent() && !app.isolated) {
2255 if (!callerWillRestart) {
2256 willRestart = true;
2257 } else {
2258 needRestart = true;
2259 }
2260 }
2261 app.kill(reason, true);
2262 mService.handleAppDiedLocked(app, willRestart, allowRestart);
2263 if (willRestart) {
2264 removeLruProcessLocked(app);
2265 mService.addAppLocked(app.info, null, false, null /* ABI override */);
2266 }
2267 } else {
2268 mRemovedProcesses.add(app);
2269 }
2270
2271 return needRestart;
2272 }
2273
2274 @GuardedBy("mService")
2275 final void addProcessNameLocked(ProcessRecord proc) {
2276 // We shouldn't already have a process under this name, but just in case we
2277 // need to clean up whatever may be there now.
2278 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
2279 if (old == proc && proc.isPersistent()) {
2280 // We are re-adding a persistent process. Whatevs! Just leave it there.
2281 Slog.w(TAG, "Re-adding persistent process " + proc);
2282 } else if (old != null) {
2283 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
2284 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08002285 UidRecord uidRec = mActiveUids.get(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002286 if (uidRec == null) {
Riddle Hsud7088f82019-01-30 13:04:50 +08002287 uidRec = new UidRecord(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002288 // This is the first appearance of the uid, report it now!
2289 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2290 "Creating new process uid: " + uidRec);
2291 if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
2292 UserHandle.getAppId(proc.uid)) >= 0
2293 || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
2294 uidRec.setWhitelist = uidRec.curWhitelist = true;
2295 }
2296 uidRec.updateHasInternetPermission();
Amith Yamasaniaa746442019-01-10 10:09:12 -08002297 mActiveUids.put(proc.uid, uidRec);
Amith Yamasani98a00922018-08-21 12:50:30 -04002298 EventLogTags.writeAmUidRunning(uidRec.uid);
Wale Ogunwalebff2df42018-10-18 17:09:19 -07002299 mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
Amith Yamasani98a00922018-08-21 12:50:30 -04002300 }
2301 proc.uidRecord = uidRec;
2302
2303 // Reset render thread tid if it was already set, so new process can set it again.
2304 proc.renderThreadTid = 0;
2305 uidRec.numProcs++;
2306 mProcessNames.put(proc.processName, proc.uid, proc);
2307 if (proc.isolated) {
2308 mIsolatedProcesses.put(proc.uid, proc);
2309 }
2310 }
2311
2312 @GuardedBy("mService")
Martijn Coenen01e719b2018-12-05 16:01:38 +01002313 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002314 HostingRecord hostingRecord) {
2315 if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01002316 // Allocate an isolated UID from the global range
2317 return mGlobalIsolatedUids;
2318 } else {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002319 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
2320 info.processName, hostingRecord.getDefiningUid());
Martijn Coenen01e719b2018-12-05 16:01:38 +01002321 }
2322 }
2323
2324 @GuardedBy("mService")
Amith Yamasani98a00922018-08-21 12:50:30 -04002325 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002326 boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002327 String proc = customProcess != null ? customProcess : info.processName;
2328 final int userId = UserHandle.getUserId(info.uid);
2329 int uid = info.uid;
2330 if (isolated) {
2331 if (isolatedUid == 0) {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002332 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
Martijn Coenen01e719b2018-12-05 16:01:38 +01002333 if (uidRange == null) {
2334 return null;
2335 }
2336 uid = uidRange.allocateIsolatedUidLocked(userId);
2337 if (uid == -1) {
2338 return null;
Amith Yamasani98a00922018-08-21 12:50:30 -04002339 }
2340 } else {
2341 // Special case for startIsolatedProcess (internal only), where
2342 // the uid of the isolated process is specified by the caller.
2343 uid = isolatedUid;
2344 }
2345 mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
2346
2347 // Register the isolated UID with this application so BatteryStats knows to
2348 // attribute resource usage to the application.
2349 //
2350 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
2351 // about the process state of the isolated UID *before* it is registered with the
2352 // owning application.
2353 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
2354 StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
2355 StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
2356 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002357 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002358
2359 if (!mService.mBooted && !mService.mBooting
2360 && userId == UserHandle.USER_SYSTEM
2361 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
2362 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
2363 r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
2364 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
2365 r.setPersistent(true);
2366 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
2367 }
2368 if (isolated && isolatedUid != 0) {
2369 // Special case for startIsolatedProcess (internal only) - assume the process
2370 // is required by the system server to prevent it being killed.
2371 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
2372 }
2373 addProcessNameLocked(r);
2374 return r;
2375 }
2376
2377 @GuardedBy("mService")
2378 final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
2379 return removeProcessNameLocked(name, uid, null);
2380 }
2381
2382 @GuardedBy("mService")
2383 final ProcessRecord removeProcessNameLocked(final String name, final int uid,
2384 final ProcessRecord expecting) {
2385 ProcessRecord old = mProcessNames.get(name, uid);
2386 // Only actually remove when the currently recorded value matches the
2387 // record that we expected; if it doesn't match then we raced with a
2388 // newly created process and we don't want to destroy the new one.
2389 if ((expecting == null) || (old == expecting)) {
2390 mProcessNames.remove(name, uid);
2391 }
2392 if (old != null && old.uidRecord != null) {
2393 old.uidRecord.numProcs--;
2394 if (old.uidRecord.numProcs == 0) {
2395 // No more processes using this uid, tell clients it is gone.
2396 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2397 "No more processes in " + old.uidRecord);
2398 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
2399 EventLogTags.writeAmUidStopped(uid);
Amith Yamasaniaa746442019-01-10 10:09:12 -08002400 mActiveUids.remove(uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002401 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
2402 }
2403 old.uidRecord = null;
2404 }
2405 mIsolatedProcesses.remove(uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +01002406 mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002407 // Remove the (expected) ProcessRecord from the app zygote
2408 final ProcessRecord record = expecting != null ? expecting : old;
Martijn Coenen01e719b2018-12-05 16:01:38 +01002409 if (record != null && record.appZygote) {
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002410 removeProcessFromAppZygoteLocked(record);
2411 }
2412
Amith Yamasani98a00922018-08-21 12:50:30 -04002413 return old;
2414 }
2415
2416 /** Call setCoreSettings on all LRU processes, with the new settings. */
2417 @GuardedBy("mService")
2418 void updateCoreSettingsLocked(Bundle settings) {
2419 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2420 ProcessRecord processRecord = mLruProcesses.get(i);
2421 try {
2422 if (processRecord.thread != null) {
2423 processRecord.thread.setCoreSettings(settings);
2424 }
2425 } catch (RemoteException re) {
2426 /* ignore */
2427 }
2428 }
2429 }
2430
2431 /**
2432 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2433 * procstate lower than maxProcState.
2434 * @param minTargetSdk
2435 * @param maxProcState
2436 */
2437 @GuardedBy("mService")
2438 void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2439 final ArrayList<ProcessRecord> procs = new ArrayList<>();
2440 final int NP = mProcessNames.getMap().size();
2441 for (int ip = 0; ip < NP; ip++) {
2442 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2443 final int NA = apps.size();
2444 for (int ia = 0; ia < NA; ia++) {
2445 final ProcessRecord app = apps.valueAt(ia);
Riddle Hsuaaef7312019-01-24 19:00:58 +08002446 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2447 && (maxProcState < 0 || app.setProcState > maxProcState))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002448 procs.add(app);
2449 }
2450 }
2451 }
2452
2453 final int N = procs.size();
2454 for (int i = 0; i < N; i++) {
2455 removeProcessLocked(procs.get(i), false, true, "kill all background except");
2456 }
2457 }
2458
2459 /**
2460 * Call updateTimePrefs on all LRU processes
2461 * @param timePref The time pref to pass to each process
2462 */
2463 @GuardedBy("mService")
2464 void updateAllTimePrefsLocked(int timePref) {
2465 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2466 ProcessRecord r = mLruProcesses.get(i);
2467 if (r.thread != null) {
2468 try {
2469 r.thread.updateTimePrefs(timePref);
2470 } catch (RemoteException ex) {
2471 Slog.w(TAG, "Failed to update preferences for: "
2472 + r.info.processName);
2473 }
2474 }
2475 }
2476 }
2477
Irina Dumitrescu34a27c42019-04-15 19:20:38 +01002478 void setAllHttpProxy() {
2479 // Update the HTTP proxy for each application thread.
2480 synchronized (mService) {
2481 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2482 ProcessRecord r = mLruProcesses.get(i);
2483 // Don't dispatch to isolated processes as they can't access ConnectivityManager and
2484 // don't have network privileges anyway. Exclude system server and update it
2485 // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
2486 if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) {
2487 try {
2488 r.thread.updateHttpProxy();
2489 } catch (RemoteException ex) {
2490 Slog.w(TAG, "Failed to update http proxy for: "
2491 + r.info.processName);
2492 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002493 }
2494 }
2495 }
Irina Dumitrescu34a27c42019-04-15 19:20:38 +01002496 ActivityThread.updateHttpProxy(mService.mContext);
Amith Yamasani98a00922018-08-21 12:50:30 -04002497 }
2498
2499 @GuardedBy("mService")
2500 void clearAllDnsCacheLocked() {
2501 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2502 ProcessRecord r = mLruProcesses.get(i);
2503 if (r.thread != null) {
2504 try {
2505 r.thread.clearDnsCache();
2506 } catch (RemoteException ex) {
2507 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2508 }
2509 }
2510 }
2511 }
2512
2513 @GuardedBy("mService")
2514 void handleAllTrustStorageUpdateLocked() {
2515 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2516 ProcessRecord r = mLruProcesses.get(i);
2517 if (r.thread != null) {
2518 try {
2519 r.thread.handleTrustStorageUpdate();
2520 } catch (RemoteException ex) {
2521 Slog.w(TAG, "Failed to handle trust storage update for: " +
2522 r.info.processName);
2523 }
2524 }
2525 }
2526 }
2527
2528 @GuardedBy("mService")
2529 int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
Dianne Hackborna631d562018-11-20 15:58:15 -08002530 int lruSeq, String what, Object obj, ProcessRecord srcApp) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002531 app.lastActivityTime = now;
2532
2533 if (app.hasActivitiesOrRecentTasks()) {
2534 // Don't want to touch dependent processes that are hosting activities.
2535 return index;
2536 }
2537
2538 int lrui = mLruProcesses.lastIndexOf(app);
2539 if (lrui < 0) {
2540 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2541 + what + " " + obj + " from " + srcApp);
2542 return index;
2543 }
2544
2545 if (lrui >= index) {
2546 // Don't want to cause this to move dependent processes *back* in the
2547 // list as if they were less frequently used.
2548 return index;
2549 }
2550
Dianne Hackborna631d562018-11-20 15:58:15 -08002551 if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002552 // Don't want to touch dependent processes that are hosting activities.
2553 return index;
2554 }
2555
2556 mLruProcesses.remove(lrui);
2557 if (index > 0) {
2558 index--;
2559 }
2560 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2561 + " in LRU list: " + app);
2562 mLruProcesses.add(index, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002563 app.lruSeq = lruSeq;
Amith Yamasani98a00922018-08-21 12:50:30 -04002564 return index;
2565 }
2566
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002567 /**
2568 * Handle the case where we are inserting a process hosting client activities:
2569 * Make sure any groups have their order match their importance, and take care of
2570 * distributing old clients across other activity processes so they can't spam
2571 * the LRU list. Processing of the list will be restricted by the indices provided,
2572 * and not extend out of them.
2573 *
2574 * @param topApp The app at the top that has just been inserted in to the list.
2575 * @param topI The position in the list where topApp was inserted; this is the start (at the
2576 * top) where we are going to do our processing.
2577 * @param bottomI The last position at which we will be processing; this is the end position
2578 * of whichever section of the LRU list we are in. Nothing past it will be
2579 * touched.
2580 * @param endIndex The current end of the top being processed. Typically topI - 1. That is,
2581 * where we are going to start potentially adjusting other entries in the list.
2582 */
2583 private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
2584 final int bottomI, int endIndex) {
2585 if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
2586 || !topApp.hasClientActivities()) {
2587 // If this is not a special process that has client activities, then there is
2588 // nothing to do.
2589 return;
2590 }
2591
2592 final int uid = topApp.info.uid;
2593 if (topApp.connectionGroup > 0) {
2594 int endImportance = topApp.connectionImportance;
2595 for (int i = endIndex; i >= bottomI; i--) {
2596 final ProcessRecord subProc = mLruProcesses.get(i);
2597 if (subProc.info.uid == uid
2598 && subProc.connectionGroup == topApp.connectionGroup) {
2599 if (i == endIndex && subProc.connectionImportance >= endImportance) {
2600 // This process is already in the group, and its importance
2601 // is not as strong as the process before it, so keep it
2602 // correctly positioned in the group.
2603 if (DEBUG_LRU) Slog.d(TAG_LRU,
2604 "Keeping in-place above " + subProc
2605 + " endImportance=" + endImportance
2606 + " group=" + subProc.connectionGroup
2607 + " importance=" + subProc.connectionImportance);
2608 endIndex--;
2609 endImportance = subProc.connectionImportance;
2610 } else {
2611 // We want to pull this up to be with the rest of the group,
2612 // and order within the group by importance.
2613 if (DEBUG_LRU) Slog.d(TAG_LRU,
2614 "Pulling up " + subProc
2615 + " to position in group with importance="
2616 + subProc.connectionImportance);
2617 boolean moved = false;
2618 for (int pos = topI; pos > endIndex; pos--) {
2619 final ProcessRecord posProc = mLruProcesses.get(pos);
2620 if (subProc.connectionImportance
2621 <= posProc.connectionImportance) {
2622 mLruProcesses.remove(i);
2623 mLruProcesses.add(pos, subProc);
2624 if (DEBUG_LRU) Slog.d(TAG_LRU,
2625 "Moving " + subProc
2626 + " from position " + i + " to above " + posProc
2627 + " @ " + pos);
2628 moved = true;
2629 endIndex--;
2630 break;
2631 }
2632 }
2633 if (!moved) {
2634 // Goes to the end of the group.
2635 mLruProcesses.remove(i);
Jing Ji6bd77ab2019-08-20 16:49:08 -07002636 mLruProcesses.add(endIndex, subProc);
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002637 if (DEBUG_LRU) Slog.d(TAG_LRU,
2638 "Moving " + subProc
2639 + " from position " + i + " to end of group @ "
2640 + endIndex);
2641 endIndex--;
2642 endImportance = subProc.connectionImportance;
2643 }
2644 }
2645 }
2646 }
2647
2648 }
2649 // To keep it from spamming the LRU list (by making a bunch of clients),
2650 // we will distribute other entries owned by it to be in-between other apps.
2651 int i = endIndex;
2652 while (i >= bottomI) {
2653 ProcessRecord subProc = mLruProcesses.get(i);
2654 if (DEBUG_LRU) Slog.d(TAG_LRU,
2655 "Looking to spread old procs, at " + subProc + " @ " + i);
2656 if (subProc.info.uid != uid) {
2657 // This is a different app... if we have gone through some of the
2658 // target app, pull this up to be before them. We want to pull up
2659 // one activity process, but any number of non-activity processes.
2660 if (i < endIndex) {
2661 boolean hasActivity = false;
2662 int connUid = 0;
2663 int connGroup = 0;
2664 while (i >= bottomI) {
2665 mLruProcesses.remove(i);
2666 mLruProcesses.add(endIndex, subProc);
2667 if (DEBUG_LRU) Slog.d(TAG_LRU,
2668 "Different app, moving to " + endIndex);
2669 i--;
2670 if (i < bottomI) {
2671 break;
2672 }
2673 subProc = mLruProcesses.get(i);
2674 if (DEBUG_LRU) Slog.d(TAG_LRU,
2675 "Looking at next app at " + i + ": " + subProc);
2676 if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
2677 if (DEBUG_LRU) Slog.d(TAG_LRU,
2678 "This is hosting an activity!");
2679 if (hasActivity) {
2680 // Already found an activity, done.
2681 if (DEBUG_LRU) Slog.d(TAG_LRU,
2682 "Already found an activity, done");
2683 break;
2684 }
2685 hasActivity = true;
2686 } else if (subProc.hasClientActivities()) {
2687 if (DEBUG_LRU) Slog.d(TAG_LRU,
2688 "This is a client of an activity");
2689 if (hasActivity) {
2690 if (connUid == 0 || connUid != subProc.info.uid) {
2691 // Already have an activity that is not from from a client
2692 // connection or is a different client connection, done.
2693 if (DEBUG_LRU) Slog.d(TAG_LRU,
2694 "Already found a different activity: connUid="
2695 + connUid + " uid=" + subProc.info.uid);
2696 break;
2697 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
2698 // Previously saw a different group or not from a group,
2699 // want to treat these as different things.
2700 if (DEBUG_LRU) Slog.d(TAG_LRU,
2701 "Already found a different group: connGroup="
2702 + connGroup + " group=" + subProc.connectionGroup);
2703 break;
2704 }
2705 } else {
2706 if (DEBUG_LRU) Slog.d(TAG_LRU,
2707 "This is an activity client! uid="
2708 + subProc.info.uid + " group=" + subProc.connectionGroup);
2709 hasActivity = true;
2710 connUid = subProc.info.uid;
2711 connGroup = subProc.connectionGroup;
2712 }
2713 }
2714 endIndex--;
2715 }
2716 }
2717 // Find the end of the next group of processes for target app. This
2718 // is after any entries of different apps (so we don't change the existing
2719 // relative order of apps) and then after the next last group of processes
2720 // of the target app.
2721 for (endIndex--; endIndex >= bottomI; endIndex--) {
2722 final ProcessRecord endProc = mLruProcesses.get(endIndex);
2723 if (endProc.info.uid == uid) {
2724 if (DEBUG_LRU) Slog.d(TAG_LRU,
2725 "Found next group of app: " + endProc + " @ "
2726 + endIndex);
2727 break;
2728 }
2729 }
2730 if (endIndex >= bottomI) {
2731 final ProcessRecord endProc = mLruProcesses.get(endIndex);
2732 for (endIndex--; endIndex >= bottomI; endIndex--) {
2733 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
2734 if (nextEndProc.info.uid != uid
2735 || nextEndProc.connectionGroup != endProc.connectionGroup) {
2736 if (DEBUG_LRU) Slog.d(TAG_LRU,
2737 "Found next group or app: " + nextEndProc + " @ "
2738 + endIndex + " group=" + nextEndProc.connectionGroup);
2739 break;
2740 }
2741 }
2742 }
2743 if (DEBUG_LRU) Slog.d(TAG_LRU,
2744 "Bumping scan position to " + endIndex);
2745 i = endIndex;
2746 } else {
2747 i--;
2748 }
2749 }
2750 }
2751
Amith Yamasani98a00922018-08-21 12:50:30 -04002752 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2753 ProcessRecord client) {
2754 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
2755 || app.treatLikeActivity;
2756 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2757 if (!activityChange && hasActivity) {
2758 // The process has activities, so we are only allowing activity-based adjustments
2759 // to move it. It should be kept in the front of the list with other
2760 // processes that have activities, and we don't want those to change their
2761 // order except due to activity operations.
2762 return;
2763 }
2764
2765 mLruSeq++;
2766 final long now = SystemClock.uptimeMillis();
2767 app.lastActivityTime = now;
2768
2769 // First a quick reject: if the app is already at the position we will
2770 // put it, then there is nothing to do.
2771 if (hasActivity) {
2772 final int N = mLruProcesses.size();
2773 if (N > 0 && mLruProcesses.get(N - 1) == app) {
2774 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2775 return;
2776 }
2777 } else {
2778 if (mLruProcessServiceStart > 0
2779 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2780 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2781 return;
2782 }
2783 }
2784
2785 int lrui = mLruProcesses.lastIndexOf(app);
2786
2787 if (app.isPersistent() && lrui >= 0) {
2788 // We don't care about the position of persistent processes, as long as
2789 // they are in the list.
2790 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2791 return;
2792 }
2793
2794 /* In progress: compute new position first, so we can avoid doing work
2795 if the process is not actually going to move. Not yet working.
2796 int addIndex;
2797 int nextIndex;
2798 boolean inActivity = false, inService = false;
2799 if (hasActivity) {
2800 // Process has activities, put it at the very tipsy-top.
2801 addIndex = mLruProcesses.size();
2802 nextIndex = mLruProcessServiceStart;
2803 inActivity = true;
2804 } else if (hasService) {
2805 // Process has services, put it at the top of the service list.
2806 addIndex = mLruProcessActivityStart;
2807 nextIndex = mLruProcessServiceStart;
2808 inActivity = true;
2809 inService = true;
2810 } else {
2811 // Process not otherwise of interest, it goes to the top of the non-service area.
2812 addIndex = mLruProcessServiceStart;
2813 if (client != null) {
2814 int clientIndex = mLruProcesses.lastIndexOf(client);
2815 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2816 + app);
2817 if (clientIndex >= 0 && addIndex > clientIndex) {
2818 addIndex = clientIndex;
2819 }
2820 }
2821 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2822 }
2823
2824 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2825 + mLruProcessActivityStart + "): " + app);
2826 */
2827
2828 if (lrui >= 0) {
2829 if (lrui < mLruProcessActivityStart) {
2830 mLruProcessActivityStart--;
2831 }
2832 if (lrui < mLruProcessServiceStart) {
2833 mLruProcessServiceStart--;
2834 }
2835 /*
2836 if (addIndex > lrui) {
2837 addIndex--;
2838 }
2839 if (nextIndex > lrui) {
2840 nextIndex--;
2841 }
2842 */
2843 mLruProcesses.remove(lrui);
2844 }
2845
2846 /*
2847 mLruProcesses.add(addIndex, app);
2848 if (inActivity) {
2849 mLruProcessActivityStart++;
2850 }
2851 if (inService) {
2852 mLruProcessActivityStart++;
2853 }
2854 */
2855
2856 int nextIndex;
Dianne Hackborna631d562018-11-20 15:58:15 -08002857 int nextActivityIndex = -1;
Amith Yamasani98a00922018-08-21 12:50:30 -04002858 if (hasActivity) {
2859 final int N = mLruProcesses.size();
Dianne Hackborna631d562018-11-20 15:58:15 -08002860 nextIndex = mLruProcessServiceStart;
2861 if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
Amith Yamasani98a00922018-08-21 12:50:30 -04002862 && mLruProcessActivityStart < (N - 1)) {
2863 // Process doesn't have activities, but has clients with
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002864 // activities... move it up, but below the app that is binding to it.
Amith Yamasani98a00922018-08-21 12:50:30 -04002865 if (DEBUG_LRU) Slog.d(TAG_LRU,
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002866 "Adding to second-top of LRU activity list: " + app
2867 + " group=" + app.connectionGroup
2868 + " importance=" + app.connectionImportance);
2869 int pos = N - 1;
2870 while (pos > mLruProcessActivityStart) {
2871 final ProcessRecord posproc = mLruProcesses.get(pos);
2872 if (posproc.info.uid == app.info.uid) {
2873 // Technically this app could have multiple processes with different
2874 // activities and so we should be looking for the actual process that
2875 // is bound to the target proc... but I don't really care, do you?
2876 break;
2877 }
2878 pos--;
2879 }
2880 mLruProcesses.add(pos, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002881 // If this process is part of a group, need to pull up any other processes
2882 // in that group to be with it.
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002883 int endIndex = pos - 1;
2884 if (endIndex < mLruProcessActivityStart) {
2885 endIndex = mLruProcessActivityStart;
Dianne Hackborna631d562018-11-20 15:58:15 -08002886 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002887 nextActivityIndex = endIndex;
2888 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
Amith Yamasani98a00922018-08-21 12:50:30 -04002889 } else {
2890 // Process has activities, put it at the very tipsy-top.
2891 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2892 mLruProcesses.add(app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002893 nextActivityIndex = mLruProcesses.size() - 1;
Amith Yamasani98a00922018-08-21 12:50:30 -04002894 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002895 } else if (hasService) {
2896 // Process has services, put it at the top of the service list.
2897 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2898 mLruProcesses.add(mLruProcessActivityStart, app);
2899 nextIndex = mLruProcessServiceStart;
2900 mLruProcessActivityStart++;
2901 } else {
2902 // Process not otherwise of interest, it goes to the top of the non-service area.
2903 int index = mLruProcessServiceStart;
2904 if (client != null) {
2905 // If there is a client, don't allow the process to be moved up higher
2906 // in the list than that client.
2907 int clientIndex = mLruProcesses.lastIndexOf(client);
2908 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2909 + " when updating " + app);
2910 if (clientIndex <= lrui) {
2911 // Don't allow the client index restriction to push it down farther in the
2912 // list than it already is.
2913 clientIndex = lrui;
2914 }
2915 if (clientIndex >= 0 && index > clientIndex) {
2916 index = clientIndex;
2917 }
2918 }
2919 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2920 mLruProcesses.add(index, app);
2921 nextIndex = index - 1;
2922 mLruProcessActivityStart++;
2923 mLruProcessServiceStart++;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002924 if (index > 1) {
2925 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
2926 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002927 }
2928
Dianne Hackborna631d562018-11-20 15:58:15 -08002929 app.lruSeq = mLruSeq;
2930
Amith Yamasani98a00922018-08-21 12:50:30 -04002931 // If the app is currently using a content provider or service,
2932 // bump those processes as well.
2933 for (int j = app.connections.size() - 1; j >= 0; j--) {
2934 ConnectionRecord cr = app.connections.valueAt(j);
2935 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2936 && cr.binding.service.app != null
2937 && cr.binding.service.app.lruSeq != mLruSeq
Dianne Hackborna631d562018-11-20 15:58:15 -08002938 && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
Amith Yamasani98a00922018-08-21 12:50:30 -04002939 && !cr.binding.service.app.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08002940 if (cr.binding.service.app.hasClientActivities()) {
2941 if (nextActivityIndex >= 0) {
2942 nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2943 now,
2944 nextActivityIndex, mLruSeq,
2945 "service connection", cr, app);
2946 }
2947 } else {
2948 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2949 now,
2950 nextIndex, mLruSeq,
2951 "service connection", cr, app);
2952 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002953 }
2954 }
2955 for (int j = app.conProviders.size() - 1; j >= 0; j--) {
2956 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2957 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08002958 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
Amith Yamasani98a00922018-08-21 12:50:30 -04002959 "provider reference", cpr, app);
2960 }
2961 }
2962 }
2963
2964 final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
2965 final IBinder threadBinder = thread.asBinder();
2966 // Find the application record.
2967 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2968 final ProcessRecord rec = mLruProcesses.get(i);
2969 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2970 return rec;
2971 }
2972 }
2973 return null;
2974 }
2975
2976 boolean haveBackgroundProcessLocked() {
2977 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2978 final ProcessRecord rec = mLruProcesses.get(i);
2979 if (rec.thread != null
2980 && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
2981 return true;
2982 }
2983 }
2984 return false;
2985 }
2986
2987 private static int procStateToImportance(int procState, int memAdj,
2988 ActivityManager.RunningAppProcessInfo currApp,
2989 int clientTargetSdk) {
2990 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
2991 procState, clientTargetSdk);
2992 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
2993 currApp.lru = memAdj;
2994 } else {
2995 currApp.lru = 0;
2996 }
2997 return imp;
2998 }
2999
3000 @GuardedBy("mService")
3001 void fillInProcMemInfoLocked(ProcessRecord app,
3002 ActivityManager.RunningAppProcessInfo outInfo,
3003 int clientTargetSdk) {
3004 outInfo.pid = app.pid;
3005 outInfo.uid = app.info.uid;
3006 if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
3007 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
3008 }
3009 if (app.isPersistent()) {
3010 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
3011 }
3012 if (app.hasActivities()) {
3013 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
3014 }
3015 outInfo.lastTrimLevel = app.trimMemoryLevel;
3016 int adj = app.curAdj;
3017 int procState = app.getCurProcState();
3018 outInfo.importance = procStateToImportance(procState, adj, outInfo,
3019 clientTargetSdk);
3020 outInfo.importanceReasonCode = app.adjTypeCode;
3021 outInfo.processState = app.getCurProcState();
3022 outInfo.isFocused = (app == mService.getTopAppLocked());
3023 outInfo.lastActivityTime = app.lastActivityTime;
3024 }
3025
3026 @GuardedBy("mService")
3027 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
3028 int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3029 // Lazy instantiation of list
3030 List<ActivityManager.RunningAppProcessInfo> runList = null;
3031
3032 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3033 ProcessRecord app = mLruProcesses.get(i);
3034 if ((!allUsers && app.userId != userId)
3035 || (!allUids && app.uid != callingUid)) {
3036 continue;
3037 }
3038 if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
3039 // Generate process state info for running application
3040 ActivityManager.RunningAppProcessInfo currApp =
3041 new ActivityManager.RunningAppProcessInfo(app.processName,
3042 app.pid, app.getPackageList());
3043 fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
3044 if (app.adjSource instanceof ProcessRecord) {
3045 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
3046 currApp.importanceReasonImportance =
3047 ActivityManager.RunningAppProcessInfo.procStateToImportance(
3048 app.adjSourceProcState);
Wale Ogunwale59507092018-10-29 09:00:30 -07003049 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
3050 final ActivityServiceConnectionsHolder r =
3051 (ActivityServiceConnectionsHolder) app.adjSource;
3052 final int pid = r.getActivityPid();
3053 if (pid != -1) {
3054 currApp.importanceReasonPid = pid;
3055 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003056 }
3057 if (app.adjTarget instanceof ComponentName) {
3058 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
3059 }
3060 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
3061 // + " lru=" + currApp.lru);
3062 if (runList == null) {
3063 runList = new ArrayList<>();
3064 }
3065 runList.add(currApp);
3066 }
3067 }
3068 return runList;
3069 }
3070
3071 @GuardedBy("mService")
3072 int getLruSizeLocked() {
3073 return mLruProcesses.size();
3074 }
3075
3076 @GuardedBy("mService")
3077 void dumpLruListHeaderLocked(PrintWriter pw) {
3078 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
3079 pw.print(" total, non-act at ");
3080 pw.print(mLruProcesses.size() - mLruProcessActivityStart);
3081 pw.print(", non-svc at ");
3082 pw.print(mLruProcesses.size() - mLruProcessServiceStart);
3083 pw.println("):");
3084 }
3085
3086 @GuardedBy("mService")
3087 ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
3088 ArrayList<ProcessRecord> procs;
3089 if (args != null && args.length > start
3090 && args[start].charAt(0) != '-') {
3091 procs = new ArrayList<ProcessRecord>();
3092 int pid = -1;
3093 try {
3094 pid = Integer.parseInt(args[start]);
3095 } catch (NumberFormatException e) {
3096 }
3097 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3098 ProcessRecord proc = mLruProcesses.get(i);
3099 if (proc.pid > 0 && proc.pid == pid) {
3100 procs.add(proc);
3101 } else if (allPkgs && proc.pkgList != null
3102 && proc.pkgList.containsKey(args[start])) {
3103 procs.add(proc);
3104 } else if (proc.processName.equals(args[start])) {
3105 procs.add(proc);
3106 }
3107 }
3108 if (procs.size() <= 0) {
3109 return null;
3110 }
3111 } else {
3112 procs = new ArrayList<ProcessRecord>(mLruProcesses);
3113 }
3114 return procs;
3115 }
3116
3117 @GuardedBy("mService")
3118 void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3119 boolean updateFrameworkRes) {
3120 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3121 final ProcessRecord app = mLruProcesses.get(i);
3122 if (app.thread == null) {
3123 continue;
3124 }
3125
3126 if (userId != UserHandle.USER_ALL && app.userId != userId) {
3127 continue;
3128 }
3129
3130 final int packageCount = app.pkgList.size();
3131 for (int j = 0; j < packageCount; j++) {
3132 final String packageName = app.pkgList.keyAt(j);
3133 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
3134 try {
3135 final ApplicationInfo ai = AppGlobals.getPackageManager()
3136 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3137 if (ai != null) {
3138 app.thread.scheduleApplicationInfoChanged(ai);
3139 }
3140 } catch (RemoteException e) {
3141 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3142 packageName, app));
3143 }
3144 }
3145 }
3146 }
3147 }
3148
3149 @GuardedBy("mService")
3150 void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
Winson23863be2019-04-04 17:41:28 -07003151 boolean foundProcess = false;
Amith Yamasani98a00922018-08-21 12:50:30 -04003152 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3153 ProcessRecord r = mLruProcesses.get(i);
3154 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3155 try {
Winson23863be2019-04-04 17:41:28 -07003156 for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
3157 if (packages[index].equals(r.info.packageName)) {
3158 foundProcess = true;
3159 }
3160 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003161 r.thread.dispatchPackageBroadcast(cmd, packages);
3162 } catch (RemoteException ex) {
3163 }
3164 }
3165 }
Winson23863be2019-04-04 17:41:28 -07003166
3167 if (!foundProcess) {
3168 try {
3169 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
3170 } catch (RemoteException ignored) {
3171 }
3172 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003173 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08003174
3175 /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3176 @GuardedBy("mService")
3177 int getUidProcStateLocked(int uid) {
3178 UidRecord uidRec = mActiveUids.get(uid);
3179 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3180 }
3181
3182 /** Returns the UidRecord for the given uid, if it exists. */
3183 @GuardedBy("mService")
3184 UidRecord getUidRecordLocked(int uid) {
3185 return mActiveUids.get(uid);
3186 }
3187
3188 /**
3189 * Call {@link ActivityManagerService#doStopUidLocked}
3190 * (which will also stop background services) for all idle UIDs.
3191 */
3192 @GuardedBy("mService")
3193 void doStopUidForIdleUidsLocked() {
3194 final int size = mActiveUids.size();
3195 for (int i = 0; i < size; i++) {
3196 final int uid = mActiveUids.keyAt(i);
3197 if (UserHandle.isCore(uid)) {
3198 continue;
3199 }
3200 final UidRecord uidRec = mActiveUids.valueAt(i);
3201 if (!uidRec.idle) {
3202 continue;
3203 }
3204 mService.doStopUidLocked(uidRec.uid, uidRec);
3205 }
3206 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07003207}