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