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