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.os.Build.VERSION_CODES.Q; 21 import static android.view.Display.INVALID_DISPLAY; 22 23 import static com.android.server.am.ActivityManagerService.MY_PID; 24 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED; 25 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; 26 import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; 27 import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; 28 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; 29 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; 30 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION; 31 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE; 32 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; 33 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE; 34 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 35 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 36 import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS; 37 import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS; 38 import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS; 39 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; 40 41 import android.annotation.NonNull; 42 import android.app.Activity; 43 import android.app.ActivityThread; 44 import android.app.IApplicationThread; 45 import android.app.ProfilerInfo; 46 import android.app.servertransaction.ConfigurationChangeItem; 47 import android.content.Intent; 48 import android.content.pm.ActivityInfo; 49 import android.content.pm.ApplicationInfo; 50 import android.content.res.Configuration; 51 import android.os.Message; 52 import android.os.RemoteException; 53 import android.os.SystemClock; 54 import android.util.ArraySet; 55 import android.util.Log; 56 import android.util.Slog; 57 import android.util.proto.ProtoOutputStream; 58 import android.view.IRemoteAnimationRunner; 59 60 import com.android.internal.annotations.VisibleForTesting; 61 import com.android.internal.app.HeavyWeightSwitcherActivity; 62 import com.android.internal.util.function.pooled.PooledLambda; 63 import com.android.server.Watchdog; 64 import com.android.server.wm.ActivityTaskManagerService.HotPath; 65 66 import java.io.IOException; 67 import java.io.PrintWriter; 68 import java.util.ArrayList; 69 70 /** 71 * The Activity Manager (AM) package manages the lifecycle of processes in the system through 72 * ProcessRecord. However, it is important for the Window Manager (WM) package to be aware 73 * of the processes and their state since it affects how WM manages windows and activities. This 74 * class that allows the ProcessRecord object in the AM package to communicate important 75 * changes to its state to the WM package in a structured way. WM package also uses 76 * {@link WindowProcessListener} to request changes to the process state on the AM side. 77 * Note that public calls into this class are assumed to be originating from outside the 78 * window manager so the window manager lock is held and appropriate permissions are checked before 79 * calls are allowed to proceed. 80 */ 81 public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer> 82 implements ConfigurationContainerListener { 83 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM; 84 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 85 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; 86 87 // all about the first app in the process 88 final ApplicationInfo mInfo; 89 final String mName; 90 final int mUid; 91 // The process of this application; 0 if none 92 private volatile int mPid; 93 // user of process. 94 final int mUserId; 95 // The owner of this window process controller object. Mainly for identification when we 96 // communicate back to the activity manager side. 97 public final Object mOwner; 98 // List of packages running in the process 99 final ArraySet<String> mPkgList = new ArraySet<>(); 100 private final WindowProcessListener mListener; 101 private final ActivityTaskManagerService mAtm; 102 // The actual proc... may be null only if 'persistent' is true (in which case we are in the 103 // process of launching the app) 104 private IApplicationThread mThread; 105 // Currently desired scheduling class 106 private volatile int mCurSchedGroup; 107 // Currently computed process state 108 private volatile int mCurProcState = PROCESS_STATE_NONEXISTENT; 109 // Last reported process state; 110 private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT; 111 // are we in the process of crashing? 112 private volatile boolean mCrashing; 113 // does the app have a not responding dialog? 114 private volatile boolean mNotResponding; 115 // always keep this application running? 116 private volatile boolean mPersistent; 117 // The ABI this process was launched with 118 private volatile String mRequiredAbi; 119 // Running any services that are foreground? 120 private volatile boolean mHasForegroundServices; 121 // Running any activities that are foreground? 122 private volatile boolean mHasForegroundActivities; 123 // Are there any client services with activities? 124 private volatile boolean mHasClientActivities; 125 // Is this process currently showing a non-activity UI that the user is interacting with? 126 // E.g. The status bar when it is expanded, but not when it is minimized. When true the process 127 // will be set to use the ProcessList#SCHED_GROUP_TOP_APP scheduling group to boost performance. 128 private volatile boolean mHasTopUi; 129 // Is the process currently showing a non-activity UI that overlays on-top of activity UIs on 130 // screen. E.g. display a window of type 131 // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY When true the process will 132 // oom adj score will be set to ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance 133 // of the process getting killed. 134 private volatile boolean mHasOverlayUi; 135 // Want to clean up resources from showing UI? 136 private volatile boolean mPendingUiClean; 137 // The time we sent the last interaction event 138 private volatile long mInteractionEventTime; 139 // When we became foreground for interaction purposes 140 private volatile long mFgInteractionTime; 141 // When (uptime) the process last became unimportant 142 private volatile long mWhenUnimportant; 143 // was app launched for debugging? 144 private volatile boolean mDebugging; 145 // Active instrumentation running in process? 146 private volatile boolean mInstrumenting; 147 // Active instrumentation with background activity starts privilege running in process? 148 private volatile boolean mInstrumentingWithBackgroundActivityStartPrivileges; 149 // This process it perceptible by the user. 150 private volatile boolean mPerceptible; 151 // Set to true when process was launched with a wrapper attached 152 private volatile boolean mUsingWrapper; 153 // Set to true if this process is currently temporarily whitelisted to start activities even if 154 // it's not in the foreground 155 private volatile boolean mAllowBackgroundActivityStarts; 156 // Set of UIDs of clients currently bound to this process 157 private volatile ArraySet<Integer> mBoundClientUids = new ArraySet<Integer>(); 158 159 // Thread currently set for VR scheduling 160 int mVrThreadTid; 161 162 // all activities running in the process 163 private final ArrayList<ActivityRecord> mActivities = new ArrayList<>(); 164 // any tasks this process had run root activities in 165 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>(); 166 // The most recent top-most activity that was resumed in the process for pre-Q app. 167 private ActivityRecord mPreQTopResumedActivity = null; 168 // The last time an activity was launched in the process 169 private long mLastActivityLaunchTime; 170 // The last time an activity was finished in the process while the process participated 171 // in a visible task 172 private long mLastActivityFinishTime; 173 174 // Last configuration that was reported to the process. 175 private final Configuration mLastReportedConfiguration; 176 // Registered display id as a listener to override config change 177 private int mDisplayId; 178 179 /** Whether our process is currently running a {@link RecentsAnimation} */ 180 private boolean mRunningRecentsAnimation; 181 182 /** Whether our process is currently running a {@link IRemoteAnimationRunner} */ 183 private boolean mRunningRemoteAnimation; 184 WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info, String name, int uid, int userId, Object owner, WindowProcessListener listener)185 public WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info, 186 String name, int uid, int userId, Object owner, WindowProcessListener listener) { 187 mInfo = info; 188 mName = name; 189 mUid = uid; 190 mUserId = userId; 191 mOwner = owner; 192 mListener = listener; 193 mAtm = atm; 194 mLastReportedConfiguration = new Configuration(); 195 mDisplayId = INVALID_DISPLAY; 196 if (atm != null) { 197 onConfigurationChanged(atm.getGlobalConfiguration()); 198 } 199 } 200 setPid(int pid)201 public void setPid(int pid) { 202 mPid = pid; 203 } 204 getPid()205 public int getPid() { 206 return mPid; 207 } 208 209 @HotPath(caller = HotPath.PROCESS_CHANGE) setThread(IApplicationThread thread)210 public void setThread(IApplicationThread thread) { 211 synchronized (mAtm.mGlobalLockWithoutBoost) { 212 mThread = thread; 213 } 214 } 215 getThread()216 IApplicationThread getThread() { 217 return mThread; 218 } 219 hasThread()220 boolean hasThread() { 221 return mThread != null; 222 } 223 setCurrentSchedulingGroup(int curSchedGroup)224 public void setCurrentSchedulingGroup(int curSchedGroup) { 225 mCurSchedGroup = curSchedGroup; 226 } 227 getCurrentSchedulingGroup()228 int getCurrentSchedulingGroup() { 229 return mCurSchedGroup; 230 } 231 setCurrentProcState(int curProcState)232 public void setCurrentProcState(int curProcState) { 233 mCurProcState = curProcState; 234 } 235 getCurrentProcState()236 int getCurrentProcState() { 237 return mCurProcState; 238 } 239 setReportedProcState(int repProcState)240 public void setReportedProcState(int repProcState) { 241 mRepProcState = repProcState; 242 } 243 getReportedProcState()244 int getReportedProcState() { 245 return mRepProcState; 246 } 247 setCrashing(boolean crashing)248 public void setCrashing(boolean crashing) { 249 mCrashing = crashing; 250 } 251 isCrashing()252 boolean isCrashing() { 253 return mCrashing; 254 } 255 setNotResponding(boolean notResponding)256 public void setNotResponding(boolean notResponding) { 257 mNotResponding = notResponding; 258 } 259 isNotResponding()260 boolean isNotResponding() { 261 return mNotResponding; 262 } 263 setPersistent(boolean persistent)264 public void setPersistent(boolean persistent) { 265 mPersistent = persistent; 266 } 267 isPersistent()268 boolean isPersistent() { 269 return mPersistent; 270 } 271 setHasForegroundServices(boolean hasForegroundServices)272 public void setHasForegroundServices(boolean hasForegroundServices) { 273 mHasForegroundServices = hasForegroundServices; 274 } 275 hasForegroundServices()276 boolean hasForegroundServices() { 277 return mHasForegroundServices; 278 } 279 setHasForegroundActivities(boolean hasForegroundActivities)280 public void setHasForegroundActivities(boolean hasForegroundActivities) { 281 mHasForegroundActivities = hasForegroundActivities; 282 } 283 hasForegroundActivities()284 boolean hasForegroundActivities() { 285 return mHasForegroundActivities; 286 } 287 setHasClientActivities(boolean hasClientActivities)288 public void setHasClientActivities(boolean hasClientActivities) { 289 mHasClientActivities = hasClientActivities; 290 } 291 hasClientActivities()292 boolean hasClientActivities() { 293 return mHasClientActivities; 294 } 295 setHasTopUi(boolean hasTopUi)296 public void setHasTopUi(boolean hasTopUi) { 297 mHasTopUi = hasTopUi; 298 } 299 hasTopUi()300 boolean hasTopUi() { 301 return mHasTopUi; 302 } 303 setHasOverlayUi(boolean hasOverlayUi)304 public void setHasOverlayUi(boolean hasOverlayUi) { 305 mHasOverlayUi = hasOverlayUi; 306 } 307 hasOverlayUi()308 boolean hasOverlayUi() { 309 return mHasOverlayUi; 310 } 311 setPendingUiClean(boolean hasPendingUiClean)312 public void setPendingUiClean(boolean hasPendingUiClean) { 313 mPendingUiClean = hasPendingUiClean; 314 } 315 hasPendingUiClean()316 boolean hasPendingUiClean() { 317 return mPendingUiClean; 318 } 319 320 /** @return {@code true} if the process registered to a display as a config listener. */ registeredForDisplayConfigChanges()321 boolean registeredForDisplayConfigChanges() { 322 return mDisplayId != INVALID_DISPLAY; 323 } 324 postPendingUiCleanMsg(boolean pendingUiClean)325 void postPendingUiCleanMsg(boolean pendingUiClean) { 326 if (mListener == null) return; 327 // Posting on handler so WM lock isn't held when we call into AM. 328 final Message m = PooledLambda.obtainMessage( 329 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean); 330 mAtm.mH.sendMessage(m); 331 } 332 setInteractionEventTime(long interactionEventTime)333 public void setInteractionEventTime(long interactionEventTime) { 334 mInteractionEventTime = interactionEventTime; 335 } 336 getInteractionEventTime()337 long getInteractionEventTime() { 338 return mInteractionEventTime; 339 } 340 setFgInteractionTime(long fgInteractionTime)341 public void setFgInteractionTime(long fgInteractionTime) { 342 mFgInteractionTime = fgInteractionTime; 343 } 344 getFgInteractionTime()345 long getFgInteractionTime() { 346 return mFgInteractionTime; 347 } 348 setWhenUnimportant(long whenUnimportant)349 public void setWhenUnimportant(long whenUnimportant) { 350 mWhenUnimportant = whenUnimportant; 351 } 352 getWhenUnimportant()353 long getWhenUnimportant() { 354 return mWhenUnimportant; 355 } 356 setRequiredAbi(String requiredAbi)357 public void setRequiredAbi(String requiredAbi) { 358 mRequiredAbi = requiredAbi; 359 } 360 getRequiredAbi()361 String getRequiredAbi() { 362 return mRequiredAbi; 363 } 364 365 /** Returns ID of display overriding the configuration for this process, or 366 * INVALID_DISPLAY if no display is overriding. */ 367 @VisibleForTesting getDisplayId()368 int getDisplayId() { 369 return mDisplayId; 370 } 371 setDebugging(boolean debugging)372 public void setDebugging(boolean debugging) { 373 mDebugging = debugging; 374 } 375 isDebugging()376 boolean isDebugging() { 377 return mDebugging; 378 } 379 setUsingWrapper(boolean usingWrapper)380 public void setUsingWrapper(boolean usingWrapper) { 381 mUsingWrapper = usingWrapper; 382 } 383 isUsingWrapper()384 boolean isUsingWrapper() { 385 return mUsingWrapper; 386 } 387 setLastActivityLaunchTime(long launchTime)388 void setLastActivityLaunchTime(long launchTime) { 389 if (launchTime <= mLastActivityLaunchTime) { 390 return; 391 } 392 mLastActivityLaunchTime = launchTime; 393 } 394 setLastActivityFinishTimeIfNeeded(long finishTime)395 void setLastActivityFinishTimeIfNeeded(long finishTime) { 396 if (finishTime <= mLastActivityFinishTime || !hasActivityInVisibleTask()) { 397 return; 398 } 399 mLastActivityFinishTime = finishTime; 400 } 401 setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts)402 public void setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts) { 403 mAllowBackgroundActivityStarts = allowBackgroundActivityStarts; 404 } 405 areBackgroundActivityStartsAllowed()406 boolean areBackgroundActivityStartsAllowed() { 407 // allow if the whitelisting flag was explicitly set 408 if (mAllowBackgroundActivityStarts) { 409 return true; 410 } 411 // allow if any activity in the caller has either started or finished very recently, and 412 // it must be started or finished after last stop app switches time. 413 final long now = SystemClock.uptimeMillis(); 414 if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS 415 || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) { 416 // if activity is started and finished before stop app switch time, we should not 417 // let app to be able to start background activity even it's in grace period. 418 if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime() 419 || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) { 420 return true; 421 } 422 } 423 // allow if the proc is instrumenting with background activity starts privs 424 if (mInstrumentingWithBackgroundActivityStartPrivileges) { 425 return true; 426 } 427 // allow if the caller has an activity in any foreground task 428 if (hasActivityInVisibleTask()) { 429 return true; 430 } 431 // allow if the caller is bound by a UID that's currently foreground 432 if (isBoundByForegroundUid()) { 433 return true; 434 } 435 return false; 436 } 437 isBoundByForegroundUid()438 private boolean isBoundByForegroundUid() { 439 for (int i = mBoundClientUids.size() - 1; i >= 0; --i) { 440 if (mAtm.isUidForeground(mBoundClientUids.valueAt(i))) { 441 return true; 442 } 443 } 444 return false; 445 } 446 setBoundClientUids(ArraySet<Integer> boundClientUids)447 public void setBoundClientUids(ArraySet<Integer> boundClientUids) { 448 mBoundClientUids = boundClientUids; 449 } 450 setInstrumenting(boolean instrumenting, boolean hasBackgroundActivityStartPrivileges)451 public void setInstrumenting(boolean instrumenting, 452 boolean hasBackgroundActivityStartPrivileges) { 453 mInstrumenting = instrumenting; 454 mInstrumentingWithBackgroundActivityStartPrivileges = hasBackgroundActivityStartPrivileges; 455 } 456 isInstrumenting()457 boolean isInstrumenting() { 458 return mInstrumenting; 459 } 460 setPerceptible(boolean perceptible)461 public void setPerceptible(boolean perceptible) { 462 mPerceptible = perceptible; 463 } 464 isPerceptible()465 boolean isPerceptible() { 466 return mPerceptible; 467 } 468 469 @Override getChildCount()470 protected int getChildCount() { 471 return 0; 472 } 473 474 @Override getChildAt(int index)475 protected ConfigurationContainer getChildAt(int index) { 476 return null; 477 } 478 479 @Override getParent()480 protected ConfigurationContainer getParent() { 481 return null; 482 } 483 484 @HotPath(caller = HotPath.PROCESS_CHANGE) addPackage(String packageName)485 public void addPackage(String packageName) { 486 synchronized (mAtm.mGlobalLockWithoutBoost) { 487 mPkgList.add(packageName); 488 } 489 } 490 491 @HotPath(caller = HotPath.PROCESS_CHANGE) clearPackageList()492 public void clearPackageList() { 493 synchronized (mAtm.mGlobalLockWithoutBoost) { 494 mPkgList.clear(); 495 } 496 } 497 addActivityIfNeeded(ActivityRecord r)498 void addActivityIfNeeded(ActivityRecord r) { 499 // even if we already track this activity, note down that it has been launched 500 setLastActivityLaunchTime(r.lastLaunchTime); 501 if (mActivities.contains(r)) { 502 return; 503 } 504 mActivities.add(r); 505 } 506 removeActivity(ActivityRecord r)507 void removeActivity(ActivityRecord r) { 508 mActivities.remove(r); 509 } 510 makeFinishingForProcessRemoved()511 void makeFinishingForProcessRemoved() { 512 for (int i = mActivities.size() - 1; i >= 0; --i) { 513 mActivities.get(i).makeFinishingLocked(); 514 } 515 } 516 clearActivities()517 void clearActivities() { 518 mActivities.clear(); 519 } 520 521 @HotPath(caller = HotPath.OOM_ADJUSTMENT) hasActivities()522 public boolean hasActivities() { 523 synchronized (mAtm.mGlobalLockWithoutBoost) { 524 return !mActivities.isEmpty(); 525 } 526 } 527 528 @HotPath(caller = HotPath.OOM_ADJUSTMENT) hasVisibleActivities()529 public boolean hasVisibleActivities() { 530 synchronized (mAtm.mGlobalLockWithoutBoost) { 531 for (int i = mActivities.size() - 1; i >= 0; --i) { 532 final ActivityRecord r = mActivities.get(i); 533 if (r.visible) { 534 return true; 535 } 536 } 537 } 538 return false; 539 } 540 541 @HotPath(caller = HotPath.LRU_UPDATE) hasActivitiesOrRecentTasks()542 public boolean hasActivitiesOrRecentTasks() { 543 synchronized (mAtm.mGlobalLockWithoutBoost) { 544 return !mActivities.isEmpty() || !mRecentTasks.isEmpty(); 545 } 546 } 547 hasActivityInVisibleTask()548 private boolean hasActivityInVisibleTask() { 549 for (int i = mActivities.size() - 1; i >= 0; --i) { 550 TaskRecord task = mActivities.get(i).getTaskRecord(); 551 if (task == null) { 552 continue; 553 } 554 ActivityRecord topActivity = task.getTopActivity(); 555 if (topActivity != null && topActivity.visible) { 556 return true; 557 } 558 } 559 return false; 560 } 561 562 /** 563 * Update the top resuming activity in process for pre-Q apps, only the top-most visible 564 * activities are allowed to be resumed per process. 565 * @return {@code true} if the activity is allowed to be resumed by compatibility 566 * restrictions, which the activity was the topmost visible activity in process or the app is 567 * targeting after Q. Note that non-focusable activity, in picture-in-picture mode for instance, 568 * does not count as a topmost activity. 569 */ updateTopResumingActivityInProcessIfNeeded(@onNull ActivityRecord activity)570 boolean updateTopResumingActivityInProcessIfNeeded(@NonNull ActivityRecord activity) { 571 if (mInfo.targetSdkVersion >= Q || mPreQTopResumedActivity == activity) { 572 return true; 573 } 574 575 final ActivityDisplay display = activity.getDisplay(); 576 if (display == null) { 577 // No need to update if the activity hasn't attach to any display. 578 return false; 579 } 580 581 boolean canUpdate = false; 582 final ActivityDisplay topDisplay = 583 mPreQTopResumedActivity != null ? mPreQTopResumedActivity.getDisplay() : null; 584 // Update the topmost activity if current top activity is 585 // - not on any display OR 586 // - no longer visible OR 587 // - not focusable (in PiP mode for instance) 588 if (topDisplay == null 589 || !mPreQTopResumedActivity.visible 590 || !mPreQTopResumedActivity.isFocusable()) { 591 canUpdate = true; 592 } 593 594 // Update the topmost activity if the current top activity wasn't on top of the other one. 595 if (!canUpdate && topDisplay.mDisplayContent.compareTo(display.mDisplayContent) < 0) { 596 canUpdate = true; 597 } 598 599 // Compare the z-order of ActivityStacks if both activities landed on same display. 600 if (display == topDisplay 601 && mPreQTopResumedActivity.getActivityStack().mTaskStack.compareTo( 602 activity.getActivityStack().mTaskStack) <= 0) { 603 canUpdate = true; 604 } 605 606 if (canUpdate) { 607 // Make sure the previous top activity in the process no longer be resumed. 608 if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) { 609 final ActivityStack stack = mPreQTopResumedActivity.getActivityStack(); 610 if (stack != null) { 611 stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, 612 null /* resuming */, false /* pauseImmediately */); 613 } 614 } 615 mPreQTopResumedActivity = activity; 616 } 617 return canUpdate; 618 } 619 stopFreezingActivities()620 public void stopFreezingActivities() { 621 synchronized (mAtm.mGlobalLock) { 622 int i = mActivities.size(); 623 while (i > 0) { 624 i--; 625 mActivities.get(i).stopFreezingScreenLocked(true); 626 } 627 } 628 } 629 finishActivities()630 void finishActivities() { 631 ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities); 632 for (int i = 0; i < activities.size(); i++) { 633 final ActivityRecord r = activities.get(i); 634 if (!r.finishing && r.isInStackLocked()) { 635 r.getActivityStack().finishActivityLocked(r, Activity.RESULT_CANCELED, 636 null, "finish-heavy", true); 637 } 638 } 639 } 640 isInterestingToUser()641 public boolean isInterestingToUser() { 642 synchronized (mAtm.mGlobalLock) { 643 final int size = mActivities.size(); 644 for (int i = 0; i < size; i++) { 645 ActivityRecord r = mActivities.get(i); 646 if (r.isInterestingToUserLocked()) { 647 return true; 648 } 649 } 650 } 651 return false; 652 } 653 hasRunningActivity(String packageName)654 public boolean hasRunningActivity(String packageName) { 655 synchronized (mAtm.mGlobalLock) { 656 for (int i = mActivities.size() - 1; i >= 0; --i) { 657 final ActivityRecord r = mActivities.get(i); 658 if (packageName.equals(r.packageName)) { 659 return true; 660 } 661 } 662 } 663 return false; 664 } 665 clearPackagePreferredForHomeActivities()666 public void clearPackagePreferredForHomeActivities() { 667 synchronized (mAtm.mGlobalLock) { 668 for (int i = mActivities.size() - 1; i >= 0; --i) { 669 final ActivityRecord r = mActivities.get(i); 670 if (r.isActivityTypeHome()) { 671 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 672 try { 673 ActivityThread.getPackageManager() 674 .clearPackagePreferredActivities(r.packageName); 675 } catch (RemoteException c) { 676 // pm is in same process, this will never happen. 677 } 678 } 679 } 680 } 681 } 682 hasStartedActivity(ActivityRecord launchedActivity)683 boolean hasStartedActivity(ActivityRecord launchedActivity) { 684 for (int i = mActivities.size() - 1; i >= 0; i--) { 685 final ActivityRecord activity = mActivities.get(i); 686 if (launchedActivity == activity) { 687 continue; 688 } 689 if (!activity.stopped) { 690 return true; 691 } 692 } 693 return false; 694 } 695 696 updateIntentForHeavyWeightActivity(Intent intent)697 void updateIntentForHeavyWeightActivity(Intent intent) { 698 if (mActivities.isEmpty()) { 699 return; 700 } 701 ActivityRecord hist = mActivities.get(0); 702 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName); 703 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTaskRecord().taskId); 704 } 705 shouldKillProcessForRemovedTask(TaskRecord tr)706 boolean shouldKillProcessForRemovedTask(TaskRecord tr) { 707 for (int k = 0; k < mActivities.size(); k++) { 708 final ActivityRecord activity = mActivities.get(k); 709 if (!activity.stopped) { 710 // Don't kill process(es) that has an activity not stopped. 711 return false; 712 } 713 final TaskRecord otherTask = activity.getTaskRecord(); 714 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 715 // Don't kill process(es) that has an activity in a different task that is 716 // also in recents. 717 return false; 718 } 719 } 720 return true; 721 } 722 getReleaseSomeActivitiesTasks()723 ArraySet<TaskRecord> getReleaseSomeActivitiesTasks() { 724 // Examine all activities currently running in the process. 725 TaskRecord firstTask = null; 726 // Tasks is non-null only if two or more tasks are found. 727 ArraySet<TaskRecord> tasks = null; 728 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this); 729 for (int i = 0; i < mActivities.size(); i++) { 730 final ActivityRecord r = mActivities.get(i); 731 // First, if we find an activity that is in the process of being destroyed, 732 // then we just aren't going to do anything for now; we want things to settle 733 // down before we try to prune more activities. 734 if (r.finishing || r.isState(DESTROYING, DESTROYED)) { 735 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); 736 return null; 737 } 738 // Don't consider any activies that are currently not in a state where they 739 // can be destroyed. 740 if (r.visible || !r.stopped || !r.haveState 741 || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) { 742 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); 743 continue; 744 } 745 746 final TaskRecord task = r.getTaskRecord(); 747 if (task != null) { 748 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task 749 + " from " + r); 750 if (firstTask == null) { 751 firstTask = task; 752 } else if (firstTask != task) { 753 if (tasks == null) { 754 tasks = new ArraySet<>(); 755 tasks.add(firstTask); 756 } 757 tasks.add(task); 758 } 759 } 760 } 761 762 return tasks; 763 } 764 765 public interface ComputeOomAdjCallback { onVisibleActivity()766 void onVisibleActivity(); onPausedActivity()767 void onPausedActivity(); onStoppingActivity(boolean finishing)768 void onStoppingActivity(boolean finishing); onOtherActivity()769 void onOtherActivity(); 770 } 771 772 @HotPath(caller = HotPath.OOM_ADJUSTMENT) computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback)773 public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) { 774 synchronized (mAtm.mGlobalLockWithoutBoost) { 775 final int activitiesSize = mActivities.size(); 776 for (int j = 0; j < activitiesSize; j++) { 777 final ActivityRecord r = mActivities.get(j); 778 if (r.app != this) { 779 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app 780 + " instead of expected " + this); 781 if (r.app == null || (r.app.mUid == mUid)) { 782 // Only fix things up when they look sane 783 r.setProcess(this); 784 } else { 785 continue; 786 } 787 } 788 if (r.visible) { 789 callback.onVisibleActivity(); 790 final TaskRecord task = r.getTaskRecord(); 791 if (task != null && minTaskLayer > 0) { 792 final int layer = task.mLayerRank; 793 if (layer >= 0 && minTaskLayer > layer) { 794 minTaskLayer = layer; 795 } 796 } 797 break; 798 } else if (r.isState(PAUSING, PAUSED)) { 799 callback.onPausedActivity(); 800 } else if (r.isState(STOPPING)) { 801 callback.onStoppingActivity(r.finishing); 802 } else { 803 callback.onOtherActivity(); 804 } 805 } 806 } 807 808 return minTaskLayer; 809 } 810 computeRelaunchReason()811 public int computeRelaunchReason() { 812 synchronized (mAtm.mGlobalLock) { 813 final int activitiesSize = mActivities.size(); 814 for (int i = activitiesSize - 1; i >= 0; i--) { 815 final ActivityRecord r = mActivities.get(i); 816 if (r.mRelaunchReason != RELAUNCH_REASON_NONE) { 817 return r.mRelaunchReason; 818 } 819 } 820 } 821 return RELAUNCH_REASON_NONE; 822 } 823 getInputDispatchingTimeout()824 public long getInputDispatchingTimeout() { 825 synchronized (mAtm.mGlobalLock) { 826 return isInstrumenting() || isUsingWrapper() 827 ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS; 828 } 829 } 830 clearProfilerIfNeeded()831 void clearProfilerIfNeeded() { 832 if (mListener == null) return; 833 // Posting on handler so WM lock isn't held when we call into AM. 834 mAtm.mH.sendMessage(PooledLambda.obtainMessage( 835 WindowProcessListener::clearProfilerIfNeeded, mListener)); 836 } 837 updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange, boolean updateOomAdj)838 void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange, 839 boolean updateOomAdj) { 840 if (mListener == null) return; 841 // Posting on handler so WM lock isn't held when we call into AM. 842 final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo, 843 mListener, updateServiceConnectionActivities, activityChange, updateOomAdj); 844 mAtm.mH.sendMessage(m); 845 } 846 updateServiceConnectionActivities()847 void updateServiceConnectionActivities() { 848 if (mListener == null) return; 849 // Posting on handler so WM lock isn't held when we call into AM. 850 mAtm.mH.sendMessage(PooledLambda.obtainMessage( 851 WindowProcessListener::updateServiceConnectionActivities, mListener)); 852 } 853 setPendingUiCleanAndForceProcessStateUpTo(int newState)854 void setPendingUiCleanAndForceProcessStateUpTo(int newState) { 855 if (mListener == null) return; 856 // Posting on handler so WM lock isn't held when we call into AM. 857 final Message m = PooledLambda.obtainMessage( 858 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo, 859 mListener, newState); 860 mAtm.mH.sendMessage(m); 861 } 862 isRemoved()863 boolean isRemoved() { 864 return mListener == null ? false : mListener.isRemoved(); 865 } 866 shouldSetProfileProc()867 private boolean shouldSetProfileProc() { 868 return mAtm.mProfileApp != null && mAtm.mProfileApp.equals(mName) 869 && (mAtm.mProfileProc == null || mAtm.mProfileProc == this); 870 } 871 createProfilerInfoIfNeeded()872 ProfilerInfo createProfilerInfoIfNeeded() { 873 final ProfilerInfo currentProfilerInfo = mAtm.mProfilerInfo; 874 if (currentProfilerInfo == null || currentProfilerInfo.profileFile == null 875 || !shouldSetProfileProc()) { 876 return null; 877 } 878 if (currentProfilerInfo.profileFd != null) { 879 try { 880 currentProfilerInfo.profileFd = currentProfilerInfo.profileFd.dup(); 881 } catch (IOException e) { 882 currentProfilerInfo.closeFd(); 883 } 884 } 885 return new ProfilerInfo(currentProfilerInfo); 886 } 887 onStartActivity(int topProcessState, ActivityInfo info)888 void onStartActivity(int topProcessState, ActivityInfo info) { 889 if (mListener == null) return; 890 String packageName = null; 891 if ((info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0 892 || !"android".equals(info.packageName)) { 893 // Don't add this if it is a platform component that is marked to run in multiple 894 // processes, because this is actually part of the framework so doesn't make sense 895 // to track as a separate apk in the process. 896 packageName = info.packageName; 897 } 898 // Posting the message at the front of queue so WM lock isn't held when we call into AM, 899 // and the process state of starting activity can be updated quicker which will give it a 900 // higher scheduling group. 901 final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity, 902 mListener, topProcessState, shouldSetProfileProc(), packageName, 903 info.applicationInfo.longVersionCode); 904 mAtm.mH.sendMessageAtFrontOfQueue(m); 905 } 906 appDied()907 public void appDied() { 908 if (mListener == null) return; 909 // Posting on handler so WM lock isn't held when we call into AM. 910 final Message m = PooledLambda.obtainMessage( 911 WindowProcessListener::appDied, mListener); 912 mAtm.mH.sendMessage(m); 913 } 914 registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay)915 void registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay) { 916 if (activityDisplay == null) { 917 return; 918 } 919 // A process can only register to one display to listener to the override configuration 920 // change. Unregister existing listener if it has one before register the new one. 921 unregisterDisplayConfigurationListenerLocked(); 922 mDisplayId = activityDisplay.mDisplayId; 923 activityDisplay.registerConfigurationChangeListener(this); 924 } 925 926 @VisibleForTesting unregisterDisplayConfigurationListenerLocked()927 void unregisterDisplayConfigurationListenerLocked() { 928 if (mDisplayId == INVALID_DISPLAY) { 929 return; 930 } 931 final ActivityDisplay activityDisplay = 932 mAtm.mRootActivityContainer.getActivityDisplay(mDisplayId); 933 if (activityDisplay != null) { 934 activityDisplay.unregisterConfigurationChangeListener(this); 935 } 936 mDisplayId = INVALID_DISPLAY; 937 } 938 939 @Override onConfigurationChanged(Configuration newGlobalConfig)940 public void onConfigurationChanged(Configuration newGlobalConfig) { 941 super.onConfigurationChanged(newGlobalConfig); 942 updateConfiguration(); 943 } 944 945 @Override onRequestedOverrideConfigurationChanged(Configuration newOverrideConfig)946 public void onRequestedOverrideConfigurationChanged(Configuration newOverrideConfig) { 947 super.onRequestedOverrideConfigurationChanged(newOverrideConfig); 948 updateConfiguration(); 949 } 950 updateConfiguration()951 private void updateConfiguration() { 952 final Configuration config = getConfiguration(); 953 if (mLastReportedConfiguration.diff(config) == 0) { 954 // Nothing changed. 955 return; 956 } 957 958 try { 959 if (mThread == null) { 960 return; 961 } 962 if (DEBUG_CONFIGURATION) { 963 Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName 964 + " new config " + config); 965 } 966 config.seq = mAtm.increaseConfigurationSeqLocked(); 967 mAtm.getLifecycleManager().scheduleTransaction(mThread, 968 ConfigurationChangeItem.obtain(config)); 969 setLastReportedConfiguration(config); 970 } catch (Exception e) { 971 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e); 972 } 973 } 974 setLastReportedConfiguration(Configuration config)975 private void setLastReportedConfiguration(Configuration config) { 976 mLastReportedConfiguration.setTo(config); 977 } 978 getLastReportedConfiguration()979 Configuration getLastReportedConfiguration() { 980 return mLastReportedConfiguration; 981 } 982 983 /** Returns the total time (in milliseconds) spent executing in both user and system code. */ getCpuTime()984 public long getCpuTime() { 985 return (mListener != null) ? mListener.getCpuTime() : 0; 986 } 987 addRecentTask(TaskRecord task)988 void addRecentTask(TaskRecord task) { 989 mRecentTasks.add(task); 990 } 991 removeRecentTask(TaskRecord task)992 void removeRecentTask(TaskRecord task) { 993 mRecentTasks.remove(task); 994 } 995 996 @HotPath(caller = HotPath.OOM_ADJUSTMENT) hasRecentTasks()997 public boolean hasRecentTasks() { 998 synchronized (mAtm.mGlobalLockWithoutBoost) { 999 return !mRecentTasks.isEmpty(); 1000 } 1001 } 1002 clearRecentTasks()1003 void clearRecentTasks() { 1004 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1005 mRecentTasks.get(i).clearRootProcess(); 1006 } 1007 mRecentTasks.clear(); 1008 } 1009 appEarlyNotResponding(String annotation, Runnable killAppCallback)1010 public void appEarlyNotResponding(String annotation, Runnable killAppCallback) { 1011 synchronized (mAtm.mGlobalLock) { 1012 if (mAtm.mController == null) { 1013 return; 1014 } 1015 1016 try { 1017 // 0 == continue, -1 = kill process immediately 1018 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation); 1019 if (res < 0 && mPid != MY_PID) { 1020 killAppCallback.run(); 1021 } 1022 } catch (RemoteException e) { 1023 mAtm.mController = null; 1024 Watchdog.getInstance().setActivityController(null); 1025 } 1026 } 1027 } 1028 appNotResponding(String info, Runnable killAppCallback, Runnable serviceTimeoutCallback)1029 public boolean appNotResponding(String info, Runnable killAppCallback, 1030 Runnable serviceTimeoutCallback) { 1031 Runnable targetRunnable = null; 1032 synchronized (mAtm.mGlobalLock) { 1033 if (mAtm.mController == null) { 1034 return false; 1035 } 1036 1037 try { 1038 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 1039 int res = mAtm.mController.appNotResponding(mName, mPid, info); 1040 if (res != 0) { 1041 if (res < 0 && mPid != MY_PID) { 1042 targetRunnable = killAppCallback; 1043 } else { 1044 targetRunnable = serviceTimeoutCallback; 1045 } 1046 } 1047 } catch (RemoteException e) { 1048 mAtm.mController = null; 1049 Watchdog.getInstance().setActivityController(null); 1050 return false; 1051 } 1052 } 1053 if (targetRunnable != null) { 1054 targetRunnable.run(); 1055 return true; 1056 } 1057 return false; 1058 } 1059 1060 @HotPath(caller = HotPath.OOM_ADJUSTMENT) onTopProcChanged()1061 public void onTopProcChanged() { 1062 synchronized (mAtm.mGlobalLockWithoutBoost) { 1063 mAtm.mVrController.onTopProcChangedLocked(this); 1064 } 1065 } 1066 1067 @HotPath(caller = HotPath.OOM_ADJUSTMENT) isHomeProcess()1068 public boolean isHomeProcess() { 1069 synchronized (mAtm.mGlobalLockWithoutBoost) { 1070 return this == mAtm.mHomeProcess; 1071 } 1072 } 1073 1074 @HotPath(caller = HotPath.OOM_ADJUSTMENT) isPreviousProcess()1075 public boolean isPreviousProcess() { 1076 synchronized (mAtm.mGlobalLockWithoutBoost) { 1077 return this == mAtm.mPreviousProcess; 1078 } 1079 } 1080 setRunningRecentsAnimation(boolean running)1081 void setRunningRecentsAnimation(boolean running) { 1082 if (mRunningRecentsAnimation == running) { 1083 return; 1084 } 1085 mRunningRecentsAnimation = running; 1086 updateRunningRemoteOrRecentsAnimation(); 1087 } 1088 setRunningRemoteAnimation(boolean running)1089 void setRunningRemoteAnimation(boolean running) { 1090 if (mRunningRemoteAnimation == running) { 1091 return; 1092 } 1093 mRunningRemoteAnimation = running; 1094 updateRunningRemoteOrRecentsAnimation(); 1095 } 1096 updateRunningRemoteOrRecentsAnimation()1097 private void updateRunningRemoteOrRecentsAnimation() { 1098 1099 // Posting on handler so WM lock isn't held when we call into AM. 1100 mAtm.mH.sendMessage(PooledLambda.obtainMessage( 1101 WindowProcessListener::setRunningRemoteAnimation, mListener, 1102 mRunningRecentsAnimation || mRunningRemoteAnimation)); 1103 } 1104 1105 @Override toString()1106 public String toString() { 1107 return mOwner != null ? mOwner.toString() : null; 1108 } 1109 dump(PrintWriter pw, String prefix)1110 public void dump(PrintWriter pw, String prefix) { 1111 synchronized (mAtm.mGlobalLock) { 1112 if (mActivities.size() > 0) { 1113 pw.print(prefix); pw.println("Activities:"); 1114 for (int i = 0; i < mActivities.size(); i++) { 1115 pw.print(prefix); pw.print(" - "); pw.println(mActivities.get(i)); 1116 } 1117 } 1118 1119 if (mRecentTasks.size() > 0) { 1120 pw.println(prefix + "Recent Tasks:"); 1121 for (int i = 0; i < mRecentTasks.size(); i++) { 1122 pw.println(prefix + " - " + mRecentTasks.get(i)); 1123 } 1124 } 1125 1126 if (mVrThreadTid != 0) { 1127 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid); 1128 } 1129 } 1130 pw.println(prefix + " Configuration=" + getConfiguration()); 1131 pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration()); 1132 pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration); 1133 } 1134 writeToProto(ProtoOutputStream proto, long fieldId)1135 void writeToProto(ProtoOutputStream proto, long fieldId) { 1136 if (mListener != null) { 1137 mListener.writeToProto(proto, fieldId); 1138 } 1139 } 1140 } 1141