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