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