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