blob: 954be20122b4b6c54130bdf7ac0abe2ac1c98552 [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;
Jing Ji094c3ef2019-08-27 17:02:09 -070023import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
24import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
Jing Jie29afc92019-10-29 18:14:49 -070025import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
Amith Yamasani98a00922018-08-21 12:50:30 -040026import static android.os.Process.SYSTEM_UID;
27import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
28import static android.os.Process.getFreeMemory;
29import static android.os.Process.getTotalMemory;
30import static android.os.Process.killProcessQuiet;
31import static android.os.Process.startWebView;
32
33import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
Jing Ji094c3ef2019-08-27 17:02:09 -070034import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
Amith Yamasani98a00922018-08-21 12:50:30 -040035import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
36import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
37import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080038import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
39import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010040import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS;
41import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG;
Amith Yamasani98a00922018-08-21 12:50:30 -040042import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK;
43import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT;
44import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG;
45import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER;
46import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
47import static com.android.server.am.ActivityManagerService.TAG_LRU;
Jing Ji094c3ef2019-08-27 17:02:09 -070048import static com.android.server.am.ActivityManagerService.TAG_NETWORK;
Amith Yamasani98a00922018-08-21 12:50:30 -040049import static com.android.server.am.ActivityManagerService.TAG_PROCESSES;
50import static com.android.server.am.ActivityManagerService.TAG_PSS;
51import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
Wale Ogunwalee23149f2015-03-06 15:39:44 -080052
Dianne Hackborn8e692572013-09-10 19:06:15 -070053import android.app.ActivityManager;
Irina Dumitrescu34a27c42019-04-15 19:20:38 +010054import android.app.ActivityThread;
Amith Yamasani98a00922018-08-21 12:50:30 -040055import android.app.AppGlobals;
Bookatzdb026a22018-01-10 19:01:56 -080056import android.app.AppProtoEnums;
Jing Ji8055a3a2019-12-17 15:55:33 -080057import android.app.ApplicationExitInfo;
58import android.app.ApplicationExitInfo.Reason;
59import android.app.ApplicationExitInfo.SubReason;
Amith Yamasani98a00922018-08-21 12:50:30 -040060import android.app.IApplicationThread;
Jing Jie423f762019-12-10 15:05:18 -080061import android.app.IUidObserver;
62import android.content.BroadcastReceiver;
Amith Yamasani98a00922018-08-21 12:50:30 -040063import android.content.ComponentName;
Dianne Hackborna631d562018-11-20 15:58:15 -080064import android.content.Context;
Amith Yamasani98a00922018-08-21 12:50:30 -040065import android.content.Intent;
Jing Jie423f762019-12-10 15:05:18 -080066import android.content.IntentFilter;
Amith Yamasani98a00922018-08-21 12:50:30 -040067import android.content.pm.ApplicationInfo;
68import android.content.pm.IPackageManager;
Ricky Wai5a8fe7a2019-12-13 15:20:47 +000069import android.content.pm.PackageManagerInternal;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070070import android.content.res.Resources;
71import android.graphics.Point;
Jing Jie29afc92019-10-29 18:14:49 -070072import android.net.LocalSocket;
73import android.net.LocalSocketAddress;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010074import android.os.AppZygote;
Amith Yamasani98a00922018-08-21 12:50:30 -040075import android.os.Binder;
Dianne Hackborn9d52f792014-09-11 17:46:06 -070076import android.os.Build;
Amith Yamasani98a00922018-08-21 12:50:30 -040077import android.os.Bundle;
Jing Jie423f762019-12-10 15:05:18 -080078import android.os.DropBoxManager;
Amith Yamasani98a00922018-08-21 12:50:30 -040079import android.os.Handler;
80import android.os.IBinder;
81import android.os.Looper;
82import android.os.Message;
Jing Jie423f762019-12-10 15:05:18 -080083import android.os.PowerManager;
Amith Yamasani98a00922018-08-21 12:50:30 -040084import android.os.Process;
85import android.os.RemoteException;
86import android.os.StrictMode;
Dianne Hackbornecf1cda2014-08-28 16:58:28 -070087import android.os.SystemClock;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070088import android.os.SystemProperties;
89import android.os.Trace;
90import android.os.UserHandle;
Jeff Sharkey10ec9d82018-11-28 14:52:45 -070091import android.os.storage.StorageManager;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070092import android.os.storage.StorageManagerInternal;
Ricky Wai5a8fe7a2019-12-13 15:20:47 +000093import android.provider.DeviceConfig;
Jing Ji03109072019-12-02 20:49:23 -080094import android.system.Os;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070095import android.text.TextUtils;
Martijn Coenen7e6fa672018-11-05 11:45:26 +010096import android.util.ArrayMap;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070097import android.util.EventLog;
98import android.util.LongSparseArray;
Ricky Wai5a8fe7a2019-12-13 15:20:47 +000099import android.util.Pair;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700100import android.util.Slog;
101import android.util.SparseArray;
Martijn Coenen01e719b2018-12-05 16:01:38 +0100102import android.util.SparseBooleanArray;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700103import android.util.StatsLog;
104import android.view.Display;
Amith Yamasani98a00922018-08-21 12:50:30 -0400105
106import com.android.internal.annotations.GuardedBy;
107import com.android.internal.annotations.VisibleForTesting;
108import com.android.internal.app.ProcessMap;
109import com.android.internal.app.procstats.ProcessStats;
110import com.android.internal.os.Zygote;
111import com.android.internal.util.ArrayUtils;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700112import com.android.internal.util.MemInfoReader;
Amith Yamasani98a00922018-08-21 12:50:30 -0400113import com.android.server.LocalServices;
114import com.android.server.ServiceThread;
Ricky Wai825d3e92019-12-18 15:16:17 +0000115import com.android.server.SystemConfig;
Amith Yamasani98a00922018-08-21 12:50:30 -0400116import com.android.server.Watchdog;
atrost5ae996f2019-12-11 18:32:48 +0000117import com.android.server.compat.PlatformCompat;
Amith Yamasani98a00922018-08-21 12:50:30 -0400118import com.android.server.pm.dex.DexManager;
Wale Ogunwale59507092018-10-29 09:00:30 -0700119import com.android.server.wm.ActivityServiceConnectionsHolder;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700120import com.android.server.wm.WindowManagerService;
121
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700122import dalvik.system.VMRuntime;
123
124import java.io.File;
Jing Jie29afc92019-10-29 18:14:49 -0700125import java.io.FileDescriptor;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700126import java.io.IOException;
Sudheer Shanka87915d62018-11-06 10:57:35 -0800127import java.io.OutputStream;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700128import java.io.PrintWriter;
129import java.nio.ByteBuffer;
130import java.util.ArrayList;
131import java.util.Arrays;
Martijn Coenen01e719b2018-12-05 16:01:38 +0100132import java.util.BitSet;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -0700133import java.util.List;
Ricky Wai5a8fe7a2019-12-13 15:20:47 +0000134import java.util.Map;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700135
136/**
137 * Activity manager code dealing with processes.
138 */
Sudheer Shanka352dc572017-09-22 17:09:38 -0700139public final class ProcessList {
Amith Yamasaniaa746442019-01-10 10:09:12 -0800140 static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800141
Ricky Wai5a8fe7a2019-12-13 15:20:47 +0000142 // A device config to control the minimum target SDK to enable app data isolation
143 static final String ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY =
144 "persist.zygote.app_data_isolation";
145
146 // A device config to control the minimum target SDK to enable app data isolation
147 static final String ANDROID_APP_DATA_ISOLATION_MIN_SDK = "android_app_data_isolation_min_sdk";
148
Dianne Hackborn7d608422011-08-07 16:24:18 -0700149 // The minimum time we allow between crashes, for us to consider this
150 // application to be bad and stop and its services and reject broadcasts.
Amith Yamasani98a00922018-08-21 12:50:30 -0400151 static final int MIN_CRASH_INTERVAL = 60 * 1000;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700152
153 // OOM adjustments for processes in various states:
154
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700155 // Uninitialized value for any major or minor adj fields
156 static final int INVALID_ADJ = -10000;
157
Dianne Hackbornc8230512013-07-13 21:32:12 -0700158 // Adjustment used in certain places where we don't know it yet.
159 // (Generally this is something that is going to be cached, but we
160 // don't know the exact value in the cached range to assign yet.)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700161 static final int UNKNOWN_ADJ = 1001;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700162
Dianne Hackborn7d608422011-08-07 16:24:18 -0700163 // This is a process only hosting activities that are not visible,
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700164 // so it can be killed without any disruption.
Dianne Hackbornb446ce52018-12-10 16:44:35 -0800165 static final int CACHED_APP_MAX_ADJ = 999;
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700166 static final int CACHED_APP_MIN_ADJ = 900;
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700167
Tim Murray0d42abe2019-01-23 09:54:15 -0800168 // This is the oom_adj level that we allow to die first. This cannot be equal to
169 // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of
170 // CACHED_APP_MAX_ADJ.
171 static final int CACHED_APP_LMK_FIRST_ADJ = 950;
172
Dianne Hackbornb446ce52018-12-10 16:44:35 -0800173 // Number of levels we have available for different service connection group importance
174 // levels.
175 static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
176
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700177 // The B list of SERVICE_ADJ -- these are the old and decrepit
178 // services that aren't as shiny and interesting as the ones in the A list.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700179 static final int SERVICE_B_ADJ = 800;
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700180
181 // This is the process of the previous application that the user was in.
182 // This process is kept above other things, because it is very common to
183 // switch back to the previous app. This is important both for recent
184 // task switch (toggling between the two top recent apps) as well as normal
185 // UI flow such as clicking on a URI in the e-mail app to view in the browser,
186 // and then pressing back to return to e-mail.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700187 static final int PREVIOUS_APP_ADJ = 700;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700188
189 // This is a process holding the home application -- we want to try
190 // avoiding killing it, even if it would normally be in the background,
191 // because the user interacts with it so much.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700192 static final int HOME_APP_ADJ = 600;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700193
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700194 // This is a process holding an application service -- killing it will not
195 // have much of an impact as far as the user is concerned.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700196 static final int SERVICE_ADJ = 500;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700197
Dianne Hackborn7d608422011-08-07 16:24:18 -0700198 // This is a process with a heavy-weight application. It is in the
199 // background, but we want to try to avoid killing it. Value set in
200 // system/rootdir/init.rc on startup.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700201 static final int HEAVY_WEIGHT_APP_ADJ = 400;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700202
203 // This is a process currently hosting a backup operation. Killing it
204 // is not entirely fatal but is generally a bad idea.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700205 static final int BACKUP_APP_ADJ = 300;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700206
Amith Yamasani5016a782019-06-17 16:20:24 -0700207 // This is a process bound by the system (or other app) that's more important than services but
208 // not so perceptible that it affects the user immediately if killed.
Amith Yamasani0567ec62019-01-23 11:11:02 -0800209 static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
210
Dianne Hackborn7d608422011-08-07 16:24:18 -0700211 // This is a process only hosting components that are perceptible to the
212 // user, and we really want to avoid killing them, but they are not
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700213 // immediately visible. An example is background music playback.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700214 static final int PERCEPTIBLE_APP_ADJ = 200;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700215
216 // This is a process only hosting activities that are visible to the
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700217 // user, so we'd prefer they don't disappear.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700218 static final int VISIBLE_APP_ADJ = 100;
219 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700220
Amith Yamasanib7358302018-09-05 18:52:35 -0700221 // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
222 // like a foreground app for a while.
223 // @see TOP_TO_FGS_GRACE_PERIOD
224 static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
225
Dianne Hackborn7d608422011-08-07 16:24:18 -0700226 // This is the process running the current foreground app. We'd really
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700227 // rather not kill it!
Dianne Hackborn7d608422011-08-07 16:24:18 -0700228 static final int FOREGROUND_APP_ADJ = 0;
229
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700230 // This is a process that the system or a persistent process has bound to,
231 // and indicated it is important.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700232 static final int PERSISTENT_SERVICE_ADJ = -700;
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700233
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700234 // This is a system persistent process, such as telephony. Definitely
Dianne Hackborn7d608422011-08-07 16:24:18 -0700235 // don't want to kill it, but doing so is not completely fatal.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700236 static final int PERSISTENT_PROC_ADJ = -800;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700237
238 // The system process runs at the default adjustment.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700239 static final int SYSTEM_ADJ = -900;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700240
Dianne Hackborn8e692572013-09-10 19:06:15 -0700241 // Special code for native processes that are not being managed by the system (so
242 // don't have an oom adj assigned by the system).
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700243 static final int NATIVE_ADJ = -1000;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700244
Dianne Hackborn7d608422011-08-07 16:24:18 -0700245 // Memory pages are 4K.
Amith Yamasani98a00922018-08-21 12:50:30 -0400246 static final int PAGE_SIZE = 4 * 1024;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700247
Rick Yiu021c0642019-10-03 17:29:20 +0800248 // Activity manager's version of Process.THREAD_GROUP_BACKGROUND
Dianne Hackborna49ad092016-03-03 13:39:10 -0800249 static final int SCHED_GROUP_BACKGROUND = 0;
Tim Murrayfef10a42018-04-13 10:15:17 -0700250 // Activity manager's version of Process.THREAD_GROUP_RESTRICTED
251 static final int SCHED_GROUP_RESTRICTED = 1;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800252 // Activity manager's version of Process.THREAD_GROUP_DEFAULT
Tim Murrayfef10a42018-04-13 10:15:17 -0700253 static final int SCHED_GROUP_DEFAULT = 2;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800254 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
Wale Ogunwale59507092018-10-29 09:00:30 -0700255 public static final int SCHED_GROUP_TOP_APP = 3;
Tim Murray33eb07f2016-06-10 10:03:20 -0700256 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
257 // Disambiguate between actual top app and processes bound to the top app
Tim Murrayfef10a42018-04-13 10:15:17 -0700258 static final int SCHED_GROUP_TOP_APP_BOUND = 4;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800259
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700260 // The minimum number of cached apps we want to be able to keep around,
Dianne Hackborn7d608422011-08-07 16:24:18 -0700261 // without empty apps being able to push them out of memory.
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700262 static final int MIN_CACHED_APPS = 2;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700263
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700264 // We allow empty processes to stick around for at most 30 minutes.
Amith Yamasani98a00922018-08-21 12:50:30 -0400265 static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700266
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700267 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700268 static final int TRIM_CRITICAL_THRESHOLD = 3;
269
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700270 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700271 static final int TRIM_LOW_THRESHOLD = 5;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700272
Jing Ji094c3ef2019-08-27 17:02:09 -0700273 /**
274 * State indicating that there is no need for any blocking for network.
275 */
276 @VisibleForTesting
277 static final int NETWORK_STATE_NO_CHANGE = 0;
278
279 /**
280 * State indicating that the main thread needs to be informed about the network wait.
281 */
282 @VisibleForTesting
283 static final int NETWORK_STATE_BLOCK = 1;
284
285 /**
286 * State indicating that any threads waiting for network state to get updated can be unblocked.
287 */
288 @VisibleForTesting
289 static final int NETWORK_STATE_UNBLOCK = 2;
290
Mathieu Chartier77bd1232019-03-05 13:53:11 -0800291 // If true, then we pass the flag to ART to load the app image startup cache.
292 private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
293 "persist.device_config.runtime_native.use_app_image_startup_cache";
294
Jing Jie29afc92019-10-29 18:14:49 -0700295 // The socket path for zygote to send unsolicited msg.
296 // Must keep sync with com_android_internal_os_Zygote.cpp.
297 private static final String UNSOL_ZYGOTE_MSG_SOCKET_PATH = "/data/system/unsolzygotesocket";
298
Todd Poynorbfdd6232013-07-10 19:15:07 -0700299 // Low Memory Killer Daemon command codes.
Suren Baghdasaryanb6b8d1d2019-12-23 13:38:53 -0800300 // These must be kept in sync with lmk_cmd definitions in lmkd.h
Todd Poynorbfdd6232013-07-10 19:15:07 -0700301 //
302 // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700303 // LMK_PROCPRIO <pid> <uid> <prio>
Todd Poynorbfdd6232013-07-10 19:15:07 -0700304 // LMK_PROCREMOVE <pid>
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -0700305 // LMK_PROCPURGE
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700306 // LMK_GETKILLCNT
Suren Baghdasaryanb6b8d1d2019-12-23 13:38:53 -0800307 // LMK_SUBSCRIBE
Jing Ji4fcb2a12019-09-11 16:59:36 -0700308 // LMK_PROCKILL
Todd Poynorbfdd6232013-07-10 19:15:07 -0700309 static final byte LMK_TARGET = 0;
310 static final byte LMK_PROCPRIO = 1;
311 static final byte LMK_PROCREMOVE = 2;
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -0700312 static final byte LMK_PROCPURGE = 3;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700313 static final byte LMK_GETKILLCNT = 4;
Suren Baghdasaryanb6b8d1d2019-12-23 13:38:53 -0800314 static final byte LMK_SUBSCRIBE = 5;
315 static final byte LMK_PROCKILL = 6; // Note: this is an unsolicated command
316
317 // Low Memory Killer Daemon command codes.
318 // These must be kept in sync with async_event_type definitions in lmkd.h
319 //
320 static final int LMK_ASYNC_EVENT_KILL = 0;
Todd Poynorbfdd6232013-07-10 19:15:07 -0700321
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700322 // lmkd reconnect delay in msecs
Jing Ji4fcb2a12019-09-11 16:59:36 -0700323 private static final long LMKD_RECONNECT_DELAY_MS = 1000;
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700324
Jing Ji03109072019-12-02 20:49:23 -0800325 /**
326 * How long between a process kill and we actually receive its death recipient
327 */
Jing Ji9f21e892020-01-14 14:28:17 -0800328 private static final int PROC_KILL_TIMEOUT = 2000; // 2 seconds;
Jing Ji03109072019-12-02 20:49:23 -0800329
Amith Yamasani98a00922018-08-21 12:50:30 -0400330 ActivityManagerService mService = null;
331
332 // To kill process groups asynchronously
333 static KillHandler sKillHandler = null;
334 static ServiceThread sKillThread = null;
335
Dianne Hackborn7d608422011-08-07 16:24:18 -0700336 // These are the various interesting memory levels that we will give to
337 // the OOM killer. Note that the OOM killer only supports 6 slots, so we
338 // can't give it a different value for every possible kind of process.
339 private final int[] mOomAdj = new int[] {
340 FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
Amith Yamasani5016a782019-06-17 16:20:24 -0700341 PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
Dianne Hackborn7d608422011-08-07 16:24:18 -0700342 };
343 // These are the low-end OOM level limits. This is appropriate for an
344 // HVGA or smaller phone with less than 512MB. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700345 private final int[] mOomMinFreeLow = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700346 12288, 18432, 24576,
347 36864, 43008, 49152
Dianne Hackborn7d608422011-08-07 16:24:18 -0700348 };
349 // These are the high-end OOM level limits. This is appropriate for a
350 // 1280x800 or larger screen with around 1GB RAM. Values are in KB.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700351 private final int[] mOomMinFreeHigh = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700352 73728, 92160, 110592,
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800353 129024, 147456, 184320
Dianne Hackborn7d608422011-08-07 16:24:18 -0700354 };
355 // The actual OOM killer memory levels we are using.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700356 private final int[] mOomMinFree = new int[mOomAdj.length];
Dianne Hackborn7d608422011-08-07 16:24:18 -0700357
358 private final long mTotalMemMb;
359
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700360 private long mCachedRestoreLevel;
361
Dianne Hackborn7d608422011-08-07 16:24:18 -0700362 private boolean mHaveDisplaySize;
363
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700364 private static LmkdConnection sLmkdConnection = null;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700365
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700366 private boolean mOomLevelsSet = false;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700367
Ricky Wai5a8fe7a2019-12-13 15:20:47 +0000368 private boolean mAppDataIsolationEnabled = false;
369
Ricky Wai825d3e92019-12-18 15:16:17 +0000370 private ArrayList<String> mAppDataIsolationWhitelistedApps;
371
Amith Yamasani98a00922018-08-21 12:50:30 -0400372 /**
373 * Temporary to avoid allocations. Protected by main lock.
374 */
375 @GuardedBy("mService")
376 final StringBuilder mStringBuilder = new StringBuilder(256);
377
378 /**
379 * A global counter for generating sequence numbers.
380 * This value will be used when incrementing sequence numbers in individual uidRecords.
381 *
382 * Having a global counter ensures that seq numbers are monotonically increasing for a
383 * particular uid even when the uidRecord is re-created.
384 */
385 @GuardedBy("mService")
386 @VisibleForTesting
387 long mProcStateSeqCounter = 0;
388
389 /**
390 * A global counter for generating sequence numbers to uniquely identify pending process starts.
391 */
392 @GuardedBy("mService")
393 private long mProcStartSeqCounter = 0;
394
395 /**
396 * Contains {@link ProcessRecord} objects for pending process starts.
397 *
398 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
399 */
400 @GuardedBy("mService")
401 final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
402
403 /**
404 * List of running applications, sorted by recent usage.
405 * The first entry in the list is the least recently used.
406 */
407 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
408
409 /**
410 * Where in mLruProcesses that the processes hosting activities start.
411 */
412 int mLruProcessActivityStart = 0;
413
414 /**
415 * Where in mLruProcesses that the processes hosting services start.
416 * This is after (lower index) than mLruProcessesActivityStart.
417 */
418 int mLruProcessServiceStart = 0;
419
420 /**
421 * Current sequence id for process LRU updating.
422 */
423 int mLruSeq = 0;
424
Amith Yamasaniaa746442019-01-10 10:09:12 -0800425 ActiveUids mActiveUids;
426
Amith Yamasani98a00922018-08-21 12:50:30 -0400427 /**
428 * The currently running isolated processes.
429 */
430 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
431
432 /**
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100433 * The currently running application zygotes.
434 */
435 final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
436
437 /**
Jing Ji8055a3a2019-12-17 15:55:33 -0800438 * Managees the {@link android.app.ApplicationExitInfo} records.
439 */
440 @GuardedBy("mAppExitInfoTracker")
441 final AppExitInfoTracker mAppExitInfoTracker = new AppExitInfoTracker();
442
443 /**
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100444 * The processes that are forked off an application zygote.
445 */
446 final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses =
447 new ArrayMap<AppZygote, ArrayList<ProcessRecord>>();
448
atrost5ae996f2019-12-11 18:32:48 +0000449 private PlatformCompat mPlatformCompat = null;
450
Jing Jie29afc92019-10-29 18:14:49 -0700451 /**
452 * The server socket in system_server, zygote will connect to it
453 * in order to send unsolicited messages to system_server.
454 */
455 private LocalSocket mSystemServerSocketForZygote;
456
457 /**
458 * Maximum number of bytes that an incoming unsolicited zygote message could be.
459 * To be updated if new message type needs to be supported.
460 */
461 private static final int MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE = 16;
462
463 /**
464 * The buffer to be used to receive the incoming unsolicited zygote message.
465 */
466 private final byte[] mZygoteUnsolicitedMessage = new byte[MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE];
467
468 /**
469 * The buffer to be used to receive the SIGCHLD data, it includes pid/uid/status.
470 */
471 private final int[] mZygoteSigChldMessage = new int[3];
472
Jing Ji4fcb2a12019-09-11 16:59:36 -0700473 interface LmkdKillListener {
474 /**
475 * Called when there is a process kill by lmkd.
476 */
477 void onLmkdKillOccurred(int pid, int uid);
478 }
479
Martijn Coenen01e719b2018-12-05 16:01:38 +0100480 final class IsolatedUidRange {
481 @VisibleForTesting
482 public final int mFirstUid;
483 @VisibleForTesting
484 public final int mLastUid;
485
486 @GuardedBy("ProcessList.this.mService")
487 private final SparseBooleanArray mUidUsed = new SparseBooleanArray();
488
489 @GuardedBy("ProcessList.this.mService")
490 private int mNextUid;
491
492 IsolatedUidRange(int firstUid, int lastUid) {
493 mFirstUid = firstUid;
494 mLastUid = lastUid;
495 mNextUid = firstUid;
496 }
497
498 @GuardedBy("ProcessList.this.mService")
499 int allocateIsolatedUidLocked(int userId) {
500 int uid;
501 int stepsLeft = (mLastUid - mFirstUid + 1);
502 for (int i = 0; i < stepsLeft; ++i) {
503 if (mNextUid < mFirstUid || mNextUid > mLastUid) {
504 mNextUid = mFirstUid;
505 }
506 uid = UserHandle.getUid(userId, mNextUid);
507 mNextUid++;
508 if (!mUidUsed.get(uid, false)) {
509 mUidUsed.put(uid, true);
510 return uid;
511 }
512 }
513 return -1;
514 }
515
516 @GuardedBy("ProcessList.this.mService")
517 void freeIsolatedUidLocked(int uid) {
Martijn Coenenc9a0df22019-12-18 07:01:25 +0100518 mUidUsed.delete(uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +0100519 }
520 };
521
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100522 /**
Martijn Coenen01e719b2018-12-05 16:01:38 +0100523 * A class that allocates ranges of isolated UIDs per application, and keeps track of them.
Amith Yamasani98a00922018-08-21 12:50:30 -0400524 */
Martijn Coenen01e719b2018-12-05 16:01:38 +0100525 final class IsolatedUidRangeAllocator {
526 private final int mFirstUid;
527 private final int mNumUidRanges;
528 private final int mNumUidsPerRange;
529 /**
530 * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange)
531 * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that.
532 */
533 @GuardedBy("ProcessList.this.mService")
534 private final BitSet mAvailableUidRanges;
535 @GuardedBy("ProcessList.this.mService")
536 private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>();
537
538 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) {
539 mFirstUid = firstUid;
540 mNumUidsPerRange = numUidsPerRange;
541 mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange;
542 mAvailableUidRanges = new BitSet(mNumUidRanges);
543 // Mark all as available
544 mAvailableUidRanges.set(0, mNumUidRanges);
545 }
546
547 @GuardedBy("ProcessList.this.mService")
Martijn Coenen572ed7f2019-03-28 19:50:44 +0100548 IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) {
549 return mAppRanges.get(processName, uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +0100550 }
551
552 @GuardedBy("ProcessList.this.mService")
Martijn Coenen572ed7f2019-03-28 19:50:44 +0100553 IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) {
554 IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +0100555 if (range == null) {
556 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
557 if (uidRangeIndex < 0) {
558 // No free range
559 return null;
560 }
561 mAvailableUidRanges.clear(uidRangeIndex);
562 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
563 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
Martijn Coenen572ed7f2019-03-28 19:50:44 +0100564 mAppRanges.put(processName, uid, range);
Martijn Coenen01e719b2018-12-05 16:01:38 +0100565 }
566 return range;
567 }
568
569 @GuardedBy("ProcessList.this.mService")
570 void freeUidRangeLocked(ApplicationInfo info) {
571 // Find the UID range
572 IsolatedUidRange range = mAppRanges.get(info.processName, info.uid);
573 if (range != null) {
574 // Map back to starting uid
575 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange;
576 // Mark it as available in the underlying bitset
577 mAvailableUidRanges.set(uidRangeIndex);
578 // And the map
579 mAppRanges.remove(info.processName, info.uid);
580 }
581 }
582 }
583
584 /**
585 * The available isolated UIDs for processes that are not spawned from an application zygote.
586 */
587 @VisibleForTesting
588 IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID,
589 Process.LAST_ISOLATED_UID);
590
591 /**
592 * An allocator for isolated UID ranges for apps that use an application zygote.
593 */
594 @VisibleForTesting
595 IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator =
596 new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
597 Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE);
Amith Yamasani98a00922018-08-21 12:50:30 -0400598
599 /**
600 * Processes that are being forcibly torn down.
601 */
602 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
603
604 /**
605 * All of the applications we currently have running organized by name.
606 * The keys are strings of the application package name (as
607 * returned by the package manager), and the keys are ApplicationRecord
608 * objects.
609 */
610 final MyProcessMap mProcessNames = new MyProcessMap();
611
612 final class MyProcessMap extends ProcessMap<ProcessRecord> {
613 @Override
614 public ProcessRecord put(String name, int uid, ProcessRecord value) {
615 final ProcessRecord r = super.put(name, uid, value);
616 mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());
617 return r;
618 }
619
620 @Override
621 public ProcessRecord remove(String name, int uid) {
622 final ProcessRecord r = super.remove(name, uid);
623 mService.mAtmInternal.onProcessRemoved(name, uid);
624 return r;
625 }
626 }
627
628 final class KillHandler extends Handler {
629 static final int KILL_PROCESS_GROUP_MSG = 4000;
Jing Ji4fcb2a12019-09-11 16:59:36 -0700630 static final int LMKD_RECONNECT_MSG = 4001;
Amith Yamasani98a00922018-08-21 12:50:30 -0400631
632 public KillHandler(Looper looper) {
633 super(looper, null, true);
634 }
635
636 @Override
637 public void handleMessage(Message msg) {
638 switch (msg.what) {
639 case KILL_PROCESS_GROUP_MSG:
640 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
641 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
642 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
643 break;
Jing Ji4fcb2a12019-09-11 16:59:36 -0700644 case LMKD_RECONNECT_MSG:
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700645 if (!sLmkdConnection.connect()) {
646 Slog.i(TAG, "Failed to connect to lmkd, retry after " +
Jing Ji4fcb2a12019-09-11 16:59:36 -0700647 LMKD_RECONNECT_DELAY_MS + " ms");
648 // retry after LMKD_RECONNECT_DELAY_MS
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700649 sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
Jing Ji4fcb2a12019-09-11 16:59:36 -0700650 KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700651 }
652 break;
Amith Yamasani98a00922018-08-21 12:50:30 -0400653 default:
654 super.handleMessage(msg);
655 }
656 }
657 }
658
Jing Jie423f762019-12-10 15:05:18 -0800659 /**
660 * A runner to handle the imperceptible killings.
661 */
662 ImperceptibleKillRunner mImperceptibleKillRunner;
663
Amith Yamasani98a00922018-08-21 12:50:30 -0400664 //////////////////// END FIELDS ////////////////////
665
Dianne Hackborn7d608422011-08-07 16:24:18 -0700666 ProcessList() {
667 MemInfoReader minfo = new MemInfoReader();
668 minfo.readMemInfo();
669 mTotalMemMb = minfo.getTotalSize()/(1024*1024);
670 updateOomLevels(0, 0, false);
671 }
672
atrost5ae996f2019-12-11 18:32:48 +0000673 void init(ActivityManagerService service, ActiveUids activeUids,
674 PlatformCompat platformCompat) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400675 mService = service;
Amith Yamasaniaa746442019-01-10 10:09:12 -0800676 mActiveUids = activeUids;
atrost5ae996f2019-12-11 18:32:48 +0000677 mPlatformCompat = platformCompat;
Ricky Wai5a8fe7a2019-12-13 15:20:47 +0000678 // Get this after boot, and won't be changed until it's rebooted, as we don't
679 // want some apps enabled while some apps disabled
680 mAppDataIsolationEnabled =
Ricky Wai19889422020-01-15 01:59:00 +0000681 SystemProperties.getBoolean(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true);
Ricky Wai825d3e92019-12-18 15:16:17 +0000682 mAppDataIsolationWhitelistedApps = new ArrayList<>(
683 SystemConfig.getInstance().getAppDataIsolationWhitelistedApps());
684
Amith Yamasani98a00922018-08-21 12:50:30 -0400685 if (sKillHandler == null) {
686 sKillThread = new ServiceThread(TAG + ":kill",
687 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
688 sKillThread.start();
689 sKillHandler = new KillHandler(sKillThread.getLooper());
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700690 sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(),
691 new LmkdConnection.LmkdConnectionListener() {
692 @Override
693 public boolean onConnect(OutputStream ostream) {
694 Slog.i(TAG, "Connection with lmkd established");
695 return onLmkdConnect(ostream);
696 }
atrost5ae996f2019-12-11 18:32:48 +0000697
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700698 @Override
699 public void onDisconnect() {
700 Slog.w(TAG, "Lost connection to lmkd");
701 // start reconnection after delay to let lmkd restart
702 sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
Jing Ji4fcb2a12019-09-11 16:59:36 -0700703 KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700704 }
atrost5ae996f2019-12-11 18:32:48 +0000705
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700706 @Override
707 public boolean isReplyExpected(ByteBuffer replyBuf,
708 ByteBuffer dataReceived, int receivedLen) {
709 // compare the preambule (currently one integer) to check if
710 // this is the reply packet we are waiting for
711 return (receivedLen == replyBuf.array().length &&
712 dataReceived.getInt(0) == replyBuf.getInt(0));
713 }
Jing Ji4fcb2a12019-09-11 16:59:36 -0700714
715 @Override
716 public boolean handleUnsolicitedMessage(ByteBuffer dataReceived,
717 int receivedLen) {
718 if (receivedLen < 4) {
719 return false;
720 }
721 switch (dataReceived.getInt(0)) {
722 case LMK_PROCKILL:
723 if (receivedLen != 12) {
724 return false;
725 }
Jing Ji8055a3a2019-12-17 15:55:33 -0800726 mAppExitInfoTracker.scheduleNoteLmkdProcKilled(
727 dataReceived.getInt(4), dataReceived.getInt(8));
Jing Ji4fcb2a12019-09-11 16:59:36 -0700728 return true;
729 default:
730 return false;
731 }
732 }
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700733 }
734 );
Jing Jie29afc92019-10-29 18:14:49 -0700735 // Start listening on incoming connections from zygotes.
736 mSystemServerSocketForZygote = createSystemServerSocketForZygote();
737 if (mSystemServerSocketForZygote != null) {
738 sKillHandler.getLooper().getQueue().addOnFileDescriptorEventListener(
739 mSystemServerSocketForZygote.getFileDescriptor(),
740 EVENT_INPUT, this::handleZygoteMessages);
741 }
Jing Ji8055a3a2019-12-17 15:55:33 -0800742 mAppExitInfoTracker.init(mService, sKillThread.getLooper());
Jing Jie423f762019-12-10 15:05:18 -0800743 mImperceptibleKillRunner = new ImperceptibleKillRunner(sKillThread.getLooper());
Amith Yamasani98a00922018-08-21 12:50:30 -0400744 }
745 }
746
Jing Ji8055a3a2019-12-17 15:55:33 -0800747 void onSystemReady() {
748 mAppExitInfoTracker.onSystemReady();
749 }
750
Dianne Hackborn7d608422011-08-07 16:24:18 -0700751 void applyDisplaySize(WindowManagerService wm) {
752 if (!mHaveDisplaySize) {
753 Point p = new Point();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700754 // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
Colin Cross637dbfc2013-07-18 17:15:15 -0700755 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700756 if (p.x != 0 && p.y != 0) {
757 updateOomLevels(p.x, p.y, true);
758 mHaveDisplaySize = true;
759 }
760 }
761 }
762
763 private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
764 // Scale buckets from avail memory: at 300MB we use the lowest values to
765 // 700MB or more for the top values.
Amith Yamasani98a00922018-08-21 12:50:30 -0400766 float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700767
768 // Scale buckets from screen size.
Amith Yamasani98a00922018-08-21 12:50:30 -0400769 int minSize = 480 * 800; // 384000
770 int maxSize = 1280 * 800; // 1024000 230400 870400 .264
771 float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700772 if (false) {
773 Slog.i("XXXXXX", "scaleMem=" + scaleMem);
774 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
775 + " dh=" + displayHeight);
776 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700777
Dianne Hackborn7d608422011-08-07 16:24:18 -0700778 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
779 if (scale < 0) scale = 0;
780 else if (scale > 1) scale = 1;
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700781 int minfree_adj = Resources.getSystem().getInteger(
782 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
783 int minfree_abs = Resources.getSystem().getInteger(
784 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
785 if (false) {
786 Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
787 }
Colin Crossfcdad6f2013-07-25 15:04:40 -0700788
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800789 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700790
Amith Yamasani98a00922018-08-21 12:50:30 -0400791 for (int i = 0; i < mOomAdj.length; i++) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700792 int low = mOomMinFreeLow[i];
793 int high = mOomMinFreeHigh[i];
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800794 if (is64bit) {
795 // Increase the high min-free levels for cached processes for 64-bit
Amith Yamasani98a00922018-08-21 12:50:30 -0400796 if (i == 4) high = (high * 3) / 2;
797 else if (i == 5) high = (high * 7) / 4;
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800798 }
Amith Yamasani98a00922018-08-21 12:50:30 -0400799 mOomMinFree[i] = (int)(low + ((high - low) * scale));
Colin Crossfcdad6f2013-07-25 15:04:40 -0700800 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700801
Colin Crossfcdad6f2013-07-25 15:04:40 -0700802 if (minfree_abs >= 0) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400803 for (int i = 0; i < mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700804 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
805 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700806 }
807 }
808
809 if (minfree_adj != 0) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400810 for (int i = 0; i < mOomAdj.length; i++) {
811 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700812 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700813 if (mOomMinFree[i] < 0) {
814 mOomMinFree[i] = 0;
815 }
816 }
817 }
818
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700819 // The maximum size we will restore a process from cached to background, when under
820 // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
821 // before killing background processes.
Amith Yamasani98a00922018-08-21 12:50:30 -0400822 mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700823
Colin Cross59d80a52013-07-25 10:45:05 -0700824 // Ask the kernel to try to keep enough memory free to allocate 3 full
825 // screen 32bpp buffers without entering direct reclaim.
826 int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
Amith Yamasani98a00922018-08-21 12:50:30 -0400827 int reserve_adj = Resources.getSystem().getInteger(
828 com.android.internal.R.integer.config_extraFreeKbytesAdjust);
829 int reserve_abs = Resources.getSystem().getInteger(
830 com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
Colin Cross59d80a52013-07-25 10:45:05 -0700831
832 if (reserve_abs >= 0) {
833 reserve = reserve_abs;
834 }
835
836 if (reserve_adj != 0) {
837 reserve += reserve_adj;
838 if (reserve < 0) {
839 reserve = 0;
840 }
841 }
842
Dianne Hackborn7d608422011-08-07 16:24:18 -0700843 if (write) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400844 ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
Todd Poynorbfdd6232013-07-10 19:15:07 -0700845 buf.putInt(LMK_TARGET);
Amith Yamasani98a00922018-08-21 12:50:30 -0400846 for (int i = 0; i < mOomAdj.length; i++) {
847 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700848 buf.putInt(mOomAdj[i]);
849 }
850
Suren Baghdasaryan254752c2018-10-12 11:10:22 -0700851 writeLmkd(buf, null);
Colin Cross59d80a52013-07-25 10:45:05 -0700852 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -0700853 mOomLevelsSet = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700854 }
855 // GB: 2048,3072,4096,6144,7168,8192
856 // HC: 8192,10240,12288,14336,16384,20480
857 }
858
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700859 public static int computeEmptyProcessLimit(int totalProcessLimit) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700860 return totalProcessLimit/2;
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700861 }
862
Dianne Hackborn311473c2019-02-04 15:34:51 -0800863 private static String buildOomTag(String prefix, String compactPrefix, String space, int val,
864 int base, boolean compact) {
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800865 final int diff = val - base;
866 if (diff == 0) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800867 if (compact) {
868 return compactPrefix;
869 }
Dianne Hackborn8e692572013-09-10 19:06:15 -0700870 if (space == null) return prefix;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800871 return prefix + space;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700872 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800873 if (diff < 10) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800874 return prefix + (compact ? "+" : "+ ") + Integer.toString(diff);
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -0800875 }
876 return prefix + "+" + Integer.toString(diff);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700877 }
878
Dianne Hackborn311473c2019-02-04 15:34:51 -0800879 public static String makeOomAdjString(int setAdj, boolean compact) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700880 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800881 return buildOomTag("cch", "cch", " ", setAdj,
882 ProcessList.CACHED_APP_MIN_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700883 } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800884 return buildOomTag("svcb ", "svcb", null, setAdj,
885 ProcessList.SERVICE_B_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700886 } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800887 return buildOomTag("prev ", "prev", null, setAdj,
888 ProcessList.PREVIOUS_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700889 } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800890 return buildOomTag("home ", "home", null, setAdj,
891 ProcessList.HOME_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700892 } else if (setAdj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800893 return buildOomTag("svc ", "svc", null, setAdj,
894 ProcessList.SERVICE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700895 } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800896 return buildOomTag("hvy ", "hvy", null, setAdj,
897 ProcessList.HEAVY_WEIGHT_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700898 } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800899 return buildOomTag("bkup ", "bkup", null, setAdj,
900 ProcessList.BACKUP_APP_ADJ, compact);
Amith Yamasani0567ec62019-01-23 11:11:02 -0800901 } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
902 return buildOomTag("prcl ", "prcl", null, setAdj,
903 ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700904 } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800905 return buildOomTag("prcp ", "prcp", null, setAdj,
906 ProcessList.PERCEPTIBLE_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700907 } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800908 return buildOomTag("vis", "vis", " ", setAdj,
909 ProcessList.VISIBLE_APP_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700910 } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800911 return buildOomTag("fore ", "fore", null, setAdj,
912 ProcessList.FOREGROUND_APP_ADJ, compact);
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700913 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800914 return buildOomTag("psvc ", "psvc", null, setAdj,
915 ProcessList.PERSISTENT_SERVICE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700916 } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800917 return buildOomTag("pers ", "pers", null, setAdj,
918 ProcessList.PERSISTENT_PROC_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700919 } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800920 return buildOomTag("sys ", "sys", null, setAdj,
921 ProcessList.SYSTEM_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700922 } else if (setAdj >= ProcessList.NATIVE_ADJ) {
Dianne Hackborn311473c2019-02-04 15:34:51 -0800923 return buildOomTag("ntv ", "ntv", null, setAdj,
924 ProcessList.NATIVE_ADJ, compact);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700925 } else {
926 return Integer.toString(setAdj);
927 }
928 }
929
Dianne Hackborn8e692572013-09-10 19:06:15 -0700930 public static String makeProcStateString(int curProcState) {
931 String procState;
932 switch (curProcState) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700933 case ActivityManager.PROCESS_STATE_PERSISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700934 procState = "PER ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700935 break;
936 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Dianne Hackborn94846032017-03-31 17:55:23 -0700937 procState = "PERU";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700938 break;
939 case ActivityManager.PROCESS_STATE_TOP:
Dianne Hackbornf4dd3712017-05-11 17:25:23 -0700940 procState = "TOP ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700941 break;
Amith Yamasanif235d0b2019-03-20 22:49:43 -0700942 case ActivityManager.PROCESS_STATE_BOUND_TOP:
943 procState = "BTOP";
944 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700945 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700946 procState = "FGS ";
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700947 break;
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -0800948 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
949 procState = "BFGS";
950 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700951 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700952 procState = "IMPF";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700953 break;
954 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Dianne Hackborn94846032017-03-31 17:55:23 -0700955 procState = "IMPB";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700956 break;
Dianne Hackborn83b40f62017-04-26 13:59:47 -0700957 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
958 procState = "TRNB";
959 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700960 case ActivityManager.PROCESS_STATE_BACKUP:
Dianne Hackborn94846032017-03-31 17:55:23 -0700961 procState = "BKUP";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700962 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700963 case ActivityManager.PROCESS_STATE_SERVICE:
Dianne Hackborn94846032017-03-31 17:55:23 -0700964 procState = "SVC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700965 break;
966 case ActivityManager.PROCESS_STATE_RECEIVER:
Dianne Hackborn94846032017-03-31 17:55:23 -0700967 procState = "RCVR";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700968 break;
Dianne Hackbornbad8d912017-12-18 16:45:52 -0800969 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
970 procState = "TPSL";
971 break;
Dianne Hackbornf097d422017-12-15 16:32:19 -0800972 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
973 procState = "HVY ";
974 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700975 case ActivityManager.PROCESS_STATE_HOME:
Dianne Hackborn94846032017-03-31 17:55:23 -0700976 procState = "HOME";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700977 break;
978 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700979 procState = "LAST";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700980 break;
981 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700982 procState = "CAC ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700983 break;
984 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700985 procState = "CACC";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700986 break;
Dianne Hackborn68a06332017-11-15 17:54:18 -0800987 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
988 procState = "CRE ";
989 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700990 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Dianne Hackborn94846032017-03-31 17:55:23 -0700991 procState = "CEM ";
Dianne Hackborn8e692572013-09-10 19:06:15 -0700992 break;
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800993 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Dianne Hackborn94846032017-03-31 17:55:23 -0700994 procState = "NONE";
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800995 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700996 default:
997 procState = "??";
998 break;
999 }
1000 return procState;
1001 }
1002
Yi Jin148d7f42017-11-28 14:23:56 -08001003 public static int makeProcStateProtoEnum(int curProcState) {
1004 switch (curProcState) {
1005 case ActivityManager.PROCESS_STATE_PERSISTENT:
Bookatzdb026a22018-01-10 19:01:56 -08001006 return AppProtoEnums.PROCESS_STATE_PERSISTENT;
Yi Jin148d7f42017-11-28 14:23:56 -08001007 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
Bookatzdb026a22018-01-10 19:01:56 -08001008 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
Yi Jin148d7f42017-11-28 14:23:56 -08001009 case ActivityManager.PROCESS_STATE_TOP:
Bookatzdb026a22018-01-10 19:01:56 -08001010 return AppProtoEnums.PROCESS_STATE_TOP;
Amith Yamasanif235d0b2019-03-20 22:49:43 -07001011 case ActivityManager.PROCESS_STATE_BOUND_TOP:
1012 return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
Yi Jin148d7f42017-11-28 14:23:56 -08001013 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -08001014 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
Amith Yamasania0a30a12019-01-22 11:38:06 -08001015 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
1016 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -08001017 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
Bookatzdb026a22018-01-10 19:01:56 -08001018 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING;
Yi Jin148d7f42017-11-28 14:23:56 -08001019 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
Bookatzdb026a22018-01-10 19:01:56 -08001020 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -08001021 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -08001022 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -08001023 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
Bookatzdb026a22018-01-10 19:01:56 -08001024 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND;
Yi Jin148d7f42017-11-28 14:23:56 -08001025 case ActivityManager.PROCESS_STATE_BACKUP:
Bookatzdb026a22018-01-10 19:01:56 -08001026 return AppProtoEnums.PROCESS_STATE_BACKUP;
Yi Jin148d7f42017-11-28 14:23:56 -08001027 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
Bookatzdb026a22018-01-10 19:01:56 -08001028 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT;
Yi Jin148d7f42017-11-28 14:23:56 -08001029 case ActivityManager.PROCESS_STATE_SERVICE:
Bookatzdb026a22018-01-10 19:01:56 -08001030 return AppProtoEnums.PROCESS_STATE_SERVICE;
Yi Jin148d7f42017-11-28 14:23:56 -08001031 case ActivityManager.PROCESS_STATE_RECEIVER:
Bookatzdb026a22018-01-10 19:01:56 -08001032 return AppProtoEnums.PROCESS_STATE_RECEIVER;
Yi Jin148d7f42017-11-28 14:23:56 -08001033 case ActivityManager.PROCESS_STATE_HOME:
Bookatzdb026a22018-01-10 19:01:56 -08001034 return AppProtoEnums.PROCESS_STATE_HOME;
Yi Jin148d7f42017-11-28 14:23:56 -08001035 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -08001036 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -08001037 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
Bookatzdb026a22018-01-10 19:01:56 -08001038 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY;
Yi Jin148d7f42017-11-28 14:23:56 -08001039 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
Bookatzdb026a22018-01-10 19:01:56 -08001040 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
Yi Jin148d7f42017-11-28 14:23:56 -08001041 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
Bookatzdb026a22018-01-10 19:01:56 -08001042 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT;
Yi Jin148d7f42017-11-28 14:23:56 -08001043 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
Bookatzdb026a22018-01-10 19:01:56 -08001044 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY;
Yi Jin148d7f42017-11-28 14:23:56 -08001045 case ActivityManager.PROCESS_STATE_NONEXISTENT:
Bookatzdb026a22018-01-10 19:01:56 -08001046 return AppProtoEnums.PROCESS_STATE_NONEXISTENT;
1047 case ActivityManager.PROCESS_STATE_UNKNOWN:
1048 return AppProtoEnums.PROCESS_STATE_UNKNOWN;
Yi Jin148d7f42017-11-28 14:23:56 -08001049 default:
Bookatzdb026a22018-01-10 19:01:56 -08001050 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO;
Yi Jin148d7f42017-11-28 14:23:56 -08001051 }
1052 }
1053
Dianne Hackborn8e692572013-09-10 19:06:15 -07001054 public static void appendRamKb(StringBuilder sb, long ramKb) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001055 for (int j = 0, fact = 10; j < 6; j++, fact *= 10) {
Dianne Hackborn8e692572013-09-10 19:06:15 -07001056 if (ramKb < fact) {
1057 sb.append(' ');
1058 }
1059 }
1060 sb.append(ramKb);
1061 }
1062
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -08001063 // How long after a state change that it is safe to collect PSS without it being dirty.
1064 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
1065
1066 // The minimum time interval after a state change it is safe to collect PSS.
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001067 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
1068
1069 // The maximum amount of time we want to go between PSS collections.
Dianne Hackborne17b4452018-01-10 13:15:40 -08001070 public static final int PSS_MAX_INTERVAL = 60*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001071
1072 // The minimum amount of time between successive PSS requests for *all* processes.
Dianne Hackborn052e3142017-12-19 16:08:30 -08001073 public static final int PSS_ALL_INTERVAL = 20*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001074
Dianne Hackborn052e3142017-12-19 16:08:30 -08001075 // The amount of time until PSS when a persistent process first appears.
1076 private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001077
1078 // The amount of time until PSS when a process first becomes top.
1079 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
1080
1081 // The amount of time until PSS when a process first goes into the background.
1082 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
1083
1084 // The amount of time until PSS when a process first becomes cached.
Dianne Hackborne17b4452018-01-10 13:15:40 -08001085 private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;
1086
1087 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -08001088 private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001089
Dianne Hackborn052e3142017-12-19 16:08:30 -08001090 // The amount of time until PSS when the top process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -08001091 private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;
Dianne Hackborn052e3142017-12-19 16:08:30 -08001092
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001093 // The amount of time until PSS when an important process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -08001094 private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001095
1096 // The amount of time until PSS when a service process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -08001097 private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001098
1099 // The amount of time until PSS when a cached process stays in the same state.
Dianne Hackborned0a3222018-02-06 16:01:23 -08001100 private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001101
Dianne Hackborn052e3142017-12-19 16:08:30 -08001102 // The amount of time until PSS when a persistent process first appears.
1103 private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
1104
1105 // The amount of time until PSS when a process first becomes top.
1106 private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000;
1107
1108 // The amount of time until PSS when a process first goes into the background.
1109 private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000;
1110
1111 // The amount of time until PSS when a process first becomes cached.
1112 private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000;
1113
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -08001114 // The minimum time interval after a state change it is safe to collect PSS.
1115 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
1116
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001117 // The amount of time during testing until PSS when a process first becomes top.
1118 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
1119
1120 // The amount of time during testing until PSS when a process first goes into the background.
1121 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
1122
1123 // The amount of time during testing until PSS when an important process stays in same state.
1124 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
1125
1126 // The amount of time during testing until PSS when a background process stays in same state.
1127 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
1128
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001129 public static final int PROC_MEM_PERSISTENT = 0;
1130 public static final int PROC_MEM_TOP = 1;
1131 public static final int PROC_MEM_IMPORTANT = 2;
1132 public static final int PROC_MEM_SERVICE = 3;
1133 public static final int PROC_MEM_CACHED = 4;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001134 public static final int PROC_MEM_NUM = 5;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001135
Dianne Hackborne17b4452018-01-10 13:15:40 -08001136 // Map large set of system process states to
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001137 private static final int[] sProcStateToProcMem = new int[] {
1138 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
1139 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
1140 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001141 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
Amith Yamasanif235d0b2019-03-20 22:49:43 -07001142 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_BOUND_TOP
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -08001143 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001144 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
1145 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
Dianne Hackborn83b40f62017-04-26 13:59:47 -07001146 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001147 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001148 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
1149 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER
Dianne Hackbornbad8d912017-12-18 16:45:52 -08001150 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackbornf097d422017-12-15 16:32:19 -08001151 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001152 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME
1153 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
1154 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
1155 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
Dianne Hackborn68a06332017-11-15 17:54:18 -08001156 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001157 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
1158 };
1159
1160 private static final long[] sFirstAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001161 PSS_FIRST_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1162 PSS_FIRST_TOP_INTERVAL, // PROC_MEM_TOP
1163 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1164 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1165 PSS_FIRST_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001166 };
1167
1168 private static final long[] sSameAwakePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001169 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1170 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP
1171 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
1172 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE
1173 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn052e3142017-12-19 16:08:30 -08001174 };
1175
1176 private static final long[] sFirstAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001177 PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1178 PSS_FIRST_ASLEEP_TOP_INTERVAL, // PROC_MEM_TOP
1179 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1180 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1181 PSS_FIRST_ASLEEP_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn052e3142017-12-19 16:08:30 -08001182 };
1183
1184 private static final long[] sSameAsleepPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001185 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT
1186 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP
1187 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
1188 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE
1189 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001190 };
1191
Dianne Hackbornf097d422017-12-15 16:32:19 -08001192 private static final long[] sTestFirstPssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001193 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_PERSISTENT
1194 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_TOP
1195 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT
1196 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1197 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001198 };
1199
Dianne Hackbornf097d422017-12-15 16:32:19 -08001200 private static final long[] sTestSamePssTimes = new long[] {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001201 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_PERSISTENT
1202 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_TOP
1203 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT
1204 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE
1205 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_CACHED
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001206 };
1207
Dianne Hackborne17b4452018-01-10 13:15:40 -08001208 public static final class ProcStateMemTracker {
1209 final int[] mHighestMem = new int[PROC_MEM_NUM];
Dianne Hackborned0a3222018-02-06 16:01:23 -08001210 final float[] mScalingFactor = new float[PROC_MEM_NUM];
Dianne Hackborne17b4452018-01-10 13:15:40 -08001211 int mTotalHighestMem = PROC_MEM_CACHED;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001212
1213 int mPendingMemState;
1214 int mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001215 float mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001216
1217 public ProcStateMemTracker() {
1218 for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
1219 mHighestMem[i] = PROC_MEM_NUM;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001220 mScalingFactor[i] = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001221 }
1222 mPendingMemState = -1;
1223 }
1224
1225 public void dumpLine(PrintWriter pw) {
1226 pw.print("best=");
1227 pw.print(mTotalHighestMem);
Dianne Hackborned0a3222018-02-06 16:01:23 -08001228 pw.print(" (");
1229 boolean needSep = false;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001230 for (int i = 0; i < PROC_MEM_NUM; i++) {
Dianne Hackborned0a3222018-02-06 16:01:23 -08001231 if (mHighestMem[i] < PROC_MEM_NUM) {
1232 if (needSep) {
1233 pw.print(", ");
1234 needSep = false;
1235 }
1236 pw.print(i);
1237 pw.print("=");
1238 pw.print(mHighestMem[i]);
1239 pw.print(" ");
1240 pw.print(mScalingFactor[i]);
1241 pw.print("x");
1242 needSep = true;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001243 }
Dianne Hackborne17b4452018-01-10 13:15:40 -08001244 }
1245 pw.print(")");
1246 if (mPendingMemState >= 0) {
1247 pw.print(" / pending state=");
1248 pw.print(mPendingMemState);
1249 pw.print(" highest=");
1250 pw.print(mPendingHighestMemState);
Dianne Hackborned0a3222018-02-06 16:01:23 -08001251 pw.print(" ");
1252 pw.print(mPendingScalingFactor);
1253 pw.print("x");
Dianne Hackborne17b4452018-01-10 13:15:40 -08001254 }
1255 pw.println();
1256 }
1257 }
1258
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001259 public static boolean procStatesDifferForMem(int procState1, int procState2) {
1260 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
1261 }
1262
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -08001263 public static long minTimeFromStateChange(boolean test) {
1264 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
1265 }
1266
Dianne Hackborne17b4452018-01-10 13:15:40 -08001267 public static void commitNextPssTime(ProcStateMemTracker tracker) {
1268 if (tracker.mPendingMemState >= 0) {
1269 tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001270 tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001271 tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001272 tracker.mPendingMemState = -1;
1273 }
1274 }
1275
1276 public static void abortNextPssTime(ProcStateMemTracker tracker) {
1277 tracker.mPendingMemState = -1;
1278 }
1279
1280 public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001281 boolean sleeping, long now) {
Dianne Hackborne17b4452018-01-10 13:15:40 -08001282 boolean first;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001283 float scalingFactor;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001284 final int memState = sProcStateToProcMem[procState];
1285 if (tracker != null) {
1286 final int highestMemState = memState < tracker.mTotalHighestMem
1287 ? memState : tracker.mTotalHighestMem;
1288 first = highestMemState < tracker.mHighestMem[memState];
1289 tracker.mPendingMemState = memState;
1290 tracker.mPendingHighestMemState = highestMemState;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001291 if (first) {
1292 tracker.mPendingScalingFactor = scalingFactor = 1.0f;
1293 } else {
1294 scalingFactor = tracker.mScalingFactor[memState];
1295 tracker.mPendingScalingFactor = scalingFactor * 1.5f;
1296 }
Dianne Hackborne17b4452018-01-10 13:15:40 -08001297 } else {
1298 first = true;
Dianne Hackborned0a3222018-02-06 16:01:23 -08001299 scalingFactor = 1.0f;
Dianne Hackborne17b4452018-01-10 13:15:40 -08001300 }
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -08001301 final long[] table = test
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001302 ? (first
Dianne Hackborne17b4452018-01-10 13:15:40 -08001303 ? sTestFirstPssTimes
1304 : sTestSamePssTimes)
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001305 : (first
Dianne Hackborne17b4452018-01-10 13:15:40 -08001306 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
1307 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
Dianne Hackborned0a3222018-02-06 16:01:23 -08001308 long delay = (long)(table[memState] * scalingFactor);
Dianne Hackborne17b4452018-01-10 13:15:40 -08001309 if (delay > PSS_MAX_INTERVAL) {
1310 delay = PSS_MAX_INTERVAL;
1311 }
1312 return now + delay;
Dianne Hackbornf1cca182013-08-01 10:50:28 -07001313 }
1314
Dianne Hackborn7d608422011-08-07 16:24:18 -07001315 long getMemLevel(int adjustment) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001316 for (int i = 0; i < mOomAdj.length; i++) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07001317 if (adjustment <= mOomAdj[i]) {
1318 return mOomMinFree[i] * 1024;
1319 }
1320 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001321 return mOomMinFree[mOomAdj.length - 1] * 1024;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001322 }
1323
Todd Poynorbfdd6232013-07-10 19:15:07 -07001324 /**
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001325 * Return the maximum pss size in kb that we consider a process acceptable to
1326 * restore from its cached state for running in the background when RAM is low.
1327 */
Dianne Hackborncbd9a522013-09-24 23:10:14 -07001328 long getCachedRestoreThresholdKb() {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001329 return mCachedRestoreLevel;
1330 }
1331
Dianne Hackborn9bef5b62013-09-20 10:40:34 -07001332 /**
Todd Poynorbfdd6232013-07-10 19:15:07 -07001333 * Set the out-of-memory badness adjustment for a process.
Sudheer Shankaf6690102017-10-16 10:20:32 -07001334 * If {@code pid <= 0}, this method will be a no-op.
Todd Poynorbfdd6232013-07-10 19:15:07 -07001335 *
1336 * @param pid The process identifier to set.
Colin Crossd908edd2014-06-13 14:56:04 -07001337 * @param uid The uid of the app
Rafal Slawikda8c0ab2019-03-07 13:54:40 +00001338 * @param amt Adjustment value -- lmkd allows -1000 to +1000
Todd Poynorbfdd6232013-07-10 19:15:07 -07001339 *
1340 * {@hide}
1341 */
Rafal Slawikda8c0ab2019-03-07 13:54:40 +00001342 public static void setOomAdj(int pid, int uid, int amt) {
Sudheer Shankaf6690102017-10-16 10:20:32 -07001343 // This indicates that the process is not started yet and so no need to proceed further.
1344 if (pid <= 0) {
1345 return;
1346 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001347 if (amt == UNKNOWN_ADJ)
1348 return;
1349
Dianne Hackbornecf1cda2014-08-28 16:58:28 -07001350 long start = SystemClock.elapsedRealtime();
Colin Crossd908edd2014-06-13 14:56:04 -07001351 ByteBuffer buf = ByteBuffer.allocate(4 * 4);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001352 buf.putInt(LMK_PROCPRIO);
1353 buf.putInt(pid);
Colin Crossd908edd2014-06-13 14:56:04 -07001354 buf.putInt(uid);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001355 buf.putInt(amt);
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001356 writeLmkd(buf, null);
Dianne Hackbornecf1cda2014-08-28 16:58:28 -07001357 long now = SystemClock.elapsedRealtime();
1358 if ((now-start) > 250) {
1359 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
1360 + " = " + amt);
1361 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001362 }
1363
1364 /*
1365 * {@hide}
1366 */
1367 public static final void remove(int pid) {
Sudheer Shankaf6690102017-10-16 10:20:32 -07001368 // This indicates that the process is not started yet and so no need to proceed further.
1369 if (pid <= 0) {
1370 return;
1371 }
Todd Poynorbfdd6232013-07-10 19:15:07 -07001372 ByteBuffer buf = ByteBuffer.allocate(4 * 2);
1373 buf.putInt(LMK_PROCREMOVE);
1374 buf.putInt(pid);
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001375 writeLmkd(buf, null);
Todd Poynorbfdd6232013-07-10 19:15:07 -07001376 }
1377
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001378 /*
1379 * {@hide}
1380 */
1381 public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) {
1382 ByteBuffer buf = ByteBuffer.allocate(4 * 3);
1383 ByteBuffer repl = ByteBuffer.allocate(4 * 2);
1384 buf.putInt(LMK_GETKILLCNT);
1385 buf.putInt(min_oom_adj);
1386 buf.putInt(max_oom_adj);
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001387 // indicate what we are waiting for
1388 repl.putInt(LMK_GETKILLCNT);
1389 repl.rewind();
1390 if (writeLmkd(buf, repl) && repl.getInt() == LMK_GETKILLCNT) {
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001391 return new Integer(repl.getInt());
1392 }
1393 return null;
1394 }
1395
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001396 public boolean onLmkdConnect(OutputStream ostream) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07001397 try {
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001398 // Purge any previously registered pids
1399 ByteBuffer buf = ByteBuffer.allocate(4);
1400 buf.putInt(LMK_PROCPURGE);
1401 ostream.write(buf.array(), 0, buf.position());
1402 if (mOomLevelsSet) {
1403 // Reset oom_adj levels
1404 buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
1405 buf.putInt(LMK_TARGET);
1406 for (int i = 0; i < mOomAdj.length; i++) {
1407 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
1408 buf.putInt(mOomAdj[i]);
1409 }
1410 ostream.write(buf.array(), 0, buf.position());
Suren Baghdasaryan2b2011a2018-10-10 14:22:20 -07001411 }
Suren Baghdasaryanb6b8d1d2019-12-23 13:38:53 -08001412 // Subscribe for kill event notifications
1413 buf = ByteBuffer.allocate(4 * 2);
1414 buf.putInt(LMK_SUBSCRIBE);
1415 buf.putInt(LMK_ASYNC_EVENT_KILL);
1416 ostream.write(buf.array(), 0, buf.position());
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001417 } catch (IOException ex) {
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001418 return false;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001419 }
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001420 return true;
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001421 }
1422
1423 private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001424 if (!sLmkdConnection.isConnected()) {
1425 // try to connect immediately and then keep retrying
1426 sKillHandler.sendMessage(
Jing Ji4fcb2a12019-09-11 16:59:36 -07001427 sKillHandler.obtainMessage(KillHandler.LMKD_RECONNECT_MSG));
Suren Baghdasaryan254752c2018-10-12 11:10:22 -07001428
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001429 // wait for connection retrying 3 times (up to 3 seconds)
Jing Ji4fcb2a12019-09-11 16:59:36 -07001430 if (!sLmkdConnection.waitForConnection(3 * LMKD_RECONNECT_DELAY_MS)) {
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001431 return false;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001432 }
1433 }
Suren Baghdasaryan4a4bc7d2019-03-15 15:06:54 -07001434
1435 return sLmkdConnection.exchange(buf, repl);
Dianne Hackborn7d608422011-08-07 16:24:18 -07001436 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001437
1438 static void killProcessGroup(int uid, int pid) {
1439 /* static; one-time init here */
1440 if (sKillHandler != null) {
1441 sKillHandler.sendMessage(
1442 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
1443 } else {
1444 Slog.w(TAG, "Asked to kill process group before system bringup!");
1445 Process.killProcessGroup(uid, pid);
1446 }
1447 }
1448
1449 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean
1450 keepIfLarge) {
1451 if (uid == SYSTEM_UID) {
1452 // The system gets to run in any process. If there are multiple
1453 // processes with the same uid, just pick the first (this
1454 // should never happen).
1455 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
1456 if (procs == null) return null;
1457 final int procCount = procs.size();
1458 for (int i = 0; i < procCount; i++) {
1459 final int procUid = procs.keyAt(i);
Jing Ji78a3a742019-11-04 11:35:49 -08001460 if (!UserHandle.isCore(procUid) || !UserHandle.isSameUser(procUid, uid)) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001461 // Don't use an app process or different user process for system component.
1462 continue;
1463 }
1464 return procs.valueAt(i);
1465 }
1466 }
1467 ProcessRecord proc = mProcessNames.get(processName, uid);
1468 if (false && proc != null && !keepIfLarge
1469 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
1470 && proc.lastCachedPss >= 4000) {
1471 // Turn this condition on to cause killing to happen regularly, for testing.
1472 if (proc.baseProcessTracker != null) {
1473 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
1474 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1475 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1476 StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1477 proc.info.uid,
1478 holder.state.getName(),
1479 holder.state.getPackage(),
1480 proc.lastCachedPss, holder.appVersion);
1481 }
1482 }
Jing Ji8055a3a2019-12-17 15:55:33 -08001483 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached",
1484 ApplicationExitInfo.REASON_OTHER,
1485 ApplicationExitInfo.SUBREASON_LARGE_CACHED,
1486 true);
Amith Yamasani98a00922018-08-21 12:50:30 -04001487 } else if (proc != null && !keepIfLarge
1488 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
1489 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
1490 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc
1491 .lastCachedPss);
1492 if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) {
1493 if (proc.baseProcessTracker != null) {
1494 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
1495 proc.lastCachedPss);
1496 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
1497 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
1498 StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
1499 proc.info.uid,
1500 holder.state.getName(),
1501 holder.state.getPackage(),
1502 proc.lastCachedPss, holder.appVersion);
1503 }
1504 }
Jing Ji8055a3a2019-12-17 15:55:33 -08001505 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached",
1506 ApplicationExitInfo.REASON_OTHER,
1507 ApplicationExitInfo.SUBREASON_LARGE_CACHED,
1508 true);
Amith Yamasani98a00922018-08-21 12:50:30 -04001509 }
1510 }
1511 return proc;
1512 }
1513
1514 void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
1515 final long homeAppMem = getMemLevel(HOME_APP_ADJ);
1516 final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ);
1517 outInfo.availMem = getFreeMemory();
1518 outInfo.totalMem = getTotalMemory();
1519 outInfo.threshold = homeAppMem;
1520 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
1521 outInfo.hiddenAppThreshold = cachedAppMem;
1522 outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ);
1523 outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ);
1524 outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ);
1525 }
1526
1527 ProcessRecord findAppProcessLocked(IBinder app, String reason) {
1528 final int NP = mProcessNames.getMap().size();
1529 for (int ip = 0; ip < NP; ip++) {
1530 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
1531 final int NA = apps.size();
1532 for (int ia = 0; ia < NA; ia++) {
1533 ProcessRecord p = apps.valueAt(ia);
1534 if (p.thread != null && p.thread.asBinder() == app) {
1535 return p;
1536 }
1537 }
1538 }
1539
1540 Slog.w(TAG, "Can't find mystery application for " + reason
1541 + " from pid=" + Binder.getCallingPid()
1542 + " uid=" + Binder.getCallingUid() + ": " + app);
1543 return null;
1544 }
1545
1546 private void checkSlow(long startTime, String where) {
1547 long now = SystemClock.uptimeMillis();
1548 if ((now - startTime) > 50) {
1549 // If we are taking more than 50ms, log about it.
1550 Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where);
1551 }
1552 }
1553
Zim86f98ce2020-01-24 17:37:20 +00001554 private int[] computeGidsForProcess(int mountExternal, int uid, int[] permGids) {
Zim3982e542020-01-24 14:13:17 +00001555 ArrayList<Integer> gidList = new ArrayList<>(permGids.length + 5);
1556
1557 final int sharedAppGid = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
1558 final int cacheAppGid = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
1559 final int userGid = UserHandle.getUserGid(UserHandle.getUserId(uid));
1560
1561 // Add shared application and profile GIDs so applications can share some
1562 // resources like shared libraries and access user-wide resources
1563 for (int permGid : permGids) {
1564 gidList.add(permGid);
1565 }
1566 if (sharedAppGid != UserHandle.ERR_GID) {
1567 gidList.add(sharedAppGid);
1568 }
1569 if (cacheAppGid != UserHandle.ERR_GID) {
1570 gidList.add(cacheAppGid);
1571 }
1572 if (userGid != UserHandle.ERR_GID) {
1573 gidList.add(userGid);
1574 }
1575 if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
Zimda8df982020-01-24 16:44:10 +00001576 // For DownloadProviders and MTP: To grant access to /sdcard/Android/
Zim3982e542020-01-24 14:13:17 +00001577 gidList.add(Process.SDCARD_RW_GID);
1578 }
Zimda8df982020-01-24 16:44:10 +00001579 if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
1580 // For the FUSE daemon: To grant access to the lower filesystem.
1581 // EmulatedVolumes: /data/media and /mnt/expand/<volume>/data/media
1582 // PublicVolumes: /mnt/media_rw/<volume>
1583 gidList.add(Process.MEDIA_RW_GID);
1584 }
Zim3982e542020-01-24 14:13:17 +00001585
1586 int[] gidArray = new int[gidList.size()];
1587 for (int i = 0; i < gidArray.length; i++) {
1588 gidArray[i] = gidList.get(i);
1589 }
1590 return gidArray;
1591 }
1592
Amith Yamasani98a00922018-08-21 12:50:30 -04001593 /**
1594 * @return {@code true} if process start is successful, false otherwise.
Amith Yamasani98a00922018-08-21 12:50:30 -04001595 */
1596 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01001597 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
Artur Satayev19305b42019-10-28 15:25:14 +00001598 boolean disableHiddenApiChecks, boolean disableTestApiChecks,
1599 boolean mountExtStorageFull, String abiOverride) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001600 if (app.pendingStart) {
1601 return true;
1602 }
Jing Ji03109072019-12-02 20:49:23 -08001603 long startTime = SystemClock.uptimeMillis();
Amith Yamasani98a00922018-08-21 12:50:30 -04001604 if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
1605 checkSlow(startTime, "startProcess: removing from pids map");
Dianne Hackbornf6729fa2020-01-06 13:12:36 -08001606 mService.removePidLocked(app);
Wale Ogunwale0b940842018-12-03 06:58:11 -08001607 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04001608 checkSlow(startTime, "startProcess: done removing from pids map");
1609 app.setPid(0);
Hui Yu6dabda82019-05-07 14:02:57 -07001610 app.startSeq = 0;
Amith Yamasani98a00922018-08-21 12:50:30 -04001611 }
1612
1613 if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
1614 TAG_PROCESSES,
1615 "startProcessLocked removing on hold: " + app);
1616 mService.mProcessesOnHold.remove(app);
1617
1618 checkSlow(startTime, "startProcess: starting to update cpu stats");
1619 mService.updateCpuStats();
1620 checkSlow(startTime, "startProcess: done updating cpu stats");
1621
1622 try {
1623 try {
1624 final int userId = UserHandle.getUserId(app.uid);
1625 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
1626 } catch (RemoteException e) {
1627 throw e.rethrowAsRuntimeException();
1628 }
1629
1630 int uid = app.uid;
1631 int[] gids = null;
1632 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1633 if (!app.isolated) {
1634 int[] permGids = null;
1635 try {
1636 checkSlow(startTime, "startProcess: getting gids from package manager");
1637 final IPackageManager pm = AppGlobals.getPackageManager();
1638 permGids = pm.getPackageGids(app.info.packageName,
1639 MATCH_DIRECT_BOOT_AUTO, app.userId);
Jeff Sharkey10ec9d82018-11-28 14:52:45 -07001640 if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07001641 mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
1642 } else {
1643 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1644 StorageManagerInternal.class);
1645 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
1646 app.info.packageName);
1647 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001648 } catch (RemoteException e) {
1649 throw e.rethrowAsRuntimeException();
1650 }
Dianne Hackbornf6729fa2020-01-06 13:12:36 -08001651
1652 // Remove any gids needed if the process has been denied permissions.
1653 // NOTE: eventually we should probably have the package manager pre-compute
1654 // this for us?
1655 if (app.processInfo != null && app.processInfo.deniedPermissions != null) {
1656 for (int i = app.processInfo.deniedPermissions.size() - 1; i >= 0; i--) {
1657 int[] denyGids = mService.mPackageManagerInt.getPermissionGids(
1658 app.processInfo.deniedPermissions.valueAt(i), app.userId);
1659 if (denyGids != null) {
1660 for (int gid : denyGids) {
1661 permGids = ArrayUtils.removeInt(permGids, gid);
1662 }
1663 }
1664 }
1665 }
1666
Zim86f98ce2020-01-24 17:37:20 +00001667 gids = computeGidsForProcess(mountExternal, uid, permGids);
Amith Yamasani98a00922018-08-21 12:50:30 -04001668 }
Sudheer Shanka87915d62018-11-06 10:57:35 -08001669 app.mountMode = mountExternal;
Amith Yamasani98a00922018-08-21 12:50:30 -04001670 checkSlow(startTime, "startProcess: building args");
1671 if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
1672 uid = 0;
1673 }
1674 int runtimeFlags = 0;
1675 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1676 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
1677 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
1678 // Also turn on CheckJNI for debuggable apps. It's quite
1679 // awkward to turn on otherwise.
1680 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
Alex Buynytskyy5d5921ee2019-01-22 15:22:55 -08001681
1682 // Check if the developer does not want ART verification
1683 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(),
1684 android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) {
1685 runtimeFlags |= Zygote.DISABLE_VERIFIER;
1686 Slog.w(TAG_PROCESSES, app + ": ART verification disabled");
1687 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001688 }
1689 // Run the app in safe mode if its manifest requests so or the
1690 // system is booted in safe mode.
1691 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1692 mService.mSafeMode == true) {
1693 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1694 }
Yabin Cui4d8546d2019-01-29 16:29:20 -08001695 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
1696 runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
1697 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001698 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1699 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1700 }
1701 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
1702 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
1703 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
1704 }
1705 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
1706 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
1707 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
1708 }
1709 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1710 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1711 }
1712 if ("1".equals(SystemProperties.get("debug.assert"))) {
1713 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1714 }
randy.jeong4c2eafc2019-05-29 10:43:39 +09001715 if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) {
1716 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER;
1717 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001718 if (mService.mNativeDebuggingApp != null
1719 && mService.mNativeDebuggingApp.equals(app.processName)) {
1720 // Enable all debug flags required by the native debugger.
1721 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
1722 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
1723 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
1724 mService.mNativeDebuggingApp = null;
1725 }
1726
Victor Hsiehfa9df0b2019-01-29 12:48:36 -08001727 if (app.info.isEmbeddedDexUsed()
Victor Hsiehe7b5a8d2018-11-16 10:27:06 -08001728 || (app.info.isPrivilegedApp()
1729 && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04001730 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
1731 }
1732
1733 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
1734 app.info.maybeUpdateHiddenApiEnforcementPolicy(
David Brazdil06ae4b82018-11-02 18:01:45 +00001735 mService.mHiddenApiBlacklist.getPolicy());
Amith Yamasani98a00922018-08-21 12:50:30 -04001736 @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
1737 app.info.getHiddenApiEnforcementPolicy();
1738 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
1739 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
1740 throw new IllegalStateException("Invalid API policy: " + policy);
1741 }
1742 runtimeFlags |= policyBits;
Artur Satayev19305b42019-10-28 15:25:14 +00001743
1744 if (disableTestApiChecks) {
1745 runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY;
1746 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001747 }
1748
Mathieu Chartier77bd1232019-03-05 13:53:11 -08001749 String useAppImageCache = SystemProperties.get(
1750 PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
1751 // Property defaults to true currently.
1752 if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) {
1753 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
1754 }
1755
Amith Yamasani98a00922018-08-21 12:50:30 -04001756 String invokeWith = null;
1757 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1758 // Debuggable apps may include a wrapper script with their library directory.
1759 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
1760 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
1761 try {
1762 if (new File(wrapperFileName).exists()) {
1763 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
1764 }
1765 } finally {
1766 StrictMode.setThreadPolicy(oldPolicy);
1767 }
1768 }
1769
1770 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
1771 if (requiredAbi == null) {
1772 requiredAbi = Build.SUPPORTED_ABIS[0];
1773 }
1774
1775 String instructionSet = null;
1776 if (app.info.primaryCpuAbi != null) {
1777 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
1778 }
1779
1780 app.gids = gids;
1781 app.setRequiredAbi(requiredAbi);
1782 app.instructionSet = instructionSet;
1783
1784 // the per-user SELinux context must be set
1785 if (TextUtils.isEmpty(app.info.seInfoUser)) {
1786 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
1787 new IllegalStateException("SELinux tag not defined for "
1788 + app.info.packageName + " (uid " + app.uid + ")"));
1789 }
1790 final String seInfo = app.info.seInfo
1791 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
1792 // Start the process. It will either succeed and return a result containing
1793 // the PID of the new process, or else throw a RuntimeException.
1794 final String entryPoint = "android.app.ActivityThread";
1795
Martijn Coenene8431c22019-03-28 14:09:38 +01001796 return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
Amith Yamasani98a00922018-08-21 12:50:30 -04001797 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
1798 startTime);
1799 } catch (RuntimeException e) {
1800 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1801
1802 // Something went very wrong while trying to start this process; one
1803 // common case is when the package is frozen due to an active
1804 // upgrade. To recover, clean up any active bookkeeping related to
1805 // starting this process. (We already invoked this method once when
1806 // the package was initially frozen through KILL_APPLICATION_MSG, so
1807 // it doesn't hurt to use it again.)
1808 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1809 false, false, true, false, false, app.userId, "start failure");
1810 return false;
1811 }
1812 }
1813
1814 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01001815 boolean startProcessLocked(HostingRecord hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04001816 String entryPoint,
1817 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
1818 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1819 long startTime) {
1820 app.pendingStart = true;
1821 app.killedByAm = false;
1822 app.removed = false;
1823 app.killed = false;
Hui Yu6dabda82019-05-07 14:02:57 -07001824 if (app.startSeq != 0) {
1825 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
1826 + " with non-zero startSeq:" + app.startSeq);
1827 }
1828 if (app.pid != 0) {
1829 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
1830 + " with non-zero pid:" + app.pid);
1831 }
atrost5ae996f2019-12-11 18:32:48 +00001832 app.mDisabledCompatChanges = null;
1833 if (mPlatformCompat != null) {
1834 app.mDisabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info);
1835 }
Amith Yamasani98a00922018-08-21 12:50:30 -04001836 final long startSeq = app.startSeq = ++mProcStartSeqCounter;
Martijn Coenene8431c22019-03-28 14:09:38 +01001837 app.setStartParams(uid, hostingRecord, seInfo, startTime);
Amith Yamasani4b76bc12019-04-24 11:46:43 -07001838 app.setUsingWrapper(invokeWith != null
Christopher Ferris2d030bc2019-06-05 14:05:21 -07001839 || Zygote.getWrapProperty(app.processName) != null);
Amith Yamasani4b76bc12019-04-24 11:46:43 -07001840 mPendingStarts.put(startSeq, app);
1841
Amith Yamasani98a00922018-08-21 12:50:30 -04001842 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
1843 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
1844 "Posting procStart msg for " + app.toShortString());
1845 mService.mProcStartHandler.post(() -> {
1846 try {
Martijn Coenene8431c22019-03-28 14:09:38 +01001847 final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04001848 entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
1849 app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
1850 synchronized (mService) {
1851 handleProcessStartedLocked(app, startResult, startSeq);
1852 }
1853 } catch (RuntimeException e) {
1854 synchronized (mService) {
1855 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1856 + app.processName, e);
1857 mPendingStarts.remove(startSeq);
1858 app.pendingStart = false;
1859 mService.forceStopPackageLocked(app.info.packageName,
1860 UserHandle.getAppId(app.uid),
1861 false, false, true, false, false, app.userId, "start failure");
1862 }
1863 }
1864 });
1865 return true;
1866 } else {
1867 try {
Martijn Coenene8431c22019-03-28 14:09:38 +01001868 final Process.ProcessStartResult startResult = startProcess(hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04001869 entryPoint, app,
1870 uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
1871 invokeWith, startTime);
1872 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
1873 startSeq, false);
1874 } catch (RuntimeException e) {
1875 Slog.e(ActivityManagerService.TAG, "Failure starting process "
1876 + app.processName, e);
1877 app.pendingStart = false;
1878 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1879 false, false, true, false, false, app.userId, "start failure");
1880 }
1881 return app.pid > 0;
1882 }
1883 }
1884
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001885 @GuardedBy("mService")
Martijn Coenen4cc2a1c2020-01-21 14:40:21 +01001886 public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) {
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001887 final ApplicationInfo appInfo = appZygote.getAppInfo();
1888 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
Martijn Coenen4cc2a1c2020-01-21 14:40:21 +01001889 if (zygoteProcesses != null && (force || zygoteProcesses.size() == 0)) {
1890 // Only remove if no longer in use now, or forced kill
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001891 mAppZygotes.remove(appInfo.processName, appInfo.uid);
1892 mAppZygoteProcesses.remove(appZygote);
Martijn Coenen01e719b2018-12-05 16:01:38 +01001893 mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001894 appZygote.stopZygote();
1895 }
1896 }
1897
1898 @GuardedBy("mService")
1899 private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01001900 // Free the isolated uid for this process
1901 final IsolatedUidRange appUidRange =
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001902 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName,
1903 app.hostingRecord.getDefiningUid());
Martijn Coenen01e719b2018-12-05 16:01:38 +01001904 if (appUidRange != null) {
1905 appUidRange.freeIsolatedUidLocked(app.uid);
1906 }
1907
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001908 final AppZygote appZygote = mAppZygotes.get(app.info.processName,
1909 app.hostingRecord.getDefiningUid());
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001910 if (appZygote != null) {
1911 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
1912 zygoteProcesses.remove(app);
1913 if (zygoteProcesses.size() == 0) {
Martijn Coenenb27a8ea2019-02-12 10:23:47 +01001914 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG);
Martijn Coenen378b2702019-02-20 10:33:41 +01001915 if (app.removed) {
1916 // If we stopped this process because the package hosting it was removed,
1917 // there's no point in delaying the app zygote kill.
Martijn Coenen4cc2a1c2020-01-21 14:40:21 +01001918 killAppZygoteIfNeededLocked(appZygote, false /* force */);
Martijn Coenen378b2702019-02-20 10:33:41 +01001919 } else {
1920 Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
1921 msg.obj = appZygote;
1922 mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS);
1923 }
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001924 }
1925 }
1926 }
1927
1928 private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
1929 synchronized (mService) {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001930 // The UID for the app zygote should be the UID of the application hosting
1931 // the service.
1932 final int uid = app.hostingRecord.getDefiningUid();
1933 AppZygote appZygote = mAppZygotes.get(app.info.processName, uid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001934 final ArrayList<ProcessRecord> zygoteProcessList;
1935 if (appZygote == null) {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001936 if (DEBUG_PROCESSES) {
1937 Slog.d(TAG_PROCESSES, "Creating new app zygote.");
1938 }
Martijn Coenen01e719b2018-12-05 16:01:38 +01001939 final IsolatedUidRange uidRange =
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001940 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(
1941 app.info.processName, app.hostingRecord.getDefiningUid());
1942 final int userId = UserHandle.getUserId(uid);
Martijn Coenen86f08a52019-01-03 16:23:01 +01001943 // Create the app-zygote and provide it with the UID-range it's allowed
1944 // to setresuid/setresgid to.
1945 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
1946 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001947 ApplicationInfo appInfo = new ApplicationInfo(app.info);
1948 // If this was an external service, the package name and uid in the passed in
1949 // ApplicationInfo have been changed to match those of the calling package;
1950 // that is not what we want for the AppZygote though, which needs to have the
1951 // packageName and uid of the defining application. This is because the
1952 // preloading only makes sense in the context of the defining application,
1953 // not the calling one.
1954 appInfo.packageName = app.hostingRecord.getDefiningPackageName();
1955 appInfo.uid = uid;
1956 appZygote = new AppZygote(appInfo, uid, firstUid, lastUid);
1957 mAppZygotes.put(app.info.processName, uid, appZygote);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001958 zygoteProcessList = new ArrayList<ProcessRecord>();
1959 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
1960 } else {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01001961 if (DEBUG_PROCESSES) {
1962 Slog.d(TAG_PROCESSES, "Reusing existing app zygote.");
1963 }
Martijn Coenen7e6fa672018-11-05 11:45:26 +01001964 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
1965 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
1966 }
1967 // Note that we already add the app to mAppZygoteProcesses here;
1968 // this is so that another thread can't come in and kill the zygote
1969 // before we've even tried to start the process. If the process launch
1970 // goes wrong, we'll clean this up in removeProcessNameLocked()
1971 zygoteProcessList.add(app);
1972
1973 return appZygote;
1974 }
1975 }
1976
Ricky Wai5a8fe7a2019-12-13 15:20:47 +00001977 private boolean shouldIsolateAppData(ProcessRecord app) {
1978 if (!mAppDataIsolationEnabled) {
1979 return false;
1980 }
1981 if (!UserHandle.isApp(app.uid)) {
1982 return false;
1983 }
1984 final int minTargetSdk = DeviceConfig.getInt(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
1985 ANDROID_APP_DATA_ISOLATION_MIN_SDK, Build.VERSION_CODES.R);
1986 return app.info.targetSdkVersion >= minTargetSdk;
1987 }
1988
1989 private Map<String, Pair<String, Long>> getPackageAppDataInfoMap(PackageManagerInternal pmInt,
1990 String[] packages, int uid) {
1991 Map<String, Pair<String, Long>> result = new ArrayMap<>(packages.length);
1992 int userId = UserHandle.getUserId(uid);
1993 for (String packageName : packages) {
1994 String volumeUuid = pmInt.getPackage(packageName).getVolumeUuid();
1995 long inode = pmInt.getCeDataInode(packageName, userId);
1996 if (inode != 0) {
1997 result.put(packageName, Pair.create(volumeUuid, inode));
1998 }
1999 }
Ricky Wai825d3e92019-12-18 15:16:17 +00002000 if (mAppDataIsolationWhitelistedApps != null) {
2001 for (String packageName : mAppDataIsolationWhitelistedApps) {
2002 String volumeUuid = pmInt.getPackage(packageName).getVolumeUuid();
2003 long inode = pmInt.getCeDataInode(packageName, userId);
2004 if (inode != 0) {
2005 result.put(packageName, Pair.create(volumeUuid, inode));
2006 }
2007 }
2008 }
2009
Ricky Wai5a8fe7a2019-12-13 15:20:47 +00002010 return result;
2011 }
2012
Martijn Coenene8431c22019-03-28 14:09:38 +01002013 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
Amith Yamasani98a00922018-08-21 12:50:30 -04002014 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
2015 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
2016 long startTime) {
2017 try {
Amith Yamasani98a00922018-08-21 12:50:30 -04002018 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
2019 app.processName);
2020 checkSlow(startTime, "startProcess: asking zygote to start proc");
Riddle Hsu32dbdca2019-05-17 23:10:16 -06002021 final boolean isTopApp = hostingRecord.isTopApp();
2022 if (isTopApp) {
2023 // Use has-foreground-activities as a temporary hint so the current scheduling
2024 // group won't be lost when the process is attaching. The actual state will be
2025 // refreshed when computing oom-adj.
2026 app.setHasForegroundActivities(true);
2027 }
2028
Ricky Wai5a8fe7a2019-12-13 15:20:47 +00002029 final Map<String, Pair<String, Long>> pkgDataInfoMap;
2030
2031 if (shouldIsolateAppData(app)) {
2032 // Get all packages belongs to the same shared uid. sharedPackages is empty array
2033 // if it doesn't have shared uid.
2034 final PackageManagerInternal pmInt = mService.getPackageManagerInternalLocked();
Alan Stokes20fbef22019-12-17 15:33:12 +00002035 final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage(
2036 app.info.packageName, app.userId);
Ricky Wai5a8fe7a2019-12-13 15:20:47 +00002037 pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, sharedPackages.length == 0
2038 ? new String[]{app.info.packageName} : sharedPackages, uid);
2039 } else {
2040 pkgDataInfoMap = null;
2041 }
2042
Amith Yamasani98a00922018-08-21 12:50:30 -04002043 final Process.ProcessStartResult startResult;
Martijn Coenene8431c22019-03-28 14:09:38 +01002044 if (hostingRecord.usesWebviewZygote()) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002045 startResult = startWebView(entryPoint,
2046 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2047 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
atrost5ae996f2019-12-11 18:32:48 +00002048 app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
2049 new String[]{PROC_START_SEQ_IDENT + app.startSeq});
Martijn Coenene8431c22019-03-28 14:09:38 +01002050 } else if (hostingRecord.usesAppZygote()) {
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002051 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
2052
2053 startResult = appZygote.getProcess().start(entryPoint,
2054 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2055 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2056 app.info.dataDir, null, app.info.packageName,
atrost5ae996f2019-12-11 18:32:48 +00002057 /*useUsapPool=*/ false, isTopApp, app.mDisabledCompatChanges,
Ricky Wai5a8fe7a2019-12-13 15:20:47 +00002058 pkgDataInfoMap, new String[]{PROC_START_SEQ_IDENT + app.startSeq});
Amith Yamasani98a00922018-08-21 12:50:30 -04002059 } else {
2060 startResult = Process.start(entryPoint,
2061 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2062 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
Riddle Hsu32dbdca2019-05-17 23:10:16 -06002063 app.info.dataDir, invokeWith, app.info.packageName, isTopApp,
Ricky Wai5a8fe7a2019-12-13 15:20:47 +00002064 app.mDisabledCompatChanges, pkgDataInfoMap,
atrost5ae996f2019-12-11 18:32:48 +00002065 new String[]{PROC_START_SEQ_IDENT + app.startSeq});
Amith Yamasani98a00922018-08-21 12:50:30 -04002066 }
2067 checkSlow(startTime, "startProcess: returned from zygote!");
2068 return startResult;
2069 } finally {
2070 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2071 }
2072 }
2073
2074 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01002075 final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {
2076 startProcessLocked(app, hostingRecord, null /* abiOverride */);
Amith Yamasani98a00922018-08-21 12:50:30 -04002077 }
2078
2079 @GuardedBy("mService")
Martijn Coenene8431c22019-03-28 14:09:38 +01002080 final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
2081 String abiOverride) {
2082 return startProcessLocked(app, hostingRecord,
Artur Satayev19305b42019-10-28 15:25:14 +00002083 false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
2084 false /* mountExtStorageFull */, abiOverride);
Amith Yamasani98a00922018-08-21 12:50:30 -04002085 }
2086
2087 @GuardedBy("mService")
2088 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
Martijn Coenene8431c22019-03-28 14:09:38 +01002089 boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
Amith Yamasani98a00922018-08-21 12:50:30 -04002090 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2091 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
Jing Ji03109072019-12-02 20:49:23 -08002092 long startTime = SystemClock.uptimeMillis();
Amith Yamasani98a00922018-08-21 12:50:30 -04002093 ProcessRecord app;
2094 if (!isolated) {
2095 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2096 checkSlow(startTime, "startProcess: after getProcessRecord");
2097
2098 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2099 // If we are in the background, then check to see if this process
2100 // is bad. If so, we will just silently fail.
2101 if (mService.mAppErrors.isBadProcessLocked(info)) {
2102 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2103 + "/" + info.processName);
2104 return null;
2105 }
2106 } else {
2107 // When the user is explicitly starting a process, then clear its
2108 // crash count so that we won't make it bad until they see at
2109 // least one crash dialog again, and make the process good again
2110 // if it had been bad.
2111 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2112 + "/" + info.processName);
2113 mService.mAppErrors.resetProcessCrashTimeLocked(info);
2114 if (mService.mAppErrors.isBadProcessLocked(info)) {
2115 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2116 UserHandle.getUserId(info.uid), info.uid,
2117 info.processName);
2118 mService.mAppErrors.clearBadProcessLocked(info);
2119 if (app != null) {
2120 app.bad = false;
2121 }
2122 }
2123 }
2124 } else {
2125 // If this is an isolated process, it can't re-use an existing process.
2126 app = null;
2127 }
2128
2129 // We don't have to do anything more if:
2130 // (1) There is an existing application record; and
2131 // (2) The caller doesn't think it is dead, OR there is no thread
2132 // object attached to it so we know it couldn't have crashed; and
2133 // (3) There is a pid assigned to it, so it is either starting or
2134 // already running.
2135 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
2136 + " app=" + app + " knownToBeDead=" + knownToBeDead
2137 + " thread=" + (app != null ? app.thread : null)
2138 + " pid=" + (app != null ? app.pid : -1));
2139 if (app != null && app.pid > 0) {
2140 if ((!knownToBeDead && !app.killed) || app.thread == null) {
2141 // We already have the app running, or are waiting for it to
2142 // come up (we have a pid but not yet its thread), so keep it.
2143 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
2144 // If this is a new package in the process, add the package to the list
Dianne Hackborn6f30f182019-05-23 15:41:41 -07002145 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
Amith Yamasani98a00922018-08-21 12:50:30 -04002146 checkSlow(startTime, "startProcess: done, added package to proc");
2147 return app;
2148 }
2149
2150 // An application record is attached to a previous process,
2151 // clean it up now.
2152 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
Jing Ji03109072019-12-02 20:49:23 -08002153 // do the killing
2154 killProcAndWaitIfNecessaryLocked(app, true, app.uid == info.uid || app.isolated,
2155 "startProcess: bad proc running, killing: %s", startTime);
Amith Yamasani98a00922018-08-21 12:50:30 -04002156 }
2157
Amith Yamasani98a00922018-08-21 12:50:30 -04002158 if (app == null) {
2159 checkSlow(startTime, "startProcess: creating new process record");
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002160 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
Amith Yamasani98a00922018-08-21 12:50:30 -04002161 if (app == null) {
2162 Slog.w(TAG, "Failed making new process record for "
2163 + processName + "/" + info.uid + " isolated=" + isolated);
2164 return null;
2165 }
2166 app.crashHandler = crashHandler;
2167 app.isolatedEntryPoint = entryPoint;
2168 app.isolatedEntryPointArgs = entryPointArgs;
2169 checkSlow(startTime, "startProcess: done creating new process record");
2170 } else {
2171 // If this is a new package in the process, add the package to the list
Dianne Hackborn6f30f182019-05-23 15:41:41 -07002172 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
Amith Yamasani98a00922018-08-21 12:50:30 -04002173 checkSlow(startTime, "startProcess: added package to existing proc");
2174 }
2175
2176 // If the system is not ready yet, then hold off on starting this
2177 // process until it is.
2178 if (!mService.mProcessesReady
2179 && !mService.isAllowedWhileBooting(info)
2180 && !allowWhileBooting) {
2181 if (!mService.mProcessesOnHold.contains(app)) {
2182 mService.mProcessesOnHold.add(app);
2183 }
2184 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
2185 "System not ready, putting on hold: " + app);
2186 checkSlow(startTime, "startProcess: returning with proc on hold");
2187 return app;
2188 }
2189
2190 checkSlow(startTime, "startProcess: stepping in to startProcess");
Martijn Coenene8431c22019-03-28 14:09:38 +01002191 final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
Amith Yamasani98a00922018-08-21 12:50:30 -04002192 checkSlow(startTime, "startProcess: done starting proc!");
2193 return success ? app : null;
2194 }
2195
Jing Ji03109072019-12-02 20:49:23 -08002196 /**
Jing Ji03109072019-12-02 20:49:23 -08002197 * Kill (if asked to) and wait for the given process died if necessary
2198 * @param app - The process record to kill
2199 * @param doKill - Kill the given process record
2200 * @param wait - Wait for the death of the given process
2201 * @param formatString - The log message for slow operation
2202 * @param startTime - The start timestamp of the operation
2203 */
2204 @GuardedBy("mService")
2205 void killProcAndWaitIfNecessaryLocked(final ProcessRecord app, final boolean doKill,
2206 final boolean wait, final String formatString, final long startTime) {
2207
2208 checkSlow(startTime, String.format(formatString, "before appDied"));
2209
2210 if (doKill) {
2211 // do the killing
2212 ProcessList.killProcessGroup(app.uid, app.pid);
Jing Ji8055a3a2019-12-17 15:55:33 -08002213 noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2214 ApplicationExitInfo.SUBREASON_UNKNOWN,
2215 String.format(formatString, ""));
Jing Ji03109072019-12-02 20:49:23 -08002216 }
2217
2218 // wait for the death
2219 if (wait) {
Jing Ji9f21e892020-01-14 14:28:17 -08002220 try {
2221 Process.waitForProcessDeath(app.pid, PROC_KILL_TIMEOUT);
2222 } catch (Exception e) {
Jing Ji03109072019-12-02 20:49:23 -08002223 // Maybe the process goes into zombie, use an expensive API to check again.
2224 if (mService.isProcessAliveLocked(app)) {
2225 Slog.w(TAG, String.format(formatString,
2226 "waiting for app killing timed out"));
2227 }
2228 }
2229 }
2230
2231 checkSlow(startTime, String.format(formatString, "after appDied"));
2232 }
2233
Amith Yamasani98a00922018-08-21 12:50:30 -04002234 @GuardedBy("mService")
2235 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
2236 StringBuilder sb = null;
2237 if (app.killedByAm) {
2238 if (sb == null) sb = new StringBuilder();
2239 sb.append("killedByAm=true;");
2240 }
2241 if (mProcessNames.get(app.processName, app.uid) != app) {
2242 if (sb == null) sb = new StringBuilder();
2243 sb.append("No entry in mProcessNames;");
2244 }
2245 if (!app.pendingStart) {
2246 if (sb == null) sb = new StringBuilder();
2247 sb.append("pendingStart=false;");
2248 }
2249 if (app.startSeq > expectedStartSeq) {
2250 if (sb == null) sb = new StringBuilder();
2251 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
2252 }
2253 return sb == null ? null : sb.toString();
2254 }
2255
2256 @GuardedBy("mService")
2257 private boolean handleProcessStartedLocked(ProcessRecord pending,
2258 Process.ProcessStartResult startResult, long expectedStartSeq) {
2259 // Indicates that this process start has been taken care of.
2260 if (mPendingStarts.get(expectedStartSeq) == null) {
2261 if (pending.pid == startResult.pid) {
2262 pending.setUsingWrapper(startResult.usingWrapper);
2263 // TODO: Update already existing clients of usingWrapper
2264 }
2265 return false;
2266 }
2267 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
2268 expectedStartSeq, false);
2269 }
2270
2271 @GuardedBy("mService")
2272 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
2273 long expectedStartSeq, boolean procAttached) {
2274 mPendingStarts.remove(expectedStartSeq);
2275 final String reason = isProcStartValidLocked(app, expectedStartSeq);
2276 if (reason != null) {
2277 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
2278 pid
2279 + ", " + reason);
2280 app.pendingStart = false;
2281 killProcessQuiet(pid);
2282 Process.killProcessGroup(app.uid, app.pid);
Jing Ji8055a3a2019-12-17 15:55:33 -08002283 noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2284 ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
Amith Yamasani98a00922018-08-21 12:50:30 -04002285 return false;
2286 }
2287 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2288 checkSlow(app.startTime, "startProcess: done updating battery stats");
2289
2290 EventLog.writeEvent(EventLogTags.AM_PROC_START,
2291 UserHandle.getUserId(app.startUid), pid, app.startUid,
Martijn Coenene8431c22019-03-28 14:09:38 +01002292 app.processName, app.hostingRecord.getType(),
2293 app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
Amith Yamasani98a00922018-08-21 12:50:30 -04002294
2295 try {
2296 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
2297 app.seInfo, app.info.sourceDir, pid);
2298 } catch (RemoteException ex) {
2299 // Ignore
2300 }
2301
2302 if (app.isPersistent()) {
2303 Watchdog.getInstance().processStarted(app.processName, pid);
2304 }
2305
2306 checkSlow(app.startTime, "startProcess: building log message");
2307 StringBuilder buf = mStringBuilder;
2308 buf.setLength(0);
2309 buf.append("Start proc ");
2310 buf.append(pid);
2311 buf.append(':');
2312 buf.append(app.processName);
2313 buf.append('/');
2314 UserHandle.formatUid(buf, app.startUid);
2315 if (app.isolatedEntryPoint != null) {
2316 buf.append(" [");
2317 buf.append(app.isolatedEntryPoint);
2318 buf.append("]");
2319 }
2320 buf.append(" for ");
Martijn Coenene8431c22019-03-28 14:09:38 +01002321 buf.append(app.hostingRecord.getType());
2322 if (app.hostingRecord.getName() != null) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002323 buf.append(" ");
Martijn Coenene8431c22019-03-28 14:09:38 +01002324 buf.append(app.hostingRecord.getName());
Amith Yamasani98a00922018-08-21 12:50:30 -04002325 }
2326 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
2327 app.setPid(pid);
2328 app.setUsingWrapper(usingWrapper);
2329 app.pendingStart = false;
2330 checkSlow(app.startTime, "startProcess: starting to update pids map");
2331 ProcessRecord oldApp;
2332 synchronized (mService.mPidsSelfLocked) {
2333 oldApp = mService.mPidsSelfLocked.get(pid);
2334 }
2335 // If there is already an app occupying that pid that hasn't been cleaned up
2336 if (oldApp != null && !app.isolated) {
2337 // Clean up anything relating to this pid first
Hui Yu6dabda82019-05-07 14:02:57 -07002338 Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
2339 + " startSeq:" + app.startSeq
2340 + " pid:" + pid
2341 + " belongs to another existing app:" + oldApp.processName
2342 + " startSeq:" + oldApp.startSeq);
Amith Yamasani98a00922018-08-21 12:50:30 -04002343 mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
2344 true /*replacingPid*/);
2345 }
Dianne Hackbornf6729fa2020-01-06 13:12:36 -08002346 mService.addPidLocked(app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002347 synchronized (mService.mPidsSelfLocked) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002348 if (!procAttached) {
2349 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2350 msg.obj = app;
2351 mService.mHandler.sendMessageDelayed(msg, usingWrapper
2352 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2353 }
2354 }
2355 checkSlow(app.startTime, "startProcess: done updating pids map");
2356 return true;
2357 }
2358
2359 final void removeLruProcessLocked(ProcessRecord app) {
2360 int lrui = mLruProcesses.lastIndexOf(app);
2361 if (lrui >= 0) {
2362 if (!app.killed) {
2363 if (app.isPersistent()) {
2364 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
2365 } else {
2366 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2367 if (app.pid > 0) {
2368 killProcessQuiet(app.pid);
2369 ProcessList.killProcessGroup(app.uid, app.pid);
Jing Ji8055a3a2019-12-17 15:55:33 -08002370 noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
2371 ApplicationExitInfo.SUBREASON_UNKNOWN, "hasn't been killed");
Amith Yamasani98a00922018-08-21 12:50:30 -04002372 } else {
2373 app.pendingStart = false;
2374 }
2375 }
2376 }
Jing Jid3556f12019-08-20 16:49:08 -07002377 if (lrui < mLruProcessActivityStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002378 mLruProcessActivityStart--;
2379 }
Jing Jid3556f12019-08-20 16:49:08 -07002380 if (lrui < mLruProcessServiceStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002381 mLruProcessServiceStart--;
2382 }
2383 mLruProcesses.remove(lrui);
2384 }
2385 }
2386
Riddle Hsuaaef7312019-01-24 19:00:58 +08002387 @GuardedBy("mService")
2388 boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
2389 String reason) {
2390 return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
2391 false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
2392 false /* evenPersistent */, false /* setRemoved */, reason);
Amith Yamasani98a00922018-08-21 12:50:30 -04002393 }
2394
2395 @GuardedBy("mService")
Martijn Coenen4cc2a1c2020-01-21 14:40:21 +01002396 void killAppZygotesLocked(String packageName, int appId, int userId, boolean force) {
2397 // See if there are any app zygotes running for this packageName / UID combination,
2398 // and kill it if so.
2399 final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
2400 for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
2401 for (int i = 0; i < appZygotes.size(); ++i) {
2402 final int appZygoteUid = appZygotes.keyAt(i);
2403 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
2404 continue;
2405 }
2406 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
2407 continue;
2408 }
2409 final AppZygote appZygote = appZygotes.valueAt(i);
2410 if (packageName != null
2411 && !packageName.equals(appZygote.getAppInfo().packageName)) {
2412 continue;
2413 }
2414 zygotesToKill.add(appZygote);
2415 }
2416 }
2417 for (AppZygote appZygote : zygotesToKill) {
2418 killAppZygoteIfNeededLocked(appZygote, force);
2419 }
2420 }
2421
2422 @GuardedBy("mService")
Amith Yamasani98a00922018-08-21 12:50:30 -04002423 final boolean killPackageProcessesLocked(String packageName, int appId,
2424 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
Riddle Hsuaaef7312019-01-24 19:00:58 +08002425 boolean doit, boolean evenPersistent, boolean setRemoved, String reason) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002426 ArrayList<ProcessRecord> procs = new ArrayList<>();
2427
2428 // Remove all processes this package may have touched: all with the
2429 // same UID (except for the system or root user), and all whose name
2430 // matches the package name.
2431 final int NP = mProcessNames.getMap().size();
2432 for (int ip = 0; ip < NP; ip++) {
2433 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2434 final int NA = apps.size();
2435 for (int ia = 0; ia < NA; ia++) {
2436 ProcessRecord app = apps.valueAt(ia);
2437 if (app.isPersistent() && !evenPersistent) {
2438 // we don't kill persistent processes
2439 continue;
2440 }
2441 if (app.removed) {
2442 if (doit) {
2443 procs.add(app);
2444 }
2445 continue;
2446 }
2447
2448 // Skip process if it doesn't meet our oom adj requirement.
2449 if (app.setAdj < minOomAdj) {
Riddle Hsu4405d8a2019-03-06 22:09:32 +08002450 // Note it is still possible to have a process with oom adj 0 in the killed
2451 // processes, but it does not mean misjudgment. E.g. a bound service process
2452 // and its client activity process are both in the background, so they are
2453 // collected to be killed. If the client activity is killed first, the service
2454 // may be scheduled to unbind and become an executing service (oom adj 0).
Amith Yamasani98a00922018-08-21 12:50:30 -04002455 continue;
2456 }
2457
2458 // If no package is specified, we call all processes under the
2459 // give user id.
2460 if (packageName == null) {
2461 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2462 continue;
2463 }
2464 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
2465 continue;
2466 }
2467 // Package has been specified, we want to hit all processes
2468 // that match it. We need to qualify this by the processes
2469 // that are running under the specified app and user ID.
2470 } else {
2471 final boolean isDep = app.pkgDeps != null
2472 && app.pkgDeps.contains(packageName);
2473 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
2474 continue;
2475 }
2476 if (userId != UserHandle.USER_ALL && app.userId != userId) {
2477 continue;
2478 }
2479 if (!app.pkgList.containsKey(packageName) && !isDep) {
2480 continue;
2481 }
2482 }
2483
2484 // Process has passed all conditions, kill it!
2485 if (!doit) {
2486 return true;
2487 }
Riddle Hsuaaef7312019-01-24 19:00:58 +08002488 if (setRemoved) {
2489 app.removed = true;
2490 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002491 procs.add(app);
2492 }
2493 }
2494
2495 int N = procs.size();
2496 for (int i=0; i<N; i++) {
2497 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
2498 }
Martijn Coenen4cc2a1c2020-01-21 14:40:21 +01002499 killAppZygotesLocked(packageName, appId, userId, false /* force */);
Amith Yamasanid2775cd2019-04-12 15:47:54 -07002500 mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
Amith Yamasani98a00922018-08-21 12:50:30 -04002501 return N > 0;
2502 }
Amith Yamasanid2775cd2019-04-12 15:47:54 -07002503
Amith Yamasani98a00922018-08-21 12:50:30 -04002504 @GuardedBy("mService")
2505 boolean removeProcessLocked(ProcessRecord app,
2506 boolean callerWillRestart, boolean allowRestart, String reason) {
Jing Ji8055a3a2019-12-17 15:55:33 -08002507 return removeProcessLocked(app, callerWillRestart, allowRestart, reason,
2508 ApplicationExitInfo.REASON_OTHER);
2509 }
2510
2511 boolean removeProcessLocked(ProcessRecord app,
2512 boolean callerWillRestart, boolean allowRestart, String reason, int reasonCode) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002513 final String name = app.processName;
2514 final int uid = app.uid;
2515 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
2516 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
2517
2518 ProcessRecord old = mProcessNames.get(name, uid);
2519 if (old != app) {
2520 // This process is no longer active, so nothing to do.
2521 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
2522 return false;
2523 }
2524 removeProcessNameLocked(name, uid);
2525 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
2526
2527 boolean needRestart = false;
2528 if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
2529 .pendingStart)) {
2530 int pid = app.pid;
2531 if (pid > 0) {
Dianne Hackbornf6729fa2020-01-06 13:12:36 -08002532 mService.removePidLocked(app);
Wale Ogunwale0b940842018-12-03 06:58:11 -08002533 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
Amith Yamasani98a00922018-08-21 12:50:30 -04002534 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2535 if (app.isolated) {
2536 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2537 mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
2538 }
2539 }
2540 boolean willRestart = false;
2541 if (app.isPersistent() && !app.isolated) {
2542 if (!callerWillRestart) {
2543 willRestart = true;
2544 } else {
2545 needRestart = true;
2546 }
2547 }
Jing Ji8055a3a2019-12-17 15:55:33 -08002548 app.kill(reason, reasonCode, true);
Amith Yamasani98a00922018-08-21 12:50:30 -04002549 mService.handleAppDiedLocked(app, willRestart, allowRestart);
2550 if (willRestart) {
2551 removeLruProcessLocked(app);
2552 mService.addAppLocked(app.info, null, false, null /* ABI override */);
2553 }
2554 } else {
2555 mRemovedProcesses.add(app);
2556 }
2557
2558 return needRestart;
2559 }
2560
2561 @GuardedBy("mService")
2562 final void addProcessNameLocked(ProcessRecord proc) {
2563 // We shouldn't already have a process under this name, but just in case we
2564 // need to clean up whatever may be there now.
2565 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
2566 if (old == proc && proc.isPersistent()) {
2567 // We are re-adding a persistent process. Whatevs! Just leave it there.
2568 Slog.w(TAG, "Re-adding persistent process " + proc);
2569 } else if (old != null) {
2570 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
2571 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08002572 UidRecord uidRec = mActiveUids.get(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002573 if (uidRec == null) {
Riddle Hsud7088f82019-01-30 13:04:50 +08002574 uidRec = new UidRecord(proc.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002575 // This is the first appearance of the uid, report it now!
2576 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2577 "Creating new process uid: " + uidRec);
2578 if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
2579 UserHandle.getAppId(proc.uid)) >= 0
2580 || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
2581 uidRec.setWhitelist = uidRec.curWhitelist = true;
2582 }
2583 uidRec.updateHasInternetPermission();
Amith Yamasaniaa746442019-01-10 10:09:12 -08002584 mActiveUids.put(proc.uid, uidRec);
Amith Yamasani98a00922018-08-21 12:50:30 -04002585 EventLogTags.writeAmUidRunning(uidRec.uid);
Hui Yu26969322019-08-21 14:56:35 -07002586 mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState(),
2587 uidRec.curCapability);
Amith Yamasani98a00922018-08-21 12:50:30 -04002588 }
2589 proc.uidRecord = uidRec;
2590
2591 // Reset render thread tid if it was already set, so new process can set it again.
2592 proc.renderThreadTid = 0;
2593 uidRec.numProcs++;
2594 mProcessNames.put(proc.processName, proc.uid, proc);
2595 if (proc.isolated) {
2596 mIsolatedProcesses.put(proc.uid, proc);
2597 }
2598 }
2599
2600 @GuardedBy("mService")
Martijn Coenen01e719b2018-12-05 16:01:38 +01002601 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002602 HostingRecord hostingRecord) {
2603 if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
Martijn Coenen01e719b2018-12-05 16:01:38 +01002604 // Allocate an isolated UID from the global range
2605 return mGlobalIsolatedUids;
2606 } else {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002607 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
2608 info.processName, hostingRecord.getDefiningUid());
Martijn Coenen01e719b2018-12-05 16:01:38 +01002609 }
2610 }
2611
2612 @GuardedBy("mService")
Amith Yamasani98a00922018-08-21 12:50:30 -04002613 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002614 boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002615 String proc = customProcess != null ? customProcess : info.processName;
2616 final int userId = UserHandle.getUserId(info.uid);
2617 int uid = info.uid;
2618 if (isolated) {
2619 if (isolatedUid == 0) {
Martijn Coenen572ed7f2019-03-28 19:50:44 +01002620 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
Martijn Coenen01e719b2018-12-05 16:01:38 +01002621 if (uidRange == null) {
2622 return null;
2623 }
2624 uid = uidRange.allocateIsolatedUidLocked(userId);
2625 if (uid == -1) {
2626 return null;
Amith Yamasani98a00922018-08-21 12:50:30 -04002627 }
2628 } else {
2629 // Special case for startIsolatedProcess (internal only), where
2630 // the uid of the isolated process is specified by the caller.
2631 uid = isolatedUid;
2632 }
Jing Ji8055a3a2019-12-17 15:55:33 -08002633 mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002634 mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
2635
2636 // Register the isolated UID with this application so BatteryStats knows to
2637 // attribute resource usage to the application.
2638 //
2639 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
2640 // about the process state of the isolated UID *before* it is registered with the
2641 // owning application.
2642 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
2643 StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
2644 StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
2645 }
Wale Ogunwale387b34c2018-10-25 19:59:40 -07002646 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
Amith Yamasani98a00922018-08-21 12:50:30 -04002647
2648 if (!mService.mBooted && !mService.mBooting
2649 && userId == UserHandle.USER_SYSTEM
2650 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
2651 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
2652 r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
2653 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
2654 r.setPersistent(true);
2655 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
2656 }
2657 if (isolated && isolatedUid != 0) {
2658 // Special case for startIsolatedProcess (internal only) - assume the process
2659 // is required by the system server to prevent it being killed.
2660 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
2661 }
2662 addProcessNameLocked(r);
2663 return r;
2664 }
2665
2666 @GuardedBy("mService")
2667 final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
2668 return removeProcessNameLocked(name, uid, null);
2669 }
2670
2671 @GuardedBy("mService")
2672 final ProcessRecord removeProcessNameLocked(final String name, final int uid,
2673 final ProcessRecord expecting) {
2674 ProcessRecord old = mProcessNames.get(name, uid);
2675 // Only actually remove when the currently recorded value matches the
2676 // record that we expected; if it doesn't match then we raced with a
2677 // newly created process and we don't want to destroy the new one.
2678 if ((expecting == null) || (old == expecting)) {
2679 mProcessNames.remove(name, uid);
2680 }
2681 if (old != null && old.uidRecord != null) {
2682 old.uidRecord.numProcs--;
2683 if (old.uidRecord.numProcs == 0) {
2684 // No more processes using this uid, tell clients it is gone.
2685 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
2686 "No more processes in " + old.uidRecord);
2687 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
2688 EventLogTags.writeAmUidStopped(uid);
Amith Yamasaniaa746442019-01-10 10:09:12 -08002689 mActiveUids.remove(uid);
Hui Yu26969322019-08-21 14:56:35 -07002690 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
2691 ActivityManager.PROCESS_CAPABILITY_NONE);
Amith Yamasani98a00922018-08-21 12:50:30 -04002692 }
2693 old.uidRecord = null;
2694 }
2695 mIsolatedProcesses.remove(uid);
Martijn Coenen01e719b2018-12-05 16:01:38 +01002696 mGlobalIsolatedUids.freeIsolatedUidLocked(uid);
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002697 // Remove the (expected) ProcessRecord from the app zygote
2698 final ProcessRecord record = expecting != null ? expecting : old;
Martijn Coenen01e719b2018-12-05 16:01:38 +01002699 if (record != null && record.appZygote) {
Martijn Coenen7e6fa672018-11-05 11:45:26 +01002700 removeProcessFromAppZygoteLocked(record);
2701 }
2702
Amith Yamasani98a00922018-08-21 12:50:30 -04002703 return old;
2704 }
2705
2706 /** Call setCoreSettings on all LRU processes, with the new settings. */
2707 @GuardedBy("mService")
2708 void updateCoreSettingsLocked(Bundle settings) {
2709 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2710 ProcessRecord processRecord = mLruProcesses.get(i);
2711 try {
2712 if (processRecord.thread != null) {
2713 processRecord.thread.setCoreSettings(settings);
2714 }
2715 } catch (RemoteException re) {
2716 /* ignore */
2717 }
2718 }
2719 }
2720
2721 /**
2722 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
2723 * procstate lower than maxProcState.
2724 * @param minTargetSdk
2725 * @param maxProcState
2726 */
2727 @GuardedBy("mService")
2728 void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
2729 final ArrayList<ProcessRecord> procs = new ArrayList<>();
2730 final int NP = mProcessNames.getMap().size();
2731 for (int ip = 0; ip < NP; ip++) {
2732 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2733 final int NA = apps.size();
2734 for (int ia = 0; ia < NA; ia++) {
2735 final ProcessRecord app = apps.valueAt(ia);
Riddle Hsuaaef7312019-01-24 19:00:58 +08002736 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
2737 && (maxProcState < 0 || app.setProcState > maxProcState))) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002738 procs.add(app);
2739 }
2740 }
2741 }
2742
2743 final int N = procs.size();
2744 for (int i = 0; i < N; i++) {
2745 removeProcessLocked(procs.get(i), false, true, "kill all background except");
2746 }
2747 }
2748
2749 /**
2750 * Call updateTimePrefs on all LRU processes
2751 * @param timePref The time pref to pass to each process
2752 */
2753 @GuardedBy("mService")
2754 void updateAllTimePrefsLocked(int timePref) {
2755 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2756 ProcessRecord r = mLruProcesses.get(i);
2757 if (r.thread != null) {
2758 try {
2759 r.thread.updateTimePrefs(timePref);
2760 } catch (RemoteException ex) {
2761 Slog.w(TAG, "Failed to update preferences for: "
2762 + r.info.processName);
2763 }
2764 }
2765 }
2766 }
2767
Irina Dumitrescu34a27c42019-04-15 19:20:38 +01002768 void setAllHttpProxy() {
2769 // Update the HTTP proxy for each application thread.
2770 synchronized (mService) {
2771 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2772 ProcessRecord r = mLruProcesses.get(i);
2773 // Don't dispatch to isolated processes as they can't access ConnectivityManager and
2774 // don't have network privileges anyway. Exclude system server and update it
2775 // separately outside the AMS lock, to avoid deadlock with Connectivity Service.
2776 if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) {
2777 try {
2778 r.thread.updateHttpProxy();
2779 } catch (RemoteException ex) {
2780 Slog.w(TAG, "Failed to update http proxy for: "
2781 + r.info.processName);
2782 }
Amith Yamasani98a00922018-08-21 12:50:30 -04002783 }
2784 }
2785 }
Irina Dumitrescu34a27c42019-04-15 19:20:38 +01002786 ActivityThread.updateHttpProxy(mService.mContext);
Amith Yamasani98a00922018-08-21 12:50:30 -04002787 }
2788
2789 @GuardedBy("mService")
2790 void clearAllDnsCacheLocked() {
2791 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2792 ProcessRecord r = mLruProcesses.get(i);
2793 if (r.thread != null) {
2794 try {
2795 r.thread.clearDnsCache();
2796 } catch (RemoteException ex) {
2797 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2798 }
2799 }
2800 }
2801 }
2802
2803 @GuardedBy("mService")
2804 void handleAllTrustStorageUpdateLocked() {
2805 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2806 ProcessRecord r = mLruProcesses.get(i);
2807 if (r.thread != null) {
2808 try {
2809 r.thread.handleTrustStorageUpdate();
2810 } catch (RemoteException ex) {
2811 Slog.w(TAG, "Failed to handle trust storage update for: " +
2812 r.info.processName);
2813 }
2814 }
2815 }
2816 }
2817
2818 @GuardedBy("mService")
2819 int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
Dianne Hackborna631d562018-11-20 15:58:15 -08002820 int lruSeq, String what, Object obj, ProcessRecord srcApp) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002821 app.lastActivityTime = now;
2822
2823 if (app.hasActivitiesOrRecentTasks()) {
2824 // Don't want to touch dependent processes that are hosting activities.
2825 return index;
2826 }
2827
2828 int lrui = mLruProcesses.lastIndexOf(app);
2829 if (lrui < 0) {
2830 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2831 + what + " " + obj + " from " + srcApp);
2832 return index;
2833 }
2834
2835 if (lrui >= index) {
2836 // Don't want to cause this to move dependent processes *back* in the
2837 // list as if they were less frequently used.
2838 return index;
2839 }
2840
Dianne Hackborna631d562018-11-20 15:58:15 -08002841 if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) {
Amith Yamasani98a00922018-08-21 12:50:30 -04002842 // Don't want to touch dependent processes that are hosting activities.
2843 return index;
2844 }
2845
2846 mLruProcesses.remove(lrui);
2847 if (index > 0) {
2848 index--;
2849 }
2850 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2851 + " in LRU list: " + app);
2852 mLruProcesses.add(index, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08002853 app.lruSeq = lruSeq;
Amith Yamasani98a00922018-08-21 12:50:30 -04002854 return index;
2855 }
2856
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002857 /**
2858 * Handle the case where we are inserting a process hosting client activities:
2859 * Make sure any groups have their order match their importance, and take care of
2860 * distributing old clients across other activity processes so they can't spam
2861 * the LRU list. Processing of the list will be restricted by the indices provided,
2862 * and not extend out of them.
2863 *
2864 * @param topApp The app at the top that has just been inserted in to the list.
2865 * @param topI The position in the list where topApp was inserted; this is the start (at the
2866 * top) where we are going to do our processing.
2867 * @param bottomI The last position at which we will be processing; this is the end position
2868 * of whichever section of the LRU list we are in. Nothing past it will be
2869 * touched.
2870 * @param endIndex The current end of the top being processed. Typically topI - 1. That is,
2871 * where we are going to start potentially adjusting other entries in the list.
2872 */
2873 private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI,
2874 final int bottomI, int endIndex) {
2875 if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity
2876 || !topApp.hasClientActivities()) {
2877 // If this is not a special process that has client activities, then there is
2878 // nothing to do.
2879 return;
2880 }
2881
2882 final int uid = topApp.info.uid;
2883 if (topApp.connectionGroup > 0) {
2884 int endImportance = topApp.connectionImportance;
2885 for (int i = endIndex; i >= bottomI; i--) {
2886 final ProcessRecord subProc = mLruProcesses.get(i);
2887 if (subProc.info.uid == uid
2888 && subProc.connectionGroup == topApp.connectionGroup) {
2889 if (i == endIndex && subProc.connectionImportance >= endImportance) {
2890 // This process is already in the group, and its importance
2891 // is not as strong as the process before it, so keep it
2892 // correctly positioned in the group.
2893 if (DEBUG_LRU) Slog.d(TAG_LRU,
2894 "Keeping in-place above " + subProc
2895 + " endImportance=" + endImportance
2896 + " group=" + subProc.connectionGroup
2897 + " importance=" + subProc.connectionImportance);
2898 endIndex--;
2899 endImportance = subProc.connectionImportance;
2900 } else {
2901 // We want to pull this up to be with the rest of the group,
2902 // and order within the group by importance.
2903 if (DEBUG_LRU) Slog.d(TAG_LRU,
2904 "Pulling up " + subProc
2905 + " to position in group with importance="
2906 + subProc.connectionImportance);
2907 boolean moved = false;
2908 for (int pos = topI; pos > endIndex; pos--) {
2909 final ProcessRecord posProc = mLruProcesses.get(pos);
2910 if (subProc.connectionImportance
2911 <= posProc.connectionImportance) {
2912 mLruProcesses.remove(i);
2913 mLruProcesses.add(pos, subProc);
2914 if (DEBUG_LRU) Slog.d(TAG_LRU,
2915 "Moving " + subProc
2916 + " from position " + i + " to above " + posProc
2917 + " @ " + pos);
2918 moved = true;
2919 endIndex--;
2920 break;
2921 }
2922 }
2923 if (!moved) {
2924 // Goes to the end of the group.
2925 mLruProcesses.remove(i);
Jing Jid3556f12019-08-20 16:49:08 -07002926 mLruProcesses.add(endIndex, subProc);
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08002927 if (DEBUG_LRU) Slog.d(TAG_LRU,
2928 "Moving " + subProc
2929 + " from position " + i + " to end of group @ "
2930 + endIndex);
2931 endIndex--;
2932 endImportance = subProc.connectionImportance;
2933 }
2934 }
2935 }
2936 }
2937
2938 }
2939 // To keep it from spamming the LRU list (by making a bunch of clients),
2940 // we will distribute other entries owned by it to be in-between other apps.
2941 int i = endIndex;
2942 while (i >= bottomI) {
2943 ProcessRecord subProc = mLruProcesses.get(i);
2944 if (DEBUG_LRU) Slog.d(TAG_LRU,
2945 "Looking to spread old procs, at " + subProc + " @ " + i);
2946 if (subProc.info.uid != uid) {
2947 // This is a different app... if we have gone through some of the
2948 // target app, pull this up to be before them. We want to pull up
2949 // one activity process, but any number of non-activity processes.
2950 if (i < endIndex) {
2951 boolean hasActivity = false;
2952 int connUid = 0;
2953 int connGroup = 0;
2954 while (i >= bottomI) {
2955 mLruProcesses.remove(i);
2956 mLruProcesses.add(endIndex, subProc);
2957 if (DEBUG_LRU) Slog.d(TAG_LRU,
2958 "Different app, moving to " + endIndex);
2959 i--;
2960 if (i < bottomI) {
2961 break;
2962 }
2963 subProc = mLruProcesses.get(i);
2964 if (DEBUG_LRU) Slog.d(TAG_LRU,
2965 "Looking at next app at " + i + ": " + subProc);
2966 if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) {
2967 if (DEBUG_LRU) Slog.d(TAG_LRU,
2968 "This is hosting an activity!");
2969 if (hasActivity) {
2970 // Already found an activity, done.
2971 if (DEBUG_LRU) Slog.d(TAG_LRU,
2972 "Already found an activity, done");
2973 break;
2974 }
2975 hasActivity = true;
2976 } else if (subProc.hasClientActivities()) {
2977 if (DEBUG_LRU) Slog.d(TAG_LRU,
2978 "This is a client of an activity");
2979 if (hasActivity) {
2980 if (connUid == 0 || connUid != subProc.info.uid) {
2981 // Already have an activity that is not from from a client
2982 // connection or is a different client connection, done.
2983 if (DEBUG_LRU) Slog.d(TAG_LRU,
2984 "Already found a different activity: connUid="
2985 + connUid + " uid=" + subProc.info.uid);
2986 break;
2987 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) {
2988 // Previously saw a different group or not from a group,
2989 // want to treat these as different things.
2990 if (DEBUG_LRU) Slog.d(TAG_LRU,
2991 "Already found a different group: connGroup="
2992 + connGroup + " group=" + subProc.connectionGroup);
2993 break;
2994 }
2995 } else {
2996 if (DEBUG_LRU) Slog.d(TAG_LRU,
2997 "This is an activity client! uid="
2998 + subProc.info.uid + " group=" + subProc.connectionGroup);
2999 hasActivity = true;
3000 connUid = subProc.info.uid;
3001 connGroup = subProc.connectionGroup;
3002 }
3003 }
3004 endIndex--;
3005 }
3006 }
3007 // Find the end of the next group of processes for target app. This
3008 // is after any entries of different apps (so we don't change the existing
3009 // relative order of apps) and then after the next last group of processes
3010 // of the target app.
3011 for (endIndex--; endIndex >= bottomI; endIndex--) {
3012 final ProcessRecord endProc = mLruProcesses.get(endIndex);
3013 if (endProc.info.uid == uid) {
3014 if (DEBUG_LRU) Slog.d(TAG_LRU,
3015 "Found next group of app: " + endProc + " @ "
3016 + endIndex);
3017 break;
3018 }
3019 }
3020 if (endIndex >= bottomI) {
3021 final ProcessRecord endProc = mLruProcesses.get(endIndex);
3022 for (endIndex--; endIndex >= bottomI; endIndex--) {
3023 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex);
3024 if (nextEndProc.info.uid != uid
3025 || nextEndProc.connectionGroup != endProc.connectionGroup) {
3026 if (DEBUG_LRU) Slog.d(TAG_LRU,
3027 "Found next group or app: " + nextEndProc + " @ "
3028 + endIndex + " group=" + nextEndProc.connectionGroup);
3029 break;
3030 }
3031 }
3032 }
3033 if (DEBUG_LRU) Slog.d(TAG_LRU,
3034 "Bumping scan position to " + endIndex);
3035 i = endIndex;
3036 } else {
3037 i--;
3038 }
3039 }
3040 }
3041
Amith Yamasani98a00922018-08-21 12:50:30 -04003042 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3043 ProcessRecord client) {
3044 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
3045 || app.treatLikeActivity;
3046 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3047 if (!activityChange && hasActivity) {
3048 // The process has activities, so we are only allowing activity-based adjustments
3049 // to move it. It should be kept in the front of the list with other
3050 // processes that have activities, and we don't want those to change their
3051 // order except due to activity operations.
3052 return;
3053 }
3054
3055 mLruSeq++;
3056 final long now = SystemClock.uptimeMillis();
3057 app.lastActivityTime = now;
3058
3059 // First a quick reject: if the app is already at the position we will
3060 // put it, then there is nothing to do.
3061 if (hasActivity) {
3062 final int N = mLruProcesses.size();
3063 if (N > 0 && mLruProcesses.get(N - 1) == app) {
3064 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3065 return;
3066 }
3067 } else {
3068 if (mLruProcessServiceStart > 0
3069 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3070 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3071 return;
3072 }
3073 }
3074
3075 int lrui = mLruProcesses.lastIndexOf(app);
3076
3077 if (app.isPersistent() && lrui >= 0) {
3078 // We don't care about the position of persistent processes, as long as
3079 // they are in the list.
3080 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3081 return;
3082 }
3083
3084 /* In progress: compute new position first, so we can avoid doing work
3085 if the process is not actually going to move. Not yet working.
3086 int addIndex;
3087 int nextIndex;
3088 boolean inActivity = false, inService = false;
3089 if (hasActivity) {
3090 // Process has activities, put it at the very tipsy-top.
3091 addIndex = mLruProcesses.size();
3092 nextIndex = mLruProcessServiceStart;
3093 inActivity = true;
3094 } else if (hasService) {
3095 // Process has services, put it at the top of the service list.
3096 addIndex = mLruProcessActivityStart;
3097 nextIndex = mLruProcessServiceStart;
3098 inActivity = true;
3099 inService = true;
3100 } else {
3101 // Process not otherwise of interest, it goes to the top of the non-service area.
3102 addIndex = mLruProcessServiceStart;
3103 if (client != null) {
3104 int clientIndex = mLruProcesses.lastIndexOf(client);
3105 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3106 + app);
3107 if (clientIndex >= 0 && addIndex > clientIndex) {
3108 addIndex = clientIndex;
3109 }
3110 }
3111 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3112 }
3113
3114 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3115 + mLruProcessActivityStart + "): " + app);
3116 */
3117
3118 if (lrui >= 0) {
3119 if (lrui < mLruProcessActivityStart) {
3120 mLruProcessActivityStart--;
3121 }
3122 if (lrui < mLruProcessServiceStart) {
3123 mLruProcessServiceStart--;
3124 }
3125 /*
3126 if (addIndex > lrui) {
3127 addIndex--;
3128 }
3129 if (nextIndex > lrui) {
3130 nextIndex--;
3131 }
3132 */
3133 mLruProcesses.remove(lrui);
3134 }
3135
3136 /*
3137 mLruProcesses.add(addIndex, app);
3138 if (inActivity) {
3139 mLruProcessActivityStart++;
3140 }
3141 if (inService) {
3142 mLruProcessActivityStart++;
3143 }
3144 */
3145
3146 int nextIndex;
Dianne Hackborna631d562018-11-20 15:58:15 -08003147 int nextActivityIndex = -1;
Amith Yamasani98a00922018-08-21 12:50:30 -04003148 if (hasActivity) {
3149 final int N = mLruProcesses.size();
Dianne Hackborna631d562018-11-20 15:58:15 -08003150 nextIndex = mLruProcessServiceStart;
3151 if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity
Amith Yamasani98a00922018-08-21 12:50:30 -04003152 && mLruProcessActivityStart < (N - 1)) {
3153 // Process doesn't have activities, but has clients with
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08003154 // activities... move it up, but below the app that is binding to it.
Amith Yamasani98a00922018-08-21 12:50:30 -04003155 if (DEBUG_LRU) Slog.d(TAG_LRU,
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08003156 "Adding to second-top of LRU activity list: " + app
3157 + " group=" + app.connectionGroup
3158 + " importance=" + app.connectionImportance);
3159 int pos = N - 1;
3160 while (pos > mLruProcessActivityStart) {
3161 final ProcessRecord posproc = mLruProcesses.get(pos);
3162 if (posproc.info.uid == app.info.uid) {
3163 // Technically this app could have multiple processes with different
3164 // activities and so we should be looking for the actual process that
3165 // is bound to the target proc... but I don't really care, do you?
3166 break;
3167 }
3168 pos--;
3169 }
3170 mLruProcesses.add(pos, app);
Dianne Hackborna631d562018-11-20 15:58:15 -08003171 // If this process is part of a group, need to pull up any other processes
3172 // in that group to be with it.
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08003173 int endIndex = pos - 1;
3174 if (endIndex < mLruProcessActivityStart) {
3175 endIndex = mLruProcessActivityStart;
Dianne Hackborna631d562018-11-20 15:58:15 -08003176 }
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08003177 nextActivityIndex = endIndex;
3178 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex);
Amith Yamasani98a00922018-08-21 12:50:30 -04003179 } else {
3180 // Process has activities, put it at the very tipsy-top.
3181 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3182 mLruProcesses.add(app);
Dianne Hackborna631d562018-11-20 15:58:15 -08003183 nextActivityIndex = mLruProcesses.size() - 1;
Amith Yamasani98a00922018-08-21 12:50:30 -04003184 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003185 } else if (hasService) {
3186 // Process has services, put it at the top of the service list.
3187 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3188 mLruProcesses.add(mLruProcessActivityStart, app);
3189 nextIndex = mLruProcessServiceStart;
3190 mLruProcessActivityStart++;
3191 } else {
3192 // Process not otherwise of interest, it goes to the top of the non-service area.
3193 int index = mLruProcessServiceStart;
3194 if (client != null) {
3195 // If there is a client, don't allow the process to be moved up higher
3196 // in the list than that client.
3197 int clientIndex = mLruProcesses.lastIndexOf(client);
3198 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3199 + " when updating " + app);
3200 if (clientIndex <= lrui) {
3201 // Don't allow the client index restriction to push it down farther in the
3202 // list than it already is.
3203 clientIndex = lrui;
3204 }
3205 if (clientIndex >= 0 && index > clientIndex) {
3206 index = clientIndex;
3207 }
3208 }
3209 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3210 mLruProcesses.add(index, app);
3211 nextIndex = index - 1;
3212 mLruProcessActivityStart++;
3213 mLruProcessServiceStart++;
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08003214 if (index > 1) {
3215 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1);
3216 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003217 }
3218
Dianne Hackborna631d562018-11-20 15:58:15 -08003219 app.lruSeq = mLruSeq;
3220
Amith Yamasani98a00922018-08-21 12:50:30 -04003221 // If the app is currently using a content provider or service,
3222 // bump those processes as well.
3223 for (int j = app.connections.size() - 1; j >= 0; j--) {
3224 ConnectionRecord cr = app.connections.valueAt(j);
3225 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3226 && cr.binding.service.app != null
3227 && cr.binding.service.app.lruSeq != mLruSeq
Dianne Hackborna631d562018-11-20 15:58:15 -08003228 && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0
Amith Yamasani98a00922018-08-21 12:50:30 -04003229 && !cr.binding.service.app.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08003230 if (cr.binding.service.app.hasClientActivities()) {
3231 if (nextActivityIndex >= 0) {
3232 nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app,
3233 now,
3234 nextActivityIndex, mLruSeq,
3235 "service connection", cr, app);
3236 }
3237 } else {
3238 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
3239 now,
3240 nextIndex, mLruSeq,
3241 "service connection", cr, app);
3242 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003243 }
3244 }
3245 for (int j = app.conProviders.size() - 1; j >= 0; j--) {
3246 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3247 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
Dianne Hackborna631d562018-11-20 15:58:15 -08003248 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq,
Amith Yamasani98a00922018-08-21 12:50:30 -04003249 "provider reference", cpr, app);
3250 }
3251 }
3252 }
3253
3254 final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
3255 final IBinder threadBinder = thread.asBinder();
3256 // Find the application record.
3257 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3258 final ProcessRecord rec = mLruProcesses.get(i);
3259 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3260 return rec;
3261 }
3262 }
3263 return null;
3264 }
3265
3266 boolean haveBackgroundProcessLocked() {
3267 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3268 final ProcessRecord rec = mLruProcesses.get(i);
3269 if (rec.thread != null
3270 && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
3271 return true;
3272 }
3273 }
3274 return false;
3275 }
3276
3277 private static int procStateToImportance(int procState, int memAdj,
3278 ActivityManager.RunningAppProcessInfo currApp,
3279 int clientTargetSdk) {
3280 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
3281 procState, clientTargetSdk);
3282 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
3283 currApp.lru = memAdj;
3284 } else {
3285 currApp.lru = 0;
3286 }
3287 return imp;
3288 }
3289
3290 @GuardedBy("mService")
3291 void fillInProcMemInfoLocked(ProcessRecord app,
3292 ActivityManager.RunningAppProcessInfo outInfo,
3293 int clientTargetSdk) {
3294 outInfo.pid = app.pid;
3295 outInfo.uid = app.info.uid;
3296 if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
3297 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
3298 }
3299 if (app.isPersistent()) {
3300 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
3301 }
3302 if (app.hasActivities()) {
3303 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
3304 }
3305 outInfo.lastTrimLevel = app.trimMemoryLevel;
3306 int adj = app.curAdj;
3307 int procState = app.getCurProcState();
3308 outInfo.importance = procStateToImportance(procState, adj, outInfo,
3309 clientTargetSdk);
3310 outInfo.importanceReasonCode = app.adjTypeCode;
3311 outInfo.processState = app.getCurProcState();
3312 outInfo.isFocused = (app == mService.getTopAppLocked());
3313 outInfo.lastActivityTime = app.lastActivityTime;
3314 }
3315
3316 @GuardedBy("mService")
3317 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
3318 int userId, boolean allUids, int callingUid, int clientTargetSdk) {
3319 // Lazy instantiation of list
3320 List<ActivityManager.RunningAppProcessInfo> runList = null;
3321
3322 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3323 ProcessRecord app = mLruProcesses.get(i);
3324 if ((!allUsers && app.userId != userId)
3325 || (!allUids && app.uid != callingUid)) {
3326 continue;
3327 }
3328 if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
3329 // Generate process state info for running application
3330 ActivityManager.RunningAppProcessInfo currApp =
3331 new ActivityManager.RunningAppProcessInfo(app.processName,
3332 app.pid, app.getPackageList());
3333 fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
3334 if (app.adjSource instanceof ProcessRecord) {
3335 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
3336 currApp.importanceReasonImportance =
3337 ActivityManager.RunningAppProcessInfo.procStateToImportance(
3338 app.adjSourceProcState);
Wale Ogunwale59507092018-10-29 09:00:30 -07003339 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) {
3340 final ActivityServiceConnectionsHolder r =
3341 (ActivityServiceConnectionsHolder) app.adjSource;
3342 final int pid = r.getActivityPid();
3343 if (pid != -1) {
3344 currApp.importanceReasonPid = pid;
3345 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003346 }
3347 if (app.adjTarget instanceof ComponentName) {
3348 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
3349 }
3350 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
3351 // + " lru=" + currApp.lru);
3352 if (runList == null) {
3353 runList = new ArrayList<>();
3354 }
3355 runList.add(currApp);
3356 }
3357 }
3358 return runList;
3359 }
3360
3361 @GuardedBy("mService")
3362 int getLruSizeLocked() {
3363 return mLruProcesses.size();
3364 }
3365
3366 @GuardedBy("mService")
3367 void dumpLruListHeaderLocked(PrintWriter pw) {
3368 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
3369 pw.print(" total, non-act at ");
3370 pw.print(mLruProcesses.size() - mLruProcessActivityStart);
3371 pw.print(", non-svc at ");
3372 pw.print(mLruProcesses.size() - mLruProcessServiceStart);
3373 pw.println("):");
3374 }
3375
3376 @GuardedBy("mService")
3377 ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
3378 ArrayList<ProcessRecord> procs;
3379 if (args != null && args.length > start
3380 && args[start].charAt(0) != '-') {
3381 procs = new ArrayList<ProcessRecord>();
3382 int pid = -1;
3383 try {
3384 pid = Integer.parseInt(args[start]);
3385 } catch (NumberFormatException e) {
3386 }
3387 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3388 ProcessRecord proc = mLruProcesses.get(i);
3389 if (proc.pid > 0 && proc.pid == pid) {
3390 procs.add(proc);
3391 } else if (allPkgs && proc.pkgList != null
3392 && proc.pkgList.containsKey(args[start])) {
3393 procs.add(proc);
3394 } else if (proc.processName.equals(args[start])) {
3395 procs.add(proc);
3396 }
3397 }
3398 if (procs.size() <= 0) {
3399 return null;
3400 }
3401 } else {
3402 procs = new ArrayList<ProcessRecord>(mLruProcesses);
3403 }
3404 return procs;
3405 }
3406
3407 @GuardedBy("mService")
3408 void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
3409 boolean updateFrameworkRes) {
3410 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3411 final ProcessRecord app = mLruProcesses.get(i);
3412 if (app.thread == null) {
3413 continue;
3414 }
3415
3416 if (userId != UserHandle.USER_ALL && app.userId != userId) {
3417 continue;
3418 }
3419
3420 final int packageCount = app.pkgList.size();
3421 for (int j = 0; j < packageCount; j++) {
3422 final String packageName = app.pkgList.keyAt(j);
3423 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
3424 try {
3425 final ApplicationInfo ai = AppGlobals.getPackageManager()
3426 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
3427 if (ai != null) {
3428 app.thread.scheduleApplicationInfoChanged(ai);
3429 }
3430 } catch (RemoteException e) {
3431 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
3432 packageName, app));
3433 }
3434 }
3435 }
3436 }
3437 }
3438
3439 @GuardedBy("mService")
3440 void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
Winson23863be2019-04-04 17:41:28 -07003441 boolean foundProcess = false;
Amith Yamasani98a00922018-08-21 12:50:30 -04003442 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3443 ProcessRecord r = mLruProcesses.get(i);
3444 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
3445 try {
Winson23863be2019-04-04 17:41:28 -07003446 for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) {
3447 if (packages[index].equals(r.info.packageName)) {
3448 foundProcess = true;
3449 }
3450 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003451 r.thread.dispatchPackageBroadcast(cmd, packages);
3452 } catch (RemoteException ex) {
3453 }
3454 }
3455 }
Winson23863be2019-04-04 17:41:28 -07003456
3457 if (!foundProcess) {
3458 try {
3459 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages);
3460 } catch (RemoteException ignored) {
3461 }
3462 }
Amith Yamasani98a00922018-08-21 12:50:30 -04003463 }
Amith Yamasaniaa746442019-01-10 10:09:12 -08003464
3465 /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */
3466 @GuardedBy("mService")
3467 int getUidProcStateLocked(int uid) {
3468 UidRecord uidRec = mActiveUids.get(uid);
3469 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
3470 }
3471
3472 /** Returns the UidRecord for the given uid, if it exists. */
3473 @GuardedBy("mService")
3474 UidRecord getUidRecordLocked(int uid) {
3475 return mActiveUids.get(uid);
3476 }
3477
3478 /**
3479 * Call {@link ActivityManagerService#doStopUidLocked}
3480 * (which will also stop background services) for all idle UIDs.
3481 */
3482 @GuardedBy("mService")
3483 void doStopUidForIdleUidsLocked() {
3484 final int size = mActiveUids.size();
3485 for (int i = 0; i < size; i++) {
3486 final int uid = mActiveUids.keyAt(i);
3487 if (UserHandle.isCore(uid)) {
3488 continue;
3489 }
3490 final UidRecord uidRec = mActiveUids.valueAt(i);
3491 if (!uidRec.idle) {
3492 continue;
3493 }
3494 mService.doStopUidLocked(uidRec.uid, uidRec);
3495 }
3496 }
Jing Ji094c3ef2019-08-27 17:02:09 -07003497
3498 /**
3499 * Checks if the uid is coming from background to foreground or vice versa and returns
3500 * appropriate block state based on this.
3501 *
3502 * @return blockState based on whether the uid is coming from background to foreground or
3503 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
3504 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
3505 * {@link #NETWORK_STATE_NO_CHANGE}.
3506 */
3507 @VisibleForTesting
3508 int getBlockStateForUid(UidRecord uidRec) {
3509 // Denotes whether uid's process state is currently allowed network access.
3510 final boolean isAllowed =
3511 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState())
3512 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState());
3513 // Denotes whether uid's process state was previously allowed network access.
3514 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
3515 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
3516
3517 // When the uid is coming to foreground, AMS should inform the app thread that it should
3518 // block for the network rules to get updated before launching an activity.
3519 if (!wasAllowed && isAllowed) {
3520 return NETWORK_STATE_BLOCK;
3521 }
3522 // When the uid is going to background, AMS should inform the app thread that if an
3523 // activity launch is blocked for the network rules to get updated, it should be unblocked.
3524 if (wasAllowed && !isAllowed) {
3525 return NETWORK_STATE_UNBLOCK;
3526 }
3527 return NETWORK_STATE_NO_CHANGE;
3528 }
3529
3530 /**
3531 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
3532 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
3533 * {@link ProcessList#mProcStateSeqCounter} and notifies the app if it needs to block.
3534 */
3535 @VisibleForTesting
3536 @GuardedBy("mService")
3537 void incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids) {
3538 if (mService.mWaitForNetworkTimeoutMs <= 0) {
3539 return;
3540 }
3541 // Used for identifying which uids need to block for network.
3542 ArrayList<Integer> blockingUids = null;
3543 for (int i = activeUids.size() - 1; i >= 0; --i) {
3544 final UidRecord uidRec = activeUids.valueAt(i);
3545 // If the network is not restricted for uid, then nothing to do here.
3546 if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
3547 continue;
3548 }
3549 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
3550 continue;
3551 }
3552 // If process state is not changed, then there's nothing to do.
3553 if (uidRec.setProcState == uidRec.getCurProcState()) {
3554 continue;
3555 }
3556 final int blockState = getBlockStateForUid(uidRec);
3557 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
3558 // there's nothing the app needs to do in this scenario.
3559 if (blockState == NETWORK_STATE_NO_CHANGE) {
3560 continue;
3561 }
3562 synchronized (uidRec.networkStateLock) {
3563 uidRec.curProcStateSeq = ++mProcStateSeqCounter; // TODO: use method
3564 if (blockState == NETWORK_STATE_BLOCK) {
3565 if (blockingUids == null) {
3566 blockingUids = new ArrayList<>();
3567 }
3568 blockingUids.add(uidRec.uid);
3569 } else {
3570 if (DEBUG_NETWORK) {
3571 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
3572 + " threads for uid: " + uidRec);
3573 }
3574 if (uidRec.waitingForNetwork) {
3575 uidRec.networkStateLock.notifyAll();
3576 }
3577 }
3578 }
3579 }
3580
3581 // There are no uids that need to block, so nothing more to do.
3582 if (blockingUids == null) {
3583 return;
3584 }
3585
3586 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
3587 final ProcessRecord app = mLruProcesses.get(i);
3588 if (!blockingUids.contains(app.uid)) {
3589 continue;
3590 }
3591 if (!app.killedByAm && app.thread != null) {
3592 final UidRecord uidRec = getUidRecordLocked(app.uid);
3593 try {
3594 if (DEBUG_NETWORK) {
3595 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
3596 + uidRec);
3597 }
3598 if (uidRec != null) {
3599 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
3600 }
3601 } catch (RemoteException ignored) {
3602 }
3603 }
3604 }
3605 }
Jing Ji4fcb2a12019-09-11 16:59:36 -07003606
Jing Jie29afc92019-10-29 18:14:49 -07003607 /**
3608 * Create a server socket in system_server, zygote will connect to it
3609 * in order to send unsolicited messages to system_server.
3610 */
3611 private LocalSocket createSystemServerSocketForZygote() {
3612 // The file system entity for this socket is created with 0666 perms, owned
3613 // by system:system. selinux restricts things so that only zygotes can
3614 // access it.
3615 final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH);
3616 if (socketFile.exists()) {
3617 socketFile.delete();
3618 }
3619
3620 LocalSocket serverSocket = null;
3621 try {
3622 serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM);
3623 serverSocket.bind(new LocalSocketAddress(
3624 UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM));
3625 Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666);
3626 } catch (Exception e) {
3627 if (serverSocket != null) {
3628 try {
3629 serverSocket.close();
3630 } catch (IOException ex) {
3631 }
3632 serverSocket = null;
3633 }
3634 }
3635 return serverSocket;
3636 }
3637
3638 /**
3639 * Handle the unsolicited message from zygote.
3640 */
3641 private int handleZygoteMessages(FileDescriptor fd, int events) {
3642 final int eventFd = fd.getInt$();
3643 if ((events & EVENT_INPUT) != 0) {
3644 // An incoming message from zygote
3645 try {
3646 final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0,
3647 mZygoteUnsolicitedMessage.length);
3648 if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld(
3649 mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) {
Jing Ji8055a3a2019-12-17 15:55:33 -08003650 mAppExitInfoTracker.handleZygoteSigChld(
3651 mZygoteSigChldMessage[0] /* pid */,
Jing Jie29afc92019-10-29 18:14:49 -07003652 mZygoteSigChldMessage[1] /* uid */,
3653 mZygoteSigChldMessage[2] /* status */);
3654 }
3655 } catch (Exception e) {
3656 Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e);
3657 }
3658 }
3659 return EVENT_INPUT;
3660 }
Jing Ji8055a3a2019-12-17 15:55:33 -08003661
3662 /**
3663 * Called by ActivityManagerService when a process died.
3664 */
3665 @GuardedBy("mService")
3666 void noteProcessDiedLocked(final ProcessRecord app) {
3667 if (DEBUG_PROCESSES) {
3668 Slog.i(TAG, "note: " + app + " died, saving the exit info");
3669 }
3670
3671 mAppExitInfoTracker.scheduleNoteProcessDiedLocked(app);
3672 }
3673
3674 /**
3675 * Called by ActivityManagerService when it decides to kill an application process.
3676 */
3677 void noteAppKill(final ProcessRecord app, final @Reason int reason,
3678 final @SubReason int subReason, final String msg) {
3679 if (DEBUG_PROCESSES) {
3680 Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
3681 + ", sub-reason: " + subReason + ", message: " + msg);
3682 }
3683 mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg);
3684 }
3685
3686 void noteAppKill(final int pid, final int uid, final @Reason int reason,
3687 final @SubReason int subReason, final String msg) {
3688 if (DEBUG_PROCESSES) {
3689 Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason
3690 + ", sub-reason: " + subReason + ", message: " + msg);
3691 }
3692
3693 mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg);
3694 }
Jing Jie423f762019-12-10 15:05:18 -08003695
3696 /**
3697 * Schedule to kill the given pids when the device is idle
3698 */
3699 void killProcessesWhenImperceptible(int[] pids, String reason, int requester) {
3700 if (ArrayUtils.isEmpty(pids)) {
3701 return;
3702 }
3703
3704 synchronized (mService) {
3705 ProcessRecord app;
3706 for (int i = 0; i < pids.length; i++) {
3707 synchronized (mService.mPidsSelfLocked) {
3708 app = mService.mPidsSelfLocked.get(pids[i]);
3709 }
3710 if (app != null) {
3711 mImperceptibleKillRunner.enqueueLocked(app, reason, requester);
3712 }
3713 }
3714 }
3715 }
3716
3717 private final class ImperceptibleKillRunner extends IUidObserver.Stub {
3718 private static final String EXTRA_PID = "pid";
3719 private static final String EXTRA_UID = "uid";
3720 private static final String EXTRA_TIMESTAMP = "timestamp";
3721 private static final String EXTRA_REASON = "reason";
3722 private static final String EXTRA_REQUESTER = "requester";
3723
3724 private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill";
3725
3726 // uid -> killing information mapping
3727 private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>();
3728
3729 // The last time the various processes have been killed by us.
3730 private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>();
3731
3732 // Device idle or not.
3733 private volatile boolean mIdle;
3734 private boolean mUidObserverEnabled;
3735 private Handler mHandler;
3736 private IdlenessReceiver mReceiver;
3737
3738 private final class H extends Handler {
3739 static final int MSG_DEVICE_IDLE = 0;
3740 static final int MSG_UID_GONE = 1;
3741 static final int MSG_UID_STATE_CHANGED = 2;
3742
3743 H(Looper looper) {
3744 super(looper);
3745 }
3746
3747 @Override
3748 public void handleMessage(Message msg) {
3749 switch (msg.what) {
3750 case MSG_DEVICE_IDLE:
3751 handleDeviceIdle();
3752 break;
3753 case MSG_UID_GONE:
3754 handleUidGone(msg.arg1 /* uid */);
3755 break;
3756 case MSG_UID_STATE_CHANGED:
3757 handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */);
3758 break;
3759 }
3760 }
3761 }
3762
3763 private final class IdlenessReceiver extends BroadcastReceiver {
3764 @Override
3765 public void onReceive(Context context, Intent intent) {
3766 final PowerManager pm = mService.mContext.getSystemService(PowerManager.class);
3767 switch (intent.getAction()) {
3768 case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
3769 notifyDeviceIdleness(pm.isLightDeviceIdleMode());
3770 break;
3771 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
3772 notifyDeviceIdleness(pm.isDeviceIdleMode());
3773 break;
3774 }
3775 }
3776 }
3777
3778 ImperceptibleKillRunner(Looper looper) {
3779 mHandler = new H(looper);
3780 }
3781
3782 @GuardedBy("mService")
3783 boolean enqueueLocked(ProcessRecord app, String reason, int requester) {
3784 // Throttle the killing request for potential bad app to avoid cpu thrashing
3785 Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid);
3786 if (last != null && SystemClock.uptimeMillis() < last + MIN_CRASH_INTERVAL) {
3787 return false;
3788 }
3789
3790 final Bundle bundle = new Bundle();
3791 bundle.putInt(EXTRA_PID, app.pid);
3792 bundle.putInt(EXTRA_UID, app.uid);
3793 // Since the pid could be reused, let's get the actual start time of each process
3794 bundle.putLong(EXTRA_TIMESTAMP, app.startTime);
3795 bundle.putString(EXTRA_REASON, reason);
3796 bundle.putInt(EXTRA_REQUESTER, requester);
3797 List<Bundle> list = mWorkItems.get(app.uid);
3798 if (list == null) {
3799 list = new ArrayList<Bundle>();
3800 mWorkItems.put(app.uid, list);
3801 }
3802 list.add(bundle);
3803 if (mReceiver == null) {
3804 mReceiver = new IdlenessReceiver();
3805 IntentFilter filter = new IntentFilter(
3806 PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
3807 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
3808 mService.mContext.registerReceiver(mReceiver, filter);
3809 }
3810 return true;
3811 }
3812
3813 void notifyDeviceIdleness(boolean idle) {
3814 // No lock is held regarding mIdle, this function is the only updater and caller
3815 // won't re-entry.
3816 boolean diff = mIdle != idle;
3817 mIdle = idle;
3818 if (diff && idle) {
3819 synchronized (this) {
3820 if (mWorkItems.size() > 0) {
3821 mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE);
3822 }
3823 }
3824 }
3825 }
3826
3827 private void handleDeviceIdle() {
3828 final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
3829 final boolean logToDropbox = dbox != null
3830 && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
3831
3832 synchronized (mService) {
3833 final int size = mWorkItems.size();
3834 for (int i = size - 1; mIdle && i >= 0; i--) {
3835 List<Bundle> list = mWorkItems.valueAt(i);
3836 final int len = list.size();
3837 for (int j = len - 1; mIdle && j >= 0; j--) {
3838 Bundle bundle = list.get(j);
3839 if (killProcessLocked(
3840 bundle.getInt(EXTRA_PID),
3841 bundle.getInt(EXTRA_UID),
3842 bundle.getLong(EXTRA_TIMESTAMP),
3843 bundle.getString(EXTRA_REASON),
3844 bundle.getInt(EXTRA_REQUESTER),
3845 dbox, logToDropbox)) {
3846 list.remove(j);
3847 }
3848 }
3849 if (list.size() == 0) {
3850 mWorkItems.removeAt(i);
3851 }
3852 }
3853 registerUidObserverIfNecessaryLocked();
3854 }
3855 }
3856
3857 @GuardedBy("mService")
3858 private void registerUidObserverIfNecessaryLocked() {
3859 // If there are still works remaining, register UID observer
3860 if (!mUidObserverEnabled && mWorkItems.size() > 0) {
3861 mUidObserverEnabled = true;
3862 mService.registerUidObserver(this,
3863 ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
3864 ActivityManager.PROCESS_STATE_UNKNOWN, "android");
3865 } else if (mUidObserverEnabled && mWorkItems.size() == 0) {
3866 mUidObserverEnabled = false;
3867 mService.unregisterUidObserver(this);
3868 }
3869 }
3870
3871 /**
3872 * Kill the given processes, if they are not exempted.
3873 *
3874 * @return True if the process is killed, or it's gone already, or we are not allowed to
3875 * kill it (one of the packages in this process is being exempted).
3876 */
3877 @GuardedBy("mService")
3878 private boolean killProcessLocked(final int pid, final int uid, final long timestamp,
3879 final String reason, final int requester, final DropBoxManager dbox,
3880 final boolean logToDropbox) {
3881 ProcessRecord app = null;
3882 synchronized (mService.mPidsSelfLocked) {
3883 app = mService.mPidsSelfLocked.get(pid);
3884 }
3885
3886 if (app == null || app.pid != pid || app.uid != uid || app.startTime != timestamp) {
3887 // This process record has been reused for another process, meaning the old process
3888 // has been gone.
3889 return true;
3890 }
3891
3892 final int pkgSize = app.pkgList.size();
3893 for (int ip = 0; ip < pkgSize; ip++) {
3894 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(
3895 app.pkgList.keyAt(ip))) {
3896 // One of the packages in this process is exempted
3897 return true;
3898 }
3899 }
3900
3901 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(
3902 app.getReportedProcState())) {
3903 // We need to reschedule it.
3904 return false;
3905 }
3906
3907 app.kill(reason, ApplicationExitInfo.REASON_OTHER, true);
3908
3909 if (!app.isolated) {
3910 mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());
3911 }
3912
3913 if (logToDropbox) {
3914 final long now = SystemClock.elapsedRealtime();
3915 final StringBuilder sb = new StringBuilder();
3916 mService.appendDropBoxProcessHeaders(app, app.processName, sb);
3917 sb.append("Reason: " + reason).append("\n");
3918 sb.append("Requester UID: " + requester).append("\n");
3919 dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString());
3920 }
3921 return true;
3922 }
3923
3924 private void handleUidStateChanged(int uid, int procState) {
3925 final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
3926 final boolean logToDropbox = dbox != null
3927 && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
3928 synchronized (mService) {
3929 if (mIdle && !mService.mConstants
3930 .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) {
3931 List<Bundle> list = mWorkItems.get(uid);
3932 if (list != null) {
3933 final int len = list.size();
3934 for (int j = len - 1; mIdle && j >= 0; j--) {
3935 Bundle bundle = list.get(j);
3936 if (killProcessLocked(
3937 bundle.getInt(EXTRA_PID),
3938 bundle.getInt(EXTRA_UID),
3939 bundle.getLong(EXTRA_TIMESTAMP),
3940 bundle.getString(EXTRA_REASON),
3941 bundle.getInt(EXTRA_REQUESTER),
3942 dbox, logToDropbox)) {
3943 list.remove(j);
3944 }
3945 }
3946 if (list.size() == 0) {
3947 mWorkItems.remove(uid);
3948 }
3949 registerUidObserverIfNecessaryLocked();
3950 }
3951 }
3952 }
3953 }
3954
3955 private void handleUidGone(int uid) {
3956 synchronized (mService) {
3957 mWorkItems.remove(uid);
3958 registerUidObserverIfNecessaryLocked();
3959 }
3960 }
3961
3962 @Override
3963 public void onUidGone(int uid, boolean disabled) {
3964 mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget();
3965 }
3966
3967 @Override
3968 public void onUidActive(int uid) {
3969 }
3970
3971 @Override
3972 public void onUidIdle(int uid, boolean disabled) {
3973 }
3974
3975 @Override
3976 public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
3977 mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
3978 }
3979
3980 @Override
3981 public void onUidCachedChanged(int uid, boolean cached) {
3982 }
3983 };
Dianne Hackborn7d608422011-08-07 16:24:18 -07003984}