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