1 /* 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 17 package com.android.server.am; 18 19 import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE; 20 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 21 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 22 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_END; 23 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_RESTRICTION_CHANGE; 24 import static android.app.ActivityThread.PROC_START_SEQ_IDENT; 25 import static android.content.pm.Flags.appCompatOption16kb; 26 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO; 27 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; 28 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; 29 import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; 30 import static android.os.Process.SYSTEM_UID; 31 import static android.os.Process.THREAD_PRIORITY_BACKGROUND; 32 import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY; 33 import static android.os.Process.getAdvertisedMem; 34 import static android.os.Process.getFreeMemory; 35 import static android.os.Process.getTotalMemory; 36 import static android.os.Process.killProcessQuiet; 37 import static android.os.Process.startWebView; 38 import static android.system.OsConstants.EAGAIN; 39 40 import static com.android.sdksandbox.flags.Flags.selinuxInputSelector; 41 import static com.android.sdksandbox.flags.Flags.selinuxSdkSandboxAudit; 42 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; 43 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK; 44 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; 45 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS; 46 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; 47 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS; 48 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 49 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 50 import static com.android.server.am.ActivityManagerService.DISPATCH_PROCESSES_CHANGED_UI_MSG; 51 import static com.android.server.am.ActivityManagerService.DISPATCH_PROCESS_DIED_UI_MSG; 52 import static com.android.server.am.ActivityManagerService.IDLE_UIDS_MSG; 53 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS; 54 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG; 55 import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK; 56 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT; 57 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG; 58 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER; 59 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS; 60 import static com.android.server.am.ActivityManagerService.TAG_LRU; 61 import static com.android.server.am.ActivityManagerService.TAG_NETWORK; 62 import static com.android.server.am.ActivityManagerService.TAG_PROCESSES; 63 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS; 64 import static com.android.server.wm.WindowProcessController.STOPPED_STATE_FIRST_LAUNCH; 65 import static com.android.server.wm.WindowProcessController.STOPPED_STATE_FORCE_STOPPED; 66 67 import android.Manifest; 68 import android.annotation.NonNull; 69 import android.annotation.Nullable; 70 import android.annotation.SpecialUsers.CanBeALL; 71 import android.annotation.UserIdInt; 72 import android.app.ActivityManager; 73 import android.app.ActivityManager.ProcessCapability; 74 import android.app.ActivityThread; 75 import android.app.AppGlobals; 76 import android.app.AppProtoEnums; 77 import android.app.ApplicationExitInfo; 78 import android.app.ApplicationExitInfo.Reason; 79 import android.app.ApplicationExitInfo.SubReason; 80 import android.app.ApplicationStartInfo; 81 import android.app.IApplicationThread; 82 import android.app.IProcessObserver; 83 import android.app.UidObserver; 84 import android.compat.annotation.ChangeId; 85 import android.compat.annotation.EnabledAfter; 86 import android.content.BroadcastReceiver; 87 import android.content.ComponentName; 88 import android.content.Context; 89 import android.content.Intent; 90 import android.content.IntentFilter; 91 import android.content.pm.ApplicationInfo; 92 import android.content.pm.IPackageManager; 93 import android.content.pm.PackageManager; 94 import android.content.pm.PackageManagerInternal; 95 import android.content.res.Resources; 96 import android.graphics.Point; 97 import android.net.LocalSocket; 98 import android.net.LocalSocketAddress; 99 import android.os.AppZygote; 100 import android.os.Binder; 101 import android.os.Build; 102 import android.os.Bundle; 103 import android.os.DropBoxManager; 104 import android.os.Handler; 105 import android.os.IBinder; 106 import android.os.Looper; 107 import android.os.Message; 108 import android.os.OomKillRecord; 109 import android.os.PowerManager; 110 import android.os.Process; 111 import android.os.RemoteCallbackList; 112 import android.os.RemoteException; 113 import android.os.StrictMode; 114 import android.os.SystemClock; 115 import android.os.SystemProperties; 116 import android.os.Trace; 117 import android.os.UserHandle; 118 import android.os.storage.StorageManagerInternal; 119 import android.provider.DeviceConfig; 120 import android.system.Os; 121 import android.system.OsConstants; 122 import android.text.TextUtils; 123 import android.util.ArrayMap; 124 import android.util.ArraySet; 125 import android.util.DebugUtils; 126 import android.util.EventLog; 127 import android.util.LongSparseArray; 128 import android.util.Pair; 129 import android.util.Slog; 130 import android.util.SparseArray; 131 import android.util.SparseBooleanArray; 132 import android.util.TimeUtils; 133 import android.util.proto.ProtoOutputStream; 134 import android.view.Display; 135 136 import com.android.internal.annotations.CompositeRWLock; 137 import com.android.internal.annotations.GuardedBy; 138 import com.android.internal.annotations.VisibleForTesting; 139 import com.android.internal.app.ProcessMap; 140 import com.android.internal.os.Zygote; 141 import com.android.internal.util.ArrayUtils; 142 import com.android.internal.util.MemInfoReader; 143 import com.android.server.AppStateTracker; 144 import com.android.server.LocalServices; 145 import com.android.server.ServiceThread; 146 import com.android.server.SystemConfig; 147 import com.android.server.Watchdog; 148 import com.android.server.am.ActivityManagerService.ProcessChangeItem; 149 import com.android.server.compat.PlatformCompat; 150 import com.android.server.pm.pkg.AndroidPackage; 151 import com.android.server.pm.pkg.PackageStateInternal; 152 import com.android.server.wm.ActivityServiceConnectionsHolder; 153 import com.android.server.wm.WindowManagerService; 154 import com.android.server.wm.WindowProcessController; 155 156 import dalvik.system.VMRuntime; 157 158 import java.io.DataInputStream; 159 import java.io.File; 160 import java.io.FileDescriptor; 161 import java.io.IOException; 162 import java.io.OutputStream; 163 import java.io.PrintWriter; 164 import java.nio.ByteBuffer; 165 import java.util.ArrayList; 166 import java.util.Arrays; 167 import java.util.BitSet; 168 import java.util.Collections; 169 import java.util.Comparator; 170 import java.util.HashMap; 171 import java.util.List; 172 import java.util.Map; 173 import java.util.Set; 174 import java.util.function.Consumer; 175 import java.util.function.Function; 176 177 /** 178 * Activity manager code dealing with processes. 179 */ 180 public final class ProcessList { 181 static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; 182 183 static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS; 184 185 // A system property to control if app data isolation is enabled. 186 static final String ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY = 187 "persist.zygote.app_data_isolation"; 188 189 // A system property to control if obb app data isolation is enabled in vold. 190 static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY = 191 "persist.sys.vold_app_data_isolation_enabled"; 192 193 private static final String APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS = ":isSdkSandboxAudit"; 194 private static final String APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = ":isSdkSandboxNext"; 195 196 // OOM adjustments for processes in various states: 197 198 // Uninitialized value for any major or minor adj fields 199 public static final int INVALID_ADJ = -10000; 200 201 // Adjustment used in certain places where we don't know it yet. 202 // (Generally this is something that is going to be cached, but we 203 // don't know the exact value in the cached range to assign yet.) 204 public static final int UNKNOWN_ADJ = 1001; 205 206 // This is a process only hosting activities that are not visible, 207 // so it can be killed without any disruption. 208 public static final int CACHED_APP_MAX_ADJ = 999; 209 public static final int CACHED_APP_MIN_ADJ = 900; 210 211 // This is the oom_adj level that we allow to die first. This cannot be equal to 212 // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of 213 // CACHED_APP_MAX_ADJ. 214 public static final int CACHED_APP_LMK_FIRST_ADJ = 950; 215 216 // Number of levels we have available for different service connection group importance 217 // levels. 218 public static final int CACHED_APP_IMPORTANCE_LEVELS = 5; 219 220 // The B list of SERVICE_ADJ -- these are the old and decrepit 221 // services that aren't as shiny and interesting as the ones in the A list. 222 public static final int SERVICE_B_ADJ = 800; 223 224 // This is the process of the previous application that the user was in. 225 // This process is kept above other things, because it is very common to 226 // switch back to the previous app. This is important both for recent 227 // task switch (toggling between the two top recent apps) as well as normal 228 // UI flow such as clicking on a URI in the e-mail app to view in the browser, 229 // and then pressing back to return to e-mail. 230 public static final int PREVIOUS_APP_ADJ = 700; 231 public static final int PREVIOUS_APP_MAX_ADJ = Flags.oomadjusterPrevLaddering() ? 799 : 700; 232 233 // This is a process holding the home application -- we want to try 234 // avoiding killing it, even if it would normally be in the background, 235 // because the user interacts with it so much. 236 public static final int HOME_APP_ADJ = 600; 237 238 // This is a process holding an application service -- killing it will not 239 // have much of an impact as far as the user is concerned. 240 public static final int SERVICE_ADJ = 500; 241 242 // This is a process with a heavy-weight application. It is in the 243 // background, but we want to try to avoid killing it. Value set in 244 // system/rootdir/init.rc on startup. 245 public static final int HEAVY_WEIGHT_APP_ADJ = 400; 246 247 // This is a process currently hosting a backup operation. Killing it 248 // is not entirely fatal but is generally a bad idea. 249 public static final int BACKUP_APP_ADJ = 300; 250 251 // This is a process bound by the system (or other app) that's more important than services but 252 // not so perceptible that it affects the user immediately if killed. 253 public static final int PERCEPTIBLE_LOW_APP_ADJ = 250; 254 255 // This is a process hosting services that are not perceptible to the user but the 256 // client (system) binding to it requested to treat it as if it is perceptible and avoid killing 257 // it if possible. 258 public static final int PERCEPTIBLE_MEDIUM_APP_ADJ = 225; 259 260 // This is a process only hosting components that are perceptible to the 261 // user, and we really want to avoid killing them, but they are not 262 // immediately visible. An example is background music playback. 263 public static final int PERCEPTIBLE_APP_ADJ = 200; 264 265 // This is a process only hosting activities that are visible to the 266 // user, so we'd prefer they don't disappear. 267 public static final int VISIBLE_APP_ADJ = 100; 268 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1; 269 270 // This is a process that was recently TOP and moved to FGS. Continue to treat it almost 271 // like a foreground app for a while. 272 // @see TOP_TO_FGS_GRACE_PERIOD 273 public static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50; 274 275 // This is the process running the current foreground app. We'd really 276 // rather not kill it! 277 public static final int FOREGROUND_APP_ADJ = 0; 278 279 // This is a process that the system or a persistent process has bound to, 280 // and indicated it is important. 281 public static final int PERSISTENT_SERVICE_ADJ = -700; 282 283 // This is a system persistent process, such as telephony. Definitely 284 // don't want to kill it, but doing so is not completely fatal. 285 public static final int PERSISTENT_PROC_ADJ = -800; 286 287 // The system process runs at the default adjustment. 288 public static final int SYSTEM_ADJ = -900; 289 290 // Special code for native processes that are not being managed by the system (so 291 // don't have an oom adj assigned by the system). 292 public static final int NATIVE_ADJ = -1000; 293 294 // Memory page size. 295 static final int PAGE_SIZE = (int) Os.sysconf(OsConstants._SC_PAGESIZE); 296 297 // Activity manager's version of an undefined schedule group 298 static final int SCHED_GROUP_UNDEFINED = Integer.MIN_VALUE; 299 // Activity manager's version of Process.THREAD_GROUP_BACKGROUND 300 static final int SCHED_GROUP_BACKGROUND = 0; 301 // Activity manager's version of Process.THREAD_GROUP_RESTRICTED 302 static final int SCHED_GROUP_RESTRICTED = 1; 303 // Activity manager's version of Process.THREAD_GROUP_DEFAULT 304 static final int SCHED_GROUP_DEFAULT = 2; 305 // Activity manager's version of Process.THREAD_GROUP_TOP_APP 306 public static final int SCHED_GROUP_TOP_APP = 3; 307 // Activity manager's version of Process.THREAD_GROUP_TOP_APP 308 // Disambiguate between actual top app and processes bound to the top app 309 static final int SCHED_GROUP_TOP_APP_BOUND = 4; 310 // Activity manager's version of Process.THREAD_GROUP_FOREGROUND_WINDOW 311 // The priority is like between default and top-app. 312 static final int SCHED_GROUP_FOREGROUND_WINDOW = 5; 313 314 // The minimum number of cached apps we want to be able to keep around, 315 // without empty apps being able to push them out of memory. 316 static final int MIN_CACHED_APPS = 2; 317 318 // Threshold of number of cached+empty where we consider memory critical. 319 static final int TRIM_CRITICAL_THRESHOLD = 3; 320 321 // Threshold of number of cached+empty where we consider memory critical. 322 static final int TRIM_LOW_THRESHOLD = 5; 323 324 /** 325 * State indicating that there is no need for any blocking for network. 326 */ 327 @VisibleForTesting 328 static final int NETWORK_STATE_NO_CHANGE = 0; 329 330 /** 331 * State indicating that the main thread needs to be informed about the network wait. 332 */ 333 @VisibleForTesting 334 static final int NETWORK_STATE_BLOCK = 1; 335 336 /** 337 * State indicating that any threads waiting for network state to get updated can be unblocked. 338 */ 339 @VisibleForTesting 340 static final int NETWORK_STATE_UNBLOCK = 2; 341 342 // If true, then we pass the flag to ART to load the app image startup cache. 343 private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE = 344 "persist.device_config.runtime_native.use_app_image_startup_cache"; 345 346 // The socket path for zygote to send unsolicited msg. 347 // Must keep sync with com_android_internal_os_Zygote.cpp. 348 private static final String UNSOL_ZYGOTE_MSG_SOCKET_PATH = "/data/system/unsolzygotesocket"; 349 350 // Low Memory Killer Daemon command codes. 351 // These must be kept in sync with lmk_cmd definitions in lmkd.h 352 // 353 // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs) 354 // LMK_PROCPRIO <pid> <uid> <prio> 355 // LMK_PROCREMOVE <pid> 356 // LMK_PROCPURGE 357 // LMK_GETKILLCNT 358 // LMK_SUBSCRIBE 359 // LMK_PROCKILL 360 // LMK_UPDATE_PROPS 361 // LMK_KILL_OCCURRED 362 // LMK_START_MONITORING 363 // LMK_BOOT_COMPLETED 364 // LMK_PROCS_PRIO 365 static final byte LMK_TARGET = 0; 366 static final byte LMK_PROCPRIO = 1; 367 static final byte LMK_PROCREMOVE = 2; 368 static final byte LMK_PROCPURGE = 3; 369 static final byte LMK_GETKILLCNT = 4; 370 static final byte LMK_SUBSCRIBE = 5; 371 static final byte LMK_PROCKILL = 6; // Note: this is an unsolicited command 372 static final byte LMK_UPDATE_PROPS = 7; 373 static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event 374 static final byte LMK_START_MONITORING = 9; // Start monitoring if delayed earlier 375 static final byte LMK_BOOT_COMPLETED = 10; 376 static final byte LMK_PROCS_PRIO = 11; // Batch option for LMK_PROCPRIO 377 378 // Low Memory Killer Daemon command codes. 379 // These must be kept in sync with async_event_type definitions in lmkd.h 380 // 381 static final int LMK_ASYNC_EVENT_KILL = 0; 382 static final int LMK_ASYNC_EVENT_STAT = 1; 383 384 // lmkd reconnect delay in msecs 385 private static final long LMKD_RECONNECT_DELAY_MS = 1000; 386 387 /** 388 * Apps have no access to the private data directories of any other app, even if the other 389 * app has made them world-readable. 390 */ 391 @ChangeId 392 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) 393 private static final long APP_DATA_DIRECTORY_ISOLATION = 143937733; // See b/143937733 394 395 ActivityManagerService mService = null; 396 397 // To kill process groups asynchronously 398 static KillHandler sKillHandler = null; 399 static ServiceThread sKillThread = null; 400 401 // These are the various interesting memory levels that we will give to 402 // the OOM killer. Note that the OOM killer only supports 6 slots, so we 403 // can't give it a different value for every possible kind of process. 404 private final int[] mOomAdj = new int[] { 405 FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ, 406 PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ 407 }; 408 // These are the low-end OOM level limits. This is appropriate for an 409 // HVGA or smaller phone with less than 512MB. Values are in KB. 410 private final int[] mOomMinFreeLow = new int[] { 411 12288, 18432, 24576, 412 36864, 43008, 49152 413 }; 414 // These are the high-end OOM level limits. This is appropriate for a 415 // 1280x800 or larger screen with around 1GB RAM. Values are in KB. 416 private final int[] mOomMinFreeHigh = new int[] { 417 73728, 92160, 110592, 418 129024, 147456, 184320 419 }; 420 // The actual OOM killer memory levels we are using. 421 private final int[] mOomMinFree = new int[mOomAdj.length]; 422 423 private final long mTotalMemMb; 424 425 private long mCachedRestoreLevel; 426 427 private boolean mHaveDisplaySize; 428 429 private static LmkdConnection sLmkdConnection = null; 430 431 private static OomConnection sOomConnection = null; 432 433 private boolean mOomLevelsSet = false; 434 435 private boolean mAppDataIsolationEnabled = false; 436 437 private boolean mVoldAppDataIsolationEnabled = false; 438 439 private ArrayList<String> mAppDataIsolationAllowlistedApps; 440 441 /** 442 * Temporary to avoid allocations. Protected by main lock. 443 */ 444 @GuardedBy("mService") 445 final StringBuilder mStringBuilder = new StringBuilder(256); 446 447 /** 448 * A global counter for generating sequence numbers. 449 * This value will be used when incrementing sequence numbers in individual uidRecords. 450 * 451 * Having a global counter ensures that seq numbers are monotonically increasing for a 452 * particular uid even when the uidRecord is re-created. 453 */ 454 @VisibleForTesting 455 volatile long mProcStateSeqCounter = 0; 456 457 /** 458 * A global counter for generating sequence numbers to uniquely identify pending process starts. 459 */ 460 @GuardedBy("mService") 461 private long mProcStartSeqCounter = 0; 462 463 /** 464 * Contains {@link ProcessRecord} objects for pending process starts. 465 * 466 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord} 467 */ 468 @GuardedBy("mService") 469 final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>(); 470 471 /** 472 * List of running applications, sorted by recent usage. 473 * The first entry in the list is the least recently used. 474 */ 475 @CompositeRWLock({"mService", "mProcLock"}) 476 private final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 477 478 /** 479 * Where in mLruProcesses that the processes hosting activities start. 480 */ 481 @CompositeRWLock({"mService", "mProcLock"}) 482 private int mLruProcessActivityStart = 0; 483 484 /** 485 * Where in mLruProcesses that the processes hosting services start. 486 * This is after (lower index) than mLruProcessesActivityStart. 487 */ 488 @CompositeRWLock({"mService", "mProcLock"}) 489 private int mLruProcessServiceStart = 0; 490 491 /** 492 * Current sequence id for process LRU updating. 493 */ 494 @CompositeRWLock({"mService", "mProcLock"}) 495 private int mLruSeq = 0; 496 497 @CompositeRWLock({"mService", "mProcLock"}) 498 ActiveUids mActiveUids; 499 500 /** 501 * The currently running isolated processes. 502 */ 503 @GuardedBy("mService") 504 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>(); 505 506 /** 507 * The currently running application zygotes. 508 */ 509 @GuardedBy("mService") 510 final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>(); 511 512 /** Manages the {@link android.app.ApplicationStartInfo} records. */ 513 @GuardedBy("mAppStartInfoTracker") 514 private final AppStartInfoTracker mAppStartInfoTracker = new AppStartInfoTracker(); 515 516 /** 517 * The currently running SDK sandbox processes for a uid. 518 */ 519 @GuardedBy("mService") 520 final SparseArray<ArrayList<ProcessRecord>> mSdkSandboxes = new SparseArray<>(); 521 522 /** 523 * Managees the {@link android.app.ApplicationExitInfo} records. 524 */ 525 @GuardedBy("mAppExitInfoTracker") 526 final AppExitInfoTracker mAppExitInfoTracker = new AppExitInfoTracker(); 527 528 /** 529 * The processes that are forked off an application zygote. 530 */ 531 @GuardedBy("mService") 532 final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses = 533 new ArrayMap<AppZygote, ArrayList<ProcessRecord>>(); 534 535 /** 536 * The list of apps in background restricted mode. 537 */ 538 @GuardedBy("mService") 539 final ArraySet<ProcessRecord> mAppsInBackgroundRestricted = new ArraySet<>(); 540 541 private PlatformCompat mPlatformCompat = null; 542 543 /** 544 * The server socket in system_server, zygote will connect to it 545 * in order to send unsolicited messages to system_server. 546 */ 547 private LocalSocket mSystemServerSocketForZygote; 548 549 /** 550 * Maximum number of bytes that an incoming unsolicited zygote message could be. 551 * To be updated if new message type needs to be supported. 552 */ 553 private static final int MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE = 16; 554 555 /** 556 * The buffer to be used to receive the incoming unsolicited zygote message. 557 */ 558 private final byte[] mZygoteUnsolicitedMessage = new byte[MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE]; 559 560 /** 561 * The buffer to be used to receive the SIGCHLD data, it includes pid/uid/status. 562 */ 563 private final int[] mZygoteSigChldMessage = new int[3]; 564 565 ActivityManagerGlobalLock mProcLock; 566 567 private static final String PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS = 568 "apply_sdk_sandbox_audit_restrictions"; 569 private static final boolean DEFAULT_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS = false; 570 571 private static final String PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = 572 "apply_sdk_sandbox_next_restrictions"; 573 private static final boolean DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = false; 574 575 @GuardedBy("mService") 576 private ProcessListSettingsListener mProcessListSettingsListener; 577 578 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) getProcessListSettingsListener()579 ProcessListSettingsListener getProcessListSettingsListener() { 580 synchronized (mService) { 581 if (mProcessListSettingsListener == null) { 582 mProcessListSettingsListener = new ProcessListSettingsListener(mService.mContext); 583 mProcessListSettingsListener.registerObserver(); 584 } 585 return mProcessListSettingsListener; 586 } 587 } 588 589 static class ProcessListSettingsListener implements DeviceConfig.OnPropertiesChangedListener { 590 591 private final Context mContext; 592 private final Object mLock = new Object(); 593 594 @GuardedBy("mLock") 595 private boolean mSdkSandboxApplyRestrictionsAudit = 596 DeviceConfig.getBoolean( 597 DeviceConfig.NAMESPACE_ADSERVICES, 598 PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS, 599 DEFAULT_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS); 600 601 @GuardedBy("mLock") 602 private boolean mSdkSandboxApplyRestrictionsNext = 603 DeviceConfig.getBoolean( 604 DeviceConfig.NAMESPACE_ADSERVICES, 605 PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS, 606 DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS); 607 ProcessListSettingsListener(Context context)608 ProcessListSettingsListener(Context context) { 609 mContext = context; 610 } 611 registerObserver()612 private void registerObserver() { 613 DeviceConfig.addOnPropertiesChangedListener( 614 DeviceConfig.NAMESPACE_ADSERVICES, mContext.getMainExecutor(), this); 615 } 616 617 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) unregisterObserver()618 void unregisterObserver() { 619 DeviceConfig.removeOnPropertiesChangedListener(this); 620 } 621 applySdkSandboxRestrictionsAudit()622 boolean applySdkSandboxRestrictionsAudit() { 623 synchronized (mLock) { 624 return mSdkSandboxApplyRestrictionsAudit; 625 } 626 } 627 applySdkSandboxRestrictionsNext()628 boolean applySdkSandboxRestrictionsNext() { 629 synchronized (mLock) { 630 return mSdkSandboxApplyRestrictionsNext; 631 } 632 } 633 634 @Override onPropertiesChanged(@onNull DeviceConfig.Properties properties)635 public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { 636 synchronized (mLock) { 637 for (String name : properties.getKeyset()) { 638 if (name == null) { 639 continue; 640 } 641 642 switch (name) { 643 case PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS: 644 mSdkSandboxApplyRestrictionsAudit = 645 properties.getBoolean( 646 PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS, 647 DEFAULT_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS); 648 break; 649 case PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS: 650 mSdkSandboxApplyRestrictionsNext = 651 properties.getBoolean( 652 PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS, 653 DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS); 654 break; 655 default: 656 } 657 } 658 } 659 } 660 } 661 662 final class IsolatedUidRange { 663 @VisibleForTesting 664 public final int mFirstUid; 665 @VisibleForTesting 666 public final int mLastUid; 667 668 @GuardedBy("ProcessList.this.mService") 669 private final SparseBooleanArray mUidUsed = new SparseBooleanArray(); 670 671 @GuardedBy("ProcessList.this.mService") 672 private int mNextUid; 673 IsolatedUidRange(int firstUid, int lastUid)674 IsolatedUidRange(int firstUid, int lastUid) { 675 mFirstUid = firstUid; 676 mLastUid = lastUid; 677 mNextUid = firstUid; 678 } 679 680 @GuardedBy("ProcessList.this.mService") allocateIsolatedUidLocked(int userId)681 int allocateIsolatedUidLocked(int userId) { 682 int uid; 683 int stepsLeft = (mLastUid - mFirstUid + 1); 684 for (int i = 0; i < stepsLeft; ++i) { 685 if (mNextUid < mFirstUid || mNextUid > mLastUid) { 686 mNextUid = mFirstUid; 687 } 688 uid = UserHandle.getUid(userId, mNextUid); 689 mNextUid++; 690 if (!mUidUsed.get(uid, false)) { 691 mUidUsed.put(uid, true); 692 return uid; 693 } 694 } 695 return -1; 696 } 697 698 @GuardedBy("ProcessList.this.mService") freeIsolatedUidLocked(int uid)699 void freeIsolatedUidLocked(int uid) { 700 mUidUsed.delete(uid); 701 } 702 }; 703 704 /** 705 * A class that allocates ranges of isolated UIDs per application, and keeps track of them. 706 */ 707 final class IsolatedUidRangeAllocator { 708 private final int mFirstUid; 709 private final int mNumUidRanges; 710 private final int mNumUidsPerRange; 711 /** 712 * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange) 713 * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that. 714 */ 715 @GuardedBy("ProcessList.this.mService") 716 private final BitSet mAvailableUidRanges; 717 @GuardedBy("ProcessList.this.mService") 718 private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>(); 719 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange)720 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) { 721 mFirstUid = firstUid; 722 mNumUidsPerRange = numUidsPerRange; 723 mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange; 724 mAvailableUidRanges = new BitSet(mNumUidRanges); 725 // Mark all as available 726 mAvailableUidRanges.set(0, mNumUidRanges); 727 } 728 729 @GuardedBy("ProcessList.this.mService") getIsolatedUidRangeLocked(String processName, int uid)730 IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) { 731 return mAppRanges.get(processName, uid); 732 } 733 734 @GuardedBy("ProcessList.this.mService") getOrCreateIsolatedUidRangeLocked(String processName, int uid)735 IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) { 736 IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid); 737 if (range == null) { 738 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0); 739 if (uidRangeIndex < 0) { 740 // No free range 741 return null; 742 } 743 mAvailableUidRanges.clear(uidRangeIndex); 744 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange; 745 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1); 746 mAppRanges.put(processName, uid, range); 747 } 748 return range; 749 } 750 751 @GuardedBy("ProcessList.this.mService") freeUidRangeLocked(ApplicationInfo info)752 void freeUidRangeLocked(ApplicationInfo info) { 753 // Find the UID range 754 IsolatedUidRange range = mAppRanges.get(info.processName, info.uid); 755 if (range != null) { 756 // Map back to starting uid 757 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange; 758 // Mark it as available in the underlying bitset 759 mAvailableUidRanges.set(uidRangeIndex); 760 // And the map 761 mAppRanges.remove(info.processName, info.uid); 762 } 763 } 764 } 765 766 /** 767 * The available isolated UIDs for processes that are not spawned from an application zygote. 768 */ 769 @VisibleForTesting 770 @GuardedBy("mService") 771 IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID, 772 Process.LAST_ISOLATED_UID); 773 774 /** 775 * An allocator for isolated UID ranges for apps that use an application zygote. 776 */ 777 @VisibleForTesting 778 @GuardedBy("mService") 779 IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator = 780 new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 781 Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE); 782 783 /** 784 * Processes that are being forcibly torn down. 785 */ 786 @GuardedBy("mService") 787 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 788 789 /** 790 * Processes that are killed by us and being waiting for the death notification. 791 */ 792 @GuardedBy("mService") 793 final ProcessMap<ProcessRecord> mDyingProcesses = new ProcessMap<>(); 794 795 // Self locked with the inner lock within the RemoteCallbackList 796 @GuardedBy("mProcessObservers") 797 private final RemoteCallbackList<IProcessObserver> mProcessObservers = 798 new RemoteCallbackList<>(); 799 800 // No lock is needed as it's accessed from single thread only 801 private ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 802 803 @GuardedBy("mProcessChangeLock") 804 private final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>(); 805 806 @GuardedBy("mProcessChangeLock") 807 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>(); 808 809 /** 810 * A dedicated lock for dispatching the process changes as it occurs frequently 811 */ 812 private final Object mProcessChangeLock = new Object(); 813 814 /** 815 * All of the processes that are running organized by name. 816 * The keys are process names and the values are the associated ProcessRecord objects. 817 */ 818 @CompositeRWLock({"mService", "mProcLock"}) 819 private final MyProcessMap mProcessNames = new MyProcessMap(); 820 821 final class MyProcessMap extends ProcessMap<ProcessRecord> { 822 @Override put(String name, int uid, ProcessRecord value)823 public ProcessRecord put(String name, int uid, ProcessRecord value) { 824 final ProcessRecord r = super.put(name, uid, value); 825 mService.mAtmInternal.onProcessAdded(r.getWindowProcessController()); 826 return r; 827 } 828 829 @Override remove(String name, int uid)830 public ProcessRecord remove(String name, int uid) { 831 final ProcessRecord r = super.remove(name, uid); 832 mService.mAtmInternal.onProcessRemoved(name, uid); 833 return r; 834 } 835 } 836 837 final class KillHandler extends Handler { 838 static final int KILL_PROCESS_GROUP_MSG = 4000; 839 static final int LMKD_RECONNECT_MSG = 4001; 840 KillHandler(Looper looper)841 public KillHandler(Looper looper) { 842 super(looper, null, true); 843 } 844 845 @Override handleMessage(Message msg)846 public void handleMessage(Message msg) { 847 switch (msg.what) { 848 case KILL_PROCESS_GROUP_MSG: 849 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup"); 850 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); 851 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 852 break; 853 case LMKD_RECONNECT_MSG: 854 if (!sLmkdConnection.connect()) { 855 Slog.i(TAG, "Failed to connect to lmkd, retry after " + 856 LMKD_RECONNECT_DELAY_MS + " ms"); 857 // retry after LMKD_RECONNECT_DELAY_MS 858 sendMessageDelayed(obtainMessage( 859 LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS); 860 } 861 break; 862 default: 863 super.handleMessage(msg); 864 } 865 } 866 } 867 868 /** 869 * A runner to handle the imperceptible killings. 870 */ 871 ImperceptibleKillRunner mImperceptibleKillRunner; 872 873 //////////////////// END FIELDS //////////////////// 874 ProcessList()875 ProcessList() { 876 MemInfoReader minfo = new MemInfoReader(); 877 minfo.readMemInfo(); 878 mTotalMemMb = minfo.getTotalSize()/(1024*1024); 879 updateOomLevels(0, 0, false); 880 } 881 init(ActivityManagerService service, ActiveUids activeUids, PlatformCompat platformCompat)882 void init(ActivityManagerService service, ActiveUids activeUids, 883 PlatformCompat platformCompat) { 884 mService = service; 885 mActiveUids = activeUids; 886 mPlatformCompat = platformCompat; 887 mProcLock = service.mProcLock; 888 // Get this after boot, and won't be changed until it's rebooted, as we don't 889 // want some apps enabled while some apps disabled 890 mAppDataIsolationEnabled = 891 SystemProperties.getBoolean(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true); 892 mVoldAppDataIsolationEnabled = SystemProperties.getBoolean( 893 ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false); 894 mAppDataIsolationAllowlistedApps = new ArrayList<>( 895 SystemConfig.getInstance().getAppDataIsolationWhitelistedApps()); 896 897 if (sKillHandler == null) { 898 sKillThread = new ServiceThread(TAG + ":kill", 899 THREAD_PRIORITY_BACKGROUND, true /* allowIo */); 900 sKillThread.start(); 901 sKillHandler = new KillHandler(sKillThread.getLooper()); 902 sOomConnection = new OomConnection(new OomConnection.OomConnectionListener() { 903 @Override 904 public void handleOomEvent(OomKillRecord[] oomKills) { 905 for (OomKillRecord oomKill: oomKills) { 906 synchronized (mProcLock) { 907 noteAppKill( 908 oomKill.getPid(), 909 oomKill.getUid(), 910 ApplicationExitInfo.REASON_LOW_MEMORY, 911 ApplicationExitInfo.SUBREASON_OOM_KILL, 912 "oom"); 913 914 oomKill.logKillOccurred(); 915 } 916 } 917 } 918 }); 919 sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(), 920 new LmkdConnection.LmkdConnectionListener() { 921 @Override 922 public boolean onConnect(OutputStream ostream) { 923 Slog.i(TAG, "Connection with lmkd established"); 924 return onLmkdConnect(ostream); 925 } 926 927 @Override 928 public void onDisconnect() { 929 Slog.w(TAG, "Lost connection to lmkd"); 930 // start reconnection after delay to let lmkd restart 931 sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( 932 KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS); 933 } 934 935 @Override 936 public boolean isReplyExpected(ByteBuffer replyBuf, 937 ByteBuffer dataReceived, int receivedLen) { 938 // compare the preambule (currently one integer) to check if 939 // this is the reply packet we are waiting for 940 return (receivedLen == replyBuf.array().length && 941 dataReceived.getInt(0) == replyBuf.getInt(0)); 942 } 943 944 @Override 945 public boolean handleUnsolicitedMessage(DataInputStream inputData, 946 int receivedLen) { 947 if (receivedLen < 4) { 948 return false; 949 } 950 951 try { 952 switch (inputData.readInt()) { 953 case LMK_PROCKILL: 954 if (receivedLen != 16) { 955 return false; 956 } 957 final int pid = inputData.readInt(); 958 final int uid = inputData.readInt(); 959 final int rssKb = inputData.readInt(); 960 mAppExitInfoTracker.scheduleNoteLmkdProcKilled(pid, uid, 961 rssKb); 962 return true; 963 case LMK_KILL_OCCURRED: 964 if (receivedLen 965 < LmkdStatsReporter.KILL_OCCURRED_MSG_SIZE) { 966 return false; 967 } 968 // Note: directly access 969 // ActiveServices.sNumForegroundServices, do not try to 970 // hold AMS lock here, otherwise it is a potential deadlock. 971 Pair<Integer, Integer> foregroundServices = 972 ActiveServices.sNumForegroundServices.get(); 973 LmkdStatsReporter.logKillOccurred(inputData, 974 foregroundServices.first, 975 foregroundServices.second); 976 return true; 977 default: 978 return false; 979 } 980 } catch (IOException e) { 981 Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED"); 982 } 983 return false; 984 } 985 } 986 ); 987 // Start listening on incoming connections from zygotes. 988 mSystemServerSocketForZygote = createSystemServerSocketForZygote(); 989 if (mSystemServerSocketForZygote != null) { 990 sKillHandler.getLooper().getQueue().addOnFileDescriptorEventListener( 991 mSystemServerSocketForZygote.getFileDescriptor(), 992 EVENT_INPUT, this::handleZygoteMessages); 993 } 994 mAppStartInfoTracker.init(mService); 995 mAppExitInfoTracker.init(mService); 996 mImperceptibleKillRunner = new ImperceptibleKillRunner(sKillThread.getLooper()); 997 } 998 } 999 onSystemReady()1000 void onSystemReady() { 1001 mAppStartInfoTracker.onSystemReady(); 1002 mAppExitInfoTracker.onSystemReady(); 1003 } 1004 applyDisplaySize(WindowManagerService wm)1005 void applyDisplaySize(WindowManagerService wm) { 1006 if (!mHaveDisplaySize) { 1007 Point p = new Point(); 1008 // TODO(multi-display): Compute based on sum of all connected displays' resolutions. 1009 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p); 1010 if (p.x != 0 && p.y != 0) { 1011 updateOomLevels(p.x, p.y, true); 1012 mHaveDisplaySize = true; 1013 } 1014 } 1015 } 1016 1017 /** 1018 * Get a map of pid and package name that process of that pid Android/data and Android/obb 1019 * directory is not mounted to lowerfs to speed up access. 1020 */ getProcessesWithPendingBindMounts(int userId)1021 Map<Integer, String> getProcessesWithPendingBindMounts(int userId) { 1022 final Map<Integer, String> pidPackageMap = new HashMap<>(); 1023 synchronized (mProcLock) { 1024 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 1025 final ProcessRecord record = mLruProcesses.get(i); 1026 if (record.userId != userId || !record.isBindMountPending()) { 1027 continue; 1028 } 1029 final int pid = record.getPid(); 1030 // It can happen when app process is starting, but zygote work is not done yet so 1031 // system does not this pid record yet. 1032 if (pid == 0) { 1033 throw new IllegalStateException("Pending process is not started yet," 1034 + "retry later"); 1035 } 1036 pidPackageMap.put(pid, record.info.packageName); 1037 } 1038 } 1039 return pidPackageMap; 1040 } 1041 updateOomLevels(int displayWidth, int displayHeight, boolean write)1042 private void updateOomLevels(int displayWidth, int displayHeight, boolean write) { 1043 // Scale buckets from avail memory: at 300MB we use the lowest values to 1044 // 700MB or more for the top values. 1045 float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350); 1046 1047 // Scale buckets from screen size. 1048 int minSize = 480 * 800; // 384000 1049 int maxSize = 1280 * 800; // 1024000 230400 870400 .264 1050 float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize); 1051 if (false) { 1052 Slog.i("XXXXXX", "scaleMem=" + scaleMem); 1053 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth 1054 + " dh=" + displayHeight); 1055 } 1056 1057 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp; 1058 if (scale < 0) scale = 0; 1059 else if (scale > 1) scale = 1; 1060 int minfree_adj = Resources.getSystem().getInteger( 1061 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust); 1062 int minfree_abs = Resources.getSystem().getInteger( 1063 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute); 1064 if (false) { 1065 Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs); 1066 } 1067 1068 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0; 1069 1070 for (int i = 0; i < mOomAdj.length; i++) { 1071 int low = mOomMinFreeLow[i]; 1072 int high = mOomMinFreeHigh[i]; 1073 if (is64bit) { 1074 // Increase the high min-free levels for cached processes for 64-bit 1075 if (i == 4) high = (high * 3) / 2; 1076 else if (i == 5) high = (high * 7) / 4; 1077 } 1078 mOomMinFree[i] = (int)(low + ((high - low) * scale)); 1079 } 1080 1081 if (minfree_abs >= 0) { 1082 for (int i = 0; i < mOomAdj.length; i++) { 1083 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] 1084 / mOomMinFree[mOomAdj.length - 1]); 1085 } 1086 } 1087 1088 if (minfree_adj != 0) { 1089 for (int i = 0; i < mOomAdj.length; i++) { 1090 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i] 1091 / mOomMinFree[mOomAdj.length - 1]); 1092 if (mOomMinFree[i] < 0) { 1093 mOomMinFree[i] = 0; 1094 } 1095 } 1096 } 1097 1098 // The maximum size we will restore a process from cached to background, when under 1099 // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead 1100 // before killing background processes. 1101 mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3; 1102 1103 // Ask the kernel to try to keep enough memory free to allocate 3 full 1104 // screen 32bpp buffers without entering direct reclaim. 1105 int reserve = displayWidth * displayHeight * 4 * 3 / 1024; 1106 int reserve_adj = Resources.getSystem().getInteger( 1107 com.android.internal.R.integer.config_extraFreeKbytesAdjust); 1108 int reserve_abs = Resources.getSystem().getInteger( 1109 com.android.internal.R.integer.config_extraFreeKbytesAbsolute); 1110 1111 if (reserve_abs >= 0) { 1112 reserve = reserve_abs; 1113 } 1114 1115 if (reserve_adj != 0) { 1116 reserve += reserve_adj; 1117 if (reserve < 0) { 1118 reserve = 0; 1119 } 1120 } 1121 1122 if (write) { 1123 ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1)); 1124 buf.putInt(LMK_TARGET); 1125 for (int i = 0; i < mOomAdj.length; i++) { 1126 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE); 1127 buf.putInt(mOomAdj[i]); 1128 } 1129 1130 writeLmkd(buf, null); 1131 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); 1132 mOomLevelsSet = true; 1133 } 1134 // GB: 2048,3072,4096,6144,7168,8192 1135 // HC: 8192,10240,12288,14336,16384,20480 1136 } 1137 computeEmptyProcessLimit(int totalProcessLimit)1138 public static int computeEmptyProcessLimit(int totalProcessLimit) { 1139 return totalProcessLimit/2; 1140 } 1141 buildOomTag(String prefix, String compactPrefix, String space, int val, int base, boolean compact)1142 private static String buildOomTag(String prefix, String compactPrefix, String space, int val, 1143 int base, boolean compact) { 1144 final int diff = val - base; 1145 if (diff == 0) { 1146 if (compact) { 1147 return compactPrefix; 1148 } 1149 if (space == null) return prefix; 1150 return prefix + space; 1151 } 1152 if (diff < 10) { 1153 return prefix + (compact ? "+" : "+ ") + Integer.toString(diff); 1154 } 1155 return prefix + "+" + Integer.toString(diff); 1156 } 1157 makeOomAdjString(int setAdj, boolean compact)1158 public static String makeOomAdjString(int setAdj, boolean compact) { 1159 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 1160 return buildOomTag("cch", "cch", " ", setAdj, 1161 ProcessList.CACHED_APP_MIN_ADJ, compact); 1162 } else if (setAdj >= ProcessList.SERVICE_B_ADJ) { 1163 return buildOomTag("svcb ", "svcb", null, setAdj, 1164 ProcessList.SERVICE_B_ADJ, compact); 1165 } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 1166 return buildOomTag("prev ", "prev", null, setAdj, 1167 ProcessList.PREVIOUS_APP_ADJ, compact); 1168 } else if (setAdj >= ProcessList.HOME_APP_ADJ) { 1169 return buildOomTag("home ", "home", null, setAdj, 1170 ProcessList.HOME_APP_ADJ, compact); 1171 } else if (setAdj >= ProcessList.SERVICE_ADJ) { 1172 return buildOomTag("svc ", "svc", null, setAdj, 1173 ProcessList.SERVICE_ADJ, compact); 1174 } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 1175 return buildOomTag("hvy ", "hvy", null, setAdj, 1176 ProcessList.HEAVY_WEIGHT_APP_ADJ, compact); 1177 } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) { 1178 return buildOomTag("bkup ", "bkup", null, setAdj, 1179 ProcessList.BACKUP_APP_ADJ, compact); 1180 } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { 1181 return buildOomTag("prcl ", "prcl", null, setAdj, 1182 ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact); 1183 } else if (setAdj >= ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ) { 1184 return buildOomTag("prcm ", "prcm", null, setAdj, 1185 ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ, compact); 1186 } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 1187 return buildOomTag("prcp ", "prcp", null, setAdj, 1188 ProcessList.PERCEPTIBLE_APP_ADJ, compact); 1189 } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) { 1190 return buildOomTag("vis", "vis", " ", setAdj, 1191 ProcessList.VISIBLE_APP_ADJ, compact); 1192 } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1193 return buildOomTag("fg ", "fg ", " ", setAdj, 1194 ProcessList.FOREGROUND_APP_ADJ, compact); 1195 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) { 1196 return buildOomTag("psvc ", "psvc", null, setAdj, 1197 ProcessList.PERSISTENT_SERVICE_ADJ, compact); 1198 } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 1199 return buildOomTag("pers ", "pers", null, setAdj, 1200 ProcessList.PERSISTENT_PROC_ADJ, compact); 1201 } else if (setAdj >= ProcessList.SYSTEM_ADJ) { 1202 return buildOomTag("sys ", "sys", null, setAdj, 1203 ProcessList.SYSTEM_ADJ, compact); 1204 } else if (setAdj >= ProcessList.NATIVE_ADJ) { 1205 return buildOomTag("ntv ", "ntv", null, setAdj, 1206 ProcessList.NATIVE_ADJ, compact); 1207 } else { 1208 return Integer.toString(setAdj); 1209 } 1210 } 1211 makeProcStateString(int curProcState)1212 public static String makeProcStateString(int curProcState) { 1213 return ActivityManager.procStateToString(curProcState); 1214 } 1215 makeProcStateProtoEnum(int curProcState)1216 public static int makeProcStateProtoEnum(int curProcState) { 1217 switch (curProcState) { 1218 case ActivityManager.PROCESS_STATE_PERSISTENT: 1219 return AppProtoEnums.PROCESS_STATE_PERSISTENT; 1220 case ActivityManager.PROCESS_STATE_PERSISTENT_UI: 1221 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI; 1222 case ActivityManager.PROCESS_STATE_TOP: 1223 return AppProtoEnums.PROCESS_STATE_TOP; 1224 case ActivityManager.PROCESS_STATE_BOUND_TOP: 1225 return AppProtoEnums.PROCESS_STATE_BOUND_TOP; 1226 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: 1227 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; 1228 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: 1229 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 1230 case ActivityManager.PROCESS_STATE_TOP_SLEEPING: 1231 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING; 1232 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 1233 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND; 1234 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 1235 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND; 1236 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: 1237 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND; 1238 case ActivityManager.PROCESS_STATE_BACKUP: 1239 return AppProtoEnums.PROCESS_STATE_BACKUP; 1240 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT: 1241 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT; 1242 case ActivityManager.PROCESS_STATE_SERVICE: 1243 return AppProtoEnums.PROCESS_STATE_SERVICE; 1244 case ActivityManager.PROCESS_STATE_RECEIVER: 1245 return AppProtoEnums.PROCESS_STATE_RECEIVER; 1246 case ActivityManager.PROCESS_STATE_HOME: 1247 return AppProtoEnums.PROCESS_STATE_HOME; 1248 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY: 1249 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY; 1250 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 1251 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY; 1252 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 1253 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 1254 case ActivityManager.PROCESS_STATE_CACHED_RECENT: 1255 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT; 1256 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 1257 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY; 1258 case ActivityManager.PROCESS_STATE_NONEXISTENT: 1259 return AppProtoEnums.PROCESS_STATE_NONEXISTENT; 1260 case ActivityManager.PROCESS_STATE_UNKNOWN: 1261 return AppProtoEnums.PROCESS_STATE_UNKNOWN; 1262 default: 1263 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO; 1264 } 1265 } 1266 appendRamKb(StringBuilder sb, long ramKb)1267 public static void appendRamKb(StringBuilder sb, long ramKb) { 1268 for (int j = 0, fact = 10; j < 6; j++, fact *= 10) { 1269 if (ramKb < fact) { 1270 sb.append(' '); 1271 } 1272 } 1273 sb.append(ramKb); 1274 } 1275 1276 // How long after a state change that it is safe to collect PSS without it being dirty. 1277 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000; 1278 1279 // The minimum time interval after a state change it is safe to collect PSS. 1280 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000; 1281 1282 // The maximum amount of time we want to go between PSS collections. 1283 public static final int PSS_MAX_INTERVAL = 60*60*1000; 1284 1285 // The minimum amount of time between successive PSS requests for *all* processes. 1286 public static final int PSS_ALL_INTERVAL = 20*60*1000; 1287 1288 // The amount of time until PSS when a persistent process first appears. 1289 private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000; 1290 1291 // The amount of time until PSS when a process first becomes top. 1292 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000; 1293 1294 // The amount of time until PSS when a process first goes into the background. 1295 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000; 1296 1297 // The amount of time until PSS when a process first becomes cached. 1298 private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000; 1299 1300 // The amount of time until PSS when an important process stays in the same state. 1301 private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000; 1302 1303 // The amount of time until PSS when the top process stays in the same state. 1304 private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000; 1305 1306 // The amount of time until PSS when an important process stays in the same state. 1307 private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000; 1308 1309 // The amount of time until PSS when a service process stays in the same state. 1310 private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000; 1311 1312 // The amount of time until PSS when a cached process stays in the same state. 1313 private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000; 1314 1315 // The amount of time until PSS when a persistent process first appears. 1316 private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000; 1317 1318 // The amount of time until PSS when a process first becomes top. 1319 private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000; 1320 1321 // The amount of time until PSS when a process first goes into the background. 1322 private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000; 1323 1324 // The amount of time until PSS when a process first becomes cached. 1325 private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000; 1326 1327 // The minimum time interval after a state change it is safe to collect PSS. 1328 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000; 1329 1330 // The amount of time during testing until PSS when a process first becomes top. 1331 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000; 1332 1333 // The amount of time during testing until PSS when a process first goes into the background. 1334 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000; 1335 1336 // The amount of time during testing until PSS when an important process stays in same state. 1337 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000; 1338 1339 // The amount of time during testing until PSS when a background process stays in same state. 1340 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000; 1341 1342 public static final int PROC_MEM_PERSISTENT = 0; 1343 public static final int PROC_MEM_TOP = 1; 1344 public static final int PROC_MEM_IMPORTANT = 2; 1345 public static final int PROC_MEM_SERVICE = 3; 1346 public static final int PROC_MEM_CACHED = 4; 1347 public static final int PROC_MEM_NUM = 5; 1348 1349 // Map large set of system process states to 1350 private static final int[] sProcStateToProcMem = new int[] { 1351 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT 1352 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI 1353 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP 1354 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 1355 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_BOUND_TOP 1356 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE 1357 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND 1358 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 1359 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND 1360 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP 1361 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE 1362 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER 1363 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING 1364 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT 1365 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME 1366 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY 1367 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY 1368 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT 1369 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT 1370 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY 1371 }; 1372 1373 private static final long[] sFirstAwakePssTimes = new long[] { 1374 PSS_FIRST_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1375 PSS_FIRST_TOP_INTERVAL, // PROC_MEM_TOP 1376 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 1377 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1378 PSS_FIRST_CACHED_INTERVAL, // PROC_MEM_CACHED 1379 }; 1380 1381 private static final long[] sSameAwakePssTimes = new long[] { 1382 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1383 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP 1384 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1385 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE 1386 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED 1387 }; 1388 1389 private static final long[] sFirstAsleepPssTimes = new long[] { 1390 PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1391 PSS_FIRST_ASLEEP_TOP_INTERVAL, // PROC_MEM_TOP 1392 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 1393 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1394 PSS_FIRST_ASLEEP_CACHED_INTERVAL, // PROC_MEM_CACHED 1395 }; 1396 1397 private static final long[] sSameAsleepPssTimes = new long[] { 1398 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1399 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP 1400 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1401 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE 1402 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED 1403 }; 1404 1405 private static final long[] sTestFirstPssTimes = new long[] { 1406 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_PERSISTENT 1407 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_TOP 1408 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 1409 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1410 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED 1411 }; 1412 1413 private static final long[] sTestSamePssTimes = new long[] { 1414 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_PERSISTENT 1415 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_TOP 1416 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1417 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1418 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_CACHED 1419 }; 1420 1421 public static final class ProcStateMemTracker { 1422 final int[] mHighestMem = new int[PROC_MEM_NUM]; 1423 final float[] mScalingFactor = new float[PROC_MEM_NUM]; 1424 int mTotalHighestMem = PROC_MEM_CACHED; 1425 1426 int mPendingMemState; 1427 int mPendingHighestMemState; 1428 float mPendingScalingFactor; 1429 ProcStateMemTracker()1430 public ProcStateMemTracker() { 1431 for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) { 1432 mHighestMem[i] = PROC_MEM_NUM; 1433 mScalingFactor[i] = 1.0f; 1434 } 1435 mPendingMemState = -1; 1436 } 1437 dumpLine(PrintWriter pw)1438 public void dumpLine(PrintWriter pw) { 1439 pw.print("best="); 1440 pw.print(mTotalHighestMem); 1441 pw.print(" ("); 1442 boolean needSep = false; 1443 for (int i = 0; i < PROC_MEM_NUM; i++) { 1444 if (mHighestMem[i] < PROC_MEM_NUM) { 1445 if (needSep) { 1446 pw.print(", "); 1447 needSep = false; 1448 } 1449 pw.print(i); 1450 pw.print("="); 1451 pw.print(mHighestMem[i]); 1452 pw.print(" "); 1453 pw.print(mScalingFactor[i]); 1454 pw.print("x"); 1455 needSep = true; 1456 } 1457 } 1458 pw.print(")"); 1459 if (mPendingMemState >= 0) { 1460 pw.print(" / pending state="); 1461 pw.print(mPendingMemState); 1462 pw.print(" highest="); 1463 pw.print(mPendingHighestMemState); 1464 pw.print(" "); 1465 pw.print(mPendingScalingFactor); 1466 pw.print("x"); 1467 } 1468 pw.println(); 1469 } 1470 } 1471 procStatesDifferForMem(int procState1, int procState2)1472 public static boolean procStatesDifferForMem(int procState1, int procState2) { 1473 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2]; 1474 } 1475 minTimeFromStateChange(boolean test)1476 public static long minTimeFromStateChange(boolean test) { 1477 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE; 1478 } 1479 computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, boolean sleeping, long now, long earliest)1480 public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, 1481 boolean sleeping, long now, long earliest) { 1482 boolean first; 1483 float scalingFactor; 1484 final int memState = sProcStateToProcMem[procState]; 1485 if (tracker != null) { 1486 final int highestMemState = memState < tracker.mTotalHighestMem 1487 ? memState : tracker.mTotalHighestMem; 1488 first = highestMemState < tracker.mHighestMem[memState]; 1489 tracker.mPendingMemState = memState; 1490 tracker.mPendingHighestMemState = highestMemState; 1491 if (first) { 1492 tracker.mPendingScalingFactor = scalingFactor = 1.0f; 1493 } else { 1494 scalingFactor = tracker.mScalingFactor[memState]; 1495 tracker.mPendingScalingFactor = scalingFactor * 1.5f; 1496 } 1497 } else { 1498 first = true; 1499 scalingFactor = 1.0f; 1500 } 1501 final long[] table = test 1502 ? (first 1503 ? sTestFirstPssTimes 1504 : sTestSamePssTimes) 1505 : (first 1506 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes) 1507 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes)); 1508 long delay = (long)(table[memState] * scalingFactor); 1509 if (delay > PSS_MAX_INTERVAL) { 1510 delay = PSS_MAX_INTERVAL; 1511 } 1512 return Math.max(now + delay, earliest); 1513 } 1514 1515 long getMemLevel(int adjustment) { 1516 for (int i = 0; i < mOomAdj.length; i++) { 1517 if (adjustment <= mOomAdj[i]) { 1518 return mOomMinFree[i] * 1024; 1519 } 1520 } 1521 return mOomMinFree[mOomAdj.length - 1] * 1024; 1522 } 1523 1524 /** 1525 * Return the maximum pss size in kb that we consider a process acceptable to 1526 * restore from its cached state for running in the background when RAM is low. 1527 */ 1528 long getCachedRestoreThresholdKb() { 1529 return mCachedRestoreLevel; 1530 } 1531 1532 AppStartInfoTracker getAppStartInfoTracker() { 1533 return mAppStartInfoTracker; 1534 } 1535 1536 /** 1537 * Set the out-of-memory badness adjustment for a process. 1538 * If {@code pid <= 0}, this method will be a no-op. 1539 * 1540 * @param pid The process identifier to set. 1541 * @param uid The uid of the app 1542 * @param amt Adjustment value -- lmkd allows -1000 to +1000 1543 * 1544 * {@hide} 1545 */ 1546 public static void setOomAdj(int pid, int uid, int amt) { 1547 // This indicates that the process is not started yet and so no need to proceed further. 1548 if (pid <= 0) { 1549 return; 1550 } 1551 if (amt == UNKNOWN_ADJ) 1552 return; 1553 1554 long start = SystemClock.elapsedRealtime(); 1555 ByteBuffer buf = ByteBuffer.allocate(4 * 4); 1556 buf.putInt(LMK_PROCPRIO); 1557 buf.putInt(pid); 1558 buf.putInt(uid); 1559 buf.putInt(amt); 1560 writeLmkd(buf, null); 1561 long now = SystemClock.elapsedRealtime(); 1562 if ((now-start) > 250) { 1563 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid 1564 + " = " + amt); 1565 } 1566 } 1567 1568 1569 // The max size for PROCS_PRIO cmd in LMKD 1570 private static final int MAX_PROCS_PRIO_PACKET_SIZE = 3; 1571 1572 // (4 bytes per field * 4 fields * 3 processes per batch) + 4 bytes for the LMKD cmd 1573 private static final int MAX_OOM_ADJ_BATCH_LENGTH = ((4 * 4) * MAX_PROCS_PRIO_PACKET_SIZE) + 4; 1574 1575 /** 1576 * Set the out-of-memory badness adjustment for a list of processes. 1577 * 1578 * @param apps App list to adjust their respective oom score. 1579 * 1580 * {@hide} 1581 */ 1582 public static void batchSetOomAdj(ArrayList<ProcessRecord> apps) { 1583 final int totalApps = apps.size(); 1584 if (totalApps == 0) { 1585 return; 1586 } 1587 1588 ByteBuffer buf = ByteBuffer.allocate(MAX_OOM_ADJ_BATCH_LENGTH); 1589 int total_procs_in_buf = 0; 1590 buf.putInt(LMK_PROCS_PRIO); 1591 for (int i = 0; i < totalApps; i++) { 1592 final int pid = apps.get(i).getPid(); 1593 final int amt = apps.get(i).mState.getCurAdj(); 1594 final int uid = apps.get(i).uid; 1595 if (pid <= 0 || amt == UNKNOWN_ADJ) continue; 1596 if (total_procs_in_buf >= MAX_PROCS_PRIO_PACKET_SIZE) { 1597 writeLmkd(buf, null); 1598 buf.clear(); 1599 total_procs_in_buf = 0; 1600 buf.allocate(MAX_OOM_ADJ_BATCH_LENGTH); 1601 buf.putInt(LMK_PROCS_PRIO); 1602 } 1603 buf.putInt(pid); 1604 buf.putInt(uid); 1605 buf.putInt(amt); 1606 buf.putInt(0); // Default proc type to PROC_TYPE_APP 1607 total_procs_in_buf++; 1608 } 1609 writeLmkd(buf, null); 1610 } 1611 1612 /* 1613 * {@hide} 1614 */ 1615 public static final void remove(int pid) { 1616 // This indicates that the process is not started yet and so no need to proceed further. 1617 if (pid <= 0) { 1618 return; 1619 } 1620 ByteBuffer buf = ByteBuffer.allocate(4 * 2); 1621 buf.putInt(LMK_PROCREMOVE); 1622 buf.putInt(pid); 1623 writeLmkd(buf, null); 1624 } 1625 1626 /* 1627 * {@hide} 1628 */ 1629 public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) { 1630 ByteBuffer buf = ByteBuffer.allocate(4 * 3); 1631 ByteBuffer repl = ByteBuffer.allocate(4 * 2); 1632 buf.putInt(LMK_GETKILLCNT); 1633 buf.putInt(min_oom_adj); 1634 buf.putInt(max_oom_adj); 1635 // indicate what we are waiting for 1636 repl.putInt(LMK_GETKILLCNT); 1637 repl.rewind(); 1638 if (writeLmkd(buf, repl) && repl.getInt() == LMK_GETKILLCNT) { 1639 return new Integer(repl.getInt()); 1640 } 1641 return null; 1642 } 1643 1644 public boolean onLmkdConnect(OutputStream ostream) { 1645 try { 1646 // Purge any previously registered pids 1647 ByteBuffer buf = ByteBuffer.allocate(4); 1648 buf.putInt(LMK_PROCPURGE); 1649 ostream.write(buf.array(), 0, buf.position()); 1650 if (mOomLevelsSet) { 1651 // Reset oom_adj levels 1652 buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1)); 1653 buf.putInt(LMK_TARGET); 1654 for (int i = 0; i < mOomAdj.length; i++) { 1655 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE); 1656 buf.putInt(mOomAdj[i]); 1657 } 1658 ostream.write(buf.array(), 0, buf.position()); 1659 } 1660 // Subscribe for kill event notifications 1661 buf = ByteBuffer.allocate(4 * 2); 1662 buf.putInt(LMK_SUBSCRIBE); 1663 buf.putInt(LMK_ASYNC_EVENT_KILL); 1664 ostream.write(buf.array(), 0, buf.position()); 1665 1666 // Subscribe for stats event notifications 1667 buf = ByteBuffer.allocate(4 * 2); 1668 buf.putInt(LMK_SUBSCRIBE); 1669 buf.putInt(LMK_ASYNC_EVENT_STAT); 1670 ostream.write(buf.array(), 0, buf.position()); 1671 } catch (IOException ex) { 1672 return false; 1673 } 1674 return true; 1675 } 1676 1677 /** 1678 * {@hide} 1679 */ 1680 public static void startPsiMonitoringAfterBoot() { 1681 ByteBuffer buf = ByteBuffer.allocate(4); 1682 buf.putInt(LMK_START_MONITORING); 1683 writeLmkd(buf, null); 1684 } 1685 1686 private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) { 1687 if (!sLmkdConnection.isConnected()) { 1688 // try to connect immediately and then keep retrying 1689 sKillHandler.sendMessage( 1690 sKillHandler.obtainMessage(KillHandler.LMKD_RECONNECT_MSG)); 1691 1692 // wait for connection retrying 3 times (up to 3 seconds) 1693 if (!sLmkdConnection.waitForConnection(3 * LMKD_RECONNECT_DELAY_MS)) { 1694 return false; 1695 } 1696 } 1697 1698 return sLmkdConnection.exchange(buf, repl); 1699 } 1700 1701 static void killProcessGroup(int uid, int pid) { 1702 /* static; one-time init here */ 1703 if (sKillHandler != null) { 1704 sKillHandler.sendMessage( 1705 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid)); 1706 } else { 1707 Slog.w(TAG, "Asked to kill process group before system bringup!"); 1708 Process.killProcessGroup(uid, pid); 1709 } 1710 } 1711 1712 @GuardedBy("mService") 1713 ProcessRecord getProcessRecordLocked(String processName, int uid) { 1714 if (uid == SYSTEM_UID) { 1715 // The system gets to run in any process. If there are multiple 1716 // processes with the same uid, just pick the first (this 1717 // should never happen). 1718 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 1719 if (procs == null) return null; 1720 final int procCount = procs.size(); 1721 for (int i = 0; i < procCount; i++) { 1722 final int procUid = procs.keyAt(i); 1723 if (!UserHandle.isCore(procUid) || !UserHandle.isSameUser(procUid, uid)) { 1724 // Don't use an app process or different user process for system component. 1725 continue; 1726 } 1727 return procs.valueAt(i); 1728 } 1729 } 1730 return mProcessNames.get(processName, uid); 1731 } 1732 1733 void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 1734 final long homeAppMem = getMemLevel(HOME_APP_ADJ); 1735 final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ); 1736 outInfo.advertisedMem = getAdvertisedMem(); 1737 outInfo.availMem = getFreeMemory(); 1738 outInfo.totalMem = getTotalMemory(); 1739 outInfo.threshold = homeAppMem; 1740 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 1741 outInfo.hiddenAppThreshold = cachedAppMem; 1742 outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ); 1743 outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ); 1744 outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ); 1745 } 1746 1747 @GuardedBy(anyOf = {"mService", "mProcLock"}) 1748 ProcessRecord findAppProcessLOSP(IBinder app, String reason) { 1749 final int NP = mProcessNames.getMap().size(); 1750 for (int ip = 0; ip < NP; ip++) { 1751 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 1752 final int NA = apps.size(); 1753 for (int ia = 0; ia < NA; ia++) { 1754 ProcessRecord p = apps.valueAt(ia); 1755 final IApplicationThread thread = p.getThread(); 1756 if (thread != null && thread.asBinder() == app) { 1757 return p; 1758 } 1759 } 1760 } 1761 1762 Slog.w(TAG, "Can't find mystery application for " + reason 1763 + " from pid=" + Binder.getCallingPid() 1764 + " uid=" + Binder.getCallingUid() + ": " + app); 1765 return null; 1766 } 1767 1768 private void checkSlow(long startTime, String where) { 1769 long now = SystemClock.uptimeMillis(); 1770 if ((now - startTime) > 50) { 1771 // If we are taking more than 50ms, log about it. 1772 Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where); 1773 } 1774 } 1775 1776 private int[] computeGidsForProcess(int mountExternal, int uid, int[] permGids, 1777 boolean externalStorageAccess) { 1778 ArrayList<Integer> gidList = new ArrayList<>(permGids.length + 5); 1779 1780 final int sharedAppGid = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 1781 final int cacheAppGid = UserHandle.getCacheAppGid(UserHandle.getAppId(uid)); 1782 final int userGid = UserHandle.getUserGid(UserHandle.getUserId(uid)); 1783 1784 // Add shared application and profile GIDs so applications can share some 1785 // resources like shared libraries and access user-wide resources 1786 for (int permGid : permGids) { 1787 gidList.add(permGid); 1788 } 1789 if (sharedAppGid != UserHandle.ERR_GID) { 1790 gidList.add(sharedAppGid); 1791 } 1792 if (cacheAppGid != UserHandle.ERR_GID) { 1793 gidList.add(cacheAppGid); 1794 } 1795 if (userGid != UserHandle.ERR_GID) { 1796 gidList.add(userGid); 1797 } 1798 if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE 1799 || mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) { 1800 // For DownloadProviders and MTP: To grant access to /sdcard/Android/ 1801 // And a special case for the FUSE daemon since it runs an MTP server and should have 1802 // access to Android/ 1803 // Note that we must add in the user id, because sdcardfs synthesizes this permission 1804 // based on the user 1805 gidList.add(UserHandle.getUid(UserHandle.getUserId(uid), Process.SDCARD_RW_GID)); 1806 1807 // For devices without sdcardfs, these GIDs are needed instead; note that we 1808 // consciously don't add the user_id in the GID, since these apps are anyway 1809 // isolated to only their own user 1810 gidList.add(Process.EXT_DATA_RW_GID); 1811 gidList.add(Process.EXT_OBB_RW_GID); 1812 } 1813 if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) { 1814 // For devices without sdcardfs, this GID is needed to allow installers access to OBBs 1815 gidList.add(Process.EXT_OBB_RW_GID); 1816 } 1817 if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) { 1818 // For the FUSE daemon: To grant access to the lower filesystem. 1819 // EmulatedVolumes: /data/media and /mnt/expand/<volume>/data/media 1820 // PublicVolumes: /mnt/media_rw/<volume> 1821 gidList.add(Process.MEDIA_RW_GID); 1822 } 1823 if (externalStorageAccess) { 1824 // Apps with MANAGE_EXTERNAL_STORAGE PERMISSION need the external_storage gid to access 1825 // USB OTG (unreliable) volumes on /mnt/media_rw/<vol name> 1826 gidList.add(Process.EXTERNAL_STORAGE_GID); 1827 } 1828 1829 int[] gidArray = new int[gidList.size()]; 1830 for (int i = 0; i < gidArray.length; i++) { 1831 gidArray[i] = gidList.get(i); 1832 } 1833 return gidArray; 1834 } 1835 1836 /** 1837 * @return {@code true} if process start is successful, false otherwise. 1838 */ 1839 @GuardedBy("mService") 1840 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, 1841 int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks, 1842 String abiOverride) { 1843 if (app.isPendingStart()) { 1844 return true; 1845 } 1846 final long startUptime = SystemClock.uptimeMillis(); 1847 final long startElapsedTime = SystemClock.elapsedRealtime(); 1848 if (app.getPid() > 0 && app.getPid() != ActivityManagerService.MY_PID) { 1849 checkSlow(startUptime, "startProcess: removing from pids map"); 1850 mService.removePidLocked(app.getPid(), app); 1851 app.setBindMountPending(false); 1852 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1853 checkSlow(startUptime, "startProcess: done removing from pids map"); 1854 app.setPid(0); 1855 app.setStartSeq(0); 1856 } 1857 // Clear any residual death recipient link as the ProcessRecord could be reused. 1858 app.unlinkDeathRecipient(); 1859 app.setDyingPid(0); 1860 1861 if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v( 1862 TAG_PROCESSES, 1863 "startProcessLocked removing on hold: " + app); 1864 mService.mProcessesOnHold.remove(app); 1865 1866 checkSlow(startUptime, "startProcess: starting to update cpu stats"); 1867 mService.updateCpuStats(); 1868 checkSlow(startUptime, "startProcess: done updating cpu stats"); 1869 1870 try { 1871 final int userId = UserHandle.getUserId(app.uid); 1872 try { 1873 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId); 1874 } catch (RemoteException e) { 1875 throw e.rethrowAsRuntimeException(); 1876 } 1877 1878 int uid = app.uid; 1879 int[] gids = null; 1880 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1881 boolean externalStorageAccess = false; 1882 if (!app.isolated) { 1883 int[] permGids = null; 1884 try { 1885 checkSlow(startUptime, "startProcess: getting gids from package manager"); 1886 final IPackageManager pm = AppGlobals.getPackageManager(); 1887 permGids = pm.getPackageGids(app.info.packageName, 1888 MATCH_DIRECT_BOOT_AUTO, app.userId); 1889 StorageManagerInternal storageManagerInternal = LocalServices.getService( 1890 StorageManagerInternal.class); 1891 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, 1892 app.info.packageName); 1893 externalStorageAccess = storageManagerInternal.hasExternalStorageAccess(uid, 1894 app.info.packageName); 1895 if (mService.isAppFreezerExemptInstPkg() 1896 && pm.checkPermission(Manifest.permission.INSTALL_PACKAGES, 1897 app.info.packageName, userId) 1898 == PackageManager.PERMISSION_GRANTED) { 1899 Slog.i(TAG, app.info.packageName + " is exempt from freezer"); 1900 app.mOptRecord.setFreezeExempt(true); 1901 } 1902 } catch (RemoteException e) { 1903 throw e.rethrowAsRuntimeException(); 1904 } 1905 1906 // Remove any gids needed if the process has been denied permissions. 1907 // NOTE: eventually we should probably have the package manager pre-compute 1908 // this for us? 1909 if (app.processInfo != null && app.processInfo.deniedPermissions != null) { 1910 for (int i = app.processInfo.deniedPermissions.size() - 1; i >= 0; i--) { 1911 int[] denyGids = mService.mPackageManagerInt.getPermissionGids( 1912 app.processInfo.deniedPermissions.valueAt(i), app.userId); 1913 if (denyGids != null) { 1914 for (int gid : denyGids) { 1915 permGids = ArrayUtils.removeInt(permGids, gid); 1916 } 1917 } 1918 } 1919 } 1920 1921 gids = computeGidsForProcess(mountExternal, uid, permGids, externalStorageAccess); 1922 } 1923 app.setMountMode(mountExternal); 1924 checkSlow(startUptime, "startProcess: building args"); 1925 if (app.getWindowProcessController().isFactoryTestProcess()) { 1926 uid = 0; 1927 } 1928 int runtimeFlags = 0; 1929 1930 boolean debuggableFlag = (app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 1931 boolean isProfileableByShell = app.info.isProfileableByShell(); 1932 boolean isProfileable = app.info.isProfileable(); 1933 1934 if (app.isSdkSandbox) { 1935 ApplicationInfo clientInfo = app.getClientInfoForSdkSandbox(); 1936 if (clientInfo != null) { 1937 debuggableFlag |= (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 1938 isProfileableByShell |= clientInfo.isProfileableByShell(); 1939 isProfileable |= clientInfo.isProfileable(); 1940 } 1941 } 1942 1943 if (debuggableFlag) { 1944 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP; 1945 runtimeFlags |= Zygote.DEBUG_ENABLE_PTRACE; 1946 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE; 1947 // Also turn on CheckJNI for debuggable apps. It's quite 1948 // awkward to turn on otherwise. 1949 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1950 1951 // Check if the developer does not want ART verification 1952 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(), 1953 android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) { 1954 runtimeFlags |= Zygote.DISABLE_VERIFIER; 1955 Slog.w(TAG_PROCESSES, app + ": ART verification disabled"); 1956 } 1957 } 1958 // Run the app in safe mode if its manifest requests so or the 1959 // system is booted in safe mode. 1960 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) { 1961 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1962 } 1963 if (isProfileableByShell) { 1964 runtimeFlags |= Zygote.PROFILE_FROM_SHELL; 1965 } 1966 if (isProfileable) { 1967 runtimeFlags |= Zygote.PROFILEABLE; 1968 } 1969 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1970 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1971 } 1972 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info"); 1973 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) { 1974 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; 1975 } 1976 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo"); 1977 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) { 1978 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO; 1979 } 1980 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 1981 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 1982 } 1983 if ("1".equals(SystemProperties.get("debug.assert"))) { 1984 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1985 } 1986 if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) { 1987 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER; 1988 } 1989 if (mService.mNativeDebuggingApp != null 1990 && mService.mNativeDebuggingApp.equals(app.processName)) { 1991 // Enable all debug flags required by the native debugger. 1992 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything 1993 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info 1994 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations 1995 mService.mNativeDebuggingApp = null; 1996 } 1997 1998 if (app.info.isEmbeddedDexUsed() 1999 || (app.processInfo != null && app.processInfo.useEmbeddedDex)) { 2000 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; 2001 } 2002 2003 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) { 2004 app.info.maybeUpdateHiddenApiEnforcementPolicy( 2005 mService.mHiddenApiBlacklist.getPolicy()); 2006 @ApplicationInfo.HiddenApiEnforcementPolicy int policy = 2007 app.info.getHiddenApiEnforcementPolicy(); 2008 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT); 2009 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) { 2010 throw new IllegalStateException("Invalid API policy: " + policy); 2011 } 2012 runtimeFlags |= policyBits; 2013 2014 if (disableTestApiChecks) { 2015 runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY; 2016 } 2017 } 2018 2019 String useAppImageCache = SystemProperties.get( 2020 PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, ""); 2021 // Property defaults to true currently. 2022 if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) { 2023 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE; 2024 } 2025 2026 if (appCompatOption16kb()) { 2027 boolean is16KbDevice = Os.sysconf(OsConstants._SC_PAGESIZE) == 16384; 2028 if (is16KbDevice 2029 && mService.mContext 2030 .getPackageManager() 2031 .isPageSizeCompatEnabled(app.info.packageName)) { 2032 runtimeFlags |= Zygote.ENABLE_PAGE_SIZE_APP_COMPAT; 2033 } 2034 } 2035 2036 String invokeWith = null; 2037 if (debuggableFlag) { 2038 // Debuggable apps may include a wrapper script with their library directory. 2039 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; 2040 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 2041 try { 2042 if (new File(wrapperFileName).exists()) { 2043 invokeWith = "/system/bin/logwrapper " + wrapperFileName; 2044 } 2045 } finally { 2046 StrictMode.setThreadPolicy(oldPolicy); 2047 } 2048 } 2049 2050 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2051 if (requiredAbi == null) { 2052 requiredAbi = Build.SUPPORTED_ABIS[0]; 2053 } 2054 2055 String instructionSet = null; 2056 if (app.info.primaryCpuAbi != null) { 2057 // If ABI override is specified, use the isa derived from the value of ABI override. 2058 // Otherwise, use the isa derived from primary ABI 2059 instructionSet = VMRuntime.getInstructionSet(requiredAbi); 2060 } 2061 2062 app.setGids(gids); 2063 app.setRequiredAbi(requiredAbi); 2064 app.setInstructionSet(instructionSet); 2065 2066 // If this was an external service, the package name and uid in the passed in 2067 // ApplicationInfo have been changed to match those of the calling package; 2068 // that will incorrectly apply compat feature overrides for the calling package instead 2069 // of the defining one. 2070 ApplicationInfo definingAppInfo; 2071 if (hostingRecord.getDefiningPackageName() != null) { 2072 definingAppInfo = new ApplicationInfo(app.info); 2073 definingAppInfo.packageName = hostingRecord.getDefiningPackageName(); 2074 definingAppInfo.uid = uid; 2075 } else { 2076 definingAppInfo = app.info; 2077 } 2078 2079 runtimeFlags |= Zygote.getMemorySafetyRuntimeFlags( 2080 definingAppInfo, app.processInfo, instructionSet, mPlatformCompat); 2081 2082 // the per-user SELinux context must be set 2083 if (TextUtils.isEmpty(app.info.seInfoUser)) { 2084 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined", 2085 new IllegalStateException("SELinux tag not defined for " 2086 + app.info.packageName + " (uid " + app.uid + ")")); 2087 } 2088 2089 String seInfo = updateSeInfo(app); 2090 2091 // Start the process. It will either succeed and return a result containing 2092 // the PID of the new process, or else throw a RuntimeException. 2093 final String entryPoint = "android.app.ActivityThread"; 2094 2095 return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, 2096 runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi, 2097 instructionSet, invokeWith, startUptime, startElapsedTime); 2098 } catch (RuntimeException e) { 2099 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e); 2100 2101 // Something went very wrong while trying to start this process; one 2102 // common case is when the package is frozen due to an active 2103 // upgrade. To recover, clean up any active bookkeeping related to 2104 // starting this process. (We already invoked this method once when 2105 // the package was initially frozen through KILL_APPLICATION_MSG, so 2106 // it doesn't hurt to use it again.) 2107 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), 2108 false, false, true, false, false, false, app.userId, "start failure"); 2109 return false; 2110 } 2111 } 2112 2113 @VisibleForTesting 2114 @GuardedBy("mService") 2115 String updateSeInfo(ProcessRecord app) { 2116 String extraInfo = ""; 2117 // By the time the first the SDK sandbox process is started, device config service 2118 // should be available. If both Next and Audit are enabled, Next takes precedence. 2119 if (app.isSdkSandbox) { 2120 if (getProcessListSettingsListener().applySdkSandboxRestrictionsNext()) { 2121 extraInfo = APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS; 2122 } else if (selinuxSdkSandboxAudit() 2123 && getProcessListSettingsListener().applySdkSandboxRestrictionsAudit()) { 2124 extraInfo = APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS; 2125 } 2126 } 2127 2128 // The order of selectors in seInfo matters, the string is terminated by the word complete. 2129 if (selinuxInputSelector()) { 2130 return app.info.seInfo + extraInfo + TextUtils.emptyIfNull(app.info.seInfoUser); 2131 } else { 2132 return app.info.seInfo 2133 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser) 2134 + extraInfo; 2135 } 2136 } 2137 2138 @GuardedBy("mService") 2139 boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app, 2140 int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal, 2141 String seInfo, String requiredAbi, String instructionSet, String invokeWith, 2142 long startUptime, long startElapsedTime) { 2143 app.setPendingStart(true); 2144 app.setRemoved(false); 2145 synchronized (mProcLock) { 2146 app.setKilledByAm(false); 2147 app.setKilled(false); 2148 } 2149 if (app.getStartSeq() != 0) { 2150 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName 2151 + " with non-zero startSeq:" + app.getStartSeq()); 2152 } 2153 if (app.getPid() != 0) { 2154 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName 2155 + " with non-zero pid:" + app.getPid()); 2156 } 2157 app.setDisabledCompatChanges(null); 2158 app.setLoggableCompatChanges(null); 2159 if (mPlatformCompat != null) { 2160 app.setDisabledCompatChanges(mPlatformCompat.getDisabledChanges(app.info)); 2161 app.setLoggableCompatChanges(mPlatformCompat.getLoggableChanges(app.info)); 2162 } 2163 final long startSeq = ++mProcStartSeqCounter; 2164 app.setStartSeq(startSeq); 2165 app.setStartParams(uid, hostingRecord, seInfo, startUptime, startElapsedTime); 2166 app.setUsingWrapper(invokeWith != null 2167 || Zygote.getWrapProperty(app.processName) != null); 2168 mPendingStarts.put(startSeq, app); 2169 2170 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { 2171 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES, 2172 "Posting procStart msg for " + app.toShortString()); 2173 mService.mProcStartHandler.post(() -> handleProcessStart( 2174 app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal, 2175 requiredAbi, instructionSet, invokeWith, startSeq)); 2176 return true; 2177 } else { 2178 try { 2179 final Process.ProcessStartResult startResult = startProcess(hostingRecord, 2180 entryPoint, app, 2181 uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, 2182 requiredAbi, instructionSet, invokeWith, startUptime); 2183 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, 2184 startSeq, false); 2185 } catch (RuntimeException e) { 2186 Slog.e(ActivityManagerService.TAG, "Failure starting process " 2187 + app.processName, e); 2188 app.setPendingStart(false); 2189 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), 2190 false, false, true, false, false, false, app.userId, "start failure"); 2191 } 2192 return app.getPid() > 0; 2193 } 2194 } 2195 2196 /** 2197 * Main handler routine to start the given process from the ProcStartHandler. 2198 * 2199 * <p>Note: this function doesn't hold the global AM lock intentionally.</p> 2200 */ 2201 private void handleProcessStart(final ProcessRecord app, final String entryPoint, 2202 final int[] gids, final int runtimeFlags, int zygotePolicyFlags, 2203 final int mountExternal, final String requiredAbi, final String instructionSet, 2204 final String invokeWith, final long startSeq) { 2205 final Runnable startRunnable = () -> { 2206 try { 2207 final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(), 2208 entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags, 2209 mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith, 2210 app.getStartTime()); 2211 2212 synchronized (mService) { 2213 handleProcessStartedLocked(app, startResult, startSeq); 2214 } 2215 } catch (RuntimeException e) { 2216 synchronized (mService) { 2217 Slog.e(ActivityManagerService.TAG, "Failure starting process " 2218 + app.processName, e); 2219 mPendingStarts.remove(startSeq); 2220 app.setPendingStart(false); 2221 mService.forceStopPackageLocked(app.info.packageName, 2222 UserHandle.getAppId(app.uid), 2223 false, false, true, false, false, false, app.userId, "start failure"); 2224 app.doEarlyCleanupIfNecessaryLocked(); 2225 } 2226 } 2227 }; 2228 // Use local reference since we are not using locks here 2229 final ProcessRecord predecessor = app.mPredecessor; 2230 if (predecessor != null && predecessor.getDyingPid() > 0) { 2231 handleProcessStartWithPredecessor(predecessor, startRunnable); 2232 } else { 2233 // Kick off the process start for real. 2234 startRunnable.run(); 2235 } 2236 } 2237 2238 /** 2239 * Handle the case where the given process is killed but still not gone, but we'd need to start 2240 * the new instance of it. 2241 */ 2242 private void handleProcessStartWithPredecessor(final ProcessRecord predecessor, 2243 final Runnable successorStartRunnable) { 2244 // If there is a preceding instance of the process, wait for its death with a timeout. 2245 if (predecessor.mSuccessorStartRunnable != null) { 2246 // It's been watched already, this shouldn't happen. 2247 Slog.wtf(TAG, "We've been watching for the death of " + predecessor); 2248 return; 2249 } 2250 predecessor.mSuccessorStartRunnable = successorStartRunnable; 2251 mService.mProcStartHandler.sendMessageDelayed(mService.mProcStartHandler.obtainMessage( 2252 ProcStartHandler.MSG_PROCESS_KILL_TIMEOUT, predecessor), 2253 mService.mConstants.mProcessKillTimeoutMs); 2254 } 2255 2256 static final class ProcStartHandler extends Handler { 2257 static final int MSG_PROCESS_DIED = 1; 2258 static final int MSG_PROCESS_KILL_TIMEOUT = 2; 2259 2260 private final ActivityManagerService mService; 2261 2262 ProcStartHandler(ActivityManagerService service, Looper looper) { 2263 super(looper); 2264 mService = service; 2265 } 2266 2267 @Override 2268 public void handleMessage(Message msg) { 2269 switch (msg.what) { 2270 case MSG_PROCESS_DIED: 2271 mService.mProcessList.handlePredecessorProcDied((ProcessRecord) msg.obj); 2272 break; 2273 case MSG_PROCESS_KILL_TIMEOUT: 2274 synchronized (mService) { 2275 mService.handleProcessStartOrKillTimeoutLocked((ProcessRecord) msg.obj, 2276 /* isKillTimeout */ true); 2277 } 2278 break; 2279 } 2280 } 2281 } 2282 2283 /** 2284 * Called when the dying process we're waiting for is really gone. 2285 */ 2286 private void handlePredecessorProcDied(ProcessRecord app) { 2287 if (DEBUG_PROCESSES) { 2288 Slog.i(TAG, app.toString() + " is really gone now"); 2289 } 2290 2291 // Now kick off the subsequent process start if there is any. 2292 final Runnable start = app.mSuccessorStartRunnable; 2293 if (start != null) { 2294 app.mSuccessorStartRunnable = null; 2295 start.run(); 2296 } 2297 } 2298 2299 @GuardedBy("mService") 2300 public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) { 2301 final ApplicationInfo appInfo = appZygote.getAppInfo(); 2302 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); 2303 if (zygoteProcesses != null && (force || zygoteProcesses.size() == 0)) { 2304 // Only remove if no longer in use now, or forced kill 2305 mAppZygotes.remove(appInfo.processName, appInfo.uid); 2306 mAppZygoteProcesses.remove(appZygote); 2307 mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo); 2308 appZygote.stopZygote(); 2309 } 2310 } 2311 2312 @GuardedBy("mService") 2313 private void removeProcessFromAppZygoteLocked(final ProcessRecord app) { 2314 // Free the isolated uid for this process 2315 final IsolatedUidRange appUidRange = 2316 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName, 2317 app.getHostingRecord().getDefiningUid()); 2318 if (appUidRange != null) { 2319 appUidRange.freeIsolatedUidLocked(app.uid); 2320 } 2321 2322 final AppZygote appZygote = mAppZygotes.get(app.info.processName, 2323 app.getHostingRecord().getDefiningUid()); 2324 if (appZygote != null) { 2325 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); 2326 zygoteProcesses.remove(app); 2327 if (zygoteProcesses.size() == 0) { 2328 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG); 2329 if (app.isRemoved()) { 2330 // If we stopped this process because the package hosting it was removed, 2331 // there's no point in delaying the app zygote kill. 2332 killAppZygoteIfNeededLocked(appZygote, false /* force */); 2333 } else { 2334 Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG); 2335 msg.obj = appZygote; 2336 mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS); 2337 } 2338 } 2339 } 2340 } 2341 2342 private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) { 2343 synchronized (mService) { 2344 // The UID for the app zygote should be the UID of the application hosting 2345 // the service. 2346 final int uid = app.getHostingRecord().getDefiningUid(); 2347 AppZygote appZygote = mAppZygotes.get(app.info.processName, uid); 2348 final ArrayList<ProcessRecord> zygoteProcessList; 2349 if (appZygote == null) { 2350 if (DEBUG_PROCESSES) { 2351 Slog.d(TAG_PROCESSES, "Creating new app zygote."); 2352 } 2353 final IsolatedUidRange uidRange = 2354 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked( 2355 app.info.processName, app.getHostingRecord().getDefiningUid()); 2356 final int userId = UserHandle.getUserId(uid); 2357 // Create the app-zygote and provide it with the UID-range it's allowed 2358 // to setresuid/setresgid to. 2359 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid); 2360 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid); 2361 ApplicationInfo appInfo = new ApplicationInfo(app.info); 2362 // If this was an external service, the package name and uid in the passed in 2363 // ApplicationInfo have been changed to match those of the calling package; 2364 // that is not what we want for the AppZygote though, which needs to have the 2365 // packageName and uid of the defining application. This is because the 2366 // preloading only makes sense in the context of the defining application, 2367 // not the calling one. 2368 appInfo.packageName = app.getHostingRecord().getDefiningPackageName(); 2369 appInfo.uid = uid; 2370 appZygote = new AppZygote(appInfo, app.processInfo, uid, firstUid, lastUid); 2371 mAppZygotes.put(app.info.processName, uid, appZygote); 2372 zygoteProcessList = new ArrayList<ProcessRecord>(); 2373 mAppZygoteProcesses.put(appZygote, zygoteProcessList); 2374 } else { 2375 if (DEBUG_PROCESSES) { 2376 Slog.d(TAG_PROCESSES, "Reusing existing app zygote."); 2377 } 2378 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote); 2379 zygoteProcessList = mAppZygoteProcesses.get(appZygote); 2380 } 2381 // Note that we already add the app to mAppZygoteProcesses here; 2382 // this is so that another thread can't come in and kill the zygote 2383 // before we've even tried to start the process. If the process launch 2384 // goes wrong, we'll clean this up in removeProcessNameLocked() 2385 zygoteProcessList.add(app); 2386 2387 return appZygote; 2388 } 2389 } 2390 2391 private Map<String, Pair<String, Long>> getPackageAppDataInfoMap(PackageManagerInternal pmInt, 2392 String[] packages, int uid) { 2393 Map<String, Pair<String, Long>> result = new ArrayMap<>(packages.length); 2394 int userId = UserHandle.getUserId(uid); 2395 for (String packageName : packages) { 2396 final PackageStateInternal packageState = pmInt.getPackageStateInternal(packageName); 2397 if (packageState == null) { 2398 Slog.w(TAG, "Unknown package:" + packageName); 2399 continue; 2400 } 2401 String volumeUuid = packageState.getVolumeUuid(); 2402 long inode = packageState.getUserStateOrDefault(userId).getCeDataInode(); 2403 if (inode <= 0) { 2404 Slog.w(TAG, packageName + " inode == 0 or app uninstalled with keep-data"); 2405 return null; 2406 } 2407 result.put(packageName, Pair.create(volumeUuid, inode)); 2408 } 2409 2410 return result; 2411 } 2412 2413 private boolean needsStorageDataIsolation(StorageManagerInternal storageManagerInternal, 2414 ProcessRecord app) { 2415 final int mountMode = app.getMountMode(); 2416 return mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid) 2417 && !storageManagerInternal.isExternalStorageService(app.uid) 2418 // Special mounting mode doesn't need to have data isolation as they won't 2419 // access /mnt/user anyway. 2420 && mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE 2421 && mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH 2422 && mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER 2423 && mountMode != Zygote.MOUNT_EXTERNAL_NONE; 2424 } 2425 2426 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint, 2427 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, 2428 int mountExternal, String seInfo, String requiredAbi, String instructionSet, 2429 String invokeWith, long startTime) { 2430 try { 2431 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + 2432 app.processName); 2433 checkSlow(startTime, "startProcess: asking zygote to start proc"); 2434 final boolean isTopApp = hostingRecord.isTopApp(); 2435 if (isTopApp) { 2436 // Use has-foreground-activities as a temporary hint so the current scheduling 2437 // group won't be lost when the process is attaching. The actual state will be 2438 // refreshed when computing oom-adj. 2439 app.mState.setHasForegroundActivities(true); 2440 } 2441 2442 Map<String, Pair<String, Long>> pkgDataInfoMap; 2443 Map<String, Pair<String, Long>> allowlistedAppDataInfoMap; 2444 boolean bindMountAppStorageDirs = false; 2445 boolean bindMountAppsData = mAppDataIsolationEnabled 2446 && (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid) 2447 || app.isSdkSandbox) 2448 && mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info); 2449 2450 // Get all packages belongs to the same shared uid. sharedPackages is empty array 2451 // if it doesn't have shared uid. 2452 final PackageManagerInternal pmInt = mService.getPackageManagerInternal(); 2453 2454 // In the case of sdk sandbox, the pkgDataInfoMap of only the client app associated with 2455 // the sandbox is required to handle app visibility restrictions for the sandbox. 2456 final String[] targetPackagesList; 2457 if (app.isSdkSandbox) { 2458 targetPackagesList = new String[]{app.sdkSandboxClientAppPackage}; 2459 } else { 2460 final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage( 2461 app.info.packageName, app.userId); 2462 targetPackagesList = sharedPackages.length == 0 2463 ? new String[]{app.info.packageName} : sharedPackages; 2464 } 2465 2466 final boolean hasAppStorage = hasAppStorage(pmInt, app.info.packageName); 2467 2468 pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, targetPackagesList, uid); 2469 if (pkgDataInfoMap == null) { 2470 // TODO(b/152760674): Handle inode == 0 case properly, now we just give it a 2471 // tmp free pass. 2472 bindMountAppsData = false; 2473 } 2474 2475 // Remove all packages in pkgDataInfoMap from mAppDataIsolationAllowlistedApps, so 2476 // it won't be mounted twice. 2477 final Set<String> allowlistedApps = new ArraySet<>(mAppDataIsolationAllowlistedApps); 2478 for (String pkg : targetPackagesList) { 2479 allowlistedApps.remove(pkg); 2480 } 2481 2482 allowlistedAppDataInfoMap = getPackageAppDataInfoMap(pmInt, 2483 allowlistedApps.toArray(new String[0]), uid); 2484 if (allowlistedAppDataInfoMap == null) { 2485 // TODO(b/152760674): Handle inode == 0 case properly, now we just give it a 2486 // tmp free pass. 2487 bindMountAppsData = false; 2488 } 2489 2490 if (!hasAppStorage && !app.isSdkSandbox) { 2491 bindMountAppsData = false; 2492 pkgDataInfoMap = null; 2493 allowlistedAppDataInfoMap = null; 2494 } 2495 2496 int userId = UserHandle.getUserId(uid); 2497 StorageManagerInternal storageManagerInternal = LocalServices.getService( 2498 StorageManagerInternal.class); 2499 if (needsStorageDataIsolation(storageManagerInternal, app)) { 2500 // We will run prepareStorageDirs() after we trigger zygote fork, so it won't 2501 // slow down app starting speed as those dirs might not be cached. 2502 if (pkgDataInfoMap != null && storageManagerInternal.isFuseMounted(userId)) { 2503 bindMountAppStorageDirs = true; 2504 } else { 2505 // Fuse is not mounted or inode == 0, 2506 // so we won't mount it in zygote, but resume the mount after unlocking device. 2507 app.setBindMountPending(true); 2508 bindMountAppStorageDirs = false; 2509 } 2510 } 2511 2512 // If it's an isolated process, it should not even mount its own app data directories, 2513 // since it has no access to them anyway. 2514 if (app.isolated) { 2515 pkgDataInfoMap = null; 2516 allowlistedAppDataInfoMap = null; 2517 } 2518 2519 boolean bindOverrideSysprops = false; 2520 String[] syspropOverridePkgNames = DeviceConfig.getString( 2521 DeviceConfig.NAMESPACE_APP_COMPAT, 2522 "appcompat_sysprop_override_pkgs", "").split(","); 2523 String[] pkgs = app.getPackageList(); 2524 for (int i = 0; i < pkgs.length; i++) { 2525 if (ArrayUtils.contains(syspropOverridePkgNames, pkgs[i])) { 2526 bindOverrideSysprops = true; 2527 break; 2528 } 2529 } 2530 2531 AppStateTracker ast = mService.mServices.mAppStateTracker; 2532 if (ast != null) { 2533 final boolean inBgRestricted = ast.isAppBackgroundRestricted( 2534 app.info.uid, app.info.packageName); 2535 if (inBgRestricted) { 2536 synchronized (mService) { 2537 mAppsInBackgroundRestricted.add(app); 2538 } 2539 } 2540 app.mState.setBackgroundRestricted(inBgRestricted); 2541 } 2542 2543 final Process.ProcessStartResult startResult; 2544 boolean regularZygote = false; 2545 app.mProcessGroupCreated = false; 2546 app.mSkipProcessGroupCreation = false; 2547 long forkTimeNs = SystemClock.uptimeNanos(); 2548 if (hostingRecord.usesWebviewZygote()) { 2549 startResult = startWebView(entryPoint, 2550 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 2551 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2552 app.info.dataDir, null, app.info.packageName, 2553 app.getDisabledCompatChanges(), 2554 new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); 2555 } else if (hostingRecord.usesAppZygote()) { 2556 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); 2557 2558 // We can't isolate app data and storage data as parent zygote already did that. 2559 startResult = appZygote.startProcess(entryPoint, 2560 app.processName, uid, gids, runtimeFlags, mountExternal, 2561 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2562 app.info.dataDir, app.info.packageName, isTopApp, 2563 app.getDisabledCompatChanges(), pkgDataInfoMap, 2564 allowlistedAppDataInfoMap, 2565 new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); 2566 } else { 2567 regularZygote = true; 2568 startResult = Process.start(entryPoint, 2569 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 2570 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2571 app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags, 2572 isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap, 2573 allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs, 2574 bindOverrideSysprops, 2575 new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); 2576 // By now the process group should have been created by zygote. 2577 app.mProcessGroupCreated = true; 2578 } 2579 2580 if (android.app.Flags.appStartInfoTimestamps()) { 2581 mAppStartInfoTracker.addTimestampToStart(app, forkTimeNs, 2582 ApplicationStartInfo.START_TIMESTAMP_FORK); 2583 } 2584 2585 if (!regularZygote) { 2586 // webview and app zygote don't have the permission to create the nodes 2587 synchronized (app) { 2588 if (!app.mSkipProcessGroupCreation) { 2589 // If we're not told to skip the process group creation, go create it. 2590 final int res = Process.createProcessGroup(uid, startResult.pid); 2591 if (res < 0) { 2592 if (res == -OsConstants.ESRCH) { 2593 Slog.e(ActivityManagerService.TAG, 2594 "Unable to create process group for " 2595 + app.processName + " (" + startResult.pid + ")"); 2596 } else { 2597 throw new AssertionError("Unable to create process group for " 2598 + app.processName + " (" + startResult.pid + ")"); 2599 } 2600 } else { 2601 app.mProcessGroupCreated = true; 2602 } 2603 } 2604 } 2605 } 2606 2607 // This runs after Process.start() as this method may block app process starting time 2608 // if dir is not cached. Running this method after Process.start() can make it 2609 // cache the dir asynchronously, so zygote can use it without waiting for it. 2610 if (bindMountAppStorageDirs) { 2611 storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(), 2612 app.processName); 2613 } 2614 checkSlow(startTime, "startProcess: returned from zygote!"); 2615 return startResult; 2616 } finally { 2617 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2618 } 2619 } 2620 2621 private boolean hasAppStorage(PackageManagerInternal pmInt, String packageName) { 2622 final AndroidPackage pkg = pmInt.getPackage(packageName); 2623 if (pkg == null) { 2624 Slog.w(TAG, "Unknown package " + packageName); 2625 return false; 2626 } 2627 final PackageManager.Property noAppStorageProp = 2628 pkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE); 2629 return noAppStorageProp == null || !noAppStorageProp.getBoolean(); 2630 } 2631 2632 @GuardedBy("mService") 2633 void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, int zygotePolicyFlags) { 2634 startProcessLocked(app, hostingRecord, zygotePolicyFlags, null /* abiOverride */); 2635 } 2636 2637 @GuardedBy("mService") 2638 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, 2639 int zygotePolicyFlags, String abiOverride) { 2640 return startProcessLocked(app, hostingRecord, zygotePolicyFlags, 2641 false /* disableHiddenApiChecks */, false /* disableTestApiChecks */, 2642 abiOverride); 2643 } 2644 2645 @GuardedBy("mService") 2646 ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2647 boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, 2648 int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid, 2649 boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage, 2650 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2651 long startTime = SystemClock.uptimeMillis(); 2652 final long startTimeNs = SystemClock.elapsedRealtimeNanos(); 2653 ProcessRecord app; 2654 if (!isolated) { 2655 app = getProcessRecordLocked(processName, info.uid); 2656 checkSlow(startTime, "startProcess: after getProcessRecord"); 2657 2658 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) { 2659 // If we are in the background, then check to see if this process 2660 // is bad. If so, we will just silently fail. 2661 if (mService.mAppErrors.isBadProcess(processName, info.uid)) { 2662 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2663 + "/" + processName); 2664 return null; 2665 } 2666 } else { 2667 // When the user is explicitly starting a process, then clear its 2668 // crash count so that we won't make it bad until they see at 2669 // least one crash dialog again, and make the process good again 2670 // if it had been bad. 2671 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2672 + "/" + processName); 2673 mService.mAppErrors.resetProcessCrashTime(processName, info.uid); 2674 if (mService.mAppErrors.isBadProcess(processName, info.uid)) { 2675 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2676 UserHandle.getUserId(info.uid), info.uid, 2677 info.processName); 2678 mService.mAppErrors.clearBadProcess(processName, info.uid); 2679 if (app != null) { 2680 app.mErrorState.setBad(false); 2681 } 2682 } 2683 } 2684 } else { 2685 // If this is an isolated process, it can't re-use an existing process. 2686 app = null; 2687 } 2688 2689 // We don't have to do anything more if: 2690 // (1) There is an existing application record; and 2691 // (2) The caller doesn't think it is dead, OR there is no thread 2692 // object attached to it so we know it couldn't have crashed; and 2693 // (3) There is a pid assigned to it, so it is either starting or 2694 // already running. 2695 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName 2696 + " app=" + app + " knownToBeDead=" + knownToBeDead 2697 + " thread=" + (app != null ? app.getThread() : null) 2698 + " pid=" + (app != null ? app.getPid() : -1)); 2699 ProcessRecord predecessor = null; 2700 if (app != null && app.getPid() > 0) { 2701 if ((!knownToBeDead && !app.isKilled()) || app.getThread() == null) { 2702 // We already have the app running, or are waiting for it to 2703 // come up (we have a pid but not yet its thread), so keep it. 2704 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app); 2705 // If this is a new package in the process, add the package to the list 2706 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats); 2707 checkSlow(startTime, "startProcess: done, added package to proc"); 2708 return app; 2709 } 2710 2711 // An application record is attached to a previous process, 2712 // clean it up now. 2713 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app); 2714 checkSlow(startTime, "startProcess: bad proc running, killing"); 2715 ProcessList.killProcessGroup(app.uid, app.getPid()); 2716 checkSlow(startTime, "startProcess: done killing old proc"); 2717 2718 if (!app.isKilled()) { 2719 // Throw a wtf if it's not killed 2720 Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process"); 2721 } else { 2722 Slog.w(TAG_PROCESSES, app.toString() + " is attached to a previous process"); 2723 } 2724 // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup 2725 // routine of it yet, but we'd set it as the predecessor of the new process. 2726 predecessor = app; 2727 app = null; 2728 } else if (!isolated) { 2729 // This app may have been removed from process name maps, probably because we killed it 2730 // and did the cleanup before the actual death notification. Check the dying processes. 2731 predecessor = mDyingProcesses.get(processName, info.uid); 2732 if (predecessor != null) { 2733 // The process record could have existed but its pid is set to 0. In this case, 2734 // the 'app' and 'predecessor' could end up pointing to the same instance; 2735 // so make sure we check this case here. 2736 if (app != null && app != predecessor) { 2737 app.mPredecessor = predecessor; 2738 predecessor.mSuccessor = app; 2739 } else { 2740 app = null; 2741 } 2742 Slog.w(TAG_PROCESSES, predecessor.toString() + " is attached to a previous process " 2743 + predecessor.getDyingPid()); 2744 } 2745 } 2746 2747 if (app == null) { 2748 checkSlow(startTime, "startProcess: creating new process record"); 2749 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox, 2750 sdkSandboxUid, sdkSandboxClientAppPackage, hostingRecord); 2751 if (app == null) { 2752 Slog.w(TAG, "Failed making new process record for " 2753 + processName + "/" + info.uid + " isolated=" + isolated); 2754 return null; 2755 } 2756 app.mErrorState.setCrashHandler(crashHandler); 2757 app.setIsolatedEntryPoint(entryPoint); 2758 app.setIsolatedEntryPointArgs(entryPointArgs); 2759 if (predecessor != null) { 2760 app.mPredecessor = predecessor; 2761 predecessor.mSuccessor = app; 2762 } 2763 checkSlow(startTime, "startProcess: done creating new process record"); 2764 } else { 2765 // If this is a new package in the process, add the package to the list 2766 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats); 2767 checkSlow(startTime, "startProcess: added package to existing proc"); 2768 } 2769 2770 // If the system is not ready yet, then hold off on starting this 2771 // process until it is. 2772 if (!mService.mProcessesReady 2773 && !mService.isAllowedWhileBooting(info) 2774 && !allowWhileBooting) { 2775 if (!mService.mProcessesOnHold.contains(app)) { 2776 mService.mProcessesOnHold.add(app); 2777 } 2778 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, 2779 "System not ready, putting on hold: " + app); 2780 checkSlow(startTime, "startProcess: returning with proc on hold"); 2781 return app; 2782 } 2783 2784 checkSlow(startTime, "startProcess: stepping in to startProcess"); 2785 final boolean success = 2786 startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride); 2787 checkSlow(startTime, "startProcess: done starting proc!"); 2788 return success ? app : null; 2789 } 2790 2791 @GuardedBy("mService") 2792 String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) { 2793 StringBuilder sb = null; 2794 if (app.isKilledByAm()) { 2795 if (sb == null) sb = new StringBuilder(); 2796 sb.append("killedByAm=true;"); 2797 } 2798 if (mProcessNames.get(app.processName, app.uid) != app) { 2799 if (sb == null) sb = new StringBuilder(); 2800 sb.append("No entry in mProcessNames;"); 2801 } 2802 if (!app.isPendingStart()) { 2803 if (sb == null) sb = new StringBuilder(); 2804 sb.append("pendingStart=false;"); 2805 } 2806 if (app.getStartSeq() > expectedStartSeq) { 2807 if (sb == null) sb = new StringBuilder(); 2808 sb.append("seq=" + app.getStartSeq() + ",expected=" + expectedStartSeq + ";"); 2809 } 2810 try { 2811 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, app.userId); 2812 } catch (RemoteException e) { 2813 // unexpected; ignore 2814 } catch (SecurityException e) { 2815 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { 2816 if (sb == null) sb = new StringBuilder(); 2817 sb.append("Package is frozen;"); 2818 } else { 2819 // we're not being started async and so should throw to the caller. 2820 throw e; 2821 } 2822 } 2823 return sb == null ? null : sb.toString(); 2824 } 2825 2826 @GuardedBy("mService") 2827 private boolean handleProcessStartedLocked(ProcessRecord pending, 2828 Process.ProcessStartResult startResult, long expectedStartSeq) { 2829 // Indicates that this process start has been taken care of. 2830 if (mPendingStarts.get(expectedStartSeq) == null) { 2831 if (pending.getPid() == startResult.pid) { 2832 pending.setUsingWrapper(startResult.usingWrapper); 2833 // TODO: Update already existing clients of usingWrapper 2834 } 2835 return false; 2836 } 2837 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper, 2838 expectedStartSeq, false); 2839 } 2840 2841 @GuardedBy("mService") 2842 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, 2843 long expectedStartSeq, boolean procAttached) { 2844 mPendingStarts.remove(expectedStartSeq); 2845 final String reason = isProcStartValidLocked(app, expectedStartSeq); 2846 if (reason != null) { 2847 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + 2848 pid 2849 + ", " + reason); 2850 app.setPendingStart(false); 2851 killProcessQuiet(pid); 2852 final int appPid = app.getPid(); 2853 if (appPid != 0) { 2854 Process.killProcessGroup(app.uid, appPid); 2855 } 2856 noteAppKill(app, ApplicationExitInfo.REASON_OTHER, 2857 ApplicationExitInfo.SUBREASON_INVALID_START, reason); 2858 app.doEarlyCleanupIfNecessaryLocked(); 2859 return false; 2860 } 2861 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2862 checkSlow(app.getStartTime(), "startProcess: done updating battery stats"); 2863 2864 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2865 UserHandle.getUserId(app.getStartUid()), pid, app.getStartUid(), 2866 app.processName, app.getHostingRecord().getType(), 2867 app.getHostingRecord().getName() != null ? app.getHostingRecord().getName() : ""); 2868 2869 try { 2870 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.info.packageName, 2871 app.processName, app.uid, app.getSeInfo(), app.info.sourceDir, pid); 2872 } catch (RemoteException ex) { 2873 // Ignore 2874 } 2875 2876 Watchdog.getInstance().processStarted(app.processName, pid); 2877 2878 checkSlow(app.getStartTime(), "startProcess: building log message"); 2879 StringBuilder buf = mStringBuilder; 2880 buf.setLength(0); 2881 buf.append("Start proc "); 2882 buf.append(pid); 2883 buf.append(':'); 2884 buf.append(app.processName); 2885 buf.append('/'); 2886 UserHandle.formatUid(buf, app.getStartUid()); 2887 if (app.getIsolatedEntryPoint() != null) { 2888 buf.append(" ["); 2889 buf.append(app.getIsolatedEntryPoint()); 2890 buf.append("]"); 2891 } 2892 buf.append(" for "); 2893 buf.append(app.getHostingRecord().getType()); 2894 if (app.getHostingRecord().getName() != null) { 2895 buf.append(" "); 2896 buf.append(app.getHostingRecord().getName()); 2897 } 2898 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.getStartUid()); 2899 synchronized (mProcLock) { 2900 app.setPid(pid); 2901 app.setUsingWrapper(usingWrapper); 2902 app.setPendingStart(false); 2903 } 2904 checkSlow(app.getStartTime(), "startProcess: starting to update pids map"); 2905 ProcessRecord oldApp; 2906 synchronized (mService.mPidsSelfLocked) { 2907 oldApp = mService.mPidsSelfLocked.get(pid); 2908 } 2909 // If there is already an app occupying that pid that hasn't been cleaned up 2910 if (oldApp != null && !app.isolated) { 2911 // Clean up anything relating to this pid first 2912 Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName 2913 + " startSeq:" + app.getStartSeq() 2914 + " pid:" + pid 2915 + " belongs to another existing app:" + oldApp.processName 2916 + " startSeq:" + oldApp.getStartSeq()); 2917 mService.cleanUpApplicationRecordLocked(oldApp, pid, false, false, -1, 2918 true /*replacingPid*/, false /* fromBinderDied */); 2919 } 2920 mService.addPidLocked(app); 2921 synchronized (mService.mPidsSelfLocked) { 2922 if (!procAttached) { 2923 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2924 msg.obj = app; 2925 mService.mHandler.sendMessageDelayed(msg, usingWrapper 2926 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2927 } 2928 } 2929 dispatchProcessStarted(app, pid); 2930 checkSlow(app.getStartTime(), "startProcess: done updating pids map"); 2931 return true; 2932 } 2933 2934 @GuardedBy("mService") 2935 void removeLruProcessLocked(ProcessRecord app) { 2936 int lrui = mLruProcesses.lastIndexOf(app); 2937 if (lrui >= 0) { 2938 synchronized (mProcLock) { 2939 if (!app.isKilled()) { 2940 if (app.isPersistent()) { 2941 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app); 2942 } else { 2943 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2944 if (app.getPid() > 0) { 2945 killProcessQuiet(app.getPid()); 2946 ProcessList.killProcessGroup(app.uid, app.getPid()); 2947 noteAppKill(app, ApplicationExitInfo.REASON_OTHER, 2948 ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed"); 2949 } else { 2950 app.setPendingStart(false); 2951 } 2952 } 2953 } 2954 if (lrui < mLruProcessActivityStart) { 2955 mLruProcessActivityStart--; 2956 } 2957 if (lrui < mLruProcessServiceStart) { 2958 mLruProcessServiceStart--; 2959 } 2960 mLruProcesses.remove(lrui); 2961 } 2962 } 2963 mService.removeOomAdjTargetLocked(app, true); 2964 } 2965 2966 @GuardedBy({"mService", "mProcLock"}) 2967 boolean killPackageProcessesLSP(String packageName, int appId, @CanBeALL @UserIdInt int userId, 2968 int minOomAdj, int reasonCode, int subReason, String reason) { 2969 return killPackageProcessesLSP(packageName, appId, userId, minOomAdj, 2970 false /* callerWillRestart */, true /* allowRestart */, true /* doit */, 2971 false /* evenPersistent */, false /* setRemoved */, false /* uninstalling */, 2972 reasonCode, subReason, reason); 2973 } 2974 2975 @GuardedBy("mService") 2976 void killAppZygotesLocked(String packageName, int appId, @CanBeALL @UserIdInt int userId, 2977 boolean force) { 2978 // See if there are any app zygotes running for this packageName / UID combination, 2979 // and kill it if so. 2980 final ArrayList<AppZygote> zygotesToKill = new ArrayList<>(); 2981 for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) { 2982 for (int i = 0; i < appZygotes.size(); ++i) { 2983 final int appZygoteUid = appZygotes.keyAt(i); 2984 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) { 2985 continue; 2986 } 2987 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) { 2988 continue; 2989 } 2990 final AppZygote appZygote = appZygotes.valueAt(i); 2991 if (packageName != null 2992 && !packageName.equals(appZygote.getAppInfo().packageName)) { 2993 continue; 2994 } 2995 zygotesToKill.add(appZygote); 2996 } 2997 } 2998 for (AppZygote appZygote : zygotesToKill) { 2999 killAppZygoteIfNeededLocked(appZygote, force); 3000 } 3001 } 3002 3003 private static boolean freezePackageCgroup(int packageUID, boolean freeze) { 3004 try { 3005 Process.freezeCgroupUid(packageUID, freeze); 3006 } catch (RuntimeException e) { 3007 final String logtxt = freeze ? "freeze" : "unfreeze"; 3008 Slog.e(TAG, "Unable to " + logtxt + " cgroup uid: " + packageUID + ": " + e); 3009 return false; 3010 } 3011 return true; 3012 } 3013 3014 private static boolean unfreezePackageCgroup(int packageUID) { 3015 return freezePackageCgroup(packageUID, false); 3016 } 3017 3018 private void freezeBinderAndPackageCgroup(List<Pair<ProcessRecord, Boolean>> procs, 3019 int packageUID) { 3020 // Freeze all binder processes under the target UID (whose cgroup is about to be frozen). 3021 // Since we're going to kill these, we don't need to unfreze them later. 3022 // The procs list may not include all processes under the UID cgroup, but unincluded 3023 // processes (forks) should not be Binder users. 3024 int N = procs.size(); 3025 for (int i = 0; i < N; i++) { 3026 final int pid = procs.get(i).first.getPid(); 3027 int nRetries = 0; 3028 if (pid > 0) { 3029 try { 3030 int rc; 3031 do { 3032 rc = mService.getFreezer().freezeBinder(pid, true, 10 /* timeout_ms */); 3033 } while (rc == -EAGAIN && nRetries++ < 1); 3034 if (rc != 0) Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + rc); 3035 } catch (RuntimeException e) { 3036 Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + e); 3037 } 3038 } 3039 } 3040 3041 // We freeze the entire UID (parent) cgroup so that newly-specialized processes also freeze 3042 // despite being added to a child cgroup created after this call that would otherwise be 3043 // unfrozen. 3044 freezePackageCgroup(packageUID, true); 3045 } 3046 3047 private static List<Pair<ProcessRecord, Boolean>> getUIDSublist( 3048 List<Pair<ProcessRecord, Boolean>> procs, int startIdx) { 3049 final int uid = procs.get(startIdx).first.uid; 3050 int endIdx = startIdx + 1; 3051 while (endIdx < procs.size() && procs.get(endIdx).first.uid == uid) ++endIdx; 3052 return procs.subList(startIdx, endIdx); 3053 } 3054 3055 @GuardedBy({"mService", "mProcLock"}) 3056 boolean killPackageProcessesLSP(String packageName, int appId, 3057 @CanBeALL @UserIdInt int userId, int minOomAdj, boolean callerWillRestart, 3058 boolean allowRestart, boolean doit, boolean evenPersistent, boolean setRemoved, 3059 boolean uninstalling, int reasonCode, int subReason, String reason) { 3060 final PackageManagerInternal pm = mService.getPackageManagerInternal(); 3061 final ArrayList<Pair<ProcessRecord, Boolean>> procs = new ArrayList<>(); 3062 3063 // Remove all processes this package may have touched: all with the 3064 // same UID (except for the system or root user), and all whose name 3065 // matches the package name. 3066 final int NP = mProcessNames.getMap().size(); 3067 for (int ip = 0; ip < NP; ip++) { 3068 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 3069 final int NA = apps.size(); 3070 for (int ia = 0; ia < NA; ia++) { 3071 ProcessRecord app = apps.valueAt(ia); 3072 if (app.isPersistent() && !evenPersistent) { 3073 // we don't kill persistent processes 3074 continue; 3075 } 3076 if (app.isRemoved()) { 3077 if (doit) { 3078 boolean shouldAllowRestart = false; 3079 if (!uninstalling && packageName != null) { 3080 // This package has a dependency on the given package being stopped, 3081 // while it's not being frozen nor uninstalled, allow to restart it. 3082 shouldAllowRestart = !app.getPkgList().containsKey(packageName) 3083 && app.getPkgDeps() != null 3084 && app.getPkgDeps().contains(packageName) 3085 && app.info != null 3086 && !pm.isPackageFrozen(app.info.packageName, app.uid, 3087 app.userId); 3088 } 3089 procs.add(new Pair<>(app, shouldAllowRestart)); 3090 } 3091 continue; 3092 } 3093 3094 // Skip process if it doesn't meet our oom adj requirement. 3095 if (app.mState.getSetAdj() < minOomAdj) { 3096 // Note it is still possible to have a process with oom adj 0 in the killed 3097 // processes, but it does not mean misjudgment. E.g. a bound service process 3098 // and its client activity process are both in the background, so they are 3099 // collected to be killed. If the client activity is killed first, the service 3100 // may be scheduled to unbind and become an executing service (oom adj 0). 3101 continue; 3102 } 3103 3104 boolean shouldAllowRestart = false; 3105 3106 // If no package is specified, we call all processes under the 3107 // given user id. 3108 if (packageName == null) { 3109 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3110 continue; 3111 } 3112 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 3113 continue; 3114 } 3115 // Package has been specified, we want to hit all processes 3116 // that match it. We need to qualify this by the processes 3117 // that are running under the specified app and user ID. 3118 } else { 3119 final boolean isDep = app.getPkgDeps() != null 3120 && app.getPkgDeps().contains(packageName); 3121 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 3122 continue; 3123 } 3124 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3125 continue; 3126 } 3127 final boolean isInPkgList = app.getPkgList().containsKey(packageName); 3128 if (!isInPkgList && !isDep) { 3129 continue; 3130 } 3131 if (!isInPkgList && isDep && !uninstalling && app.info != null 3132 && !pm.isPackageFrozen(app.info.packageName, app.uid, app.userId)) { 3133 // This package has a dependency on the given package being stopped, 3134 // while it's not being frozen nor uninstalled, allow to restart it. 3135 shouldAllowRestart = true; 3136 } 3137 } 3138 3139 // Process has passed all conditions, kill it! 3140 if (!doit) { 3141 return true; 3142 } 3143 if (setRemoved) { 3144 app.setRemoved(true); 3145 } 3146 procs.add(new Pair<>(app, shouldAllowRestart)); 3147 } 3148 } 3149 3150 final boolean killingUserApp = appId >= Process.FIRST_APPLICATION_UID 3151 && appId <= Process.LAST_APPLICATION_UID; 3152 3153 if (killingUserApp) { 3154 procs.sort((o1, o2) -> Integer.compare(o1.first.uid, o2.first.uid)); 3155 } 3156 3157 int idx = 0; 3158 while (idx < procs.size()) { 3159 final List<Pair<ProcessRecord, Boolean>> uidProcs = getUIDSublist(procs, idx); 3160 final int packageUID = uidProcs.get(0).first.uid; 3161 3162 // Do not freeze for system apps or for dependencies of the targeted package, but 3163 // make sure to freeze the targeted package for all users if called with USER_ALL. 3164 final boolean doFreeze = killingUserApp && UserHandle.getAppId(packageUID) == appId; 3165 3166 if (doFreeze) freezeBinderAndPackageCgroup(uidProcs, packageUID); 3167 3168 for (Pair<ProcessRecord, Boolean> proc : uidProcs) { 3169 removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second, 3170 reasonCode, subReason, reason, !doFreeze /* async */); 3171 } 3172 killAppZygotesLocked(packageName, appId, userId, false /* force */); 3173 3174 if (doFreeze) unfreezePackageCgroup(packageUID); 3175 3176 idx += uidProcs.size(); 3177 } 3178 mService.updateOomAdjLocked(OOM_ADJ_REASON_PROCESS_END); 3179 return procs.size() > 0; 3180 } 3181 3182 @GuardedBy("mService") 3183 boolean removeProcessLocked(ProcessRecord app, 3184 boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) { 3185 return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode, 3186 ApplicationExitInfo.SUBREASON_UNKNOWN, reason, true); 3187 } 3188 3189 @GuardedBy("mService") 3190 boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart, 3191 boolean allowRestart, int reasonCode, int subReason, String reason) { 3192 return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode, subReason, 3193 reason, true); 3194 } 3195 3196 @GuardedBy("mService") 3197 boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart, 3198 boolean allowRestart, int reasonCode, int subReason, String reason, boolean async) { 3199 final String name = app.processName; 3200 final int uid = app.uid; 3201 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES, 3202 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")"); 3203 3204 ProcessRecord old = mProcessNames.get(name, uid); 3205 if (old != app) { 3206 // This process is no longer active, so nothing to do. 3207 Slog.w(TAG, "Ignoring remove of inactive process: " + app); 3208 return false; 3209 } 3210 removeProcessNameLocked(name, uid); 3211 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController()); 3212 3213 boolean needRestart = false; 3214 final int pid = app.getPid(); 3215 if ((pid > 0 && pid != ActivityManagerService.MY_PID) 3216 || (pid == 0 && app.isPendingStart())) { 3217 if (pid > 0) { 3218 app.setBindMountPending(false); 3219 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3220 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3221 if (app.isolated) { 3222 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3223 mService.getPackageManagerInternal().removeIsolatedUid(app.uid); 3224 } 3225 } 3226 boolean willRestart = false; 3227 if (app.isPersistent() && !app.isolated) { 3228 if (!callerWillRestart) { 3229 willRestart = true; 3230 } else { 3231 needRestart = true; 3232 } 3233 } 3234 app.killLocked(reason, reasonCode, subReason, true, async); 3235 if (pid > 0) { 3236 // Remove pid record mapping after killing the process, so there won't be a short 3237 // period that the app is still alive but its access to system may be illegal due 3238 // to no existing record for its pid. 3239 mService.removePidLocked(pid, app); 3240 } 3241 mService.handleAppDiedLocked(app, pid, willRestart, allowRestart, 3242 false /* fromBinderDied */); 3243 if (willRestart) { 3244 removeLruProcessLocked(app); 3245 mService.addAppLocked(app.info, null, false, null /* ABI override */, 3246 ZYGOTE_POLICY_FLAG_EMPTY); 3247 } 3248 } else { 3249 mRemovedProcesses.add(app); 3250 } 3251 3252 return needRestart; 3253 } 3254 3255 @GuardedBy("mService") 3256 void addProcessNameLocked(ProcessRecord proc) { 3257 // We shouldn't already have a process under this name, but just in case we 3258 // need to clean up whatever may be there now. 3259 synchronized (mProcLock) { 3260 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); 3261 if (old == proc && proc.isPersistent()) { 3262 // We are re-adding a persistent process. Whatevs! Just leave it there. 3263 Slog.w(TAG, "Re-adding persistent process " + proc); 3264 // Ensure that the mCrashing flag is cleared, since this is a restart 3265 proc.resetCrashingOnRestart(); 3266 } else if (old != null) { 3267 if (old.isKilled()) { 3268 // The old process has been killed, we probably haven't had 3269 // a chance to clean up the old record, just log a warning 3270 Slog.w(TAG, "Existing proc " + old + " was killed " 3271 + (SystemClock.uptimeMillis() - old.getKillTime()) 3272 + "ms ago when adding " + proc); 3273 } else { 3274 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc); 3275 } 3276 } 3277 UidRecord uidRec = mActiveUids.get(proc.uid); 3278 if (uidRec == null) { 3279 uidRec = new UidRecord(proc.uid, mService); 3280 // This is the first appearance of the uid, report it now! 3281 if (DEBUG_UID_OBSERVERS) { 3282 Slog.i(TAG_UID_OBSERVERS, "Creating new process uid: " + uidRec); 3283 } 3284 if (Arrays.binarySearch(mService.mDeviceIdleTempAllowlist, 3285 UserHandle.getAppId(proc.uid)) >= 0 3286 || mService.mPendingTempAllowlist.indexOfKey(proc.uid) >= 0) { 3287 uidRec.setCurAllowListed(true); 3288 uidRec.setSetAllowListed(true); 3289 } 3290 uidRec.updateHasInternetPermission(); 3291 mActiveUids.put(proc.uid, uidRec); 3292 EventLogTags.writeAmUidRunning(uidRec.getUid()); 3293 mService.noteUidProcessStateAndCapability(uidRec.getUid(), uidRec.getCurProcState(), 3294 uidRec.getCurCapability()); 3295 mService.noteUidProcessState(uidRec.getUid(), uidRec.getCurProcState()); 3296 } 3297 proc.setUidRecord(uidRec); 3298 uidRec.addProcess(proc); 3299 3300 // Reset render thread tid if it was already set, so new process can set it again. 3301 proc.setRenderThreadTid(0); 3302 mProcessNames.put(proc.processName, proc.uid, proc); 3303 } 3304 if (proc.isolated) { 3305 mIsolatedProcesses.put(proc.uid, proc); 3306 } 3307 if (proc.isSdkSandbox) { 3308 ArrayList<ProcessRecord> sdkSandboxes = mSdkSandboxes.get(proc.uid); 3309 if (sdkSandboxes == null) { 3310 sdkSandboxes = new ArrayList<>(); 3311 } 3312 sdkSandboxes.add(proc); 3313 mSdkSandboxes.put(Process.getAppUidForSdkSandboxUid(proc.uid), sdkSandboxes); 3314 } 3315 } 3316 3317 @GuardedBy("mService") 3318 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, 3319 HostingRecord hostingRecord) { 3320 if (hostingRecord == null || !hostingRecord.usesAppZygote()) { 3321 // Allocate an isolated UID from the global range 3322 return mGlobalIsolatedUids; 3323 } else { 3324 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked( 3325 info.processName, hostingRecord.getDefiningUid()); 3326 } 3327 } 3328 3329 ProcessRecord getSharedIsolatedProcess(String processName, int uid, String packageName) { 3330 for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) { 3331 final ProcessRecord app = mIsolatedProcesses.valueAt(i); 3332 if (app.info.uid == uid && app.info.packageName.equals(packageName) 3333 && app.processName.equals(processName)) { 3334 return app; 3335 } 3336 } 3337 return null; 3338 } 3339 @Nullable 3340 @GuardedBy("mService") 3341 List<Integer> getIsolatedProcessesLocked(int uid) { 3342 List<Integer> ret = null; 3343 for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) { 3344 final ProcessRecord app = mIsolatedProcesses.valueAt(i); 3345 if (app.info.uid == uid) { 3346 if (ret == null) { 3347 ret = new ArrayList<>(); 3348 } 3349 ret.add(app.getPid()); 3350 } 3351 } 3352 return ret; 3353 } 3354 3355 /** 3356 * Returns the associated SDK sandbox processes for a UID. Note that this does 3357 * NOT return a copy, so callers should not modify the result, or use it outside 3358 * of the lock scope. 3359 * 3360 * @param uid UID to return sansdbox processes for 3361 */ 3362 @Nullable 3363 @GuardedBy("mService") 3364 List<ProcessRecord> getSdkSandboxProcessesForAppLocked(int uid) { 3365 return mSdkSandboxes.get(uid); 3366 } 3367 3368 @GuardedBy("mService") 3369 ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 3370 boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid, 3371 String sdkSandboxClientAppPackage, HostingRecord hostingRecord) { 3372 String proc = customProcess != null ? customProcess : info.processName; 3373 final int userId = UserHandle.getUserId(info.uid); 3374 int uid = info.uid; 3375 if (isSdkSandbox) { 3376 uid = sdkSandboxUid; 3377 } 3378 if (Process.isSdkSandboxUid(uid) && (!isSdkSandbox || sdkSandboxClientAppPackage == null)) { 3379 Slog.e(TAG, "Abort creating new sandbox process as required parameters are missing."); 3380 return null; 3381 } 3382 if (isolated) { 3383 if (isolatedUid == 0) { 3384 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord); 3385 if (uidRange == null) { 3386 return null; 3387 } 3388 uid = uidRange.allocateIsolatedUidLocked(userId); 3389 if (uid == -1) { 3390 return null; 3391 } 3392 } else { 3393 // Special case for startIsolatedProcess (internal only), where 3394 // the uid of the isolated process is specified by the caller. 3395 uid = isolatedUid; 3396 } 3397 mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid); 3398 mService.getPackageManagerInternal().addIsolatedUid(uid, info.uid); 3399 3400 // Register the isolated UID with this application so BatteryStats knows to 3401 // attribute resource usage to the application. 3402 // 3403 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats 3404 // about the process state of the isolated UID *before* it is registered with the 3405 // owning application. 3406 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid); 3407 } 3408 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid, 3409 sdkSandboxClientAppPackage, 3410 hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName()); 3411 final ProcessStateRecord state = r.mState; 3412 3413 final boolean wasStopped = info.isStopped(); 3414 // Check if we should mark the processrecord for first launch after force-stopping 3415 if (wasStopped) { 3416 boolean wasEverLaunched = false; 3417 if (android.app.Flags.useAppInfoNotLaunched()) { 3418 wasEverLaunched = !info.isNotLaunched(); 3419 } else { 3420 try { 3421 wasEverLaunched = mService.getPackageManagerInternal() 3422 .wasPackageEverLaunched(r.getApplicationInfo().packageName, r.userId); 3423 } catch (IllegalArgumentException e) { 3424 // Package doesn't have state yet, assume not launched 3425 } 3426 } 3427 // Check if the hosting record is for an activity or not. Since the stopped 3428 // state tracking is handled differently to avoid WM calling back into AM, 3429 // store the state in the correct record 3430 if (hostingRecord.isTypeActivity()) { 3431 // If the package was launched in the past but is currently stopped, only then 3432 // should it be considered as force-stopped. 3433 @WindowProcessController.StoppedState int stoppedState = wasEverLaunched 3434 ? STOPPED_STATE_FORCE_STOPPED 3435 : STOPPED_STATE_FIRST_LAUNCH; 3436 r.getWindowProcessController().setStoppedState(stoppedState); 3437 } else { 3438 if (android.app.Flags.useAppInfoNotLaunched()) { 3439 // If it was launched before, then it must be a force-stop 3440 r.setWasForceStopped(wasEverLaunched); 3441 } else { 3442 r.setWasForceStopped(true); 3443 } 3444 } 3445 } 3446 3447 if (!isolated && !isSdkSandbox 3448 && userId == UserHandle.USER_SYSTEM 3449 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK 3450 && (TextUtils.equals(proc, info.processName))) { 3451 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc. 3452 state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); 3453 state.setSetSchedGroup(ProcessList.SCHED_GROUP_DEFAULT); 3454 r.setPersistent(true); 3455 mService.mProcessStateController.setMaxAdj(r, ProcessList.PERSISTENT_PROC_ADJ); 3456 } 3457 if (isolated && isolatedUid != 0) { 3458 // Special case for startIsolatedProcess (internal only) - assume the process 3459 // is required by the system server to prevent it being killed. 3460 mService.mProcessStateController.setMaxAdj(r, ProcessList.PERSISTENT_SERVICE_ADJ); 3461 } 3462 addProcessNameLocked(r); 3463 return r; 3464 } 3465 3466 @GuardedBy("mService") 3467 ProcessRecord removeProcessNameLocked(final String name, final int uid) { 3468 return removeProcessNameLocked(name, uid, null); 3469 } 3470 3471 @GuardedBy("mService") 3472 ProcessRecord removeProcessNameLocked(final String name, final int uid, 3473 final ProcessRecord expecting) { 3474 ProcessRecord old = mProcessNames.get(name, uid); 3475 final ProcessRecord record = expecting != null ? expecting : old; 3476 synchronized (mProcLock) { 3477 // Only actually remove when the currently recorded value matches the 3478 // record that we expected; if it doesn't match then we raced with a 3479 // newly created process and we don't want to destroy the new one. 3480 if ((expecting == null) || (old == expecting)) { 3481 mProcessNames.remove(name, uid); 3482 } 3483 if (record != null) { 3484 final UidRecord uidRecord = record.getUidRecord(); 3485 if (uidRecord != null) { 3486 uidRecord.removeProcess(record); 3487 if (uidRecord.getNumOfProcs() == 0) { 3488 // No more processes using this uid, tell clients it is gone. 3489 if (DEBUG_UID_OBSERVERS) { 3490 Slog.i(TAG_UID_OBSERVERS, "No more processes in " + uidRecord); 3491 } 3492 mService.enqueueUidChangeLocked(uidRecord, -1, 3493 UidRecord.CHANGE_GONE | UidRecord.CHANGE_PROCSTATE); 3494 EventLogTags.writeAmUidStopped(uid); 3495 mActiveUids.remove(uid); 3496 mService.mFgsStartTempAllowList.removeUid(record.info.uid); 3497 mService.noteUidProcessStateAndCapability(uid, 3498 ActivityManager.PROCESS_STATE_NONEXISTENT, 3499 ActivityManager.PROCESS_CAPABILITY_NONE); 3500 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT 3501 ); 3502 } 3503 record.setUidRecord(null); 3504 } 3505 } 3506 } 3507 mIsolatedProcesses.remove(uid); 3508 mGlobalIsolatedUids.freeIsolatedUidLocked(uid); 3509 // Remove the (expected) ProcessRecord from the app zygote 3510 if (record != null && record.appZygote) { 3511 removeProcessFromAppZygoteLocked(record); 3512 } 3513 if (record != null && record.isSdkSandbox) { 3514 final int appUid = Process.getAppUidForSdkSandboxUid(uid); 3515 final ArrayList<ProcessRecord> sdkSandboxesForUid = mSdkSandboxes.get(appUid); 3516 if (sdkSandboxesForUid != null) { 3517 sdkSandboxesForUid.remove(record); 3518 if (sdkSandboxesForUid.size() == 0) { 3519 mSdkSandboxes.remove(appUid); 3520 } 3521 } 3522 } 3523 mAppsInBackgroundRestricted.remove(record); 3524 3525 return old; 3526 } 3527 3528 /** Call setCoreSettings on all LRU processes, with the new settings. */ 3529 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3530 void updateCoreSettingsLOSP(Bundle settings) { 3531 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3532 ProcessRecord processRecord = mLruProcesses.get(i); 3533 final IApplicationThread thread = processRecord.getThread(); 3534 try { 3535 if (thread != null) { 3536 thread.setCoreSettings(settings); 3537 } 3538 } catch (RemoteException re) { 3539 /* ignore */ 3540 } 3541 } 3542 } 3543 3544 /** 3545 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and 3546 * procstate lower than maxProcState. 3547 * @param minTargetSdk 3548 * @param maxProcState 3549 */ 3550 @GuardedBy({"mService", "mProcLock"}) 3551 void killAllBackgroundProcessesExceptLSP(int minTargetSdk, int maxProcState) { 3552 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 3553 final int NP = mProcessNames.getMap().size(); 3554 for (int ip = 0; ip < NP; ip++) { 3555 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 3556 final int NA = apps.size(); 3557 for (int ia = 0; ia < NA; ia++) { 3558 final ProcessRecord app = apps.valueAt(ia); 3559 if (app.isRemoved() 3560 || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk) 3561 && (maxProcState < 0 || app.mState.getSetProcState() > maxProcState))) { 3562 procs.add(app); 3563 } 3564 } 3565 } 3566 3567 final int N = procs.size(); 3568 for (int i = 0; i < N; i++) { 3569 removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER, 3570 ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except"); 3571 } 3572 } 3573 3574 /** 3575 * Call updateTimePrefs on all LRU processes 3576 * @param timePref The time pref to pass to each process 3577 */ 3578 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3579 void updateAllTimePrefsLOSP(int timePref) { 3580 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3581 ProcessRecord r = mLruProcesses.get(i); 3582 final IApplicationThread thread = r.getThread(); 3583 if (thread != null) { 3584 try { 3585 thread.updateTimePrefs(timePref); 3586 } catch (RemoteException ex) { 3587 Slog.w(TAG, "Failed to update preferences for: " 3588 + r.info.processName); 3589 } 3590 } 3591 } 3592 } 3593 3594 void setAllHttpProxy() { 3595 // Update the HTTP proxy for each application thread. 3596 synchronized (mProcLock) { 3597 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 3598 ProcessRecord r = mLruProcesses.get(i); 3599 IApplicationThread thread = r.getThread(); 3600 // Don't dispatch to isolated processes as they can't access ConnectivityManager and 3601 // don't have network privileges anyway. Exclude system server and update it 3602 // separately outside the AMS lock, to avoid deadlock with Connectivity Service. 3603 if (r.getPid() != ActivityManagerService.MY_PID && thread != null && !r.isolated) { 3604 try { 3605 thread.updateHttpProxy(); 3606 } catch (RemoteException ex) { 3607 Slog.w(TAG, "Failed to update http proxy for: " 3608 + r.info.processName); 3609 } 3610 } 3611 } 3612 } 3613 ActivityThread.updateHttpProxy(mService.mContext); 3614 } 3615 3616 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3617 void clearAllDnsCacheLOSP() { 3618 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3619 ProcessRecord r = mLruProcesses.get(i); 3620 final IApplicationThread thread = r.getThread(); 3621 if (thread != null) { 3622 try { 3623 thread.clearDnsCache(); 3624 } catch (RemoteException ex) { 3625 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 3626 } 3627 } 3628 } 3629 } 3630 3631 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3632 void handleAllTrustStorageUpdateLOSP() { 3633 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3634 ProcessRecord r = mLruProcesses.get(i); 3635 final IApplicationThread thread = r.getThread(); 3636 if (thread != null) { 3637 try { 3638 thread.handleTrustStorageUpdate(); 3639 } catch (RemoteException ex) { 3640 Slog.w(TAG, "Failed to handle trust storage update for: " + 3641 r.info.processName); 3642 } 3643 } 3644 } 3645 } 3646 3647 @GuardedBy({"mService", "mProcLock"}) 3648 private int offerLruProcessInternalLSP(ProcessRecord app, long now, String what, Object obj, 3649 ProcessRecord srcApp) { 3650 app.setLastActivityTime(now); 3651 3652 if (app.hasActivitiesOrRecentTasks()) { 3653 // Don't want to touch dependent processes that are hosting activities. 3654 return -1; 3655 } 3656 3657 final int lrui = mLruProcesses.lastIndexOf(app); 3658 if (lrui < 0) { 3659 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 3660 + what + " " + obj + " from " + srcApp); 3661 } 3662 return lrui; 3663 } 3664 3665 /** 3666 * This method is called after the indices array is populated by the indices offered by 3667 * {@link #offerLruProcessInternalLSP} to actually move the processes to the desired locations 3668 * in the LRU list. Since the indices array is a SparseBooleanArray, the indices are sorted 3669 * and this allows us to preserve the previous order of the processes relative to each other. 3670 * Key of the indices array holds the current index of the process in the LRU list and the value 3671 * is a boolean indicating whether the process is an activity process or not. Activity processes 3672 * are moved to the nextActivityIndex and non-activity processes are moved to the nextIndex 3673 * positions, which are provided by the caller. 3674 * 3675 * @param indices The indices of the processes to move. 3676 * @param nextActivityIndex The next index to insert an activity process. 3677 * @param nextIndex The next index to insert a non-activity process. 3678 */ 3679 @GuardedBy({"mService", "mProcLock"}) 3680 private void completeLruProcessInternalLSP(SparseBooleanArray indices, int nextActivityIndex, 3681 int nextIndex) { 3682 for (int i = indices.size() - 1; i >= 0; i--) { 3683 final int lrui = indices.keyAt(i); 3684 if (lrui < 0) { 3685 // Rest of the indices are invalid, we can return early. 3686 return; 3687 } 3688 final boolean isActivity = indices.valueAt(i); 3689 int index = isActivity ? nextActivityIndex : nextIndex; 3690 3691 if (lrui >= index) { 3692 // Don't want to cause this to move dependent processes *back* in the 3693 // list as if they were less frequently used. 3694 continue; 3695 } 3696 3697 final ProcessRecord app = mLruProcesses.remove(lrui); 3698 index--; 3699 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index 3700 + " in LRU list: " + app); 3701 mLruProcesses.add(index, app); 3702 app.setLruSeq(mLruSeq); 3703 3704 if (isActivity) { 3705 nextActivityIndex = index; 3706 } else { 3707 nextIndex = index; 3708 } 3709 } 3710 } 3711 3712 /** 3713 * Handle the case where we are inserting a process hosting client activities: 3714 * Make sure any groups have their order match their importance, and take care of 3715 * distributing old clients across other activity processes so they can't spam 3716 * the LRU list. Processing of the list will be restricted by the indices provided, 3717 * and not extend out of them. 3718 * 3719 * @param topApp The app at the top that has just been inserted in to the list. 3720 * @param topI The position in the list where topApp was inserted; this is the start (at the 3721 * top) where we are going to do our processing. 3722 * @param bottomI The last position at which we will be processing; this is the end position 3723 * of whichever section of the LRU list we are in. Nothing past it will be 3724 * touched. 3725 * @param endIndex The current end of the top being processed. Typically topI - 1. That is, 3726 * where we are going to start potentially adjusting other entries in the list. 3727 */ 3728 @GuardedBy({"mService", "mProcLock"}) 3729 private void updateClientActivitiesOrderingLSP(final ProcessRecord topApp, final int topI, 3730 final int bottomI, int endIndex) { 3731 final ProcessServiceRecord topPsr = topApp.mServices; 3732 if (topApp.hasActivitiesOrRecentTasks() || topPsr.isTreatedLikeActivity() 3733 || !topPsr.hasClientActivities()) { 3734 // If this is not a special process that has client activities, then there is 3735 // nothing to do. 3736 return; 3737 } 3738 3739 final int uid = topApp.info.uid; 3740 final int topConnectionGroup = topPsr.getConnectionGroup(); 3741 if (topConnectionGroup > 0) { 3742 int endImportance = topPsr.getConnectionImportance(); 3743 for (int i = endIndex; i >= bottomI; i--) { 3744 final ProcessRecord subProc = mLruProcesses.get(i); 3745 final ProcessServiceRecord subPsr = subProc.mServices; 3746 final int subConnectionGroup = subPsr.getConnectionGroup(); 3747 final int subConnectionImportance = subPsr.getConnectionImportance(); 3748 if (subProc.info.uid == uid 3749 && subConnectionGroup == topConnectionGroup) { 3750 if (i == endIndex && subConnectionImportance >= endImportance) { 3751 // This process is already in the group, and its importance 3752 // is not as strong as the process before it, so keep it 3753 // correctly positioned in the group. 3754 if (DEBUG_LRU) Slog.d(TAG_LRU, 3755 "Keeping in-place above " + subProc 3756 + " endImportance=" + endImportance 3757 + " group=" + subConnectionGroup 3758 + " importance=" + subConnectionImportance); 3759 endIndex--; 3760 endImportance = subConnectionImportance; 3761 } else { 3762 // We want to pull this up to be with the rest of the group, 3763 // and order within the group by importance. 3764 if (DEBUG_LRU) Slog.d(TAG_LRU, 3765 "Pulling up " + subProc 3766 + " to position in group with importance=" 3767 + subConnectionImportance); 3768 boolean moved = false; 3769 for (int pos = topI; pos > endIndex; pos--) { 3770 final ProcessRecord posProc = mLruProcesses.get(pos); 3771 if (subConnectionImportance 3772 <= posProc.mServices.getConnectionImportance()) { 3773 mLruProcesses.remove(i); 3774 mLruProcesses.add(pos, subProc); 3775 if (DEBUG_LRU) Slog.d(TAG_LRU, 3776 "Moving " + subProc 3777 + " from position " + i + " to above " + posProc 3778 + " @ " + pos); 3779 moved = true; 3780 endIndex--; 3781 break; 3782 } 3783 } 3784 if (!moved) { 3785 // Goes to the end of the group. 3786 mLruProcesses.remove(i); 3787 mLruProcesses.add(endIndex, subProc); 3788 if (DEBUG_LRU) Slog.d(TAG_LRU, 3789 "Moving " + subProc 3790 + " from position " + i + " to end of group @ " 3791 + endIndex); 3792 endIndex--; 3793 endImportance = subConnectionImportance; 3794 } 3795 } 3796 } 3797 } 3798 3799 } 3800 // To keep it from spamming the LRU list (by making a bunch of clients), 3801 // we will distribute other entries owned by it to be in-between other apps. 3802 int i = endIndex; 3803 while (i >= bottomI) { 3804 ProcessRecord subProc = mLruProcesses.get(i); 3805 final ProcessServiceRecord subPsr = subProc.mServices; 3806 final int subConnectionGroup = subPsr.getConnectionGroup(); 3807 if (DEBUG_LRU) Slog.d(TAG_LRU, 3808 "Looking to spread old procs, at " + subProc + " @ " + i); 3809 if (subProc.info.uid != uid) { 3810 // This is a different app... if we have gone through some of the 3811 // target app, pull this up to be before them. We want to pull up 3812 // one activity process, but any number of non-activity processes. 3813 if (i < endIndex) { 3814 boolean hasActivity = false; 3815 int connUid = 0; 3816 int connGroup = 0; 3817 while (subProc.info.uid != uid) { 3818 mLruProcesses.remove(i); 3819 mLruProcesses.add(endIndex, subProc); 3820 if (DEBUG_LRU) Slog.d(TAG_LRU, 3821 "Different app, moving to " + endIndex); 3822 i--; 3823 if (i < bottomI) { 3824 break; 3825 } 3826 subProc = mLruProcesses.get(i); 3827 if (DEBUG_LRU) Slog.d(TAG_LRU, 3828 "Looking at next app at " + i + ": " + subProc); 3829 if (subProc.hasActivitiesOrRecentTasks() 3830 || subPsr.isTreatedLikeActivity()) { 3831 if (DEBUG_LRU) Slog.d(TAG_LRU, 3832 "This is hosting an activity!"); 3833 if (hasActivity) { 3834 // Already found an activity, done. 3835 if (DEBUG_LRU) Slog.d(TAG_LRU, 3836 "Already found an activity, done"); 3837 break; 3838 } 3839 hasActivity = true; 3840 } else if (subPsr.hasClientActivities()) { 3841 if (DEBUG_LRU) Slog.d(TAG_LRU, 3842 "This is a client of an activity"); 3843 if (hasActivity) { 3844 if (connUid == 0 || connUid != subProc.info.uid) { 3845 // Already have an activity that is not from from a client 3846 // connection or is a different client connection, done. 3847 if (DEBUG_LRU) Slog.d(TAG_LRU, 3848 "Already found a different activity: connUid=" 3849 + connUid + " uid=" + subProc.info.uid); 3850 break; 3851 } else if (connGroup == 0 || connGroup != subConnectionGroup) { 3852 // Previously saw a different group or not from a group, 3853 // want to treat these as different things. 3854 if (DEBUG_LRU) Slog.d(TAG_LRU, 3855 "Already found a different group: connGroup=" 3856 + connGroup + " group=" + subConnectionGroup); 3857 break; 3858 } 3859 } else { 3860 if (DEBUG_LRU) Slog.d(TAG_LRU, 3861 "This is an activity client! uid=" 3862 + subProc.info.uid + " group=" + subConnectionGroup); 3863 hasActivity = true; 3864 connUid = subProc.info.uid; 3865 connGroup = subConnectionGroup; 3866 } 3867 } 3868 endIndex--; 3869 } 3870 } 3871 // Find the end of the next group of processes for target app. This 3872 // is after any entries of different apps (so we don't change the existing 3873 // relative order of apps) and then after the next last group of processes 3874 // of the target app. 3875 for (endIndex--; endIndex >= bottomI; endIndex--) { 3876 final ProcessRecord endProc = mLruProcesses.get(endIndex); 3877 if (endProc.info.uid == uid) { 3878 if (DEBUG_LRU) Slog.d(TAG_LRU, 3879 "Found next group of app: " + endProc + " @ " 3880 + endIndex); 3881 break; 3882 } 3883 } 3884 if (endIndex >= bottomI) { 3885 final ProcessRecord endProc = mLruProcesses.get(endIndex); 3886 final ProcessServiceRecord endPsr = endProc.mServices; 3887 final int endConnectionGroup = endPsr.getConnectionGroup(); 3888 for (endIndex--; endIndex >= bottomI; endIndex--) { 3889 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex); 3890 final int nextConnectionGroup = nextEndProc.mServices.getConnectionGroup(); 3891 if (nextEndProc.info.uid != uid 3892 || nextConnectionGroup != endConnectionGroup) { 3893 if (DEBUG_LRU) Slog.d(TAG_LRU, 3894 "Found next group or app: " + nextEndProc + " @ " 3895 + endIndex + " group=" + nextConnectionGroup); 3896 break; 3897 } 3898 } 3899 } 3900 if (DEBUG_LRU) Slog.d(TAG_LRU, 3901 "Bumping scan position to " + endIndex); 3902 i = endIndex; 3903 } else { 3904 i--; 3905 } 3906 } 3907 } 3908 3909 @GuardedBy("mService") 3910 void updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client) { 3911 final ProcessServiceRecord psr = app.mServices; 3912 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || psr.hasClientActivities() 3913 || psr.isTreatedLikeActivity(); 3914 final boolean hasService = false; // not impl yet. app.services.size() > 0; 3915 if (!activityChange && hasActivity) { 3916 // The process has activities, so we are only allowing activity-based adjustments 3917 // to move it. It should be kept in the front of the list with other 3918 // processes that have activities, and we don't want those to change their 3919 // order except due to activity operations. 3920 return; 3921 } 3922 3923 if (app.getPid() == 0 && !app.isPendingStart()) { 3924 // This process has been killed and its cleanup is done, don't proceed the LRU update. 3925 return; 3926 } 3927 3928 synchronized (mProcLock) { 3929 updateLruProcessLSP(app, client, hasActivity, hasService); 3930 } 3931 } 3932 3933 @GuardedBy({"mService", "mProcLock"}) 3934 private void updateLruProcessLSP(ProcessRecord app, ProcessRecord client, 3935 boolean hasActivity, boolean hasService) { 3936 mLruSeq++; 3937 final long now = SystemClock.uptimeMillis(); 3938 final ProcessServiceRecord psr = app.mServices; 3939 app.setLastActivityTime(now); 3940 3941 // First a quick reject: if the app is already at the position we will 3942 // put it, then there is nothing to do. 3943 if (hasActivity) { 3944 final int N = mLruProcesses.size(); 3945 if (N > 0 && mLruProcesses.get(N - 1) == app) { 3946 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app); 3947 return; 3948 } 3949 } else { 3950 if (mLruProcessServiceStart > 0 3951 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 3952 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app); 3953 return; 3954 } 3955 } 3956 3957 int lrui = mLruProcesses.lastIndexOf(app); 3958 3959 if (app.isPersistent() && lrui >= 0) { 3960 // We don't care about the position of persistent processes, as long as 3961 // they are in the list. 3962 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app); 3963 return; 3964 } 3965 3966 /* In progress: compute new position first, so we can avoid doing work 3967 if the process is not actually going to move. Not yet working. 3968 int addIndex; 3969 int nextIndex; 3970 boolean inActivity = false, inService = false; 3971 if (hasActivity) { 3972 // Process has activities, put it at the very tipsy-top. 3973 addIndex = mLruProcesses.size(); 3974 nextIndex = mLruProcessServiceStart; 3975 inActivity = true; 3976 } else if (hasService) { 3977 // Process has services, put it at the top of the service list. 3978 addIndex = mLruProcessActivityStart; 3979 nextIndex = mLruProcessServiceStart; 3980 inActivity = true; 3981 inService = true; 3982 } else { 3983 // Process not otherwise of interest, it goes to the top of the non-service area. 3984 addIndex = mLruProcessServiceStart; 3985 if (client != null) { 3986 int clientIndex = mLruProcesses.lastIndexOf(client); 3987 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 3988 + app); 3989 if (clientIndex >= 0 && addIndex > clientIndex) { 3990 addIndex = clientIndex; 3991 } 3992 } 3993 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 3994 } 3995 3996 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 3997 + mLruProcessActivityStart + "): " + app); 3998 */ 3999 4000 if (lrui >= 0) { 4001 if (lrui < mLruProcessActivityStart) { 4002 mLruProcessActivityStart--; 4003 } 4004 if (lrui < mLruProcessServiceStart) { 4005 mLruProcessServiceStart--; 4006 } 4007 /* 4008 if (addIndex > lrui) { 4009 addIndex--; 4010 } 4011 if (nextIndex > lrui) { 4012 nextIndex--; 4013 } 4014 */ 4015 mLruProcesses.remove(lrui); 4016 } 4017 4018 /* 4019 mLruProcesses.add(addIndex, app); 4020 if (inActivity) { 4021 mLruProcessActivityStart++; 4022 } 4023 if (inService) { 4024 mLruProcessActivityStart++; 4025 } 4026 */ 4027 4028 int nextIndex; 4029 int nextActivityIndex = -1; 4030 if (hasActivity) { 4031 final int N = mLruProcesses.size(); 4032 nextIndex = mLruProcessServiceStart; 4033 if (!app.hasActivitiesOrRecentTasks() && !psr.isTreatedLikeActivity() 4034 && mLruProcessActivityStart < (N - 1)) { 4035 // Process doesn't have activities, but has clients with 4036 // activities... move it up, but below the app that is binding to it. 4037 if (DEBUG_LRU) Slog.d(TAG_LRU, 4038 "Adding to second-top of LRU activity list: " + app 4039 + " group=" + psr.getConnectionGroup() 4040 + " importance=" + psr.getConnectionImportance()); 4041 int pos = N - 1; 4042 while (pos > mLruProcessActivityStart) { 4043 final ProcessRecord posproc = mLruProcesses.get(pos); 4044 if (posproc.info.uid == app.info.uid) { 4045 // Technically this app could have multiple processes with different 4046 // activities and so we should be looking for the actual process that 4047 // is bound to the target proc... but I don't really care, do you? 4048 break; 4049 } 4050 pos--; 4051 } 4052 mLruProcesses.add(pos, app); 4053 // If this process is part of a group, need to pull up any other processes 4054 // in that group to be with it. 4055 int endIndex = pos - 1; 4056 if (endIndex < mLruProcessActivityStart) { 4057 endIndex = mLruProcessActivityStart; 4058 } 4059 nextActivityIndex = endIndex; 4060 updateClientActivitiesOrderingLSP(app, pos, mLruProcessActivityStart, endIndex); 4061 } else { 4062 // Process has activities, put it at the very tipsy-top. 4063 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app); 4064 mLruProcesses.add(app); 4065 nextActivityIndex = mLruProcesses.size() - 1; 4066 } 4067 } else if (hasService) { 4068 // Process has services, put it at the top of the service list. 4069 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app); 4070 mLruProcesses.add(mLruProcessActivityStart, app); 4071 nextIndex = mLruProcessServiceStart; 4072 mLruProcessActivityStart++; 4073 } else { 4074 // Process not otherwise of interest, it goes to the top of the non-service area. 4075 int index = mLruProcessServiceStart; 4076 if (client != null) { 4077 // If there is a client, don't allow the process to be moved up higher 4078 // in the list than that client. 4079 int clientIndex = mLruProcesses.lastIndexOf(client); 4080 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client 4081 + " when updating " + app); 4082 if (clientIndex <= lrui) { 4083 // Don't allow the client index restriction to push it down farther in the 4084 // list than it already is. 4085 clientIndex = lrui; 4086 } 4087 if (clientIndex >= 0 && index > clientIndex) { 4088 index = clientIndex; 4089 } 4090 } 4091 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app); 4092 mLruProcesses.add(index, app); 4093 nextIndex = index - 1; 4094 mLruProcessActivityStart++; 4095 mLruProcessServiceStart++; 4096 if (index > 1) { 4097 updateClientActivitiesOrderingLSP(app, mLruProcessServiceStart - 1, 0, index - 1); 4098 } 4099 } 4100 4101 app.setLruSeq(mLruSeq); 4102 4103 // Key of the indices array holds the current index of the process in the LRU list and the 4104 // value is a boolean indicating whether the process is an activity process or not. 4105 // Activity processes will be moved to the nextActivityIndex and non-activity processes will 4106 // be moved to the nextIndex positions when completeLruProcessInternalLSP is called. 4107 // Since SparseBooleanArray's keys are sorted, we'll be able to keep the existing order of 4108 // the processes relative to each other after the move. 4109 final SparseBooleanArray indices = new SparseBooleanArray(psr.numberOfConnections() 4110 + app.mProviders.numberOfProviderConnections()); 4111 4112 // If the app is currently using a content provider or service, 4113 // bump those processes as well. 4114 for (int j = psr.numberOfConnections() - 1; j >= 0; j--) { 4115 ConnectionRecord cr = psr.getConnectionAt(j); 4116 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 4117 && cr.binding.service.app != null 4118 && cr.binding.service.app.getLruSeq() != mLruSeq 4119 && cr.notHasFlag(Context.BIND_REDUCTION_FLAGS) 4120 && !cr.binding.service.app.isPersistent()) { 4121 if (cr.binding.service.app.mServices.hasClientActivities()) { 4122 if (nextActivityIndex >= 0) { 4123 indices.append(offerLruProcessInternalLSP(cr.binding.service.app, now, 4124 "service connection", cr, app), true); 4125 } 4126 } else { 4127 indices.append(offerLruProcessInternalLSP(cr.binding.service.app, now, 4128 "service connection", cr, app), false); 4129 } 4130 } 4131 } 4132 final ProcessProviderRecord ppr = app.mProviders; 4133 for (int j = ppr.numberOfProviderConnections() - 1; j >= 0; j--) { 4134 ContentProviderRecord cpr = ppr.getProviderConnectionAt(j).provider; 4135 if (cpr.proc != null && cpr.proc.getLruSeq() != mLruSeq && !cpr.proc.isPersistent()) { 4136 indices.append(offerLruProcessInternalLSP(cpr.proc, now, 4137 "provider reference", cpr, app), false); 4138 } 4139 } 4140 completeLruProcessInternalLSP(indices, nextActivityIndex, nextIndex); 4141 } 4142 4143 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLRURecordForAppLOSP(IApplicationThread thread)4144 ProcessRecord getLRURecordForAppLOSP(IApplicationThread thread) { 4145 if (thread == null) { 4146 return null; 4147 } 4148 return getLRURecordForAppLOSP(thread.asBinder()); 4149 } 4150 4151 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLRURecordForAppLOSP(IBinder threadBinder)4152 ProcessRecord getLRURecordForAppLOSP(IBinder threadBinder) { 4153 if (threadBinder == null) { 4154 return null; 4155 } 4156 // Find the application record. 4157 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4158 final ProcessRecord rec = mLruProcesses.get(i); 4159 final IApplicationThread t = rec.getThread(); 4160 if (t != null && t.asBinder() == threadBinder) { 4161 return rec; 4162 } 4163 } 4164 return null; 4165 } 4166 4167 @GuardedBy(anyOf = {"mService", "mProcLock"}) haveBackgroundProcessLOSP()4168 boolean haveBackgroundProcessLOSP() { 4169 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4170 final ProcessRecord rec = mLruProcesses.get(i); 4171 if (rec.getThread() != null 4172 && rec.mState.getSetProcState() >= PROCESS_STATE_CACHED_ACTIVITY) { 4173 return true; 4174 } 4175 } 4176 return false; 4177 } 4178 4179 @GuardedBy(anyOf = {"mService", "mProcLock"}) fillInProcMemInfoLOSP(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, int clientTargetSdk)4180 void fillInProcMemInfoLOSP(ProcessRecord app, 4181 ActivityManager.RunningAppProcessInfo outInfo, 4182 int clientTargetSdk) { 4183 outInfo.pid = app.getPid(); 4184 outInfo.uid = app.info.uid; 4185 if (app.getWindowProcessController().isHeavyWeightProcess()) { 4186 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 4187 } 4188 if (app.isPersistent()) { 4189 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 4190 } 4191 if (app.hasActivities()) { 4192 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 4193 } 4194 outInfo.lastTrimLevel = app.mProfile.getTrimMemoryLevel(); 4195 final ProcessStateRecord state = app.mState; 4196 final int procState = state.getCurProcState(); 4197 outInfo.importance = ActivityManager.RunningAppProcessInfo 4198 .procStateToImportanceForTargetSdk(procState, clientTargetSdk); 4199 if (outInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 4200 outInfo.lru = state.getCurAdj(); 4201 } else { 4202 outInfo.lru = 0; 4203 } 4204 outInfo.importanceReasonCode = state.getAdjTypeCode(); 4205 outInfo.processState = procState; 4206 outInfo.isFocused = (app == mService.getTopApp()); 4207 outInfo.lastActivityTime = app.getLastActivityTime(); 4208 // Note: ActivityManager$RunningAppProcessInfo.copyTo() must be updated if what gets 4209 // "filled into" outInfo in this method changes. 4210 } 4211 4212 @GuardedBy(anyOf = {"mService", "mProcLock"}) getRunningAppProcessesLOSP(boolean allUsers, int userId, boolean allUids, int callingUid, int clientTargetSdk)4213 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLOSP(boolean allUsers, 4214 int userId, boolean allUids, int callingUid, int clientTargetSdk) { 4215 // Lazy instantiation of list 4216 List<ActivityManager.RunningAppProcessInfo> runList = null; 4217 4218 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4219 ProcessRecord app = mLruProcesses.get(i); 4220 final ProcessStateRecord state = app.mState; 4221 final ProcessErrorStateRecord errState = app.mErrorState; 4222 if ((!allUsers && app.userId != userId) 4223 || (!allUids && app.uid != callingUid)) { 4224 continue; 4225 } 4226 if ((app.getThread() != null) 4227 && (!errState.isCrashing() && !errState.isNotResponding())) { 4228 // Generate process state info for running application 4229 ActivityManager.RunningAppProcessInfo currApp = 4230 new ActivityManager.RunningAppProcessInfo(app.processName, 4231 app.getPid(), app.getPackageList()); 4232 if (app.getPkgDeps() != null) { 4233 final int size = app.getPkgDeps().size(); 4234 currApp.pkgDeps = app.getPkgDeps().toArray(new String[size]); 4235 } 4236 fillInProcMemInfoLOSP(app, currApp, clientTargetSdk); 4237 if (state.getAdjSource() instanceof ProcessRecord) { 4238 currApp.importanceReasonPid = ((ProcessRecord) state.getAdjSource()).getPid(); 4239 currApp.importanceReasonImportance = 4240 ActivityManager.RunningAppProcessInfo.procStateToImportance( 4241 state.getAdjSourceProcState()); 4242 } else if (state.getAdjSource() instanceof ActivityServiceConnectionsHolder) { 4243 final ActivityServiceConnectionsHolder r = 4244 (ActivityServiceConnectionsHolder) state.getAdjSource(); 4245 final int pid = r.getActivityPid(); 4246 if (pid != -1) { 4247 currApp.importanceReasonPid = pid; 4248 } 4249 } 4250 if (state.getAdjTarget() instanceof ComponentName) { 4251 currApp.importanceReasonComponent = (ComponentName) state.getAdjTarget(); 4252 } 4253 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 4254 // + " lru=" + currApp.lru); 4255 if (runList == null) { 4256 runList = new ArrayList<>(); 4257 } 4258 runList.add(currApp); 4259 } 4260 } 4261 return runList; 4262 } 4263 4264 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLruSizeLOSP()4265 int getLruSizeLOSP() { 4266 return mLruProcesses.size(); 4267 } 4268 4269 /** 4270 * Return the reference to the LRU list, call this function for read-only access 4271 */ 4272 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLruProcessesLOSP()4273 ArrayList<ProcessRecord> getLruProcessesLOSP() { 4274 return mLruProcesses; 4275 } 4276 4277 /** 4278 * Return the reference to the LRU list, call this function for read/write access 4279 */ 4280 @GuardedBy({"mService", "mProcLock"}) getLruProcessesLSP()4281 ArrayList<ProcessRecord> getLruProcessesLSP() { 4282 return mLruProcesses; 4283 } 4284 4285 /** 4286 * For test only 4287 */ 4288 @VisibleForTesting 4289 @GuardedBy({"mService", "mProcLock"}) setLruProcessServiceStartLSP(int pos)4290 void setLruProcessServiceStartLSP(int pos) { 4291 mLruProcessServiceStart = pos; 4292 } 4293 4294 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLruProcessServiceStartLOSP()4295 int getLruProcessServiceStartLOSP() { 4296 return mLruProcessServiceStart; 4297 } 4298 4299 /** 4300 * Iterate the whole LRU list, invoke the given {@code callback} with each of the ProcessRecord 4301 * in that list. 4302 * 4303 * @param iterateForward If {@code true}, iterate the LRU list from the least recent used 4304 * to most recent used ProcessRecord. 4305 * @param callback The callback interface to accept the current ProcessRecord. 4306 */ 4307 @GuardedBy(anyOf = {"mService", "mProcLock"}) forEachLruProcessesLOSP(boolean iterateForward, @NonNull Consumer<ProcessRecord> callback)4308 void forEachLruProcessesLOSP(boolean iterateForward, 4309 @NonNull Consumer<ProcessRecord> callback) { 4310 if (iterateForward) { 4311 for (int i = 0, size = mLruProcesses.size(); i < size; i++) { 4312 callback.accept(mLruProcesses.get(i)); 4313 } 4314 } else { 4315 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4316 callback.accept(mLruProcesses.get(i)); 4317 } 4318 } 4319 } 4320 4321 /** 4322 * Search in the LRU list, invoke the given {@code callback} with each of the ProcessRecord 4323 * in that list; if the callback returns a non-null object, halt the search, return that 4324 * object as the return value of this search function. 4325 * 4326 * @param iterateForward If {@code true}, iterate the LRU list from the least recent used 4327 * to most recent used ProcessRecord. 4328 * @param callback The callback interface to accept the current ProcessRecord; if it returns 4329 * a non-null object, the search will be halted and this object will be used 4330 * as the return value of this search function. 4331 */ 4332 @GuardedBy(anyOf = {"mService", "mProcLock"}) searchEachLruProcessesLOSP(boolean iterateForward, @NonNull Function<ProcessRecord, R> callback)4333 <R> R searchEachLruProcessesLOSP(boolean iterateForward, 4334 @NonNull Function<ProcessRecord, R> callback) { 4335 if (iterateForward) { 4336 for (int i = 0, size = mLruProcesses.size(); i < size; i++) { 4337 R r; 4338 if ((r = callback.apply(mLruProcesses.get(i))) != null) { 4339 return r; 4340 } 4341 } 4342 } else { 4343 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4344 R r; 4345 if ((r = callback.apply(mLruProcesses.get(i))) != null) { 4346 return r; 4347 } 4348 } 4349 } 4350 return null; 4351 } 4352 4353 @GuardedBy(anyOf = {"mService", "mProcLock"}) isInLruListLOSP(ProcessRecord app)4354 boolean isInLruListLOSP(ProcessRecord app) { 4355 return mLruProcesses.contains(app); 4356 } 4357 4358 @GuardedBy(anyOf = {"mService", "mProcLock"}) getLruSeqLOSP()4359 int getLruSeqLOSP() { 4360 return mLruSeq; 4361 } 4362 4363 @GuardedBy(anyOf = {"mService", "mProcLock"}) getProcessNamesLOSP()4364 MyProcessMap getProcessNamesLOSP() { 4365 return mProcessNames; 4366 } 4367 4368 @GuardedBy("mService") dumpLruListHeaderLocked(PrintWriter pw)4369 void dumpLruListHeaderLocked(PrintWriter pw) { 4370 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 4371 pw.print(" total, non-act at "); 4372 pw.print(mLruProcesses.size() - mLruProcessActivityStart); 4373 pw.print(", non-svc at "); 4374 pw.print(mLruProcesses.size() - mLruProcessServiceStart); 4375 pw.println("):"); 4376 } 4377 4378 @GuardedBy("mService") dumpLruEntryLocked(PrintWriter pw, int index, ProcessRecord proc, String prefix)4379 private void dumpLruEntryLocked(PrintWriter pw, int index, ProcessRecord proc, String prefix) { 4380 pw.print(prefix); 4381 pw.print('#'); 4382 if (index < 10) { 4383 pw.print(' '); 4384 } 4385 pw.print(index); 4386 pw.print(": "); 4387 pw.print(makeOomAdjString(proc.mState.getSetAdj(), false)); 4388 pw.print(' '); 4389 pw.print(makeProcStateString(proc.mState.getCurProcState())); 4390 pw.print(' '); 4391 ActivityManager.printCapabilitiesSummary(pw, proc.mState.getCurCapability()); 4392 pw.print(' '); 4393 pw.print(proc.toShortString()); 4394 final ProcessServiceRecord psr = proc.mServices; 4395 if (proc.hasActivitiesOrRecentTasks() || psr.hasClientActivities() 4396 || psr.isTreatedLikeActivity()) { 4397 pw.print(" act:"); 4398 boolean printed = false; 4399 if (proc.hasActivities()) { 4400 pw.print("activities"); 4401 printed = true; 4402 } 4403 if (proc.hasRecentTasks()) { 4404 if (printed) { 4405 pw.print("|"); 4406 } 4407 pw.print("recents"); 4408 printed = true; 4409 } 4410 if (psr.hasClientActivities()) { 4411 if (printed) { 4412 pw.print("|"); 4413 } 4414 pw.print("client"); 4415 printed = true; 4416 } 4417 if (psr.isTreatedLikeActivity()) { 4418 if (printed) { 4419 pw.print("|"); 4420 } 4421 pw.print("treated"); 4422 } 4423 } 4424 pw.println(); 4425 } 4426 4427 @GuardedBy("mService") dumpLruLocked(PrintWriter pw, String dumpPackage, String prefix)4428 boolean dumpLruLocked(PrintWriter pw, String dumpPackage, String prefix) { 4429 final int lruSize = mLruProcesses.size(); 4430 final String innerPrefix; 4431 if (prefix == null) { 4432 pw.println("ACTIVITY MANAGER LRU PROCESSES (dumpsys activity lru)"); 4433 innerPrefix = " "; 4434 } else { 4435 boolean haveAny = false; 4436 for (int i = lruSize - 1; i >= 0; i--) { 4437 final ProcessRecord r = mLruProcesses.get(i); 4438 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4439 continue; 4440 } 4441 haveAny = true; 4442 break; 4443 } 4444 if (!haveAny) { 4445 return false; 4446 } 4447 pw.print(prefix); 4448 pw.println("Raw LRU list (dumpsys activity lru):"); 4449 innerPrefix = prefix + " "; 4450 } 4451 int i; 4452 boolean first = true; 4453 for (i = lruSize - 1; i >= mLruProcessActivityStart; i--) { 4454 final ProcessRecord r = mLruProcesses.get(i); 4455 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4456 continue; 4457 } 4458 if (first) { 4459 pw.print(innerPrefix); 4460 pw.println("Activities:"); 4461 first = false; 4462 } 4463 dumpLruEntryLocked(pw, i, r, innerPrefix); 4464 } 4465 first = true; 4466 for (; i >= mLruProcessServiceStart; i--) { 4467 final ProcessRecord r = mLruProcesses.get(i); 4468 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4469 continue; 4470 } 4471 if (first) { 4472 pw.print(innerPrefix); 4473 pw.println("Services:"); 4474 first = false; 4475 } 4476 dumpLruEntryLocked(pw, i, r, innerPrefix); 4477 } 4478 first = true; 4479 for (; i >= 0; i--) { 4480 final ProcessRecord r = mLruProcesses.get(i); 4481 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4482 continue; 4483 } 4484 if (first) { 4485 pw.print(innerPrefix); 4486 pw.println("Other:"); 4487 first = false; 4488 } 4489 dumpLruEntryLocked(pw, i, r, innerPrefix); 4490 } 4491 return true; 4492 } 4493 4494 @GuardedBy({"mService", "mProcLock"}) dumpProcessesLSP(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage, int dumpAppId)4495 void dumpProcessesLSP(FileDescriptor fd, PrintWriter pw, String[] args, 4496 int opti, boolean dumpAll, String dumpPackage, int dumpAppId) { 4497 boolean needSep = false; 4498 int numPers = 0; 4499 4500 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 4501 4502 if (dumpAll || dumpPackage != null) { 4503 final int numOfNames = mProcessNames.getMap().size(); 4504 for (int ip = 0; ip < numOfNames; ip++) { 4505 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 4506 for (int ia = 0, size = procs.size(); ia < size; ia++) { 4507 ProcessRecord r = procs.valueAt(ia); 4508 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4509 continue; 4510 } 4511 if (!needSep) { 4512 pw.println(" All known processes:"); 4513 needSep = true; 4514 } 4515 pw.print(r.isPersistent() ? " *PERS*" : " *APP*"); 4516 pw.print(" UID "); pw.print(procs.keyAt(ia)); 4517 pw.print(" "); pw.println(r); 4518 r.dump(pw, " "); 4519 if (r.isPersistent()) { 4520 numPers++; 4521 } 4522 } 4523 } 4524 } 4525 4526 if (mIsolatedProcesses.size() > 0) { 4527 boolean printed = false; 4528 for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) { 4529 ProcessRecord r = mIsolatedProcesses.valueAt(i); 4530 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4531 continue; 4532 } 4533 if (!printed) { 4534 if (needSep) { 4535 pw.println(); 4536 } 4537 pw.println(" Isolated process list (sorted by uid):"); 4538 printed = true; 4539 needSep = true; 4540 } 4541 pw.print(" Isolated #"); pw.print(i); pw.print(": "); 4542 pw.println(r); 4543 } 4544 } 4545 4546 needSep = mService.dumpActiveInstruments(pw, dumpPackage, needSep); 4547 4548 if (dumpOomLocked(fd, pw, needSep, args, opti, dumpAll, dumpPackage, false)) { 4549 needSep = true; 4550 } 4551 4552 if (mActiveUids.size() > 0) { 4553 needSep |= mActiveUids.dump(pw, dumpPackage, dumpAppId, 4554 "UID states:", needSep); 4555 } 4556 4557 if (dumpAll) { 4558 needSep |= mService.mUidObserverController.dumpValidateUids(pw, 4559 dumpPackage, dumpAppId, "UID validation:", needSep); 4560 } 4561 4562 if (needSep) { 4563 pw.println(); 4564 } 4565 if (dumpLruLocked(pw, dumpPackage, " ")) { 4566 needSep = true; 4567 } 4568 4569 if (getLruSizeLOSP() > 0) { 4570 if (needSep) { 4571 pw.println(); 4572 } 4573 dumpLruListHeaderLocked(pw); 4574 dumpProcessOomList(pw, mService, mLruProcesses, " ", "Proc", "PERS", false, 4575 dumpPackage); 4576 needSep = true; 4577 } 4578 4579 mService.dumpOtherProcessesInfoLSP(fd, pw, dumpAll, dumpPackage, dumpAppId, numPers, 4580 needSep); 4581 } 4582 4583 @GuardedBy({"mService", "mProcLock"}) writeProcessesToProtoLSP(ProtoOutputStream proto, String dumpPackage)4584 void writeProcessesToProtoLSP(ProtoOutputStream proto, String dumpPackage) { 4585 int numPers = 0; 4586 4587 final int numOfNames = mProcessNames.getMap().size(); 4588 for (int ip = 0; ip < numOfNames; ip++) { 4589 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 4590 for (int ia = 0, size = procs.size(); ia < size; ia++) { 4591 ProcessRecord r = procs.valueAt(ia); 4592 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4593 continue; 4594 } 4595 r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.PROCS, 4596 mLruProcesses.indexOf(r) 4597 ); 4598 if (r.isPersistent()) { 4599 numPers++; 4600 } 4601 } 4602 } 4603 4604 for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) { 4605 ProcessRecord r = mIsolatedProcesses.valueAt(i); 4606 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4607 continue; 4608 } 4609 r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS, 4610 mLruProcesses.indexOf(r) 4611 ); 4612 } 4613 4614 final int dumpAppId = mService.getAppId(dumpPackage); 4615 mActiveUids.dumpProto(proto, dumpPackage, dumpAppId, 4616 ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS); 4617 4618 if (getLruSizeLOSP() > 0) { 4619 long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS); 4620 int total = getLruSizeLOSP(); 4621 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total); 4622 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, 4623 total - mLruProcessActivityStart); 4624 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, 4625 total - mLruProcessServiceStart); 4626 writeProcessOomListToProto(proto, 4627 ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, mService, 4628 mLruProcesses, true, dumpPackage); 4629 proto.end(lruToken); 4630 } 4631 4632 mService.writeOtherProcessesInfoToProtoLSP(proto, dumpPackage, dumpAppId, numPers); 4633 } 4634 sortProcessOomList( List<ProcessRecord> origList, String dumpPackage)4635 private static ArrayList<Pair<ProcessRecord, Integer>> sortProcessOomList( 4636 List<ProcessRecord> origList, String dumpPackage) { 4637 ArrayList<Pair<ProcessRecord, Integer>> list = 4638 new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 4639 for (int i = 0, size = origList.size(); i < size; i++) { 4640 ProcessRecord r = origList.get(i); 4641 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4642 continue; 4643 } 4644 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 4645 } 4646 4647 Comparator<Pair<ProcessRecord, Integer>> comparator = 4648 new Comparator<Pair<ProcessRecord, Integer>>() { 4649 @Override 4650 public int compare(Pair<ProcessRecord, Integer> object1, 4651 Pair<ProcessRecord, Integer> object2) { 4652 final int adj = object2.first.mState.getSetAdj() - object1.first.mState.getSetAdj(); 4653 if (adj != 0) { 4654 return adj; 4655 } 4656 final int procState = object2.first.mState.getSetProcState() 4657 - object1.first.mState.getSetProcState(); 4658 if (procState != 0) { 4659 return procState; 4660 } 4661 final int val = object2.second - object1.second; 4662 if (val != 0) { 4663 return val; 4664 } 4665 return 0; 4666 } 4667 }; 4668 4669 Collections.sort(list, comparator); 4670 return list; 4671 } 4672 writeProcessOomListToProto(ProtoOutputStream proto, long fieldId, ActivityManagerService service, List<ProcessRecord> origList, boolean inclDetails, String dumpPackage)4673 private static boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId, 4674 ActivityManagerService service, List<ProcessRecord> origList, 4675 boolean inclDetails, String dumpPackage) { 4676 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage); 4677 if (list.isEmpty()) return false; 4678 4679 final long curUptime = SystemClock.uptimeMillis(); 4680 4681 for (int i = list.size() - 1; i >= 0; i--) { 4682 ProcessRecord r = list.get(i).first; 4683 final ProcessStateRecord state = r.mState; 4684 final ProcessServiceRecord psr = r.mServices; 4685 long token = proto.start(fieldId); 4686 String oomAdj = makeOomAdjString(state.getSetAdj(), true); 4687 proto.write(ProcessOomProto.PERSISTENT, r.isPersistent()); 4688 proto.write(ProcessOomProto.NUM, (origList.size() - 1) - list.get(i).second); 4689 proto.write(ProcessOomProto.OOM_ADJ, oomAdj); 4690 int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN; 4691 switch (state.getSetSchedGroup()) { 4692 case SCHED_GROUP_BACKGROUND: 4693 schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND; 4694 break; 4695 case SCHED_GROUP_DEFAULT: 4696 schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT; 4697 break; 4698 case SCHED_GROUP_TOP_APP: 4699 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP; 4700 break; 4701 case SCHED_GROUP_TOP_APP_BOUND: 4702 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND; 4703 break; 4704 } 4705 if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) { 4706 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup); 4707 } 4708 if (state.hasForegroundActivities()) { 4709 proto.write(ProcessOomProto.ACTIVITIES, true); 4710 } else if (psr.hasForegroundServices()) { 4711 proto.write(ProcessOomProto.SERVICES, true); 4712 } 4713 proto.write(ProcessOomProto.STATE, 4714 makeProcStateProtoEnum(state.getCurProcState())); 4715 proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.mProfile.getTrimMemoryLevel()); 4716 r.dumpDebug(proto, ProcessOomProto.PROC); 4717 proto.write(ProcessOomProto.ADJ_TYPE, state.getAdjType()); 4718 if (state.getAdjSource() != null || state.getAdjTarget() != null) { 4719 if (state.getAdjTarget() instanceof ComponentName) { 4720 ComponentName cn = (ComponentName) state.getAdjTarget(); 4721 cn.dumpDebug(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME); 4722 } else if (state.getAdjTarget() != null) { 4723 proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, state.getAdjTarget().toString()); 4724 } 4725 if (state.getAdjSource() instanceof ProcessRecord) { 4726 ProcessRecord p = (ProcessRecord) state.getAdjSource(); 4727 p.dumpDebug(proto, ProcessOomProto.ADJ_SOURCE_PROC); 4728 } else if (state.getAdjSource() != null) { 4729 proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, state.getAdjSource().toString()); 4730 } 4731 } 4732 if (inclDetails) { 4733 long detailToken = proto.start(ProcessOomProto.DETAIL); 4734 proto.write(ProcessOomProto.Detail.MAX_ADJ, state.getMaxAdj()); 4735 proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, state.getCurRawAdj()); 4736 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, state.getSetRawAdj()); 4737 proto.write(ProcessOomProto.Detail.CUR_ADJ, state.getCurAdj()); 4738 proto.write(ProcessOomProto.Detail.SET_ADJ, state.getSetAdj()); 4739 proto.write(ProcessOomProto.Detail.CURRENT_STATE, 4740 makeProcStateProtoEnum(state.getCurProcState())); 4741 proto.write(ProcessOomProto.Detail.SET_STATE, 4742 makeProcStateProtoEnum(state.getSetProcState())); 4743 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString( 4744 r.mProfile.getLastPss() * 1024, new StringBuilder())); 4745 proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString( 4746 r.mProfile.getLastSwapPss() * 1024, new StringBuilder())); 4747 // TODO(b/296454553): This proto field should be replaced with last cached RSS once 4748 // AppProfiler is no longer collecting PSS. 4749 proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString( 4750 r.mProfile.getLastCachedPss() * 1024, new StringBuilder())); 4751 proto.write(ProcessOomProto.Detail.CACHED, state.isCached()); 4752 proto.write(ProcessOomProto.Detail.EMPTY, state.isEmpty()); 4753 proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, psr.hasAboveClient()); 4754 4755 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) { 4756 long lastCpuTime = r.mProfile.mLastCpuTime.get(); 4757 long uptimeSince = curUptime - service.mLastPowerCheckUptime; 4758 if (lastCpuTime != 0 && uptimeSince > 0) { 4759 long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime; 4760 long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME); 4761 proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince); 4762 proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed); 4763 proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION, 4764 (100.0 * timeUsed) / uptimeSince); 4765 proto.end(cpuTimeToken); 4766 } 4767 } 4768 proto.end(detailToken); 4769 } 4770 proto.end(token); 4771 } 4772 4773 return true; 4774 } 4775 dumpProcessOomList(PrintWriter pw, ActivityManagerService service, List<ProcessRecord> origList, String prefix, String normalLabel, String persistentLabel, boolean inclDetails, String dumpPackage)4776 private static boolean dumpProcessOomList(PrintWriter pw, 4777 ActivityManagerService service, List<ProcessRecord> origList, 4778 String prefix, String normalLabel, String persistentLabel, 4779 boolean inclDetails, String dumpPackage) { 4780 4781 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage); 4782 if (list.isEmpty()) return false; 4783 4784 final long curUptime = SystemClock.uptimeMillis(); 4785 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 4786 4787 for (int i = list.size() - 1; i >= 0; i--) { 4788 ProcessRecord r = list.get(i).first; 4789 final ProcessStateRecord state = r.mState; 4790 final ProcessServiceRecord psr = r.mServices; 4791 String oomAdj = makeOomAdjString(state.getSetAdj(), false); 4792 char schedGroup; 4793 switch (state.getSetSchedGroup()) { 4794 case SCHED_GROUP_BACKGROUND: 4795 schedGroup = 'b'; 4796 break; 4797 case SCHED_GROUP_DEFAULT: 4798 schedGroup = 'F'; 4799 break; 4800 case SCHED_GROUP_TOP_APP: 4801 schedGroup = 'T'; 4802 break; 4803 case SCHED_GROUP_RESTRICTED: 4804 schedGroup = 'R'; 4805 break; 4806 case SCHED_GROUP_TOP_APP_BOUND: 4807 schedGroup = 'B'; 4808 break; 4809 default: 4810 schedGroup = '?'; 4811 break; 4812 } 4813 char foreground; 4814 if (state.hasForegroundActivities()) { 4815 foreground = 'A'; 4816 } else if (psr.hasForegroundServices()) { 4817 foreground = 'S'; 4818 } else { 4819 foreground = ' '; 4820 } 4821 String procState = makeProcStateString(state.getCurProcState()); 4822 pw.print(prefix); 4823 pw.print(r.isPersistent() ? persistentLabel : normalLabel); 4824 pw.print(" #"); 4825 int num = (origList.size() - 1) - list.get(i).second; 4826 if (num < 10) pw.print(' '); 4827 pw.print(num); 4828 pw.print(": "); 4829 pw.print(oomAdj); 4830 pw.print(' '); 4831 pw.print(schedGroup); 4832 pw.print('/'); 4833 pw.print(foreground); 4834 pw.print('/'); 4835 pw.print(procState); 4836 pw.print(' '); 4837 ActivityManager.printCapabilitiesSummary(pw, state.getCurCapability()); 4838 pw.print(' '); 4839 pw.print(" t:"); 4840 if (r.mProfile.getTrimMemoryLevel() < 10) pw.print(' '); 4841 pw.print(r.mProfile.getTrimMemoryLevel()); 4842 pw.print(' '); 4843 pw.print(r.toShortString()); 4844 pw.print(" ("); 4845 pw.print(state.getAdjType()); 4846 pw.println(')'); 4847 if (state.getAdjSource() != null || state.getAdjTarget() != null) { 4848 pw.print(prefix); 4849 pw.print(" "); 4850 if (state.getAdjTarget() instanceof ComponentName) { 4851 pw.print(((ComponentName) state.getAdjTarget()).flattenToShortString()); 4852 } else if (state.getAdjTarget() != null) { 4853 pw.print(state.getAdjTarget().toString()); 4854 } else { 4855 pw.print("{null}"); 4856 } 4857 pw.print("<="); 4858 if (state.getAdjSource() instanceof ProcessRecord) { 4859 pw.print("Proc{"); 4860 pw.print(((ProcessRecord) state.getAdjSource()).toShortString()); 4861 pw.println("}"); 4862 } else if (state.getAdjSource() != null) { 4863 pw.println(state.getAdjSource().toString()); 4864 } else { 4865 pw.println("{null}"); 4866 } 4867 } 4868 if (inclDetails) { 4869 pw.print(prefix); 4870 pw.print(" "); 4871 pw.print("oom: max="); pw.print(state.getMaxAdj()); 4872 pw.print(" curRaw="); pw.print(state.getCurRawAdj()); 4873 pw.print(" setRaw="); pw.print(state.getSetRawAdj()); 4874 pw.print(" cur="); pw.print(state.getCurAdj()); 4875 pw.print(" set="); pw.println(state.getSetAdj()); 4876 pw.print(prefix); 4877 pw.print(" "); 4878 pw.print("state: cur="); pw.print(makeProcStateString(state.getCurProcState())); 4879 pw.print(" set="); pw.print(makeProcStateString(state.getSetProcState())); 4880 // These values won't be collected if the flag is enabled. 4881 if (service.mAppProfiler.isProfilingPss()) { 4882 pw.print(" lastPss="); 4883 DebugUtils.printSizeValue(pw, r.mProfile.getLastPss() * 1024); 4884 pw.print(" lastSwapPss="); 4885 DebugUtils.printSizeValue(pw, r.mProfile.getLastSwapPss() * 1024); 4886 pw.print(" lastCachedPss="); 4887 DebugUtils.printSizeValue(pw, r.mProfile.getLastCachedPss() * 1024); 4888 } else { 4889 pw.print(" lastRss="); 4890 DebugUtils.printSizeValue(pw, r.mProfile.getLastRss() * 1024); 4891 pw.print(" lastCachedRss="); 4892 DebugUtils.printSizeValue(pw, r.mProfile.getLastCachedRss() * 1024); 4893 } 4894 pw.println(); 4895 pw.print(prefix); 4896 pw.print(" "); 4897 pw.print("cached="); pw.print(state.isCached()); 4898 pw.print(" empty="); pw.print(state.isEmpty()); 4899 pw.print(" hasAboveClient="); pw.println(psr.hasAboveClient()); 4900 4901 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) { 4902 long lastCpuTime = r.mProfile.mLastCpuTime.get(); 4903 if (lastCpuTime != 0 && uptimeSince > 0) { 4904 long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime; 4905 pw.print(prefix); 4906 pw.print(" "); 4907 pw.print("run cpu over "); 4908 TimeUtils.formatDuration(uptimeSince, pw); 4909 pw.print(" used "); 4910 TimeUtils.formatDuration(timeUsed, pw); 4911 pw.print(" ("); 4912 pw.print((timeUsed * 100) / uptimeSince); 4913 pw.println("%)"); 4914 } 4915 } 4916 } 4917 } 4918 return true; 4919 } 4920 printOomLevel(PrintWriter pw, String name, int adj)4921 private void printOomLevel(PrintWriter pw, String name, int adj) { 4922 pw.print(" "); 4923 if (adj >= 0) { 4924 pw.print(' '); 4925 if (adj < 10) pw.print(' '); 4926 } else { 4927 if (adj > -10) pw.print(' '); 4928 } 4929 pw.print(adj); 4930 pw.print(": "); 4931 pw.print(name); 4932 pw.print(" ("); 4933 pw.print(ActivityManagerService.stringifySize(getMemLevel(adj), 1024)); 4934 pw.println(")"); 4935 } 4936 4937 @GuardedBy("mService") dumpOomLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String[] args, int opti, boolean dumpAll, String dumpPackage, boolean inclGc)4938 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String[] args, 4939 int opti, boolean dumpAll, String dumpPackage, boolean inclGc) { 4940 if (getLruSizeLOSP() > 0) { 4941 if (needSep) pw.println(); 4942 needSep = true; 4943 pw.println(" OOM levels:"); 4944 printOomLevel(pw, "SYSTEM_ADJ", SYSTEM_ADJ); 4945 printOomLevel(pw, "PERSISTENT_PROC_ADJ", PERSISTENT_PROC_ADJ); 4946 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", PERSISTENT_SERVICE_ADJ); 4947 printOomLevel(pw, "FOREGROUND_APP_ADJ", FOREGROUND_APP_ADJ); 4948 printOomLevel(pw, "VISIBLE_APP_ADJ", VISIBLE_APP_ADJ); 4949 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", PERCEPTIBLE_APP_ADJ); 4950 printOomLevel(pw, "PERCEPTIBLE_MEDIUM_APP_ADJ", PERCEPTIBLE_MEDIUM_APP_ADJ); 4951 printOomLevel(pw, "PERCEPTIBLE_LOW_APP_ADJ", PERCEPTIBLE_LOW_APP_ADJ); 4952 printOomLevel(pw, "BACKUP_APP_ADJ", BACKUP_APP_ADJ); 4953 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", HEAVY_WEIGHT_APP_ADJ); 4954 printOomLevel(pw, "SERVICE_ADJ", SERVICE_ADJ); 4955 printOomLevel(pw, "HOME_APP_ADJ", HOME_APP_ADJ); 4956 printOomLevel(pw, "PREVIOUS_APP_ADJ", PREVIOUS_APP_ADJ); 4957 printOomLevel(pw, "SERVICE_B_ADJ", SERVICE_B_ADJ); 4958 printOomLevel(pw, "CACHED_APP_MIN_ADJ", CACHED_APP_MIN_ADJ); 4959 printOomLevel(pw, "CACHED_APP_MAX_ADJ", CACHED_APP_MAX_ADJ); 4960 4961 if (needSep) pw.println(); 4962 pw.print(" Process OOM control ("); pw.print(getLruSizeLOSP()); 4963 pw.print(" total, non-act at "); 4964 pw.print(getLruSizeLOSP() - mLruProcessActivityStart); 4965 pw.print(", non-svc at "); 4966 pw.print(getLruSizeLOSP() - mLruProcessServiceStart); 4967 pw.println("):"); 4968 dumpProcessOomList(pw, mService, mLruProcesses, 4969 " ", "Proc", "PERS", true, dumpPackage); 4970 needSep = true; 4971 } 4972 4973 synchronized (mService.mAppProfiler.mProfilerLock) { 4974 mService.mAppProfiler.dumpProcessesToGc(pw, needSep, dumpPackage); 4975 } 4976 4977 pw.println(); 4978 mService.mAtmInternal.dumpForOom(pw); 4979 4980 return true; 4981 } 4982 registerProcessObserver(IProcessObserver observer)4983 void registerProcessObserver(IProcessObserver observer) { 4984 synchronized (mProcessObservers) { 4985 mProcessObservers.register(observer); 4986 } 4987 } 4988 unregisterProcessObserver(IProcessObserver observer)4989 void unregisterProcessObserver(IProcessObserver observer) { 4990 synchronized (mProcessObservers) { 4991 mProcessObservers.unregister(observer); 4992 } 4993 } 4994 dispatchProcessesChanged()4995 void dispatchProcessesChanged() { 4996 int numOfChanges; 4997 synchronized (mProcessChangeLock) { 4998 numOfChanges = mPendingProcessChanges.size(); 4999 if (mActiveProcessChanges.length < numOfChanges) { 5000 mActiveProcessChanges = new ProcessChangeItem[numOfChanges]; 5001 } 5002 mPendingProcessChanges.toArray(mActiveProcessChanges); 5003 mPendingProcessChanges.clear(); 5004 if (DEBUG_PROCESS_OBSERVERS) { 5005 Slog.i(TAG_PROCESS_OBSERVERS, 5006 "*** Delivering " + numOfChanges + " process changes"); 5007 } 5008 } 5009 5010 synchronized (mProcessObservers) { 5011 int i = mProcessObservers.beginBroadcast(); 5012 while (i > 0) { 5013 i--; 5014 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 5015 if (observer != null) { 5016 try { 5017 for (int j = 0; j < numOfChanges; j++) { 5018 ProcessChangeItem item = mActiveProcessChanges[j]; 5019 if ((item.changes & ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 5020 if (DEBUG_PROCESS_OBSERVERS) { 5021 Slog.i(TAG_PROCESS_OBSERVERS, 5022 "ACTIVITIES CHANGED pid=" + item.pid + " uid=" 5023 + item.uid + ": " + item.foregroundActivities); 5024 } 5025 observer.onForegroundActivitiesChanged(item.pid, item.uid, 5026 item.foregroundActivities); 5027 } 5028 if ((item.changes & ProcessChangeItem.CHANGE_FOREGROUND_SERVICES) 5029 != 0) { 5030 if (DEBUG_PROCESS_OBSERVERS) { 5031 Slog.i(TAG_PROCESS_OBSERVERS, 5032 "FOREGROUND SERVICES CHANGED pid=" + item.pid + " uid=" 5033 + item.uid + ": " + item.foregroundServiceTypes); 5034 } 5035 observer.onForegroundServicesChanged(item.pid, item.uid, 5036 item.foregroundServiceTypes); 5037 } 5038 } 5039 } catch (RemoteException e) { 5040 } 5041 } 5042 } 5043 mProcessObservers.finishBroadcast(); 5044 } 5045 5046 synchronized (mProcessChangeLock) { 5047 for (int j = 0; j < numOfChanges; j++) { 5048 mAvailProcessChanges.add(mActiveProcessChanges[j]); 5049 } 5050 } 5051 } 5052 5053 @GuardedBy("mService") enqueueProcessChangeItemLocked(int pid, int uid, int changes, int foregroundServicetypes)5054 void enqueueProcessChangeItemLocked(int pid, int uid, int changes, int foregroundServicetypes) { 5055 synchronized (mProcessChangeLock) { 5056 final ProcessChangeItem item = enqueueProcessChangeItemLocked(pid, uid); 5057 item.changes |= changes; 5058 item.foregroundServiceTypes = foregroundServicetypes; 5059 } 5060 } 5061 5062 @GuardedBy("mService") enqueueProcessChangeItemLocked(int pid, int uid, int changes, boolean hasForegroundActivities)5063 void enqueueProcessChangeItemLocked(int pid, int uid, int changes, 5064 boolean hasForegroundActivities) { 5065 synchronized (mProcessChangeLock) { 5066 final ProcessChangeItem item = enqueueProcessChangeItemLocked(pid, uid); 5067 item.changes |= changes; 5068 item.foregroundActivities = hasForegroundActivities; 5069 } 5070 } 5071 5072 @GuardedBy({"mService", "mProcessChangeLock"}) enqueueProcessChangeItemLocked(int pid, int uid)5073 private ProcessChangeItem enqueueProcessChangeItemLocked(int pid, int uid) { 5074 int i = mPendingProcessChanges.size() - 1; 5075 ActivityManagerService.ProcessChangeItem item = null; 5076 while (i >= 0) { 5077 item = mPendingProcessChanges.get(i); 5078 if (item.pid == pid) { 5079 if (DEBUG_PROCESS_OBSERVERS) { 5080 Slog.i(TAG_PROCESS_OBSERVERS, "Re-using existing item: " + item); 5081 } 5082 break; 5083 } 5084 i--; 5085 } 5086 5087 if (i < 0) { 5088 // No existing item in pending changes; need a new one. 5089 final int num = mAvailProcessChanges.size(); 5090 if (num > 0) { 5091 item = mAvailProcessChanges.remove(num - 1); 5092 if (DEBUG_PROCESS_OBSERVERS) { 5093 Slog.i(TAG_PROCESS_OBSERVERS, "Retrieving available item: " + item); 5094 } 5095 } else { 5096 item = new ActivityManagerService.ProcessChangeItem(); 5097 if (DEBUG_PROCESS_OBSERVERS) { 5098 Slog.i(TAG_PROCESS_OBSERVERS, "Allocating new item: " + item); 5099 } 5100 } 5101 item.changes = 0; 5102 item.pid = pid; 5103 item.uid = uid; 5104 if (mPendingProcessChanges.size() == 0) { 5105 if (DEBUG_PROCESS_OBSERVERS) { 5106 Slog.i(TAG_PROCESS_OBSERVERS, "*** Enqueueing dispatch processes changed!"); 5107 } 5108 mService.mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG) 5109 .sendToTarget(); 5110 } 5111 mPendingProcessChanges.add(item); 5112 } 5113 5114 return item; 5115 } 5116 5117 @GuardedBy("mService") scheduleDispatchProcessDiedLocked(int pid, int uid)5118 void scheduleDispatchProcessDiedLocked(int pid, int uid) { 5119 synchronized (mProcessChangeLock) { 5120 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) { 5121 ProcessChangeItem item = mPendingProcessChanges.get(i); 5122 if (pid > 0 && item.pid == pid) { 5123 mPendingProcessChanges.remove(i); 5124 mAvailProcessChanges.add(item); 5125 } 5126 } 5127 mService.mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, pid, uid, 5128 null).sendToTarget(); 5129 } 5130 } 5131 dispatchProcessStarted(ProcessRecord app, int pid)5132 void dispatchProcessStarted(ProcessRecord app, int pid) { 5133 if (!android.app.Flags.enableProcessObserverBroadcastOnProcessStarted()) { 5134 Slog.i(TAG, "ProcessObserver broadcast disabled"); 5135 return; 5136 } 5137 synchronized (mProcessObservers) { 5138 int i = mProcessObservers.beginBroadcast(); 5139 while (i > 0) { 5140 i--; 5141 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 5142 if (observer != null) { 5143 try { 5144 observer.onProcessStarted(pid, app.uid, app.info.uid, 5145 app.info.packageName, app.processName); 5146 } catch (RemoteException e) { 5147 } 5148 } 5149 } 5150 mProcessObservers.finishBroadcast(); 5151 } 5152 } 5153 dispatchProcessDied(int pid, int uid)5154 void dispatchProcessDied(int pid, int uid) { 5155 synchronized (mProcessObservers) { 5156 int i = mProcessObservers.beginBroadcast(); 5157 while (i > 0) { 5158 i--; 5159 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 5160 if (observer != null) { 5161 try { 5162 observer.onProcessDied(pid, uid); 5163 } catch (RemoteException e) { 5164 } 5165 } 5166 } 5167 mProcessObservers.finishBroadcast(); 5168 } 5169 } 5170 5171 @GuardedBy(anyOf = {"mService", "mProcLock"}) collectProcessesLOSP(int start, boolean allPkgs, String[] args)5172 ArrayList<ProcessRecord> collectProcessesLOSP(int start, boolean allPkgs, String[] args) { 5173 ArrayList<ProcessRecord> procs; 5174 if (args != null && args.length > start 5175 && args[start].charAt(0) != '-') { 5176 procs = new ArrayList<ProcessRecord>(); 5177 int pid = -1; 5178 try { 5179 pid = Integer.parseInt(args[start]); 5180 } catch (NumberFormatException e) { 5181 } 5182 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5183 ProcessRecord proc = mLruProcesses.get(i); 5184 if (proc.getPid() > 0 && proc.getPid() == pid) { 5185 procs.add(proc); 5186 } else if (allPkgs && proc.getPkgList() != null 5187 && proc.getPkgList().containsKey(args[start])) { 5188 procs.add(proc); 5189 } else if (proc.processName.equals(args[start])) { 5190 procs.add(proc); 5191 } 5192 } 5193 if (procs.size() <= 0) { 5194 return null; 5195 } 5196 } else { 5197 procs = new ArrayList<ProcessRecord>(mLruProcesses); 5198 } 5199 return procs; 5200 } 5201 5202 @GuardedBy(anyOf = {"mService", "mProcLock"}) updateApplicationInfoLOSP(List<String> packagesToUpdate, int userId, boolean updateFrameworkRes)5203 void updateApplicationInfoLOSP(List<String> packagesToUpdate, int userId, 5204 boolean updateFrameworkRes) { 5205 final ArrayMap<String, ApplicationInfo> applicationInfoByPackage = new ArrayMap<>(); 5206 for (int i = packagesToUpdate.size() - 1; i >= 0; i--) { 5207 final String packageName = packagesToUpdate.get(i); 5208 final ApplicationInfo ai = mService.getPackageManagerInternal().getApplicationInfo( 5209 packageName, STOCK_PM_FLAGS, Process.SYSTEM_UID, userId); 5210 if (ai != null) { 5211 applicationInfoByPackage.put(packageName, ai); 5212 } 5213 } 5214 mService.mActivityTaskManager.updateActivityApplicationInfo(userId, 5215 applicationInfoByPackage); 5216 5217 final ArrayList<WindowProcessController> targetProcesses = new ArrayList<>(); 5218 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5219 final ProcessRecord app = mLruProcesses.get(i); 5220 if (app.getThread() == null) { 5221 continue; 5222 } 5223 5224 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5225 continue; 5226 } 5227 5228 app.getPkgList().forEachPackage(packageName -> { 5229 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) { 5230 try { 5231 final ApplicationInfo ai = applicationInfoByPackage.get(packageName); 5232 if (ai != null) { 5233 if (ai.packageName.equals(app.info.packageName)) { 5234 app.info = ai; 5235 app.getWindowProcessController().updateApplicationInfo(ai); 5236 PlatformCompatCache.getInstance() 5237 .onApplicationInfoChanged(ai); 5238 } 5239 app.getThread().scheduleApplicationInfoChanged(ai); 5240 targetProcesses.add(app.getWindowProcessController()); 5241 } 5242 } catch (RemoteException e) { 5243 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", 5244 packageName, app)); 5245 } 5246 } 5247 }); 5248 } 5249 5250 mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes); 5251 } 5252 5253 @GuardedBy("mService") sendPackageBroadcastLocked(int cmd, String[] packages, @CanBeALL @UserIdInt int userId)5254 void sendPackageBroadcastLocked(int cmd, String[] packages, @CanBeALL @UserIdInt int userId) { 5255 boolean foundProcess = false; 5256 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5257 ProcessRecord r = mLruProcesses.get(i); 5258 final IApplicationThread thread = r.getThread(); 5259 if (thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 5260 try { 5261 for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) { 5262 if (packages[index].equals(r.info.packageName)) { 5263 foundProcess = true; 5264 } 5265 } 5266 thread.dispatchPackageBroadcast(cmd, packages); 5267 } catch (RemoteException ex) { 5268 } 5269 } 5270 } 5271 5272 if (!foundProcess) { 5273 try { 5274 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages); 5275 } catch (RemoteException ignored) { 5276 } 5277 } 5278 } 5279 5280 /** 5281 * Returns the uid's process state or {@link ActivityManager#PROCESS_STATE_NONEXISTENT} 5282 * if not running 5283 */ 5284 @GuardedBy(anyOf = {"mService", "mProcLock"}) getUidProcStateLOSP(int uid)5285 int getUidProcStateLOSP(int uid) { 5286 UidRecord uidRec = mActiveUids.get(uid); 5287 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState(); 5288 } 5289 5290 /** 5291 * Returns the uid's process capability or {@link ActivityManager#PROCESS_CAPABILITY_NONE} 5292 * if not running 5293 */ 5294 @GuardedBy(anyOf = {"mService", "mProcLock"}) getUidProcessCapabilityLOSP(int uid)5295 @ProcessCapability int getUidProcessCapabilityLOSP(int uid) { 5296 UidRecord uidRec = mActiveUids.get(uid); 5297 return uidRec == null ? PROCESS_CAPABILITY_NONE : uidRec.getCurCapability(); 5298 } 5299 5300 /** Returns the UidRecord for the given uid, if it exists. */ 5301 @GuardedBy(anyOf = {"mService", "mProcLock"}) getUidRecordLOSP(int uid)5302 UidRecord getUidRecordLOSP(int uid) { 5303 return mActiveUids.get(uid); 5304 } 5305 5306 /** 5307 * Call {@link ActivityManagerService#doStopUidLocked} 5308 * (which will also stop background services) for all idle UIDs. 5309 */ 5310 @GuardedBy("mService") doStopUidForIdleUidsLocked()5311 void doStopUidForIdleUidsLocked() { 5312 final int size = mActiveUids.size(); 5313 for (int i = 0; i < size; i++) { 5314 final int uid = mActiveUids.keyAt(i); 5315 if (UserHandle.isCore(uid)) { 5316 continue; 5317 } 5318 final UidRecord uidRec = mActiveUids.valueAt(i); 5319 if (!uidRec.isIdle()) { 5320 continue; 5321 } 5322 mService.doStopUidLocked(uidRec.getUid(), uidRec); 5323 } 5324 } 5325 5326 /** 5327 * Checks if the uid is coming from background to foreground or vice versa and returns 5328 * appropriate block state based on this. 5329 * 5330 * @return blockState based on whether the uid is coming from background to foreground or 5331 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or 5332 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise 5333 * {@link #NETWORK_STATE_NO_CHANGE}. 5334 */ 5335 @VisibleForTesting 5336 @GuardedBy(anyOf = {"mService", "mProcLock"}) getBlockStateForUid(UidRecord uidRec)5337 int getBlockStateForUid(UidRecord uidRec) { 5338 // Denotes whether uid's process state is currently allowed network access. 5339 final boolean isAllowed = 5340 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState(), 5341 uidRec.getCurCapability()) 5342 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState(), 5343 uidRec.getCurCapability()); 5344 // Denotes whether uid's process state was previously allowed network access. 5345 final boolean wasAllowed = 5346 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getSetProcState(), 5347 uidRec.getSetCapability()) 5348 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getSetProcState(), 5349 uidRec.getSetCapability()); 5350 5351 // When the uid is coming to foreground, AMS should inform the app thread that it should 5352 // block for the network rules to get updated before launching an activity. 5353 if (!wasAllowed && isAllowed) { 5354 return NETWORK_STATE_BLOCK; 5355 } 5356 // When the uid is going to background, AMS should inform the app thread that if an 5357 // activity launch is blocked for the network rules to get updated, it should be unblocked. 5358 if (wasAllowed && !isAllowed) { 5359 return NETWORK_STATE_UNBLOCK; 5360 } 5361 return NETWORK_STATE_NO_CHANGE; 5362 } 5363 5364 /** 5365 * Increments the {@link UidRecord#curProcStateSeq} for all uids using global seq counter 5366 * {@link ProcessList#mProcStateSeqCounter} and checks if any uid is coming 5367 * from background to foreground or vice versa and if so, notifies the app if it needs to block. 5368 */ 5369 @VisibleForTesting 5370 @GuardedBy(anyOf = {"mService", "mProcLock"}) incrementProcStateSeqAndNotifyAppsLOSP(ActiveUids activeUids)5371 void incrementProcStateSeqAndNotifyAppsLOSP(ActiveUids activeUids) { 5372 for (int i = activeUids.size() - 1; i >= 0; --i) { 5373 final UidRecord uidRec = activeUids.valueAt(i); 5374 uidRec.curProcStateSeq = getNextProcStateSeq(); 5375 } 5376 if (mService.mConstants.mNetworkAccessTimeoutMs <= 0) { 5377 return; 5378 } 5379 // Used for identifying which uids need to block for network. 5380 ArrayList<Integer> blockingUids = null; 5381 for (int i = activeUids.size() - 1; i >= 0; --i) { 5382 final UidRecord uidRec = activeUids.valueAt(i); 5383 // If the network is not restricted for uid, then nothing to do here. 5384 if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.getUid())) { 5385 continue; 5386 } 5387 if (!UserHandle.isApp(uidRec.getUid()) || !uidRec.hasInternetPermission) { 5388 continue; 5389 } 5390 // If process state and capabilities are not changed, then there's nothing to do. 5391 if (uidRec.getSetProcState() == uidRec.getCurProcState() 5392 && uidRec.getSetCapability() == uidRec.getCurCapability()) { 5393 continue; 5394 } 5395 final int blockState = getBlockStateForUid(uidRec); 5396 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as 5397 // there's nothing the app needs to do in this scenario. 5398 if (blockState == NETWORK_STATE_NO_CHANGE) { 5399 continue; 5400 } 5401 synchronized (uidRec.networkStateLock) { 5402 if (blockState == NETWORK_STATE_BLOCK) { 5403 if (blockingUids == null) { 5404 blockingUids = new ArrayList<>(); 5405 } 5406 blockingUids.add(uidRec.getUid()); 5407 } else { 5408 if (DEBUG_NETWORK) { 5409 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking" 5410 + " threads for uid: " + uidRec); 5411 } 5412 if (uidRec.procStateSeqWaitingForNetwork != 0) { 5413 uidRec.networkStateLock.notifyAll(); 5414 } 5415 } 5416 } 5417 } 5418 5419 // There are no uids that need to block, so nothing more to do. 5420 if (blockingUids == null) { 5421 return; 5422 } 5423 5424 for (int i = mLruProcesses.size() - 1; i >= 0; --i) { 5425 final ProcessRecord app = mLruProcesses.get(i); 5426 if (!blockingUids.contains(app.uid)) { 5427 continue; 5428 } 5429 final IApplicationThread thread = app.getThread(); 5430 if (!app.isKilledByAm() && thread != null) { 5431 final UidRecord uidRec = getUidRecordLOSP(app.uid); 5432 try { 5433 if (DEBUG_NETWORK) { 5434 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: " 5435 + uidRec); 5436 } 5437 if (uidRec != null) { 5438 thread.setNetworkBlockSeq(uidRec.curProcStateSeq); 5439 } 5440 } catch (RemoteException ignored) { 5441 } 5442 } 5443 } 5444 } 5445 getNextProcStateSeq()5446 long getNextProcStateSeq() { 5447 return ++mProcStateSeqCounter; 5448 } 5449 5450 /** 5451 * Create a server socket in system_server, zygote will connect to it 5452 * in order to send unsolicited messages to system_server. 5453 */ createSystemServerSocketForZygote()5454 private LocalSocket createSystemServerSocketForZygote() { 5455 // The file system entity for this socket is created with 0666 perms, owned 5456 // by system:system. selinux restricts things so that only zygotes can 5457 // access it. 5458 final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH); 5459 if (socketFile.exists()) { 5460 socketFile.delete(); 5461 } 5462 5463 LocalSocket serverSocket = null; 5464 try { 5465 serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM); 5466 serverSocket.bind(new LocalSocketAddress( 5467 UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM)); 5468 Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666); 5469 } catch (Exception e) { 5470 if (serverSocket != null) { 5471 try { 5472 serverSocket.close(); 5473 } catch (IOException ex) { 5474 } 5475 serverSocket = null; 5476 } 5477 } 5478 return serverSocket; 5479 } 5480 5481 /** 5482 * Handle the unsolicited message from zygote. 5483 */ handleZygoteMessages(FileDescriptor fd, int events)5484 private int handleZygoteMessages(FileDescriptor fd, int events) { 5485 final int eventFd = fd.getInt$(); 5486 if ((events & EVENT_INPUT) != 0) { 5487 // An incoming message from zygote 5488 try { 5489 final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0, 5490 mZygoteUnsolicitedMessage.length); 5491 if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld( 5492 mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) { 5493 mAppExitInfoTracker.handleZygoteSigChld( 5494 mZygoteSigChldMessage[0] /* pid */, 5495 mZygoteSigChldMessage[1] /* uid */, 5496 mZygoteSigChldMessage[2] /* status */); 5497 } 5498 } catch (Exception e) { 5499 Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e); 5500 } 5501 } 5502 return EVENT_INPUT; 5503 } 5504 5505 /** 5506 * Handle the death notification if it's a dying app. 5507 * 5508 * @return {@code true} if it's a dying app that we were tracking. 5509 */ 5510 @GuardedBy("mService") handleDyingAppDeathLocked(ProcessRecord app, int pid)5511 boolean handleDyingAppDeathLocked(ProcessRecord app, int pid) { 5512 if (mProcessNames.get(app.processName, app.uid) != app 5513 && mDyingProcesses.get(app.processName, app.uid) == app) { 5514 // App has been removed already, meaning cleanup has done. 5515 Slog.v(TAG, "Got obituary of " + pid + ":" + app.processName); 5516 app.unlinkDeathRecipient(); 5517 // It's really gone now, let's remove from the dying process list. 5518 mDyingProcesses.remove(app.processName, app.uid); 5519 app.setDyingPid(0); 5520 handlePrecedingAppDiedLocked(app); 5521 // Remove from the LRU list if it's still there. 5522 removeLruProcessLocked(app); 5523 return true; 5524 } 5525 return false; 5526 } 5527 5528 /** 5529 * Handle the case where the given app is a preceding instance of another process instance. 5530 * 5531 * @return {@code false} if this given app should not be allowed to restart. 5532 */ 5533 @GuardedBy("mService") handlePrecedingAppDiedLocked(ProcessRecord app)5534 boolean handlePrecedingAppDiedLocked(ProcessRecord app) { 5535 if (app.mSuccessor != null) { 5536 // We don't allow restart with this ProcessRecord now, 5537 // because we have created a new one already. 5538 // If it's persistent, add the successor to mPersistentStartingProcesses 5539 if (app.isPersistent() && !app.isRemoved()) { 5540 if (mService.mPersistentStartingProcesses.indexOf(app.mSuccessor) < 0) { 5541 mService.mPersistentStartingProcesses.add(app.mSuccessor); 5542 } 5543 } 5544 // clean up the field so the successor's proc starter could proceed. 5545 app.mSuccessor.mPredecessor = null; 5546 app.mSuccessor = null; 5547 // Remove any pending timeout msg. 5548 mService.mProcStartHandler.removeMessages( 5549 ProcStartHandler.MSG_PROCESS_KILL_TIMEOUT, app); 5550 // Kick off the proc start for the succeeding instance 5551 mService.mProcStartHandler.obtainMessage( 5552 ProcStartHandler.MSG_PROCESS_DIED, app).sendToTarget(); 5553 return false; 5554 } 5555 return true; 5556 } 5557 5558 @GuardedBy("mService") updateBackgroundRestrictedForUidPackageLocked(int uid, String packageName, boolean restricted)5559 void updateBackgroundRestrictedForUidPackageLocked(int uid, String packageName, 5560 boolean restricted) { 5561 final UidRecord uidRec = getUidRecordLOSP(uid); 5562 if (uidRec != null) { 5563 final long nowElapsed = SystemClock.elapsedRealtime(); 5564 uidRec.forEachProcess(app -> { 5565 if (TextUtils.equals(app.info.packageName, packageName)) { 5566 app.mState.setBackgroundRestricted(restricted); 5567 if (restricted) { 5568 mAppsInBackgroundRestricted.add(app); 5569 final long future = killAppIfBgRestrictedAndCachedIdleLocked( 5570 app, nowElapsed); 5571 if (future > 0 5572 && (mService.mDeterministicUidIdle 5573 || !mService.mHandler.hasMessages(IDLE_UIDS_MSG))) { 5574 mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 5575 future - nowElapsed); 5576 } 5577 } else { 5578 mAppsInBackgroundRestricted.remove(app); 5579 } 5580 if (!app.isKilledByAm()) { 5581 mService.enqueueOomAdjTargetLocked(app); 5582 } 5583 } 5584 }); 5585 /* Will be a no-op if nothing pending */ 5586 mService.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_RESTRICTION_CHANGE); 5587 } 5588 } 5589 5590 /** 5591 * Kill the given app if it's in cached idle and background restricted mode. 5592 * 5593 * @return A future timestamp when the app should be killed at, or a 0 if it shouldn't 5594 * be killed or it has been killed. 5595 */ 5596 @GuardedBy("mService") killAppIfBgRestrictedAndCachedIdleLocked(ProcessRecord app, long nowElapsed)5597 long killAppIfBgRestrictedAndCachedIdleLocked(ProcessRecord app, long nowElapsed) { 5598 final UidRecord uidRec = app.getUidRecord(); 5599 final long lastCanKillTime = app.mState.getLastCanKillOnBgRestrictedAndIdleTime(); 5600 if (!mService.mConstants.mKillBgRestrictedAndCachedIdle 5601 || app.isKilled() || app.getThread() == null || uidRec == null || !uidRec.isIdle() 5602 || !app.isCached() || app.mState.shouldNotKillOnBgRestrictedAndIdle() 5603 || !app.mState.isBackgroundRestricted() || lastCanKillTime == 0) { 5604 return 0; 5605 } 5606 final long future = lastCanKillTime 5607 + mService.mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs; 5608 if (future <= nowElapsed) { 5609 app.killLocked("cached idle & background restricted", 5610 ApplicationExitInfo.REASON_OTHER, 5611 ApplicationExitInfo.SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY, 5612 true); 5613 return 0; 5614 } 5615 return future; 5616 } 5617 5618 /** 5619 * Called by {@link ActivityManagerService#enqueueUidChangeLocked} only, it doesn't schedule 5620 * the standy killing checks because it should have been scheduled before enqueueing UID idle 5621 * changed. 5622 */ 5623 @GuardedBy("mService") killAppIfBgRestrictedAndCachedIdleLocked(UidRecord uidRec)5624 void killAppIfBgRestrictedAndCachedIdleLocked(UidRecord uidRec) { 5625 final long nowElapsed = SystemClock.elapsedRealtime(); 5626 uidRec.forEachProcess(app -> killAppIfBgRestrictedAndCachedIdleLocked(app, nowElapsed)); 5627 } 5628 5629 /** 5630 * Called by ActivityManagerService when a process died. 5631 */ 5632 @GuardedBy("mService") noteProcessDiedLocked(final ProcessRecord app)5633 void noteProcessDiedLocked(final ProcessRecord app) { 5634 if (DEBUG_PROCESSES) { 5635 Slog.i(TAG, "note: " + app + " died, saving the exit info"); 5636 } 5637 5638 Watchdog.getInstance().processDied(app.processName, app.getPid()); 5639 if (app.getDeathRecipient() == null 5640 && mDyingProcesses.get(app.processName, app.uid) == app) { 5641 // If we've done unlinkDeathRecipient before calling into this, remove from dying list. 5642 mDyingProcesses.remove(app.processName, app.uid); 5643 app.setDyingPid(0); 5644 } 5645 mAppExitInfoTracker.scheduleNoteProcessDied(app); 5646 } 5647 5648 /** 5649 * Called by ActivityManagerService when a recoverable native crash occurs. 5650 */ 5651 @GuardedBy("mService") noteAppRecoverableCrash(final ProcessRecord app)5652 void noteAppRecoverableCrash(final ProcessRecord app) { 5653 if (DEBUG_PROCESSES) { 5654 Slog.i(TAG, "note: " + app + " has a recoverable native crash"); 5655 } 5656 mAppExitInfoTracker.scheduleNoteAppRecoverableCrash(app); 5657 } 5658 5659 /** 5660 * Called by ActivityManagerService when it decides to kill an application process. 5661 */ 5662 @GuardedBy("mService") noteAppKill(final ProcessRecord app, final @Reason int reason, final @SubReason int subReason, final String msg)5663 void noteAppKill(final ProcessRecord app, final @Reason int reason, 5664 final @SubReason int subReason, final String msg) { 5665 if (DEBUG_PROCESSES) { 5666 Slog.i(TAG, "note: " + app + " is being killed, reason: " 5667 + ApplicationExitInfo.reasonCodeToString(reason) + ", sub-reason: " 5668 + ApplicationExitInfo.subreasonToString(subReason) + ", message: " + msg); 5669 } 5670 if (app.getPid() > 0 && !app.isolated && app.getDeathRecipient() != null) { 5671 // We are killing it, put it into the dying process list. 5672 mDyingProcesses.put(app.processName, app.uid, app); 5673 app.setDyingPid(app.getPid()); 5674 } 5675 mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg); 5676 } 5677 5678 @GuardedBy("mService") noteAppKill(final int pid, final int uid, final @Reason int reason, final @SubReason int subReason, final String msg)5679 void noteAppKill(final int pid, final int uid, final @Reason int reason, 5680 final @SubReason int subReason, final String msg) { 5681 if (DEBUG_PROCESSES) { 5682 Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason 5683 + ", sub-reason: " + subReason + ", message: " + msg); 5684 } 5685 5686 final ProcessRecord app; 5687 synchronized (mService.mPidsSelfLocked) { 5688 app = mService.mPidsSelfLocked.get(pid); 5689 } 5690 if (app != null && app.uid == uid && !app.isolated && app.getDeathRecipient() != null) { 5691 // We are killing it, put it into the dying process list. 5692 mDyingProcesses.put(app.processName, uid, app); 5693 app.setDyingPid(app.getPid()); 5694 } 5695 mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg); 5696 } 5697 5698 /** 5699 * Schedule to kill the given pids when the device is idle 5700 */ killProcessesWhenImperceptible(int[] pids, String reason, int requester)5701 void killProcessesWhenImperceptible(int[] pids, String reason, int requester) { 5702 if (ArrayUtils.isEmpty(pids)) { 5703 return; 5704 } 5705 5706 synchronized (mService) { 5707 ProcessRecord app; 5708 for (int i = 0; i < pids.length; i++) { 5709 synchronized (mService.mPidsSelfLocked) { 5710 app = mService.mPidsSelfLocked.get(pids[i]); 5711 } 5712 if (app != null) { 5713 mImperceptibleKillRunner.enqueueLocked(app, reason, requester); 5714 } 5715 } 5716 } 5717 } 5718 5719 /** 5720 * Get the number of foreground services in all processes and number of processes that have 5721 * foreground service within. 5722 */ getNumForegroundServices()5723 Pair<Integer, Integer> getNumForegroundServices() { 5724 int numForegroundServices = 0; 5725 int procs = 0; 5726 synchronized (mService) { 5727 for (int i = 0, size = mLruProcesses.size(); i < size; i++) { 5728 ProcessRecord pr = mLruProcesses.get(i); 5729 int numFgs = pr.mServices.getNumForegroundServices(); 5730 if (numFgs > 0) { 5731 numForegroundServices += numFgs; 5732 procs++; 5733 } 5734 } 5735 } 5736 return new Pair<>(numForegroundServices, procs); 5737 } 5738 5739 private final class ImperceptibleKillRunner extends UidObserver { 5740 private static final String EXTRA_PID = "pid"; 5741 private static final String EXTRA_UID = "uid"; 5742 private static final String EXTRA_TIMESTAMP = "timestamp"; 5743 private static final String EXTRA_REASON = "reason"; 5744 private static final String EXTRA_REQUESTER = "requester"; 5745 5746 private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill"; 5747 private static final boolean LOG_TO_DROPBOX = false; 5748 5749 // uid -> killing information mapping 5750 private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>(); 5751 5752 // The last time the various processes have been killed by us. 5753 private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>(); 5754 5755 // Device idle or not. 5756 private volatile boolean mIdle; 5757 private boolean mUidObserverEnabled; 5758 private Handler mHandler; 5759 private IdlenessReceiver mReceiver; 5760 5761 private final class H extends Handler { 5762 static final int MSG_DEVICE_IDLE = 0; 5763 static final int MSG_UID_GONE = 1; 5764 static final int MSG_UID_STATE_CHANGED = 2; 5765 H(Looper looper)5766 H(Looper looper) { 5767 super(looper); 5768 } 5769 5770 @Override handleMessage(Message msg)5771 public void handleMessage(Message msg) { 5772 switch (msg.what) { 5773 case MSG_DEVICE_IDLE: 5774 handleDeviceIdle(); 5775 break; 5776 case MSG_UID_GONE: 5777 handleUidGone(msg.arg1 /* uid */); 5778 break; 5779 case MSG_UID_STATE_CHANGED: 5780 handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */); 5781 break; 5782 } 5783 } 5784 } 5785 5786 private final class IdlenessReceiver extends BroadcastReceiver { 5787 @Override onReceive(Context context, Intent intent)5788 public void onReceive(Context context, Intent intent) { 5789 final PowerManager pm = mService.mContext.getSystemService(PowerManager.class); 5790 switch (intent.getAction()) { 5791 case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED: 5792 notifyDeviceIdleness(pm.isLightDeviceIdleMode()); 5793 break; 5794 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED: 5795 notifyDeviceIdleness(pm.isDeviceIdleMode()); 5796 break; 5797 } 5798 } 5799 } 5800 ImperceptibleKillRunner(Looper looper)5801 ImperceptibleKillRunner(Looper looper) { 5802 mHandler = new H(looper); 5803 } 5804 5805 @GuardedBy("mService") enqueueLocked(ProcessRecord app, String reason, int requester)5806 boolean enqueueLocked(ProcessRecord app, String reason, int requester) { 5807 // Throttle the killing request for potential bad app to avoid cpu thrashing 5808 Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid); 5809 if ((last != null) && (SystemClock.uptimeMillis() 5810 < (last + ActivityManagerConstants.MIN_CRASH_INTERVAL))) { 5811 return false; 5812 } 5813 5814 final Bundle bundle = new Bundle(); 5815 bundle.putInt(EXTRA_PID, app.getPid()); 5816 bundle.putInt(EXTRA_UID, app.uid); 5817 // Since the pid could be reused, let's get the actual start time of each process 5818 bundle.putLong(EXTRA_TIMESTAMP, app.getStartTime()); 5819 bundle.putString(EXTRA_REASON, reason); 5820 bundle.putInt(EXTRA_REQUESTER, requester); 5821 List<Bundle> list = mWorkItems.get(app.uid); 5822 if (list == null) { 5823 list = new ArrayList<Bundle>(); 5824 mWorkItems.put(app.uid, list); 5825 } 5826 list.add(bundle); 5827 if (mReceiver == null) { 5828 mReceiver = new IdlenessReceiver(); 5829 IntentFilter filter = new IntentFilter( 5830 PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); 5831 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 5832 mService.mContext.registerReceiver(mReceiver, filter); 5833 } 5834 return true; 5835 } 5836 notifyDeviceIdleness(boolean idle)5837 void notifyDeviceIdleness(boolean idle) { 5838 // No lock is held regarding mIdle, this function is the only updater and caller 5839 // won't re-entry. 5840 boolean diff = mIdle != idle; 5841 mIdle = idle; 5842 if (diff && idle) { 5843 synchronized (mService) { 5844 if (mWorkItems.size() > 0) { 5845 mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE); 5846 } 5847 } 5848 } 5849 } 5850 handleDeviceIdle()5851 private void handleDeviceIdle() { 5852 final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class); 5853 final boolean logToDropbox = LOG_TO_DROPBOX && dbox != null 5854 && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL); 5855 5856 synchronized (mService) { 5857 final int size = mWorkItems.size(); 5858 for (int i = size - 1; mIdle && i >= 0; i--) { 5859 List<Bundle> list = mWorkItems.valueAt(i); 5860 final int len = list.size(); 5861 for (int j = len - 1; mIdle && j >= 0; j--) { 5862 Bundle bundle = list.get(j); 5863 if (killProcessLocked( 5864 bundle.getInt(EXTRA_PID), 5865 bundle.getInt(EXTRA_UID), 5866 bundle.getLong(EXTRA_TIMESTAMP), 5867 bundle.getString(EXTRA_REASON), 5868 bundle.getInt(EXTRA_REQUESTER), 5869 dbox, logToDropbox)) { 5870 list.remove(j); 5871 } 5872 } 5873 if (list.size() == 0) { 5874 mWorkItems.removeAt(i); 5875 } 5876 } 5877 registerUidObserverIfNecessaryLocked(); 5878 } 5879 } 5880 5881 @GuardedBy("mService") registerUidObserverIfNecessaryLocked()5882 private void registerUidObserverIfNecessaryLocked() { 5883 // If there are still works remaining, register UID observer 5884 if (!mUidObserverEnabled && mWorkItems.size() > 0) { 5885 mUidObserverEnabled = true; 5886 mService.registerUidObserver(this, 5887 ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE, 5888 ActivityManager.PROCESS_STATE_UNKNOWN, "android"); 5889 } else if (mUidObserverEnabled && mWorkItems.size() == 0) { 5890 mUidObserverEnabled = false; 5891 mService.unregisterUidObserver(this); 5892 } 5893 } 5894 5895 /** 5896 * Kill the given processes, if they are not exempted. 5897 * 5898 * @return True if the process is killed, or it's gone already, or we are not allowed to 5899 * kill it (one of the packages in this process is being exempted). 5900 */ 5901 @GuardedBy("mService") killProcessLocked(final int pid, final int uid, final long timestamp, final String reason, final int requester, final DropBoxManager dbox, final boolean logToDropbox)5902 private boolean killProcessLocked(final int pid, final int uid, final long timestamp, 5903 final String reason, final int requester, final DropBoxManager dbox, 5904 final boolean logToDropbox) { 5905 ProcessRecord app = null; 5906 synchronized (mService.mPidsSelfLocked) { 5907 app = mService.mPidsSelfLocked.get(pid); 5908 } 5909 5910 if (app == null || app.getPid() != pid || app.uid != uid 5911 || app.getStartTime() != timestamp) { 5912 // This process record has been reused for another process, meaning the old process 5913 // has been gone. 5914 return true; 5915 } 5916 5917 if (app.getPkgList().searchEachPackage(pkgName -> { 5918 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(pkgName)) { 5919 // One of the packages in this process is exempted 5920 return Boolean.TRUE; 5921 } 5922 return null; 5923 }) != null) { 5924 return true; 5925 } 5926 5927 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains( 5928 app.mState.getReportedProcState())) { 5929 // We need to reschedule it. 5930 return false; 5931 } 5932 5933 app.killLocked(reason, ApplicationExitInfo.REASON_OTHER, 5934 ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true); 5935 5936 if (!app.isolated) { 5937 mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis()); 5938 } 5939 5940 if (logToDropbox) { 5941 final long now = SystemClock.elapsedRealtime(); 5942 final StringBuilder sb = new StringBuilder(); 5943 mService.appendDropBoxProcessHeaders(app, app.processName, null, sb); 5944 sb.append("Reason: " + reason).append("\n"); 5945 sb.append("Requester UID: " + requester).append("\n"); 5946 dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString()); 5947 } 5948 return true; 5949 } 5950 handleUidStateChanged(int uid, int procState)5951 private void handleUidStateChanged(int uid, int procState) { 5952 final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class); 5953 final boolean logToDropbox = dbox != null 5954 && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL); 5955 synchronized (mService) { 5956 if (mIdle && !mService.mConstants 5957 .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) { 5958 List<Bundle> list = mWorkItems.get(uid); 5959 if (list != null) { 5960 final int len = list.size(); 5961 for (int j = len - 1; mIdle && j >= 0; j--) { 5962 Bundle bundle = list.get(j); 5963 if (killProcessLocked( 5964 bundle.getInt(EXTRA_PID), 5965 bundle.getInt(EXTRA_UID), 5966 bundle.getLong(EXTRA_TIMESTAMP), 5967 bundle.getString(EXTRA_REASON), 5968 bundle.getInt(EXTRA_REQUESTER), 5969 dbox, logToDropbox)) { 5970 list.remove(j); 5971 } 5972 } 5973 if (list.size() == 0) { 5974 mWorkItems.remove(uid); 5975 } 5976 registerUidObserverIfNecessaryLocked(); 5977 } 5978 } 5979 } 5980 } 5981 handleUidGone(int uid)5982 private void handleUidGone(int uid) { 5983 synchronized (mService) { 5984 mWorkItems.remove(uid); 5985 registerUidObserverIfNecessaryLocked(); 5986 } 5987 } 5988 5989 @Override onUidGone(int uid, boolean disabled)5990 public void onUidGone(int uid, boolean disabled) { 5991 mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget(); 5992 } 5993 5994 @Override onUidStateChanged(int uid, int procState, long procStateSeq, int capability)5995 public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { 5996 mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); 5997 } 5998 }; 5999 } 6000