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