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