diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index bc12923cb6b32..420675c5ba1eb 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -1469,11 +1469,11 @@ class ActivityStack extends Task { if (resumeNext) { final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack(); - if (!topStack.shouldSleepOrShutDownActivities()) { + if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) { mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null); } else { checkReadyForSleep(); - ActivityRecord top = topStack.topRunningActivity(); + final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null; if (top == null || (prev != null && top != prev)) { // If there are no more activities available to run, do resume anyway to start // something. Also if the top activity on the stack is not the just paused diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 32103048469f5..984ae218431cb 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -615,12 +615,15 @@ class ActivityStarter { int res; synchronized (mService.mGlobalLock) { - final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack(); - stack.mConfigWillChange = mRequest.globalConfig != null + final boolean globalConfigWillChange = mRequest.globalConfig != null && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0; + final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack(); + if (stack != null) { + stack.mConfigWillChange = globalConfigWillChange; + } if (DEBUG_CONFIGURATION) { Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = " - + stack.mConfigWillChange); + + globalConfigWillChange); } final long origId = Binder.clearCallingIdentity(); @@ -633,7 +636,7 @@ class ActivityStarter { Binder.restoreCallingIdentity(origId); - if (stack.mConfigWillChange) { + if (globalConfigWillChange) { // If the caller also wants to switch to a new configuration, do so now. // This allows a clean switch, as we are waiting for the current activity // to pause (so we will not destroy it), and have not yet started the @@ -641,7 +644,9 @@ class ActivityStarter { mService.mAmInternal.enforceCallingPermission( android.Manifest.permission.CHANGE_CONFIGURATION, "updateConfiguration()"); - stack.mConfigWillChange = false; + if (stack != null) { + stack.mConfigWillChange = false; + } if (DEBUG_CONFIGURATION) { Slog.v(TAG_CONFIGURATION, "Updating to new configuration after starting activity."); @@ -1536,9 +1541,11 @@ class ActivityStarter { // If the activity being launched is the same as the one currently at the top, then // we need to check if it should only be launched once. final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack(); - startResult = deliverToCurrentTopIfNeeded(topStack); - if (startResult != START_SUCCESS) { - return startResult; + if (topStack != null) { + startResult = deliverToCurrentTopIfNeeded(topStack); + if (startResult != START_SUCCESS) { + return startResult; + } } if (mTargetStack == null) { @@ -2126,10 +2133,13 @@ class ActivityStarter { if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { ActivityRecord checkedCaller = sourceRecord; if (checkedCaller == null) { - checkedCaller = mRootWindowContainer.getTopDisplayFocusedStack() - .topRunningNonDelayedActivityLocked(mNotTop); + ActivityStack topFocusedStack = mRootWindowContainer.getTopDisplayFocusedStack(); + if (topFocusedStack != null) { + checkedCaller = topFocusedStack.topRunningNonDelayedActivityLocked(mNotTop); + } } - if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) { + if (checkedCaller == null + || !checkedCaller.mActivityComponent.equals(r.mActivityComponent)) { // Caller is not the same as launcher, so always needed. mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED; } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 98c8b61b07422..911812bc74103 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -1104,8 +1104,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // If this is coming from the currently resumed activity, it is // effectively saying that app switches are allowed at this point. final ActivityStack stack = getTopDisplayFocusedStack(); - if (stack.mResumedActivity != null && - stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { + if (stack != null && stack.mResumedActivity != null + && stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { mAppSwitchesAllowedTime = 0; } } @@ -1951,8 +1951,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public boolean isTopActivityImmersive() { enforceNotIsolatedCaller("isTopActivityImmersive"); synchronized (mGlobalLock) { - final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivity(); - return (r != null) ? r.immersive : false; + final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + if (topFocusedStack == null) { + return false; + } + + final ActivityRecord r = topFocusedStack.topRunningActivity(); + return r != null && r.immersive; } } @@ -1981,7 +1986,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public int getFrontActivityScreenCompatMode() { enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); synchronized (mGlobalLock) { - final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivity(); + final ActivityStack stack = getTopDisplayFocusedStack(); + final ActivityRecord r = stack != null ? stack.topRunningActivity() : null; if (r == null) { return ActivityManager.COMPAT_MODE_UNKNOWN; } @@ -1995,7 +2001,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { "setFrontActivityScreenCompatMode"); ApplicationInfo ai; synchronized (mGlobalLock) { - final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivity(); + final ActivityStack stack = getTopDisplayFocusedStack(); + final ActivityRecord r = stack != null ? stack.topRunningActivity() : null; if (r == null) { Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity"); return; @@ -2383,7 +2390,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { final long origId = Binder.clearCallingIdentity(); try { - getTopDisplayFocusedStack().unhandledBackLocked(); + final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + if (topFocusedStack != null) { + topFocusedStack.unhandledBackLocked(); + } } finally { Binder.restoreCallingIdentity(origId); } @@ -3616,7 +3626,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { "enqueueAssistContext()"); synchronized (mGlobalLock) { - ActivityRecord activity = getTopDisplayFocusedStack().getTopNonFinishingActivity(); + final ActivityStack stack = getTopDisplayFocusedStack(); + ActivityRecord activity = stack != null ? stack.getTopNonFinishingActivity() : null; if (activity == null) { Slog.w(TAG, "getAssistContextExtras failed: no top activity"); return null; @@ -7037,9 +7048,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mRootWindowContainer.dumpDisplayConfigs(pw, " "); } if (dumpAll) { - if (dumpPackage == null) { - pw.println(" mConfigWillChange: " - + getTopDisplayFocusedStack().mConfigWillChange); + final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + if (dumpPackage == null && topFocusedStack != null) { + pw.println(" mConfigWillChange: " + topFocusedStack.mConfigWillChange); } if (mCompatModePackages.getPackages().size() > 0) { boolean printed = false; @@ -7120,7 +7131,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { if (dumpPackage == null) { getGlobalConfiguration().dumpDebug(proto, GLOBAL_CONFIGURATION); - proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange); + final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + if (topFocusedStack != null) { + proto.write(CONFIG_WILL_CHANGE, topFocusedStack.mConfigWillChange); + } writeSleepStateToProto(proto, wakeFullness, testPssMode); if (mRunningVoice != null) { final long vrToken = proto.start( diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index ada5685e6817a..74c30442d8f0d 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -1980,7 +1980,9 @@ class RootWindowContainer extends WindowContainer } boolean switchUser(int userId, UserState uss) { - final int focusStackId = getTopDisplayFocusedStack().getRootTaskId(); + final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + final int focusStackId = topFocusedStack != null + ? topFocusedStack.getRootTaskId() : INVALID_TASK_ID; // We dismiss the docked stack whenever we switch users. final ActivityStack dockedStack = getDefaultDisplay().getRootSplitScreenPrimaryTask(); if (dockedStack != null) { @@ -3455,7 +3457,12 @@ class RootWindowContainer extends WindowContainer ArrayList getDumpActivities(String name, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) { if (dumpFocusedStackOnly) { - return getTopDisplayFocusedStack().getDumpActivitiesLocked(name); + final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); + if (topFocusedStack != null) { + return topFocusedStack.getDumpActivitiesLocked(name); + } else { + return new ArrayList<>(); + } } else { ArrayList activities = new ArrayList<>(); int numDisplays = getChildCount();