blob: 3c098d1a66536b4a762a0761f1553ae13c311bb0 [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.
1422 * @param app
Martijn Coenene8431c22019-03-28 14:09:38 +01001423 * @param hostingRecord
Amith Yamasani98a00922018-08-21 12:50:30 -04001424 * @param disableHiddenApiChecks
1425 * @param abiOverride
1426 */
1427 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01001428 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1429 boolean disableHiddenApiChecks, boolean mountExtStorageFull,
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001430 String abiOverride) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001431 if (app.pendingStart) {
1432 return true;
1433 }
1434 long startTime = SystemClock.elapsedRealtime();
1435 if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
1436 checkSlow(startTime, "startProcess: removing from pids map");
Hui Yu6dabda82019-05-07 14:02:57 -07001437 mService.mPidsSelfLocked.remove(app);
Wale Ogunwale0b940842018-12-03 06:58:11 -08001438 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04001439 checkSlow(startTime, "startProcess: done removing from pids map");
1440 app.setPid(0);
Hui Yu6dabda82019-05-07 14:02:57 -07001441 app.startSeq = 0;
Amith Yamasani98a00922018-08-21 12:50:30 -04001442 }
1443
1444 if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
1445 TAG_PROCESSES,
1446 "startProcessLocked removing on hold: " + app);
1447 mService.mProcessesOnHold.remove(app);
1448
1449 checkSlow(startTime, "startProcess: starting to update cpu stats");
1450 mService.updateCpuStats();
1451 checkSlow(startTime, "startProcess: done updating cpu stats");
1452
1453 try {
1454 try {
1455 final int userId = UserHandle.getUserId(app.uid);
1456 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
1457 } catch (RemoteException e) {
1458 throw e.rethrowAsRuntimeException();
1459 }
1460
1461 int uid = app.uid;
1462 int[] gids = null;
1463 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1464 if (!app.isolated) {
1465 int[] permGids = null;
1466 try {
1467 checkSlow(startTime, "startProcess: getting gids from package manager");
1468 final IPackageManager pm = AppGlobals.getPackageManager();
1469 permGids = pm.getPackageGids(app.info.packageName,
1470 MATCH_DIRECT_BOOT_AUTO, app.userId);
Jeff Sharkey10ec9d82018-11-28 14:52:45 -07001471 if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001472 mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
1473 } else {
1474 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1475 StorageManagerInternal.class);
1476 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
1477 app.info.packageName);
1478 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001479 } catch (RemoteException e) {
1480 throw e.rethrowAsRuntimeException();
1481 }
1482
1483 /*
1484 * Add shared application and profile GIDs so applications can share some
1485 * resources like shared libraries and access user-wide resources
1486 */
1487 if (ArrayUtils.isEmpty(permGids)) {
1488 gids = new int[3];
1489 } else {
1490 gids = new int[permGids.length + 3];
1491 System.arraycopy(permGids, 0, gids, 3, permGids.length);
1492 }
1493 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
1494 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
1495 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
1496
1497 // Replace any invalid GIDs
1498 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
1499 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
1500 }
Sudheer Shanka87915d62018-11-06 10:57:35 -08001501 app.mountMode = mountExternal;
Amith Yamasani98a00922018-08-21 12:50:30 -04001502 checkSlow(startTime, "startProcess: building args");
1503 if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
1504 uid = 0;
1505 }
1506 int runtimeFlags = 0;
1507 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1508 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
1509 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1510 // Also turn on CheckJNI for debuggable apps. It's quite
1511 // awkward to turn on otherwise.
1512 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
Alex Buynytskyy5d5921ee2019-01-22 15:22:55 -08001513
1514 // Check if the developer does not want ART verification
1515 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(),
1516 android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) {
1517 runtimeFlags |= Zygote.DISABLE_VERIFIER;
1518 Slog.w(TAG_PROCESSES, app + ": ART verification disabled");
1519 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001520 }
1521 // Run the app in safe mode if its manifest requests so or the
1522 // system is booted in safe mode.
1523 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1524 mService.mSafeMode == true) {
1525 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1526 }
Yabin Cui4d8546d2019-01-29 16:29:20 -08001527 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
1528 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
1529 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001530 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1531 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1532 }
1533 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1534 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1535 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1536 }
1537 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1538 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1539 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1540 }
1541 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1542 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1543 }
1544 if ("1".equals(SystemProperties.get("debug.assert"))) {
1545 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1546 }
randy.jeong3ea95802019-05-29 10:43:39 +09001547 if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) {
1548 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER;
1549 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001550 if (mService.mNativeDebuggingApp != null
1551 && mService.mNativeDebuggingApp.equals(app.processName)) {
1552 // Enable all debug flags required by the native debugger.
1553 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
1554 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1555 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
1556 mService.mNativeDebuggingApp = null;
1557 }
1558
Victor Hsiehfa9df0b2019-01-29 12:48:36 -08001559 if (app.info.isEmbeddedDexUsed()
Victor Hsiehe7b5a8d2018-11-16 10:27:06 -08001560 || (app.info.isPrivilegedApp()
1561 && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001562 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1563 }
1564
1565 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
1566 app.info.maybeUpdateHiddenApiEnforcementPolicy(
David Brazdil06ae4b82018-11-02 18:01:45 +00001567 mService.mHiddenApiBlacklist.getPolicy());
Amith Yamasani98a00922018-08-21 12:50:30 -04001568 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
1569 app.info.getHiddenApiEnforcementPolicy();
1570 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
1571 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
1572 throw new IllegalStateException("Invalid API policy: " + policy);
1573 }
1574 runtimeFlags |= policyBits;
1575 }
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,
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001848 false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
Amith Yamasani98a00922018-08-21 12:50:30 -04001849 }
1850
1851 @GuardedBy("mService")
1852 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
Martijn Coenene8431c22019-03-28 14:09:38 +01001853 boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04001854 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
1855 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
1856 long startTime = SystemClock.elapsedRealtime();
1857 ProcessRecord app;
1858 if (!isolated) {
1859 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
1860 checkSlow(startTime, "startProcess: after getProcessRecord");
1861
1862 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
1863 // If we are in the background, then check to see if this process
1864 // is bad. If so, we will just silently fail.
1865 if (mService.mAppErrors.isBadProcessLocked(info)) {
1866 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1867 + "/" + info.processName);
1868 return null;
1869 }
1870 } else {
1871 // When the user is explicitly starting a process, then clear its
1872 // crash count so that we won't make it bad until they see at
1873 // least one crash dialog again, and make the process good again
1874 // if it had been bad.
1875 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1876 + "/" + info.processName);
1877 mService.mAppErrors.resetProcessCrashTimeLocked(info);
1878 if (mService.mAppErrors.isBadProcessLocked(info)) {
1879 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
1880 UserHandle.getUserId(info.uid), info.uid,
1881 info.processName);
1882 mService.mAppErrors.clearBadProcessLocked(info);
1883 if (app != null) {
1884 app.bad = false;
1885 }
1886 }
1887 }
1888 } else {
1889 // If this is an isolated process, it can't re-use an existing process.
1890 app = null;
1891 }
1892
1893 // We don't have to do anything more if:
1894 // (1) There is an existing application record; and
1895 // (2) The caller doesn't think it is dead, OR there is no thread
1896 // object attached to it so we know it couldn't have crashed; and
1897 // (3) There is a pid assigned to it, so it is either starting or
1898 // already running.
1899 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
1900 + " app=" + app + " knownToBeDead=" + knownToBeDead
1901 + " thread=" + (app != null ? app.thread : null)
1902 + " pid=" + (app != null ? app.pid : -1));
1903 if (app != null && app.pid > 0) {
1904 if ((!knownToBeDead && !app.killed) || app.thread == null) {
1905 // We already have the app running, or are waiting for it to
1906 // come up (we have a pid but not yet its thread), so keep it.
1907 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
1908 // If this is a new package in the process, add the package to the list
Dianne Hackborn6f30f182019-05-23 15:41:41 -07001909 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
Amith Yamasani98a00922018-08-21 12:50:30 -04001910 checkSlow(startTime, "startProcess: done, added package to proc");
1911 return app;
1912 }
1913
1914 // An application record is attached to a previous process,
1915 // clean it up now.
1916 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
1917 checkSlow(startTime, "startProcess: bad proc running, killing");
1918 ProcessList.killProcessGroup(app.uid, app.pid);
1919 mService.handleAppDiedLocked(app, true, true);
1920 checkSlow(startTime, "startProcess: done killing old proc");
1921 }
1922
Amith Yamasani98a00922018-08-21 12:50:30 -04001923 if (app == null) {
1924 checkSlow(startTime, "startProcess: creating new process record");
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001925 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
Amith Yamasani98a00922018-08-21 12:50:30 -04001926 if (app == null) {
1927 Slog.w(TAG, "Failed making new process record for "
1928 + processName + "/" + info.uid + " isolated=" + isolated);
1929 return null;
1930 }
1931 app.crashHandler = crashHandler;
1932 app.isolatedEntryPoint = entryPoint;
1933 app.isolatedEntryPointArgs = entryPointArgs;
1934 checkSlow(startTime, "startProcess: done creating new process record");
1935 } else {
1936 // If this is a new package in the process, add the package to the list
Dianne Hackborn6f30f182019-05-23 15:41:41 -07001937 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
Amith Yamasani98a00922018-08-21 12:50:30 -04001938 checkSlow(startTime, "startProcess: added package to existing proc");
1939 }
1940
1941 // If the system is not ready yet, then hold off on starting this
1942 // process until it is.
1943 if (!mService.mProcessesReady
1944 && !mService.isAllowedWhileBooting(info)
1945 && !allowWhileBooting) {
1946 if (!mService.mProcessesOnHold.contains(app)) {
1947 mService.mProcessesOnHold.add(app);
1948 }
1949 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
1950 "System not ready, putting on hold: " + app);
1951 checkSlow(startTime, "startProcess: returning with proc on hold");
1952 return app;
1953 }
1954
1955 checkSlow(startTime, "startProcess: stepping in to startProcess");
Martijn Coenene8431c22019-03-28 14:09:38 +01001956 final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
Amith Yamasani98a00922018-08-21 12:50:30 -04001957 checkSlow(startTime, "startProcess: done starting proc!");
1958 return success ? app : null;
1959 }
1960
1961 @GuardedBy("mService")
1962 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
1963 StringBuilder sb = null;
1964 if (app.killedByAm) {
1965 if (sb == null) sb = new StringBuilder();
1966 sb.append("killedByAm=true;");
1967 }
1968 if (mProcessNames.get(app.processName, app.uid) != app) {
1969 if (sb == null) sb = new StringBuilder();
1970 sb.append("No entry in mProcessNames;");
1971 }
1972 if (!app.pendingStart) {
1973 if (sb == null) sb = new StringBuilder();
1974 sb.append("pendingStart=false;");
1975 }
1976 if (app.startSeq > expectedStartSeq) {
1977 if (sb == null) sb = new StringBuilder();
1978 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
1979 }
1980 return sb == null ? null : sb.toString();
1981 }
1982
1983 @GuardedBy("mService")
1984 private boolean handleProcessStartedLocked(ProcessRecord pending,
1985 Process.ProcessStartResult startResult, long expectedStartSeq) {
1986 // Indicates that this process start has been taken care of.
1987 if (mPendingStarts.get(expectedStartSeq) == null) {
1988 if (pending.pid == startResult.pid) {
1989 pending.setUsingWrapper(startResult.usingWrapper);
1990 // TODO: Update already existing clients of usingWrapper
1991 }
1992 return false;
1993 }
1994 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
1995 expectedStartSeq, false);
1996 }
1997
1998 @GuardedBy("mService")
1999 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
2000 long expectedStartSeq, boolean procAttached) {
2001 mPendingStarts.remove(expectedStartSeq);
2002 final String reason = isProcStartValidLocked(app, expectedStartSeq);
2003 if (reason != null) {
2004 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
2005 pid
2006 + ", " + reason);
2007 app.pendingStart = false;
2008 killProcessQuiet(pid);
2009 Process.killProcessGroup(app.uid, app.pid);
2010 return false;
2011 }
2012 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2013 checkSlow(app.startTime, "startProcess: done updating battery stats");
2014
2015 EventLog.writeEvent(EventLogTags.AM_PROC_START,
2016 UserHandle.getUserId(app.startUid), pid, app.startUid,
Martijn Coenene8431c22019-03-28 14:09:38 +01002017 app.processName, app.hostingRecord.getType(),
2018 app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
Amith Yamasani98a00922018-08-21 12:50:30 -04002019
2020 try {
2021 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
2022 app.seInfo, app.info.sourceDir, pid);
2023 } catch (RemoteException ex) {
2024 // Ignore
2025 }
2026
2027 if (app.isPersistent()) {
2028 Watchdog.getInstance().processStarted(app.processName, pid);
2029 }
2030
2031 checkSlow(app.startTime, "startProcess: building log message");
2032 StringBuilder buf = mStringBuilder;
2033 buf.setLength(0);
2034 buf.append("Start proc ");
2035 buf.append(pid);
2036 buf.append(':');
2037 buf.append(app.processName);
2038 buf.append('/');
2039 UserHandle.formatUid(buf, app.startUid);
2040 if (app.isolatedEntryPoint != null) {
2041 buf.append(" [");
2042 buf.append(app.isolatedEntryPoint);
2043 buf.append("]");
2044 }
2045 buf.append(" for ");
Martijn Coenene8431c22019-03-28 14:09:38 +01002046 buf.append(app.hostingRecord.getType());
2047 if (app.hostingRecord.getName() != null) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002048 buf.append(" ");
Martijn Coenene8431c22019-03-28 14:09:38 +01002049 buf.append(app.hostingRecord.getName());
Amith Yamasani98a00922018-08-21 12:50:30 -04002050 }
2051 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
2052 app.setPid(pid);
2053 app.setUsingWrapper(usingWrapper);
2054 app.pendingStart = false;
2055 checkSlow(app.startTime, "startProcess: starting to update pids map");
2056 ProcessRecord oldApp;
2057 synchronized (mService.mPidsSelfLocked) {
2058 oldApp = mService.mPidsSelfLocked.get(pid);
2059 }
2060 // If there is already an app occupying that pid that hasn't been cleaned up
2061 if (oldApp != null && !app.isolated) {
2062 // Clean up anything relating to this pid first
Hui Yu6dabda82019-05-07 14:02:57 -07002063 Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
2064 + " startSeq:" + app.startSeq
2065 + " pid:" + pid
2066 + " belongs to another existing app:" + oldApp.processName
2067 + " startSeq:" + oldApp.startSeq);
Amith Yamasani98a00922018-08-21 12:50:30 -04002068 mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
2069 true /*replacingPid*/);
2070 }
Hui Yu6dabda82019-05-07 14:02:57 -07002071 mService.mPidsSelfLocked.put(app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002072 synchronized (mService.mPidsSelfLocked) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002073 if (!procAttached) {
2074 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2075 msg.obj = app;
2076 mService.mHandler.sendMessageDelayed(msg, usingWrapper
2077 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2078 }
2079 }
2080 checkSlow(app.startTime, "startProcess: done updating pids map");
2081 return true;
2082 }
2083
2084 final void removeLruProcessLocked(ProcessRecord app) {
2085 int lrui = mLruProcesses.lastIndexOf(app);
2086 if (lrui >= 0) {
2087 if (!app.killed) {
2088 if (app.isPersistent()) {
2089 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2090 } else {
2091 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2092 if (app.pid > 0) {
2093 killProcessQuiet(app.pid);
2094 ProcessList.killProcessGroup(app.uid, app.pid);
2095 } else {
2096 app.pendingStart = false;
2097 }
2098 }
2099 }
Jing Ji6bd77ab2019-08-20 16:49:08 -07002100 if (lrui < mLruProcessActivityStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002101 mLruProcessActivityStart--;
2102 }
Jing Ji6bd77ab2019-08-20 16:49:08 -07002103 if (lrui < mLruProcessServiceStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002104 mLruProcessServiceStart--;
2105 }
2106 mLruProcesses.remove(lrui);
2107 }
2108 }
2109
Riddle Hsuaaef7312019-01-24 19:00:58 +08002110 @GuardedBy("mService")
2111 boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
2112 String reason) {
2113 return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
2114 false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2115 false /* evenPersistent */, false /* setRemoved */, reason);
Amith Yamasani98a00922018-08-21 12:50:30 -04002116 }
2117
2118 @GuardedBy("mService")
2119 final boolean killPackageProcessesLocked(String packageName, int appId,
2120 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
Riddle Hsuaaef7312019-01-24 19:00:58 +08002121 boolean doit, boolean evenPersistent, boolean setRemoved, String reason) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002122 ArrayList<ProcessRecord> procs = new ArrayList<>();
2123
2124 // Remove all processes this package may have touched: all with the
2125 // same UID (except for the system or root user), and all whose name
2126 // matches the package name.
2127 final int NP = mProcessNames.getMap().size();
2128 for (int ip = 0; ip < NP; ip++) {
2129 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2130 final int NA = apps.size();
2131 for (int ia = 0; ia < NA; ia++) {
2132 ProcessRecord app = apps.valueAt(ia);
2133 if (app.isPersistent() && !evenPersistent) {
2134 // we don't kill persistent processes
2135 continue;
2136 }
2137 if (app.removed) {
2138 if (doit) {
2139 procs.add(app);
2140 }
2141 continue;
2142 }
2143
2144 // Skip process if it doesn't meet our oom adj requirement.
2145 if (app.setAdj < minOomAdj) {
Riddle Hsu4405d8a2019-03-06 22:09:32 +08002146 // Note it is still possible to have a process with oom adj 0 in the killed
2147 // processes, but it does not mean misjudgment. E.g. a bound service process
2148 // and its client activity process are both in the background, so they are
2149 // collected to be killed. If the client activity is killed first, the service
2150 // may be scheduled to unbind and become an executing service (oom adj 0).
Amith Yamasani98a00922018-08-21 12:50:30 -04002151 continue;
2152 }
2153
2154 // If no package is specified, we call all processes under the
2155 // give user id.
2156 if (packageName == null) {
2157 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2158 continue;
2159 }
2160 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2161 continue;
2162 }
2163 // Package has been specified, we want to hit all processes
2164 // that match it. We need to qualify this by the processes
2165 // that are running under the specified app and user ID.
2166 } else {
2167 final boolean isDep = app.pkgDeps != null
2168 && app.pkgDeps.contains(packageName);
2169 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2170 continue;
2171 }
2172 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2173 continue;
2174 }
2175 if (!app.pkgList.containsKey(packageName) && !isDep) {
2176 continue;
2177 }
2178 }
2179
2180 // Process has passed all conditions, kill it!
2181 if (!doit) {
2182 return true;
2183 }
Riddle Hsuaaef7312019-01-24 19:00:58 +08002184 if (setRemoved) {
2185 app.removed = true;
2186 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002187 procs.add(app);
2188 }
2189 }
2190
2191 int N = procs.size();
2192 for (int i=0; i<N; i++) {
2193 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
2194 }
Martijn Coenen378b2702019-02-20 10:33:41 +01002195 // See if there are any app zygotes running for this packageName / UID combination,
2196 // and kill it if so.
2197 final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2198 for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2199 for (int i = 0; i < appZygotes.size(); ++i) {
2200 final int appZygoteUid = appZygotes.keyAt(i);
2201 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2202 continue;
2203 }
2204 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2205 continue;
2206 }
2207 final AppZygote appZygote = appZygotes.valueAt(i);
2208 if (packageName != null
2209 && !packageName.equals(appZygote.getAppInfo().packageName)) {
2210 continue;
2211 }
2212 zygotesToKill.add(appZygote);
2213 }
2214 }
2215 for (AppZygote appZygote : zygotesToKill) {
2216 killAppZygoteIfNeededLocked(appZygote);
2217 }
Amith Yamasanid2775cd2019-04-12 15:47:54 -07002218 mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
Amith Yamasani98a00922018-08-21 12:50:30 -04002219 return N > 0;
2220 }
Amith Yamasanid2775cd2019-04-12 15:47:54 -07002221
Amith Yamasani98a00922018-08-21 12:50:30 -04002222 @GuardedBy("mService")
2223 boolean removeProcessLocked(ProcessRecord app,
2224 boolean callerWillRestart, boolean allowRestart, String reason) {
2225 final String name = app.processName;
2226 final int uid = app.uid;
2227 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
2228 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
2229
2230 ProcessRecord old = mProcessNames.get(name, uid);
2231 if (old != app) {
2232 // This process is no longer active, so nothing to do.
2233 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
2234 return false;
2235 }
2236 removeProcessNameLocked(name, uid);
2237 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
2238
2239 boolean needRestart = false;
2240 if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
2241 .pendingStart)) {
2242 int pid = app.pid;
2243 if (pid > 0) {
Hui Yu6dabda82019-05-07 14:02:57 -07002244 mService.mPidsSelfLocked.remove(app);
Wale Ogunwale0b940842018-12-03 06:58:11 -08002245 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002246 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2247 if (app.isolated) {
2248 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2249 mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
2250 }
2251 }
2252 boolean willRestart = false;
2253 if (app.isPersistent() && !app.isolated) {
2254 if (!callerWillRestart) {
2255 willRestart = true;
2256 } else {
2257 needRestart = true;
2258 }
2259 }
2260 app.kill(reason, true);
2261 mService.handleAppDiedLocked(app, willRestart, allowRestart);
2262 if (willRestart) {
2263 removeLruProcessLocked(app);
2264 mService.addAppLocked(app.info, null, false, null /* ABI override */);
2265 }
2266 } else {
2267 mRemovedProcesses.add(app);
2268 }
2269
2270 return needRestart;
2271 }
2272
2273 @GuardedBy("mService")
2274 final void addProcessNameLocked(ProcessRecord proc) {
2275 // We shouldn't already have a process under this name, but just in case we
2276 // need to clean up whatever may be there now.
2277 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
2278 if (old == proc && proc.isPersistent()) {
2279 // We are re-adding a persistent process. Whatevs! Just leave it there.
2280 Slog.w(TAG, "Re-adding persistent process " + proc);
2281 } else if (old != null) {
2282 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
2283 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08002284 UidRecord uidRec = mActiveUids.get(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002285 if (uidRec == null) {
Riddle Hsud7088f82019-01-30 13:04:50 +08002286 uidRec = new UidRecord(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002287 // This is the first appearance of the uid, report it now!
2288 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2289 "Creating new process uid: " + uidRec);
2290 if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
2291 UserHandle.getAppId(proc.uid)) >= 0
2292 || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
2293 uidRec.setWhitelist = uidRec.curWhitelist = true;
2294 }
2295 uidRec.updateHasInternetPermission();
Amith Yamasaniaa746442019-01-10 10:09:12 -08002296 mActiveUids.put(proc.uid, uidRec);
Amith Yamasani98a00922018-08-21 12:50:30 -04002297 EventLogTags.writeAmUidRunning(uidRec.uid);
Wale Ogunwalebff2df42018-10-18 17:09:19 -07002298 mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
Amith Yamasani98a00922018-08-21 12:50:30 -04002299 }
2300 proc.uidRecord = uidRec;
2301
2302 // Reset render thread tid if it was already set, so new process can set it again.
2303 proc.renderThreadTid = 0;
2304 uidRec.numProcs++;
2305 mProcessNames.put(proc.processName, proc.uid, proc);
2306 if (proc.isolated) {
2307 mIsolatedProcesses.put(proc.uid, proc);
2308 }
2309 }
2310
2311 @GuardedBy("mService")
Martijn Coenen01e719b2018-12-05 16:01:38 +01002312 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002313 HostingRecord hostingRecord) {
2314 if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01002315 // Allocate an isolated UID from the global range
2316 return mGlobalIsolatedUids;
2317 } else {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002318 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
2319 info.processName, hostingRecord.getDefiningUid());
Martijn Coenen01e719b2018-12-05 16:01:38 +01002320 }
2321 }
2322
2323 @GuardedBy("mService")
Amith Yamasani98a00922018-08-21 12:50:30 -04002324 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002325 boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002326 String proc = customProcess != null ? customProcess : info.processName;
2327 final int userId = UserHandle.getUserId(info.uid);
2328 int uid = info.uid;
2329 if (isolated) {
2330 if (isolatedUid == 0) {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002331 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
Martijn Coenen01e719b2018-12-05 16:01:38 +01002332 if (uidRange == null) {
2333 return null;
2334 }
2335 uid = uidRange.allocateIsolatedUidLocked(userId);
2336 if (uid == -1) {
2337 return null;
Amith Yamasani98a00922018-08-21 12:50:30 -04002338 }
2339 } else {
2340 // Special case for startIsolatedProcess (internal only), where
2341 // the uid of the isolated process is specified by the caller.
2342 uid = isolatedUid;
2343 }
2344 mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
2345
2346 // Register the isolated UID with this application so BatteryStats knows to
2347 // attribute resource usage to the application.
2348 //
2349 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
2350 // about the process state of the isolated UID *before* it is registered with the
2351 // owning application.
2352 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
2353 StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
2354 StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
2355 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002356 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002357
2358 if (!mService.mBooted && !mService.mBooting
2359 && userId == UserHandle.USER_SYSTEM
2360 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
2361 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
2362 r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
2363 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
2364 r.setPersistent(true);
2365 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
2366 }
2367 if (isolated && isolatedUid != 0) {
2368 // Special case for startIsolatedProcess (internal only) - assume the process
2369 // is required by the system server to prevent it being killed.
2370 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
2371 }
2372 addProcessNameLocked(r);
2373 return r;
2374 }
2375
2376 @GuardedBy("mService")
2377 final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
2378 return removeProcessNameLocked(name, uid, null);
2379 }
2380
2381 @GuardedBy("mService")
2382 final ProcessRecord removeProcessNameLocked(final String name, final int uid,
2383 final ProcessRecord expecting) {
2384 ProcessRecord old = mProcessNames.get(name, uid);
2385 // Only actually remove when the currently recorded value matches the
2386 // record that we expected; if it doesn't match then we raced with a
2387 // newly created process and we don't want to destroy the new one.
2388 if ((expecting == null) || (old == expecting)) {
2389 mProcessNames.remove(name, uid);
2390 }
2391 if (old != null && old.uidRecord != null) {
2392 old.uidRecord.numProcs--;
2393 if (old.uidRecord.numProcs == 0) {
2394 // No more processes using this uid, tell clients it is gone.
2395 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2396 "No more processes in " + old.uidRecord);
2397 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
2398 EventLogTags.writeAmUidStopped(uid);
Amith Yamasaniaa746442019-01-10 10:09:12 -08002399 mActiveUids.remove(uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002400 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
2401 }
2402 old.uidRecord = null;
2403 }
2404 mIsolatedProcesses.remove(uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +01002405 mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002406 // Remove the (expected) ProcessRecord from the app zygote
2407 final ProcessRecord record = expecting != null ? expecting : old;
Martijn Coenen01e719b2018-12-05 16:01:38 +01002408 if (record != null && record.appZygote) {
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002409 removeProcessFromAppZygoteLocked(record);
2410 }
2411
Amith Yamasani98a00922018-08-21 12:50:30 -04002412 return old;
2413 }
2414
2415 /** Call setCoreSettings on all LRU processes, with the new settings. */
2416 @GuardedBy("mService")
2417 void updateCoreSettingsLocked(Bundle settings) {
2418 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2419 ProcessRecord processRecord = mLruProcesses.get(i);
2420 try {
2421 if (processRecord.thread != null) {
2422 processRecord.thread.setCoreSettings(settings);
2423 }
2424 } catch (RemoteException re) {
2425 /* ignore */
2426 }
2427 }
2428 }
2429
2430 /**
2431 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2432 * procstate lower than maxProcState.
2433 * @param minTargetSdk
2434 * @param maxProcState
2435 */
2436 @GuardedBy("mService")
2437 void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2438 final ArrayList<ProcessRecord> procs = new ArrayList<>();
2439 final int NP = mProcessNames.getMap().size();
2440 for (int ip = 0; ip < NP; ip++) {
2441 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2442 final int NA = apps.size();
2443 for (int ia = 0; ia < NA; ia++) {
2444 final ProcessRecord app = apps.valueAt(ia);
Riddle Hsuaaef7312019-01-24 19:00:58 +08002445 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2446 && (maxProcState < 0 || app.setProcState > maxProcState))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002447 procs.add(app);
2448 }
2449 }
2450 }
2451
2452 final int N = procs.size();
2453 for (int i = 0; i < N; i++) {
2454 removeProcessLocked(procs.get(i), false, true, "kill all background except");
2455 }
2456 }
2457
2458 /**
2459 * Call updateTimePrefs on all LRU processes
2460 * @param timePref The time pref to pass to each process
2461 */
2462 @GuardedBy("mService")
2463 void updateAllTimePrefsLocked(int timePref) {
2464 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2465 ProcessRecord r = mLruProcesses.get(i);
2466 if (r.thread != null) {
2467 try {
2468 r.thread.updateTimePrefs(timePref);
2469 } catch (RemoteException ex) {
2470 Slog.w(TAG, "Failed to update preferences for: "
2471 + r.info.processName);
2472 }
2473 }
2474 }
2475 }
2476
Irina Dumitrescu34a27c42019-04-15 19:20:38 +01002477 void setAllHttpProxy() {
2478 // Update the HTTP proxy for each application thread.
2479 synchronized (mService) {
2480 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2481 ProcessRecord r = mLruProcesses.get(i);
2482 // Don't dispatch to isolated processes as they can't access ConnectivityManager and
2483 // don't have network privileges anyway. Exclude system server and update it
2484 // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
2485 if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) {
2486 try {
2487 r.thread.updateHttpProxy();
2488 } catch (RemoteException ex) {
2489 Slog.w(TAG, "Failed to update http proxy for: "
2490 + r.info.processName);
2491 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002492 }
2493 }
2494 }
Irina Dumitrescu34a27c42019-04-15 19:20:38 +01002495 ActivityThread.updateHttpProxy(mService.mContext);
Amith Yamasani98a00922018-08-21 12:50:30 -04002496 }
2497
2498 @GuardedBy("mService")
2499 void clearAllDnsCacheLocked() {
2500 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2501 ProcessRecord r = mLruProcesses.get(i);
2502 if (r.thread != null) {
2503 try {
2504 r.thread.clearDnsCache();
2505 } catch (RemoteException ex) {
2506 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2507 }
2508 }
2509 }
2510 }
2511
2512 @GuardedBy("mService")
2513 void handleAllTrustStorageUpdateLocked() {
2514 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2515 ProcessRecord r = mLruProcesses.get(i);
2516 if (r.thread != null) {
2517 try {
2518 r.thread.handleTrustStorageUpdate();
2519 } catch (RemoteException ex) {
2520 Slog.w(TAG, "Failed to handle trust storage update for: " +
2521 r.info.processName);
2522 }
2523 }
2524 }
2525 }
2526
2527 @GuardedBy("mService")
2528 int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
Dianne Hackborna631d562018-11-20 15:58:15 -08002529 int lruSeq, String what, Object obj, ProcessRecord srcApp) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002530 app.lastActivityTime = now;
2531
2532 if (app.hasActivitiesOrRecentTasks()) {
2533 // Don't want to touch dependent processes that are hosting activities.
2534 return index;
2535 }
2536
2537 int lrui = mLruProcesses.lastIndexOf(app);
2538 if (lrui < 0) {
2539 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2540 + what + " " + obj + " from " + srcApp);
2541 return index;
2542 }
2543
2544 if (lrui >= index) {
2545 // Don't want to cause this to move dependent processes *back* in the
2546 // list as if they were less frequently used.
2547 return index;
2548 }
2549
Dianne Hackborna631d562018-11-20 15:58:15 -08002550 if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002551 // Don't want to touch dependent processes that are hosting activities.
2552 return index;
2553 }
2554
2555 mLruProcesses.remove(lrui);
2556 if (index > 0) {
2557 index--;
2558 }
2559 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2560 + " in LRU list: " + app);
2561 mLruProcesses.add(index, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002562 app.lruSeq = lruSeq;
Amith Yamasani98a00922018-08-21 12:50:30 -04002563 return index;
2564 }
2565
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002566 /**
2567 * Handle the case where we are inserting a process hosting client activities:
2568 * Make sure any groups have their order match their importance, and take care of
2569 * distributing old clients across other activity processes so they can't spam
2570 * the LRU list. Processing of the list will be restricted by the indices provided,
2571 * and not extend out of them.
2572 *
2573 * @param topApp The app at the top that has just been inserted in to the list.
2574 * @param topI The position in the list where topApp was inserted; this is the start (at the
2575 * top) where we are going to do our processing.
2576 * @param bottomI The last position at which we will be processing; this is the end position
2577 * of whichever section of the LRU list we are in. Nothing past it will be
2578 * touched.
2579 * @param endIndex The current end of the top being processed. Typically topI - 1. That is,
2580 * where we are going to start potentially adjusting other entries in the list.
2581 */
2582 private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
2583 final int bottomI, int endIndex) {
2584 if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
2585 || !topApp.hasClientActivities()) {
2586 // If this is not a special process that has client activities, then there is
2587 // nothing to do.
2588 return;
2589 }
2590
2591 final int uid = topApp.info.uid;
2592 if (topApp.connectionGroup > 0) {
2593 int endImportance = topApp.connectionImportance;
2594 for (int i = endIndex; i >= bottomI; i--) {
2595 final ProcessRecord subProc = mLruProcesses.get(i);
2596 if (subProc.info.uid == uid
2597 && subProc.connectionGroup == topApp.connectionGroup) {
2598 if (i == endIndex && subProc.connectionImportance >= endImportance) {
2599 // This process is already in the group, and its importance
2600 // is not as strong as the process before it, so keep it
2601 // correctly positioned in the group.
2602 if (DEBUG_LRU) Slog.d(TAG_LRU,
2603 "Keeping in-place above " + subProc
2604 + " endImportance=" + endImportance
2605 + " group=" + subProc.connectionGroup
2606 + " importance=" + subProc.connectionImportance);
2607 endIndex--;
2608 endImportance = subProc.connectionImportance;
2609 } else {
2610 // We want to pull this up to be with the rest of the group,
2611 // and order within the group by importance.
2612 if (DEBUG_LRU) Slog.d(TAG_LRU,
2613 "Pulling up " + subProc
2614 + " to position in group with importance="
2615 + subProc.connectionImportance);
2616 boolean moved = false;
2617 for (int pos = topI; pos > endIndex; pos--) {
2618 final ProcessRecord posProc = mLruProcesses.get(pos);
2619 if (subProc.connectionImportance
2620 <= posProc.connectionImportance) {
2621 mLruProcesses.remove(i);
2622 mLruProcesses.add(pos, subProc);
2623 if (DEBUG_LRU) Slog.d(TAG_LRU,
2624 "Moving " + subProc
2625 + " from position " + i + " to above " + posProc
2626 + " @ " + pos);
2627 moved = true;
2628 endIndex--;
2629 break;
2630 }
2631 }
2632 if (!moved) {
2633 // Goes to the end of the group.
2634 mLruProcesses.remove(i);
Jing Ji6bd77ab2019-08-20 16:49:08 -07002635 mLruProcesses.add(endIndex, subProc);
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002636 if (DEBUG_LRU) Slog.d(TAG_LRU,
2637 "Moving " + subProc
2638 + " from position " + i + " to end of group @ "
2639 + endIndex);
2640 endIndex--;
2641 endImportance = subProc.connectionImportance;
2642 }
2643 }
2644 }
2645 }
2646
2647 }
2648 // To keep it from spamming the LRU list (by making a bunch of clients),
2649 // we will distribute other entries owned by it to be in-between other apps.
2650 int i = endIndex;
2651 while (i >= bottomI) {
2652 ProcessRecord subProc = mLruProcesses.get(i);
2653 if (DEBUG_LRU) Slog.d(TAG_LRU,
2654 "Looking to spread old procs, at " + subProc + " @ " + i);
2655 if (subProc.info.uid != uid) {
2656 // This is a different app... if we have gone through some of the
2657 // target app, pull this up to be before them. We want to pull up
2658 // one activity process, but any number of non-activity processes.
2659 if (i < endIndex) {
2660 boolean hasActivity = false;
2661 int connUid = 0;
2662 int connGroup = 0;
2663 while (i >= bottomI) {
2664 mLruProcesses.remove(i);
2665 mLruProcesses.add(endIndex, subProc);
2666 if (DEBUG_LRU) Slog.d(TAG_LRU,
2667 "Different app, moving to " + endIndex);
2668 i--;
2669 if (i < bottomI) {
2670 break;
2671 }
2672 subProc = mLruProcesses.get(i);
2673 if (DEBUG_LRU) Slog.d(TAG_LRU,
2674 "Looking at next app at " + i + ": " + subProc);
2675 if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
2676 if (DEBUG_LRU) Slog.d(TAG_LRU,
2677 "This is hosting an activity!");
2678 if (hasActivity) {
2679 // Already found an activity, done.
2680 if (DEBUG_LRU) Slog.d(TAG_LRU,
2681 "Already found an activity, done");
2682 break;
2683 }
2684 hasActivity = true;
2685 } else if (subProc.hasClientActivities()) {
2686 if (DEBUG_LRU) Slog.d(TAG_LRU,
2687 "This is a client of an activity");
2688 if (hasActivity) {
2689 if (connUid == 0 || connUid != subProc.info.uid) {
2690 // Already have an activity that is not from from a client
2691 // connection or is a different client connection, done.
2692 if (DEBUG_LRU) Slog.d(TAG_LRU,
2693 "Already found a different activity: connUid="
2694 + connUid + " uid=" + subProc.info.uid);
2695 break;
2696 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
2697 // Previously saw a different group or not from a group,
2698 // want to treat these as different things.
2699 if (DEBUG_LRU) Slog.d(TAG_LRU,
2700 "Already found a different group: connGroup="
2701 + connGroup + " group=" + subProc.connectionGroup);
2702 break;
2703 }
2704 } else {
2705 if (DEBUG_LRU) Slog.d(TAG_LRU,
2706 "This is an activity client! uid="
2707 + subProc.info.uid + " group=" + subProc.connectionGroup);
2708 hasActivity = true;
2709 connUid = subProc.info.uid;
2710 connGroup = subProc.connectionGroup;
2711 }
2712 }
2713 endIndex--;
2714 }
2715 }
2716 // Find the end of the next group of processes for target app. This
2717 // is after any entries of different apps (so we don't change the existing
2718 // relative order of apps) and then after the next last group of processes
2719 // of the target app.
2720 for (endIndex--; endIndex >= bottomI; endIndex--) {
2721 final ProcessRecord endProc = mLruProcesses.get(endIndex);
2722 if (endProc.info.uid == uid) {
2723 if (DEBUG_LRU) Slog.d(TAG_LRU,
2724 "Found next group of app: " + endProc + " @ "
2725 + endIndex);
2726 break;
2727 }
2728 }
2729 if (endIndex >= bottomI) {
2730 final ProcessRecord endProc = mLruProcesses.get(endIndex);
2731 for (endIndex--; endIndex >= bottomI; endIndex--) {
2732 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
2733 if (nextEndProc.info.uid != uid
2734 || nextEndProc.connectionGroup != endProc.connectionGroup) {
2735 if (DEBUG_LRU) Slog.d(TAG_LRU,
2736 "Found next group or app: " + nextEndProc + " @ "
2737 + endIndex + " group=" + nextEndProc.connectionGroup);
2738 break;
2739 }
2740 }
2741 }
2742 if (DEBUG_LRU) Slog.d(TAG_LRU,
2743 "Bumping scan position to " + endIndex);
2744 i = endIndex;
2745 } else {
2746 i--;
2747 }
2748 }
2749 }
2750
Amith Yamasani98a00922018-08-21 12:50:30 -04002751 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2752 ProcessRecord client) {
2753 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
2754 || app.treatLikeActivity;
2755 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2756 if (!activityChange && hasActivity) {
2757 // The process has activities, so we are only allowing activity-based adjustments
2758 // to move it. It should be kept in the front of the list with other
2759 // processes that have activities, and we don't want those to change their
2760 // order except due to activity operations.
2761 return;
2762 }
2763
2764 mLruSeq++;
2765 final long now = SystemClock.uptimeMillis();
2766 app.lastActivityTime = now;
2767
2768 // First a quick reject: if the app is already at the position we will
2769 // put it, then there is nothing to do.
2770 if (hasActivity) {
2771 final int N = mLruProcesses.size();
2772 if (N > 0 && mLruProcesses.get(N - 1) == app) {
2773 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2774 return;
2775 }
2776 } else {
2777 if (mLruProcessServiceStart > 0
2778 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2779 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2780 return;
2781 }
2782 }
2783
2784 int lrui = mLruProcesses.lastIndexOf(app);
2785
2786 if (app.isPersistent() && lrui >= 0) {
2787 // We don't care about the position of persistent processes, as long as
2788 // they are in the list.
2789 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2790 return;
2791 }
2792
2793 /* In progress: compute new position first, so we can avoid doing work
2794 if the process is not actually going to move. Not yet working.
2795 int addIndex;
2796 int nextIndex;
2797 boolean inActivity = false, inService = false;
2798 if (hasActivity) {
2799 // Process has activities, put it at the very tipsy-top.
2800 addIndex = mLruProcesses.size();
2801 nextIndex = mLruProcessServiceStart;
2802 inActivity = true;
2803 } else if (hasService) {
2804 // Process has services, put it at the top of the service list.
2805 addIndex = mLruProcessActivityStart;
2806 nextIndex = mLruProcessServiceStart;
2807 inActivity = true;
2808 inService = true;
2809 } else {
2810 // Process not otherwise of interest, it goes to the top of the non-service area.
2811 addIndex = mLruProcessServiceStart;
2812 if (client != null) {
2813 int clientIndex = mLruProcesses.lastIndexOf(client);
2814 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2815 + app);
2816 if (clientIndex >= 0 && addIndex > clientIndex) {
2817 addIndex = clientIndex;
2818 }
2819 }
2820 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2821 }
2822
2823 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2824 + mLruProcessActivityStart + "): " + app);
2825 */
2826
2827 if (lrui >= 0) {
2828 if (lrui < mLruProcessActivityStart) {
2829 mLruProcessActivityStart--;
2830 }
2831 if (lrui < mLruProcessServiceStart) {
2832 mLruProcessServiceStart--;
2833 }
2834 /*
2835 if (addIndex > lrui) {
2836 addIndex--;
2837 }
2838 if (nextIndex > lrui) {
2839 nextIndex--;
2840 }
2841 */
2842 mLruProcesses.remove(lrui);
2843 }
2844
2845 /*
2846 mLruProcesses.add(addIndex, app);
2847 if (inActivity) {
2848 mLruProcessActivityStart++;
2849 }
2850 if (inService) {
2851 mLruProcessActivityStart++;
2852 }
2853 */
2854
2855 int nextIndex;
Dianne Hackborna631d562018-11-20 15:58:15 -08002856 int nextActivityIndex = -1;
Amith Yamasani98a00922018-08-21 12:50:30 -04002857 if (hasActivity) {
2858 final int N = mLruProcesses.size();
Dianne Hackborna631d562018-11-20 15:58:15 -08002859 nextIndex = mLruProcessServiceStart;
2860 if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
Amith Yamasani98a00922018-08-21 12:50:30 -04002861 && mLruProcessActivityStart < (N - 1)) {
2862 // Process doesn't have activities, but has clients with
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002863 // activities... move it up, but below the app that is binding to it.
Amith Yamasani98a00922018-08-21 12:50:30 -04002864 if (DEBUG_LRU) Slog.d(TAG_LRU,
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002865 "Adding to second-top of LRU activity list: " + app
2866 + " group=" + app.connectionGroup
2867 + " importance=" + app.connectionImportance);
2868 int pos = N - 1;
2869 while (pos > mLruProcessActivityStart) {
2870 final ProcessRecord posproc = mLruProcesses.get(pos);
2871 if (posproc.info.uid == app.info.uid) {
2872 // Technically this app could have multiple processes with different
2873 // activities and so we should be looking for the actual process that
2874 // is bound to the target proc... but I don't really care, do you?
2875 break;
2876 }
2877 pos--;
2878 }
2879 mLruProcesses.add(pos, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002880 // If this process is part of a group, need to pull up any other processes
2881 // in that group to be with it.
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002882 int endIndex = pos - 1;
2883 if (endIndex < mLruProcessActivityStart) {
2884 endIndex = mLruProcessActivityStart;
Dianne Hackborna631d562018-11-20 15:58:15 -08002885 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002886 nextActivityIndex = endIndex;
2887 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
Amith Yamasani98a00922018-08-21 12:50:30 -04002888 } else {
2889 // Process has activities, put it at the very tipsy-top.
2890 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2891 mLruProcesses.add(app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002892 nextActivityIndex = mLruProcesses.size() - 1;
Amith Yamasani98a00922018-08-21 12:50:30 -04002893 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002894 } else if (hasService) {
2895 // Process has services, put it at the top of the service list.
2896 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2897 mLruProcesses.add(mLruProcessActivityStart, app);
2898 nextIndex = mLruProcessServiceStart;
2899 mLruProcessActivityStart++;
2900 } else {
2901 // Process not otherwise of interest, it goes to the top of the non-service area.
2902 int index = mLruProcessServiceStart;
2903 if (client != null) {
2904 // If there is a client, don't allow the process to be moved up higher
2905 // in the list than that client.
2906 int clientIndex = mLruProcesses.lastIndexOf(client);
2907 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2908 + " when updating " + app);
2909 if (clientIndex <= lrui) {
2910 // Don't allow the client index restriction to push it down farther in the
2911 // list than it already is.
2912 clientIndex = lrui;
2913 }
2914 if (clientIndex >= 0 && index > clientIndex) {
2915 index = clientIndex;
2916 }
2917 }
2918 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2919 mLruProcesses.add(index, app);
2920 nextIndex = index - 1;
2921 mLruProcessActivityStart++;
2922 mLruProcessServiceStart++;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002923 if (index > 1) {
2924 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
2925 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002926 }
2927
Dianne Hackborna631d562018-11-20 15:58:15 -08002928 app.lruSeq = mLruSeq;
2929
Amith Yamasani98a00922018-08-21 12:50:30 -04002930 // If the app is currently using a content provider or service,
2931 // bump those processes as well.
2932 for (int j = app.connections.size() - 1; j >= 0; j--) {
2933 ConnectionRecord cr = app.connections.valueAt(j);
2934 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2935 && cr.binding.service.app != null
2936 && cr.binding.service.app.lruSeq != mLruSeq
Dianne Hackborna631d562018-11-20 15:58:15 -08002937 && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
Amith Yamasani98a00922018-08-21 12:50:30 -04002938 && !cr.binding.service.app.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08002939 if (cr.binding.service.app.hasClientActivities()) {
2940 if (nextActivityIndex >= 0) {
2941 nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2942 now,
2943 nextActivityIndex, mLruSeq,
2944 "service connection", cr, app);
2945 }
2946 } else {
2947 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
2948 now,
2949 nextIndex, mLruSeq,
2950 "service connection", cr, app);
2951 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002952 }
2953 }
2954 for (int j = app.conProviders.size() - 1; j >= 0; j--) {
2955 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2956 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08002957 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
Amith Yamasani98a00922018-08-21 12:50:30 -04002958 "provider reference", cpr, app);
2959 }
2960 }
2961 }
2962
2963 final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
2964 final IBinder threadBinder = thread.asBinder();
2965 // Find the application record.
2966 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2967 final ProcessRecord rec = mLruProcesses.get(i);
2968 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2969 return rec;
2970 }
2971 }
2972 return null;
2973 }
2974
2975 boolean haveBackgroundProcessLocked() {
2976 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2977 final ProcessRecord rec = mLruProcesses.get(i);
2978 if (rec.thread != null
2979 && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
2980 return true;
2981 }
2982 }
2983 return false;
2984 }
2985
2986 private static int procStateToImportance(int procState, int memAdj,
2987 ActivityManager.RunningAppProcessInfo currApp,
2988 int clientTargetSdk) {
2989 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
2990 procState, clientTargetSdk);
2991 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
2992 currApp.lru = memAdj;
2993 } else {
2994 currApp.lru = 0;
2995 }
2996 return imp;
2997 }
2998
2999 @GuardedBy("mService")
3000 void fillInProcMemInfoLocked(ProcessRecord app,
3001 ActivityManager.RunningAppProcessInfo outInfo,
3002 int clientTargetSdk) {
3003 outInfo.pid = app.pid;
3004 outInfo.uid = app.info.uid;
3005 if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
3006 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
3007 }
3008 if (app.isPersistent()) {
3009 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
3010 }
3011 if (app.hasActivities()) {
3012 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
3013 }
3014 outInfo.lastTrimLevel = app.trimMemoryLevel;
3015 int adj = app.curAdj;
3016 int procState = app.getCurProcState();
3017 outInfo.importance = procStateToImportance(procState, adj, outInfo,
3018 clientTargetSdk);
3019 outInfo.importanceReasonCode = app.adjTypeCode;
3020 outInfo.processState = app.getCurProcState();
3021 outInfo.isFocused = (app == mService.getTopAppLocked());
3022 outInfo.lastActivityTime = app.lastActivityTime;
3023 }
3024
3025 @GuardedBy("mService")
3026 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
3027 int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3028 // Lazy instantiation of list
3029 List<ActivityManager.RunningAppProcessInfo> runList = null;
3030
3031 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3032 ProcessRecord app = mLruProcesses.get(i);
3033 if ((!allUsers && app.userId != userId)
3034 || (!allUids && app.uid != callingUid)) {
3035 continue;
3036 }
3037 if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
3038 // Generate process state info for running application
3039 ActivityManager.RunningAppProcessInfo currApp =
3040 new ActivityManager.RunningAppProcessInfo(app.processName,
3041 app.pid, app.getPackageList());
3042 fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
3043 if (app.adjSource instanceof ProcessRecord) {
3044 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
3045 currApp.importanceReasonImportance =
3046 ActivityManager.RunningAppProcessInfo.procStateToImportance(
3047 app.adjSourceProcState);
Wale Ogunwale59507092018-10-29 09:00:30 -07003048 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
3049 final ActivityServiceConnectionsHolder r =
3050 (ActivityServiceConnectionsHolder) app.adjSource;
3051 final int pid = r.getActivityPid();
3052 if (pid != -1) {
3053 currApp.importanceReasonPid = pid;
3054 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003055 }
3056 if (app.adjTarget instanceof ComponentName) {
3057 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
3058 }
3059 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
3060 // + " lru=" + currApp.lru);
3061 if (runList == null) {
3062 runList = new ArrayList<>();
3063 }
3064 runList.add(currApp);
3065 }
3066 }
3067 return runList;
3068 }
3069
3070 @GuardedBy("mService")
3071 int getLruSizeLocked() {
3072 return mLruProcesses.size();
3073 }
3074
3075 @GuardedBy("mService")
3076 void dumpLruListHeaderLocked(PrintWriter pw) {
3077 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
3078 pw.print(" total, non-act at ");
3079 pw.print(mLruProcesses.size() - mLruProcessActivityStart);
3080 pw.print(", non-svc at ");
3081 pw.print(mLruProcesses.size() - mLruProcessServiceStart);
3082 pw.println("):");
3083 }
3084
3085 @GuardedBy("mService")
3086 ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
3087 ArrayList<ProcessRecord> procs;
3088 if (args != null && args.length > start
3089 && args[start].charAt(0) != '-') {
3090 procs = new ArrayList<ProcessRecord>();
3091 int pid = -1;
3092 try {
3093 pid = Integer.parseInt(args[start]);
3094 } catch (NumberFormatException e) {
3095 }
3096 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3097 ProcessRecord proc = mLruProcesses.get(i);
3098 if (proc.pid > 0 && proc.pid == pid) {
3099 procs.add(proc);
3100 } else if (allPkgs && proc.pkgList != null
3101 && proc.pkgList.containsKey(args[start])) {
3102 procs.add(proc);
3103 } else if (proc.processName.equals(args[start])) {
3104 procs.add(proc);
3105 }
3106 }
3107 if (procs.size() <= 0) {
3108 return null;
3109 }
3110 } else {
3111 procs = new ArrayList<ProcessRecord>(mLruProcesses);
3112 }
3113 return procs;
3114 }
3115
3116 @GuardedBy("mService")
3117 void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3118 boolean updateFrameworkRes) {
3119 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3120 final ProcessRecord app = mLruProcesses.get(i);
3121 if (app.thread == null) {
3122 continue;
3123 }
3124
3125 if (userId != UserHandle.USER_ALL && app.userId != userId) {
3126 continue;
3127 }
3128
3129 final int packageCount = app.pkgList.size();
3130 for (int j = 0; j < packageCount; j++) {
3131 final String packageName = app.pkgList.keyAt(j);
3132 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
3133 try {
3134 final ApplicationInfo ai = AppGlobals.getPackageManager()
3135 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3136 if (ai != null) {
3137 app.thread.scheduleApplicationInfoChanged(ai);
3138 }
3139 } catch (RemoteException e) {
3140 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3141 packageName, app));
3142 }
3143 }
3144 }
3145 }
3146 }
3147
3148 @GuardedBy("mService")
3149 void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
Winson23863be2019-04-04 17:41:28 -07003150 boolean foundProcess = false;
Amith Yamasani98a00922018-08-21 12:50:30 -04003151 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3152 ProcessRecord r = mLruProcesses.get(i);
3153 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3154 try {
Winson23863be2019-04-04 17:41:28 -07003155 for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
3156 if (packages[index].equals(r.info.packageName)) {
3157 foundProcess = true;
3158 }
3159 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003160 r.thread.dispatchPackageBroadcast(cmd, packages);
3161 } catch (RemoteException ex) {
3162 }
3163 }
3164 }
Winson23863be2019-04-04 17:41:28 -07003165
3166 if (!foundProcess) {
3167 try {
3168 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
3169 } catch (RemoteException ignored) {
3170 }
3171 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003172 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08003173
3174 /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3175 @GuardedBy("mService")
3176 int getUidProcStateLocked(int uid) {
3177 UidRecord uidRec = mActiveUids.get(uid);
3178 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3179 }
3180
3181 /** Returns the UidRecord for the given uid, if it exists. */
3182 @GuardedBy("mService")
3183 UidRecord getUidRecordLocked(int uid) {
3184 return mActiveUids.get(uid);
3185 }
3186
3187 /**
3188 * Call {@link ActivityManagerService#doStopUidLocked}
3189 * (which will also stop background services) for all idle UIDs.
3190 */
3191 @GuardedBy("mService")
3192 void doStopUidForIdleUidsLocked() {
3193 final int size = mActiveUids.size();
3194 for (int i = 0; i < size; i++) {
3195 final int uid = mActiveUids.keyAt(i);
3196 if (UserHandle.isCore(uid)) {
3197 continue;
3198 }
3199 final UidRecord uidRec = mActiveUids.valueAt(i);
3200 if (!uidRec.idle) {
3201 continue;
3202 }
3203 mService.doStopUidLocked(uidRec.uid, uidRec);
3204 }
3205 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07003206}