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