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