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_JAVA_DEBUGGABLE; 1831 // Also turn on CheckJNI for debuggable apps. It's quite 1832 // awkward to turn on otherwise. 1833 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1834 1835 // Check if the developer does not want ART verification 1836 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(), 1837 android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) { 1838 runtimeFlags |= Zygote.DISABLE_VERIFIER; 1839 Slog.w(TAG_PROCESSES, app + ": ART verification disabled"); 1840 } 1841 } 1842 // Run the app in safe mode if its manifest requests so or the 1843 // system is booted in safe mode. 1844 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) { 1845 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1846 } 1847 if (isProfileableByShell) { 1848 runtimeFlags |= Zygote.PROFILE_FROM_SHELL; 1849 } 1850 if (isProfileable) { 1851 runtimeFlags |= Zygote.PROFILEABLE; 1852 } 1853 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1854 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1855 } 1856 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info"); 1857 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) { 1858 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; 1859 } 1860 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo"); 1861 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) { 1862 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO; 1863 } 1864 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 1865 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 1866 } 1867 if ("1".equals(SystemProperties.get("debug.assert"))) { 1868 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1869 } 1870 if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) { 1871 runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER; 1872 } 1873 if (mService.mNativeDebuggingApp != null 1874 && mService.mNativeDebuggingApp.equals(app.processName)) { 1875 // Enable all debug flags required by the native debugger. 1876 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything 1877 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info 1878 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations 1879 mService.mNativeDebuggingApp = null; 1880 } 1881 1882 if (app.info.isEmbeddedDexUsed()) { 1883 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; 1884 } 1885 1886 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) { 1887 app.info.maybeUpdateHiddenApiEnforcementPolicy( 1888 mService.mHiddenApiBlacklist.getPolicy()); 1889 @ApplicationInfo.HiddenApiEnforcementPolicy int policy = 1890 app.info.getHiddenApiEnforcementPolicy(); 1891 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT); 1892 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) { 1893 throw new IllegalStateException("Invalid API policy: " + policy); 1894 } 1895 runtimeFlags |= policyBits; 1896 1897 if (disableTestApiChecks) { 1898 runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY; 1899 } 1900 } 1901 1902 String useAppImageCache = SystemProperties.get( 1903 PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, ""); 1904 // Property defaults to true currently. 1905 if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) { 1906 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE; 1907 } 1908 1909 String invokeWith = null; 1910 if (debuggableFlag) { 1911 // Debuggable apps may include a wrapper script with their library directory. 1912 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; 1913 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 1914 try { 1915 if (new File(wrapperFileName).exists()) { 1916 invokeWith = "/system/bin/logwrapper " + wrapperFileName; 1917 } 1918 } finally { 1919 StrictMode.setThreadPolicy(oldPolicy); 1920 } 1921 } 1922 1923 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 1924 if (requiredAbi == null) { 1925 requiredAbi = Build.SUPPORTED_ABIS[0]; 1926 } 1927 1928 String instructionSet = null; 1929 if (app.info.primaryCpuAbi != null) { 1930 // If ABI override is specified, use the isa derived from the value of ABI override. 1931 // Otherwise, use the isa derived from primary ABI 1932 instructionSet = VMRuntime.getInstructionSet(requiredAbi); 1933 } 1934 1935 app.setGids(gids); 1936 app.setRequiredAbi(requiredAbi); 1937 app.setInstructionSet(instructionSet); 1938 1939 // If this was an external service, the package name and uid in the passed in 1940 // ApplicationInfo have been changed to match those of the calling package; 1941 // that will incorrectly apply compat feature overrides for the calling package instead 1942 // of the defining one. 1943 ApplicationInfo definingAppInfo; 1944 if (hostingRecord.getDefiningPackageName() != null) { 1945 definingAppInfo = new ApplicationInfo(app.info); 1946 definingAppInfo.packageName = hostingRecord.getDefiningPackageName(); 1947 definingAppInfo.uid = uid; 1948 } else { 1949 definingAppInfo = app.info; 1950 } 1951 1952 runtimeFlags |= Zygote.getMemorySafetyRuntimeFlags( 1953 definingAppInfo, app.processInfo, instructionSet, mPlatformCompat); 1954 1955 // the per-user SELinux context must be set 1956 if (TextUtils.isEmpty(app.info.seInfoUser)) { 1957 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined", 1958 new IllegalStateException("SELinux tag not defined for " 1959 + app.info.packageName + " (uid " + app.uid + ")")); 1960 } 1961 1962 String seInfo = updateSeInfo(app); 1963 1964 // Start the process. It will either succeed and return a result containing 1965 // the PID of the new process, or else throw a RuntimeException. 1966 final String entryPoint = "android.app.ActivityThread"; 1967 1968 return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, 1969 runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi, 1970 instructionSet, invokeWith, startUptime, startElapsedTime); 1971 } catch (RuntimeException e) { 1972 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e); 1973 1974 // Something went very wrong while trying to start this process; one 1975 // common case is when the package is frozen due to an active 1976 // upgrade. To recover, clean up any active bookkeeping related to 1977 // starting this process. (We already invoked this method once when 1978 // the package was initially frozen through KILL_APPLICATION_MSG, so 1979 // it doesn't hurt to use it again.) 1980 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), 1981 false, false, true, false, false, app.userId, "start failure"); 1982 return false; 1983 } 1984 } 1985 1986 @VisibleForTesting 1987 @GuardedBy("mService") 1988 String updateSeInfo(ProcessRecord app) { 1989 String extraInfo = ""; 1990 // By the time the first the SDK sandbox process is started, device config service 1991 // should be available. 1992 if (app.isSdkSandbox 1993 && getProcessListSettingsListener().applySdkSandboxRestrictionsNext()) { 1994 extraInfo = APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS; 1995 } 1996 1997 return app.info.seInfo 1998 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser) + extraInfo; 1999 } 2000 2001 2002 @GuardedBy("mService") 2003 boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app, 2004 int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal, 2005 String seInfo, String requiredAbi, String instructionSet, String invokeWith, 2006 long startUptime, long startElapsedTime) { 2007 app.setPendingStart(true); 2008 app.setRemoved(false); 2009 synchronized (mProcLock) { 2010 app.setKilledByAm(false); 2011 app.setKilled(false); 2012 } 2013 if (app.getStartSeq() != 0) { 2014 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName 2015 + " with non-zero startSeq:" + app.getStartSeq()); 2016 } 2017 if (app.getPid() != 0) { 2018 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName 2019 + " with non-zero pid:" + app.getPid()); 2020 } 2021 app.setDisabledCompatChanges(null); 2022 if (mPlatformCompat != null) { 2023 app.setDisabledCompatChanges(mPlatformCompat.getDisabledChanges(app.info)); 2024 } 2025 final long startSeq = ++mProcStartSeqCounter; 2026 app.setStartSeq(startSeq); 2027 app.setStartParams(uid, hostingRecord, seInfo, startUptime, startElapsedTime); 2028 app.setUsingWrapper(invokeWith != null 2029 || Zygote.getWrapProperty(app.processName) != null); 2030 mPendingStarts.put(startSeq, app); 2031 2032 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { 2033 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES, 2034 "Posting procStart msg for " + app.toShortString()); 2035 mService.mProcStartHandler.post(() -> handleProcessStart( 2036 app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal, 2037 requiredAbi, instructionSet, invokeWith, startSeq)); 2038 return true; 2039 } else { 2040 try { 2041 final Process.ProcessStartResult startResult = startProcess(hostingRecord, 2042 entryPoint, app, 2043 uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, 2044 requiredAbi, instructionSet, invokeWith, startUptime); 2045 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, 2046 startSeq, false); 2047 } catch (RuntimeException e) { 2048 Slog.e(ActivityManagerService.TAG, "Failure starting process " 2049 + app.processName, e); 2050 app.setPendingStart(false); 2051 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), 2052 false, false, true, false, false, app.userId, "start failure"); 2053 } 2054 return app.getPid() > 0; 2055 } 2056 } 2057 2058 /** 2059 * Main handler routine to start the given process from the ProcStartHandler. 2060 * 2061 * <p>Note: this function doesn't hold the global AM lock intentionally.</p> 2062 */ 2063 private void handleProcessStart(final ProcessRecord app, final String entryPoint, 2064 final int[] gids, final int runtimeFlags, int zygotePolicyFlags, 2065 final int mountExternal, final String requiredAbi, final String instructionSet, 2066 final String invokeWith, final long startSeq) { 2067 final Runnable startRunnable = () -> { 2068 try { 2069 final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(), 2070 entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags, 2071 mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith, 2072 app.getStartTime()); 2073 2074 synchronized (mService) { 2075 handleProcessStartedLocked(app, startResult, startSeq); 2076 } 2077 } catch (RuntimeException e) { 2078 synchronized (mService) { 2079 Slog.e(ActivityManagerService.TAG, "Failure starting process " 2080 + app.processName, e); 2081 mPendingStarts.remove(startSeq); 2082 app.setPendingStart(false); 2083 mService.forceStopPackageLocked(app.info.packageName, 2084 UserHandle.getAppId(app.uid), 2085 false, false, true, false, false, app.userId, "start failure"); 2086 } 2087 } 2088 }; 2089 // Use local reference since we are not using locks here 2090 final ProcessRecord predecessor = app.mPredecessor; 2091 if (predecessor != null && predecessor.getDyingPid() > 0) { 2092 handleProcessStartWithPredecessor(predecessor, startRunnable); 2093 } else { 2094 // Kick off the process start for real. 2095 startRunnable.run(); 2096 } 2097 } 2098 2099 /** 2100 * Handle the case where the given process is killed but still not gone, but we'd need to start 2101 * the new instance of it. 2102 */ 2103 private void handleProcessStartWithPredecessor(final ProcessRecord predecessor, 2104 final Runnable successorStartRunnable) { 2105 // If there is a preceding instance of the process, wait for its death with a timeout. 2106 if (predecessor.mSuccessorStartRunnable != null) { 2107 // It's been watched already, this shouldn't happen. 2108 Slog.wtf(TAG, "We've been watching for the death of " + predecessor); 2109 return; 2110 } 2111 predecessor.mSuccessorStartRunnable = successorStartRunnable; 2112 mService.mProcStartHandler.sendMessageDelayed(mService.mProcStartHandler.obtainMessage( 2113 ProcStartHandler.MSG_PROCESS_KILL_TIMEOUT, predecessor), 2114 mService.mConstants.mProcessKillTimeoutMs); 2115 } 2116 2117 static final class ProcStartHandler extends Handler { 2118 static final int MSG_PROCESS_DIED = 1; 2119 static final int MSG_PROCESS_KILL_TIMEOUT = 2; 2120 2121 private final ActivityManagerService mService; 2122 2123 ProcStartHandler(ActivityManagerService service, Looper looper) { 2124 super(looper); 2125 mService = service; 2126 } 2127 2128 @Override 2129 public void handleMessage(Message msg) { 2130 switch (msg.what) { 2131 case MSG_PROCESS_DIED: 2132 mService.mProcessList.handlePredecessorProcDied((ProcessRecord) msg.obj); 2133 break; 2134 case MSG_PROCESS_KILL_TIMEOUT: 2135 synchronized (mService) { 2136 mService.handleProcessStartOrKillTimeoutLocked((ProcessRecord) msg.obj, 2137 /* isKillTimeout */ true); 2138 } 2139 break; 2140 } 2141 } 2142 } 2143 2144 /** 2145 * Called when the dying process we're waiting for is really gone. 2146 */ 2147 private void handlePredecessorProcDied(ProcessRecord app) { 2148 if (DEBUG_PROCESSES) { 2149 Slog.i(TAG, app.toString() + " is really gone now"); 2150 } 2151 2152 // Now kick off the subsequent process start if there is any. 2153 final Runnable start = app.mSuccessorStartRunnable; 2154 if (start != null) { 2155 app.mSuccessorStartRunnable = null; 2156 start.run(); 2157 } 2158 } 2159 2160 @GuardedBy("mService") 2161 public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) { 2162 final ApplicationInfo appInfo = appZygote.getAppInfo(); 2163 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); 2164 if (zygoteProcesses != null && (force || zygoteProcesses.size() == 0)) { 2165 // Only remove if no longer in use now, or forced kill 2166 mAppZygotes.remove(appInfo.processName, appInfo.uid); 2167 mAppZygoteProcesses.remove(appZygote); 2168 mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo); 2169 appZygote.stopZygote(); 2170 } 2171 } 2172 2173 @GuardedBy("mService") 2174 private void removeProcessFromAppZygoteLocked(final ProcessRecord app) { 2175 // Free the isolated uid for this process 2176 final IsolatedUidRange appUidRange = 2177 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName, 2178 app.getHostingRecord().getDefiningUid()); 2179 if (appUidRange != null) { 2180 appUidRange.freeIsolatedUidLocked(app.uid); 2181 } 2182 2183 final AppZygote appZygote = mAppZygotes.get(app.info.processName, 2184 app.getHostingRecord().getDefiningUid()); 2185 if (appZygote != null) { 2186 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); 2187 zygoteProcesses.remove(app); 2188 if (zygoteProcesses.size() == 0) { 2189 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG); 2190 if (app.isRemoved()) { 2191 // If we stopped this process because the package hosting it was removed, 2192 // there's no point in delaying the app zygote kill. 2193 killAppZygoteIfNeededLocked(appZygote, false /* force */); 2194 } else { 2195 Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG); 2196 msg.obj = appZygote; 2197 mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS); 2198 } 2199 } 2200 } 2201 } 2202 2203 private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) { 2204 synchronized (mService) { 2205 // The UID for the app zygote should be the UID of the application hosting 2206 // the service. 2207 final int uid = app.getHostingRecord().getDefiningUid(); 2208 AppZygote appZygote = mAppZygotes.get(app.info.processName, uid); 2209 final ArrayList<ProcessRecord> zygoteProcessList; 2210 if (appZygote == null) { 2211 if (DEBUG_PROCESSES) { 2212 Slog.d(TAG_PROCESSES, "Creating new app zygote."); 2213 } 2214 final IsolatedUidRange uidRange = 2215 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked( 2216 app.info.processName, app.getHostingRecord().getDefiningUid()); 2217 final int userId = UserHandle.getUserId(uid); 2218 // Create the app-zygote and provide it with the UID-range it's allowed 2219 // to setresuid/setresgid to. 2220 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid); 2221 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid); 2222 ApplicationInfo appInfo = new ApplicationInfo(app.info); 2223 // If this was an external service, the package name and uid in the passed in 2224 // ApplicationInfo have been changed to match those of the calling package; 2225 // that is not what we want for the AppZygote though, which needs to have the 2226 // packageName and uid of the defining application. This is because the 2227 // preloading only makes sense in the context of the defining application, 2228 // not the calling one. 2229 appInfo.packageName = app.getHostingRecord().getDefiningPackageName(); 2230 appInfo.uid = uid; 2231 appZygote = new AppZygote(appInfo, app.processInfo, uid, firstUid, lastUid); 2232 mAppZygotes.put(app.info.processName, uid, appZygote); 2233 zygoteProcessList = new ArrayList<ProcessRecord>(); 2234 mAppZygoteProcesses.put(appZygote, zygoteProcessList); 2235 } else { 2236 if (DEBUG_PROCESSES) { 2237 Slog.d(TAG_PROCESSES, "Reusing existing app zygote."); 2238 } 2239 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote); 2240 zygoteProcessList = mAppZygoteProcesses.get(appZygote); 2241 } 2242 // Note that we already add the app to mAppZygoteProcesses here; 2243 // this is so that another thread can't come in and kill the zygote 2244 // before we've even tried to start the process. If the process launch 2245 // goes wrong, we'll clean this up in removeProcessNameLocked() 2246 zygoteProcessList.add(app); 2247 2248 return appZygote; 2249 } 2250 } 2251 2252 private Map<String, Pair<String, Long>> getPackageAppDataInfoMap(PackageManagerInternal pmInt, 2253 String[] packages, int uid) { 2254 Map<String, Pair<String, Long>> result = new ArrayMap<>(packages.length); 2255 int userId = UserHandle.getUserId(uid); 2256 for (String packageName : packages) { 2257 final PackageStateInternal packageState = pmInt.getPackageStateInternal(packageName); 2258 if (packageState == null) { 2259 Slog.w(TAG, "Unknown package:" + packageName); 2260 continue; 2261 } 2262 String volumeUuid = packageState.getVolumeUuid(); 2263 long inode = packageState.getUserStateOrDefault(userId).getCeDataInode(); 2264 if (inode == 0) { 2265 Slog.w(TAG, packageName + " inode == 0 (b/152760674)"); 2266 return null; 2267 } 2268 result.put(packageName, Pair.create(volumeUuid, inode)); 2269 } 2270 2271 return result; 2272 } 2273 2274 private boolean needsStorageDataIsolation(StorageManagerInternal storageManagerInternal, 2275 ProcessRecord app) { 2276 final int mountMode = app.getMountMode(); 2277 return mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid) 2278 && !storageManagerInternal.isExternalStorageService(app.uid) 2279 // Special mounting mode doesn't need to have data isolation as they won't 2280 // access /mnt/user anyway. 2281 && mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE 2282 && mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH 2283 && mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER 2284 && mountMode != Zygote.MOUNT_EXTERNAL_NONE; 2285 } 2286 2287 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint, 2288 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, 2289 int mountExternal, String seInfo, String requiredAbi, String instructionSet, 2290 String invokeWith, long startTime) { 2291 try { 2292 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + 2293 app.processName); 2294 checkSlow(startTime, "startProcess: asking zygote to start proc"); 2295 final boolean isTopApp = hostingRecord.isTopApp(); 2296 if (isTopApp) { 2297 // Use has-foreground-activities as a temporary hint so the current scheduling 2298 // group won't be lost when the process is attaching. The actual state will be 2299 // refreshed when computing oom-adj. 2300 app.mState.setHasForegroundActivities(true); 2301 } 2302 2303 Map<String, Pair<String, Long>> pkgDataInfoMap; 2304 Map<String, Pair<String, Long>> allowlistedAppDataInfoMap; 2305 boolean bindMountAppStorageDirs = false; 2306 boolean bindMountAppsData = mAppDataIsolationEnabled 2307 && (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid) 2308 || app.isSdkSandbox) 2309 && mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info); 2310 2311 // Get all packages belongs to the same shared uid. sharedPackages is empty array 2312 // if it doesn't have shared uid. 2313 final PackageManagerInternal pmInt = mService.getPackageManagerInternal(); 2314 2315 // In the case of sdk sandbox, the pkgDataInfoMap of only the client app associated with 2316 // the sandbox is required to handle app visibility restrictions for the sandbox. 2317 final String[] targetPackagesList; 2318 if (app.isSdkSandbox) { 2319 targetPackagesList = new String[]{app.sdkSandboxClientAppPackage}; 2320 } else { 2321 final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage( 2322 app.info.packageName, app.userId); 2323 targetPackagesList = sharedPackages.length == 0 2324 ? new String[]{app.info.packageName} : sharedPackages; 2325 } 2326 2327 final boolean hasAppStorage = hasAppStorage(pmInt, app.info.packageName); 2328 2329 pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, targetPackagesList, uid); 2330 if (pkgDataInfoMap == null) { 2331 // TODO(b/152760674): Handle inode == 0 case properly, now we just give it a 2332 // tmp free pass. 2333 bindMountAppsData = false; 2334 } 2335 2336 // Remove all packages in pkgDataInfoMap from mAppDataIsolationAllowlistedApps, so 2337 // it won't be mounted twice. 2338 final Set<String> allowlistedApps = new ArraySet<>(mAppDataIsolationAllowlistedApps); 2339 for (String pkg : targetPackagesList) { 2340 allowlistedApps.remove(pkg); 2341 } 2342 2343 allowlistedAppDataInfoMap = getPackageAppDataInfoMap(pmInt, 2344 allowlistedApps.toArray(new String[0]), uid); 2345 if (allowlistedAppDataInfoMap == null) { 2346 // TODO(b/152760674): Handle inode == 0 case properly, now we just give it a 2347 // tmp free pass. 2348 bindMountAppsData = false; 2349 } 2350 2351 if (!hasAppStorage && !app.isSdkSandbox) { 2352 bindMountAppsData = false; 2353 pkgDataInfoMap = null; 2354 allowlistedAppDataInfoMap = null; 2355 } 2356 2357 int userId = UserHandle.getUserId(uid); 2358 StorageManagerInternal storageManagerInternal = LocalServices.getService( 2359 StorageManagerInternal.class); 2360 if (needsStorageDataIsolation(storageManagerInternal, app)) { 2361 // We will run prepareStorageDirs() after we trigger zygote fork, so it won't 2362 // slow down app starting speed as those dirs might not be cached. 2363 if (pkgDataInfoMap != null && storageManagerInternal.isFuseMounted(userId)) { 2364 bindMountAppStorageDirs = true; 2365 } else { 2366 // Fuse is not mounted or inode == 0, 2367 // so we won't mount it in zygote, but resume the mount after unlocking device. 2368 app.setBindMountPending(true); 2369 bindMountAppStorageDirs = false; 2370 } 2371 } 2372 2373 // If it's an isolated process, it should not even mount its own app data directories, 2374 // since it has no access to them anyway. 2375 if (app.isolated) { 2376 pkgDataInfoMap = null; 2377 allowlistedAppDataInfoMap = null; 2378 } 2379 2380 AppStateTracker ast = mService.mServices.mAppStateTracker; 2381 if (ast != null) { 2382 final boolean inBgRestricted = ast.isAppBackgroundRestricted( 2383 app.info.uid, app.info.packageName); 2384 if (inBgRestricted) { 2385 synchronized (mService) { 2386 mAppsInBackgroundRestricted.add(app); 2387 } 2388 } 2389 app.mState.setBackgroundRestricted(inBgRestricted); 2390 } 2391 2392 final Process.ProcessStartResult startResult; 2393 boolean regularZygote = false; 2394 app.mProcessGroupCreated = false; 2395 app.mSkipProcessGroupCreation = false; 2396 if (hostingRecord.usesWebviewZygote()) { 2397 startResult = startWebView(entryPoint, 2398 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 2399 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2400 app.info.dataDir, null, app.info.packageName, 2401 app.getDisabledCompatChanges(), 2402 new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); 2403 } else if (hostingRecord.usesAppZygote()) { 2404 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); 2405 2406 // We can't isolate app data and storage data as parent zygote already did that. 2407 startResult = appZygote.getProcess().start(entryPoint, 2408 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 2409 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2410 app.info.dataDir, null, app.info.packageName, 2411 /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp, 2412 app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap, 2413 false, false, 2414 new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); 2415 } else { 2416 regularZygote = true; 2417 startResult = Process.start(entryPoint, 2418 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 2419 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 2420 app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags, 2421 isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap, 2422 allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs, 2423 new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); 2424 // By now the process group should have been created by zygote. 2425 app.mProcessGroupCreated = true; 2426 } 2427 2428 if (!regularZygote) { 2429 // webview and app zygote don't have the permission to create the nodes 2430 synchronized (app) { 2431 if (!app.mSkipProcessGroupCreation) { 2432 // If we're not told to skip the process group creation, go create it. 2433 final int res = Process.createProcessGroup(uid, startResult.pid); 2434 if (res < 0) { 2435 if (res == -OsConstants.ESRCH) { 2436 Slog.e(ActivityManagerService.TAG, 2437 "Unable to create process group for " 2438 + app.processName + " (" + startResult.pid + ")"); 2439 } else { 2440 throw new AssertionError("Unable to create process group for " 2441 + app.processName + " (" + startResult.pid + ")"); 2442 } 2443 } else { 2444 app.mProcessGroupCreated = true; 2445 } 2446 } 2447 } 2448 } 2449 2450 // This runs after Process.start() as this method may block app process starting time 2451 // if dir is not cached. Running this method after Process.start() can make it 2452 // cache the dir asynchronously, so zygote can use it without waiting for it. 2453 if (bindMountAppStorageDirs) { 2454 storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(), 2455 app.processName); 2456 } 2457 checkSlow(startTime, "startProcess: returned from zygote!"); 2458 return startResult; 2459 } finally { 2460 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2461 } 2462 } 2463 2464 private boolean hasAppStorage(PackageManagerInternal pmInt, String packageName) { 2465 final AndroidPackage pkg = pmInt.getPackage(packageName); 2466 if (pkg == null) { 2467 Slog.w(TAG, "Unknown package " + packageName); 2468 return false; 2469 } 2470 final PackageManager.Property noAppStorageProp = 2471 pkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE); 2472 return noAppStorageProp == null || !noAppStorageProp.getBoolean(); 2473 } 2474 2475 @GuardedBy("mService") 2476 void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, int zygotePolicyFlags) { 2477 startProcessLocked(app, hostingRecord, zygotePolicyFlags, null /* abiOverride */); 2478 } 2479 2480 @GuardedBy("mService") 2481 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, 2482 int zygotePolicyFlags, String abiOverride) { 2483 return startProcessLocked(app, hostingRecord, zygotePolicyFlags, 2484 false /* disableHiddenApiChecks */, false /* disableTestApiChecks */, 2485 abiOverride); 2486 } 2487 2488 @GuardedBy("mService") 2489 ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2490 boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, 2491 int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid, 2492 boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage, 2493 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2494 long startTime = SystemClock.uptimeMillis(); 2495 ProcessRecord app; 2496 if (!isolated) { 2497 app = getProcessRecordLocked(processName, info.uid); 2498 checkSlow(startTime, "startProcess: after getProcessRecord"); 2499 2500 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) { 2501 // If we are in the background, then check to see if this process 2502 // is bad. If so, we will just silently fail. 2503 if (mService.mAppErrors.isBadProcess(processName, info.uid)) { 2504 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2505 + "/" + processName); 2506 return null; 2507 } 2508 } else { 2509 // When the user is explicitly starting a process, then clear its 2510 // crash count so that we won't make it bad until they see at 2511 // least one crash dialog again, and make the process good again 2512 // if it had been bad. 2513 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2514 + "/" + processName); 2515 mService.mAppErrors.resetProcessCrashTime(processName, info.uid); 2516 if (mService.mAppErrors.isBadProcess(processName, info.uid)) { 2517 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2518 UserHandle.getUserId(info.uid), info.uid, 2519 info.processName); 2520 mService.mAppErrors.clearBadProcess(processName, info.uid); 2521 if (app != null) { 2522 app.mErrorState.setBad(false); 2523 } 2524 } 2525 } 2526 } else { 2527 // If this is an isolated process, it can't re-use an existing process. 2528 app = null; 2529 } 2530 2531 // We don't have to do anything more if: 2532 // (1) There is an existing application record; and 2533 // (2) The caller doesn't think it is dead, OR there is no thread 2534 // object attached to it so we know it couldn't have crashed; and 2535 // (3) There is a pid assigned to it, so it is either starting or 2536 // already running. 2537 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName 2538 + " app=" + app + " knownToBeDead=" + knownToBeDead 2539 + " thread=" + (app != null ? app.getThread() : null) 2540 + " pid=" + (app != null ? app.getPid() : -1)); 2541 ProcessRecord predecessor = null; 2542 if (app != null && app.getPid() > 0) { 2543 if ((!knownToBeDead && !app.isKilled()) || app.getThread() == null) { 2544 // We already have the app running, or are waiting for it to 2545 // come up (we have a pid but not yet its thread), so keep it. 2546 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app); 2547 // If this is a new package in the process, add the package to the list 2548 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats); 2549 checkSlow(startTime, "startProcess: done, added package to proc"); 2550 return app; 2551 } 2552 2553 // An application record is attached to a previous process, 2554 // clean it up now. 2555 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app); 2556 checkSlow(startTime, "startProcess: bad proc running, killing"); 2557 ProcessList.killProcessGroup(app.uid, app.getPid()); 2558 checkSlow(startTime, "startProcess: done killing old proc"); 2559 2560 if (!app.isKilled()) { 2561 // Throw a wtf if it's not killed 2562 Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process"); 2563 } else { 2564 Slog.w(TAG_PROCESSES, app.toString() + " is attached to a previous process"); 2565 } 2566 // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup 2567 // routine of it yet, but we'd set it as the predecessor of the new process. 2568 predecessor = app; 2569 app = null; 2570 } else if (!isolated) { 2571 // This app may have been removed from process name maps, probably because we killed it 2572 // and did the cleanup before the actual death notification. Check the dying processes. 2573 predecessor = mDyingProcesses.get(processName, info.uid); 2574 if (predecessor != null) { 2575 // The process record could have existed but its pid is set to 0. In this case, 2576 // the 'app' and 'predecessor' could end up pointing to the same instance; 2577 // so make sure we check this case here. 2578 if (app != null && app != predecessor) { 2579 app.mPredecessor = predecessor; 2580 predecessor.mSuccessor = app; 2581 } else { 2582 app = null; 2583 } 2584 Slog.w(TAG_PROCESSES, predecessor.toString() + " is attached to a previous process " 2585 + predecessor.getDyingPid()); 2586 } 2587 } 2588 2589 if (app == null) { 2590 checkSlow(startTime, "startProcess: creating new process record"); 2591 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox, 2592 sdkSandboxUid, sdkSandboxClientAppPackage, hostingRecord); 2593 if (app == null) { 2594 Slog.w(TAG, "Failed making new process record for " 2595 + processName + "/" + info.uid + " isolated=" + isolated); 2596 return null; 2597 } 2598 app.mErrorState.setCrashHandler(crashHandler); 2599 app.setIsolatedEntryPoint(entryPoint); 2600 app.setIsolatedEntryPointArgs(entryPointArgs); 2601 if (predecessor != null) { 2602 app.mPredecessor = predecessor; 2603 predecessor.mSuccessor = app; 2604 } 2605 checkSlow(startTime, "startProcess: done creating new process record"); 2606 } else { 2607 // If this is a new package in the process, add the package to the list 2608 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats); 2609 checkSlow(startTime, "startProcess: added package to existing proc"); 2610 } 2611 2612 // If the system is not ready yet, then hold off on starting this 2613 // process until it is. 2614 if (!mService.mProcessesReady 2615 && !mService.isAllowedWhileBooting(info) 2616 && !allowWhileBooting) { 2617 if (!mService.mProcessesOnHold.contains(app)) { 2618 mService.mProcessesOnHold.add(app); 2619 } 2620 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, 2621 "System not ready, putting on hold: " + app); 2622 checkSlow(startTime, "startProcess: returning with proc on hold"); 2623 return app; 2624 } 2625 2626 checkSlow(startTime, "startProcess: stepping in to startProcess"); 2627 final boolean success = 2628 startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride); 2629 checkSlow(startTime, "startProcess: done starting proc!"); 2630 return success ? app : null; 2631 } 2632 2633 @GuardedBy("mService") 2634 String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) { 2635 StringBuilder sb = null; 2636 if (app.isKilledByAm()) { 2637 if (sb == null) sb = new StringBuilder(); 2638 sb.append("killedByAm=true;"); 2639 } 2640 if (mProcessNames.get(app.processName, app.uid) != app) { 2641 if (sb == null) sb = new StringBuilder(); 2642 sb.append("No entry in mProcessNames;"); 2643 } 2644 if (!app.isPendingStart()) { 2645 if (sb == null) sb = new StringBuilder(); 2646 sb.append("pendingStart=false;"); 2647 } 2648 if (app.getStartSeq() > expectedStartSeq) { 2649 if (sb == null) sb = new StringBuilder(); 2650 sb.append("seq=" + app.getStartSeq() + ",expected=" + expectedStartSeq + ";"); 2651 } 2652 try { 2653 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, app.userId); 2654 } catch (RemoteException e) { 2655 // unexpected; ignore 2656 } catch (SecurityException e) { 2657 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { 2658 if (sb == null) sb = new StringBuilder(); 2659 sb.append("Package is frozen;"); 2660 } else { 2661 // we're not being started async and so should throw to the caller. 2662 throw e; 2663 } 2664 } 2665 return sb == null ? null : sb.toString(); 2666 } 2667 2668 @GuardedBy("mService") 2669 private boolean handleProcessStartedLocked(ProcessRecord pending, 2670 Process.ProcessStartResult startResult, long expectedStartSeq) { 2671 // Indicates that this process start has been taken care of. 2672 if (mPendingStarts.get(expectedStartSeq) == null) { 2673 if (pending.getPid() == startResult.pid) { 2674 pending.setUsingWrapper(startResult.usingWrapper); 2675 // TODO: Update already existing clients of usingWrapper 2676 } 2677 return false; 2678 } 2679 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper, 2680 expectedStartSeq, false); 2681 } 2682 2683 @GuardedBy("mService") 2684 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, 2685 long expectedStartSeq, boolean procAttached) { 2686 mPendingStarts.remove(expectedStartSeq); 2687 final String reason = isProcStartValidLocked(app, expectedStartSeq); 2688 if (reason != null) { 2689 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + 2690 pid 2691 + ", " + reason); 2692 app.setPendingStart(false); 2693 killProcessQuiet(pid); 2694 final int appPid = app.getPid(); 2695 if (appPid != 0) { 2696 Process.killProcessGroup(app.uid, appPid); 2697 } 2698 noteAppKill(app, ApplicationExitInfo.REASON_OTHER, 2699 ApplicationExitInfo.SUBREASON_INVALID_START, reason); 2700 return false; 2701 } 2702 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2703 checkSlow(app.getStartTime(), "startProcess: done updating battery stats"); 2704 2705 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2706 UserHandle.getUserId(app.getStartUid()), pid, app.getStartUid(), 2707 app.processName, app.getHostingRecord().getType(), 2708 app.getHostingRecord().getName() != null ? app.getHostingRecord().getName() : ""); 2709 2710 try { 2711 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.info.packageName, 2712 app.processName, app.uid, app.getSeInfo(), app.info.sourceDir, pid); 2713 } catch (RemoteException ex) { 2714 // Ignore 2715 } 2716 2717 Watchdog.getInstance().processStarted(app.processName, pid); 2718 2719 checkSlow(app.getStartTime(), "startProcess: building log message"); 2720 StringBuilder buf = mStringBuilder; 2721 buf.setLength(0); 2722 buf.append("Start proc "); 2723 buf.append(pid); 2724 buf.append(':'); 2725 buf.append(app.processName); 2726 buf.append('/'); 2727 UserHandle.formatUid(buf, app.getStartUid()); 2728 if (app.getIsolatedEntryPoint() != null) { 2729 buf.append(" ["); 2730 buf.append(app.getIsolatedEntryPoint()); 2731 buf.append("]"); 2732 } 2733 buf.append(" for "); 2734 buf.append(app.getHostingRecord().getType()); 2735 if (app.getHostingRecord().getName() != null) { 2736 buf.append(" "); 2737 buf.append(app.getHostingRecord().getName()); 2738 } 2739 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.getStartUid()); 2740 synchronized (mProcLock) { 2741 app.setPid(pid); 2742 app.setUsingWrapper(usingWrapper); 2743 app.setPendingStart(false); 2744 } 2745 checkSlow(app.getStartTime(), "startProcess: starting to update pids map"); 2746 ProcessRecord oldApp; 2747 synchronized (mService.mPidsSelfLocked) { 2748 oldApp = mService.mPidsSelfLocked.get(pid); 2749 } 2750 // If there is already an app occupying that pid that hasn't been cleaned up 2751 if (oldApp != null && !app.isolated) { 2752 // Clean up anything relating to this pid first 2753 Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName 2754 + " startSeq:" + app.getStartSeq() 2755 + " pid:" + pid 2756 + " belongs to another existing app:" + oldApp.processName 2757 + " startSeq:" + oldApp.getStartSeq()); 2758 mService.cleanUpApplicationRecordLocked(oldApp, pid, false, false, -1, 2759 true /*replacingPid*/, false /* fromBinderDied */); 2760 } 2761 mService.addPidLocked(app); 2762 synchronized (mService.mPidsSelfLocked) { 2763 if (!procAttached) { 2764 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2765 msg.obj = app; 2766 mService.mHandler.sendMessageDelayed(msg, usingWrapper 2767 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2768 } 2769 } 2770 checkSlow(app.getStartTime(), "startProcess: done updating pids map"); 2771 return true; 2772 } 2773 2774 @GuardedBy("mService") 2775 void removeLruProcessLocked(ProcessRecord app) { 2776 int lrui = mLruProcesses.lastIndexOf(app); 2777 if (lrui >= 0) { 2778 synchronized (mProcLock) { 2779 if (!app.isKilled()) { 2780 if (app.isPersistent()) { 2781 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app); 2782 } else { 2783 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2784 if (app.getPid() > 0) { 2785 killProcessQuiet(app.getPid()); 2786 ProcessList.killProcessGroup(app.uid, app.getPid()); 2787 noteAppKill(app, ApplicationExitInfo.REASON_OTHER, 2788 ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed"); 2789 } else { 2790 app.setPendingStart(false); 2791 } 2792 } 2793 } 2794 if (lrui < mLruProcessActivityStart) { 2795 mLruProcessActivityStart--; 2796 } 2797 if (lrui < mLruProcessServiceStart) { 2798 mLruProcessServiceStart--; 2799 } 2800 mLruProcesses.remove(lrui); 2801 } 2802 } 2803 mService.removeOomAdjTargetLocked(app, true); 2804 } 2805 2806 @GuardedBy({"mService", "mProcLock"}) 2807 boolean killPackageProcessesLSP(String packageName, int appId, int userId, int minOomAdj, 2808 int reasonCode, int subReason, String reason) { 2809 return killPackageProcessesLSP(packageName, appId, userId, minOomAdj, 2810 false /* callerWillRestart */, true /* allowRestart */, true /* doit */, 2811 false /* evenPersistent */, false /* setRemoved */, false /* uninstalling */, 2812 reasonCode, subReason, reason); 2813 } 2814 2815 @GuardedBy("mService") 2816 void killAppZygotesLocked(String packageName, int appId, int userId, boolean force) { 2817 // See if there are any app zygotes running for this packageName / UID combination, 2818 // and kill it if so. 2819 final ArrayList<AppZygote> zygotesToKill = new ArrayList<>(); 2820 for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) { 2821 for (int i = 0; i < appZygotes.size(); ++i) { 2822 final int appZygoteUid = appZygotes.keyAt(i); 2823 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) { 2824 continue; 2825 } 2826 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) { 2827 continue; 2828 } 2829 final AppZygote appZygote = appZygotes.valueAt(i); 2830 if (packageName != null 2831 && !packageName.equals(appZygote.getAppInfo().packageName)) { 2832 continue; 2833 } 2834 zygotesToKill.add(appZygote); 2835 } 2836 } 2837 for (AppZygote appZygote : zygotesToKill) { 2838 killAppZygoteIfNeededLocked(appZygote, force); 2839 } 2840 } 2841 2842 private static boolean freezePackageCgroup(int packageUID, boolean freeze) { 2843 try { 2844 Process.freezeCgroupUid(packageUID, freeze); 2845 } catch (RuntimeException e) { 2846 final String logtxt = freeze ? "freeze" : "unfreeze"; 2847 Slog.e(TAG, "Unable to " + logtxt + " cgroup uid: " + packageUID + ": " + e); 2848 return false; 2849 } 2850 return true; 2851 } 2852 2853 private static void freezeBinderAndPackageCgroup(ArrayList<Pair<ProcessRecord, Boolean>> procs, 2854 int packageUID) { 2855 // Freeze all binder processes under the target UID (whose cgroup is about to be frozen). 2856 // Since we're going to kill these, we don't need to unfreze them later. 2857 // The procs list may not include all processes under the UID cgroup, but unincluded 2858 // processes (forks) should not be Binder users. 2859 int N = procs.size(); 2860 for (int i = 0; i < N; i++) { 2861 final int uid = procs.get(i).first.uid; 2862 final int pid = procs.get(i).first.getPid(); 2863 int nRetries = 0; 2864 // We only freeze the cgroup of the target package, so we do not need to freeze the 2865 // Binder interfaces of dependant processes in other UIDs. 2866 if (pid > 0 && uid == packageUID) { 2867 try { 2868 int rc; 2869 do { 2870 rc = CachedAppOptimizer.freezeBinder(pid, true, 10 /* timeout_ms */); 2871 } while (rc == -EAGAIN && nRetries++ < 1); 2872 if (rc != 0) Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + rc); 2873 } catch (RuntimeException e) { 2874 Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + e); 2875 } 2876 } 2877 } 2878 2879 // We freeze the entire UID (parent) cgroup so that newly-specialized processes also freeze 2880 // despite being added to a new child cgroup. The cgroups of package dependant processes are 2881 // not frozen, since it's possible this would freeze processes with no dependency on the 2882 // package being killed here. 2883 freezePackageCgroup(packageUID, true); 2884 } 2885 2886 @GuardedBy({"mService", "mProcLock"}) 2887 boolean killPackageProcessesLSP(String packageName, int appId, 2888 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 2889 boolean doit, boolean evenPersistent, boolean setRemoved, boolean uninstalling, 2890 int reasonCode, int subReason, String reason) { 2891 final PackageManagerInternal pm = mService.getPackageManagerInternal(); 2892 final ArrayList<Pair<ProcessRecord, Boolean>> procs = new ArrayList<>(); 2893 2894 // Remove all processes this package may have touched: all with the 2895 // same UID (except for the system or root user), and all whose name 2896 // matches the package name. 2897 final int NP = mProcessNames.getMap().size(); 2898 for (int ip = 0; ip < NP; ip++) { 2899 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2900 final int NA = apps.size(); 2901 for (int ia = 0; ia < NA; ia++) { 2902 ProcessRecord app = apps.valueAt(ia); 2903 if (app.isPersistent() && !evenPersistent) { 2904 // we don't kill persistent processes 2905 continue; 2906 } 2907 if (app.isRemoved()) { 2908 if (doit) { 2909 boolean shouldAllowRestart = false; 2910 if (!uninstalling && packageName != null) { 2911 // This package has a dependency on the given package being stopped, 2912 // while it's not being frozen nor uninstalled, allow to restart it. 2913 shouldAllowRestart = !app.getPkgList().containsKey(packageName) 2914 && app.getPkgDeps() != null 2915 && app.getPkgDeps().contains(packageName) 2916 && app.info != null 2917 && !pm.isPackageFrozen(app.info.packageName, app.uid, 2918 app.userId); 2919 } 2920 procs.add(new Pair<>(app, shouldAllowRestart)); 2921 } 2922 continue; 2923 } 2924 2925 // Skip process if it doesn't meet our oom adj requirement. 2926 if (app.mState.getSetAdj() < minOomAdj) { 2927 // Note it is still possible to have a process with oom adj 0 in the killed 2928 // processes, but it does not mean misjudgment. E.g. a bound service process 2929 // and its client activity process are both in the background, so they are 2930 // collected to be killed. If the client activity is killed first, the service 2931 // may be scheduled to unbind and become an executing service (oom adj 0). 2932 continue; 2933 } 2934 2935 boolean shouldAllowRestart = false; 2936 2937 // If no package is specified, we call all processes under the 2938 // given user id. 2939 if (packageName == null) { 2940 if (userId != UserHandle.USER_ALL && app.userId != userId) { 2941 continue; 2942 } 2943 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 2944 continue; 2945 } 2946 // Package has been specified, we want to hit all processes 2947 // that match it. We need to qualify this by the processes 2948 // that are running under the specified app and user ID. 2949 } else { 2950 final boolean isDep = app.getPkgDeps() != null 2951 && app.getPkgDeps().contains(packageName); 2952 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 2953 continue; 2954 } 2955 if (userId != UserHandle.USER_ALL && app.userId != userId) { 2956 continue; 2957 } 2958 final boolean isInPkgList = app.getPkgList().containsKey(packageName); 2959 if (!isInPkgList && !isDep) { 2960 continue; 2961 } 2962 if (!isInPkgList && isDep && !uninstalling && app.info != null 2963 && !pm.isPackageFrozen(app.info.packageName, app.uid, app.userId)) { 2964 // This package has a dependency on the given package being stopped, 2965 // while it's not being frozen nor uninstalled, allow to restart it. 2966 shouldAllowRestart = true; 2967 } 2968 } 2969 2970 // Process has passed all conditions, kill it! 2971 if (!doit) { 2972 return true; 2973 } 2974 if (setRemoved) { 2975 app.setRemoved(true); 2976 } 2977 procs.add(new Pair<>(app, shouldAllowRestart)); 2978 } 2979 } 2980 2981 final int packageUID = UserHandle.getUid(userId, appId); 2982 final boolean doFreeze = appId >= Process.FIRST_APPLICATION_UID 2983 && appId <= Process.LAST_APPLICATION_UID; 2984 if (doFreeze) { 2985 freezeBinderAndPackageCgroup(procs, packageUID); 2986 } 2987 2988 int N = procs.size(); 2989 for (int i=0; i<N; i++) { 2990 final Pair<ProcessRecord, Boolean> proc = procs.get(i); 2991 removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second, 2992 reasonCode, subReason, reason, !doFreeze /* async */); 2993 } 2994 killAppZygotesLocked(packageName, appId, userId, false /* force */); 2995 mService.updateOomAdjLocked(OOM_ADJ_REASON_PROCESS_END); 2996 if (doFreeze) { 2997 freezePackageCgroup(packageUID, false); 2998 } 2999 return N > 0; 3000 } 3001 3002 @GuardedBy("mService") 3003 boolean removeProcessLocked(ProcessRecord app, 3004 boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) { 3005 return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode, 3006 ApplicationExitInfo.SUBREASON_UNKNOWN, reason, true); 3007 } 3008 3009 @GuardedBy("mService") 3010 boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart, 3011 boolean allowRestart, int reasonCode, int subReason, String reason) { 3012 return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode, subReason, 3013 reason, true); 3014 } 3015 3016 @GuardedBy("mService") 3017 boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart, 3018 boolean allowRestart, int reasonCode, int subReason, String reason, boolean async) { 3019 final String name = app.processName; 3020 final int uid = app.uid; 3021 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES, 3022 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")"); 3023 3024 ProcessRecord old = mProcessNames.get(name, uid); 3025 if (old != app) { 3026 // This process is no longer active, so nothing to do. 3027 Slog.w(TAG, "Ignoring remove of inactive process: " + app); 3028 return false; 3029 } 3030 removeProcessNameLocked(name, uid); 3031 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController()); 3032 3033 boolean needRestart = false; 3034 final int pid = app.getPid(); 3035 if ((pid > 0 && pid != ActivityManagerService.MY_PID) 3036 || (pid == 0 && app.isPendingStart())) { 3037 if (pid > 0) { 3038 mService.removePidLocked(pid, app); 3039 app.setBindMountPending(false); 3040 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3041 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3042 if (app.isolated) { 3043 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3044 mService.getPackageManagerInternal().removeIsolatedUid(app.uid); 3045 } 3046 } 3047 boolean willRestart = false; 3048 if (app.isPersistent() && !app.isolated) { 3049 if (!callerWillRestart) { 3050 willRestart = true; 3051 } else { 3052 needRestart = true; 3053 } 3054 } 3055 app.killLocked(reason, reasonCode, subReason, true, async); 3056 mService.handleAppDiedLocked(app, pid, willRestart, allowRestart, 3057 false /* fromBinderDied */); 3058 if (willRestart) { 3059 removeLruProcessLocked(app); 3060 mService.addAppLocked(app.info, null, false, null /* ABI override */, 3061 ZYGOTE_POLICY_FLAG_EMPTY); 3062 } 3063 } else { 3064 mRemovedProcesses.add(app); 3065 } 3066 3067 return needRestart; 3068 } 3069 3070 @GuardedBy("mService") 3071 void addProcessNameLocked(ProcessRecord proc) { 3072 // We shouldn't already have a process under this name, but just in case we 3073 // need to clean up whatever may be there now. 3074 synchronized (mProcLock) { 3075 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); 3076 if (old == proc && proc.isPersistent()) { 3077 // We are re-adding a persistent process. Whatevs! Just leave it there. 3078 Slog.w(TAG, "Re-adding persistent process " + proc); 3079 } else if (old != null) { 3080 if (old.isKilled()) { 3081 // The old process has been killed, we probably haven't had 3082 // a chance to clean up the old record, just log a warning 3083 Slog.w(TAG, "Existing proc " + old + " was killed " 3084 + (SystemClock.uptimeMillis() - old.getKillTime()) 3085 + "ms ago when adding " + proc); 3086 } else { 3087 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc); 3088 } 3089 } 3090 UidRecord uidRec = mActiveUids.get(proc.uid); 3091 if (uidRec == null) { 3092 uidRec = new UidRecord(proc.uid, mService); 3093 // This is the first appearance of the uid, report it now! 3094 if (DEBUG_UID_OBSERVERS) { 3095 Slog.i(TAG_UID_OBSERVERS, "Creating new process uid: " + uidRec); 3096 } 3097 if (Arrays.binarySearch(mService.mDeviceIdleTempAllowlist, 3098 UserHandle.getAppId(proc.uid)) >= 0 3099 || mService.mPendingTempAllowlist.indexOfKey(proc.uid) >= 0) { 3100 uidRec.setCurAllowListed(true); 3101 uidRec.setSetAllowListed(true); 3102 } 3103 uidRec.updateHasInternetPermission(); 3104 mActiveUids.put(proc.uid, uidRec); 3105 EventLogTags.writeAmUidRunning(uidRec.getUid()); 3106 mService.noteUidProcessState(uidRec.getUid(), uidRec.getCurProcState(), 3107 uidRec.getCurCapability()); 3108 } 3109 proc.setUidRecord(uidRec); 3110 uidRec.addProcess(proc); 3111 3112 // Reset render thread tid if it was already set, so new process can set it again. 3113 proc.setRenderThreadTid(0); 3114 mProcessNames.put(proc.processName, proc.uid, proc); 3115 } 3116 if (proc.isolated) { 3117 mIsolatedProcesses.put(proc.uid, proc); 3118 } 3119 if (proc.isSdkSandbox) { 3120 ArrayList<ProcessRecord> sdkSandboxes = mSdkSandboxes.get(proc.uid); 3121 if (sdkSandboxes == null) { 3122 sdkSandboxes = new ArrayList<>(); 3123 } 3124 sdkSandboxes.add(proc); 3125 mSdkSandboxes.put(Process.getAppUidForSdkSandboxUid(proc.uid), sdkSandboxes); 3126 } 3127 } 3128 3129 @GuardedBy("mService") 3130 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, 3131 HostingRecord hostingRecord) { 3132 if (hostingRecord == null || !hostingRecord.usesAppZygote()) { 3133 // Allocate an isolated UID from the global range 3134 return mGlobalIsolatedUids; 3135 } else { 3136 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked( 3137 info.processName, hostingRecord.getDefiningUid()); 3138 } 3139 } 3140 3141 ProcessRecord getSharedIsolatedProcess(String processName, int uid, String packageName) { 3142 for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) { 3143 final ProcessRecord app = mIsolatedProcesses.valueAt(i); 3144 if (app.info.uid == uid && app.info.packageName.equals(packageName) 3145 && app.processName.equals(processName)) { 3146 return app; 3147 } 3148 } 3149 return null; 3150 } 3151 @Nullable 3152 @GuardedBy("mService") 3153 List<Integer> getIsolatedProcessesLocked(int uid) { 3154 List<Integer> ret = null; 3155 for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) { 3156 final ProcessRecord app = mIsolatedProcesses.valueAt(i); 3157 if (app.info.uid == uid) { 3158 if (ret == null) { 3159 ret = new ArrayList<>(); 3160 } 3161 ret.add(app.getPid()); 3162 } 3163 } 3164 return ret; 3165 } 3166 3167 /** 3168 * Returns the associated SDK sandbox processes for a UID. Note that this does 3169 * NOT return a copy, so callers should not modify the result, or use it outside 3170 * of the lock scope. 3171 * 3172 * @param uid UID to return sansdbox processes for 3173 */ 3174 @Nullable 3175 @GuardedBy("mService") 3176 List<ProcessRecord> getSdkSandboxProcessesForAppLocked(int uid) { 3177 return mSdkSandboxes.get(uid); 3178 } 3179 3180 @GuardedBy("mService") 3181 ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 3182 boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid, 3183 String sdkSandboxClientAppPackage, HostingRecord hostingRecord) { 3184 String proc = customProcess != null ? customProcess : info.processName; 3185 final int userId = UserHandle.getUserId(info.uid); 3186 int uid = info.uid; 3187 if (isSdkSandbox) { 3188 uid = sdkSandboxUid; 3189 } 3190 if (Process.isSdkSandboxUid(uid) && (!isSdkSandbox || sdkSandboxClientAppPackage == null)) { 3191 Slog.e(TAG, "Abort creating new sandbox process as required parameters are missing."); 3192 return null; 3193 } 3194 if (isolated) { 3195 if (isolatedUid == 0) { 3196 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord); 3197 if (uidRange == null) { 3198 return null; 3199 } 3200 uid = uidRange.allocateIsolatedUidLocked(userId); 3201 if (uid == -1) { 3202 return null; 3203 } 3204 } else { 3205 // Special case for startIsolatedProcess (internal only), where 3206 // the uid of the isolated process is specified by the caller. 3207 uid = isolatedUid; 3208 } 3209 mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid); 3210 mService.getPackageManagerInternal().addIsolatedUid(uid, info.uid); 3211 3212 // Register the isolated UID with this application so BatteryStats knows to 3213 // attribute resource usage to the application. 3214 // 3215 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats 3216 // about the process state of the isolated UID *before* it is registered with the 3217 // owning application. 3218 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid); 3219 FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid, 3220 FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED); 3221 } 3222 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid, 3223 sdkSandboxClientAppPackage, 3224 hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName()); 3225 final ProcessStateRecord state = r.mState; 3226 3227 if (!isolated && !isSdkSandbox 3228 && userId == UserHandle.USER_SYSTEM 3229 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK 3230 && (TextUtils.equals(proc, info.processName))) { 3231 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc. 3232 state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); 3233 state.setSetSchedGroup(ProcessList.SCHED_GROUP_DEFAULT); 3234 r.setPersistent(true); 3235 state.setMaxAdj(ProcessList.PERSISTENT_PROC_ADJ); 3236 } 3237 if (isolated && isolatedUid != 0) { 3238 // Special case for startIsolatedProcess (internal only) - assume the process 3239 // is required by the system server to prevent it being killed. 3240 state.setMaxAdj(ProcessList.PERSISTENT_SERVICE_ADJ); 3241 } 3242 addProcessNameLocked(r); 3243 return r; 3244 } 3245 3246 @GuardedBy("mService") 3247 ProcessRecord removeProcessNameLocked(final String name, final int uid) { 3248 return removeProcessNameLocked(name, uid, null); 3249 } 3250 3251 @GuardedBy("mService") 3252 ProcessRecord removeProcessNameLocked(final String name, final int uid, 3253 final ProcessRecord expecting) { 3254 ProcessRecord old = mProcessNames.get(name, uid); 3255 final ProcessRecord record = expecting != null ? expecting : old; 3256 synchronized (mProcLock) { 3257 // Only actually remove when the currently recorded value matches the 3258 // record that we expected; if it doesn't match then we raced with a 3259 // newly created process and we don't want to destroy the new one. 3260 if ((expecting == null) || (old == expecting)) { 3261 mProcessNames.remove(name, uid); 3262 } 3263 if (record != null) { 3264 final UidRecord uidRecord = record.getUidRecord(); 3265 if (uidRecord != null) { 3266 uidRecord.removeProcess(record); 3267 if (uidRecord.getNumOfProcs() == 0) { 3268 // No more processes using this uid, tell clients it is gone. 3269 if (DEBUG_UID_OBSERVERS) { 3270 Slog.i(TAG_UID_OBSERVERS, "No more processes in " + uidRecord); 3271 } 3272 mService.enqueueUidChangeLocked(uidRecord, -1, 3273 UidRecord.CHANGE_GONE | UidRecord.CHANGE_PROCSTATE); 3274 EventLogTags.writeAmUidStopped(uid); 3275 mActiveUids.remove(uid); 3276 mService.mFgsStartTempAllowList.removeUid(record.info.uid); 3277 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 3278 ActivityManager.PROCESS_CAPABILITY_NONE); 3279 } 3280 record.setUidRecord(null); 3281 } 3282 } 3283 } 3284 mIsolatedProcesses.remove(uid); 3285 mGlobalIsolatedUids.freeIsolatedUidLocked(uid); 3286 // Remove the (expected) ProcessRecord from the app zygote 3287 if (record != null && record.appZygote) { 3288 removeProcessFromAppZygoteLocked(record); 3289 } 3290 if (record != null && record.isSdkSandbox) { 3291 final int appUid = Process.getAppUidForSdkSandboxUid(uid); 3292 final ArrayList<ProcessRecord> sdkSandboxesForUid = mSdkSandboxes.get(appUid); 3293 if (sdkSandboxesForUid != null) { 3294 sdkSandboxesForUid.remove(record); 3295 if (sdkSandboxesForUid.size() == 0) { 3296 mSdkSandboxes.remove(appUid); 3297 } 3298 } 3299 } 3300 mAppsInBackgroundRestricted.remove(record); 3301 3302 return old; 3303 } 3304 3305 /** Call setCoreSettings on all LRU processes, with the new settings. */ 3306 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3307 void updateCoreSettingsLOSP(Bundle settings) { 3308 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3309 ProcessRecord processRecord = mLruProcesses.get(i); 3310 final IApplicationThread thread = processRecord.getThread(); 3311 try { 3312 if (thread != null) { 3313 thread.setCoreSettings(settings); 3314 } 3315 } catch (RemoteException re) { 3316 /* ignore */ 3317 } 3318 } 3319 } 3320 3321 /** 3322 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and 3323 * procstate lower than maxProcState. 3324 * @param minTargetSdk 3325 * @param maxProcState 3326 */ 3327 @GuardedBy({"mService", "mProcLock"}) 3328 void killAllBackgroundProcessesExceptLSP(int minTargetSdk, int maxProcState) { 3329 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 3330 final int NP = mProcessNames.getMap().size(); 3331 for (int ip = 0; ip < NP; ip++) { 3332 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 3333 final int NA = apps.size(); 3334 for (int ia = 0; ia < NA; ia++) { 3335 final ProcessRecord app = apps.valueAt(ia); 3336 if (app.isRemoved() 3337 || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk) 3338 && (maxProcState < 0 || app.mState.getSetProcState() > maxProcState))) { 3339 procs.add(app); 3340 } 3341 } 3342 } 3343 3344 final int N = procs.size(); 3345 for (int i = 0; i < N; i++) { 3346 removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER, 3347 ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except"); 3348 } 3349 } 3350 3351 /** 3352 * Call updateTimePrefs on all LRU processes 3353 * @param timePref The time pref to pass to each process 3354 */ 3355 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3356 void updateAllTimePrefsLOSP(int timePref) { 3357 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3358 ProcessRecord r = mLruProcesses.get(i); 3359 final IApplicationThread thread = r.getThread(); 3360 if (thread != null) { 3361 try { 3362 thread.updateTimePrefs(timePref); 3363 } catch (RemoteException ex) { 3364 Slog.w(TAG, "Failed to update preferences for: " 3365 + r.info.processName); 3366 } 3367 } 3368 } 3369 } 3370 3371 void setAllHttpProxy() { 3372 // Update the HTTP proxy for each application thread. 3373 synchronized (mProcLock) { 3374 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 3375 ProcessRecord r = mLruProcesses.get(i); 3376 IApplicationThread thread = r.getThread(); 3377 // Don't dispatch to isolated processes as they can't access ConnectivityManager and 3378 // don't have network privileges anyway. Exclude system server and update it 3379 // separately outside the AMS lock, to avoid deadlock with Connectivity Service. 3380 if (r.getPid() != ActivityManagerService.MY_PID && thread != null && !r.isolated) { 3381 try { 3382 thread.updateHttpProxy(); 3383 } catch (RemoteException ex) { 3384 Slog.w(TAG, "Failed to update http proxy for: " 3385 + r.info.processName); 3386 } 3387 } 3388 } 3389 } 3390 ActivityThread.updateHttpProxy(mService.mContext); 3391 } 3392 3393 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3394 void clearAllDnsCacheLOSP() { 3395 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3396 ProcessRecord r = mLruProcesses.get(i); 3397 final IApplicationThread thread = r.getThread(); 3398 if (thread != null) { 3399 try { 3400 thread.clearDnsCache(); 3401 } catch (RemoteException ex) { 3402 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 3403 } 3404 } 3405 } 3406 } 3407 3408 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3409 void handleAllTrustStorageUpdateLOSP() { 3410 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3411 ProcessRecord r = mLruProcesses.get(i); 3412 final IApplicationThread thread = r.getThread(); 3413 if (thread != null) { 3414 try { 3415 thread.handleTrustStorageUpdate(); 3416 } catch (RemoteException ex) { 3417 Slog.w(TAG, "Failed to handle trust storage update for: " + 3418 r.info.processName); 3419 } 3420 } 3421 } 3422 } 3423 3424 @GuardedBy({"mService", "mProcLock"}) 3425 private int updateLruProcessInternalLSP(ProcessRecord app, long now, int index, 3426 int lruSeq, String what, Object obj, ProcessRecord srcApp) { 3427 app.setLastActivityTime(now); 3428 3429 if (app.hasActivitiesOrRecentTasks()) { 3430 // Don't want to touch dependent processes that are hosting activities. 3431 return index; 3432 } 3433 3434 int lrui = mLruProcesses.lastIndexOf(app); 3435 if (lrui < 0) { 3436 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 3437 + what + " " + obj + " from " + srcApp); 3438 return index; 3439 } 3440 3441 if (lrui >= index) { 3442 // Don't want to cause this to move dependent processes *back* in the 3443 // list as if they were less frequently used. 3444 return index; 3445 } 3446 3447 if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) { 3448 // Don't want to touch dependent processes that are hosting activities. 3449 return index; 3450 } 3451 3452 mLruProcesses.remove(lrui); 3453 if (index > 0) { 3454 index--; 3455 } 3456 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index 3457 + " in LRU list: " + app); 3458 mLruProcesses.add(index, app); 3459 app.setLruSeq(lruSeq); 3460 return index; 3461 } 3462 3463 /** 3464 * Handle the case where we are inserting a process hosting client activities: 3465 * Make sure any groups have their order match their importance, and take care of 3466 * distributing old clients across other activity processes so they can't spam 3467 * the LRU list. Processing of the list will be restricted by the indices provided, 3468 * and not extend out of them. 3469 * 3470 * @param topApp The app at the top that has just been inserted in to the list. 3471 * @param topI The position in the list where topApp was inserted; this is the start (at the 3472 * top) where we are going to do our processing. 3473 * @param bottomI The last position at which we will be processing; this is the end position 3474 * of whichever section of the LRU list we are in. Nothing past it will be 3475 * touched. 3476 * @param endIndex The current end of the top being processed. Typically topI - 1. That is, 3477 * where we are going to start potentially adjusting other entries in the list. 3478 */ 3479 @GuardedBy({"mService", "mProcLock"}) 3480 private void updateClientActivitiesOrderingLSP(final ProcessRecord topApp, final int topI, 3481 final int bottomI, int endIndex) { 3482 final ProcessServiceRecord topPsr = topApp.mServices; 3483 if (topApp.hasActivitiesOrRecentTasks() || topPsr.isTreatedLikeActivity() 3484 || !topPsr.hasClientActivities()) { 3485 // If this is not a special process that has client activities, then there is 3486 // nothing to do. 3487 return; 3488 } 3489 3490 final int uid = topApp.info.uid; 3491 final int topConnectionGroup = topPsr.getConnectionGroup(); 3492 if (topConnectionGroup > 0) { 3493 int endImportance = topPsr.getConnectionImportance(); 3494 for (int i = endIndex; i >= bottomI; i--) { 3495 final ProcessRecord subProc = mLruProcesses.get(i); 3496 final ProcessServiceRecord subPsr = subProc.mServices; 3497 final int subConnectionGroup = subPsr.getConnectionGroup(); 3498 final int subConnectionImportance = subPsr.getConnectionImportance(); 3499 if (subProc.info.uid == uid 3500 && subConnectionGroup == topConnectionGroup) { 3501 if (i == endIndex && subConnectionImportance >= endImportance) { 3502 // This process is already in the group, and its importance 3503 // is not as strong as the process before it, so keep it 3504 // correctly positioned in the group. 3505 if (DEBUG_LRU) Slog.d(TAG_LRU, 3506 "Keeping in-place above " + subProc 3507 + " endImportance=" + endImportance 3508 + " group=" + subConnectionGroup 3509 + " importance=" + subConnectionImportance); 3510 endIndex--; 3511 endImportance = subConnectionImportance; 3512 } else { 3513 // We want to pull this up to be with the rest of the group, 3514 // and order within the group by importance. 3515 if (DEBUG_LRU) Slog.d(TAG_LRU, 3516 "Pulling up " + subProc 3517 + " to position in group with importance=" 3518 + subConnectionImportance); 3519 boolean moved = false; 3520 for (int pos = topI; pos > endIndex; pos--) { 3521 final ProcessRecord posProc = mLruProcesses.get(pos); 3522 if (subConnectionImportance 3523 <= posProc.mServices.getConnectionImportance()) { 3524 mLruProcesses.remove(i); 3525 mLruProcesses.add(pos, subProc); 3526 if (DEBUG_LRU) Slog.d(TAG_LRU, 3527 "Moving " + subProc 3528 + " from position " + i + " to above " + posProc 3529 + " @ " + pos); 3530 moved = true; 3531 endIndex--; 3532 break; 3533 } 3534 } 3535 if (!moved) { 3536 // Goes to the end of the group. 3537 mLruProcesses.remove(i); 3538 mLruProcesses.add(endIndex, subProc); 3539 if (DEBUG_LRU) Slog.d(TAG_LRU, 3540 "Moving " + subProc 3541 + " from position " + i + " to end of group @ " 3542 + endIndex); 3543 endIndex--; 3544 endImportance = subConnectionImportance; 3545 } 3546 } 3547 } 3548 } 3549 3550 } 3551 // To keep it from spamming the LRU list (by making a bunch of clients), 3552 // we will distribute other entries owned by it to be in-between other apps. 3553 int i = endIndex; 3554 while (i >= bottomI) { 3555 ProcessRecord subProc = mLruProcesses.get(i); 3556 final ProcessServiceRecord subPsr = subProc.mServices; 3557 final int subConnectionGroup = subPsr.getConnectionGroup(); 3558 if (DEBUG_LRU) Slog.d(TAG_LRU, 3559 "Looking to spread old procs, at " + subProc + " @ " + i); 3560 if (subProc.info.uid != uid) { 3561 // This is a different app... if we have gone through some of the 3562 // target app, pull this up to be before them. We want to pull up 3563 // one activity process, but any number of non-activity processes. 3564 if (i < endIndex) { 3565 boolean hasActivity = false; 3566 int connUid = 0; 3567 int connGroup = 0; 3568 while (i >= bottomI) { 3569 mLruProcesses.remove(i); 3570 mLruProcesses.add(endIndex, subProc); 3571 if (DEBUG_LRU) Slog.d(TAG_LRU, 3572 "Different app, moving to " + endIndex); 3573 i--; 3574 if (i < bottomI) { 3575 break; 3576 } 3577 subProc = mLruProcesses.get(i); 3578 if (DEBUG_LRU) Slog.d(TAG_LRU, 3579 "Looking at next app at " + i + ": " + subProc); 3580 if (subProc.hasActivitiesOrRecentTasks() 3581 || subPsr.isTreatedLikeActivity()) { 3582 if (DEBUG_LRU) Slog.d(TAG_LRU, 3583 "This is hosting an activity!"); 3584 if (hasActivity) { 3585 // Already found an activity, done. 3586 if (DEBUG_LRU) Slog.d(TAG_LRU, 3587 "Already found an activity, done"); 3588 break; 3589 } 3590 hasActivity = true; 3591 } else if (subPsr.hasClientActivities()) { 3592 if (DEBUG_LRU) Slog.d(TAG_LRU, 3593 "This is a client of an activity"); 3594 if (hasActivity) { 3595 if (connUid == 0 || connUid != subProc.info.uid) { 3596 // Already have an activity that is not from from a client 3597 // connection or is a different client connection, done. 3598 if (DEBUG_LRU) Slog.d(TAG_LRU, 3599 "Already found a different activity: connUid=" 3600 + connUid + " uid=" + subProc.info.uid); 3601 break; 3602 } else if (connGroup == 0 || connGroup != subConnectionGroup) { 3603 // Previously saw a different group or not from a group, 3604 // want to treat these as different things. 3605 if (DEBUG_LRU) Slog.d(TAG_LRU, 3606 "Already found a different group: connGroup=" 3607 + connGroup + " group=" + subConnectionGroup); 3608 break; 3609 } 3610 } else { 3611 if (DEBUG_LRU) Slog.d(TAG_LRU, 3612 "This is an activity client! uid=" 3613 + subProc.info.uid + " group=" + subConnectionGroup); 3614 hasActivity = true; 3615 connUid = subProc.info.uid; 3616 connGroup = subConnectionGroup; 3617 } 3618 } 3619 endIndex--; 3620 } 3621 } 3622 // Find the end of the next group of processes for target app. This 3623 // is after any entries of different apps (so we don't change the existing 3624 // relative order of apps) and then after the next last group of processes 3625 // of the target app. 3626 for (endIndex--; endIndex >= bottomI; endIndex--) { 3627 final ProcessRecord endProc = mLruProcesses.get(endIndex); 3628 if (endProc.info.uid == uid) { 3629 if (DEBUG_LRU) Slog.d(TAG_LRU, 3630 "Found next group of app: " + endProc + " @ " 3631 + endIndex); 3632 break; 3633 } 3634 } 3635 if (endIndex >= bottomI) { 3636 final ProcessRecord endProc = mLruProcesses.get(endIndex); 3637 final ProcessServiceRecord endPsr = endProc.mServices; 3638 final int endConnectionGroup = endPsr.getConnectionGroup(); 3639 for (endIndex--; endIndex >= bottomI; endIndex--) { 3640 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex); 3641 final int nextConnectionGroup = nextEndProc.mServices.getConnectionGroup(); 3642 if (nextEndProc.info.uid != uid 3643 || nextConnectionGroup != endConnectionGroup) { 3644 if (DEBUG_LRU) Slog.d(TAG_LRU, 3645 "Found next group or app: " + nextEndProc + " @ " 3646 + endIndex + " group=" + nextConnectionGroup); 3647 break; 3648 } 3649 } 3650 } 3651 if (DEBUG_LRU) Slog.d(TAG_LRU, 3652 "Bumping scan position to " + endIndex); 3653 i = endIndex; 3654 } else { 3655 i--; 3656 } 3657 } 3658 } 3659 3660 @GuardedBy("mService") 3661 void updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client) { 3662 final ProcessServiceRecord psr = app.mServices; 3663 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || psr.hasClientActivities() 3664 || psr.isTreatedLikeActivity(); 3665 final boolean hasService = false; // not impl yet. app.services.size() > 0; 3666 if (!activityChange && hasActivity) { 3667 // The process has activities, so we are only allowing activity-based adjustments 3668 // to move it. It should be kept in the front of the list with other 3669 // processes that have activities, and we don't want those to change their 3670 // order except due to activity operations. 3671 return; 3672 } 3673 3674 if (app.getPid() == 0 && !app.isPendingStart()) { 3675 // This process has been killed and its cleanup is done, don't proceed the LRU update. 3676 return; 3677 } 3678 3679 synchronized (mProcLock) { 3680 updateLruProcessLSP(app, client, hasActivity, hasService); 3681 } 3682 } 3683 3684 @GuardedBy({"mService", "mProcLock"}) 3685 private void updateLruProcessLSP(ProcessRecord app, ProcessRecord client, 3686 boolean hasActivity, boolean hasService) { 3687 mLruSeq++; 3688 final long now = SystemClock.uptimeMillis(); 3689 final ProcessServiceRecord psr = app.mServices; 3690 app.setLastActivityTime(now); 3691 3692 // First a quick reject: if the app is already at the position we will 3693 // put it, then there is nothing to do. 3694 if (hasActivity) { 3695 final int N = mLruProcesses.size(); 3696 if (N > 0 && mLruProcesses.get(N - 1) == app) { 3697 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app); 3698 return; 3699 } 3700 } else { 3701 if (mLruProcessServiceStart > 0 3702 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 3703 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app); 3704 return; 3705 } 3706 } 3707 3708 int lrui = mLruProcesses.lastIndexOf(app); 3709 3710 if (app.isPersistent() && lrui >= 0) { 3711 // We don't care about the position of persistent processes, as long as 3712 // they are in the list. 3713 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app); 3714 return; 3715 } 3716 3717 /* In progress: compute new position first, so we can avoid doing work 3718 if the process is not actually going to move. Not yet working. 3719 int addIndex; 3720 int nextIndex; 3721 boolean inActivity = false, inService = false; 3722 if (hasActivity) { 3723 // Process has activities, put it at the very tipsy-top. 3724 addIndex = mLruProcesses.size(); 3725 nextIndex = mLruProcessServiceStart; 3726 inActivity = true; 3727 } else if (hasService) { 3728 // Process has services, put it at the top of the service list. 3729 addIndex = mLruProcessActivityStart; 3730 nextIndex = mLruProcessServiceStart; 3731 inActivity = true; 3732 inService = true; 3733 } else { 3734 // Process not otherwise of interest, it goes to the top of the non-service area. 3735 addIndex = mLruProcessServiceStart; 3736 if (client != null) { 3737 int clientIndex = mLruProcesses.lastIndexOf(client); 3738 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 3739 + app); 3740 if (clientIndex >= 0 && addIndex > clientIndex) { 3741 addIndex = clientIndex; 3742 } 3743 } 3744 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 3745 } 3746 3747 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 3748 + mLruProcessActivityStart + "): " + app); 3749 */ 3750 3751 if (lrui >= 0) { 3752 if (lrui < mLruProcessActivityStart) { 3753 mLruProcessActivityStart--; 3754 } 3755 if (lrui < mLruProcessServiceStart) { 3756 mLruProcessServiceStart--; 3757 } 3758 /* 3759 if (addIndex > lrui) { 3760 addIndex--; 3761 } 3762 if (nextIndex > lrui) { 3763 nextIndex--; 3764 } 3765 */ 3766 mLruProcesses.remove(lrui); 3767 } 3768 3769 /* 3770 mLruProcesses.add(addIndex, app); 3771 if (inActivity) { 3772 mLruProcessActivityStart++; 3773 } 3774 if (inService) { 3775 mLruProcessActivityStart++; 3776 } 3777 */ 3778 3779 int nextIndex; 3780 int nextActivityIndex = -1; 3781 if (hasActivity) { 3782 final int N = mLruProcesses.size(); 3783 nextIndex = mLruProcessServiceStart; 3784 if (!app.hasActivitiesOrRecentTasks() && !psr.isTreatedLikeActivity() 3785 && mLruProcessActivityStart < (N - 1)) { 3786 // Process doesn't have activities, but has clients with 3787 // activities... move it up, but below the app that is binding to it. 3788 if (DEBUG_LRU) Slog.d(TAG_LRU, 3789 "Adding to second-top of LRU activity list: " + app 3790 + " group=" + psr.getConnectionGroup() 3791 + " importance=" + psr.getConnectionImportance()); 3792 int pos = N - 1; 3793 while (pos > mLruProcessActivityStart) { 3794 final ProcessRecord posproc = mLruProcesses.get(pos); 3795 if (posproc.info.uid == app.info.uid) { 3796 // Technically this app could have multiple processes with different 3797 // activities and so we should be looking for the actual process that 3798 // is bound to the target proc... but I don't really care, do you? 3799 break; 3800 } 3801 pos--; 3802 } 3803 mLruProcesses.add(pos, app); 3804 // If this process is part of a group, need to pull up any other processes 3805 // in that group to be with it. 3806 int endIndex = pos - 1; 3807 if (endIndex < mLruProcessActivityStart) { 3808 endIndex = mLruProcessActivityStart; 3809 } 3810 nextActivityIndex = endIndex; 3811 updateClientActivitiesOrderingLSP(app, pos, mLruProcessActivityStart, endIndex); 3812 } else { 3813 // Process has activities, put it at the very tipsy-top. 3814 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app); 3815 mLruProcesses.add(app); 3816 nextActivityIndex = mLruProcesses.size() - 1; 3817 } 3818 } else if (hasService) { 3819 // Process has services, put it at the top of the service list. 3820 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app); 3821 mLruProcesses.add(mLruProcessActivityStart, app); 3822 nextIndex = mLruProcessServiceStart; 3823 mLruProcessActivityStart++; 3824 } else { 3825 // Process not otherwise of interest, it goes to the top of the non-service area. 3826 int index = mLruProcessServiceStart; 3827 if (client != null) { 3828 // If there is a client, don't allow the process to be moved up higher 3829 // in the list than that client. 3830 int clientIndex = mLruProcesses.lastIndexOf(client); 3831 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client 3832 + " when updating " + app); 3833 if (clientIndex <= lrui) { 3834 // Don't allow the client index restriction to push it down farther in the 3835 // list than it already is. 3836 clientIndex = lrui; 3837 } 3838 if (clientIndex >= 0 && index > clientIndex) { 3839 index = clientIndex; 3840 } 3841 } 3842 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app); 3843 mLruProcesses.add(index, app); 3844 nextIndex = index - 1; 3845 mLruProcessActivityStart++; 3846 mLruProcessServiceStart++; 3847 if (index > 1) { 3848 updateClientActivitiesOrderingLSP(app, mLruProcessServiceStart - 1, 0, index - 1); 3849 } 3850 } 3851 3852 app.setLruSeq(mLruSeq); 3853 3854 // If the app is currently using a content provider or service, 3855 // bump those processes as well. 3856 for (int j = psr.numberOfConnections() - 1; j >= 0; j--) { 3857 ConnectionRecord cr = psr.getConnectionAt(j); 3858 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 3859 && cr.binding.service.app != null 3860 && cr.binding.service.app.getLruSeq() != mLruSeq 3861 && cr.notHasFlag(Context.BIND_REDUCTION_FLAGS) 3862 && !cr.binding.service.app.isPersistent()) { 3863 if (cr.binding.service.app.mServices.hasClientActivities()) { 3864 if (nextActivityIndex >= 0) { 3865 nextActivityIndex = updateLruProcessInternalLSP(cr.binding.service.app, 3866 now, 3867 nextActivityIndex, mLruSeq, 3868 "service connection", cr, app); 3869 } 3870 } else { 3871 nextIndex = updateLruProcessInternalLSP(cr.binding.service.app, 3872 now, 3873 nextIndex, mLruSeq, 3874 "service connection", cr, app); 3875 } 3876 } 3877 } 3878 final ProcessProviderRecord ppr = app.mProviders; 3879 for (int j = ppr.numberOfProviderConnections() - 1; j >= 0; j--) { 3880 ContentProviderRecord cpr = ppr.getProviderConnectionAt(j).provider; 3881 if (cpr.proc != null && cpr.proc.getLruSeq() != mLruSeq && !cpr.proc.isPersistent()) { 3882 nextIndex = updateLruProcessInternalLSP(cpr.proc, now, nextIndex, mLruSeq, 3883 "provider reference", cpr, app); 3884 } 3885 } 3886 } 3887 3888 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3889 ProcessRecord getLRURecordForAppLOSP(IApplicationThread thread) { 3890 if (thread == null) { 3891 return null; 3892 } 3893 return getLRURecordForAppLOSP(thread.asBinder()); 3894 } 3895 3896 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3897 ProcessRecord getLRURecordForAppLOSP(IBinder threadBinder) { 3898 if (threadBinder == null) { 3899 return null; 3900 } 3901 // Find the application record. 3902 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3903 final ProcessRecord rec = mLruProcesses.get(i); 3904 final IApplicationThread t = rec.getThread(); 3905 if (t != null && t.asBinder() == threadBinder) { 3906 return rec; 3907 } 3908 } 3909 return null; 3910 } 3911 3912 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3913 boolean haveBackgroundProcessLOSP() { 3914 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3915 final ProcessRecord rec = mLruProcesses.get(i); 3916 if (rec.getThread() != null 3917 && rec.mState.getSetProcState() >= PROCESS_STATE_CACHED_ACTIVITY) { 3918 return true; 3919 } 3920 } 3921 return false; 3922 } 3923 3924 private static int procStateToImportance(int procState, int memAdj, 3925 ActivityManager.RunningAppProcessInfo currApp, 3926 int clientTargetSdk) { 3927 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk( 3928 procState, clientTargetSdk); 3929 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 3930 currApp.lru = memAdj; 3931 } else { 3932 currApp.lru = 0; 3933 } 3934 return imp; 3935 } 3936 3937 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3938 void fillInProcMemInfoLOSP(ProcessRecord app, 3939 ActivityManager.RunningAppProcessInfo outInfo, 3940 int clientTargetSdk) { 3941 outInfo.pid = app.getPid(); 3942 outInfo.uid = app.info.uid; 3943 if (app.getWindowProcessController().isHeavyWeightProcess()) { 3944 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 3945 } 3946 if (app.isPersistent()) { 3947 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 3948 } 3949 if (app.hasActivities()) { 3950 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 3951 } 3952 outInfo.lastTrimLevel = app.mProfile.getTrimMemoryLevel(); 3953 final ProcessStateRecord state = app.mState; 3954 int adj = state.getCurAdj(); 3955 int procState = state.getCurProcState(); 3956 outInfo.importance = procStateToImportance(procState, adj, outInfo, 3957 clientTargetSdk); 3958 outInfo.importanceReasonCode = state.getAdjTypeCode(); 3959 outInfo.processState = procState; 3960 outInfo.isFocused = (app == mService.getTopApp()); 3961 outInfo.lastActivityTime = app.getLastActivityTime(); 3962 } 3963 3964 @GuardedBy(anyOf = {"mService", "mProcLock"}) 3965 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLOSP(boolean allUsers, 3966 int userId, boolean allUids, int callingUid, int clientTargetSdk) { 3967 // Lazy instantiation of list 3968 List<ActivityManager.RunningAppProcessInfo> runList = null; 3969 3970 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3971 ProcessRecord app = mLruProcesses.get(i); 3972 final ProcessStateRecord state = app.mState; 3973 final ProcessErrorStateRecord errState = app.mErrorState; 3974 if ((!allUsers && app.userId != userId) 3975 || (!allUids && app.uid != callingUid)) { 3976 continue; 3977 } 3978 if ((app.getThread() != null) 3979 && (!errState.isCrashing() && !errState.isNotResponding())) { 3980 // Generate process state info for running application 3981 ActivityManager.RunningAppProcessInfo currApp = 3982 new ActivityManager.RunningAppProcessInfo(app.processName, 3983 app.getPid(), app.getPackageList()); 3984 if (app.getPkgDeps() != null) { 3985 final int size = app.getPkgDeps().size(); 3986 currApp.pkgDeps = app.getPkgDeps().toArray(new String[size]); 3987 } 3988 fillInProcMemInfoLOSP(app, currApp, clientTargetSdk); 3989 if (state.getAdjSource() instanceof ProcessRecord) { 3990 currApp.importanceReasonPid = ((ProcessRecord) state.getAdjSource()).getPid(); 3991 currApp.importanceReasonImportance = 3992 ActivityManager.RunningAppProcessInfo.procStateToImportance( 3993 state.getAdjSourceProcState()); 3994 } else if (state.getAdjSource() instanceof ActivityServiceConnectionsHolder) { 3995 final ActivityServiceConnectionsHolder r = 3996 (ActivityServiceConnectionsHolder) state.getAdjSource(); 3997 final int pid = r.getActivityPid(); 3998 if (pid != -1) { 3999 currApp.importanceReasonPid = pid; 4000 } 4001 } 4002 if (state.getAdjTarget() instanceof ComponentName) { 4003 currApp.importanceReasonComponent = (ComponentName) state.getAdjTarget(); 4004 } 4005 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 4006 // + " lru=" + currApp.lru); 4007 if (runList == null) { 4008 runList = new ArrayList<>(); 4009 } 4010 runList.add(currApp); 4011 } 4012 } 4013 return runList; 4014 } 4015 4016 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4017 int getLruSizeLOSP() { 4018 return mLruProcesses.size(); 4019 } 4020 4021 /** 4022 * Return the reference to the LRU list, call this function for read-only access 4023 */ 4024 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4025 ArrayList<ProcessRecord> getLruProcessesLOSP() { 4026 return mLruProcesses; 4027 } 4028 4029 /** 4030 * Return the reference to the LRU list, call this function for read/write access 4031 */ 4032 @GuardedBy({"mService", "mProcLock"}) 4033 ArrayList<ProcessRecord> getLruProcessesLSP() { 4034 return mLruProcesses; 4035 } 4036 4037 /** 4038 * For test only 4039 */ 4040 @VisibleForTesting 4041 @GuardedBy({"mService", "mProcLock"}) 4042 void setLruProcessServiceStartLSP(int pos) { 4043 mLruProcessServiceStart = pos; 4044 } 4045 4046 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4047 int getLruProcessServiceStartLOSP() { 4048 return mLruProcessServiceStart; 4049 } 4050 4051 /** 4052 * Iterate the whole LRU list, invoke the given {@code callback} with each of the ProcessRecord 4053 * in that list. 4054 * 4055 * @param iterateForward If {@code true}, iterate the LRU list from the least recent used 4056 * to most recent used ProcessRecord. 4057 * @param callback The callback interface to accept the current ProcessRecord. 4058 */ 4059 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4060 void forEachLruProcessesLOSP(boolean iterateForward, 4061 @NonNull Consumer<ProcessRecord> callback) { 4062 if (iterateForward) { 4063 for (int i = 0, size = mLruProcesses.size(); i < size; i++) { 4064 callback.accept(mLruProcesses.get(i)); 4065 } 4066 } else { 4067 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4068 callback.accept(mLruProcesses.get(i)); 4069 } 4070 } 4071 } 4072 4073 /** 4074 * Search in the LRU list, invoke the given {@code callback} with each of the ProcessRecord 4075 * in that list; if the callback returns a non-null object, halt the search, return that 4076 * object as the return value of this search function. 4077 * 4078 * @param iterateForward If {@code true}, iterate the LRU list from the least recent used 4079 * to most recent used ProcessRecord. 4080 * @param callback The callback interface to accept the current ProcessRecord; if it returns 4081 * a non-null object, the search will be halted and this object will be used 4082 * as the return value of this search function. 4083 */ 4084 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4085 <R> R searchEachLruProcessesLOSP(boolean iterateForward, 4086 @NonNull Function<ProcessRecord, R> callback) { 4087 if (iterateForward) { 4088 for (int i = 0, size = mLruProcesses.size(); i < size; i++) { 4089 R r; 4090 if ((r = callback.apply(mLruProcesses.get(i))) != null) { 4091 return r; 4092 } 4093 } 4094 } else { 4095 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4096 R r; 4097 if ((r = callback.apply(mLruProcesses.get(i))) != null) { 4098 return r; 4099 } 4100 } 4101 } 4102 return null; 4103 } 4104 4105 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4106 boolean isInLruListLOSP(ProcessRecord app) { 4107 return mLruProcesses.contains(app); 4108 } 4109 4110 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4111 int getLruSeqLOSP() { 4112 return mLruSeq; 4113 } 4114 4115 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4116 MyProcessMap getProcessNamesLOSP() { 4117 return mProcessNames; 4118 } 4119 4120 @GuardedBy("mService") 4121 void dumpLruListHeaderLocked(PrintWriter pw) { 4122 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 4123 pw.print(" total, non-act at "); 4124 pw.print(mLruProcesses.size() - mLruProcessActivityStart); 4125 pw.print(", non-svc at "); 4126 pw.print(mLruProcesses.size() - mLruProcessServiceStart); 4127 pw.println("):"); 4128 } 4129 4130 @GuardedBy("mService") 4131 private void dumpLruEntryLocked(PrintWriter pw, int index, ProcessRecord proc, String prefix) { 4132 pw.print(prefix); 4133 pw.print('#'); 4134 if (index < 10) { 4135 pw.print(' '); 4136 } 4137 pw.print(index); 4138 pw.print(": "); 4139 pw.print(makeOomAdjString(proc.mState.getSetAdj(), false)); 4140 pw.print(' '); 4141 pw.print(makeProcStateString(proc.mState.getCurProcState())); 4142 pw.print(' '); 4143 ActivityManager.printCapabilitiesSummary(pw, proc.mState.getCurCapability()); 4144 pw.print(' '); 4145 pw.print(proc.toShortString()); 4146 final ProcessServiceRecord psr = proc.mServices; 4147 if (proc.hasActivitiesOrRecentTasks() || psr.hasClientActivities() 4148 || psr.isTreatedLikeActivity()) { 4149 pw.print(" act:"); 4150 boolean printed = false; 4151 if (proc.hasActivities()) { 4152 pw.print("activities"); 4153 printed = true; 4154 } 4155 if (proc.hasRecentTasks()) { 4156 if (printed) { 4157 pw.print("|"); 4158 } 4159 pw.print("recents"); 4160 printed = true; 4161 } 4162 if (psr.hasClientActivities()) { 4163 if (printed) { 4164 pw.print("|"); 4165 } 4166 pw.print("client"); 4167 printed = true; 4168 } 4169 if (psr.isTreatedLikeActivity()) { 4170 if (printed) { 4171 pw.print("|"); 4172 } 4173 pw.print("treated"); 4174 } 4175 } 4176 pw.println(); 4177 } 4178 4179 @GuardedBy("mService") 4180 boolean dumpLruLocked(PrintWriter pw, String dumpPackage, String prefix) { 4181 final int lruSize = mLruProcesses.size(); 4182 final String innerPrefix; 4183 if (prefix == null) { 4184 pw.println("ACTIVITY MANAGER LRU PROCESSES (dumpsys activity lru)"); 4185 innerPrefix = " "; 4186 } else { 4187 boolean haveAny = false; 4188 for (int i = lruSize - 1; i >= 0; i--) { 4189 final ProcessRecord r = mLruProcesses.get(i); 4190 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4191 continue; 4192 } 4193 haveAny = true; 4194 break; 4195 } 4196 if (!haveAny) { 4197 return false; 4198 } 4199 pw.print(prefix); 4200 pw.println("Raw LRU list (dumpsys activity lru):"); 4201 innerPrefix = prefix + " "; 4202 } 4203 int i; 4204 boolean first = true; 4205 for (i = lruSize - 1; i >= mLruProcessActivityStart; i--) { 4206 final ProcessRecord r = mLruProcesses.get(i); 4207 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4208 continue; 4209 } 4210 if (first) { 4211 pw.print(innerPrefix); 4212 pw.println("Activities:"); 4213 first = false; 4214 } 4215 dumpLruEntryLocked(pw, i, r, innerPrefix); 4216 } 4217 first = true; 4218 for (; i >= mLruProcessServiceStart; i--) { 4219 final ProcessRecord r = mLruProcesses.get(i); 4220 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4221 continue; 4222 } 4223 if (first) { 4224 pw.print(innerPrefix); 4225 pw.println("Services:"); 4226 first = false; 4227 } 4228 dumpLruEntryLocked(pw, i, r, innerPrefix); 4229 } 4230 first = true; 4231 for (; i >= 0; i--) { 4232 final ProcessRecord r = mLruProcesses.get(i); 4233 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4234 continue; 4235 } 4236 if (first) { 4237 pw.print(innerPrefix); 4238 pw.println("Other:"); 4239 first = false; 4240 } 4241 dumpLruEntryLocked(pw, i, r, innerPrefix); 4242 } 4243 return true; 4244 } 4245 4246 @GuardedBy({"mService", "mProcLock"}) 4247 void dumpProcessesLSP(FileDescriptor fd, PrintWriter pw, String[] args, 4248 int opti, boolean dumpAll, String dumpPackage, int dumpAppId) { 4249 boolean needSep = false; 4250 int numPers = 0; 4251 4252 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 4253 4254 if (dumpAll || dumpPackage != null) { 4255 final int numOfNames = mProcessNames.getMap().size(); 4256 for (int ip = 0; ip < numOfNames; ip++) { 4257 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 4258 for (int ia = 0, size = procs.size(); ia < size; ia++) { 4259 ProcessRecord r = procs.valueAt(ia); 4260 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4261 continue; 4262 } 4263 if (!needSep) { 4264 pw.println(" All known processes:"); 4265 needSep = true; 4266 } 4267 pw.print(r.isPersistent() ? " *PERS*" : " *APP*"); 4268 pw.print(" UID "); pw.print(procs.keyAt(ia)); 4269 pw.print(" "); pw.println(r); 4270 r.dump(pw, " "); 4271 if (r.isPersistent()) { 4272 numPers++; 4273 } 4274 } 4275 } 4276 } 4277 4278 if (mIsolatedProcesses.size() > 0) { 4279 boolean printed = false; 4280 for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) { 4281 ProcessRecord r = mIsolatedProcesses.valueAt(i); 4282 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4283 continue; 4284 } 4285 if (!printed) { 4286 if (needSep) { 4287 pw.println(); 4288 } 4289 pw.println(" Isolated process list (sorted by uid):"); 4290 printed = true; 4291 needSep = true; 4292 } 4293 pw.print(" Isolated #"); pw.print(i); pw.print(": "); 4294 pw.println(r); 4295 } 4296 } 4297 4298 needSep = mService.dumpActiveInstruments(pw, dumpPackage, needSep); 4299 4300 if (dumpOomLocked(fd, pw, needSep, args, opti, dumpAll, dumpPackage, false)) { 4301 needSep = true; 4302 } 4303 4304 if (mActiveUids.size() > 0) { 4305 needSep |= mActiveUids.dump(pw, dumpPackage, dumpAppId, 4306 "UID states:", needSep); 4307 } 4308 4309 if (dumpAll) { 4310 needSep |= mService.mUidObserverController.dumpValidateUids(pw, 4311 dumpPackage, dumpAppId, "UID validation:", needSep); 4312 } 4313 4314 if (needSep) { 4315 pw.println(); 4316 } 4317 if (dumpLruLocked(pw, dumpPackage, " ")) { 4318 needSep = true; 4319 } 4320 4321 if (getLruSizeLOSP() > 0) { 4322 if (needSep) { 4323 pw.println(); 4324 } 4325 dumpLruListHeaderLocked(pw); 4326 dumpProcessOomList(pw, mService, mLruProcesses, " ", "Proc", "PERS", false, 4327 dumpPackage); 4328 needSep = true; 4329 } 4330 4331 mService.dumpOtherProcessesInfoLSP(fd, pw, dumpAll, dumpPackage, dumpAppId, numPers, 4332 needSep); 4333 } 4334 4335 @GuardedBy({"mService", "mProcLock"}) 4336 void writeProcessesToProtoLSP(ProtoOutputStream proto, String dumpPackage) { 4337 int numPers = 0; 4338 4339 final int numOfNames = mProcessNames.getMap().size(); 4340 for (int ip = 0; ip < numOfNames; ip++) { 4341 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 4342 for (int ia = 0, size = procs.size(); ia < size; ia++) { 4343 ProcessRecord r = procs.valueAt(ia); 4344 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4345 continue; 4346 } 4347 r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.PROCS, 4348 mLruProcesses.indexOf(r) 4349 ); 4350 if (r.isPersistent()) { 4351 numPers++; 4352 } 4353 } 4354 } 4355 4356 for (int i = 0, size = mIsolatedProcesses.size(); i < size; i++) { 4357 ProcessRecord r = mIsolatedProcesses.valueAt(i); 4358 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4359 continue; 4360 } 4361 r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS, 4362 mLruProcesses.indexOf(r) 4363 ); 4364 } 4365 4366 final int dumpAppId = mService.getAppId(dumpPackage); 4367 mActiveUids.dumpProto(proto, dumpPackage, dumpAppId, 4368 ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS); 4369 4370 if (getLruSizeLOSP() > 0) { 4371 long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS); 4372 int total = getLruSizeLOSP(); 4373 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total); 4374 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, 4375 total - mLruProcessActivityStart); 4376 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, 4377 total - mLruProcessServiceStart); 4378 writeProcessOomListToProto(proto, 4379 ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, mService, 4380 mLruProcesses, true, dumpPackage); 4381 proto.end(lruToken); 4382 } 4383 4384 mService.writeOtherProcessesInfoToProtoLSP(proto, dumpPackage, dumpAppId, numPers); 4385 } 4386 4387 private static ArrayList<Pair<ProcessRecord, Integer>> sortProcessOomList( 4388 List<ProcessRecord> origList, String dumpPackage) { 4389 ArrayList<Pair<ProcessRecord, Integer>> list = 4390 new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 4391 for (int i = 0, size = origList.size(); i < size; i++) { 4392 ProcessRecord r = origList.get(i); 4393 if (dumpPackage != null && !r.getPkgList().containsKey(dumpPackage)) { 4394 continue; 4395 } 4396 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 4397 } 4398 4399 Comparator<Pair<ProcessRecord, Integer>> comparator = 4400 new Comparator<Pair<ProcessRecord, Integer>>() { 4401 @Override 4402 public int compare(Pair<ProcessRecord, Integer> object1, 4403 Pair<ProcessRecord, Integer> object2) { 4404 final int adj = object2.first.mState.getSetAdj() - object1.first.mState.getSetAdj(); 4405 if (adj != 0) { 4406 return adj; 4407 } 4408 final int procState = object2.first.mState.getSetProcState() 4409 - object1.first.mState.getSetProcState(); 4410 if (procState != 0) { 4411 return procState; 4412 } 4413 final int val = object2.second - object1.second; 4414 if (val != 0) { 4415 return val; 4416 } 4417 return 0; 4418 } 4419 }; 4420 4421 Collections.sort(list, comparator); 4422 return list; 4423 } 4424 4425 private static boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId, 4426 ActivityManagerService service, List<ProcessRecord> origList, 4427 boolean inclDetails, String dumpPackage) { 4428 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage); 4429 if (list.isEmpty()) return false; 4430 4431 final long curUptime = SystemClock.uptimeMillis(); 4432 4433 for (int i = list.size() - 1; i >= 0; i--) { 4434 ProcessRecord r = list.get(i).first; 4435 final ProcessStateRecord state = r.mState; 4436 final ProcessServiceRecord psr = r.mServices; 4437 long token = proto.start(fieldId); 4438 String oomAdj = makeOomAdjString(state.getSetAdj(), true); 4439 proto.write(ProcessOomProto.PERSISTENT, r.isPersistent()); 4440 proto.write(ProcessOomProto.NUM, (origList.size() - 1) - list.get(i).second); 4441 proto.write(ProcessOomProto.OOM_ADJ, oomAdj); 4442 int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN; 4443 switch (state.getSetSchedGroup()) { 4444 case SCHED_GROUP_BACKGROUND: 4445 schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND; 4446 break; 4447 case SCHED_GROUP_DEFAULT: 4448 schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT; 4449 break; 4450 case SCHED_GROUP_TOP_APP: 4451 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP; 4452 break; 4453 case SCHED_GROUP_TOP_APP_BOUND: 4454 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND; 4455 break; 4456 } 4457 if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) { 4458 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup); 4459 } 4460 if (state.hasForegroundActivities()) { 4461 proto.write(ProcessOomProto.ACTIVITIES, true); 4462 } else if (psr.hasForegroundServices()) { 4463 proto.write(ProcessOomProto.SERVICES, true); 4464 } 4465 proto.write(ProcessOomProto.STATE, 4466 makeProcStateProtoEnum(state.getCurProcState())); 4467 proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.mProfile.getTrimMemoryLevel()); 4468 r.dumpDebug(proto, ProcessOomProto.PROC); 4469 proto.write(ProcessOomProto.ADJ_TYPE, state.getAdjType()); 4470 if (state.getAdjSource() != null || state.getAdjTarget() != null) { 4471 if (state.getAdjTarget() instanceof ComponentName) { 4472 ComponentName cn = (ComponentName) state.getAdjTarget(); 4473 cn.dumpDebug(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME); 4474 } else if (state.getAdjTarget() != null) { 4475 proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, state.getAdjTarget().toString()); 4476 } 4477 if (state.getAdjSource() instanceof ProcessRecord) { 4478 ProcessRecord p = (ProcessRecord) state.getAdjSource(); 4479 p.dumpDebug(proto, ProcessOomProto.ADJ_SOURCE_PROC); 4480 } else if (state.getAdjSource() != null) { 4481 proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, state.getAdjSource().toString()); 4482 } 4483 } 4484 if (inclDetails) { 4485 long detailToken = proto.start(ProcessOomProto.DETAIL); 4486 proto.write(ProcessOomProto.Detail.MAX_ADJ, state.getMaxAdj()); 4487 proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, state.getCurRawAdj()); 4488 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, state.getSetRawAdj()); 4489 proto.write(ProcessOomProto.Detail.CUR_ADJ, state.getCurAdj()); 4490 proto.write(ProcessOomProto.Detail.SET_ADJ, state.getSetAdj()); 4491 proto.write(ProcessOomProto.Detail.CURRENT_STATE, 4492 makeProcStateProtoEnum(state.getCurProcState())); 4493 proto.write(ProcessOomProto.Detail.SET_STATE, 4494 makeProcStateProtoEnum(state.getSetProcState())); 4495 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString( 4496 r.mProfile.getLastPss() * 1024, new StringBuilder())); 4497 proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString( 4498 r.mProfile.getLastSwapPss() * 1024, new StringBuilder())); 4499 proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString( 4500 r.mProfile.getLastCachedPss() * 1024, new StringBuilder())); 4501 proto.write(ProcessOomProto.Detail.CACHED, state.isCached()); 4502 proto.write(ProcessOomProto.Detail.EMPTY, state.isEmpty()); 4503 proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, psr.hasAboveClient()); 4504 4505 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) { 4506 long lastCpuTime = r.mProfile.mLastCpuTime.get(); 4507 long uptimeSince = curUptime - service.mLastPowerCheckUptime; 4508 if (lastCpuTime != 0 && uptimeSince > 0) { 4509 long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime; 4510 long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME); 4511 proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince); 4512 proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed); 4513 proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION, 4514 (100.0 * timeUsed) / uptimeSince); 4515 proto.end(cpuTimeToken); 4516 } 4517 } 4518 proto.end(detailToken); 4519 } 4520 proto.end(token); 4521 } 4522 4523 return true; 4524 } 4525 4526 private static boolean dumpProcessOomList(PrintWriter pw, 4527 ActivityManagerService service, List<ProcessRecord> origList, 4528 String prefix, String normalLabel, String persistentLabel, 4529 boolean inclDetails, String dumpPackage) { 4530 4531 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage); 4532 if (list.isEmpty()) return false; 4533 4534 final long curUptime = SystemClock.uptimeMillis(); 4535 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 4536 4537 for (int i = list.size() - 1; i >= 0; i--) { 4538 ProcessRecord r = list.get(i).first; 4539 final ProcessStateRecord state = r.mState; 4540 final ProcessServiceRecord psr = r.mServices; 4541 String oomAdj = makeOomAdjString(state.getSetAdj(), false); 4542 char schedGroup; 4543 switch (state.getSetSchedGroup()) { 4544 case SCHED_GROUP_BACKGROUND: 4545 schedGroup = 'b'; 4546 break; 4547 case SCHED_GROUP_DEFAULT: 4548 schedGroup = 'F'; 4549 break; 4550 case SCHED_GROUP_TOP_APP: 4551 schedGroup = 'T'; 4552 break; 4553 case SCHED_GROUP_RESTRICTED: 4554 schedGroup = 'R'; 4555 break; 4556 case SCHED_GROUP_TOP_APP_BOUND: 4557 schedGroup = 'B'; 4558 break; 4559 default: 4560 schedGroup = '?'; 4561 break; 4562 } 4563 char foreground; 4564 if (state.hasForegroundActivities()) { 4565 foreground = 'A'; 4566 } else if (psr.hasForegroundServices()) { 4567 foreground = 'S'; 4568 } else { 4569 foreground = ' '; 4570 } 4571 String procState = makeProcStateString(state.getCurProcState()); 4572 pw.print(prefix); 4573 pw.print(r.isPersistent() ? persistentLabel : normalLabel); 4574 pw.print(" #"); 4575 int num = (origList.size() - 1) - list.get(i).second; 4576 if (num < 10) pw.print(' '); 4577 pw.print(num); 4578 pw.print(": "); 4579 pw.print(oomAdj); 4580 pw.print(' '); 4581 pw.print(schedGroup); 4582 pw.print('/'); 4583 pw.print(foreground); 4584 pw.print('/'); 4585 pw.print(procState); 4586 pw.print(' '); 4587 ActivityManager.printCapabilitiesSummary(pw, state.getCurCapability()); 4588 pw.print(' '); 4589 pw.print(" t:"); 4590 if (r.mProfile.getTrimMemoryLevel() < 10) pw.print(' '); 4591 pw.print(r.mProfile.getTrimMemoryLevel()); 4592 pw.print(' '); 4593 pw.print(r.toShortString()); 4594 pw.print(" ("); 4595 pw.print(state.getAdjType()); 4596 pw.println(')'); 4597 if (state.getAdjSource() != null || state.getAdjTarget() != null) { 4598 pw.print(prefix); 4599 pw.print(" "); 4600 if (state.getAdjTarget() instanceof ComponentName) { 4601 pw.print(((ComponentName) state.getAdjTarget()).flattenToShortString()); 4602 } else if (state.getAdjTarget() != null) { 4603 pw.print(state.getAdjTarget().toString()); 4604 } else { 4605 pw.print("{null}"); 4606 } 4607 pw.print("<="); 4608 if (state.getAdjSource() instanceof ProcessRecord) { 4609 pw.print("Proc{"); 4610 pw.print(((ProcessRecord) state.getAdjSource()).toShortString()); 4611 pw.println("}"); 4612 } else if (state.getAdjSource() != null) { 4613 pw.println(state.getAdjSource().toString()); 4614 } else { 4615 pw.println("{null}"); 4616 } 4617 } 4618 if (inclDetails) { 4619 pw.print(prefix); 4620 pw.print(" "); 4621 pw.print("oom: max="); pw.print(state.getMaxAdj()); 4622 pw.print(" curRaw="); pw.print(state.getCurRawAdj()); 4623 pw.print(" setRaw="); pw.print(state.getSetRawAdj()); 4624 pw.print(" cur="); pw.print(state.getCurAdj()); 4625 pw.print(" set="); pw.println(state.getSetAdj()); 4626 pw.print(prefix); 4627 pw.print(" "); 4628 pw.print("state: cur="); pw.print(makeProcStateString(state.getCurProcState())); 4629 pw.print(" set="); pw.print(makeProcStateString(state.getSetProcState())); 4630 pw.print(" lastPss="); 4631 DebugUtils.printSizeValue(pw, r.mProfile.getLastPss() * 1024); 4632 pw.print(" lastSwapPss="); 4633 DebugUtils.printSizeValue(pw, r.mProfile.getLastSwapPss() * 1024); 4634 pw.print(" lastCachedPss="); 4635 DebugUtils.printSizeValue(pw, r.mProfile.getLastCachedPss() * 1024); 4636 pw.println(); 4637 pw.print(prefix); 4638 pw.print(" "); 4639 pw.print("cached="); pw.print(state.isCached()); 4640 pw.print(" empty="); pw.print(state.isEmpty()); 4641 pw.print(" hasAboveClient="); pw.println(psr.hasAboveClient()); 4642 4643 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) { 4644 long lastCpuTime = r.mProfile.mLastCpuTime.get(); 4645 if (lastCpuTime != 0 && uptimeSince > 0) { 4646 long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime; 4647 pw.print(prefix); 4648 pw.print(" "); 4649 pw.print("run cpu over "); 4650 TimeUtils.formatDuration(uptimeSince, pw); 4651 pw.print(" used "); 4652 TimeUtils.formatDuration(timeUsed, pw); 4653 pw.print(" ("); 4654 pw.print((timeUsed * 100) / uptimeSince); 4655 pw.println("%)"); 4656 } 4657 } 4658 } 4659 } 4660 return true; 4661 } 4662 4663 private void printOomLevel(PrintWriter pw, String name, int adj) { 4664 pw.print(" "); 4665 if (adj >= 0) { 4666 pw.print(' '); 4667 if (adj < 10) pw.print(' '); 4668 } else { 4669 if (adj > -10) pw.print(' '); 4670 } 4671 pw.print(adj); 4672 pw.print(": "); 4673 pw.print(name); 4674 pw.print(" ("); 4675 pw.print(ActivityManagerService.stringifySize(getMemLevel(adj), 1024)); 4676 pw.println(")"); 4677 } 4678 4679 @GuardedBy("mService") 4680 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String[] args, 4681 int opti, boolean dumpAll, String dumpPackage, boolean inclGc) { 4682 if (getLruSizeLOSP() > 0) { 4683 if (needSep) pw.println(); 4684 needSep = true; 4685 pw.println(" OOM levels:"); 4686 printOomLevel(pw, "SYSTEM_ADJ", SYSTEM_ADJ); 4687 printOomLevel(pw, "PERSISTENT_PROC_ADJ", PERSISTENT_PROC_ADJ); 4688 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", PERSISTENT_SERVICE_ADJ); 4689 printOomLevel(pw, "FOREGROUND_APP_ADJ", FOREGROUND_APP_ADJ); 4690 printOomLevel(pw, "VISIBLE_APP_ADJ", VISIBLE_APP_ADJ); 4691 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", PERCEPTIBLE_APP_ADJ); 4692 printOomLevel(pw, "PERCEPTIBLE_MEDIUM_APP_ADJ", PERCEPTIBLE_MEDIUM_APP_ADJ); 4693 printOomLevel(pw, "PERCEPTIBLE_LOW_APP_ADJ", PERCEPTIBLE_LOW_APP_ADJ); 4694 printOomLevel(pw, "BACKUP_APP_ADJ", BACKUP_APP_ADJ); 4695 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", HEAVY_WEIGHT_APP_ADJ); 4696 printOomLevel(pw, "SERVICE_ADJ", SERVICE_ADJ); 4697 printOomLevel(pw, "HOME_APP_ADJ", HOME_APP_ADJ); 4698 printOomLevel(pw, "PREVIOUS_APP_ADJ", PREVIOUS_APP_ADJ); 4699 printOomLevel(pw, "SERVICE_B_ADJ", SERVICE_B_ADJ); 4700 printOomLevel(pw, "CACHED_APP_MIN_ADJ", CACHED_APP_MIN_ADJ); 4701 printOomLevel(pw, "CACHED_APP_MAX_ADJ", CACHED_APP_MAX_ADJ); 4702 4703 if (needSep) pw.println(); 4704 pw.print(" Process OOM control ("); pw.print(getLruSizeLOSP()); 4705 pw.print(" total, non-act at "); 4706 pw.print(getLruSizeLOSP() - mLruProcessActivityStart); 4707 pw.print(", non-svc at "); 4708 pw.print(getLruSizeLOSP() - mLruProcessServiceStart); 4709 pw.println("):"); 4710 dumpProcessOomList(pw, mService, mLruProcesses, 4711 " ", "Proc", "PERS", true, dumpPackage); 4712 needSep = true; 4713 } 4714 4715 synchronized (mService.mAppProfiler.mProfilerLock) { 4716 mService.mAppProfiler.dumpProcessesToGc(pw, needSep, dumpPackage); 4717 } 4718 4719 pw.println(); 4720 mService.mAtmInternal.dumpForOom(pw); 4721 4722 return true; 4723 } 4724 4725 void registerProcessObserver(IProcessObserver observer) { 4726 mProcessObservers.register(observer); 4727 } 4728 4729 void unregisterProcessObserver(IProcessObserver observer) { 4730 mProcessObservers.unregister(observer); 4731 } 4732 4733 void dispatchProcessesChanged() { 4734 int numOfChanges; 4735 synchronized (mProcessChangeLock) { 4736 numOfChanges = mPendingProcessChanges.size(); 4737 if (mActiveProcessChanges.length < numOfChanges) { 4738 mActiveProcessChanges = new ProcessChangeItem[numOfChanges]; 4739 } 4740 mPendingProcessChanges.toArray(mActiveProcessChanges); 4741 mPendingProcessChanges.clear(); 4742 if (DEBUG_PROCESS_OBSERVERS) { 4743 Slog.i(TAG_PROCESS_OBSERVERS, 4744 "*** Delivering " + numOfChanges + " process changes"); 4745 } 4746 } 4747 4748 int i = mProcessObservers.beginBroadcast(); 4749 while (i > 0) { 4750 i--; 4751 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 4752 if (observer != null) { 4753 try { 4754 for (int j = 0; j < numOfChanges; j++) { 4755 ProcessChangeItem item = mActiveProcessChanges[j]; 4756 if ((item.changes & ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 4757 if (DEBUG_PROCESS_OBSERVERS) { 4758 Slog.i(TAG_PROCESS_OBSERVERS, 4759 "ACTIVITIES CHANGED pid=" + item.pid + " uid=" 4760 + item.uid + ": " + item.foregroundActivities); 4761 } 4762 observer.onForegroundActivitiesChanged(item.pid, item.uid, 4763 item.foregroundActivities); 4764 } 4765 if ((item.changes & ProcessChangeItem.CHANGE_FOREGROUND_SERVICES) != 0) { 4766 if (DEBUG_PROCESS_OBSERVERS) { 4767 Slog.i(TAG_PROCESS_OBSERVERS, 4768 "FOREGROUND SERVICES CHANGED pid=" + item.pid + " uid=" 4769 + item.uid + ": " + item.foregroundServiceTypes); 4770 } 4771 observer.onForegroundServicesChanged(item.pid, item.uid, 4772 item.foregroundServiceTypes); 4773 } 4774 } 4775 } catch (RemoteException e) { 4776 } 4777 } 4778 } 4779 mProcessObservers.finishBroadcast(); 4780 4781 synchronized (mProcessChangeLock) { 4782 for (int j = 0; j < numOfChanges; j++) { 4783 mAvailProcessChanges.add(mActiveProcessChanges[j]); 4784 } 4785 } 4786 } 4787 4788 @GuardedBy("mService") 4789 ProcessChangeItem enqueueProcessChangeItemLocked(int pid, int uid) { 4790 synchronized (mProcessChangeLock) { 4791 int i = mPendingProcessChanges.size() - 1; 4792 ActivityManagerService.ProcessChangeItem item = null; 4793 while (i >= 0) { 4794 item = mPendingProcessChanges.get(i); 4795 if (item.pid == pid) { 4796 if (DEBUG_PROCESS_OBSERVERS) { 4797 Slog.i(TAG_PROCESS_OBSERVERS, "Re-using existing item: " + item); 4798 } 4799 break; 4800 } 4801 i--; 4802 } 4803 4804 if (i < 0) { 4805 // No existing item in pending changes; need a new one. 4806 final int num = mAvailProcessChanges.size(); 4807 if (num > 0) { 4808 item = mAvailProcessChanges.remove(num - 1); 4809 if (DEBUG_PROCESS_OBSERVERS) { 4810 Slog.i(TAG_PROCESS_OBSERVERS, "Retrieving available item: " + item); 4811 } 4812 } else { 4813 item = new ActivityManagerService.ProcessChangeItem(); 4814 if (DEBUG_PROCESS_OBSERVERS) { 4815 Slog.i(TAG_PROCESS_OBSERVERS, "Allocating new item: " + item); 4816 } 4817 } 4818 item.changes = 0; 4819 item.pid = pid; 4820 item.uid = uid; 4821 if (mPendingProcessChanges.size() == 0) { 4822 if (DEBUG_PROCESS_OBSERVERS) { 4823 Slog.i(TAG_PROCESS_OBSERVERS, "*** Enqueueing dispatch processes changed!"); 4824 } 4825 mService.mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG) 4826 .sendToTarget(); 4827 } 4828 mPendingProcessChanges.add(item); 4829 } 4830 4831 return item; 4832 } 4833 } 4834 4835 @GuardedBy("mService") 4836 void scheduleDispatchProcessDiedLocked(int pid, int uid) { 4837 synchronized (mProcessChangeLock) { 4838 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) { 4839 ProcessChangeItem item = mPendingProcessChanges.get(i); 4840 if (pid > 0 && item.pid == pid) { 4841 mPendingProcessChanges.remove(i); 4842 mAvailProcessChanges.add(item); 4843 } 4844 } 4845 mService.mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, pid, uid, 4846 null).sendToTarget(); 4847 } 4848 } 4849 4850 void dispatchProcessDied(int pid, int uid) { 4851 int i = mProcessObservers.beginBroadcast(); 4852 while (i > 0) { 4853 i--; 4854 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 4855 if (observer != null) { 4856 try { 4857 observer.onProcessDied(pid, uid); 4858 } catch (RemoteException e) { 4859 } 4860 } 4861 } 4862 mProcessObservers.finishBroadcast(); 4863 } 4864 4865 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4866 ArrayList<ProcessRecord> collectProcessesLOSP(int start, boolean allPkgs, String[] args) { 4867 ArrayList<ProcessRecord> procs; 4868 if (args != null && args.length > start 4869 && args[start].charAt(0) != '-') { 4870 procs = new ArrayList<ProcessRecord>(); 4871 int pid = -1; 4872 try { 4873 pid = Integer.parseInt(args[start]); 4874 } catch (NumberFormatException e) { 4875 } 4876 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4877 ProcessRecord proc = mLruProcesses.get(i); 4878 if (proc.getPid() > 0 && proc.getPid() == pid) { 4879 procs.add(proc); 4880 } else if (allPkgs && proc.getPkgList() != null 4881 && proc.getPkgList().containsKey(args[start])) { 4882 procs.add(proc); 4883 } else if (proc.processName.equals(args[start])) { 4884 procs.add(proc); 4885 } 4886 } 4887 if (procs.size() <= 0) { 4888 return null; 4889 } 4890 } else { 4891 procs = new ArrayList<ProcessRecord>(mLruProcesses); 4892 } 4893 return procs; 4894 } 4895 4896 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4897 void updateApplicationInfoLOSP(List<String> packagesToUpdate, int userId, 4898 boolean updateFrameworkRes) { 4899 final ArrayList<WindowProcessController> targetProcesses = new ArrayList<>(); 4900 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4901 final ProcessRecord app = mLruProcesses.get(i); 4902 if (app.getThread() == null) { 4903 continue; 4904 } 4905 4906 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4907 continue; 4908 } 4909 4910 app.getPkgList().forEachPackage(packageName -> { 4911 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) { 4912 try { 4913 final ApplicationInfo ai = AppGlobals.getPackageManager() 4914 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId); 4915 if (ai != null) { 4916 if (ai.packageName.equals(app.info.packageName)) { 4917 app.info = ai; 4918 PlatformCompatCache.getInstance() 4919 .onApplicationInfoChanged(ai); 4920 } 4921 app.getThread().scheduleApplicationInfoChanged(ai); 4922 targetProcesses.add(app.getWindowProcessController()); 4923 } 4924 } catch (RemoteException e) { 4925 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", 4926 packageName, app)); 4927 } 4928 } 4929 }); 4930 } 4931 4932 mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes); 4933 } 4934 4935 @GuardedBy("mService") 4936 void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 4937 boolean foundProcess = false; 4938 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4939 ProcessRecord r = mLruProcesses.get(i); 4940 final IApplicationThread thread = r.getThread(); 4941 if (thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 4942 try { 4943 for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) { 4944 if (packages[index].equals(r.info.packageName)) { 4945 foundProcess = true; 4946 } 4947 } 4948 thread.dispatchPackageBroadcast(cmd, packages); 4949 } catch (RemoteException ex) { 4950 } 4951 } 4952 } 4953 4954 if (!foundProcess) { 4955 try { 4956 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages); 4957 } catch (RemoteException ignored) { 4958 } 4959 } 4960 } 4961 4962 /** 4963 * Returns the uid's process state or {@link ActivityManager#PROCESS_STATE_NONEXISTENT} 4964 * if not running 4965 */ 4966 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4967 int getUidProcStateLOSP(int uid) { 4968 UidRecord uidRec = mActiveUids.get(uid); 4969 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState(); 4970 } 4971 4972 /** 4973 * Returns the uid's process capability or {@link ActivityManager#PROCESS_CAPABILITY_NONE} 4974 * if not running 4975 */ 4976 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4977 @ProcessCapability int getUidProcessCapabilityLOSP(int uid) { 4978 UidRecord uidRec = mActiveUids.get(uid); 4979 return uidRec == null ? PROCESS_CAPABILITY_NONE : uidRec.getCurCapability(); 4980 } 4981 4982 /** Returns the UidRecord for the given uid, if it exists. */ 4983 @GuardedBy(anyOf = {"mService", "mProcLock"}) 4984 UidRecord getUidRecordLOSP(int uid) { 4985 return mActiveUids.get(uid); 4986 } 4987 4988 /** 4989 * Call {@link ActivityManagerService#doStopUidLocked} 4990 * (which will also stop background services) for all idle UIDs. 4991 */ 4992 @GuardedBy("mService") 4993 void doStopUidForIdleUidsLocked() { 4994 final int size = mActiveUids.size(); 4995 for (int i = 0; i < size; i++) { 4996 final int uid = mActiveUids.keyAt(i); 4997 if (UserHandle.isCore(uid)) { 4998 continue; 4999 } 5000 final UidRecord uidRec = mActiveUids.valueAt(i); 5001 if (!uidRec.isIdle()) { 5002 continue; 5003 } 5004 mService.doStopUidLocked(uidRec.getUid(), uidRec); 5005 } 5006 } 5007 5008 /** 5009 * Checks if the uid is coming from background to foreground or vice versa and returns 5010 * appropriate block state based on this. 5011 * 5012 * @return blockState based on whether the uid is coming from background to foreground or 5013 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or 5014 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise 5015 * {@link #NETWORK_STATE_NO_CHANGE}. 5016 */ 5017 @VisibleForTesting 5018 @GuardedBy(anyOf = {"mService", "mProcLock"}) 5019 int getBlockStateForUid(UidRecord uidRec) { 5020 // Denotes whether uid's process state is currently allowed network access. 5021 final boolean isAllowed = 5022 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState(), 5023 uidRec.getCurCapability()) 5024 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState(), 5025 uidRec.getCurCapability()); 5026 // Denotes whether uid's process state was previously allowed network access. 5027 final boolean wasAllowed = 5028 isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getSetProcState(), 5029 uidRec.getSetCapability()) 5030 || isProcStateAllowedWhileOnRestrictBackground(uidRec.getSetProcState(), 5031 uidRec.getSetCapability()); 5032 5033 // When the uid is coming to foreground, AMS should inform the app thread that it should 5034 // block for the network rules to get updated before launching an activity. 5035 if (!wasAllowed && isAllowed) { 5036 return NETWORK_STATE_BLOCK; 5037 } 5038 // When the uid is going to background, AMS should inform the app thread that if an 5039 // activity launch is blocked for the network rules to get updated, it should be unblocked. 5040 if (wasAllowed && !isAllowed) { 5041 return NETWORK_STATE_UNBLOCK; 5042 } 5043 return NETWORK_STATE_NO_CHANGE; 5044 } 5045 5046 /** 5047 * Increments the {@link UidRecord#curProcStateSeq} for all uids using global seq counter 5048 * {@link ProcessList#mProcStateSeqCounter} and checks if any uid is coming 5049 * from background to foreground or vice versa and if so, notifies the app if it needs to block. 5050 */ 5051 @VisibleForTesting 5052 @GuardedBy(anyOf = {"mService", "mProcLock"}) 5053 void incrementProcStateSeqAndNotifyAppsLOSP(ActiveUids activeUids) { 5054 for (int i = activeUids.size() - 1; i >= 0; --i) { 5055 final UidRecord uidRec = activeUids.valueAt(i); 5056 uidRec.curProcStateSeq = getNextProcStateSeq(); 5057 } 5058 if (mService.mConstants.mNetworkAccessTimeoutMs <= 0) { 5059 return; 5060 } 5061 // Used for identifying which uids need to block for network. 5062 ArrayList<Integer> blockingUids = null; 5063 for (int i = activeUids.size() - 1; i >= 0; --i) { 5064 final UidRecord uidRec = activeUids.valueAt(i); 5065 // If the network is not restricted for uid, then nothing to do here. 5066 if (!mService.mInjector.isNetworkRestrictedForUid(uidRec.getUid())) { 5067 continue; 5068 } 5069 if (!UserHandle.isApp(uidRec.getUid()) || !uidRec.hasInternetPermission) { 5070 continue; 5071 } 5072 // If process state and capabilities are not changed, then there's nothing to do. 5073 if (uidRec.getSetProcState() == uidRec.getCurProcState() 5074 && uidRec.getSetCapability() == uidRec.getCurCapability()) { 5075 continue; 5076 } 5077 final int blockState = getBlockStateForUid(uidRec); 5078 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as 5079 // there's nothing the app needs to do in this scenario. 5080 if (blockState == NETWORK_STATE_NO_CHANGE) { 5081 continue; 5082 } 5083 synchronized (uidRec.networkStateLock) { 5084 if (blockState == NETWORK_STATE_BLOCK) { 5085 if (blockingUids == null) { 5086 blockingUids = new ArrayList<>(); 5087 } 5088 blockingUids.add(uidRec.getUid()); 5089 } else { 5090 if (DEBUG_NETWORK) { 5091 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking" 5092 + " threads for uid: " + uidRec); 5093 } 5094 if (uidRec.procStateSeqWaitingForNetwork != 0) { 5095 uidRec.networkStateLock.notifyAll(); 5096 } 5097 } 5098 } 5099 } 5100 5101 // There are no uids that need to block, so nothing more to do. 5102 if (blockingUids == null) { 5103 return; 5104 } 5105 5106 for (int i = mLruProcesses.size() - 1; i >= 0; --i) { 5107 final ProcessRecord app = mLruProcesses.get(i); 5108 if (!blockingUids.contains(app.uid)) { 5109 continue; 5110 } 5111 final IApplicationThread thread = app.getThread(); 5112 if (!app.isKilledByAm() && thread != null) { 5113 final UidRecord uidRec = getUidRecordLOSP(app.uid); 5114 try { 5115 if (DEBUG_NETWORK) { 5116 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: " 5117 + uidRec); 5118 } 5119 if (uidRec != null) { 5120 thread.setNetworkBlockSeq(uidRec.curProcStateSeq); 5121 } 5122 } catch (RemoteException ignored) { 5123 } 5124 } 5125 } 5126 } 5127 5128 long getNextProcStateSeq() { 5129 return ++mProcStateSeqCounter; 5130 } 5131 5132 /** 5133 * Create a server socket in system_server, zygote will connect to it 5134 * in order to send unsolicited messages to system_server. 5135 */ 5136 private LocalSocket createSystemServerSocketForZygote() { 5137 // The file system entity for this socket is created with 0666 perms, owned 5138 // by system:system. selinux restricts things so that only zygotes can 5139 // access it. 5140 final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH); 5141 if (socketFile.exists()) { 5142 socketFile.delete(); 5143 } 5144 5145 LocalSocket serverSocket = null; 5146 try { 5147 serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM); 5148 serverSocket.bind(new LocalSocketAddress( 5149 UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM)); 5150 Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666); 5151 } catch (Exception e) { 5152 if (serverSocket != null) { 5153 try { 5154 serverSocket.close(); 5155 } catch (IOException ex) { 5156 } 5157 serverSocket = null; 5158 } 5159 } 5160 return serverSocket; 5161 } 5162 5163 /** 5164 * Handle the unsolicited message from zygote. 5165 */ 5166 private int handleZygoteMessages(FileDescriptor fd, int events) { 5167 final int eventFd = fd.getInt$(); 5168 if ((events & EVENT_INPUT) != 0) { 5169 // An incoming message from zygote 5170 try { 5171 final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0, 5172 mZygoteUnsolicitedMessage.length); 5173 if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld( 5174 mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) { 5175 mAppExitInfoTracker.handleZygoteSigChld( 5176 mZygoteSigChldMessage[0] /* pid */, 5177 mZygoteSigChldMessage[1] /* uid */, 5178 mZygoteSigChldMessage[2] /* status */); 5179 } 5180 } catch (Exception e) { 5181 Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e); 5182 } 5183 } 5184 return EVENT_INPUT; 5185 } 5186 5187 /** 5188 * Handle the death notification if it's a dying app. 5189 * 5190 * @return {@code true} if it's a dying app that we were tracking. 5191 */ 5192 @GuardedBy("mService") 5193 boolean handleDyingAppDeathLocked(ProcessRecord app, int pid) { 5194 if (mProcessNames.get(app.processName, app.uid) != app 5195 && mDyingProcesses.get(app.processName, app.uid) == app) { 5196 // App has been removed already, meaning cleanup has done. 5197 Slog.v(TAG, "Got obituary of " + pid + ":" + app.processName); 5198 app.unlinkDeathRecipient(); 5199 // It's really gone now, let's remove from the dying process list. 5200 mDyingProcesses.remove(app.processName, app.uid); 5201 app.setDyingPid(0); 5202 handlePrecedingAppDiedLocked(app); 5203 // Remove from the LRU list if it's still there. 5204 removeLruProcessLocked(app); 5205 return true; 5206 } 5207 return false; 5208 } 5209 5210 /** 5211 * Handle the case where the given app is a preceding instance of another process instance. 5212 * 5213 * @return {@code false} if this given app should not be allowed to restart. 5214 */ 5215 @GuardedBy("mService") 5216 boolean handlePrecedingAppDiedLocked(ProcessRecord app) { 5217 if (app.mSuccessor != null) { 5218 // We don't allow restart with this ProcessRecord now, 5219 // because we have created a new one already. 5220 // If it's persistent, add the successor to mPersistentStartingProcesses 5221 if (app.isPersistent() && !app.isRemoved()) { 5222 if (mService.mPersistentStartingProcesses.indexOf(app.mSuccessor) < 0) { 5223 mService.mPersistentStartingProcesses.add(app.mSuccessor); 5224 } 5225 } 5226 // clean up the field so the successor's proc starter could proceed. 5227 app.mSuccessor.mPredecessor = null; 5228 app.mSuccessor = null; 5229 // Remove any pending timeout msg. 5230 mService.mProcStartHandler.removeMessages( 5231 ProcStartHandler.MSG_PROCESS_KILL_TIMEOUT, app); 5232 // Kick off the proc start for the succeeding instance 5233 mService.mProcStartHandler.obtainMessage( 5234 ProcStartHandler.MSG_PROCESS_DIED, app).sendToTarget(); 5235 return false; 5236 } 5237 return true; 5238 } 5239 5240 @GuardedBy("mService") 5241 void updateBackgroundRestrictedForUidPackageLocked(int uid, String packageName, 5242 boolean restricted) { 5243 final UidRecord uidRec = getUidRecordLOSP(uid); 5244 if (uidRec != null) { 5245 final long nowElapsed = SystemClock.elapsedRealtime(); 5246 uidRec.forEachProcess(app -> { 5247 if (TextUtils.equals(app.info.packageName, packageName)) { 5248 app.mState.setBackgroundRestricted(restricted); 5249 if (restricted) { 5250 mAppsInBackgroundRestricted.add(app); 5251 final long future = killAppIfBgRestrictedAndCachedIdleLocked( 5252 app, nowElapsed); 5253 if (future > 0 5254 && (mService.mDeterministicUidIdle 5255 || !mService.mHandler.hasMessages(IDLE_UIDS_MSG))) { 5256 mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 5257 future - nowElapsed); 5258 } 5259 } else { 5260 mAppsInBackgroundRestricted.remove(app); 5261 } 5262 if (!app.isKilledByAm()) { 5263 mService.enqueueOomAdjTargetLocked(app); 5264 } 5265 } 5266 }); 5267 /* Will be a no-op if nothing pending */ 5268 mService.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_RESTRICTION_CHANGE); 5269 } 5270 } 5271 5272 /** 5273 * Kill the given app if it's in cached idle and background restricted mode. 5274 * 5275 * @return A future timestamp when the app should be killed at, or a 0 if it shouldn't 5276 * be killed or it has been killed. 5277 */ 5278 @GuardedBy("mService") 5279 long killAppIfBgRestrictedAndCachedIdleLocked(ProcessRecord app, long nowElapsed) { 5280 final UidRecord uidRec = app.getUidRecord(); 5281 final long lastCanKillTime = app.mState.getLastCanKillOnBgRestrictedAndIdleTime(); 5282 if (!mService.mConstants.mKillBgRestrictedAndCachedIdle 5283 || app.isKilled() || app.getThread() == null || uidRec == null || !uidRec.isIdle() 5284 || !app.isCached() || app.mState.shouldNotKillOnBgRestrictedAndIdle() 5285 || !app.mState.isBackgroundRestricted() || lastCanKillTime == 0) { 5286 return 0; 5287 } 5288 final long future = lastCanKillTime 5289 + mService.mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs; 5290 if (future <= nowElapsed) { 5291 app.killLocked("cached idle & background restricted", 5292 ApplicationExitInfo.REASON_OTHER, 5293 ApplicationExitInfo.SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY, 5294 true); 5295 return 0; 5296 } 5297 return future; 5298 } 5299 5300 /** 5301 * Called by {@link ActivityManagerService#enqueueUidChangeLocked} only, it doesn't schedule 5302 * the standy killing checks because it should have been scheduled before enqueueing UID idle 5303 * changed. 5304 */ 5305 @GuardedBy("mService") 5306 void killAppIfBgRestrictedAndCachedIdleLocked(UidRecord uidRec) { 5307 final long nowElapsed = SystemClock.elapsedRealtime(); 5308 uidRec.forEachProcess(app -> killAppIfBgRestrictedAndCachedIdleLocked(app, nowElapsed)); 5309 } 5310 5311 /** 5312 * Called by ActivityManagerService when a process died. 5313 */ 5314 @GuardedBy("mService") 5315 void noteProcessDiedLocked(final ProcessRecord app) { 5316 if (DEBUG_PROCESSES) { 5317 Slog.i(TAG, "note: " + app + " died, saving the exit info"); 5318 } 5319 5320 Watchdog.getInstance().processDied(app.processName, app.getPid()); 5321 if (app.getDeathRecipient() == null 5322 && mDyingProcesses.get(app.processName, app.uid) == app) { 5323 // If we've done unlinkDeathRecipient before calling into this, remove from dying list. 5324 mDyingProcesses.remove(app.processName, app.uid); 5325 app.setDyingPid(0); 5326 } 5327 mAppExitInfoTracker.scheduleNoteProcessDied(app); 5328 } 5329 5330 /** 5331 * Called by ActivityManagerService when a recoverable native crash occurs. 5332 */ 5333 @GuardedBy("mService") 5334 void noteAppRecoverableCrash(final ProcessRecord app) { 5335 if (DEBUG_PROCESSES) { 5336 Slog.i(TAG, "note: " + app + " has a recoverable native crash"); 5337 } 5338 mAppExitInfoTracker.scheduleNoteAppRecoverableCrash(app); 5339 } 5340 5341 /** 5342 * Called by ActivityManagerService when it decides to kill an application process. 5343 */ 5344 @GuardedBy("mService") 5345 void noteAppKill(final ProcessRecord app, final @Reason int reason, 5346 final @SubReason int subReason, final String msg) { 5347 if (DEBUG_PROCESSES) { 5348 Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason 5349 + ", sub-reason: " + subReason + ", message: " + msg); 5350 } 5351 if (app.getPid() > 0 && !app.isolated && app.getDeathRecipient() != null) { 5352 // We are killing it, put it into the dying process list. 5353 mDyingProcesses.put(app.processName, app.uid, app); 5354 app.setDyingPid(app.getPid()); 5355 } 5356 mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg); 5357 } 5358 5359 @GuardedBy("mService") 5360 void noteAppKill(final int pid, final int uid, final @Reason int reason, 5361 final @SubReason int subReason, final String msg) { 5362 if (DEBUG_PROCESSES) { 5363 Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason 5364 + ", sub-reason: " + subReason + ", message: " + msg); 5365 } 5366 5367 final ProcessRecord app; 5368 synchronized (mService.mPidsSelfLocked) { 5369 app = mService.mPidsSelfLocked.get(pid); 5370 } 5371 if (app != null && app.uid == uid && !app.isolated && app.getDeathRecipient() != null) { 5372 // We are killing it, put it into the dying process list. 5373 mDyingProcesses.put(app.processName, uid, app); 5374 app.setDyingPid(app.getPid()); 5375 } 5376 mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg); 5377 } 5378 5379 /** 5380 * Schedule to kill the given pids when the device is idle 5381 */ 5382 void killProcessesWhenImperceptible(int[] pids, String reason, int requester) { 5383 if (ArrayUtils.isEmpty(pids)) { 5384 return; 5385 } 5386 5387 synchronized (mService) { 5388 ProcessRecord app; 5389 for (int i = 0; i < pids.length; i++) { 5390 synchronized (mService.mPidsSelfLocked) { 5391 app = mService.mPidsSelfLocked.get(pids[i]); 5392 } 5393 if (app != null) { 5394 mImperceptibleKillRunner.enqueueLocked(app, reason, requester); 5395 } 5396 } 5397 } 5398 } 5399 5400 /** 5401 * Get the number of foreground services in all processes and number of processes that have 5402 * foreground service within. 5403 */ 5404 Pair<Integer, Integer> getNumForegroundServices() { 5405 int numForegroundServices = 0; 5406 int procs = 0; 5407 synchronized (mService) { 5408 for (int i = 0, size = mLruProcesses.size(); i < size; i++) { 5409 ProcessRecord pr = mLruProcesses.get(i); 5410 int numFgs = pr.mServices.getNumForegroundServices(); 5411 if (numFgs > 0) { 5412 numForegroundServices += numFgs; 5413 procs++; 5414 } 5415 } 5416 } 5417 return new Pair<>(numForegroundServices, procs); 5418 } 5419 5420 private final class ImperceptibleKillRunner extends UidObserver { 5421 private static final String EXTRA_PID = "pid"; 5422 private static final String EXTRA_UID = "uid"; 5423 private static final String EXTRA_TIMESTAMP = "timestamp"; 5424 private static final String EXTRA_REASON = "reason"; 5425 private static final String EXTRA_REQUESTER = "requester"; 5426 5427 private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill"; 5428 private static final boolean LOG_TO_DROPBOX = false; 5429 5430 // uid -> killing information mapping 5431 private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>(); 5432 5433 // The last time the various processes have been killed by us. 5434 private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>(); 5435 5436 // Device idle or not. 5437 private volatile boolean mIdle; 5438 private boolean mUidObserverEnabled; 5439 private Handler mHandler; 5440 private IdlenessReceiver mReceiver; 5441 5442 private final class H extends Handler { 5443 static final int MSG_DEVICE_IDLE = 0; 5444 static final int MSG_UID_GONE = 1; 5445 static final int MSG_UID_STATE_CHANGED = 2; 5446 5447 H(Looper looper) { 5448 super(looper); 5449 } 5450 5451 @Override 5452 public void handleMessage(Message msg) { 5453 switch (msg.what) { 5454 case MSG_DEVICE_IDLE: 5455 handleDeviceIdle(); 5456 break; 5457 case MSG_UID_GONE: 5458 handleUidGone(msg.arg1 /* uid */); 5459 break; 5460 case MSG_UID_STATE_CHANGED: 5461 handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */); 5462 break; 5463 } 5464 } 5465 } 5466 5467 private final class IdlenessReceiver extends BroadcastReceiver { 5468 @Override 5469 public void onReceive(Context context, Intent intent) { 5470 final PowerManager pm = mService.mContext.getSystemService(PowerManager.class); 5471 switch (intent.getAction()) { 5472 case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED: 5473 notifyDeviceIdleness(pm.isLightDeviceIdleMode()); 5474 break; 5475 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED: 5476 notifyDeviceIdleness(pm.isDeviceIdleMode()); 5477 break; 5478 } 5479 } 5480 } 5481 5482 ImperceptibleKillRunner(Looper looper) { 5483 mHandler = new H(looper); 5484 } 5485 5486 @GuardedBy("mService") 5487 boolean enqueueLocked(ProcessRecord app, String reason, int requester) { 5488 // Throttle the killing request for potential bad app to avoid cpu thrashing 5489 Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid); 5490 if ((last != null) && (SystemClock.uptimeMillis() 5491 < (last + ActivityManagerConstants.MIN_CRASH_INTERVAL))) { 5492 return false; 5493 } 5494 5495 final Bundle bundle = new Bundle(); 5496 bundle.putInt(EXTRA_PID, app.getPid()); 5497 bundle.putInt(EXTRA_UID, app.uid); 5498 // Since the pid could be reused, let's get the actual start time of each process 5499 bundle.putLong(EXTRA_TIMESTAMP, app.getStartTime()); 5500 bundle.putString(EXTRA_REASON, reason); 5501 bundle.putInt(EXTRA_REQUESTER, requester); 5502 List<Bundle> list = mWorkItems.get(app.uid); 5503 if (list == null) { 5504 list = new ArrayList<Bundle>(); 5505 mWorkItems.put(app.uid, list); 5506 } 5507 list.add(bundle); 5508 if (mReceiver == null) { 5509 mReceiver = new IdlenessReceiver(); 5510 IntentFilter filter = new IntentFilter( 5511 PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); 5512 filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 5513 mService.mContext.registerReceiver(mReceiver, filter); 5514 } 5515 return true; 5516 } 5517 5518 void notifyDeviceIdleness(boolean idle) { 5519 // No lock is held regarding mIdle, this function is the only updater and caller 5520 // won't re-entry. 5521 boolean diff = mIdle != idle; 5522 mIdle = idle; 5523 if (diff && idle) { 5524 synchronized (mService) { 5525 if (mWorkItems.size() > 0) { 5526 mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE); 5527 } 5528 } 5529 } 5530 } 5531 5532 private void handleDeviceIdle() { 5533 final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class); 5534 final boolean logToDropbox = LOG_TO_DROPBOX && dbox != null 5535 && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL); 5536 5537 synchronized (mService) { 5538 final int size = mWorkItems.size(); 5539 for (int i = size - 1; mIdle && i >= 0; i--) { 5540 List<Bundle> list = mWorkItems.valueAt(i); 5541 final int len = list.size(); 5542 for (int j = len - 1; mIdle && j >= 0; j--) { 5543 Bundle bundle = list.get(j); 5544 if (killProcessLocked( 5545 bundle.getInt(EXTRA_PID), 5546 bundle.getInt(EXTRA_UID), 5547 bundle.getLong(EXTRA_TIMESTAMP), 5548 bundle.getString(EXTRA_REASON), 5549 bundle.getInt(EXTRA_REQUESTER), 5550 dbox, logToDropbox)) { 5551 list.remove(j); 5552 } 5553 } 5554 if (list.size() == 0) { 5555 mWorkItems.removeAt(i); 5556 } 5557 } 5558 registerUidObserverIfNecessaryLocked(); 5559 } 5560 } 5561 5562 @GuardedBy("mService") 5563 private void registerUidObserverIfNecessaryLocked() { 5564 // If there are still works remaining, register UID observer 5565 if (!mUidObserverEnabled && mWorkItems.size() > 0) { 5566 mUidObserverEnabled = true; 5567 mService.registerUidObserver(this, 5568 ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE, 5569 ActivityManager.PROCESS_STATE_UNKNOWN, "android"); 5570 } else if (mUidObserverEnabled && mWorkItems.size() == 0) { 5571 mUidObserverEnabled = false; 5572 mService.unregisterUidObserver(this); 5573 } 5574 } 5575 5576 /** 5577 * Kill the given processes, if they are not exempted. 5578 * 5579 * @return True if the process is killed, or it's gone already, or we are not allowed to 5580 * kill it (one of the packages in this process is being exempted). 5581 */ 5582 @GuardedBy("mService") 5583 private boolean killProcessLocked(final int pid, final int uid, final long timestamp, 5584 final String reason, final int requester, final DropBoxManager dbox, 5585 final boolean logToDropbox) { 5586 ProcessRecord app = null; 5587 synchronized (mService.mPidsSelfLocked) { 5588 app = mService.mPidsSelfLocked.get(pid); 5589 } 5590 5591 if (app == null || app.getPid() != pid || app.uid != uid 5592 || app.getStartTime() != timestamp) { 5593 // This process record has been reused for another process, meaning the old process 5594 // has been gone. 5595 return true; 5596 } 5597 5598 if (app.getPkgList().searchEachPackage(pkgName -> { 5599 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(pkgName)) { 5600 // One of the packages in this process is exempted 5601 return Boolean.TRUE; 5602 } 5603 return null; 5604 }) != null) { 5605 return true; 5606 } 5607 5608 if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains( 5609 app.mState.getReportedProcState())) { 5610 // We need to reschedule it. 5611 return false; 5612 } 5613 5614 app.killLocked(reason, ApplicationExitInfo.REASON_OTHER, 5615 ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true); 5616 5617 if (!app.isolated) { 5618 mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis()); 5619 } 5620 5621 if (logToDropbox) { 5622 final long now = SystemClock.elapsedRealtime(); 5623 final StringBuilder sb = new StringBuilder(); 5624 mService.appendDropBoxProcessHeaders(app, app.processName, sb); 5625 sb.append("Reason: " + reason).append("\n"); 5626 sb.append("Requester UID: " + requester).append("\n"); 5627 dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString()); 5628 } 5629 return true; 5630 } 5631 5632 private void handleUidStateChanged(int uid, int procState) { 5633 final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class); 5634 final boolean logToDropbox = dbox != null 5635 && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL); 5636 synchronized (mService) { 5637 if (mIdle && !mService.mConstants 5638 .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) { 5639 List<Bundle> list = mWorkItems.get(uid); 5640 if (list != null) { 5641 final int len = list.size(); 5642 for (int j = len - 1; mIdle && j >= 0; j--) { 5643 Bundle bundle = list.get(j); 5644 if (killProcessLocked( 5645 bundle.getInt(EXTRA_PID), 5646 bundle.getInt(EXTRA_UID), 5647 bundle.getLong(EXTRA_TIMESTAMP), 5648 bundle.getString(EXTRA_REASON), 5649 bundle.getInt(EXTRA_REQUESTER), 5650 dbox, logToDropbox)) { 5651 list.remove(j); 5652 } 5653 } 5654 if (list.size() == 0) { 5655 mWorkItems.remove(uid); 5656 } 5657 registerUidObserverIfNecessaryLocked(); 5658 } 5659 } 5660 } 5661 } 5662 5663 private void handleUidGone(int uid) { 5664 synchronized (mService) { 5665 mWorkItems.remove(uid); 5666 registerUidObserverIfNecessaryLocked(); 5667 } 5668 } 5669 5670 @Override 5671 public void onUidGone(int uid, boolean disabled) { 5672 mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget(); 5673 } 5674 5675 @Override 5676 public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { 5677 mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); 5678 } 5679 }; 5680 } 5681