1 /* 2 * Copyright (C) 2018 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.wm; 18 19 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 20 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 22 import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED; 23 import static android.os.Build.VERSION_CODES.Q; 24 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS; 25 26 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; 27 import static com.android.internal.util.Preconditions.checkArgument; 28 import static com.android.server.am.ProcessList.INVALID_ADJ; 29 import static com.android.server.wm.ActivityRecord.State.DESTROYED; 30 import static com.android.server.wm.ActivityRecord.State.DESTROYING; 31 import static com.android.server.wm.ActivityRecord.State.PAUSED; 32 import static com.android.server.wm.ActivityRecord.State.PAUSING; 33 import static com.android.server.wm.ActivityRecord.State.RESUMED; 34 import static com.android.server.wm.ActivityRecord.State.STARTED; 35 import static com.android.server.wm.ActivityRecord.State.STOPPING; 36 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE; 37 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; 38 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE; 39 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 40 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 41 import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MILLIS; 42 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; 43 import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK; 44 import static com.android.server.wm.WindowManagerService.MY_PID; 45 46 import android.Manifest; 47 import android.annotation.NonNull; 48 import android.annotation.Nullable; 49 import android.app.ActivityManager; 50 import android.app.ActivityThread; 51 import android.app.IApplicationThread; 52 import android.app.ProfilerInfo; 53 import android.app.servertransaction.ConfigurationChangeItem; 54 import android.content.Context; 55 import android.content.Intent; 56 import android.content.pm.ActivityInfo; 57 import android.content.pm.ApplicationInfo; 58 import android.content.pm.ServiceInfo; 59 import android.content.res.Configuration; 60 import android.os.Binder; 61 import android.os.Build; 62 import android.os.IBinder; 63 import android.os.LocaleList; 64 import android.os.Message; 65 import android.os.Process; 66 import android.os.RemoteException; 67 import android.util.ArraySet; 68 import android.util.Log; 69 import android.util.Slog; 70 import android.util.proto.ProtoOutputStream; 71 import android.view.IRemoteAnimationRunner; 72 73 import com.android.internal.annotations.VisibleForTesting; 74 import com.android.internal.app.HeavyWeightSwitcherActivity; 75 import com.android.internal.protolog.common.ProtoLog; 76 import com.android.internal.util.function.pooled.PooledLambda; 77 import com.android.server.Watchdog; 78 import com.android.server.wm.ActivityTaskManagerService.HotPath; 79 80 import java.io.IOException; 81 import java.io.PrintWriter; 82 import java.util.ArrayList; 83 import java.util.List; 84 85 /** 86 * The Activity Manager (AM) package manages the lifecycle of processes in the system through 87 * ProcessRecord. However, it is important for the Window Manager (WM) package to be aware 88 * of the processes and their state since it affects how WM manages windows and activities. This 89 * class that allows the ProcessRecord object in the AM package to communicate important 90 * changes to its state to the WM package in a structured way. WM package also uses 91 * {@link WindowProcessListener} to request changes to the process state on the AM side. 92 * Note that public calls into this class are assumed to be originating from outside the 93 * window manager so the window manager lock is held and appropriate permissions are checked before 94 * calls are allowed to proceed. 95 */ 96 public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer> 97 implements ConfigurationContainerListener { 98 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM; 99 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 100 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; 101 102 // all about the first app in the process 103 final ApplicationInfo mInfo; 104 final String mName; 105 final int mUid; 106 107 // The process of this application; 0 if none 108 private volatile int mPid; 109 // user of process. 110 final int mUserId; 111 // The owner of this window process controller object. Mainly for identification when we 112 // communicate back to the activity manager side. 113 public final Object mOwner; 114 // List of packages running in the process 115 final ArraySet<String> mPkgList = new ArraySet<>(); 116 private final WindowProcessListener mListener; 117 private final ActivityTaskManagerService mAtm; 118 private final BackgroundLaunchProcessController mBgLaunchController; 119 // The actual proc... may be null only if 'persistent' is true (in which case we are in the 120 // process of launching the app) 121 private IApplicationThread mThread; 122 // Currently desired scheduling class 123 private volatile int mCurSchedGroup; 124 // Currently computed process state 125 private volatile int mCurProcState = PROCESS_STATE_NONEXISTENT; 126 // Last reported process state; 127 private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT; 128 // Currently computed oom adj score 129 private volatile int mCurAdj = INVALID_ADJ; 130 // are we in the process of crashing? 131 private volatile boolean mCrashing; 132 // does the app have a not responding dialog? 133 private volatile boolean mNotResponding; 134 // always keep this application running? 135 private volatile boolean mPersistent; 136 // The ABI this process was launched with 137 private volatile String mRequiredAbi; 138 // Running any services that are foreground? 139 private volatile boolean mHasForegroundServices; 140 // Are there any client services with activities? 141 private volatile boolean mHasClientActivities; 142 // Is this process currently showing a non-activity UI that the user is interacting with? 143 // E.g. The status bar when it is expanded, but not when it is minimized. When true the process 144 // will be set to use the ProcessList#SCHED_GROUP_TOP_APP scheduling group to boost performance. 145 private volatile boolean mHasTopUi; 146 // Is the process currently showing a non-activity UI that overlays on-top of activity UIs on 147 // screen. E.g. display a window of type 148 // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY When true the process will 149 // oom adj score will be set to ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance 150 // of the process getting killed. 151 private volatile boolean mHasOverlayUi; 152 // Want to clean up resources from showing UI? 153 private volatile boolean mPendingUiClean; 154 // The time we sent the last interaction event 155 private volatile long mInteractionEventTime; 156 // When we became foreground for interaction purposes 157 private volatile long mFgInteractionTime; 158 // When (uptime) the process last became unimportant 159 private volatile long mWhenUnimportant; 160 // was app launched for debugging? 161 private volatile boolean mDebugging; 162 // Active instrumentation running in process? 163 private volatile boolean mInstrumenting; 164 // If there is active instrumentation, this is the source 165 private volatile int mInstrumentationSourceUid = -1; 166 // Active instrumentation with background activity starts privilege running in process? 167 private volatile boolean mInstrumentingWithBackgroundActivityStartPrivileges; 168 // This process it perceptible by the user. 169 private volatile boolean mPerceptible; 170 // Set to true when process was launched with a wrapper attached 171 private volatile boolean mUsingWrapper; 172 173 // Thread currently set for VR scheduling 174 int mVrThreadTid; 175 176 // Whether this process has ever started a service with the BIND_INPUT_METHOD permission. 177 private volatile boolean mHasImeService; 178 179 /** Whether {@link #mActivities} is not empty. */ 180 private volatile boolean mHasActivities; 181 /** All activities running in the process (exclude destroying). */ 182 private final ArrayList<ActivityRecord> mActivities = new ArrayList<>(); 183 /** The activities will be removed but still belong to this process. */ 184 private ArrayList<ActivityRecord> mInactiveActivities; 185 /** Whether {@link #mRecentTasks} is not empty. */ 186 private volatile boolean mHasRecentTasks; 187 // any tasks this process had run root activities in 188 private final ArrayList<Task> mRecentTasks = new ArrayList<>(); 189 // The most recent top-most activity that was resumed in the process for pre-Q app. 190 private ActivityRecord mPreQTopResumedActivity = null; 191 // The last time an activity was launched in the process 192 private volatile long mLastActivityLaunchTime; 193 // The last time an activity was finished in the process while the process participated 194 // in a visible task 195 private volatile long mLastActivityFinishTime; 196 197 // Last configuration that was reported to the process. 198 private final Configuration mLastReportedConfiguration = new Configuration(); 199 /** Whether the process configuration is waiting to be dispatched to the process. */ 200 private boolean mHasPendingConfigurationChange; 201 202 /** If the process state is in (<=) the cached state, then defer delivery of the config. */ 203 private static final int CACHED_CONFIG_PROC_STATE = PROCESS_STATE_CACHED_ACTIVITY; 204 /** Whether {@link #mLastReportedConfiguration} is deferred by the cached state. */ 205 private volatile boolean mHasCachedConfiguration; 206 207 /** 208 * Registered {@link DisplayArea} as a listener to override config changes. {@code null} if not 209 * registered. 210 */ 211 @Nullable 212 private DisplayArea mDisplayArea; 213 private ActivityRecord mConfigActivityRecord; 214 // Whether the activity config override is allowed for this process. 215 private volatile boolean mIsActivityConfigOverrideAllowed = true; 216 /** Non-zero to pause dispatching process configuration change. */ 217 private int mPauseConfigurationDispatchCount; 218 219 /** 220 * Activities that hosts some UI drawn by the current process. The activities live 221 * in another process. This is used to check if the process is currently showing anything 222 * visible to the user. 223 */ 224 @Nullable 225 private final ArrayList<ActivityRecord> mHostActivities = new ArrayList<>(); 226 227 /** Whether our process is currently running a {@link RecentsAnimation} */ 228 private boolean mRunningRecentsAnimation; 229 230 /** Whether our process is currently running a {@link IRemoteAnimationRunner} */ 231 private boolean mRunningRemoteAnimation; 232 233 // The bits used for mActivityStateFlags. 234 private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16; 235 private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17; 236 private static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18; 237 private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19; 238 private static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20; 239 private static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21; 240 private static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22; 241 private static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff; 242 243 /** 244 * The state for oom-adjustment calculation. The higher 16 bits are the activity states, and the 245 * lower 16 bits are the task layer rank (see {@link Task#mLayerRank}). This field is written by 246 * window manager and read by activity manager. 247 */ 248 private volatile int mActivityStateFlags = ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER; 249 WindowProcessController(@onNull ActivityTaskManagerService atm, @NonNull ApplicationInfo info, String name, int uid, int userId, Object owner, @NonNull WindowProcessListener listener)250 public WindowProcessController(@NonNull ActivityTaskManagerService atm, 251 @NonNull ApplicationInfo info, String name, int uid, int userId, Object owner, 252 @NonNull WindowProcessListener listener) { 253 mInfo = info; 254 mName = name; 255 mUid = uid; 256 mUserId = userId; 257 mOwner = owner; 258 mListener = listener; 259 mAtm = atm; 260 mBgLaunchController = new BackgroundLaunchProcessController( 261 atm::hasActiveVisibleWindow, atm.getBackgroundActivityStartCallback()); 262 263 boolean isSysUiPackage = info.packageName.equals( 264 mAtm.getSysUiServiceComponentLocked().getPackageName()); 265 if (isSysUiPackage || mUid == Process.SYSTEM_UID) { 266 // This is a system owned process and should not use an activity config. 267 // TODO(b/151161907): Remove after support for display-independent (raw) SysUi configs. 268 mIsActivityConfigOverrideAllowed = false; 269 } 270 271 onConfigurationChanged(atm.getGlobalConfiguration()); 272 mAtm.mPackageConfigPersister.updateConfigIfNeeded(this, mUserId, mInfo.packageName); 273 } 274 setPid(int pid)275 public void setPid(int pid) { 276 mPid = pid; 277 } 278 getPid()279 public int getPid() { 280 return mPid; 281 } 282 283 @HotPath(caller = HotPath.PROCESS_CHANGE) setThread(IApplicationThread thread)284 public void setThread(IApplicationThread thread) { 285 synchronized (mAtm.mGlobalLockWithoutBoost) { 286 mThread = thread; 287 // In general this is called from attaching application, so the last configuration 288 // has been sent to client by {@link android.app.IApplicationThread#bindApplication}. 289 // If this process is system server, it is fine because system is booting and a new 290 // configuration will update when display is ready. 291 if (thread != null) { 292 setLastReportedConfiguration(getConfiguration()); 293 } else { 294 // The process is inactive. 295 mAtm.mVisibleActivityProcessTracker.removeProcess(this); 296 } 297 } 298 } 299 getThread()300 IApplicationThread getThread() { 301 return mThread; 302 } 303 hasThread()304 boolean hasThread() { 305 return mThread != null; 306 } 307 setCurrentSchedulingGroup(int curSchedGroup)308 public void setCurrentSchedulingGroup(int curSchedGroup) { 309 mCurSchedGroup = curSchedGroup; 310 } 311 getCurrentSchedulingGroup()312 int getCurrentSchedulingGroup() { 313 return mCurSchedGroup; 314 } 315 setCurrentProcState(int curProcState)316 public void setCurrentProcState(int curProcState) { 317 mCurProcState = curProcState; 318 } 319 getCurrentProcState()320 int getCurrentProcState() { 321 return mCurProcState; 322 } 323 setCurrentAdj(int curAdj)324 public void setCurrentAdj(int curAdj) { 325 mCurAdj = curAdj; 326 } 327 getCurrentAdj()328 int getCurrentAdj() { 329 return mCurAdj; 330 } 331 332 /** 333 * Sets the computed process state from the oom adjustment calculation. This is frequently 334 * called in activity manager's lock, so don't use window manager lock here. 335 */ 336 @HotPath(caller = HotPath.OOM_ADJUSTMENT) setReportedProcState(int repProcState)337 public void setReportedProcState(int repProcState) { 338 final int prevProcState = mRepProcState; 339 mRepProcState = repProcState; 340 341 // Deliver the cached config if the app changes from cached state to non-cached state. 342 final IApplicationThread thread = mThread; 343 if (prevProcState >= CACHED_CONFIG_PROC_STATE && repProcState < CACHED_CONFIG_PROC_STATE 344 && thread != null && mHasCachedConfiguration) { 345 final Configuration config; 346 synchronized (mLastReportedConfiguration) { 347 config = new Configuration(mLastReportedConfiguration); 348 } 349 // Schedule immediately to make sure the app component (e.g. receiver, service) can get 350 // the latest configuration in their lifecycle callbacks (e.g. onReceive, onCreate). 351 scheduleConfigurationChange(thread, config); 352 } 353 } 354 getReportedProcState()355 int getReportedProcState() { 356 return mRepProcState; 357 } 358 setCrashing(boolean crashing)359 public void setCrashing(boolean crashing) { 360 mCrashing = crashing; 361 } 362 isCrashing()363 boolean isCrashing() { 364 return mCrashing; 365 } 366 setNotResponding(boolean notResponding)367 public void setNotResponding(boolean notResponding) { 368 mNotResponding = notResponding; 369 } 370 isNotResponding()371 boolean isNotResponding() { 372 return mNotResponding; 373 } 374 setPersistent(boolean persistent)375 public void setPersistent(boolean persistent) { 376 mPersistent = persistent; 377 } 378 isPersistent()379 boolean isPersistent() { 380 return mPersistent; 381 } 382 setHasForegroundServices(boolean hasForegroundServices)383 public void setHasForegroundServices(boolean hasForegroundServices) { 384 mHasForegroundServices = hasForegroundServices; 385 } 386 hasForegroundServices()387 boolean hasForegroundServices() { 388 return mHasForegroundServices; 389 } 390 hasForegroundActivities()391 boolean hasForegroundActivities() { 392 return mAtm.mTopApp == this || (mActivityStateFlags 393 & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED 394 | ACTIVITY_STATE_FLAG_IS_STOPPING)) != 0; 395 } 396 setHasClientActivities(boolean hasClientActivities)397 public void setHasClientActivities(boolean hasClientActivities) { 398 mHasClientActivities = hasClientActivities; 399 } 400 hasClientActivities()401 boolean hasClientActivities() { 402 return mHasClientActivities; 403 } 404 setHasTopUi(boolean hasTopUi)405 public void setHasTopUi(boolean hasTopUi) { 406 mHasTopUi = hasTopUi; 407 } 408 hasTopUi()409 boolean hasTopUi() { 410 return mHasTopUi; 411 } 412 setHasOverlayUi(boolean hasOverlayUi)413 public void setHasOverlayUi(boolean hasOverlayUi) { 414 mHasOverlayUi = hasOverlayUi; 415 } 416 hasOverlayUi()417 boolean hasOverlayUi() { 418 return mHasOverlayUi; 419 } 420 setPendingUiClean(boolean hasPendingUiClean)421 public void setPendingUiClean(boolean hasPendingUiClean) { 422 mPendingUiClean = hasPendingUiClean; 423 } 424 hasPendingUiClean()425 boolean hasPendingUiClean() { 426 return mPendingUiClean; 427 } 428 429 /** @return {@code true} if the process registered to a display area as a config listener. */ registeredForDisplayAreaConfigChanges()430 boolean registeredForDisplayAreaConfigChanges() { 431 return mDisplayArea != null; 432 } 433 434 /** @return {@code true} if the process registered to an activity as a config listener. */ 435 @VisibleForTesting registeredForActivityConfigChanges()436 boolean registeredForActivityConfigChanges() { 437 return mConfigActivityRecord != null; 438 } 439 postPendingUiCleanMsg(boolean pendingUiClean)440 void postPendingUiCleanMsg(boolean pendingUiClean) { 441 // Posting on handler so WM lock isn't held when we call into AM. 442 final Message m = PooledLambda.obtainMessage( 443 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean); 444 mAtm.mH.sendMessage(m); 445 } 446 setInteractionEventTime(long interactionEventTime)447 public void setInteractionEventTime(long interactionEventTime) { 448 mInteractionEventTime = interactionEventTime; 449 } 450 getInteractionEventTime()451 long getInteractionEventTime() { 452 return mInteractionEventTime; 453 } 454 setFgInteractionTime(long fgInteractionTime)455 public void setFgInteractionTime(long fgInteractionTime) { 456 mFgInteractionTime = fgInteractionTime; 457 } 458 getFgInteractionTime()459 long getFgInteractionTime() { 460 return mFgInteractionTime; 461 } 462 setWhenUnimportant(long whenUnimportant)463 public void setWhenUnimportant(long whenUnimportant) { 464 mWhenUnimportant = whenUnimportant; 465 } 466 getWhenUnimportant()467 long getWhenUnimportant() { 468 return mWhenUnimportant; 469 } 470 setRequiredAbi(String requiredAbi)471 public void setRequiredAbi(String requiredAbi) { 472 mRequiredAbi = requiredAbi; 473 } 474 getRequiredAbi()475 String getRequiredAbi() { 476 return mRequiredAbi; 477 } 478 479 /** 480 * Registered {@link DisplayArea} as a listener to override config changes. {@code null} if not 481 * registered. 482 */ 483 @VisibleForTesting 484 @Nullable getDisplayArea()485 DisplayArea getDisplayArea() { 486 return mDisplayArea; 487 } 488 setDebugging(boolean debugging)489 public void setDebugging(boolean debugging) { 490 mDebugging = debugging; 491 } 492 isDebugging()493 boolean isDebugging() { 494 return mDebugging; 495 } 496 setUsingWrapper(boolean usingWrapper)497 public void setUsingWrapper(boolean usingWrapper) { 498 mUsingWrapper = usingWrapper; 499 } 500 isUsingWrapper()501 boolean isUsingWrapper() { 502 return mUsingWrapper; 503 } 504 hasEverLaunchedActivity()505 boolean hasEverLaunchedActivity() { 506 return mLastActivityLaunchTime > 0; 507 } 508 setLastActivityLaunchTime(long launchTime)509 void setLastActivityLaunchTime(long launchTime) { 510 if (launchTime <= mLastActivityLaunchTime) { 511 if (launchTime < mLastActivityLaunchTime) { 512 Slog.w(TAG, 513 "Tried to set launchTime (" + launchTime + ") < mLastActivityLaunchTime (" 514 + mLastActivityLaunchTime + ")"); 515 } 516 return; 517 } 518 mLastActivityLaunchTime = launchTime; 519 } 520 setLastActivityFinishTimeIfNeeded(long finishTime)521 void setLastActivityFinishTimeIfNeeded(long finishTime) { 522 if (finishTime <= mLastActivityFinishTime || !hasActivityInVisibleTask()) { 523 return; 524 } 525 mLastActivityFinishTime = finishTime; 526 } 527 528 /** 529 * @see BackgroundLaunchProcessController#addOrUpdateAllowBackgroundActivityStartsToken(Binder, 530 * IBinder) 531 */ addOrUpdateAllowBackgroundActivityStartsToken(Binder entity, @Nullable IBinder originatingToken)532 public void addOrUpdateAllowBackgroundActivityStartsToken(Binder entity, 533 @Nullable IBinder originatingToken) { 534 mBgLaunchController.addOrUpdateAllowBackgroundActivityStartsToken(entity, originatingToken); 535 } 536 537 /** @see BackgroundLaunchProcessController#removeAllowBackgroundActivityStartsToken(Binder) */ removeAllowBackgroundActivityStartsToken(Binder entity)538 public void removeAllowBackgroundActivityStartsToken(Binder entity) { 539 mBgLaunchController.removeAllowBackgroundActivityStartsToken(entity); 540 } 541 542 /** 543 * Is this WindowProcessController in the state of allowing background FGS start? 544 */ 545 @HotPath(caller = HotPath.START_SERVICE) areBackgroundFgsStartsAllowed()546 public boolean areBackgroundFgsStartsAllowed() { 547 return areBackgroundActivityStartsAllowed(mAtm.getBalAppSwitchesState(), 548 true /* isCheckingForFgsStart */) != BAL_BLOCK; 549 } 550 551 @BackgroundActivityStartController.BalCode areBackgroundActivityStartsAllowed(int appSwitchState)552 int areBackgroundActivityStartsAllowed(int appSwitchState) { 553 return areBackgroundActivityStartsAllowed(appSwitchState, 554 false /* isCheckingForFgsStart */); 555 } 556 557 @BackgroundActivityStartController.BalCode areBackgroundActivityStartsAllowed(int appSwitchState, boolean isCheckingForFgsStart)558 private int areBackgroundActivityStartsAllowed(int appSwitchState, 559 boolean isCheckingForFgsStart) { 560 return mBgLaunchController.areBackgroundActivityStartsAllowed(mPid, mUid, mInfo.packageName, 561 appSwitchState, isCheckingForFgsStart, hasActivityInVisibleTask(), 562 mInstrumentingWithBackgroundActivityStartPrivileges, 563 mAtm.getLastStopAppSwitchesTime(), 564 mLastActivityLaunchTime, mLastActivityFinishTime); 565 } 566 567 /** 568 * Returns whether this process is allowed to close system dialogs via a background activity 569 * start token that allows the close system dialogs operation (eg. notification). 570 */ canCloseSystemDialogsByToken()571 boolean canCloseSystemDialogsByToken() { 572 return mBgLaunchController.canCloseSystemDialogsByToken(mUid); 573 } 574 setBoundClientUids(ArraySet<Integer> boundClientUids)575 public void setBoundClientUids(ArraySet<Integer> boundClientUids) { 576 mBgLaunchController.setBoundClientUids(boundClientUids); 577 } 578 579 /** 580 * Set instrumentation-related info. 581 * 582 * If {@code instrumenting} is {@code false}, {@code sourceUid} has to be -1. 583 */ setInstrumenting(boolean instrumenting, int sourceUid, boolean hasBackgroundActivityStartPrivileges)584 public void setInstrumenting(boolean instrumenting, int sourceUid, 585 boolean hasBackgroundActivityStartPrivileges) { 586 checkArgument(instrumenting || sourceUid == -1); 587 mInstrumenting = instrumenting; 588 mInstrumentationSourceUid = sourceUid; 589 mInstrumentingWithBackgroundActivityStartPrivileges = hasBackgroundActivityStartPrivileges; 590 } 591 isInstrumenting()592 boolean isInstrumenting() { 593 return mInstrumenting; 594 } 595 596 /** Returns the uid of the active instrumentation source if there is one, otherwise -1. */ getInstrumentationSourceUid()597 int getInstrumentationSourceUid() { 598 return mInstrumentationSourceUid; 599 } 600 setPerceptible(boolean perceptible)601 public void setPerceptible(boolean perceptible) { 602 mPerceptible = perceptible; 603 } 604 isPerceptible()605 boolean isPerceptible() { 606 return mPerceptible; 607 } 608 609 @Override getChildCount()610 protected int getChildCount() { 611 return 0; 612 } 613 614 @Override getChildAt(int index)615 protected ConfigurationContainer getChildAt(int index) { 616 return null; 617 } 618 619 @Override getParent()620 protected ConfigurationContainer getParent() { 621 // Returning RootWindowContainer as the parent, so that this process controller always 622 // has full configuration and overrides (e.g. from display) are always added on top of 623 // global config. 624 return mAtm.mRootWindowContainer; 625 } 626 627 @HotPath(caller = HotPath.PROCESS_CHANGE) addPackage(String packageName)628 public void addPackage(String packageName) { 629 synchronized (mAtm.mGlobalLockWithoutBoost) { 630 mPkgList.add(packageName); 631 } 632 } 633 634 @HotPath(caller = HotPath.PROCESS_CHANGE) clearPackageList()635 public void clearPackageList() { 636 synchronized (mAtm.mGlobalLockWithoutBoost) { 637 mPkgList.clear(); 638 } 639 } 640 addActivityIfNeeded(ActivityRecord r)641 void addActivityIfNeeded(ActivityRecord r) { 642 // even if we already track this activity, note down that it has been launched 643 setLastActivityLaunchTime(r.lastLaunchTime); 644 if (mActivities.contains(r)) { 645 return; 646 } 647 mActivities.add(r); 648 mHasActivities = true; 649 if (mInactiveActivities != null) { 650 mInactiveActivities.remove(r); 651 } 652 updateActivityConfigurationListener(); 653 } 654 655 /** 656 * Indicates that the given activity is no longer active in this process. 657 * 658 * @param r The running activity to be removed. 659 * @param keepAssociation {@code true} if the activity still belongs to this process but will 660 * be removed soon, e.g. destroying. From the perspective of process 661 * priority, the process is not important if it only contains activities 662 * that are being destroyed. But the association is still needed to 663 * ensure all activities are reachable from this process. 664 */ removeActivity(ActivityRecord r, boolean keepAssociation)665 void removeActivity(ActivityRecord r, boolean keepAssociation) { 666 if (keepAssociation) { 667 if (mInactiveActivities == null) { 668 mInactiveActivities = new ArrayList<>(); 669 mInactiveActivities.add(r); 670 } else if (!mInactiveActivities.contains(r)) { 671 mInactiveActivities.add(r); 672 } 673 } else if (mInactiveActivities != null) { 674 mInactiveActivities.remove(r); 675 } 676 mActivities.remove(r); 677 mHasActivities = !mActivities.isEmpty(); 678 updateActivityConfigurationListener(); 679 } 680 clearActivities()681 void clearActivities() { 682 mInactiveActivities = null; 683 mActivities.clear(); 684 mHasActivities = false; 685 updateActivityConfigurationListener(); 686 } 687 688 @HotPath(caller = HotPath.OOM_ADJUSTMENT) hasActivities()689 public boolean hasActivities() { 690 return mHasActivities; 691 } 692 693 @HotPath(caller = HotPath.OOM_ADJUSTMENT) hasVisibleActivities()694 public boolean hasVisibleActivities() { 695 return (mActivityStateFlags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0; 696 } 697 hasActivityInVisibleTask()698 boolean hasActivityInVisibleTask() { 699 return (mActivityStateFlags & ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK) != 0; 700 } 701 702 @HotPath(caller = HotPath.LRU_UPDATE) hasActivitiesOrRecentTasks()703 public boolean hasActivitiesOrRecentTasks() { 704 return mHasActivities || mHasRecentTasks; 705 } 706 707 @Nullable getTopActivityDisplayArea()708 TaskDisplayArea getTopActivityDisplayArea() { 709 if (mActivities.isEmpty()) { 710 return null; 711 } 712 713 final int lastIndex = mActivities.size() - 1; 714 ActivityRecord topRecord = mActivities.get(lastIndex); 715 TaskDisplayArea displayArea = topRecord.getDisplayArea(); 716 717 for (int index = lastIndex - 1; index >= 0; --index) { 718 ActivityRecord nextRecord = mActivities.get(index); 719 TaskDisplayArea nextDisplayArea = nextRecord.getDisplayArea(); 720 if (nextRecord.compareTo(topRecord) > 0 && nextDisplayArea != null) { 721 topRecord = nextRecord; 722 displayArea = nextDisplayArea; 723 } 724 } 725 726 return displayArea; 727 } 728 729 /** 730 * Update the top resuming activity in process for pre-Q apps, only the top-most visible 731 * activities are allowed to be resumed per process. 732 * @return {@code true} if the activity is allowed to be resumed by compatibility 733 * restrictions, which the activity was the topmost visible activity in process or the app is 734 * targeting after Q. Note that non-focusable activity, in picture-in-picture mode for instance, 735 * does not count as a topmost activity. 736 */ updateTopResumingActivityInProcessIfNeeded(@onNull ActivityRecord activity)737 boolean updateTopResumingActivityInProcessIfNeeded(@NonNull ActivityRecord activity) { 738 if (mInfo.targetSdkVersion >= Q || mPreQTopResumedActivity == activity) { 739 return true; 740 } 741 742 if (!activity.isAttached()) { 743 // No need to update if the activity hasn't attach to any display. 744 return false; 745 } 746 747 boolean canUpdate = false; 748 final DisplayContent topDisplay = 749 (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isAttached()) 750 ? mPreQTopResumedActivity.mDisplayContent 751 : null; 752 // Update the topmost activity if current top activity is 753 // - not on any display OR 754 // - no longer visible OR 755 // - not focusable (in PiP mode for instance) 756 if (topDisplay == null 757 || !mPreQTopResumedActivity.isVisibleRequested() 758 || !mPreQTopResumedActivity.isFocusable()) { 759 canUpdate = true; 760 } 761 762 final DisplayContent display = activity.mDisplayContent; 763 // Update the topmost activity if the current top activity wasn't on top of the other one. 764 if (!canUpdate && topDisplay.compareTo(display) < 0) { 765 canUpdate = true; 766 } 767 768 // Update the topmost activity if the activity has higher z-order than the current 769 // top-resumed activity. 770 if (!canUpdate) { 771 final ActivityRecord ar = topDisplay.getActivity(r -> r == activity, 772 true /* traverseTopToBottom */, mPreQTopResumedActivity); 773 if (ar != null && ar != mPreQTopResumedActivity) { 774 canUpdate = true; 775 } 776 } 777 778 if (canUpdate) { 779 // Make sure the previous top activity in the process no longer be resumed. 780 if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) { 781 final TaskFragment taskFrag = mPreQTopResumedActivity.getTaskFragment(); 782 if (taskFrag != null) { 783 boolean userLeaving = taskFrag.shouldBeVisible(null); 784 taskFrag.startPausing(userLeaving, false /* uiSleeping */, 785 activity, "top-resumed-changed"); 786 } 787 } 788 mPreQTopResumedActivity = activity; 789 } 790 return canUpdate; 791 } 792 stopFreezingActivities()793 public void stopFreezingActivities() { 794 synchronized (mAtm.mGlobalLock) { 795 int i = mActivities.size(); 796 while (i > 0) { 797 i--; 798 mActivities.get(i).stopFreezingScreenLocked(true); 799 } 800 } 801 } 802 finishActivities()803 void finishActivities() { 804 ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities); 805 for (int i = 0; i < activities.size(); i++) { 806 final ActivityRecord r = activities.get(i); 807 if (!r.finishing && r.isInRootTaskLocked()) { 808 r.finishIfPossible("finish-heavy", true /* oomAdj */); 809 } 810 } 811 } 812 isInterestingToUser()813 public boolean isInterestingToUser() { 814 synchronized (mAtm.mGlobalLock) { 815 final int size = mActivities.size(); 816 for (int i = 0; i < size; i++) { 817 ActivityRecord r = mActivities.get(i); 818 if (r.isInterestingToUserLocked()) { 819 return true; 820 } 821 } 822 if (isEmbedded()) { 823 return true; 824 } 825 } 826 return false; 827 } 828 829 /** 830 * @return {@code true} if this process is rendering content on to a window shown by 831 * another process. 832 */ isEmbedded()833 private boolean isEmbedded() { 834 for (int i = mHostActivities.size() - 1; i >= 0; --i) { 835 final ActivityRecord r = mHostActivities.get(i); 836 if (r.isInterestingToUserLocked()) { 837 return true; 838 } 839 } 840 return false; 841 } 842 hasRunningActivity(String packageName)843 public boolean hasRunningActivity(String packageName) { 844 synchronized (mAtm.mGlobalLock) { 845 for (int i = mActivities.size() - 1; i >= 0; --i) { 846 final ActivityRecord r = mActivities.get(i); 847 if (packageName.equals(r.packageName)) { 848 return true; 849 } 850 } 851 } 852 return false; 853 } 854 855 // TODO(b/199277065): Re-assess how app-specific locales are applied based on UXR 856 // TODO(b/199277729): Consider whether we need to add special casing for edge cases like 857 // activity-embeddings etc. updateAppSpecificSettingsForAllActivitiesInPackage(String packageName, Integer nightMode, LocaleList localesOverride)858 void updateAppSpecificSettingsForAllActivitiesInPackage(String packageName, Integer nightMode, 859 LocaleList localesOverride) { 860 for (int i = mActivities.size() - 1; i >= 0; --i) { 861 final ActivityRecord r = mActivities.get(i); 862 // Activities from other packages could be sharing this process. Only propagate updates 863 // to those activities that are part of the package whose app-specific settings changed 864 if (packageName.equals(r.packageName) 865 && r.applyAppSpecificConfig(nightMode, localesOverride) 866 && r.isVisibleRequested()) { 867 r.ensureActivityConfiguration(0 /* globalChanges */, true /* preserveWindow */); 868 } 869 } 870 } 871 clearPackagePreferredForHomeActivities()872 public void clearPackagePreferredForHomeActivities() { 873 synchronized (mAtm.mGlobalLock) { 874 for (int i = mActivities.size() - 1; i >= 0; --i) { 875 final ActivityRecord r = mActivities.get(i); 876 if (r.isActivityTypeHome()) { 877 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 878 try { 879 ActivityThread.getPackageManager() 880 .clearPackagePreferredActivities(r.packageName); 881 } catch (RemoteException c) { 882 // pm is in same process, this will never happen. 883 } 884 } 885 } 886 } 887 } 888 hasStartedActivity(ActivityRecord launchedActivity)889 boolean hasStartedActivity(ActivityRecord launchedActivity) { 890 for (int i = mActivities.size() - 1; i >= 0; i--) { 891 final ActivityRecord activity = mActivities.get(i); 892 if (launchedActivity == activity) { 893 continue; 894 } 895 if (!activity.stopped) { 896 return true; 897 } 898 } 899 return false; 900 } 901 hasResumedActivity()902 boolean hasResumedActivity() { 903 return (mActivityStateFlags & ACTIVITY_STATE_FLAG_HAS_RESUMED) != 0; 904 } 905 updateIntentForHeavyWeightActivity(Intent intent)906 void updateIntentForHeavyWeightActivity(Intent intent) { 907 if (mActivities.isEmpty()) { 908 return; 909 } 910 ActivityRecord hist = mActivities.get(0); 911 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName); 912 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTask().mTaskId); 913 } 914 shouldKillProcessForRemovedTask(Task task)915 boolean shouldKillProcessForRemovedTask(Task task) { 916 for (int k = 0; k < mActivities.size(); k++) { 917 final ActivityRecord activity = mActivities.get(k); 918 if (!activity.stopped) { 919 // Don't kill process(es) that has an activity not stopped. 920 return false; 921 } 922 final Task otherTask = activity.getTask(); 923 if (task.mTaskId != otherTask.mTaskId && otherTask.inRecents) { 924 // Don't kill process(es) that has an activity in a different task that is 925 // also in recents. 926 return false; 927 } 928 } 929 return true; 930 } 931 releaseSomeActivities(String reason)932 void releaseSomeActivities(String reason) { 933 // Examine all activities currently running in the process. 934 // Candidate activities that can be destroyed. 935 ArrayList<ActivityRecord> candidates = null; 936 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this); 937 for (int i = 0; i < mActivities.size(); i++) { 938 final ActivityRecord r = mActivities.get(i); 939 // First, if we find an activity that is in the process of being destroyed, 940 // then we just aren't going to do anything for now; we want things to settle 941 // down before we try to prune more activities. 942 if (r.finishing || r.isState(DESTROYING, DESTROYED)) { 943 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); 944 return; 945 } 946 // Don't consider any activities that are currently not in a state where they 947 // can be destroyed. 948 if (r.isVisibleRequested() || !r.stopped || !r.hasSavedState() || !r.isDestroyable() 949 || r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING)) { 950 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); 951 continue; 952 } 953 954 if (r.getParent() != null) { 955 if (candidates == null) { 956 candidates = new ArrayList<>(); 957 } 958 candidates.add(r); 959 } 960 } 961 962 if (candidates != null) { 963 // Sort based on z-order in hierarchy. 964 candidates.sort(WindowContainer::compareTo); 965 // Release some older activities 966 int maxRelease = Math.max(candidates.size(), 1); 967 do { 968 final ActivityRecord r = candidates.remove(0); 969 if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + r 970 + " in state " + r.getState() + " for reason " + reason); 971 r.destroyImmediately(reason); 972 --maxRelease; 973 } while (maxRelease > 0); 974 } 975 } 976 977 /** 978 * Returns display UI context list which there is any app window shows or starting activities 979 * int this process. 980 */ getDisplayContextsWithErrorDialogs(List<Context> displayContexts)981 public void getDisplayContextsWithErrorDialogs(List<Context> displayContexts) { 982 if (displayContexts == null) { 983 return; 984 } 985 synchronized (mAtm.mGlobalLock) { 986 final RootWindowContainer root = mAtm.mWindowManager.mRoot; 987 root.getDisplayContextsWithNonToastVisibleWindows(mPid, displayContexts); 988 989 for (int i = mActivities.size() - 1; i >= 0; --i) { 990 final ActivityRecord r = mActivities.get(i); 991 final int displayId = r.getDisplayId(); 992 final Context c = root.getDisplayUiContext(displayId); 993 994 if (c != null && r.isVisibleRequested() && !displayContexts.contains(c)) { 995 displayContexts.add(c); 996 } 997 } 998 } 999 } 1000 1001 /** Adds an activity that hosts UI drawn by the current process. */ addHostActivity(ActivityRecord r)1002 void addHostActivity(ActivityRecord r) { 1003 if (mHostActivities.contains(r)) { 1004 return; 1005 } 1006 mHostActivities.add(r); 1007 } 1008 1009 /** Removes an activity that hosts UI drawn by the current process. */ removeHostActivity(ActivityRecord r)1010 void removeHostActivity(ActivityRecord r) { 1011 mHostActivities.remove(r); 1012 } 1013 1014 public interface ComputeOomAdjCallback { onVisibleActivity()1015 void onVisibleActivity(); onPausedActivity()1016 void onPausedActivity(); onStoppingActivity(boolean finishing)1017 void onStoppingActivity(boolean finishing); onOtherActivity()1018 void onOtherActivity(); 1019 } 1020 1021 /** 1022 * Returns the minimum task layer rank. It should only be called if {@link #hasActivities} 1023 * returns {@code true}. 1024 */ 1025 @HotPath(caller = HotPath.OOM_ADJUSTMENT) computeOomAdjFromActivities(ComputeOomAdjCallback callback)1026 public int computeOomAdjFromActivities(ComputeOomAdjCallback callback) { 1027 final int flags = mActivityStateFlags; 1028 if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) { 1029 callback.onVisibleActivity(); 1030 } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) { 1031 callback.onPausedActivity(); 1032 } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) { 1033 callback.onStoppingActivity( 1034 (flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0); 1035 } else { 1036 callback.onOtherActivity(); 1037 } 1038 return flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER; 1039 } 1040 computeProcessActivityState()1041 void computeProcessActivityState() { 1042 // Since there could be more than one activities in a process record, we don't need to 1043 // compute the OomAdj with each of them, just need to find out the activity with the 1044 // "best" state, the order would be visible, pausing, stopping... 1045 ActivityRecord.State bestInvisibleState = DESTROYED; 1046 boolean allStoppingFinishing = true; 1047 boolean visible = false; 1048 int minTaskLayer = Integer.MAX_VALUE; 1049 int stateFlags = 0; 1050 final boolean wasResumed = hasResumedActivity(); 1051 final boolean wasAnyVisible = (mActivityStateFlags 1052 & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0; 1053 for (int i = mActivities.size() - 1; i >= 0; i--) { 1054 final ActivityRecord r = mActivities.get(i); 1055 if (r.isVisible()) { 1056 stateFlags |= ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE; 1057 } 1058 final Task task = r.getTask(); 1059 if (task != null && task.mLayerRank != Task.LAYER_RANK_INVISIBLE) { 1060 stateFlags |= ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK; 1061 } 1062 if (r.isVisibleRequested()) { 1063 if (r.isState(RESUMED)) { 1064 stateFlags |= ACTIVITY_STATE_FLAG_HAS_RESUMED; 1065 } 1066 if (task != null && minTaskLayer > 0) { 1067 final int layer = task.mLayerRank; 1068 if (layer >= 0 && minTaskLayer > layer) { 1069 minTaskLayer = layer; 1070 } 1071 } 1072 visible = true; 1073 // continue the loop, in case there are multiple visible activities in 1074 // this process, we'd find out the one with the minimal layer, thus it'll 1075 // get a higher adj score. 1076 } else if (!visible && bestInvisibleState != PAUSING) { 1077 if (r.isState(PAUSING, PAUSED)) { 1078 bestInvisibleState = PAUSING; 1079 } else if (r.isState(STOPPING)) { 1080 bestInvisibleState = STOPPING; 1081 // Not "finishing" if any of activity isn't finishing. 1082 allStoppingFinishing &= r.finishing; 1083 } 1084 } 1085 } 1086 1087 stateFlags |= minTaskLayer & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER; 1088 if (visible) { 1089 stateFlags |= ACTIVITY_STATE_FLAG_IS_VISIBLE; 1090 } else if (bestInvisibleState == PAUSING) { 1091 stateFlags |= ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED; 1092 } else if (bestInvisibleState == STOPPING) { 1093 stateFlags |= ACTIVITY_STATE_FLAG_IS_STOPPING; 1094 if (allStoppingFinishing) { 1095 stateFlags |= ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING; 1096 } 1097 } 1098 mActivityStateFlags = stateFlags; 1099 1100 final boolean anyVisible = (stateFlags 1101 & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0; 1102 if (!wasAnyVisible && anyVisible) { 1103 mAtm.mVisibleActivityProcessTracker.onAnyActivityVisible(this); 1104 } else if (wasAnyVisible && !anyVisible) { 1105 mAtm.mVisibleActivityProcessTracker.onAllActivitiesInvisible(this); 1106 } else if (wasAnyVisible && !wasResumed && hasResumedActivity()) { 1107 mAtm.mVisibleActivityProcessTracker.onActivityResumedWhileVisible(this); 1108 } 1109 } 1110 1111 /** Called when the process has some oom related changes and it is going to update oom-adj. */ prepareOomAdjustment()1112 private void prepareOomAdjustment() { 1113 mAtm.mRootWindowContainer.rankTaskLayers(); 1114 mAtm.mTaskSupervisor.computeProcessActivityStateBatch(); 1115 } 1116 computeRelaunchReason()1117 public int computeRelaunchReason() { 1118 synchronized (mAtm.mGlobalLock) { 1119 final int activitiesSize = mActivities.size(); 1120 for (int i = activitiesSize - 1; i >= 0; i--) { 1121 final ActivityRecord r = mActivities.get(i); 1122 if (r.mRelaunchReason != RELAUNCH_REASON_NONE) { 1123 return r.mRelaunchReason; 1124 } 1125 } 1126 } 1127 return RELAUNCH_REASON_NONE; 1128 } 1129 1130 /** 1131 * Get the current dispatching timeout. If instrumentation is currently taking place, return 1132 * a longer value. Shorter timeout is returned otherwise. 1133 * @return The timeout in milliseconds 1134 */ getInputDispatchingTimeoutMillis()1135 public long getInputDispatchingTimeoutMillis() { 1136 synchronized (mAtm.mGlobalLock) { 1137 return isInstrumenting() || isUsingWrapper() 1138 ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MILLIS : 1139 DEFAULT_DISPATCHING_TIMEOUT_MILLIS; 1140 } 1141 } 1142 clearProfilerIfNeeded()1143 void clearProfilerIfNeeded() { 1144 // Posting on handler so WM lock isn't held when we call into AM. 1145 mAtm.mH.sendMessage(PooledLambda.obtainMessage( 1146 WindowProcessListener::clearProfilerIfNeeded, mListener)); 1147 } 1148 updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange, boolean updateOomAdj, boolean addPendingTopUid)1149 void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange, 1150 boolean updateOomAdj, boolean addPendingTopUid) { 1151 if (addPendingTopUid) { 1152 addToPendingTop(); 1153 } 1154 if (updateOomAdj) { 1155 prepareOomAdjustment(); 1156 } 1157 // Posting on handler so WM lock isn't held when we call into AM. 1158 final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo, 1159 mListener, updateServiceConnectionActivities, activityChange, updateOomAdj); 1160 mAtm.mH.sendMessage(m); 1161 } 1162 1163 /** Refreshes oom adjustment and process state of this process. */ scheduleUpdateOomAdj()1164 void scheduleUpdateOomAdj() { 1165 mAtm.mH.sendMessage(PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo, 1166 mListener, false /* updateServiceConnectionActivities */, 1167 false /* activityChange */, true /* updateOomAdj */)); 1168 } 1169 1170 /** Makes the process have top state before oom-adj is computed from a posted message. */ addToPendingTop()1171 void addToPendingTop() { 1172 mAtm.mAmInternal.addPendingTopUid(mUid, mPid, mThread); 1173 } 1174 updateServiceConnectionActivities()1175 void updateServiceConnectionActivities() { 1176 // Posting on handler so WM lock isn't held when we call into AM. 1177 mAtm.mH.sendMessage(PooledLambda.obtainMessage( 1178 WindowProcessListener::updateServiceConnectionActivities, mListener)); 1179 } 1180 setPendingUiCleanAndForceProcessStateUpTo(int newState)1181 void setPendingUiCleanAndForceProcessStateUpTo(int newState) { 1182 // Posting on handler so WM lock isn't held when we call into AM. 1183 final Message m = PooledLambda.obtainMessage( 1184 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo, 1185 mListener, newState); 1186 mAtm.mH.sendMessage(m); 1187 } 1188 isRemoved()1189 boolean isRemoved() { 1190 return mListener.isRemoved(); 1191 } 1192 shouldSetProfileProc()1193 private boolean shouldSetProfileProc() { 1194 return mAtm.mProfileApp != null && mAtm.mProfileApp.equals(mName) 1195 && (mAtm.mProfileProc == null || mAtm.mProfileProc == this); 1196 } 1197 createProfilerInfoIfNeeded()1198 ProfilerInfo createProfilerInfoIfNeeded() { 1199 final ProfilerInfo currentProfilerInfo = mAtm.mProfilerInfo; 1200 if (currentProfilerInfo == null || currentProfilerInfo.profileFile == null 1201 || !shouldSetProfileProc()) { 1202 return null; 1203 } 1204 if (currentProfilerInfo.profileFd != null) { 1205 try { 1206 currentProfilerInfo.profileFd = currentProfilerInfo.profileFd.dup(); 1207 } catch (IOException e) { 1208 currentProfilerInfo.closeFd(); 1209 } 1210 } 1211 return new ProfilerInfo(currentProfilerInfo); 1212 } 1213 onStartActivity(int topProcessState, ActivityInfo info)1214 void onStartActivity(int topProcessState, ActivityInfo info) { 1215 String packageName = null; 1216 if ((info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0 1217 || !"android".equals(info.packageName)) { 1218 // Don't add this if it is a platform component that is marked to run in multiple 1219 // processes, because this is actually part of the framework so doesn't make sense 1220 // to track as a separate apk in the process. 1221 packageName = info.packageName; 1222 } 1223 // update ActivityManagerService.PendingStartActivityUids list. 1224 if (topProcessState == ActivityManager.PROCESS_STATE_TOP) { 1225 mAtm.mAmInternal.addPendingTopUid(mUid, mPid, mThread); 1226 } 1227 prepareOomAdjustment(); 1228 // Posting the message at the front of queue so WM lock isn't held when we call into AM, 1229 // and the process state of starting activity can be updated quicker which will give it a 1230 // higher scheduling group. 1231 final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity, 1232 mListener, topProcessState, shouldSetProfileProc(), packageName, 1233 info.applicationInfo.longVersionCode); 1234 mAtm.mH.sendMessageAtFrontOfQueue(m); 1235 } 1236 appDied(String reason)1237 void appDied(String reason) { 1238 // Posting on handler so WM lock isn't held when we call into AM. 1239 final Message m = PooledLambda.obtainMessage( 1240 WindowProcessListener::appDied, mListener, reason); 1241 mAtm.mH.sendMessage(m); 1242 } 1243 1244 /** 1245 * Clean up the activities belonging to this process. 1246 * 1247 * @return {@code true} if the process has any visible activity. 1248 */ handleAppDied()1249 boolean handleAppDied() { 1250 mAtm.mTaskSupervisor.removeHistoryRecords(this); 1251 1252 boolean hasVisibleActivities = false; 1253 final boolean hasInactiveActivities = 1254 mInactiveActivities != null && !mInactiveActivities.isEmpty(); 1255 final ArrayList<ActivityRecord> activities = 1256 (mHasActivities || hasInactiveActivities) ? new ArrayList<>() : mActivities; 1257 if (mHasActivities) { 1258 activities.addAll(mActivities); 1259 } 1260 if (hasInactiveActivities) { 1261 // Make sure that all activities in this process are handled. 1262 activities.addAll(mInactiveActivities); 1263 } 1264 if (isRemoved()) { 1265 // The package of the died process should be force-stopped, so make its activities as 1266 // finishing to prevent the process from being started again if the next top (or being 1267 // visible) activity also resides in the same process. This must be done before removal. 1268 for (int i = activities.size() - 1; i >= 0; i--) { 1269 activities.get(i).makeFinishingLocked(); 1270 } 1271 } 1272 for (int i = activities.size() - 1; i >= 0; i--) { 1273 final ActivityRecord r = activities.get(i); 1274 if (r.isVisibleRequested() || r.isVisible()) { 1275 // While an activity launches a new activity, it's possible that the old activity 1276 // is already requested to be hidden (mVisibleRequested=false), but this visibility 1277 // is not yet committed, so isVisible()=true. 1278 hasVisibleActivities = true; 1279 } 1280 1281 final TaskFragment taskFragment = r.getTaskFragment(); 1282 if (taskFragment != null) { 1283 // There may be a pausing activity that hasn't shown any window and was requested 1284 // to be hidden. But pausing is also a visible state, it should be regarded as 1285 // visible, so the caller can know the next activity should be resumed. 1286 hasVisibleActivities |= taskFragment.handleAppDied(this); 1287 } 1288 r.handleAppDied(); 1289 } 1290 clearRecentTasks(); 1291 clearActivities(); 1292 1293 return hasVisibleActivities; 1294 } 1295 registerDisplayAreaConfigurationListener(@ullable DisplayArea displayArea)1296 void registerDisplayAreaConfigurationListener(@Nullable DisplayArea displayArea) { 1297 if (displayArea == null || displayArea.containsListener(this)) { 1298 return; 1299 } 1300 unregisterConfigurationListeners(); 1301 mDisplayArea = displayArea; 1302 displayArea.registerConfigurationChangeListener(this); 1303 } 1304 1305 @VisibleForTesting unregisterDisplayAreaConfigurationListener()1306 void unregisterDisplayAreaConfigurationListener() { 1307 if (mDisplayArea == null) { 1308 return; 1309 } 1310 mDisplayArea.unregisterConfigurationChangeListener(this); 1311 mDisplayArea = null; 1312 onMergedOverrideConfigurationChanged(Configuration.EMPTY); 1313 } 1314 registerActivityConfigurationListener(ActivityRecord activityRecord)1315 void registerActivityConfigurationListener(ActivityRecord activityRecord) { 1316 if (activityRecord == null || activityRecord.containsListener(this) 1317 // Check for the caller from outside of this class. 1318 || !mIsActivityConfigOverrideAllowed) { 1319 return; 1320 } 1321 unregisterConfigurationListeners(); 1322 mConfigActivityRecord = activityRecord; 1323 activityRecord.registerConfigurationChangeListener(this); 1324 } 1325 unregisterActivityConfigurationListener()1326 private void unregisterActivityConfigurationListener() { 1327 if (mConfigActivityRecord == null) { 1328 return; 1329 } 1330 mConfigActivityRecord.unregisterConfigurationChangeListener(this); 1331 mConfigActivityRecord = null; 1332 onMergedOverrideConfigurationChanged(Configuration.EMPTY); 1333 } 1334 1335 /** 1336 * A process can only register to one {@link WindowContainer} to listen to the override 1337 * configuration changes. Unregisters the existing listener if it has one before registers a 1338 * new one. 1339 */ unregisterConfigurationListeners()1340 private void unregisterConfigurationListeners() { 1341 unregisterActivityConfigurationListener(); 1342 unregisterDisplayAreaConfigurationListener(); 1343 } 1344 1345 /** 1346 * Check if activity configuration override for the activity process needs an update and perform 1347 * if needed. By default we try to override the process configuration to match the top activity 1348 * config to increase app compatibility with multi-window and multi-display. The process will 1349 * always track the configuration of the non-finishing activity last added to the process. 1350 */ updateActivityConfigurationListener()1351 private void updateActivityConfigurationListener() { 1352 if (!mIsActivityConfigOverrideAllowed) { 1353 return; 1354 } 1355 1356 for (int i = mActivities.size() - 1; i >= 0; i--) { 1357 final ActivityRecord activityRecord = mActivities.get(i); 1358 if (!activityRecord.finishing) { 1359 // Eligible activity is found, update listener. 1360 registerActivityConfigurationListener(activityRecord); 1361 return; 1362 } 1363 } 1364 1365 // No eligible activities found, let's remove the configuration listener. 1366 unregisterActivityConfigurationListener(); 1367 } 1368 1369 @Override onConfigurationChanged(Configuration newGlobalConfig)1370 public void onConfigurationChanged(Configuration newGlobalConfig) { 1371 super.onConfigurationChanged(newGlobalConfig); 1372 final Configuration config = getConfiguration(); 1373 if (mLastReportedConfiguration.equals(config)) { 1374 // Nothing changed. 1375 if (Build.IS_DEBUGGABLE && mHasImeService) { 1376 // TODO (b/135719017): Temporary log for debugging IME service. 1377 Slog.w(TAG_CONFIGURATION, "Current config: " + config 1378 + " unchanged for IME proc " + mName); 1379 } 1380 return; 1381 } 1382 1383 if (mPauseConfigurationDispatchCount > 0) { 1384 mHasPendingConfigurationChange = true; 1385 return; 1386 } 1387 dispatchConfiguration(config); 1388 } 1389 1390 @Override onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig)1391 public void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig) { 1392 super.onRequestedOverrideConfigurationChanged(mergedOverrideConfig); 1393 } 1394 1395 @Override resolveOverrideConfiguration(Configuration newParentConfig)1396 void resolveOverrideConfiguration(Configuration newParentConfig) { 1397 final Configuration requestedOverrideConfig = getRequestedOverrideConfiguration(); 1398 if (requestedOverrideConfig.assetsSeq != ASSETS_SEQ_UNDEFINED 1399 && newParentConfig.assetsSeq > requestedOverrideConfig.assetsSeq) { 1400 requestedOverrideConfig.assetsSeq = ASSETS_SEQ_UNDEFINED; 1401 } 1402 super.resolveOverrideConfiguration(newParentConfig); 1403 final Configuration resolvedConfig = getResolvedOverrideConfiguration(); 1404 // Make sure that we don't accidentally override the activity type. 1405 resolvedConfig.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED); 1406 // Activity has an independent ActivityRecord#mConfigurationSeq. If this process registers 1407 // activity configuration, its config seq shouldn't go backwards by activity configuration. 1408 // Otherwise if other places send wpc.getConfiguration() to client, the configuration may 1409 // be ignored due to the seq is older. 1410 resolvedConfig.seq = newParentConfig.seq; 1411 } 1412 dispatchConfiguration(Configuration config)1413 void dispatchConfiguration(Configuration config) { 1414 mHasPendingConfigurationChange = false; 1415 if (mThread == null) { 1416 if (Build.IS_DEBUGGABLE && mHasImeService) { 1417 // TODO (b/135719017): Temporary log for debugging IME service. 1418 Slog.w(TAG_CONFIGURATION, "Unable to send config for IME proc " + mName 1419 + ": no app thread"); 1420 } 1421 return; 1422 } 1423 1424 config.seq = mAtm.increaseConfigurationSeqLocked(); 1425 setLastReportedConfiguration(config); 1426 1427 // A cached process doesn't have running application components, so it is unnecessary to 1428 // notify the configuration change. The last-reported-configuration is still set because 1429 // setReportedProcState() should not write any fields that require WM lock. 1430 if (mRepProcState >= CACHED_CONFIG_PROC_STATE) { 1431 mHasCachedConfiguration = true; 1432 // Because there are 2 volatile accesses in setReportedProcState(): mRepProcState and 1433 // mHasCachedConfiguration, check again in case mRepProcState is changed but hasn't 1434 // read the change of mHasCachedConfiguration. 1435 if (mRepProcState >= CACHED_CONFIG_PROC_STATE) { 1436 return; 1437 } 1438 } 1439 1440 scheduleConfigurationChange(mThread, config); 1441 } 1442 scheduleConfigurationChange(IApplicationThread thread, Configuration config)1443 private void scheduleConfigurationChange(IApplicationThread thread, Configuration config) { 1444 ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending to proc %s new config %s", mName, 1445 config); 1446 if (Build.IS_DEBUGGABLE && mHasImeService) { 1447 // TODO (b/135719017): Temporary log for debugging IME service. 1448 Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config); 1449 } 1450 mHasCachedConfiguration = false; 1451 try { 1452 mAtm.getLifecycleManager().scheduleTransaction(thread, 1453 ConfigurationChangeItem.obtain(config)); 1454 } catch (Exception e) { 1455 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change: " + mOwner, e); 1456 } 1457 } 1458 setLastReportedConfiguration(Configuration config)1459 void setLastReportedConfiguration(Configuration config) { 1460 // Synchronize for the access from setReportedProcState(). 1461 synchronized (mLastReportedConfiguration) { 1462 mLastReportedConfiguration.setTo(config); 1463 } 1464 } 1465 pauseConfigurationDispatch()1466 void pauseConfigurationDispatch() { 1467 mPauseConfigurationDispatchCount++; 1468 } 1469 1470 /** Returns {@code true} if the configuration change is pending to dispatch. */ resumeConfigurationDispatch()1471 boolean resumeConfigurationDispatch() { 1472 if (mPauseConfigurationDispatchCount == 0) { 1473 return false; 1474 } 1475 mPauseConfigurationDispatchCount--; 1476 return mHasPendingConfigurationChange; 1477 } 1478 updateAssetConfiguration(int assetSeq)1479 void updateAssetConfiguration(int assetSeq) { 1480 // Update the process override configuration directly if the process configuration will 1481 // not be override from its activities. 1482 if (!mHasActivities || !mIsActivityConfigOverrideAllowed) { 1483 Configuration overrideConfig = new Configuration(getRequestedOverrideConfiguration()); 1484 overrideConfig.assetsSeq = assetSeq; 1485 onRequestedOverrideConfigurationChanged(overrideConfig); 1486 return; 1487 } 1488 1489 // Otherwise, we can just update the activity override configuration. 1490 for (int i = mActivities.size() - 1; i >= 0; i--) { 1491 ActivityRecord r = mActivities.get(i); 1492 Configuration overrideConfig = new Configuration(r.getRequestedOverrideConfiguration()); 1493 overrideConfig.assetsSeq = assetSeq; 1494 r.onRequestedOverrideConfigurationChanged(overrideConfig); 1495 if (r.isVisibleRequested()) { 1496 r.ensureActivityConfiguration(0, true); 1497 } 1498 } 1499 } 1500 1501 /** 1502 * This is called for sending {@link android.app.servertransaction.LaunchActivityItem}. 1503 * The caller must call {@link #setLastReportedConfiguration} if the delivered configuration 1504 * is newer. 1505 */ prepareConfigurationForLaunchingActivity()1506 Configuration prepareConfigurationForLaunchingActivity() { 1507 final Configuration config = getConfiguration(); 1508 if (mHasPendingConfigurationChange) { 1509 mHasPendingConfigurationChange = false; 1510 // The global configuration may not change, so the client process may have the same 1511 // config seq. This increment ensures that the client won't ignore the configuration. 1512 config.seq = mAtm.increaseConfigurationSeqLocked(); 1513 } 1514 // LaunchActivityItem includes the latest process configuration. 1515 mHasCachedConfiguration = false; 1516 return config; 1517 } 1518 1519 /** Returns the total time (in milliseconds) spent executing in both user and system code. */ getCpuTime()1520 public long getCpuTime() { 1521 return mListener.getCpuTime(); 1522 } 1523 addRecentTask(Task task)1524 void addRecentTask(Task task) { 1525 mRecentTasks.add(task); 1526 mHasRecentTasks = true; 1527 } 1528 removeRecentTask(Task task)1529 void removeRecentTask(Task task) { 1530 mRecentTasks.remove(task); 1531 mHasRecentTasks = !mRecentTasks.isEmpty(); 1532 } 1533 1534 @HotPath(caller = HotPath.OOM_ADJUSTMENT) hasRecentTasks()1535 public boolean hasRecentTasks() { 1536 return mHasRecentTasks; 1537 } 1538 clearRecentTasks()1539 void clearRecentTasks() { 1540 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1541 mRecentTasks.get(i).clearRootProcess(); 1542 } 1543 mRecentTasks.clear(); 1544 mHasRecentTasks = false; 1545 } 1546 appEarlyNotResponding(String annotation, Runnable killAppCallback)1547 public void appEarlyNotResponding(String annotation, Runnable killAppCallback) { 1548 Runnable targetRunnable = null; 1549 synchronized (mAtm.mGlobalLock) { 1550 if (mAtm.mController == null) { 1551 return; 1552 } 1553 1554 try { 1555 // 0 == continue, -1 = kill process immediately 1556 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation); 1557 if (res < 0 && mPid != MY_PID) { 1558 targetRunnable = killAppCallback; 1559 } 1560 } catch (RemoteException e) { 1561 mAtm.mController = null; 1562 Watchdog.getInstance().setActivityController(null); 1563 } 1564 } 1565 if (targetRunnable != null) { 1566 targetRunnable.run(); 1567 } 1568 } 1569 appNotResponding(String info, Runnable killAppCallback, Runnable serviceTimeoutCallback)1570 public boolean appNotResponding(String info, Runnable killAppCallback, 1571 Runnable serviceTimeoutCallback) { 1572 Runnable targetRunnable = null; 1573 synchronized (mAtm.mGlobalLock) { 1574 if (mAtm.mController == null) { 1575 return false; 1576 } 1577 1578 try { 1579 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 1580 int res = mAtm.mController.appNotResponding(mName, mPid, info); 1581 if (res != 0) { 1582 if (res < 0 && mPid != MY_PID) { 1583 targetRunnable = killAppCallback; 1584 } else { 1585 targetRunnable = serviceTimeoutCallback; 1586 } 1587 } 1588 } catch (RemoteException e) { 1589 mAtm.mController = null; 1590 Watchdog.getInstance().setActivityController(null); 1591 return false; 1592 } 1593 } 1594 if (targetRunnable != null) { 1595 // Execute runnable outside WM lock since the runnable will hold AM lock 1596 targetRunnable.run(); 1597 return true; 1598 } 1599 return false; 1600 } 1601 1602 /** 1603 * Called to notify {@link WindowProcessController} of a started service. 1604 * 1605 * @param serviceInfo information describing the started service. 1606 */ onServiceStarted(ServiceInfo serviceInfo)1607 public void onServiceStarted(ServiceInfo serviceInfo) { 1608 String permission = serviceInfo.permission; 1609 if (permission == null) { 1610 return; 1611 } 1612 1613 // TODO: Audit remaining services for disabling activity override (Wallpaper, Dream, etc). 1614 switch (permission) { 1615 case Manifest.permission.BIND_INPUT_METHOD: 1616 mHasImeService = true; 1617 // Fall-through 1618 case Manifest.permission.BIND_ACCESSIBILITY_SERVICE: 1619 case Manifest.permission.BIND_VOICE_INTERACTION: 1620 // We want to avoid overriding the config of these services with that of the 1621 // activity as it could lead to incorrect display metrics. For ex, IME services 1622 // expect their config to match the config of the display with the IME window 1623 // showing. 1624 // If the configuration has been overridden by previous activity, empty it. 1625 mIsActivityConfigOverrideAllowed = false; 1626 unregisterActivityConfigurationListener(); 1627 break; 1628 default: 1629 break; 1630 } 1631 } 1632 1633 @HotPath(caller = HotPath.OOM_ADJUSTMENT) onTopProcChanged()1634 public void onTopProcChanged() { 1635 if (mAtm.mVrController.isInterestingToSchedGroup()) { 1636 mAtm.mH.post(() -> { 1637 synchronized (mAtm.mGlobalLock) { 1638 mAtm.mVrController.onTopProcChangedLocked(this); 1639 } 1640 }); 1641 } 1642 } 1643 1644 @HotPath(caller = HotPath.OOM_ADJUSTMENT) isHomeProcess()1645 public boolean isHomeProcess() { 1646 return this == mAtm.mHomeProcess; 1647 } 1648 1649 @HotPath(caller = HotPath.OOM_ADJUSTMENT) isPreviousProcess()1650 public boolean isPreviousProcess() { 1651 return this == mAtm.mPreviousProcess; 1652 } 1653 1654 @HotPath(caller = HotPath.OOM_ADJUSTMENT) isHeavyWeightProcess()1655 public boolean isHeavyWeightProcess() { 1656 return this == mAtm.mHeavyWeightProcess; 1657 } 1658 setRunningRecentsAnimation(boolean running)1659 void setRunningRecentsAnimation(boolean running) { 1660 if (mRunningRecentsAnimation == running) { 1661 return; 1662 } 1663 mRunningRecentsAnimation = running; 1664 updateRunningRemoteOrRecentsAnimation(); 1665 } 1666 setRunningRemoteAnimation(boolean running)1667 void setRunningRemoteAnimation(boolean running) { 1668 if (mRunningRemoteAnimation == running) { 1669 return; 1670 } 1671 mRunningRemoteAnimation = running; 1672 updateRunningRemoteOrRecentsAnimation(); 1673 } 1674 updateRunningRemoteOrRecentsAnimation()1675 void updateRunningRemoteOrRecentsAnimation() { 1676 // Posting on handler so WM lock isn't held when we call into AM. 1677 mAtm.mH.sendMessage(PooledLambda.obtainMessage( 1678 WindowProcessListener::setRunningRemoteAnimation, mListener, 1679 isRunningRemoteTransition())); 1680 } 1681 isRunningRemoteTransition()1682 boolean isRunningRemoteTransition() { 1683 return mRunningRecentsAnimation || mRunningRemoteAnimation; 1684 } 1685 1686 /** Adjusts scheduling group for animation. This method MUST NOT be called inside WM lock. */ setRunningAnimationUnsafe()1687 void setRunningAnimationUnsafe() { 1688 mListener.setRunningRemoteAnimation(true); 1689 } 1690 1691 @Override toString()1692 public String toString() { 1693 return mOwner != null ? mOwner.toString() : null; 1694 } 1695 dump(PrintWriter pw, String prefix)1696 public void dump(PrintWriter pw, String prefix) { 1697 synchronized (mAtm.mGlobalLock) { 1698 if (mActivities.size() > 0) { 1699 pw.print(prefix); pw.println("Activities:"); 1700 for (int i = 0; i < mActivities.size(); i++) { 1701 pw.print(prefix); pw.print(" - "); pw.println(mActivities.get(i)); 1702 } 1703 } 1704 1705 if (mRecentTasks.size() > 0) { 1706 pw.println(prefix + "Recent Tasks:"); 1707 for (int i = 0; i < mRecentTasks.size(); i++) { 1708 pw.println(prefix + " - " + mRecentTasks.get(i)); 1709 } 1710 } 1711 1712 if (mVrThreadTid != 0) { 1713 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid); 1714 } 1715 1716 mBgLaunchController.dump(pw, prefix); 1717 } 1718 pw.println(prefix + " Configuration=" + getConfiguration()); 1719 pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration()); 1720 pw.println(prefix + " mLastReportedConfiguration=" + (mHasCachedConfiguration 1721 ? ("(cached) " + mLastReportedConfiguration) : mLastReportedConfiguration)); 1722 1723 final int stateFlags = mActivityStateFlags; 1724 if (stateFlags != ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER) { 1725 pw.print(prefix + " mActivityStateFlags="); 1726 if ((stateFlags & ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE) != 0) { 1727 pw.print("W|"); 1728 } 1729 if ((stateFlags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) { 1730 pw.print("V|"); 1731 if ((stateFlags & ACTIVITY_STATE_FLAG_HAS_RESUMED) != 0) { 1732 pw.print("R|"); 1733 } 1734 } else if ((stateFlags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) { 1735 pw.print("P|"); 1736 } else if ((stateFlags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) { 1737 pw.print("S|"); 1738 if ((stateFlags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0) { 1739 pw.print("F|"); 1740 } 1741 } 1742 final int taskLayer = stateFlags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER; 1743 if (taskLayer != ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER) { 1744 pw.print("taskLayer=" + taskLayer); 1745 } 1746 pw.println(); 1747 } 1748 } 1749 dumpDebug(ProtoOutputStream proto, long fieldId)1750 void dumpDebug(ProtoOutputStream proto, long fieldId) { 1751 mListener.dumpDebug(proto, fieldId); 1752 } 1753 } 1754