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_STATE_CACHED_ACTIVITY; 20 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 21 import static android.app.ActivityThread.PROC_START_SEQ_IDENT; 22 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO; 23 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; 24 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; 25 import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; 26 import static android.os.Process.SYSTEM_UID; 27 import static android.os.Process.THREAD_PRIORITY_BACKGROUND; 28 import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY; 29 import static android.os.Process.getFreeMemory; 30 import static android.os.Process.getTotalMemory; 31 import static android.os.Process.killProcessQuiet; 32 import static android.os.Process.startWebView; 33 34 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; 35 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK; 36 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; 37 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; 38 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; 39 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 40 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 41 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS; 42 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG; 43 import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK; 44 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT; 45 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG; 46 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER; 47 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS; 48 import static com.android.server.am.ActivityManagerService.TAG_LRU; 49 import static com.android.server.am.ActivityManagerService.TAG_NETWORK; 50 import static com.android.server.am.ActivityManagerService.TAG_PROCESSES; 51 import static com.android.server.am.ActivityManagerService.TAG_PSS; 52 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS; 53 54 import android.app.ActivityManager; 55 import android.app.ActivityThread; 56 import android.app.AppGlobals; 57 import android.app.AppProtoEnums; 58 import android.app.ApplicationExitInfo; 59 import android.app.ApplicationExitInfo.Reason; 60 import android.app.ApplicationExitInfo.SubReason; 61 import android.app.IApplicationThread; 62 import android.app.IUidObserver; 63 import android.compat.annotation.ChangeId; 64 import android.compat.annotation.Disabled; 65 import android.compat.annotation.EnabledAfter; 66 import android.content.BroadcastReceiver; 67 import android.content.ComponentName; 68 import android.content.Context; 69 import android.content.Intent; 70 import android.content.IntentFilter; 71 import android.content.pm.ApplicationInfo; 72 import android.content.pm.IPackageManager; 73 import android.content.pm.PackageManagerInternal; 74 import android.content.res.Resources; 75 import android.graphics.Point; 76 import android.net.LocalSocket; 77 import android.net.LocalSocketAddress; 78 import android.os.AppZygote; 79 import android.os.Binder; 80 import android.os.Build; 81 import android.os.Bundle; 82 import android.os.DropBoxManager; 83 import android.os.Handler; 84 import android.os.IBinder; 85 import android.os.Looper; 86 import android.os.Message; 87 import android.os.PowerManager; 88 import android.os.Process; 89 import android.os.RemoteException; 90 import android.os.StrictMode; 91 import android.os.SystemClock; 92 import android.os.SystemProperties; 93 import android.os.Trace; 94 import android.os.UserHandle; 95 import android.os.storage.StorageManager; 96 import android.os.storage.StorageManagerInternal; 97 import android.system.Os; 98 import android.text.TextUtils; 99 import android.util.ArrayMap; 100 import android.util.ArraySet; 101 import android.util.EventLog; 102 import android.util.LongSparseArray; 103 import android.util.Pair; 104 import android.util.Slog; 105 import android.util.SparseArray; 106 import android.util.SparseBooleanArray; 107 import android.view.Display; 108 109 import com.android.internal.annotations.GuardedBy; 110 import com.android.internal.annotations.VisibleForTesting; 111 import com.android.internal.app.ProcessMap; 112 import com.android.internal.app.procstats.ProcessStats; 113 import com.android.internal.os.Zygote; 114 import com.android.internal.util.ArrayUtils; 115 import com.android.internal.util.FrameworkStatsLog; 116 import com.android.internal.util.MemInfoReader; 117 import com.android.server.LocalServices; 118 import com.android.server.ServiceThread; 119 import com.android.server.SystemConfig; 120 import com.android.server.Watchdog; 121 import com.android.server.compat.PlatformCompat; 122 import com.android.server.pm.dex.DexManager; 123 import com.android.server.pm.parsing.pkg.AndroidPackage; 124 import com.android.server.wm.ActivityServiceConnectionsHolder; 125 import com.android.server.wm.WindowManagerService; 126 127 import dalvik.annotation.compat.VersionCodes; 128 import dalvik.system.VMRuntime; 129 130 import java.io.File; 131 import java.io.FileDescriptor; 132 import java.io.IOException; 133 import java.io.OutputStream; 134 import java.io.PrintWriter; 135 import java.nio.ByteBuffer; 136 import java.util.ArrayList; 137 import java.util.Arrays; 138 import java.util.BitSet; 139 import java.util.HashMap; 140 import java.util.List; 141 import java.util.Map; 142 import java.util.Set; 143 144 /** 145 * Activity manager code dealing with processes. 146 */ 147 public final class ProcessList { 148 static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; 149 150 // A system property to control if app data isolation is enabled. 151 static final String ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY = 152 "persist.zygote.app_data_isolation"; 153 154 // A system property to control if obb app data isolation is enabled in vold. 155 static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY = 156 "persist.sys.vold_app_data_isolation_enabled"; 157 158 // A system property to control if fuse is enabled. 159 static final String ANDROID_FUSE_ENABLED = "persist.sys.fuse"; 160 161 // The minimum time we allow between crashes, for us to consider this 162 // application to be bad and stop and its services and reject broadcasts. 163 static final int MIN_CRASH_INTERVAL = 60 * 1000; 164 165 // OOM adjustments for processes in various states: 166 167 // Uninitialized value for any major or minor adj fields 168 static final int INVALID_ADJ = -10000; 169 170 // Adjustment used in certain places where we don't know it yet. 171 // (Generally this is something that is going to be cached, but we 172 // don't know the exact value in the cached range to assign yet.) 173 static final int UNKNOWN_ADJ = 1001; 174 175 // This is a process only hosting activities that are not visible, 176 // so it can be killed without any disruption. 177 static final int CACHED_APP_MAX_ADJ = 999; 178 static final int CACHED_APP_MIN_ADJ = 900; 179 180 // This is the oom_adj level that we allow to die first. This cannot be equal to 181 // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of 182 // CACHED_APP_MAX_ADJ. 183 static final int CACHED_APP_LMK_FIRST_ADJ = 950; 184 185 // Number of levels we have available for different service connection group importance 186 // levels. 187 static final int CACHED_APP_IMPORTANCE_LEVELS = 5; 188 189 // The B list of SERVICE_ADJ -- these are the old and decrepit 190 // services that aren't as shiny and interesting as the ones in the A list. 191 static final int SERVICE_B_ADJ = 800; 192 193 // This is the process of the previous application that the user was in. 194 // This process is kept above other things, because it is very common to 195 // switch back to the previous app. This is important both for recent 196 // task switch (toggling between the two top recent apps) as well as normal 197 // UI flow such as clicking on a URI in the e-mail app to view in the browser, 198 // and then pressing back to return to e-mail. 199 static final int PREVIOUS_APP_ADJ = 700; 200 201 // This is a process holding the home application -- we want to try 202 // avoiding killing it, even if it would normally be in the background, 203 // because the user interacts with it so much. 204 static final int HOME_APP_ADJ = 600; 205 206 // This is a process holding an application service -- killing it will not 207 // have much of an impact as far as the user is concerned. 208 static final int SERVICE_ADJ = 500; 209 210 // This is a process with a heavy-weight application. It is in the 211 // background, but we want to try to avoid killing it. Value set in 212 // system/rootdir/init.rc on startup. 213 static final int HEAVY_WEIGHT_APP_ADJ = 400; 214 215 // This is a process currently hosting a backup operation. Killing it 216 // is not entirely fatal but is generally a bad idea. 217 static final int BACKUP_APP_ADJ = 300; 218 219 // This is a process bound by the system (or other app) that's more important than services but 220 // not so perceptible that it affects the user immediately if killed. 221 static final int PERCEPTIBLE_LOW_APP_ADJ = 250; 222 223 // This is a process only hosting components that are perceptible to the 224 // user, and we really want to avoid killing them, but they are not 225 // immediately visible. An example is background music playback. 226 static final int PERCEPTIBLE_APP_ADJ = 200; 227 228 // This is a process only hosting activities that are visible to the 229 // user, so we'd prefer they don't disappear. 230 static final int VISIBLE_APP_ADJ = 100; 231 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1; 232 233 // This is a process that was recently TOP and moved to FGS. Continue to treat it almost 234 // like a foreground app for a while. 235 // @see TOP_TO_FGS_GRACE_PERIOD 236 static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50; 237 238 // This is the process running the current foreground app. We'd really 239 // rather not kill it! 240 static final int FOREGROUND_APP_ADJ = 0; 241 242 // This is a process that the system or a persistent process has bound to, 243 // and indicated it is important. 244 static final int PERSISTENT_SERVICE_ADJ = -700; 245 246 // This is a system persistent process, such as telephony. Definitely 247 // don't want to kill it, but doing so is not completely fatal. 248 static final int PERSISTENT_PROC_ADJ = -800; 249 250 // The system process runs at the default adjustment. 251 static final int SYSTEM_ADJ = -900; 252 253 // Special code for native processes that are not being managed by the system (so 254 // don't have an oom adj assigned by the system). 255 static final int NATIVE_ADJ = -1000; 256 257 // Memory pages are 4K. 258 static final int PAGE_SIZE = 4 * 1024; 259 260 // Activity manager's version of Process.THREAD_GROUP_BACKGROUND 261 static final int SCHED_GROUP_BACKGROUND = 0; 262 // Activity manager's version of Process.THREAD_GROUP_RESTRICTED 263 static final int SCHED_GROUP_RESTRICTED = 1; 264 // Activity manager's version of Process.THREAD_GROUP_DEFAULT 265 static final int SCHED_GROUP_DEFAULT = 2; 266 // Activity manager's version of Process.THREAD_GROUP_TOP_APP 267 public static final int SCHED_GROUP_TOP_APP = 3; 268 // Activity manager's version of Process.THREAD_GROUP_TOP_APP 269 // Disambiguate between actual top app and processes bound to the top app 270 static final int SCHED_GROUP_TOP_APP_BOUND = 4; 271 272 // The minimum number of cached apps we want to be able to keep around, 273 // without empty apps being able to push them out of memory. 274 static final int MIN_CACHED_APPS = 2; 275 276 // We allow empty processes to stick around for at most 30 minutes. 277 static final long MAX_EMPTY_TIME = 30 * 60 * 1000; 278 279 // Threshold of number of cached+empty where we consider memory critical. 280 static final int TRIM_CRITICAL_THRESHOLD = 3; 281 282 // Threshold of number of cached+empty where we consider memory critical. 283 static final int TRIM_LOW_THRESHOLD = 5; 284 285 /** 286 * State indicating that there is no need for any blocking for network. 287 */ 288 @VisibleForTesting 289 static final int NETWORK_STATE_NO_CHANGE = 0; 290 291 /** 292 * State indicating that the main thread needs to be informed about the network wait. 293 */ 294 @VisibleForTesting 295 static final int NETWORK_STATE_BLOCK = 1; 296 297 /** 298 * State indicating that any threads waiting for network state to get updated can be unblocked. 299 */ 300 @VisibleForTesting 301 static final int NETWORK_STATE_UNBLOCK = 2; 302 303 // If true, then we pass the flag to ART to load the app image startup cache. 304 private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE = 305 "persist.device_config.runtime_native.use_app_image_startup_cache"; 306 307 // The socket path for zygote to send unsolicited msg. 308 // Must keep sync with com_android_internal_os_Zygote.cpp. 309 private static final String UNSOL_ZYGOTE_MSG_SOCKET_PATH = "/data/system/unsolzygotesocket"; 310 311 // Low Memory Killer Daemon command codes. 312 // These must be kept in sync with lmk_cmd definitions in lmkd.h 313 // 314 // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs) 315 // LMK_PROCPRIO <pid> <uid> <prio> 316 // LMK_PROCREMOVE <pid> 317 // LMK_PROCPURGE 318 // LMK_GETKILLCNT 319 // LMK_SUBSCRIBE 320 // LMK_PROCKILL 321 static final byte LMK_TARGET = 0; 322 static final byte LMK_PROCPRIO = 1; 323 static final byte LMK_PROCREMOVE = 2; 324 static final byte LMK_PROCPURGE = 3; 325 static final byte LMK_GETKILLCNT = 4; 326 static final byte LMK_SUBSCRIBE = 5; 327 static final byte LMK_PROCKILL = 6; // Note: this is an unsolicated command 328 329 // Low Memory Killer Daemon command codes. 330 // These must be kept in sync with async_event_type definitions in lmkd.h 331 // 332 static final int LMK_ASYNC_EVENT_KILL = 0; 333 334 // lmkd reconnect delay in msecs 335 private static final long LMKD_RECONNECT_DELAY_MS = 1000; 336 337 /** 338 * How long between a process kill and we actually receive its death recipient 339 */ 340 private static final int PROC_KILL_TIMEOUT = 2000; // 2 seconds; 341 342 /** 343 * Native heap allocations will now have a non-zero tag in the most significant byte. 344 * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged 345 * Pointers</a> 346 */ 347 @ChangeId 348 @EnabledAfter(targetSdkVersion = VersionCodes.Q) 349 private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id. 350 351 /** 352 * Enable sampled memory bug detection in the app. 353 * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>. 354 */ 355 @ChangeId 356 @Disabled 357 private static final long GWP_ASAN = 135634846; // This is a bug id. 358 359 /** 360 * Apps have no access to the private data directories of any other app, even if the other 361 * app has made them world-readable. 362 */ 363 @ChangeId 364 @EnabledAfter(targetSdkVersion = VersionCodes.Q) 365 private static final long APP_DATA_DIRECTORY_ISOLATION = 143937733; // See b/143937733 366 367 ActivityManagerService mService = null; 368 369 // To kill process groups asynchronously 370 static KillHandler sKillHandler = null; 371 static ServiceThread sKillThread = null; 372 373 // These are the various interesting memory levels that we will give to 374 // the OOM killer. Note that the OOM killer only supports 6 slots, so we 375 // can't give it a different value for every possible kind of process. 376 private final int[] mOomAdj = new int[] { 377 FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ, 378 PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ 379 }; 380 // These are the low-end OOM level limits. This is appropriate for an 381 // HVGA or smaller phone with less than 512MB. Values are in KB. 382 private final int[] mOomMinFreeLow = new int[] { 383 12288, 18432, 24576, 384 36864, 43008, 49152 385 }; 386 // These are the high-end OOM level limits. This is appropriate for a 387 // 1280x800 or larger screen with around 1GB RAM. Values are in KB. 388 private final int[] mOomMinFreeHigh = new int[] { 389 73728, 92160, 110592, 390 129024, 147456, 184320 391 }; 392 // The actual OOM killer memory levels we are using. 393 private final int[] mOomMinFree = new int[mOomAdj.length]; 394 395 private final long mTotalMemMb; 396 397 private long mCachedRestoreLevel; 398 399 private boolean mHaveDisplaySize; 400 401 private static LmkdConnection sLmkdConnection = null; 402 403 private boolean mOomLevelsSet = false; 404 405 private boolean mAppDataIsolationEnabled = false; 406 407 private boolean mVoldAppDataIsolationEnabled = false; 408 409 private ArrayList<String> mAppDataIsolationWhitelistedApps; 410 411 /** 412 * Temporary to avoid allocations. Protected by main lock. 413 */ 414 @GuardedBy("mService") 415 final StringBuilder mStringBuilder = new StringBuilder(256); 416 417 /** 418 * A global counter for generating sequence numbers. 419 * This value will be used when incrementing sequence numbers in individual uidRecords. 420 * 421 * Having a global counter ensures that seq numbers are monotonically increasing for a 422 * particular uid even when the uidRecord is re-created. 423 */ 424 @GuardedBy("mService") 425 @VisibleForTesting 426 long mProcStateSeqCounter = 0; 427 428 /** 429 * A global counter for generating sequence numbers to uniquely identify pending process starts. 430 */ 431 @GuardedBy("mService") 432 private long mProcStartSeqCounter = 0; 433 434 /** 435 * Contains {@link ProcessRecord} objects for pending process starts. 436 * 437 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord} 438 */ 439 @GuardedBy("mService") 440 final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>(); 441 442 /** 443 * List of running applications, sorted by recent usage. 444 * The first entry in the list is the least recently used. 445 */ 446 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 447 448 /** 449 * Where in mLruProcesses that the processes hosting activities start. 450 */ 451 int mLruProcessActivityStart = 0; 452 453 /** 454 * Where in mLruProcesses that the processes hosting services start. 455 * This is after (lower index) than mLruProcessesActivityStart. 456 */ 457 int mLruProcessServiceStart = 0; 458 459 /** 460 * Current sequence id for process LRU updating. 461 */ 462 int mLruSeq = 0; 463 464 ActiveUids mActiveUids; 465 466 /** 467 * The currently running isolated processes. 468 */ 469 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>(); 470 471 /** 472 * The currently running application zygotes. 473 */ 474 final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>(); 475 476 /** 477 * Managees the {@link android.app.ApplicationExitInfo} records. 478 */ 479 @GuardedBy("mAppExitInfoTracker") 480 final AppExitInfoTracker mAppExitInfoTracker = new AppExitInfoTracker(); 481 482 /** 483 * The processes that are forked off an application zygote. 484 */ 485 final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses = 486 new ArrayMap<AppZygote, ArrayList<ProcessRecord>>(); 487 488 private PlatformCompat mPlatformCompat = null; 489 490 /** 491 * The server socket in system_server, zygote will connect to it 492 * in order to send unsolicited messages to system_server. 493 */ 494 private LocalSocket mSystemServerSocketForZygote; 495 496 /** 497 * Maximum number of bytes that an incoming unsolicited zygote message could be. 498 * To be updated if new message type needs to be supported. 499 */ 500 private static final int MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE = 16; 501 502 /** 503 * The buffer to be used to receive the incoming unsolicited zygote message. 504 */ 505 private final byte[] mZygoteUnsolicitedMessage = new byte[MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE]; 506 507 /** 508 * The buffer to be used to receive the SIGCHLD data, it includes pid/uid/status. 509 */ 510 private final int[] mZygoteSigChldMessage = new int[3]; 511 512 final class IsolatedUidRange { 513 @VisibleForTesting 514 public final int mFirstUid; 515 @VisibleForTesting 516 public final int mLastUid; 517 518 @GuardedBy("ProcessList.this.mService") 519 private final SparseBooleanArray mUidUsed = new SparseBooleanArray(); 520 521 @GuardedBy("ProcessList.this.mService") 522 private int mNextUid; 523 IsolatedUidRange(int firstUid, int lastUid)524 IsolatedUidRange(int firstUid, int lastUid) { 525 mFirstUid = firstUid; 526 mLastUid = lastUid; 527 mNextUid = firstUid; 528 } 529 530 @GuardedBy("ProcessList.this.mService") allocateIsolatedUidLocked(int userId)531 int allocateIsolatedUidLocked(int userId) { 532 int uid; 533 int stepsLeft = (mLastUid - mFirstUid + 1); 534 for (int i = 0; i < stepsLeft; ++i) { 535 if (mNextUid < mFirstUid || mNextUid > mLastUid) { 536 mNextUid = mFirstUid; 537 } 538 uid = UserHandle.getUid(userId, mNextUid); 539 mNextUid++; 540 if (!mUidUsed.get(uid, false)) { 541 mUidUsed.put(uid, true); 542 return uid; 543 } 544 } 545 return -1; 546 } 547 548 @GuardedBy("ProcessList.this.mService") freeIsolatedUidLocked(int uid)549 void freeIsolatedUidLocked(int uid) { 550 mUidUsed.delete(uid); 551 } 552 }; 553 554 /** 555 * A class that allocates ranges of isolated UIDs per application, and keeps track of them. 556 */ 557 final class IsolatedUidRangeAllocator { 558 private final int mFirstUid; 559 private final int mNumUidRanges; 560 private final int mNumUidsPerRange; 561 /** 562 * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange) 563 * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that. 564 */ 565 @GuardedBy("ProcessList.this.mService") 566 private final BitSet mAvailableUidRanges; 567 @GuardedBy("ProcessList.this.mService") 568 private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>(); 569 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange)570 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) { 571 mFirstUid = firstUid; 572 mNumUidsPerRange = numUidsPerRange; 573 mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange; 574 mAvailableUidRanges = new BitSet(mNumUidRanges); 575 // Mark all as available 576 mAvailableUidRanges.set(0, mNumUidRanges); 577 } 578 579 @GuardedBy("ProcessList.this.mService") getIsolatedUidRangeLocked(String processName, int uid)580 IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) { 581 return mAppRanges.get(processName, uid); 582 } 583 584 @GuardedBy("ProcessList.this.mService") getOrCreateIsolatedUidRangeLocked(String processName, int uid)585 IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) { 586 IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid); 587 if (range == null) { 588 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0); 589 if (uidRangeIndex < 0) { 590 // No free range 591 return null; 592 } 593 mAvailableUidRanges.clear(uidRangeIndex); 594 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange; 595 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1); 596 mAppRanges.put(processName, uid, range); 597 } 598 return range; 599 } 600 601 @GuardedBy("ProcessList.this.mService") freeUidRangeLocked(ApplicationInfo info)602 void freeUidRangeLocked(ApplicationInfo info) { 603 // Find the UID range 604 IsolatedUidRange range = mAppRanges.get(info.processName, info.uid); 605 if (range != null) { 606 // Map back to starting uid 607 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange; 608 // Mark it as available in the underlying bitset 609 mAvailableUidRanges.set(uidRangeIndex); 610 // And the map 611 mAppRanges.remove(info.processName, info.uid); 612 } 613 } 614 } 615 616 /** 617 * The available isolated UIDs for processes that are not spawned from an application zygote. 618 */ 619 @VisibleForTesting 620 IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID, 621 Process.LAST_ISOLATED_UID); 622 623 /** 624 * An allocator for isolated UID ranges for apps that use an application zygote. 625 */ 626 @VisibleForTesting 627 IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator = 628 new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 629 Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE); 630 631 /** 632 * Processes that are being forcibly torn down. 633 */ 634 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 635 636 /** 637 * All of the applications we currently have running organized by name. 638 * The keys are strings of the application package name (as 639 * returned by the package manager), and the keys are ApplicationRecord 640 * objects. 641 */ 642 final MyProcessMap mProcessNames = new MyProcessMap(); 643 644 final class MyProcessMap extends ProcessMap<ProcessRecord> { 645 @Override put(String name, int uid, ProcessRecord value)646 public ProcessRecord put(String name, int uid, ProcessRecord value) { 647 final ProcessRecord r = super.put(name, uid, value); 648 mService.mAtmInternal.onProcessAdded(r.getWindowProcessController()); 649 return r; 650 } 651 652 @Override remove(String name, int uid)653 public ProcessRecord remove(String name, int uid) { 654 final ProcessRecord r = super.remove(name, uid); 655 mService.mAtmInternal.onProcessRemoved(name, uid); 656 return r; 657 } 658 } 659 660 final class KillHandler extends Handler { 661 static final int KILL_PROCESS_GROUP_MSG = 4000; 662 static final int LMKD_RECONNECT_MSG = 4001; 663 KillHandler(Looper looper)664 public KillHandler(Looper looper) { 665 super(looper, null, true); 666 } 667 668 @Override handleMessage(Message msg)669 public void handleMessage(Message msg) { 670 switch (msg.what) { 671 case KILL_PROCESS_GROUP_MSG: 672 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup"); 673 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); 674 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 675 break; 676 case LMKD_RECONNECT_MSG: 677 if (!sLmkdConnection.connect()) { 678 Slog.i(TAG, "Failed to connect to lmkd, retry after " + 679 LMKD_RECONNECT_DELAY_MS + " ms"); 680 // retry after LMKD_RECONNECT_DELAY_MS 681 sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( 682 KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS); 683 } 684 break; 685 default: 686 super.handleMessage(msg); 687 } 688 } 689 } 690 691 /** 692 * A runner to handle the imperceptible killings. 693 */ 694 ImperceptibleKillRunner mImperceptibleKillRunner; 695 696 //////////////////// END FIELDS //////////////////// 697 ProcessList()698 ProcessList() { 699 MemInfoReader minfo = new MemInfoReader(); 700 minfo.readMemInfo(); 701 mTotalMemMb = minfo.getTotalSize()/(1024*1024); 702 updateOomLevels(0, 0, false); 703 } 704 init(ActivityManagerService service, ActiveUids activeUids, PlatformCompat platformCompat)705 void init(ActivityManagerService service, ActiveUids activeUids, 706 PlatformCompat platformCompat) { 707 mService = service; 708 mActiveUids = activeUids; 709 mPlatformCompat = platformCompat; 710 // Get this after boot, and won't be changed until it's rebooted, as we don't 711 // want some apps enabled while some apps disabled 712 mAppDataIsolationEnabled = 713 SystemProperties.getBoolean(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true); 714 boolean fuseEnabled = SystemProperties.getBoolean(ANDROID_FUSE_ENABLED, false); 715 boolean voldAppDataIsolationEnabled = SystemProperties.getBoolean( 716 ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false); 717 if (!fuseEnabled && voldAppDataIsolationEnabled) { 718 Slog.e(TAG, "Fuse is not enabled while vold app data isolation is enabled"); 719 } 720 mVoldAppDataIsolationEnabled = fuseEnabled && voldAppDataIsolationEnabled; 721 mAppDataIsolationWhitelistedApps = new ArrayList<>( 722 SystemConfig.getInstance().getAppDataIsolationWhitelistedApps()); 723 724 if (sKillHandler == null) { 725 sKillThread = new ServiceThread(TAG + ":kill", 726 THREAD_PRIORITY_BACKGROUND, true /* allowIo */); 727 sKillThread.start(); 728 sKillHandler = new KillHandler(sKillThread.getLooper()); 729 sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(), 730 new LmkdConnection.LmkdConnectionListener() { 731 @Override 732 public boolean onConnect(OutputStream ostream) { 733 Slog.i(TAG, "Connection with lmkd established"); 734 return onLmkdConnect(ostream); 735 } 736 737 @Override 738 public void onDisconnect() { 739 Slog.w(TAG, "Lost connection to lmkd"); 740 // start reconnection after delay to let lmkd restart 741 sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage( 742 KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS); 743 } 744 745 @Override 746 public boolean isReplyExpected(ByteBuffer replyBuf, 747 ByteBuffer dataReceived, int receivedLen) { 748 // compare the preambule (currently one integer) to check if 749 // this is the reply packet we are waiting for 750 return (receivedLen == replyBuf.array().length && 751 dataReceived.getInt(0) == replyBuf.getInt(0)); 752 } 753 754 @Override 755 public boolean handleUnsolicitedMessage(ByteBuffer dataReceived, 756 int receivedLen) { 757 if (receivedLen < 4) { 758 return false; 759 } 760 switch (dataReceived.getInt(0)) { 761 case LMK_PROCKILL: 762 if (receivedLen != 12) { 763 return false; 764 } 765 mAppExitInfoTracker.scheduleNoteLmkdProcKilled( 766 dataReceived.getInt(4), dataReceived.getInt(8)); 767 return true; 768 default: 769 return false; 770 } 771 } 772 } 773 ); 774 // Start listening on incoming connections from zygotes. 775 mSystemServerSocketForZygote = createSystemServerSocketForZygote(); 776 if (mSystemServerSocketForZygote != null) { 777 sKillHandler.getLooper().getQueue().addOnFileDescriptorEventListener( 778 mSystemServerSocketForZygote.getFileDescriptor(), 779 EVENT_INPUT, this::handleZygoteMessages); 780 } 781 mAppExitInfoTracker.init(mService); 782 mImperceptibleKillRunner = new ImperceptibleKillRunner(sKillThread.getLooper()); 783 } 784 } 785 onSystemReady()786 void onSystemReady() { 787 mAppExitInfoTracker.onSystemReady(); 788 } 789 applyDisplaySize(WindowManagerService wm)790 void applyDisplaySize(WindowManagerService wm) { 791 if (!mHaveDisplaySize) { 792 Point p = new Point(); 793 // TODO(multi-display): Compute based on sum of all connected displays' resolutions. 794 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p); 795 if (p.x != 0 && p.y != 0) { 796 updateOomLevels(p.x, p.y, true); 797 mHaveDisplaySize = true; 798 } 799 } 800 } 801 802 /** 803 * Get a map of pid and package name that process of that pid Android/data and Android/obb 804 * directory is not mounted to lowerfs to speed up access. 805 */ getProcessesWithPendingBindMounts(int userId)806 Map<Integer, String> getProcessesWithPendingBindMounts(int userId) { 807 final Map<Integer, String> pidPackageMap = new HashMap<>(); 808 synchronized (mService) { 809 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 810 final ProcessRecord record = mLruProcesses.get(i); 811 if (record.userId != userId || !record.bindMountPending) { 812 continue; 813 } 814 final int pid = record.pid; 815 // It can happen when app process is starting, but zygote work is not done yet so 816 // system does not this pid record yet. 817 if (pid == 0) { 818 throw new IllegalStateException("Pending process is not started yet," 819 + "retry later"); 820 } 821 pidPackageMap.put(pid, record.info.packageName); 822 } 823 return pidPackageMap; 824 } 825 } 826 updateOomLevels(int displayWidth, int displayHeight, boolean write)827 private void updateOomLevels(int displayWidth, int displayHeight, boolean write) { 828 // Scale buckets from avail memory: at 300MB we use the lowest values to 829 // 700MB or more for the top values. 830 float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350); 831 832 // Scale buckets from screen size. 833 int minSize = 480 * 800; // 384000 834 int maxSize = 1280 * 800; // 1024000 230400 870400 .264 835 float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize); 836 if (false) { 837 Slog.i("XXXXXX", "scaleMem=" + scaleMem); 838 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth 839 + " dh=" + displayHeight); 840 } 841 842 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp; 843 if (scale < 0) scale = 0; 844 else if (scale > 1) scale = 1; 845 int minfree_adj = Resources.getSystem().getInteger( 846 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust); 847 int minfree_abs = Resources.getSystem().getInteger( 848 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute); 849 if (false) { 850 Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs); 851 } 852 853 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0; 854 855 for (int i = 0; i < mOomAdj.length; i++) { 856 int low = mOomMinFreeLow[i]; 857 int high = mOomMinFreeHigh[i]; 858 if (is64bit) { 859 // Increase the high min-free levels for cached processes for 64-bit 860 if (i == 4) high = (high * 3) / 2; 861 else if (i == 5) high = (high * 7) / 4; 862 } 863 mOomMinFree[i] = (int)(low + ((high - low) * scale)); 864 } 865 866 if (minfree_abs >= 0) { 867 for (int i = 0; i < mOomAdj.length; i++) { 868 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] 869 / mOomMinFree[mOomAdj.length - 1]); 870 } 871 } 872 873 if (minfree_adj != 0) { 874 for (int i = 0; i < mOomAdj.length; i++) { 875 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i] 876 / mOomMinFree[mOomAdj.length - 1]); 877 if (mOomMinFree[i] < 0) { 878 mOomMinFree[i] = 0; 879 } 880 } 881 } 882 883 // The maximum size we will restore a process from cached to background, when under 884 // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead 885 // before killing background processes. 886 mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3; 887 888 // Ask the kernel to try to keep enough memory free to allocate 3 full 889 // screen 32bpp buffers without entering direct reclaim. 890 int reserve = displayWidth * displayHeight * 4 * 3 / 1024; 891 int reserve_adj = Resources.getSystem().getInteger( 892 com.android.internal.R.integer.config_extraFreeKbytesAdjust); 893 int reserve_abs = Resources.getSystem().getInteger( 894 com.android.internal.R.integer.config_extraFreeKbytesAbsolute); 895 896 if (reserve_abs >= 0) { 897 reserve = reserve_abs; 898 } 899 900 if (reserve_adj != 0) { 901 reserve += reserve_adj; 902 if (reserve < 0) { 903 reserve = 0; 904 } 905 } 906 907 if (write) { 908 ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1)); 909 buf.putInt(LMK_TARGET); 910 for (int i = 0; i < mOomAdj.length; i++) { 911 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE); 912 buf.putInt(mOomAdj[i]); 913 } 914 915 writeLmkd(buf, null); 916 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); 917 mOomLevelsSet = true; 918 } 919 // GB: 2048,3072,4096,6144,7168,8192 920 // HC: 8192,10240,12288,14336,16384,20480 921 } 922 computeEmptyProcessLimit(int totalProcessLimit)923 public static int computeEmptyProcessLimit(int totalProcessLimit) { 924 return totalProcessLimit/2; 925 } 926 buildOomTag(String prefix, String compactPrefix, String space, int val, int base, boolean compact)927 private static String buildOomTag(String prefix, String compactPrefix, String space, int val, 928 int base, boolean compact) { 929 final int diff = val - base; 930 if (diff == 0) { 931 if (compact) { 932 return compactPrefix; 933 } 934 if (space == null) return prefix; 935 return prefix + space; 936 } 937 if (diff < 10) { 938 return prefix + (compact ? "+" : "+ ") + Integer.toString(diff); 939 } 940 return prefix + "+" + Integer.toString(diff); 941 } 942 makeOomAdjString(int setAdj, boolean compact)943 public static String makeOomAdjString(int setAdj, boolean compact) { 944 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 945 return buildOomTag("cch", "cch", " ", setAdj, 946 ProcessList.CACHED_APP_MIN_ADJ, compact); 947 } else if (setAdj >= ProcessList.SERVICE_B_ADJ) { 948 return buildOomTag("svcb ", "svcb", null, setAdj, 949 ProcessList.SERVICE_B_ADJ, compact); 950 } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 951 return buildOomTag("prev ", "prev", null, setAdj, 952 ProcessList.PREVIOUS_APP_ADJ, compact); 953 } else if (setAdj >= ProcessList.HOME_APP_ADJ) { 954 return buildOomTag("home ", "home", null, setAdj, 955 ProcessList.HOME_APP_ADJ, compact); 956 } else if (setAdj >= ProcessList.SERVICE_ADJ) { 957 return buildOomTag("svc ", "svc", null, setAdj, 958 ProcessList.SERVICE_ADJ, compact); 959 } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 960 return buildOomTag("hvy ", "hvy", null, setAdj, 961 ProcessList.HEAVY_WEIGHT_APP_ADJ, compact); 962 } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) { 963 return buildOomTag("bkup ", "bkup", null, setAdj, 964 ProcessList.BACKUP_APP_ADJ, compact); 965 } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { 966 return buildOomTag("prcl ", "prcl", null, setAdj, 967 ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact); 968 } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 969 return buildOomTag("prcp ", "prcp", null, setAdj, 970 ProcessList.PERCEPTIBLE_APP_ADJ, compact); 971 } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) { 972 return buildOomTag("vis", "vis", " ", setAdj, 973 ProcessList.VISIBLE_APP_ADJ, compact); 974 } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 975 return buildOomTag("fg ", "fg ", " ", setAdj, 976 ProcessList.FOREGROUND_APP_ADJ, compact); 977 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) { 978 return buildOomTag("psvc ", "psvc", null, setAdj, 979 ProcessList.PERSISTENT_SERVICE_ADJ, compact); 980 } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 981 return buildOomTag("pers ", "pers", null, setAdj, 982 ProcessList.PERSISTENT_PROC_ADJ, compact); 983 } else if (setAdj >= ProcessList.SYSTEM_ADJ) { 984 return buildOomTag("sys ", "sys", null, setAdj, 985 ProcessList.SYSTEM_ADJ, compact); 986 } else if (setAdj >= ProcessList.NATIVE_ADJ) { 987 return buildOomTag("ntv ", "ntv", null, setAdj, 988 ProcessList.NATIVE_ADJ, compact); 989 } else { 990 return Integer.toString(setAdj); 991 } 992 } 993 makeProcStateString(int curProcState)994 public static String makeProcStateString(int curProcState) { 995 String procState; 996 switch (curProcState) { 997 case ActivityManager.PROCESS_STATE_PERSISTENT: 998 procState = "PER "; 999 break; 1000 case ActivityManager.PROCESS_STATE_PERSISTENT_UI: 1001 procState = "PERU"; 1002 break; 1003 case ActivityManager.PROCESS_STATE_TOP: 1004 procState = "TOP "; 1005 break; 1006 case ActivityManager.PROCESS_STATE_BOUND_TOP: 1007 procState = "BTOP"; 1008 break; 1009 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: 1010 procState = "FGS "; 1011 break; 1012 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: 1013 procState = "BFGS"; 1014 break; 1015 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 1016 procState = "IMPF"; 1017 break; 1018 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 1019 procState = "IMPB"; 1020 break; 1021 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: 1022 procState = "TRNB"; 1023 break; 1024 case ActivityManager.PROCESS_STATE_BACKUP: 1025 procState = "BKUP"; 1026 break; 1027 case ActivityManager.PROCESS_STATE_SERVICE: 1028 procState = "SVC "; 1029 break; 1030 case ActivityManager.PROCESS_STATE_RECEIVER: 1031 procState = "RCVR"; 1032 break; 1033 case ActivityManager.PROCESS_STATE_TOP_SLEEPING: 1034 procState = "TPSL"; 1035 break; 1036 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT: 1037 procState = "HVY "; 1038 break; 1039 case ActivityManager.PROCESS_STATE_HOME: 1040 procState = "HOME"; 1041 break; 1042 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY: 1043 procState = "LAST"; 1044 break; 1045 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 1046 procState = "CAC "; 1047 break; 1048 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 1049 procState = "CACC"; 1050 break; 1051 case ActivityManager.PROCESS_STATE_CACHED_RECENT: 1052 procState = "CRE "; 1053 break; 1054 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 1055 procState = "CEM "; 1056 break; 1057 case ActivityManager.PROCESS_STATE_NONEXISTENT: 1058 procState = "NONE"; 1059 break; 1060 default: 1061 procState = "??"; 1062 break; 1063 } 1064 return procState; 1065 } 1066 makeProcStateProtoEnum(int curProcState)1067 public static int makeProcStateProtoEnum(int curProcState) { 1068 switch (curProcState) { 1069 case ActivityManager.PROCESS_STATE_PERSISTENT: 1070 return AppProtoEnums.PROCESS_STATE_PERSISTENT; 1071 case ActivityManager.PROCESS_STATE_PERSISTENT_UI: 1072 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI; 1073 case ActivityManager.PROCESS_STATE_TOP: 1074 return AppProtoEnums.PROCESS_STATE_TOP; 1075 case ActivityManager.PROCESS_STATE_BOUND_TOP: 1076 return AppProtoEnums.PROCESS_STATE_BOUND_TOP; 1077 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: 1078 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; 1079 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: 1080 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 1081 case ActivityManager.PROCESS_STATE_TOP_SLEEPING: 1082 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING; 1083 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 1084 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND; 1085 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 1086 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND; 1087 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: 1088 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND; 1089 case ActivityManager.PROCESS_STATE_BACKUP: 1090 return AppProtoEnums.PROCESS_STATE_BACKUP; 1091 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT: 1092 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT; 1093 case ActivityManager.PROCESS_STATE_SERVICE: 1094 return AppProtoEnums.PROCESS_STATE_SERVICE; 1095 case ActivityManager.PROCESS_STATE_RECEIVER: 1096 return AppProtoEnums.PROCESS_STATE_RECEIVER; 1097 case ActivityManager.PROCESS_STATE_HOME: 1098 return AppProtoEnums.PROCESS_STATE_HOME; 1099 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY: 1100 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY; 1101 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 1102 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY; 1103 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 1104 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 1105 case ActivityManager.PROCESS_STATE_CACHED_RECENT: 1106 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT; 1107 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 1108 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY; 1109 case ActivityManager.PROCESS_STATE_NONEXISTENT: 1110 return AppProtoEnums.PROCESS_STATE_NONEXISTENT; 1111 case ActivityManager.PROCESS_STATE_UNKNOWN: 1112 return AppProtoEnums.PROCESS_STATE_UNKNOWN; 1113 default: 1114 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO; 1115 } 1116 } 1117 appendRamKb(StringBuilder sb, long ramKb)1118 public static void appendRamKb(StringBuilder sb, long ramKb) { 1119 for (int j = 0, fact = 10; j < 6; j++, fact *= 10) { 1120 if (ramKb < fact) { 1121 sb.append(' '); 1122 } 1123 } 1124 sb.append(ramKb); 1125 } 1126 1127 // How long after a state change that it is safe to collect PSS without it being dirty. 1128 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000; 1129 1130 // The minimum time interval after a state change it is safe to collect PSS. 1131 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000; 1132 1133 // The maximum amount of time we want to go between PSS collections. 1134 public static final int PSS_MAX_INTERVAL = 60*60*1000; 1135 1136 // The minimum amount of time between successive PSS requests for *all* processes. 1137 public static final int PSS_ALL_INTERVAL = 20*60*1000; 1138 1139 // The amount of time until PSS when a persistent process first appears. 1140 private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000; 1141 1142 // The amount of time until PSS when a process first becomes top. 1143 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000; 1144 1145 // The amount of time until PSS when a process first goes into the background. 1146 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000; 1147 1148 // The amount of time until PSS when a process first becomes cached. 1149 private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000; 1150 1151 // The amount of time until PSS when an important process stays in the same state. 1152 private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000; 1153 1154 // The amount of time until PSS when the top process stays in the same state. 1155 private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000; 1156 1157 // The amount of time until PSS when an important process stays in the same state. 1158 private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000; 1159 1160 // The amount of time until PSS when a service process stays in the same state. 1161 private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000; 1162 1163 // The amount of time until PSS when a cached process stays in the same state. 1164 private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000; 1165 1166 // The amount of time until PSS when a persistent process first appears. 1167 private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000; 1168 1169 // The amount of time until PSS when a process first becomes top. 1170 private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000; 1171 1172 // The amount of time until PSS when a process first goes into the background. 1173 private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000; 1174 1175 // The amount of time until PSS when a process first becomes cached. 1176 private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000; 1177 1178 // The minimum time interval after a state change it is safe to collect PSS. 1179 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000; 1180 1181 // The amount of time during testing until PSS when a process first becomes top. 1182 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000; 1183 1184 // The amount of time during testing until PSS when a process first goes into the background. 1185 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000; 1186 1187 // The amount of time during testing until PSS when an important process stays in same state. 1188 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000; 1189 1190 // The amount of time during testing until PSS when a background process stays in same state. 1191 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000; 1192 1193 public static final int PROC_MEM_PERSISTENT = 0; 1194 public static final int PROC_MEM_TOP = 1; 1195 public static final int PROC_MEM_IMPORTANT = 2; 1196 public static final int PROC_MEM_SERVICE = 3; 1197 public static final int PROC_MEM_CACHED = 4; 1198 public static final int PROC_MEM_NUM = 5; 1199 1200 // Map large set of system process states to 1201 private static final int[] sProcStateToProcMem = new int[] { 1202 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT 1203 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI 1204 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP 1205 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 1206 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_BOUND_TOP 1207 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE 1208 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND 1209 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 1210 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND 1211 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP 1212 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE 1213 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER 1214 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING 1215 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT 1216 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME 1217 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY 1218 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY 1219 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT 1220 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT 1221 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY 1222 }; 1223 1224 private static final long[] sFirstAwakePssTimes = new long[] { 1225 PSS_FIRST_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1226 PSS_FIRST_TOP_INTERVAL, // PROC_MEM_TOP 1227 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 1228 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1229 PSS_FIRST_CACHED_INTERVAL, // PROC_MEM_CACHED 1230 }; 1231 1232 private static final long[] sSameAwakePssTimes = new long[] { 1233 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1234 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP 1235 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1236 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE 1237 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED 1238 }; 1239 1240 private static final long[] sFirstAsleepPssTimes = new long[] { 1241 PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1242 PSS_FIRST_ASLEEP_TOP_INTERVAL, // PROC_MEM_TOP 1243 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 1244 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1245 PSS_FIRST_ASLEEP_CACHED_INTERVAL, // PROC_MEM_CACHED 1246 }; 1247 1248 private static final long[] sSameAsleepPssTimes = new long[] { 1249 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1250 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP 1251 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1252 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE 1253 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED 1254 }; 1255 1256 private static final long[] sTestFirstPssTimes = new long[] { 1257 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_PERSISTENT 1258 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_TOP 1259 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 1260 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1261 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED 1262 }; 1263 1264 private static final long[] sTestSamePssTimes = new long[] { 1265 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_PERSISTENT 1266 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_TOP 1267 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1268 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1269 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_CACHED 1270 }; 1271 1272 public static final class ProcStateMemTracker { 1273 final int[] mHighestMem = new int[PROC_MEM_NUM]; 1274 final float[] mScalingFactor = new float[PROC_MEM_NUM]; 1275 int mTotalHighestMem = PROC_MEM_CACHED; 1276 1277 int mPendingMemState; 1278 int mPendingHighestMemState; 1279 float mPendingScalingFactor; 1280 ProcStateMemTracker()1281 public ProcStateMemTracker() { 1282 for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) { 1283 mHighestMem[i] = PROC_MEM_NUM; 1284 mScalingFactor[i] = 1.0f; 1285 } 1286 mPendingMemState = -1; 1287 } 1288 dumpLine(PrintWriter pw)1289 public void dumpLine(PrintWriter pw) { 1290 pw.print("best="); 1291 pw.print(mTotalHighestMem); 1292 pw.print(" ("); 1293 boolean needSep = false; 1294 for (int i = 0; i < PROC_MEM_NUM; i++) { 1295 if (mHighestMem[i] < PROC_MEM_NUM) { 1296 if (needSep) { 1297 pw.print(", "); 1298 needSep = false; 1299 } 1300 pw.print(i); 1301 pw.print("="); 1302 pw.print(mHighestMem[i]); 1303 pw.print(" "); 1304 pw.print(mScalingFactor[i]); 1305 pw.print("x"); 1306 needSep = true; 1307 } 1308 } 1309 pw.print(")"); 1310 if (mPendingMemState >= 0) { 1311 pw.print(" / pending state="); 1312 pw.print(mPendingMemState); 1313 pw.print(" highest="); 1314 pw.print(mPendingHighestMemState); 1315 pw.print(" "); 1316 pw.print(mPendingScalingFactor); 1317 pw.print("x"); 1318 } 1319 pw.println(); 1320 } 1321 } 1322 procStatesDifferForMem(int procState1, int procState2)1323 public static boolean procStatesDifferForMem(int procState1, int procState2) { 1324 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2]; 1325 } 1326 minTimeFromStateChange(boolean test)1327 public static long minTimeFromStateChange(boolean test) { 1328 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE; 1329 } 1330 commitNextPssTime(ProcStateMemTracker tracker)1331 public static void commitNextPssTime(ProcStateMemTracker tracker) { 1332 if (tracker.mPendingMemState >= 0) { 1333 tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState; 1334 tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor; 1335 tracker.mTotalHighestMem = tracker.mPendingHighestMemState; 1336 tracker.mPendingMemState = -1; 1337 } 1338 } 1339 abortNextPssTime(ProcStateMemTracker tracker)1340 public static void abortNextPssTime(ProcStateMemTracker tracker) { 1341 tracker.mPendingMemState = -1; 1342 } 1343 computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, boolean sleeping, long now)1344 public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, 1345 boolean sleeping, long now) { 1346 boolean first; 1347 float scalingFactor; 1348 final int memState = sProcStateToProcMem[procState]; 1349 if (tracker != null) { 1350 final int highestMemState = memState < tracker.mTotalHighestMem 1351 ? memState : tracker.mTotalHighestMem; 1352 first = highestMemState < tracker.mHighestMem[memState]; 1353 tracker.mPendingMemState = memState; 1354 tracker.mPendingHighestMemState = highestMemState; 1355 if (first) { 1356 tracker.mPendingScalingFactor = scalingFactor = 1.0f; 1357 } else { 1358 scalingFactor = tracker.mScalingFactor[memState]; 1359 tracker.mPendingScalingFactor = scalingFactor * 1.5f; 1360 } 1361 } else { 1362 first = true; 1363 scalingFactor = 1.0f; 1364 } 1365 final long[] table = test 1366 ? (first 1367 ? sTestFirstPssTimes 1368 : sTestSamePssTimes) 1369 : (first 1370 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes) 1371 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes)); 1372 long delay = (long)(table[memState] * scalingFactor); 1373 if (delay > PSS_MAX_INTERVAL) { 1374 delay = PSS_MAX_INTERVAL; 1375 } 1376 return now + delay; 1377 } 1378 1379 long getMemLevel(int adjustment) { 1380 for (int i = 0; i < mOomAdj.length; i++) { 1381 if (adjustment <= mOomAdj[i]) { 1382 return mOomMinFree[i] * 1024; 1383 } 1384 } 1385 return mOomMinFree[mOomAdj.length - 1] * 1024; 1386 } 1387 1388 /** 1389 * Return the maximum pss size in kb that we consider a process acceptable to 1390 * restore from its cached state for running in the background when RAM is low. 1391 */ 1392 long getCachedRestoreThresholdKb() { 1393 return mCachedRestoreLevel; 1394 } 1395 1396 /** 1397 * Set the out-of-memory badness adjustment for a process. 1398 * If {@code pid <= 0}, this method will be a no-op. 1399 * 1400 * @param pid The process identifier to set. 1401 * @param uid The uid of the app 1402 * @param amt Adjustment value -- lmkd allows -1000 to +1000 1403 * 1404 * {@hide} 1405 */ 1406 public static void setOomAdj(int pid, int uid, int amt) { 1407 // This indicates that the process is not started yet and so no need to proceed further. 1408 if (pid <= 0) { 1409 return; 1410 } 1411 if (amt == UNKNOWN_ADJ) 1412 return; 1413 1414 long start = SystemClock.elapsedRealtime(); 1415 ByteBuffer buf = ByteBuffer.allocate(4 * 4); 1416 buf.putInt(LMK_PROCPRIO); 1417 buf.putInt(pid); 1418 buf.putInt(uid); 1419 buf.putInt(amt); 1420 writeLmkd(buf, null); 1421 long now = SystemClock.elapsedRealtime(); 1422 if ((now-start) > 250) { 1423 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid 1424 + " = " + amt); 1425 } 1426 } 1427 1428 /* 1429 * {@hide} 1430 */ 1431 public static final void remove(int pid) { 1432 // This indicates that the process is not started yet and so no need to proceed further. 1433 if (pid <= 0) { 1434 return; 1435 } 1436 ByteBuffer buf = ByteBuffer.allocate(4 * 2); 1437 buf.putInt(LMK_PROCREMOVE); 1438 buf.putInt(pid); 1439 writeLmkd(buf, null); 1440 } 1441 1442 /* 1443 * {@hide} 1444 */ 1445 public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) { 1446 ByteBuffer buf = ByteBuffer.allocate(4 * 3); 1447 ByteBuffer repl = ByteBuffer.allocate(4 * 2); 1448 buf.putInt(LMK_GETKILLCNT); 1449 buf.putInt(min_oom_adj); 1450 buf.putInt(max_oom_adj); 1451 // indicate what we are waiting for 1452 repl.putInt(LMK_GETKILLCNT); 1453 repl.rewind(); 1454 if (writeLmkd(buf, repl) && repl.getInt() == LMK_GETKILLCNT) { 1455 return new Integer(repl.getInt()); 1456 } 1457 return null; 1458 } 1459 1460 public boolean onLmkdConnect(OutputStream ostream) { 1461 try { 1462 // Purge any previously registered pids 1463 ByteBuffer buf = ByteBuffer.allocate(4); 1464 buf.putInt(LMK_PROCPURGE); 1465 ostream.write(buf.array(), 0, buf.position()); 1466 if (mOomLevelsSet) { 1467 // Reset oom_adj levels 1468 buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1)); 1469 buf.putInt(LMK_TARGET); 1470 for (int i = 0; i < mOomAdj.length; i++) { 1471 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE); 1472 buf.putInt(mOomAdj[i]); 1473 } 1474 ostream.write(buf.array(), 0, buf.position()); 1475 } 1476 // Subscribe for kill event notifications 1477 buf = ByteBuffer.allocate(4 * 2); 1478 buf.putInt(LMK_SUBSCRIBE); 1479 buf.putInt(LMK_ASYNC_EVENT_KILL); 1480 ostream.write(buf.array(), 0, buf.position()); 1481 } catch (IOException ex) { 1482 return false; 1483 } 1484 return true; 1485 } 1486 1487 private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) { 1488 if (!sLmkdConnection.isConnected()) { 1489 // try to connect immediately and then keep retrying 1490 sKillHandler.sendMessage( 1491 sKillHandler.obtainMessage(KillHandler.LMKD_RECONNECT_MSG)); 1492 1493 // wait for connection retrying 3 times (up to 3 seconds) 1494 if (!sLmkdConnection.waitForConnection(3 * LMKD_RECONNECT_DELAY_MS)) { 1495 return false; 1496 } 1497 } 1498 1499 return sLmkdConnection.exchange(buf, repl); 1500 } 1501 1502 static void killProcessGroup(int uid, int pid) { 1503 /* static; one-time init here */ 1504 if (sKillHandler != null) { 1505 sKillHandler.sendMessage( 1506 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid)); 1507 } else { 1508 Slog.w(TAG, "Asked to kill process group before system bringup!"); 1509 Process.killProcessGroup(uid, pid); 1510 } 1511 } 1512 1513 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean 1514 keepIfLarge) { 1515 if (uid == SYSTEM_UID) { 1516 // The system gets to run in any process. If there are multiple 1517 // processes with the same uid, just pick the first (this 1518 // should never happen). 1519 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 1520 if (procs == null) return null; 1521 final int procCount = procs.size(); 1522 for (int i = 0; i < procCount; i++) { 1523 final int procUid = procs.keyAt(i); 1524 if (!UserHandle.isCore(procUid) || !UserHandle.isSameUser(procUid, uid)) { 1525 // Don't use an app process or different user process for system component. 1526 continue; 1527 } 1528 return procs.valueAt(i); 1529 } 1530 } 1531 ProcessRecord proc = mProcessNames.get(processName, uid); 1532 if (false && proc != null && !keepIfLarge 1533 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 1534 && proc.lastCachedPss >= 4000) { 1535 // Turn this condition on to cause killing to happen regularly, for testing. 1536 if (proc.baseProcessTracker != null) { 1537 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss); 1538 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) { 1539 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg); 1540 FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED, 1541 proc.info.uid, 1542 holder.state.getName(), 1543 holder.state.getPackage(), 1544 proc.lastCachedPss, holder.appVersion); 1545 } 1546 } 1547 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", 1548 ApplicationExitInfo.REASON_OTHER, 1549 ApplicationExitInfo.SUBREASON_LARGE_CACHED, 1550 true); 1551 } else if (proc != null && !keepIfLarge 1552 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 1553 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 1554 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc 1555 .lastCachedPss); 1556 if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) { 1557 if (proc.baseProcessTracker != null) { 1558 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, 1559 proc.lastCachedPss); 1560 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) { 1561 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg); 1562 FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED, 1563 proc.info.uid, 1564 holder.state.getName(), 1565 holder.state.getPackage(), 1566 proc.lastCachedPss, holder.appVersion); 1567 } 1568 } 1569 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", 1570 ApplicationExitInfo.REASON_OTHER, 1571 ApplicationExitInfo.SUBREASON_LARGE_CACHED, 1572 true); 1573 } 1574 } 1575 return proc; 1576 } 1577 getMemoryInfo(ActivityManager.MemoryInfo outInfo)1578 void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 1579 final long homeAppMem = getMemLevel(HOME_APP_ADJ); 1580 final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ); 1581 outInfo.availMem = getFreeMemory(); 1582 outInfo.totalMem = getTotalMemory(); 1583 outInfo.threshold = homeAppMem; 1584 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 1585 outInfo.hiddenAppThreshold = cachedAppMem; 1586 outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ); 1587 outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ); 1588 outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ); 1589 } 1590 1591 ProcessRecord findAppProcessLocked(IBinder app, String reason) { 1592 final int NP = mProcessNames.getMap().size(); 1593 for (int ip = 0; ip < NP; ip++) { 1594 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 1595 final int NA = apps.size(); 1596 for (int ia = 0; ia < NA; ia++) { 1597 ProcessRecord p = apps.valueAt(ia); 1598 if (p.thread != null && p.thread.asBinder() == app) { 1599 return p; 1600 } 1601 } 1602 } 1603 1604 Slog.w(TAG, "Can't find mystery application for " + reason 1605 + " from pid=" + Binder.getCallingPid() 1606 + " uid=" + Binder.getCallingUid() + ": " + app); 1607 return null; 1608 } 1609 1610 private void checkSlow(long startTime, String where) { 1611 long now = SystemClock.uptimeMillis(); 1612 if ((now - startTime) > 50) { 1613 // If we are taking more than 50ms, log about it. 1614 Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where); 1615 } 1616 } 1617 1618 private int[] computeGidsForProcess(int mountExternal, int uid, int[] permGids) { 1619 ArrayList<Integer> gidList = new ArrayList<>(permGids.length + 5); 1620 1621 final int sharedAppGid = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 1622 final int cacheAppGid = UserHandle.getCacheAppGid(UserHandle.getAppId(uid)); 1623 final int userGid = UserHandle.getUserGid(UserHandle.getUserId(uid)); 1624 1625 // Add shared application and profile GIDs so applications can share some 1626 // resources like shared libraries and access user-wide resources 1627 for (int permGid : permGids) { 1628 gidList.add(permGid); 1629 } 1630 if (sharedAppGid != UserHandle.ERR_GID) { 1631 gidList.add(sharedAppGid); 1632 } 1633 if (cacheAppGid != UserHandle.ERR_GID) { 1634 gidList.add(cacheAppGid); 1635 } 1636 if (userGid != UserHandle.ERR_GID) { 1637 gidList.add(userGid); 1638 } 1639 if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE 1640 || mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) { 1641 // For DownloadProviders and MTP: To grant access to /sdcard/Android/ 1642 // And a special case for the FUSE daemon since it runs an MTP server and should have 1643 // access to Android/ 1644 // Note that we must add in the user id, because sdcardfs synthesizes this permission 1645 // based on the user 1646 gidList.add(UserHandle.getUid(UserHandle.getUserId(uid), Process.SDCARD_RW_GID)); 1647 1648 // For devices without sdcardfs, these GIDs are needed instead; note that we 1649 // consciously don't add the user_id in the GID, since these apps are anyway 1650 // isolated to only their own user 1651 gidList.add(Process.EXT_DATA_RW_GID); 1652 gidList.add(Process.EXT_OBB_RW_GID); 1653 } 1654 if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) { 1655 // For devices without sdcardfs, this GID is needed to allow installers access to OBBs 1656 gidList.add(Process.EXT_OBB_RW_GID); 1657 } 1658 if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) { 1659 // For the FUSE daemon: To grant access to the lower filesystem. 1660 // EmulatedVolumes: /data/media and /mnt/expand/<volume>/data/media 1661 // PublicVolumes: /mnt/media_rw/<volume> 1662 gidList.add(Process.MEDIA_RW_GID); 1663 } 1664 1665 int[] gidArray = new int[gidList.size()]; 1666 for (int i = 0; i < gidArray.length; i++) { 1667 gidArray[i] = gidList.get(i); 1668 } 1669 return gidArray; 1670 } 1671 1672 private boolean shouldEnableTaggedPointers(ProcessRecord app) { 1673 // Ensure we have platform + kernel support for TBI. 1674 if (!Zygote.nativeSupportsTaggedPointers()) { 1675 return false; 1676 } 1677 1678 // Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute. 1679 if (!app.info.allowsNativeHeapPointerTagging()) { 1680 return false; 1681 } 1682 1683 // Check to see that the compat feature for TBI is enabled. 1684 if (!mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) { 1685 return false; 1686 } 1687 1688 return true; 1689 } 1690 1691 private int decideTaggingLevel(ProcessRecord app) { 1692 if (shouldEnableTaggedPointers(app)) { 1693 return Zygote.MEMORY_TAG_LEVEL_TBI; 1694 } 1695 1696 return 0; 1697 } 1698 1699 private int decideGwpAsanLevel(ProcessRecord app) { 1700 // Look at the process attribute first. 1701 if (app.processInfo != null 1702 && app.processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) { 1703 return app.processInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_ALWAYS 1704 ? Zygote.GWP_ASAN_LEVEL_ALWAYS 1705 : Zygote.GWP_ASAN_LEVEL_NEVER; 1706 } 1707 // Then at the applicaton attribute. 1708 if (app.info.getGwpAsanMode() != ApplicationInfo.GWP_ASAN_DEFAULT) { 1709 return app.info.getGwpAsanMode() == ApplicationInfo.GWP_ASAN_ALWAYS 1710 ? Zygote.GWP_ASAN_LEVEL_ALWAYS 1711 : Zygote.GWP_ASAN_LEVEL_NEVER; 1712 } 1713 // If the app does not specify gwpAsanMode, the default behavior is lottery among the 1714 // system apps, and disabled for user apps, unless overwritten by the compat feature. 1715 if (mPlatformCompat.isChangeEnabled(GWP_ASAN, app.info)) { 1716 return Zygote.GWP_ASAN_LEVEL_ALWAYS; 1717 } 1718 if ((app.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 1719 return Zygote.GWP_ASAN_LEVEL_LOTTERY; 1720 } 1721 return Zygote.GWP_ASAN_LEVEL_NEVER; 1722 } 1723 1724 /** 1725 * @return {@code true} if process start is successful, false otherwise. 1726 */ 1727 @GuardedBy("mService") 1728 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, 1729 int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks, 1730 boolean mountExtStorageFull, String abiOverride) { 1731 if (app.pendingStart) { 1732 return true; 1733 } 1734 long startTime = SystemClock.uptimeMillis(); 1735 if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) { 1736 checkSlow(startTime, "startProcess: removing from pids map"); 1737 mService.removePidLocked(app); 1738 app.bindMountPending = false; 1739 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1740 checkSlow(startTime, "startProcess: done removing from pids map"); 1741 app.setPid(0); 1742 app.startSeq = 0; 1743 } 1744 1745 if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v( 1746 TAG_PROCESSES, 1747 "startProcessLocked removing on hold: " + app); 1748 mService.mProcessesOnHold.remove(app); 1749 1750 checkSlow(startTime, "startProcess: starting to update cpu stats"); 1751 mService.updateCpuStats(); 1752 checkSlow(startTime, "startProcess: done updating cpu stats"); 1753 1754 try { 1755 try { 1756 final int userId = UserHandle.getUserId(app.uid); 1757 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId); 1758 } catch (RemoteException e) { 1759 throw e.rethrowAsRuntimeException(); 1760 } 1761 1762 int uid = app.uid; 1763 int[] gids = null; 1764 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1765 if (!app.isolated) { 1766 int[] permGids = null; 1767 try { 1768 checkSlow(startTime, "startProcess: getting gids from package manager"); 1769 final IPackageManager pm = AppGlobals.getPackageManager(); 1770 permGids = pm.getPackageGids(app.info.packageName, 1771 MATCH_DIRECT_BOOT_AUTO, app.userId); 1772 if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) { 1773 mountExternal = Zygote.MOUNT_EXTERNAL_FULL; 1774 } else { 1775 StorageManagerInternal storageManagerInternal = LocalServices.getService( 1776 StorageManagerInternal.class); 1777 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, 1778 app.info.packageName); 1779 } 1780 } catch (RemoteException e) { 1781 throw e.rethrowAsRuntimeException(); 1782 } 1783 1784 // Remove any gids needed if the process has been denied permissions. 1785 // NOTE: eventually we should probably have the package manager pre-compute 1786 // this for us? 1787 if (app.processInfo != null && app.processInfo.deniedPermissions != null) { 1788 for (int i = app.processInfo.deniedPermissions.size() - 1; i >= 0; i--) { 1789 int[] denyGids = mService.mPackageManagerInt.getPermissionGids( 1790 app.processInfo.deniedPermissions.valueAt(i), app.userId); 1791 if (denyGids != null) { 1792 for (int gid : denyGids) { 1793 permGids = ArrayUtils.removeInt(permGids, gid); 1794 } 1795 } 1796 } 1797 } 1798 1799 gids = computeGidsForProcess(mountExternal, uid, permGids); 1800 } 1801 app.mountMode = mountExternal; 1802 checkSlow(startTime, "startProcess: building args"); 1803 if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) { 1804 uid = 0; 1805 } 1806 int runtimeFlags = 0; 1807 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1808 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP; 1809 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE; 1810 // Also turn on CheckJNI for debuggable apps. It's quite 1811 // awkward to turn on otherwise. 1812 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1813 1814 // Check if the developer does not want ART verification 1815 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(), 1816 android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) { 1817 runtimeFlags |= Zygote.DISABLE_VERIFIER; 1818 Slog.w(TAG_PROCESSES, app + ": ART verification disabled"); 1819 } 1820 } 1821 // Run the app in safe mode if its manifest requests so or the 1822 // system is booted in safe mode. 1823 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) { 1824 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1825 } 1826 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) { 1827 runtimeFlags |= Zygote.PROFILE_FROM_SHELL; 1828 } 1829 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1830 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1831 } 1832 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info"); 1833 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) { 1834 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; 1835 } 1836 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo"); 1837 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) { 1838 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO; 1839 } 1840 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 1841 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 1842 } 1843 if ("1".equals(SystemProperties.get("debug.assert"))) { 1844 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1845 } 1846 if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) { 1847 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER; 1848 } 1849 if (mService.mNativeDebuggingApp != null 1850 && mService.mNativeDebuggingApp.equals(app.processName)) { 1851 // Enable all debug flags required by the native debugger. 1852 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything 1853 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info 1854 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations 1855 mService.mNativeDebuggingApp = null; 1856 } 1857 1858 if (app.info.isEmbeddedDexUsed() 1859 || (app.info.isPrivilegedApp() 1860 && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) { 1861 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; 1862 } 1863 1864 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) { 1865 app.info.maybeUpdateHiddenApiEnforcementPolicy( 1866 mService.mHiddenApiBlacklist.getPolicy()); 1867 @ApplicationInfo.HiddenApiEnforcementPolicy int policy = 1868 app.info.getHiddenApiEnforcementPolicy(); 1869 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT); 1870 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) { 1871 throw new IllegalStateException("Invalid API policy: " + policy); 1872 } 1873 runtimeFlags |= policyBits; 1874 1875 if (disableTestApiChecks) { 1876 runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY; 1877 } 1878 } 1879 1880 String useAppImageCache = SystemProperties.get( 1881 PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, ""); 1882 // Property defaults to true currently. 1883 if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) { 1884 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE; 1885 } 1886 1887 runtimeFlags |= decideGwpAsanLevel(app); 1888 1889 String invokeWith = null; 1890 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1891 // Debuggable apps may include a wrapper script with their library directory. 1892 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; 1893 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 1894 try { 1895 if (new File(wrapperFileName).exists()) { 1896 invokeWith = "/system/bin/logwrapper " + wrapperFileName; 1897 } 1898 } finally { 1899 StrictMode.setThreadPolicy(oldPolicy); 1900 } 1901 } 1902 1903 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 1904 if (requiredAbi == null) { 1905 requiredAbi = Build.SUPPORTED_ABIS[0]; 1906 } 1907 1908 String instructionSet = null; 1909 if (app.info.primaryCpuAbi != null) { 1910 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 1911 } 1912 1913 app.gids = gids; 1914 app.setRequiredAbi(requiredAbi); 1915 app.instructionSet = instructionSet; 1916 1917 // If instructionSet is non-null, this indicates that the system_server is spawning a 1918 // process with an ISA that may be different from its own. System (kernel and hardware) 1919 // compatililty for these features is checked in the decideTaggingLevel in the 1920 // system_server process (not the child process). As TBI is only supported in aarch64, 1921 // we can simply ensure that the new process is also aarch64. This prevents the mismatch 1922 // where a 64-bit system server spawns a 32-bit child that thinks it should enable some 1923 // tagging variant. Theoretically, a 32-bit system server could exist that spawns 64-bit 1924 // processes, in which case the new process won't get any tagging. This is fine as we 1925 // haven't seen this configuration in practice, and we can reasonable assume that if 1926 // tagging is desired, the system server will be 64-bit. 1927 if (instructionSet == null || instructionSet.equals("arm64")) { 1928 runtimeFlags |= decideTaggingLevel(app); 1929 } 1930 1931 // the per-user SELinux context must be set 1932 if (TextUtils.isEmpty(app.info.seInfoUser)) { 1933 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined", 1934 new IllegalStateException("SELinux tag not defined for " 1935 + app.info.packageName + " (uid " + app.uid + ")")); 1936 } 1937 final String seInfo = app.info.seInfo 1938 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); 1939 // Start the process. It will either succeed and return a result containing 1940 // the PID of the new process, or else throw a RuntimeException. 1941 final String entryPoint = "android.app.ActivityThread"; 1942 1943 return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, 1944 runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi, 1945 instructionSet, invokeWith, startTime); 1946 } catch (RuntimeException e) { 1947 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e); 1948 1949 // Something went very wrong while trying to start this process; one 1950 // common case is when the package is frozen due to an active 1951 // upgrade. To recover, clean up any active bookkeeping related to 1952 // starting this process. (We already invoked this method once when 1953 // the package was initially frozen through KILL_APPLICATION_MSG, so 1954 // it doesn't hurt to use it again.) 1955 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), 1956 false, false, true, false, false, app.userId, "start failure"); 1957 return false; 1958 } 1959 } 1960 1961 @GuardedBy("mService") 1962 boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app, 1963 int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal, 1964 String seInfo, String requiredAbi, String instructionSet, String invokeWith, 1965 long startTime) { 1966 app.pendingStart = true; 1967 app.killedByAm = false; 1968 app.removed = false; 1969 app.killed = false; 1970 if (app.startSeq != 0) { 1971 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName 1972 + " with non-zero startSeq:" + app.startSeq); 1973 } 1974 if (app.pid != 0) { 1975 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName 1976 + " with non-zero pid:" + app.pid); 1977 } 1978 app.mDisabledCompatChanges = null; 1979 if (mPlatformCompat != null) { 1980 app.mDisabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info); 1981 } 1982 final long startSeq = app.startSeq = ++mProcStartSeqCounter; 1983 app.setStartParams(uid, hostingRecord, seInfo, startTime); 1984 app.setUsingWrapper(invokeWith != null 1985 || Zygote.getWrapProperty(app.processName) != null); 1986 mPendingStarts.put(startSeq, app); 1987 1988 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { 1989 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES, 1990 "Posting procStart msg for " + app.toShortString()); 1991 mService.mProcStartHandler.post(() -> handleProcessStart( 1992 app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal, 1993 requiredAbi, instructionSet, invokeWith, startSeq)); 1994 return true; 1995 } else { 1996 try { 1997 final Process.ProcessStartResult startResult = startProcess(hostingRecord, 1998 entryPoint, app, 1999 uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, 2000 requiredAbi, instructionSet, invokeWith, startTime); 2001 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, 2002 startSeq, false); 2003 } catch (RuntimeException e) { 2004 Slog.e(ActivityManagerService.TAG, "Failure starting process " 2005 + app.processName, e); 2006 app.pendingStart = false; 2007 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), 2008 false, false, true, false, false, app.userId, "start failure"); 2009 } 2010 return app.pid > 0; 2011 } 2012 } 2013 2014 /** 2015 * Main handler routine to start the given process from the ProcStartHandler. 2016 * 2017 * <p>Note: this function doesn't hold the global AM lock intentionally.</p> 2018 */ 2019 private void handleProcessStart(final ProcessRecord app, final String entryPoint, 2020 final int[] gids, final int runtimeFlags, int zygotePolicyFlags, 2021 final int mountExternal, final String requiredAbi, final String instructionSet, 2022 final String invokeWith, final long startSeq) { 2023 // If there is a precede instance of the process, wait for its death with a timeout. 2024 // Use local reference since we are not using locks here 2025 final ProcessRecord precedence = app.mPrecedence; 2026 if (precedence != null) { 2027 final int pid = precedence.pid; 2028 long now = System.currentTimeMillis(); 2029 final long end = now + PROC_KILL_TIMEOUT; 2030 try { 2031 Process.waitForProcessDeath(pid, PROC_KILL_TIMEOUT); 2032 // It's killed successfully, but we'd make sure the cleanup work is done. 2033 synchronized (precedence) { 2034 if (app.mPrecedence != null) { 2035 now = System.currentTimeMillis(); 2036 if (now < end) { 2037 try { 2038 precedence.wait(end - now); 2039 } catch (InterruptedException e) { 2040 } 2041 } 2042 } 2043 if (app.mPrecedence != null) { 2044 // The cleanup work hasn't be done yet, let's log it and continue. 2045 Slog.w(TAG, precedence + " has died, but its cleanup isn't done"); 2046 } 2047 } 2048 } catch (Exception e) { 2049 // It's still alive... 2050 Slog.wtf(TAG, precedence.toString() + " refused to die, but we need to launch " 2051 + app); 2052 } 2053 } 2054 try { 2055 final Process.ProcessStartResult startResult = startProcess(app.hostingRecord, 2056 entryPoint, app, app.startUid, gids, runtimeFlags, zygotePolicyFlags, 2057 mountExternal, app.seInfo, requiredAbi, instructionSet, invokeWith, 2058 app.startTime); 2059 2060 synchronized (mService) { 2061 handleProcessStartedLocked(app, startResult, startSeq); 2062 } 2063 } catch (RuntimeException e) { 2064 synchronized (mService) { 2065 Slog.e(ActivityManagerService.TAG, "Failure starting process " 2066 + app.processName, e); 2067 mPendingStarts.remove(startSeq); 2068 app.pendingStart = false; 2069 mService.forceStopPackageLocked(app.info.packageName, 2070 UserHandle.getAppId(app.uid), 2071 false, false, true, false, false, app.userId, "start failure"); 2072 } 2073 } 2074 } 2075 2076 @GuardedBy("mService") 2077 public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) { 2078 final ApplicationInfo appInfo = appZygote.getAppInfo(); 2079 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); 2080 if (zygoteProcesses != null && (force || zygoteProcesses.size() == 0)) { 2081 // Only remove if no longer in use now, or forced kill 2082 mAppZygotes.remove(appInfo.processName, appInfo.uid); 2083 mAppZygoteProcesses.remove(appZygote); 2084 mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo); 2085 appZygote.stopZygote(); 2086 } 2087 } 2088 2089 @GuardedBy("mService") 2090 private void removeProcessFromAppZygoteLocked(final ProcessRecord app) { 2091 // Free the isolated uid for this process 2092 final IsolatedUidRange appUidRange = 2093 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName, 2094 app.hostingRecord.getDefiningUid()); 2095 if (appUidRange != null) { 2096 appUidRange.freeIsolatedUidLocked(app.uid); 2097 } 2098 2099 final AppZygote appZygote = mAppZygotes.get(app.info.processName, 2100 app.hostingRecord.getDefiningUid()); 2101 if (appZygote != null) { 2102 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); 2103 zygoteProcesses.remove(app); 2104 if (zygoteProcesses.size() == 0) { 2105 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG); 2106 if (app.removed) { 2107 // If we stopped this process because the package hosting it was removed, 2108 // there's no point in delaying the app zygote kill. 2109 killAppZygoteIfNeededLocked(appZygote, false /* force */); 2110 } else { 2111 Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG); 2112 msg.obj = appZygote; 2113 mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS); 2114 } 2115 } 2116 } 2117 } 2118 2119 private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) { 2120 synchronized (mService) { 2121 // The UID for the app zygote should be the UID of the application hosting 2122 // the service. 2123 final int uid = app.hostingRecord.getDefiningUid(); 2124 AppZygote appZygote = mAppZygotes.get(app.info.processName, uid); 2125 final ArrayList<ProcessRecord> zygoteProcessList; 2126 if (appZygote == null) { 2127 if (DEBUG_PROCESSES) { 2128 Slog.d(TAG_PROCESSES, "Creating new app zygote."); 2129 } 2130 final IsolatedUidRange uidRange = 2131 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked( 2132 app.info.processName, app.hostingRecord.getDefiningUid()); 2133 final int userId = UserHandle.getUserId(uid); 2134 // Create the app-zygote and provide it with the UID-range it's allowed 2135 // to setresuid/setresgid to. 2136 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid); 2137 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid); 2138 ApplicationInfo appInfo = new ApplicationInfo(app.info); 2139 // If this was an external service, the package name and uid in the passed in 2140 // ApplicationInfo have been changed to match those of the calling package; 2141 // that is not what we want for the AppZygote though, which needs to have the 2142 // packageName and uid of the defining application. This is because the 2143 // preloading only makes sense in the context of the defining application, 2144 // not the calling one. 2145 appInfo.packageName = app.hostingRecord.getDefiningPackageName(); 2146 appInfo.uid = uid; 2147 appZygote = new AppZygote(appInfo, uid, firstUid, lastUid); 2148 mAppZygotes.put(app.info.processName, uid, appZygote); 2149 zygoteProcessList = new ArrayList<ProcessRecord>(); 2150 mAppZygoteProcesses.put(appZygote, zygoteProcessList); 2151 } else { 2152 if (DEBUG_PROCESSES) { 2153 Slog.d(TAG_PROCESSES, "Reusing existing app zygote."); 2154 } 2155 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote); 2156 zygoteProcessList = mAppZygoteProcesses.get(appZygote); 2157 } 2158 // Note that we already add the app to mAppZygoteProcesses here; 2159 // this is so that another thread can't come in and kill the zygote 2160 // before we've even tried to start the process. If the process launch 2161 // goes wrong, we'll clean this up in removeProcessNameLocked() 2162 zygoteProcessList.add(app); 2163 2164 return appZygote; 2165 } 2166 } 2167 2168 private Map<String, Pair<String, Long>> getPackageAppDataInfoMap(PackageManagerInternal pmInt, 2169 String[] packages, int uid) { 2170 Map<String, Pair<String, Long>> result = new ArrayMap<>(packages.length); 2171 int userId = UserHandle.getUserId(uid); 2172 for (String packageName : packages) { 2173 AndroidPackage androidPackage = pmInt.getPackage(packageName); 2174 if (androidPackage == null) { 2175 Slog.w(TAG, "Unknown package:" + packageName); 2176 continue; 2177 } 2178 String volumeUuid = androidPackage.getVolumeUuid(); 2179 long inode = pmInt.getCeDataInode(packageName, userId); 2180 if (inode == 0) { 2181 Slog.w(TAG, packageName + " inode == 0 (b/152760674)"); 2182 return null; 2183 } 2184 result.put(packageName, Pair.create(volumeUuid, inode)); 2185 } 2186 2187 return result; 2188 } 2189 2190 private boolean needsStorageDataIsolation(StorageManagerInternal storageManagerInternal, 2191 ProcessRecord app) { 2192 return mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid) 2193 && !storageManagerInternal.isExternalStorageService(app.uid) 2194 // Special mounting mode doesn't need to have data isolation as they won't 2195 // access /mnt/user anyway. 2196 && app.mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE 2197 && app.mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH 2198 && app.mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER; 2199 } 2200 2201 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint, 2202 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, 2203 int mountExternal, String seInfo, String requiredAbi, String instructionSet, 2204 String invokeWith, long startTime) { 2205 try { 2206 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + 2207 app.processName); 2208 checkSlow(startTime, "startProcess: asking zygote to start proc"); 2209 final boolean isTopApp = hostingRecord.isTopApp(); 2210 if (isTopApp) { 2211 // Use has-foreground-activities as a temporary hint so the current scheduling 2212 // group won't be lost when the process is attaching. The actual state will be 2213 // refreshed when computing oom-adj. 2214 app.setHasForegroundActivities(true); 2215 } 2216 2217 Map<String, Pair<String, Long>> pkgDataInfoMap; 2218 Map<String, Pair<String, Long>> whitelistedAppDataInfoMap; 2219 boolean bindMountAppStorageDirs = false; 2220 boolean bindMountAppsData = mAppDataIsolationEnabled 2221 && (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid)) 2222 && mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info); 2223 2224 // Get all packages belongs to the same shared uid. sharedPackages is empty array 2225 // if it doesn't have shared uid. 2226 final PackageManagerInternal pmInt = mService.getPackageManagerInternalLocked(); 2227 final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage( 2228 app.info.packageName, app.userId); 2229 final String[] targetPackagesList = sharedPackages.length == 0 2230 ? new String[]{app.info.packageName} : sharedPackages; 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 mAppDataIsolationWhitelistedApps, so 2240 // it won't be mounted twice. 2241 final Set<String> whitelistedApps = new ArraySet<>(mAppDataIsolationWhitelistedApps); 2242 for (String pkg : targetPackagesList) { 2243 whitelistedApps.remove(pkg); 2244 } 2245 2246 whitelistedAppDataInfoMap = getPackageAppDataInfoMap(pmInt, 2247 whitelistedApps.toArray(new String[0]), uid); 2248 if (whitelistedAppDataInfoMap == 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 int userId = UserHandle.getUserId(uid); 2255 StorageManagerInternal storageManagerInternal = LocalServices.getService( 2256 StorageManagerInternal.class); 2257 if (needsStorageDataIsolation(storageManagerInternal, app)) { 2258 bindMountAppStorageDirs = true; 2259 if (pkgDataInfoMap == null || 2260 !storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(), 2261 app.processName)) { 2262 // Cannot prepare Android/app and Android/obb directory or inode == 0, 2263 // so we won't mount it in zygote, but resume the mount after unlocking device. 2264 app.bindMountPending = true; 2265 bindMountAppStorageDirs = false; 2266 } 2267 } 2268 2269 // If it's an isolated process, it should not even mount its own app data directories, 2270 // since it has no access to them anyway. 2271 if (app.isolated) { 2272 pkgDataInfoMap = null; 2273 whitelistedAppDataInfoMap = null; 2274 } 2275 2276 final Process.ProcessStartResult startResult; 2277 if (hostingRecord.usesWebviewZygote()) { 2278 startResult = startWebView(entryPoint, 2279 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 2280 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2281 app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges, 2282 new String[]{PROC_START_SEQ_IDENT + app.startSeq}); 2283 } else if (hostingRecord.usesAppZygote()) { 2284 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); 2285 2286 // We can't isolate app data and storage data as parent zygote already did that. 2287 startResult = appZygote.getProcess().start(entryPoint, 2288 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 2289 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2290 app.info.dataDir, null, app.info.packageName, 2291 /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp, 2292 app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap, 2293 false, false, 2294 new String[]{PROC_START_SEQ_IDENT + app.startSeq}); 2295 } else { 2296 startResult = Process.start(entryPoint, 2297 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 2298 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2299 app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags, 2300 isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap, 2301 whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs, 2302 new String[]{PROC_START_SEQ_IDENT + app.startSeq}); 2303 } 2304 checkSlow(startTime, "startProcess: returned from zygote!"); 2305 return startResult; 2306 } finally { 2307 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2308 } 2309 } 2310 2311 @GuardedBy("mService") 2312 void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, int zygotePolicyFlags) { 2313 startProcessLocked(app, hostingRecord, zygotePolicyFlags, null /* abiOverride */); 2314 } 2315 2316 @GuardedBy("mService") 2317 final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, 2318 int zygotePolicyFlags, String abiOverride) { 2319 return startProcessLocked(app, hostingRecord, zygotePolicyFlags, 2320 false /* disableHiddenApiChecks */, false /* disableTestApiChecks */, 2321 false /* mountExtStorageFull */, abiOverride); 2322 } 2323 2324 @GuardedBy("mService") 2325 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2326 boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, 2327 int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid, 2328 boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs, 2329 Runnable crashHandler) { 2330 long startTime = SystemClock.uptimeMillis(); 2331 ProcessRecord app; 2332 if (!isolated) { 2333 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2334 checkSlow(startTime, "startProcess: after getProcessRecord"); 2335 2336 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) { 2337 // If we are in the background, then check to see if this process 2338 // is bad. If so, we will just silently fail. 2339 if (mService.mAppErrors.isBadProcessLocked(info)) { 2340 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2341 + "/" + info.processName); 2342 return null; 2343 } 2344 } else { 2345 // When the user is explicitly starting a process, then clear its 2346 // crash count so that we won't make it bad until they see at 2347 // least one crash dialog again, and make the process good again 2348 // if it had been bad. 2349 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2350 + "/" + info.processName); 2351 mService.mAppErrors.resetProcessCrashTimeLocked(info); 2352 if (mService.mAppErrors.isBadProcessLocked(info)) { 2353 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2354 UserHandle.getUserId(info.uid), info.uid, 2355 info.processName); 2356 mService.mAppErrors.clearBadProcessLocked(info); 2357 if (app != null) { 2358 app.bad = false; 2359 } 2360 } 2361 } 2362 } else { 2363 // If this is an isolated process, it can't re-use an existing process. 2364 app = null; 2365 } 2366 2367 // We don't have to do anything more if: 2368 // (1) There is an existing application record; and 2369 // (2) The caller doesn't think it is dead, OR there is no thread 2370 // object attached to it so we know it couldn't have crashed; and 2371 // (3) There is a pid assigned to it, so it is either starting or 2372 // already running. 2373 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName 2374 + " app=" + app + " knownToBeDead=" + knownToBeDead 2375 + " thread=" + (app != null ? app.thread : null) 2376 + " pid=" + (app != null ? app.pid : -1)); 2377 ProcessRecord precedence = null; 2378 if (app != null && app.pid > 0) { 2379 if ((!knownToBeDead && !app.killed) || app.thread == null) { 2380 // We already have the app running, or are waiting for it to 2381 // come up (we have a pid but not yet its thread), so keep it. 2382 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app); 2383 // If this is a new package in the process, add the package to the list 2384 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats); 2385 checkSlow(startTime, "startProcess: done, added package to proc"); 2386 return app; 2387 } 2388 2389 // An application record is attached to a previous process, 2390 // clean it up now. 2391 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app); 2392 checkSlow(startTime, "startProcess: bad proc running, killing"); 2393 ProcessList.killProcessGroup(app.uid, app.pid); 2394 checkSlow(startTime, "startProcess: done killing old proc"); 2395 2396 Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process"); 2397 // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup 2398 // routine of it yet, but we'd set it as the precedence of the new process. 2399 precedence = app; 2400 app = null; 2401 } 2402 2403 if (app == null) { 2404 checkSlow(startTime, "startProcess: creating new process record"); 2405 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord); 2406 if (app == null) { 2407 Slog.w(TAG, "Failed making new process record for " 2408 + processName + "/" + info.uid + " isolated=" + isolated); 2409 return null; 2410 } 2411 app.crashHandler = crashHandler; 2412 app.isolatedEntryPoint = entryPoint; 2413 app.isolatedEntryPointArgs = entryPointArgs; 2414 if (precedence != null) { 2415 app.mPrecedence = precedence; 2416 precedence.mSuccessor = app; 2417 } 2418 checkSlow(startTime, "startProcess: done creating new process record"); 2419 } else { 2420 // If this is a new package in the process, add the package to the list 2421 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats); 2422 checkSlow(startTime, "startProcess: added package to existing proc"); 2423 } 2424 2425 // If the system is not ready yet, then hold off on starting this 2426 // process until it is. 2427 if (!mService.mProcessesReady 2428 && !mService.isAllowedWhileBooting(info) 2429 && !allowWhileBooting) { 2430 if (!mService.mProcessesOnHold.contains(app)) { 2431 mService.mProcessesOnHold.add(app); 2432 } 2433 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, 2434 "System not ready, putting on hold: " + app); 2435 checkSlow(startTime, "startProcess: returning with proc on hold"); 2436 return app; 2437 } 2438 2439 checkSlow(startTime, "startProcess: stepping in to startProcess"); 2440 final boolean success = 2441 startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride); 2442 checkSlow(startTime, "startProcess: done starting proc!"); 2443 return success ? app : null; 2444 } 2445 2446 @GuardedBy("mService") 2447 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) { 2448 StringBuilder sb = null; 2449 if (app.killedByAm) { 2450 if (sb == null) sb = new StringBuilder(); 2451 sb.append("killedByAm=true;"); 2452 } 2453 if (mProcessNames.get(app.processName, app.uid) != app) { 2454 if (sb == null) sb = new StringBuilder(); 2455 sb.append("No entry in mProcessNames;"); 2456 } 2457 if (!app.pendingStart) { 2458 if (sb == null) sb = new StringBuilder(); 2459 sb.append("pendingStart=false;"); 2460 } 2461 if (app.startSeq > expectedStartSeq) { 2462 if (sb == null) sb = new StringBuilder(); 2463 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";"); 2464 } 2465 try { 2466 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, app.userId); 2467 } catch (RemoteException e) { 2468 // unexpected; ignore 2469 } catch (SecurityException e) { 2470 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { 2471 if (sb == null) sb = new StringBuilder(); 2472 sb.append("Package is frozen;"); 2473 } else { 2474 // we're not being started async and so should throw to the caller. 2475 throw e; 2476 } 2477 } 2478 return sb == null ? null : sb.toString(); 2479 } 2480 2481 @GuardedBy("mService") handleProcessStartedLocked(ProcessRecord pending, Process.ProcessStartResult startResult, long expectedStartSeq)2482 private boolean handleProcessStartedLocked(ProcessRecord pending, 2483 Process.ProcessStartResult startResult, long expectedStartSeq) { 2484 // Indicates that this process start has been taken care of. 2485 if (mPendingStarts.get(expectedStartSeq) == null) { 2486 if (pending.pid == startResult.pid) { 2487 pending.setUsingWrapper(startResult.usingWrapper); 2488 // TODO: Update already existing clients of usingWrapper 2489 } 2490 return false; 2491 } 2492 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper, 2493 expectedStartSeq, false); 2494 } 2495 2496 @GuardedBy("mService") handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, long expectedStartSeq, boolean procAttached)2497 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, 2498 long expectedStartSeq, boolean procAttached) { 2499 mPendingStarts.remove(expectedStartSeq); 2500 final String reason = isProcStartValidLocked(app, expectedStartSeq); 2501 if (reason != null) { 2502 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + 2503 pid 2504 + ", " + reason); 2505 app.pendingStart = false; 2506 killProcessQuiet(pid); 2507 Process.killProcessGroup(app.uid, app.pid); 2508 noteAppKill(app, ApplicationExitInfo.REASON_OTHER, 2509 ApplicationExitInfo.SUBREASON_INVALID_START, reason); 2510 return false; 2511 } 2512 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2513 checkSlow(app.startTime, "startProcess: done updating battery stats"); 2514 2515 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2516 UserHandle.getUserId(app.startUid), pid, app.startUid, 2517 app.processName, app.hostingRecord.getType(), 2518 app.hostingRecord.getName() != null ? app.hostingRecord.getName() : ""); 2519 2520 try { 2521 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid, 2522 app.seInfo, app.info.sourceDir, pid); 2523 } catch (RemoteException ex) { 2524 // Ignore 2525 } 2526 2527 Watchdog.getInstance().processStarted(app.processName, pid); 2528 2529 checkSlow(app.startTime, "startProcess: building log message"); 2530 StringBuilder buf = mStringBuilder; 2531 buf.setLength(0); 2532 buf.append("Start proc "); 2533 buf.append(pid); 2534 buf.append(':'); 2535 buf.append(app.processName); 2536 buf.append('/'); 2537 UserHandle.formatUid(buf, app.startUid); 2538 if (app.isolatedEntryPoint != null) { 2539 buf.append(" ["); 2540 buf.append(app.isolatedEntryPoint); 2541 buf.append("]"); 2542 } 2543 buf.append(" for "); 2544 buf.append(app.hostingRecord.getType()); 2545 if (app.hostingRecord.getName() != null) { 2546 buf.append(" "); 2547 buf.append(app.hostingRecord.getName()); 2548 } 2549 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid); 2550 app.setPid(pid); 2551 app.setUsingWrapper(usingWrapper); 2552 app.pendingStart = false; 2553 checkSlow(app.startTime, "startProcess: starting to update pids map"); 2554 ProcessRecord oldApp; 2555 synchronized (mService.mPidsSelfLocked) { 2556 oldApp = mService.mPidsSelfLocked.get(pid); 2557 } 2558 // If there is already an app occupying that pid that hasn't been cleaned up 2559 if (oldApp != null && !app.isolated) { 2560 // Clean up anything relating to this pid first 2561 Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName 2562 + " startSeq:" + app.startSeq 2563 + " pid:" + pid 2564 + " belongs to another existing app:" + oldApp.processName 2565 + " startSeq:" + oldApp.startSeq); 2566 mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1, 2567 true /*replacingPid*/); 2568 } 2569 mService.addPidLocked(app); 2570 synchronized (mService.mPidsSelfLocked) { 2571 if (!procAttached) { 2572 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2573 msg.obj = app; 2574 mService.mHandler.sendMessageDelayed(msg, usingWrapper 2575 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2576 } 2577 } 2578 checkSlow(app.startTime, "startProcess: done updating pids map"); 2579 return true; 2580 } 2581 removeLruProcessLocked(ProcessRecord app)2582 final void removeLruProcessLocked(ProcessRecord app) { 2583 int lrui = mLruProcesses.lastIndexOf(app); 2584 if (lrui >= 0) { 2585 if (!app.killed) { 2586 if (app.isPersistent()) { 2587 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app); 2588 } else { 2589 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2590 if (app.pid > 0) { 2591 killProcessQuiet(app.pid); 2592 ProcessList.killProcessGroup(app.uid, app.pid); 2593 noteAppKill(app, ApplicationExitInfo.REASON_OTHER, 2594 ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed"); 2595 } else { 2596 app.pendingStart = false; 2597 } 2598 } 2599 } 2600 if (lrui < mLruProcessActivityStart) { 2601 mLruProcessActivityStart--; 2602 } 2603 if (lrui < mLruProcessServiceStart) { 2604 mLruProcessServiceStart--; 2605 } 2606 mLruProcesses.remove(lrui); 2607 } 2608 } 2609 2610 @GuardedBy("mService") killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, int reasonCode, int subReason, String reason)2611 boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, 2612 int reasonCode, int subReason, String reason) { 2613 return killPackageProcessesLocked(packageName, appId, userId, minOomAdj, 2614 false /* callerWillRestart */, true /* allowRestart */, true /* doit */, 2615 false /* evenPersistent */, false /* setRemoved */, reasonCode, 2616 subReason, reason); 2617 } 2618 2619 @GuardedBy("mService") killAppZygotesLocked(String packageName, int appId, int userId, boolean force)2620 void killAppZygotesLocked(String packageName, int appId, int userId, boolean force) { 2621 // See if there are any app zygotes running for this packageName / UID combination, 2622 // and kill it if so. 2623 final ArrayList<AppZygote> zygotesToKill = new ArrayList<>(); 2624 for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) { 2625 for (int i = 0; i < appZygotes.size(); ++i) { 2626 final int appZygoteUid = appZygotes.keyAt(i); 2627 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) { 2628 continue; 2629 } 2630 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) { 2631 continue; 2632 } 2633 final AppZygote appZygote = appZygotes.valueAt(i); 2634 if (packageName != null 2635 && !packageName.equals(appZygote.getAppInfo().packageName)) { 2636 continue; 2637 } 2638 zygotesToKill.add(appZygote); 2639 } 2640 } 2641 for (AppZygote appZygote : zygotesToKill) { 2642 killAppZygoteIfNeededLocked(appZygote, force); 2643 } 2644 } 2645 2646 @GuardedBy("mService") killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode, int subReason, String reason)2647 final boolean killPackageProcessesLocked(String packageName, int appId, 2648 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 2649 boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode, 2650 int subReason, String reason) { 2651 ArrayList<ProcessRecord> procs = new ArrayList<>(); 2652 2653 // Remove all processes this package may have touched: all with the 2654 // same UID (except for the system or root user), and all whose name 2655 // matches the package name. 2656 final int NP = mProcessNames.getMap().size(); 2657 for (int ip = 0; ip < NP; ip++) { 2658 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2659 final int NA = apps.size(); 2660 for (int ia = 0; ia < NA; ia++) { 2661 ProcessRecord app = apps.valueAt(ia); 2662 if (app.isPersistent() && !evenPersistent) { 2663 // we don't kill persistent processes 2664 continue; 2665 } 2666 if (app.removed) { 2667 if (doit) { 2668 procs.add(app); 2669 } 2670 continue; 2671 } 2672 2673 // Skip process if it doesn't meet our oom adj requirement. 2674 if (app.setAdj < minOomAdj) { 2675 // Note it is still possible to have a process with oom adj 0 in the killed 2676 // processes, but it does not mean misjudgment. E.g. a bound service process 2677 // and its client activity process are both in the background, so they are 2678 // collected to be killed. If the client activity is killed first, the service 2679 // may be scheduled to unbind and become an executing service (oom adj 0). 2680 continue; 2681 } 2682 2683 // If no package is specified, we call all processes under the 2684 // give user id. 2685 if (packageName == null) { 2686 if (userId != UserHandle.USER_ALL && app.userId != userId) { 2687 continue; 2688 } 2689 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 2690 continue; 2691 } 2692 // Package has been specified, we want to hit all processes 2693 // that match it. We need to qualify this by the processes 2694 // that are running under the specified app and user ID. 2695 } else { 2696 final boolean isDep = app.pkgDeps != null 2697 && app.pkgDeps.contains(packageName); 2698 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 2699 continue; 2700 } 2701 if (userId != UserHandle.USER_ALL && app.userId != userId) { 2702 continue; 2703 } 2704 if (!app.pkgList.containsKey(packageName) && !isDep) { 2705 continue; 2706 } 2707 } 2708 2709 // Process has passed all conditions, kill it! 2710 if (!doit) { 2711 return true; 2712 } 2713 if (setRemoved) { 2714 app.removed = true; 2715 } 2716 procs.add(app); 2717 } 2718 } 2719 2720 int N = procs.size(); 2721 for (int i=0; i<N; i++) { 2722 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, 2723 reasonCode, subReason, reason); 2724 } 2725 killAppZygotesLocked(packageName, appId, userId, false /* force */); 2726 mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END); 2727 return N > 0; 2728 } 2729 2730 @GuardedBy("mService") removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason)2731 boolean removeProcessLocked(ProcessRecord app, 2732 boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) { 2733 return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode, 2734 ApplicationExitInfo.SUBREASON_UNKNOWN, reason); 2735 } 2736 2737 @GuardedBy("mService") removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, int reasonCode, int subReason, String reason)2738 boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart, 2739 boolean allowRestart, int reasonCode, int subReason, String reason) { 2740 final String name = app.processName; 2741 final int uid = app.uid; 2742 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES, 2743 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")"); 2744 2745 ProcessRecord old = mProcessNames.get(name, uid); 2746 if (old != app) { 2747 // This process is no longer active, so nothing to do. 2748 Slog.w(TAG, "Ignoring remove of inactive process: " + app); 2749 return false; 2750 } 2751 removeProcessNameLocked(name, uid); 2752 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController()); 2753 2754 boolean needRestart = false; 2755 if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app 2756 .pendingStart)) { 2757 int pid = app.pid; 2758 if (pid > 0) { 2759 mService.removePidLocked(app); 2760 app.bindMountPending = false; 2761 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2762 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 2763 if (app.isolated) { 2764 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 2765 mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid); 2766 } 2767 } 2768 boolean willRestart = false; 2769 if (app.isPersistent() && !app.isolated) { 2770 if (!callerWillRestart) { 2771 willRestart = true; 2772 } else { 2773 needRestart = true; 2774 } 2775 } 2776 app.kill(reason, reasonCode, subReason, true); 2777 mService.handleAppDiedLocked(app, willRestart, allowRestart); 2778 if (willRestart) { 2779 removeLruProcessLocked(app); 2780 mService.addAppLocked(app.info, null, false, null /* ABI override */, 2781 ZYGOTE_POLICY_FLAG_EMPTY); 2782 } 2783 } else { 2784 mRemovedProcesses.add(app); 2785 } 2786 2787 return needRestart; 2788 } 2789 2790 @GuardedBy("mService") addProcessNameLocked(ProcessRecord proc)2791 final void addProcessNameLocked(ProcessRecord proc) { 2792 // We shouldn't already have a process under this name, but just in case we 2793 // need to clean up whatever may be there now. 2794 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); 2795 if (old == proc && proc.isPersistent()) { 2796 // We are re-adding a persistent process. Whatevs! Just leave it there. 2797 Slog.w(TAG, "Re-adding persistent process " + proc); 2798 } else if (old != null) { 2799 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc); 2800 } 2801 UidRecord uidRec = mActiveUids.get(proc.uid); 2802 if (uidRec == null) { 2803 uidRec = new UidRecord(proc.uid); 2804 // This is the first appearance of the uid, report it now! 2805 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 2806 "Creating new process uid: " + uidRec); 2807 if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist, 2808 UserHandle.getAppId(proc.uid)) >= 0 2809 || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) { 2810 uidRec.setWhitelist = uidRec.curWhitelist = true; 2811 } 2812 uidRec.updateHasInternetPermission(); 2813 mActiveUids.put(proc.uid, uidRec); 2814 EventLogTags.writeAmUidRunning(uidRec.uid); 2815 mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState(), 2816 uidRec.curCapability); 2817 } 2818 proc.uidRecord = uidRec; 2819 uidRec.procRecords.add(proc); 2820 2821 // Reset render thread tid if it was already set, so new process can set it again. 2822 proc.renderThreadTid = 0; 2823 uidRec.numProcs++; 2824 mProcessNames.put(proc.processName, proc.uid, proc); 2825 if (proc.isolated) { 2826 mIsolatedProcesses.put(proc.uid, proc); 2827 } 2828 } 2829 2830 @GuardedBy("mService") getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, HostingRecord hostingRecord)2831 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, 2832 HostingRecord hostingRecord) { 2833 if (hostingRecord == null || !hostingRecord.usesAppZygote()) { 2834 // Allocate an isolated UID from the global range 2835 return mGlobalIsolatedUids; 2836 } else { 2837 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked( 2838 info.processName, hostingRecord.getDefiningUid()); 2839 } 2840 } 2841 2842 @GuardedBy("mService") newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid, HostingRecord hostingRecord)2843 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 2844 boolean isolated, int isolatedUid, HostingRecord hostingRecord) { 2845 String proc = customProcess != null ? customProcess : info.processName; 2846 final int userId = UserHandle.getUserId(info.uid); 2847 int uid = info.uid; 2848 if (isolated) { 2849 if (isolatedUid == 0) { 2850 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord); 2851 if (uidRange == null) { 2852 return null; 2853 } 2854 uid = uidRange.allocateIsolatedUidLocked(userId); 2855 if (uid == -1) { 2856 return null; 2857 } 2858 } else { 2859 // Special case for startIsolatedProcess (internal only), where 2860 // the uid of the isolated process is specified by the caller. 2861 uid = isolatedUid; 2862 } 2863 mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid); 2864 mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid); 2865 2866 // Register the isolated UID with this application so BatteryStats knows to 2867 // attribute resource usage to the application. 2868 // 2869 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats 2870 // about the process state of the isolated UID *before* it is registered with the 2871 // owning application. 2872 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid); 2873 FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid, 2874 FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED); 2875 } 2876 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid); 2877 2878 if (!mService.mBooted && !mService.mBooting 2879 && userId == UserHandle.USER_SYSTEM 2880 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { 2881 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc. 2882 r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); 2883 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 2884 r.setPersistent(true); 2885 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 2886 } 2887 if (isolated && isolatedUid != 0) { 2888 // Special case for startIsolatedProcess (internal only) - assume the process 2889 // is required by the system server to prevent it being killed. 2890 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ; 2891 } 2892 addProcessNameLocked(r); 2893 return r; 2894 } 2895 2896 @GuardedBy("mService") removeProcessNameLocked(final String name, final int uid)2897 final ProcessRecord removeProcessNameLocked(final String name, final int uid) { 2898 return removeProcessNameLocked(name, uid, null); 2899 } 2900 2901 @GuardedBy("mService") removeProcessNameLocked(final String name, final int uid, final ProcessRecord expecting)2902 final ProcessRecord removeProcessNameLocked(final String name, final int uid, 2903 final ProcessRecord expecting) { 2904 ProcessRecord old = mProcessNames.get(name, uid); 2905 // Only actually remove when the currently recorded value matches the 2906 // record that we expected; if it doesn't match then we raced with a 2907 // newly created process and we don't want to destroy the new one. 2908 if ((expecting == null) || (old == expecting)) { 2909 mProcessNames.remove(name, uid); 2910 } 2911 if (old != null && old.uidRecord != null) { 2912 old.uidRecord.numProcs--; 2913 old.uidRecord.procRecords.remove(old); 2914 if (old.uidRecord.numProcs == 0) { 2915 // No more processes using this uid, tell clients it is gone. 2916 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 2917 "No more processes in " + old.uidRecord); 2918 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE); 2919 EventLogTags.writeAmUidStopped(uid); 2920 mActiveUids.remove(uid); 2921 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 2922 ActivityManager.PROCESS_CAPABILITY_NONE); 2923 } 2924 old.uidRecord = null; 2925 } 2926 mIsolatedProcesses.remove(uid); 2927 mGlobalIsolatedUids.freeIsolatedUidLocked(uid); 2928 // Remove the (expected) ProcessRecord from the app zygote 2929 final ProcessRecord record = expecting != null ? expecting : old; 2930 if (record != null && record.appZygote) { 2931 removeProcessFromAppZygoteLocked(record); 2932 } 2933 2934 return old; 2935 } 2936 2937 /** Call setCoreSettings on all LRU processes, with the new settings. */ 2938 @GuardedBy("mService") updateCoreSettingsLocked(Bundle settings)2939 void updateCoreSettingsLocked(Bundle settings) { 2940 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2941 ProcessRecord processRecord = mLruProcesses.get(i); 2942 try { 2943 if (processRecord.thread != null) { 2944 processRecord.thread.setCoreSettings(settings); 2945 } 2946 } catch (RemoteException re) { 2947 /* ignore */ 2948 } 2949 } 2950 } 2951 2952 /** 2953 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and 2954 * procstate lower than maxProcState. 2955 * @param minTargetSdk 2956 * @param maxProcState 2957 */ 2958 @GuardedBy("mService") killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState)2959 void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) { 2960 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 2961 final int NP = mProcessNames.getMap().size(); 2962 for (int ip = 0; ip < NP; ip++) { 2963 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2964 final int NA = apps.size(); 2965 for (int ia = 0; ia < NA; ia++) { 2966 final ProcessRecord app = apps.valueAt(ia); 2967 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk) 2968 && (maxProcState < 0 || app.setProcState > maxProcState))) { 2969 procs.add(app); 2970 } 2971 } 2972 } 2973 2974 final int N = procs.size(); 2975 for (int i = 0; i < N; i++) { 2976 removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER, 2977 ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except"); 2978 } 2979 } 2980 2981 /** 2982 * Call updateTimePrefs on all LRU processes 2983 * @param timePref The time pref to pass to each process 2984 */ 2985 @GuardedBy("mService") updateAllTimePrefsLocked(int timePref)2986 void updateAllTimePrefsLocked(int timePref) { 2987 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2988 ProcessRecord r = mLruProcesses.get(i); 2989 if (r.thread != null) { 2990 try { 2991 r.thread.updateTimePrefs(timePref); 2992 } catch (RemoteException ex) { 2993 Slog.w(TAG, "Failed to update preferences for: " 2994 + r.info.processName); 2995 } 2996 } 2997 } 2998 } 2999 setAllHttpProxy()3000 void setAllHttpProxy() { 3001 // Update the HTTP proxy for each application thread. 3002 synchronized (mService) { 3003 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 3004 ProcessRecord r = mLruProcesses.get(i); 3005 // Don't dispatch to isolated processes as they can't access ConnectivityManager and 3006 // don't have network privileges anyway. Exclude system server and update it 3007 // separately outside the AMS lock, to avoid deadlock with Connectivity Service. 3008 if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) { 3009 try { 3010 r.thread.updateHttpProxy(); 3011 } catch (RemoteException ex) { 3012 Slog.w(TAG, "Failed to update http proxy for: " 3013 + r.info.processName); 3014 } 3015 } 3016 } 3017 } 3018 ActivityThread.updateHttpProxy(mService.mContext); 3019 } 3020 3021 @GuardedBy("mService") clearAllDnsCacheLocked()3022 void clearAllDnsCacheLocked() { 3023 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3024 ProcessRecord r = mLruProcesses.get(i); 3025 if (r.thread != null) { 3026 try { 3027 r.thread.clearDnsCache(); 3028 } catch (RemoteException ex) { 3029 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 3030 } 3031 } 3032 } 3033 } 3034 3035 @GuardedBy("mService") handleAllTrustStorageUpdateLocked()3036 void handleAllTrustStorageUpdateLocked() { 3037 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3038 ProcessRecord r = mLruProcesses.get(i); 3039 if (r.thread != null) { 3040 try { 3041 r.thread.handleTrustStorageUpdate(); 3042 } catch (RemoteException ex) { 3043 Slog.w(TAG, "Failed to handle trust storage update for: " + 3044 r.info.processName); 3045 } 3046 } 3047 } 3048 } 3049 3050 @GuardedBy("mService") updateLruProcessInternalLocked(ProcessRecord app, long now, int index, int lruSeq, String what, Object obj, ProcessRecord srcApp)3051 int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 3052 int lruSeq, String what, Object obj, ProcessRecord srcApp) { 3053 app.lastActivityTime = now; 3054 3055 if (app.hasActivitiesOrRecentTasks()) { 3056 // Don't want to touch dependent processes that are hosting activities. 3057 return index; 3058 } 3059 3060 int lrui = mLruProcesses.lastIndexOf(app); 3061 if (lrui < 0) { 3062 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 3063 + what + " " + obj + " from " + srcApp); 3064 return index; 3065 } 3066 3067 if (lrui >= index) { 3068 // Don't want to cause this to move dependent processes *back* in the 3069 // list as if they were less frequently used. 3070 return index; 3071 } 3072 3073 if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) { 3074 // Don't want to touch dependent processes that are hosting activities. 3075 return index; 3076 } 3077 3078 mLruProcesses.remove(lrui); 3079 if (index > 0) { 3080 index--; 3081 } 3082 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index 3083 + " in LRU list: " + app); 3084 mLruProcesses.add(index, app); 3085 app.lruSeq = lruSeq; 3086 return index; 3087 } 3088 3089 /** 3090 * Handle the case where we are inserting a process hosting client activities: 3091 * Make sure any groups have their order match their importance, and take care of 3092 * distributing old clients across other activity processes so they can't spam 3093 * the LRU list. Processing of the list will be restricted by the indices provided, 3094 * and not extend out of them. 3095 * 3096 * @param topApp The app at the top that has just been inserted in to the list. 3097 * @param topI The position in the list where topApp was inserted; this is the start (at the 3098 * top) where we are going to do our processing. 3099 * @param bottomI The last position at which we will be processing; this is the end position 3100 * of whichever section of the LRU list we are in. Nothing past it will be 3101 * touched. 3102 * @param endIndex The current end of the top being processed. Typically topI - 1. That is, 3103 * where we are going to start potentially adjusting other entries in the list. 3104 */ updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI, final int bottomI, int endIndex)3105 private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI, 3106 final int bottomI, int endIndex) { 3107 if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity 3108 || !topApp.hasClientActivities()) { 3109 // If this is not a special process that has client activities, then there is 3110 // nothing to do. 3111 return; 3112 } 3113 3114 final int uid = topApp.info.uid; 3115 if (topApp.connectionGroup > 0) { 3116 int endImportance = topApp.connectionImportance; 3117 for (int i = endIndex; i >= bottomI; i--) { 3118 final ProcessRecord subProc = mLruProcesses.get(i); 3119 if (subProc.info.uid == uid 3120 && subProc.connectionGroup == topApp.connectionGroup) { 3121 if (i == endIndex && subProc.connectionImportance >= endImportance) { 3122 // This process is already in the group, and its importance 3123 // is not as strong as the process before it, so keep it 3124 // correctly positioned in the group. 3125 if (DEBUG_LRU) Slog.d(TAG_LRU, 3126 "Keeping in-place above " + subProc 3127 + " endImportance=" + endImportance 3128 + " group=" + subProc.connectionGroup 3129 + " importance=" + subProc.connectionImportance); 3130 endIndex--; 3131 endImportance = subProc.connectionImportance; 3132 } else { 3133 // We want to pull this up to be with the rest of the group, 3134 // and order within the group by importance. 3135 if (DEBUG_LRU) Slog.d(TAG_LRU, 3136 "Pulling up " + subProc 3137 + " to position in group with importance=" 3138 + subProc.connectionImportance); 3139 boolean moved = false; 3140 for (int pos = topI; pos > endIndex; pos--) { 3141 final ProcessRecord posProc = mLruProcesses.get(pos); 3142 if (subProc.connectionImportance 3143 <= posProc.connectionImportance) { 3144 mLruProcesses.remove(i); 3145 mLruProcesses.add(pos, subProc); 3146 if (DEBUG_LRU) Slog.d(TAG_LRU, 3147 "Moving " + subProc 3148 + " from position " + i + " to above " + posProc 3149 + " @ " + pos); 3150 moved = true; 3151 endIndex--; 3152 break; 3153 } 3154 } 3155 if (!moved) { 3156 // Goes to the end of the group. 3157 mLruProcesses.remove(i); 3158 mLruProcesses.add(endIndex, subProc); 3159 if (DEBUG_LRU) Slog.d(TAG_LRU, 3160 "Moving " + subProc 3161 + " from position " + i + " to end of group @ " 3162 + endIndex); 3163 endIndex--; 3164 endImportance = subProc.connectionImportance; 3165 } 3166 } 3167 } 3168 } 3169 3170 } 3171 // To keep it from spamming the LRU list (by making a bunch of clients), 3172 // we will distribute other entries owned by it to be in-between other apps. 3173 int i = endIndex; 3174 while (i >= bottomI) { 3175 ProcessRecord subProc = mLruProcesses.get(i); 3176 if (DEBUG_LRU) Slog.d(TAG_LRU, 3177 "Looking to spread old procs, at " + subProc + " @ " + i); 3178 if (subProc.info.uid != uid) { 3179 // This is a different app... if we have gone through some of the 3180 // target app, pull this up to be before them. We want to pull up 3181 // one activity process, but any number of non-activity processes. 3182 if (i < endIndex) { 3183 boolean hasActivity = false; 3184 int connUid = 0; 3185 int connGroup = 0; 3186 while (i >= bottomI) { 3187 mLruProcesses.remove(i); 3188 mLruProcesses.add(endIndex, subProc); 3189 if (DEBUG_LRU) Slog.d(TAG_LRU, 3190 "Different app, moving to " + endIndex); 3191 i--; 3192 if (i < bottomI) { 3193 break; 3194 } 3195 subProc = mLruProcesses.get(i); 3196 if (DEBUG_LRU) Slog.d(TAG_LRU, 3197 "Looking at next app at " + i + ": " + subProc); 3198 if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) { 3199 if (DEBUG_LRU) Slog.d(TAG_LRU, 3200 "This is hosting an activity!"); 3201 if (hasActivity) { 3202 // Already found an activity, done. 3203 if (DEBUG_LRU) Slog.d(TAG_LRU, 3204 "Already found an activity, done"); 3205 break; 3206 } 3207 hasActivity = true; 3208 } else if (subProc.hasClientActivities()) { 3209 if (DEBUG_LRU) Slog.d(TAG_LRU, 3210 "This is a client of an activity"); 3211 if (hasActivity) { 3212 if (connUid == 0 || connUid != subProc.info.uid) { 3213 // Already have an activity that is not from from a client 3214 // connection or is a different client connection, done. 3215 if (DEBUG_LRU) Slog.d(TAG_LRU, 3216 "Already found a different activity: connUid=" 3217 + connUid + " uid=" + subProc.info.uid); 3218 break; 3219 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) { 3220 // Previously saw a different group or not from a group, 3221 // want to treat these as different things. 3222 if (DEBUG_LRU) Slog.d(TAG_LRU, 3223 "Already found a different group: connGroup=" 3224 + connGroup + " group=" + subProc.connectionGroup); 3225 break; 3226 } 3227 } else { 3228 if (DEBUG_LRU) Slog.d(TAG_LRU, 3229 "This is an activity client! uid=" 3230 + subProc.info.uid + " group=" + subProc.connectionGroup); 3231 hasActivity = true; 3232 connUid = subProc.info.uid; 3233 connGroup = subProc.connectionGroup; 3234 } 3235 } 3236 endIndex--; 3237 } 3238 } 3239 // Find the end of the next group of processes for target app. This 3240 // is after any entries of different apps (so we don't change the existing 3241 // relative order of apps) and then after the next last group of processes 3242 // of the target app. 3243 for (endIndex--; endIndex >= bottomI; endIndex--) { 3244 final ProcessRecord endProc = mLruProcesses.get(endIndex); 3245 if (endProc.info.uid == uid) { 3246 if (DEBUG_LRU) Slog.d(TAG_LRU, 3247 "Found next group of app: " + endProc + " @ " 3248 + endIndex); 3249 break; 3250 } 3251 } 3252 if (endIndex >= bottomI) { 3253 final ProcessRecord endProc = mLruProcesses.get(endIndex); 3254 for (endIndex--; endIndex >= bottomI; endIndex--) { 3255 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex); 3256 if (nextEndProc.info.uid != uid 3257 || nextEndProc.connectionGroup != endProc.connectionGroup) { 3258 if (DEBUG_LRU) Slog.d(TAG_LRU, 3259 "Found next group or app: " + nextEndProc + " @ " 3260 + endIndex + " group=" + nextEndProc.connectionGroup); 3261 break; 3262 } 3263 } 3264 } 3265 if (DEBUG_LRU) Slog.d(TAG_LRU, 3266 "Bumping scan position to " + endIndex); 3267 i = endIndex; 3268 } else { 3269 i--; 3270 } 3271 } 3272 } 3273 updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client)3274 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 3275 ProcessRecord client) { 3276 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities() 3277 || app.treatLikeActivity; 3278 final boolean hasService = false; // not impl yet. app.services.size() > 0; 3279 if (!activityChange && hasActivity) { 3280 // The process has activities, so we are only allowing activity-based adjustments 3281 // to move it. It should be kept in the front of the list with other 3282 // processes that have activities, and we don't want those to change their 3283 // order except due to activity operations. 3284 return; 3285 } 3286 3287 mLruSeq++; 3288 final long now = SystemClock.uptimeMillis(); 3289 app.lastActivityTime = now; 3290 3291 // First a quick reject: if the app is already at the position we will 3292 // put it, then there is nothing to do. 3293 if (hasActivity) { 3294 final int N = mLruProcesses.size(); 3295 if (N > 0 && mLruProcesses.get(N - 1) == app) { 3296 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app); 3297 return; 3298 } 3299 } else { 3300 if (mLruProcessServiceStart > 0 3301 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 3302 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app); 3303 return; 3304 } 3305 } 3306 3307 int lrui = mLruProcesses.lastIndexOf(app); 3308 3309 if (app.isPersistent() && lrui >= 0) { 3310 // We don't care about the position of persistent processes, as long as 3311 // they are in the list. 3312 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app); 3313 return; 3314 } 3315 3316 /* In progress: compute new position first, so we can avoid doing work 3317 if the process is not actually going to move. Not yet working. 3318 int addIndex; 3319 int nextIndex; 3320 boolean inActivity = false, inService = false; 3321 if (hasActivity) { 3322 // Process has activities, put it at the very tipsy-top. 3323 addIndex = mLruProcesses.size(); 3324 nextIndex = mLruProcessServiceStart; 3325 inActivity = true; 3326 } else if (hasService) { 3327 // Process has services, put it at the top of the service list. 3328 addIndex = mLruProcessActivityStart; 3329 nextIndex = mLruProcessServiceStart; 3330 inActivity = true; 3331 inService = true; 3332 } else { 3333 // Process not otherwise of interest, it goes to the top of the non-service area. 3334 addIndex = mLruProcessServiceStart; 3335 if (client != null) { 3336 int clientIndex = mLruProcesses.lastIndexOf(client); 3337 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 3338 + app); 3339 if (clientIndex >= 0 && addIndex > clientIndex) { 3340 addIndex = clientIndex; 3341 } 3342 } 3343 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 3344 } 3345 3346 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 3347 + mLruProcessActivityStart + "): " + app); 3348 */ 3349 3350 if (lrui >= 0) { 3351 if (lrui < mLruProcessActivityStart) { 3352 mLruProcessActivityStart--; 3353 } 3354 if (lrui < mLruProcessServiceStart) { 3355 mLruProcessServiceStart--; 3356 } 3357 /* 3358 if (addIndex > lrui) { 3359 addIndex--; 3360 } 3361 if (nextIndex > lrui) { 3362 nextIndex--; 3363 } 3364 */ 3365 mLruProcesses.remove(lrui); 3366 } 3367 3368 /* 3369 mLruProcesses.add(addIndex, app); 3370 if (inActivity) { 3371 mLruProcessActivityStart++; 3372 } 3373 if (inService) { 3374 mLruProcessActivityStart++; 3375 } 3376 */ 3377 3378 int nextIndex; 3379 int nextActivityIndex = -1; 3380 if (hasActivity) { 3381 final int N = mLruProcesses.size(); 3382 nextIndex = mLruProcessServiceStart; 3383 if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity 3384 && mLruProcessActivityStart < (N - 1)) { 3385 // Process doesn't have activities, but has clients with 3386 // activities... move it up, but below the app that is binding to it. 3387 if (DEBUG_LRU) Slog.d(TAG_LRU, 3388 "Adding to second-top of LRU activity list: " + app 3389 + " group=" + app.connectionGroup 3390 + " importance=" + app.connectionImportance); 3391 int pos = N - 1; 3392 while (pos > mLruProcessActivityStart) { 3393 final ProcessRecord posproc = mLruProcesses.get(pos); 3394 if (posproc.info.uid == app.info.uid) { 3395 // Technically this app could have multiple processes with different 3396 // activities and so we should be looking for the actual process that 3397 // is bound to the target proc... but I don't really care, do you? 3398 break; 3399 } 3400 pos--; 3401 } 3402 mLruProcesses.add(pos, app); 3403 // If this process is part of a group, need to pull up any other processes 3404 // in that group to be with it. 3405 int endIndex = pos - 1; 3406 if (endIndex < mLruProcessActivityStart) { 3407 endIndex = mLruProcessActivityStart; 3408 } 3409 nextActivityIndex = endIndex; 3410 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex); 3411 } else { 3412 // Process has activities, put it at the very tipsy-top. 3413 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app); 3414 mLruProcesses.add(app); 3415 nextActivityIndex = mLruProcesses.size() - 1; 3416 } 3417 } else if (hasService) { 3418 // Process has services, put it at the top of the service list. 3419 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app); 3420 mLruProcesses.add(mLruProcessActivityStart, app); 3421 nextIndex = mLruProcessServiceStart; 3422 mLruProcessActivityStart++; 3423 } else { 3424 // Process not otherwise of interest, it goes to the top of the non-service area. 3425 int index = mLruProcessServiceStart; 3426 if (client != null) { 3427 // If there is a client, don't allow the process to be moved up higher 3428 // in the list than that client. 3429 int clientIndex = mLruProcesses.lastIndexOf(client); 3430 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client 3431 + " when updating " + app); 3432 if (clientIndex <= lrui) { 3433 // Don't allow the client index restriction to push it down farther in the 3434 // list than it already is. 3435 clientIndex = lrui; 3436 } 3437 if (clientIndex >= 0 && index > clientIndex) { 3438 index = clientIndex; 3439 } 3440 } 3441 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app); 3442 mLruProcesses.add(index, app); 3443 nextIndex = index - 1; 3444 mLruProcessActivityStart++; 3445 mLruProcessServiceStart++; 3446 if (index > 1) { 3447 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1); 3448 } 3449 } 3450 3451 app.lruSeq = mLruSeq; 3452 3453 // If the app is currently using a content provider or service, 3454 // bump those processes as well. 3455 for (int j = app.connections.size() - 1; j >= 0; j--) { 3456 ConnectionRecord cr = app.connections.valueAt(j); 3457 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 3458 && cr.binding.service.app != null 3459 && cr.binding.service.app.lruSeq != mLruSeq 3460 && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0 3461 && !cr.binding.service.app.isPersistent()) { 3462 if (cr.binding.service.app.hasClientActivities()) { 3463 if (nextActivityIndex >= 0) { 3464 nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app, 3465 now, 3466 nextActivityIndex, mLruSeq, 3467 "service connection", cr, app); 3468 } 3469 } else { 3470 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, 3471 now, 3472 nextIndex, mLruSeq, 3473 "service connection", cr, app); 3474 } 3475 } 3476 } 3477 for (int j = app.conProviders.size() - 1; j >= 0; j--) { 3478 ContentProviderRecord cpr = app.conProviders.get(j).provider; 3479 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) { 3480 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq, 3481 "provider reference", cpr, app); 3482 } 3483 } 3484 } 3485 getLRURecordForAppLocked(IApplicationThread thread)3486 final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) { 3487 if (thread == null) { 3488 return null; 3489 } 3490 final IBinder threadBinder = thread.asBinder(); 3491 // Find the application record. 3492 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3493 final ProcessRecord rec = mLruProcesses.get(i); 3494 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3495 return rec; 3496 } 3497 } 3498 return null; 3499 } 3500 haveBackgroundProcessLocked()3501 boolean haveBackgroundProcessLocked() { 3502 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3503 final ProcessRecord rec = mLruProcesses.get(i); 3504 if (rec.thread != null 3505 && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) { 3506 return true; 3507 } 3508 } 3509 return false; 3510 } 3511 procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp, int clientTargetSdk)3512 private static int procStateToImportance(int procState, int memAdj, 3513 ActivityManager.RunningAppProcessInfo currApp, 3514 int clientTargetSdk) { 3515 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk( 3516 procState, clientTargetSdk); 3517 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 3518 currApp.lru = memAdj; 3519 } else { 3520 currApp.lru = 0; 3521 } 3522 return imp; 3523 } 3524 3525 @GuardedBy("mService") fillInProcMemInfoLocked(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, int clientTargetSdk)3526 void fillInProcMemInfoLocked(ProcessRecord app, 3527 ActivityManager.RunningAppProcessInfo outInfo, 3528 int clientTargetSdk) { 3529 outInfo.pid = app.pid; 3530 outInfo.uid = app.info.uid; 3531 if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) { 3532 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 3533 } 3534 if (app.isPersistent()) { 3535 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 3536 } 3537 if (app.hasActivities()) { 3538 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 3539 } 3540 outInfo.lastTrimLevel = app.trimMemoryLevel; 3541 int adj = app.curAdj; 3542 int procState = app.getCurProcState(); 3543 outInfo.importance = procStateToImportance(procState, adj, outInfo, 3544 clientTargetSdk); 3545 outInfo.importanceReasonCode = app.adjTypeCode; 3546 outInfo.processState = app.getCurProcState(); 3547 outInfo.isFocused = (app == mService.getTopAppLocked()); 3548 outInfo.lastActivityTime = app.lastActivityTime; 3549 } 3550 3551 @GuardedBy("mService") getRunningAppProcessesLocked(boolean allUsers, int userId, boolean allUids, int callingUid, int clientTargetSdk)3552 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers, 3553 int userId, boolean allUids, int callingUid, int clientTargetSdk) { 3554 // Lazy instantiation of list 3555 List<ActivityManager.RunningAppProcessInfo> runList = null; 3556 3557 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3558 ProcessRecord app = mLruProcesses.get(i); 3559 if ((!allUsers && app.userId != userId) 3560 || (!allUids && app.uid != callingUid)) { 3561 continue; 3562 } 3563 if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) { 3564 // Generate process state info for running application 3565 ActivityManager.RunningAppProcessInfo currApp = 3566 new ActivityManager.RunningAppProcessInfo(app.processName, 3567 app.pid, app.getPackageList()); 3568 fillInProcMemInfoLocked(app, currApp, clientTargetSdk); 3569 if (app.adjSource instanceof ProcessRecord) { 3570 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 3571 currApp.importanceReasonImportance = 3572 ActivityManager.RunningAppProcessInfo.procStateToImportance( 3573 app.adjSourceProcState); 3574 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) { 3575 final ActivityServiceConnectionsHolder r = 3576 (ActivityServiceConnectionsHolder) app.adjSource; 3577 final int pid = r.getActivityPid(); 3578 if (pid != -1) { 3579 currApp.importanceReasonPid = pid; 3580 } 3581 } 3582 if (app.adjTarget instanceof ComponentName) { 3583 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 3584 } 3585 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 3586 // + " lru=" + currApp.lru); 3587 if (runList == null) { 3588 runList = new ArrayList<>(); 3589 } 3590 runList.add(currApp); 3591 } 3592 } 3593 return runList; 3594 } 3595 3596 @GuardedBy("mService") getLruSizeLocked()3597 int getLruSizeLocked() { 3598 return mLruProcesses.size(); 3599 } 3600 3601 @GuardedBy("mService") dumpLruListHeaderLocked(PrintWriter pw)3602 void dumpLruListHeaderLocked(PrintWriter pw) { 3603 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 3604 pw.print(" total, non-act at "); 3605 pw.print(mLruProcesses.size() - mLruProcessActivityStart); 3606 pw.print(", non-svc at "); 3607 pw.print(mLruProcesses.size() - mLruProcessServiceStart); 3608 pw.println("):"); 3609 } 3610 3611 @GuardedBy("mService") collectProcessesLocked(int start, boolean allPkgs, String[] args)3612 ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) { 3613 ArrayList<ProcessRecord> procs; 3614 if (args != null && args.length > start 3615 && args[start].charAt(0) != '-') { 3616 procs = new ArrayList<ProcessRecord>(); 3617 int pid = -1; 3618 try { 3619 pid = Integer.parseInt(args[start]); 3620 } catch (NumberFormatException e) { 3621 } 3622 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3623 ProcessRecord proc = mLruProcesses.get(i); 3624 if (proc.pid > 0 && proc.pid == pid) { 3625 procs.add(proc); 3626 } else if (allPkgs && proc.pkgList != null 3627 && proc.pkgList.containsKey(args[start])) { 3628 procs.add(proc); 3629 } else if (proc.processName.equals(args[start])) { 3630 procs.add(proc); 3631 } 3632 } 3633 if (procs.size() <= 0) { 3634 return null; 3635 } 3636 } else { 3637 procs = new ArrayList<ProcessRecord>(mLruProcesses); 3638 } 3639 return procs; 3640 } 3641 3642 @GuardedBy("mService") updateApplicationInfoLocked(List<String> packagesToUpdate, int userId, boolean updateFrameworkRes)3643 void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId, 3644 boolean updateFrameworkRes) { 3645 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3646 final ProcessRecord app = mLruProcesses.get(i); 3647 if (app.thread == null) { 3648 continue; 3649 } 3650 3651 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3652 continue; 3653 } 3654 3655 final int packageCount = app.pkgList.size(); 3656 for (int j = 0; j < packageCount; j++) { 3657 final String packageName = app.pkgList.keyAt(j); 3658 if (!updateFrameworkRes && !packagesToUpdate.contains(packageName)) { 3659 continue; 3660 } 3661 try { 3662 final ApplicationInfo ai = AppGlobals.getPackageManager() 3663 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId); 3664 if (ai == null) { 3665 continue; 3666 } 3667 app.thread.scheduleApplicationInfoChanged(ai); 3668 if (ai.packageName.equals(app.info.packageName)) { 3669 app.info = ai; 3670 } 3671 } catch (RemoteException e) { 3672 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", 3673 packageName, app)); 3674 } 3675 } 3676 } 3677 } 3678 3679 @GuardedBy("mService") sendPackageBroadcastLocked(int cmd, String[] packages, int userId)3680 void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 3681 boolean foundProcess = false; 3682 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3683 ProcessRecord r = mLruProcesses.get(i); 3684 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 3685 try { 3686 for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) { 3687 if (packages[index].equals(r.info.packageName)) { 3688 foundProcess = true; 3689 } 3690 } 3691 r.thread.dispatchPackageBroadcast(cmd, packages); 3692 } catch (RemoteException ex) { 3693 } 3694 } 3695 } 3696 3697 if (!foundProcess) { 3698 try { 3699 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages); 3700 } catch (RemoteException ignored) { 3701 } 3702 } 3703 } 3704 3705 /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */ 3706 @GuardedBy("mService") getUidProcStateLocked(int uid)3707 int getUidProcStateLocked(int uid) { 3708 UidRecord uidRec = mActiveUids.get(uid); 3709 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState(); 3710 } 3711 3712 /** Returns the UidRecord for the given uid, if it exists. */ 3713 @GuardedBy("mService") getUidRecordLocked(int uid)3714 UidRecord getUidRecordLocked(int uid) { 3715 return mActiveUids.get(uid); 3716 } 3717 3718 /** 3719 * Call {@link ActivityManagerService#doStopUidLocked} 3720 * (which will also stop background services) for all idle UIDs. 3721 */ 3722 @GuardedBy("mService") doStopUidForIdleUidsLocked()3723 void doStopUidForIdleUidsLocked() { 3724 final int size = mActiveUids.size(); 3725 for (int i = 0; i < size; i++) { 3726 final int uid = mActiveUids.keyAt(i); 3727 if (UserHandle.isCore(uid)) { 3728 continue; 3729 } 3730 final UidRecord uidRec = mActiveUids.valueAt(i); 3731 if (!uidRec.idle) { 3732 continue; 3733 } 3734 mService.doStopUidLocked(uidRec.uid, uidRec); 3735 } 3736 } 3737 3738 /** 3739 * Checks if the uid is coming from background to foreground or vice versa and returns 3740 * appropriate block state based on this. 3741 * 3742 * @return blockState based on whether the uid is coming from background to foreground or 3743 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or 3744 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise 3745 * {@link #NETWORK_STATE_NO_CHANGE}. 3746 */ 3747 @VisibleForTesting getBlockStateForUid(UidRecord uidRec)3748 int getBlockStateForUid(UidRecord uidRec) { 3749 // Denotes whether uid's process state is currently allowed network access. 3750 final boolean isAllowed = 3751 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState()) 3752 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState()); 3753 // Denotes whether uid's process state was previously allowed network access. 3754 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState) 3755 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState); 3756 3757 // When the uid is coming to foreground, AMS should inform the app thread that it should 3758 // block for the network rules to get updated before launching an activity. 3759 if (!wasAllowed && isAllowed) { 3760 return NETWORK_STATE_BLOCK; 3761 } 3762 // When the uid is going to background, AMS should inform the app thread that if an 3763 // activity launch is blocked for the network rules to get updated, it should be unblocked. 3764 if (wasAllowed && !isAllowed) { 3765 return NETWORK_STATE_UNBLOCK; 3766 } 3767 return NETWORK_STATE_NO_CHANGE; 3768 } 3769 3770 /** 3771 * Checks if any uid is coming from background to foreground or vice versa and if so, increments 3772 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter 3773 * {@link ProcessList#mProcStateSeqCounter} and notifies the app if it needs to block. 3774 */ 3775 @VisibleForTesting 3776 @GuardedBy("mService") incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids)3777 void incrementProcStateSeqAndNotifyAppsLocked(ActiveUids activeUids) { 3778 if (mService.mWaitForNetworkTimeoutMs <= 0) { 3779 return; 3780 } 3781 // Used for identifying which uids need to block for network. 3782 ArrayList<Integer> blockingUids = null; 3783 for (int i = activeUids.size() - 1; i >= 0; --i) { 3784 final UidRecord uidRec = activeUids.valueAt(i); 3785 // If the network is not restricted for uid, then nothing to do here. 3786 if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.uid)) { 3787 continue; 3788 } 3789 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) { 3790 continue; 3791 } 3792 // If process state is not changed, then there's nothing to do. 3793 if (uidRec.setProcState == uidRec.getCurProcState()) { 3794 continue; 3795 } 3796 final int blockState = getBlockStateForUid(uidRec); 3797 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as 3798 // there's nothing the app needs to do in this scenario. 3799 if (blockState == NETWORK_STATE_NO_CHANGE) { 3800 continue; 3801 } 3802 synchronized (uidRec.networkStateLock) { 3803 uidRec.curProcStateSeq = ++mProcStateSeqCounter; // TODO: use method 3804 if (blockState == NETWORK_STATE_BLOCK) { 3805 if (blockingUids == null) { 3806 blockingUids = new ArrayList<>(); 3807 } 3808 blockingUids.add(uidRec.uid); 3809 } else { 3810 if (DEBUG_NETWORK) { 3811 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking" 3812 + " threads for uid: " + uidRec); 3813 } 3814 if (uidRec.waitingForNetwork) { 3815 uidRec.networkStateLock.notifyAll(); 3816 } 3817 } 3818 } 3819 } 3820 3821 // There are no uids that need to block, so nothing more to do. 3822 if (blockingUids == null) { 3823 return; 3824 } 3825 3826 for (int i = mLruProcesses.size() - 1; i >= 0; --i) { 3827 final ProcessRecord app = mLruProcesses.get(i); 3828 if (!blockingUids.contains(app.uid)) { 3829 continue; 3830 } 3831 if (!app.killedByAm && app.thread != null) { 3832 final UidRecord uidRec = getUidRecordLocked(app.uid); 3833 try { 3834 if (DEBUG_NETWORK) { 3835 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: " 3836 + uidRec); 3837 } 3838 if (uidRec != null) { 3839 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq); 3840 } 3841 } catch (RemoteException ignored) { 3842 } 3843 } 3844 } 3845 } 3846 3847 /** 3848 * Create a server socket in system_server, zygote will connect to it 3849 * in order to send unsolicited messages to system_server. 3850 */ createSystemServerSocketForZygote()3851 private LocalSocket createSystemServerSocketForZygote() { 3852 // The file system entity for this socket is created with 0666 perms, owned 3853 // by system:system. selinux restricts things so that only zygotes can 3854 // access it. 3855 final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH); 3856 if (socketFile.exists()) { 3857 socketFile.delete(); 3858 } 3859 3860 LocalSocket serverSocket = null; 3861 try { 3862 serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM); 3863 serverSocket.bind(new LocalSocketAddress( 3864 UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM)); 3865 Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666); 3866 } catch (Exception e) { 3867 if (serverSocket != null) { 3868 try { 3869 serverSocket.close(); 3870 } catch (IOException ex) { 3871 } 3872 serverSocket = null; 3873 } 3874 } 3875 return serverSocket; 3876 } 3877 3878 /** 3879 * Handle the unsolicited message from zygote. 3880 */ handleZygoteMessages(FileDescriptor fd, int events)3881 private int handleZygoteMessages(FileDescriptor fd, int events) { 3882 final int eventFd = fd.getInt$(); 3883 if ((events & EVENT_INPUT) != 0) { 3884 // An incoming message from zygote 3885 try { 3886 final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0, 3887 mZygoteUnsolicitedMessage.length); 3888 if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld( 3889 mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) { 3890 mAppExitInfoTracker.handleZygoteSigChld( 3891 mZygoteSigChldMessage[0] /* pid */, 3892 mZygoteSigChldMessage[1] /* uid */, 3893 mZygoteSigChldMessage[2] /* status */); 3894 } 3895 } catch (Exception e) { 3896 Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e); 3897 } 3898 } 3899 return EVENT_INPUT; 3900 } 3901 3902 /** 3903 * Called by ActivityManagerService when a process died. 3904 */ 3905 @GuardedBy("mService") noteProcessDiedLocked(final ProcessRecord app)3906 void noteProcessDiedLocked(final ProcessRecord app) { 3907 if (DEBUG_PROCESSES) { 3908 Slog.i(TAG, "note: " + app + " died, saving the exit info"); 3909 } 3910 3911 Watchdog.getInstance().processDied(app.processName, app.pid); 3912 mAppExitInfoTracker.scheduleNoteProcessDied(app); 3913 } 3914 3915 /** 3916 * Called by ActivityManagerService when it decides to kill an application process. 3917 */ noteAppKill(final ProcessRecord app, final @Reason int reason, final @SubReason int subReason, final String msg)3918 void noteAppKill(final ProcessRecord app, final @Reason int reason, 3919 final @SubReason int subReason, final String msg) { 3920 if (DEBUG_PROCESSES) { 3921 Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason 3922 + ", sub-reason: " + subReason + ", message: " + msg); 3923 } 3924 mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg); 3925 } 3926 noteAppKill(final int pid, final int uid, final @Reason int reason, final @SubReason int subReason, final String msg)3927 void noteAppKill(final int pid, final int uid, final @Reason int reason, 3928 final @SubReason int subReason, final String msg) { 3929 if (DEBUG_PROCESSES) { 3930 Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason 3931 + ", sub-reason: " + subReason + ", message: " + msg); 3932 } 3933 3934 mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg); 3935 } 3936 3937 /** 3938 * Schedule to kill the given pids when the device is idle 3939 */ killProcessesWhenImperceptible(int[] pids, String reason, int requester)3940 void killProcessesWhenImperceptible(int[] pids, String reason, int requester) { 3941 if (ArrayUtils.isEmpty(pids)) { 3942 return; 3943 } 3944 3945 synchronized (mService) { 3946 ProcessRecord app; 3947 for (int i = 0; i < pids.length; i++) { 3948 synchronized (mService.mPidsSelfLocked) { 3949 app = mService.mPidsSelfLocked.get(pids[i]); 3950 } 3951 if (app != null) { 3952 mImperceptibleKillRunner.enqueueLocked(app, reason, requester); 3953 } 3954 } 3955 } 3956 } 3957 3958 private final class ImperceptibleKillRunner extends IUidObserver.Stub { 3959 private static final String EXTRA_PID = "pid"; 3960 private static final String EXTRA_UID = "uid"; 3961 private static final String EXTRA_TIMESTAMP = "timestamp"; 3962 private static final String EXTRA_REASON = "reason"; 3963 private static final String EXTRA_REQUESTER = "requester"; 3964 3965 private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill"; 3966 3967 // uid -> killing information mapping 3968 private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>(); 3969 3970 // The last time the various processes have been killed by us. 3971 private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>(); 3972 3973 // Device idle or not. 3974 private volatile boolean mIdle; 3975 private boolean mUidObserverEnabled; 3976 private Handler mHandler; 3977 private IdlenessReceiver mReceiver; 3978 3979 private final class H extends Handler { 3980 static final int MSG_DEVICE_IDLE = 0; 3981 static final int MSG_UID_GONE = 1; 3982 static final int MSG_UID_STATE_CHANGED = 2; 3983 H(Looper looper)3984 H(Looper looper) { 3985 super(looper); 3986 } 3987 3988 @Override handleMessage(Message msg)3989 public void handleMessage(Message msg) { 3990 switch (msg.what) { 3991 case MSG_DEVICE_IDLE: 3992 handleDeviceIdle(); 3993 break; 3994 case MSG_UID_GONE: 3995 handleUidGone(msg.arg1 /* uid */); 3996 break; 3997 case MSG_UID_STATE_CHANGED: 3998 handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */); 3999 break; 4000 } 4001 } 4002 } 4003 4004 private final class IdlenessReceiver extends BroadcastReceiver { 4005 @Override onReceive(Context context, Intent intent)4006 public void onReceive(Context context, Intent intent) { 4007 final PowerManager pm = mService.mContext.getSystemService(PowerManager.class); 4008 switch (intent.getAction()) { 4009 case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED: 4010 notifyDeviceIdleness(pm.isLightDeviceIdleMode()); 4011 break; 4012 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED: 4013 notifyDeviceIdleness(pm.isDeviceIdleMode()); 4014 break; 4015 } 4016 } 4017 } 4018 ImperceptibleKillRunner(Looper looper)4019 ImperceptibleKillRunner(Looper looper) { 4020 mHandler = new H(looper); 4021 } 4022 4023 @GuardedBy("mService") enqueueLocked(ProcessRecord app, String reason, int requester)4024 boolean enqueueLocked(ProcessRecord app, String reason, int requester) { 4025 // Throttle the killing request for potential bad app to avoid cpu thrashing 4026 Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid); 4027 if (last != null && SystemClock.uptimeMillis() < last + MIN_CRASH_INTERVAL) { 4028 return false; 4029 } 4030 4031 final Bundle bundle = new Bundle(); 4032 bundle.putInt(EXTRA_PID, app.pid); 4033 bundle.putInt(EXTRA_UID, app.uid); 4034 // Since the pid could be reused, let's get the actual start time of each process 4035 bundle.putLong(EXTRA_TIMESTAMP, app.startTime); 4036 bundle.putString(EXTRA_REASON, reason); 4037 bundle.putInt(EXTRA_REQUESTER, requester); 4038 List<Bundle> list = mWorkItems.get(app.uid); 4039 if (list == null) { 4040 list = new ArrayList<Bundle>(); 4041 mWorkItems.put(app.uid, list); 4042 } 4043 list.add(bundle); 4044 if (mReceiver == null) { 4045 mReceiver = new IdlenessReceiver(); 4046 IntentFilter filter = new IntentFilter( 4047 PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); 4048 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 4049 mService.mContext.registerReceiver(mReceiver, filter); 4050 } 4051 return true; 4052 } 4053 notifyDeviceIdleness(boolean idle)4054 void notifyDeviceIdleness(boolean idle) { 4055 // No lock is held regarding mIdle, this function is the only updater and caller 4056 // won't re-entry. 4057 boolean diff = mIdle != idle; 4058 mIdle = idle; 4059 if (diff && idle) { 4060 synchronized (this) { 4061 if (mWorkItems.size() > 0) { 4062 mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE); 4063 } 4064 } 4065 } 4066 } 4067 handleDeviceIdle()4068 private void handleDeviceIdle() { 4069 final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class); 4070 final boolean logToDropbox = dbox != null 4071 && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL); 4072 4073 synchronized (mService) { 4074 final int size = mWorkItems.size(); 4075 for (int i = size - 1; mIdle && i >= 0; i--) { 4076 List<Bundle> list = mWorkItems.valueAt(i); 4077 final int len = list.size(); 4078 for (int j = len - 1; mIdle && j >= 0; j--) { 4079 Bundle bundle = list.get(j); 4080 if (killProcessLocked( 4081 bundle.getInt(EXTRA_PID), 4082 bundle.getInt(EXTRA_UID), 4083 bundle.getLong(EXTRA_TIMESTAMP), 4084 bundle.getString(EXTRA_REASON), 4085 bundle.getInt(EXTRA_REQUESTER), 4086 dbox, logToDropbox)) { 4087 list.remove(j); 4088 } 4089 } 4090 if (list.size() == 0) { 4091 mWorkItems.removeAt(i); 4092 } 4093 } 4094 registerUidObserverIfNecessaryLocked(); 4095 } 4096 } 4097 4098 @GuardedBy("mService") registerUidObserverIfNecessaryLocked()4099 private void registerUidObserverIfNecessaryLocked() { 4100 // If there are still works remaining, register UID observer 4101 if (!mUidObserverEnabled && mWorkItems.size() > 0) { 4102 mUidObserverEnabled = true; 4103 mService.registerUidObserver(this, 4104 ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE, 4105 ActivityManager.PROCESS_STATE_UNKNOWN, "android"); 4106 } else if (mUidObserverEnabled && mWorkItems.size() == 0) { 4107 mUidObserverEnabled = false; 4108 mService.unregisterUidObserver(this); 4109 } 4110 } 4111 4112 /** 4113 * Kill the given processes, if they are not exempted. 4114 * 4115 * @return True if the process is killed, or it's gone already, or we are not allowed to 4116 * kill it (one of the packages in this process is being exempted). 4117 */ 4118 @GuardedBy("mService") killProcessLocked(final int pid, final int uid, final long timestamp, final String reason, final int requester, final DropBoxManager dbox, final boolean logToDropbox)4119 private boolean killProcessLocked(final int pid, final int uid, final long timestamp, 4120 final String reason, final int requester, final DropBoxManager dbox, 4121 final boolean logToDropbox) { 4122 ProcessRecord app = null; 4123 synchronized (mService.mPidsSelfLocked) { 4124 app = mService.mPidsSelfLocked.get(pid); 4125 } 4126 4127 if (app == null || app.pid != pid || app.uid != uid || app.startTime != timestamp) { 4128 // This process record has been reused for another process, meaning the old process 4129 // has been gone. 4130 return true; 4131 } 4132 4133 final int pkgSize = app.pkgList.size(); 4134 for (int ip = 0; ip < pkgSize; ip++) { 4135 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains( 4136 app.pkgList.keyAt(ip))) { 4137 // One of the packages in this process is exempted 4138 return true; 4139 } 4140 } 4141 4142 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains( 4143 app.getReportedProcState())) { 4144 // We need to reschedule it. 4145 return false; 4146 } 4147 4148 app.kill(reason, ApplicationExitInfo.REASON_OTHER, 4149 ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true); 4150 4151 if (!app.isolated) { 4152 mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis()); 4153 } 4154 4155 if (logToDropbox) { 4156 final long now = SystemClock.elapsedRealtime(); 4157 final StringBuilder sb = new StringBuilder(); 4158 mService.appendDropBoxProcessHeaders(app, app.processName, sb); 4159 sb.append("Reason: " + reason).append("\n"); 4160 sb.append("Requester UID: " + requester).append("\n"); 4161 dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString()); 4162 } 4163 return true; 4164 } 4165 handleUidStateChanged(int uid, int procState)4166 private void handleUidStateChanged(int uid, int procState) { 4167 final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class); 4168 final boolean logToDropbox = dbox != null 4169 && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL); 4170 synchronized (mService) { 4171 if (mIdle && !mService.mConstants 4172 .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) { 4173 List<Bundle> list = mWorkItems.get(uid); 4174 if (list != null) { 4175 final int len = list.size(); 4176 for (int j = len - 1; mIdle && j >= 0; j--) { 4177 Bundle bundle = list.get(j); 4178 if (killProcessLocked( 4179 bundle.getInt(EXTRA_PID), 4180 bundle.getInt(EXTRA_UID), 4181 bundle.getLong(EXTRA_TIMESTAMP), 4182 bundle.getString(EXTRA_REASON), 4183 bundle.getInt(EXTRA_REQUESTER), 4184 dbox, logToDropbox)) { 4185 list.remove(j); 4186 } 4187 } 4188 if (list.size() == 0) { 4189 mWorkItems.remove(uid); 4190 } 4191 registerUidObserverIfNecessaryLocked(); 4192 } 4193 } 4194 } 4195 } 4196 handleUidGone(int uid)4197 private void handleUidGone(int uid) { 4198 synchronized (mService) { 4199 mWorkItems.remove(uid); 4200 registerUidObserverIfNecessaryLocked(); 4201 } 4202 } 4203 4204 @Override onUidGone(int uid, boolean disabled)4205 public void onUidGone(int uid, boolean disabled) { 4206 mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget(); 4207 } 4208 4209 @Override onUidActive(int uid)4210 public void onUidActive(int uid) { 4211 } 4212 4213 @Override onUidIdle(int uid, boolean disabled)4214 public void onUidIdle(int uid, boolean disabled) { 4215 } 4216 4217 @Override onUidStateChanged(int uid, int procState, long procStateSeq, int capability)4218 public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { 4219 mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); 4220 } 4221 4222 @Override onUidCachedChanged(int uid, boolean cached)4223 public void onUidCachedChanged(int uid, boolean cached) { 4224 } 4225 }; 4226 } 4227