From 5711b8fdaf2d99414c8167d142c140c02301c64c Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Fri, 15 Nov 2019 15:44:12 -0800 Subject: Move PIP/MW mode callbacks to be on the client side We now infer the PIP/MW mode change from the new configuration. Note also that both - Activity#isInPictureInPictureMode - Activity#isInMultiWindowMode infer the current state from the configuration rather than querying against the WM. Also in this CL: - When in removePinnedStackInSurfaceTransaction, keep the pinned stack hidden till the windowing mode is set to fullscreen, this is to surpress the attempt to set the activities to be started in reparenting - When in ActivityRecord#shouldBeVisible, should take account the force hidden flag, which is not actually in use before Bug: 144097203 Bug: 142282126 Bug: 138329093 Test: atest ActivityLifecyclePipTests \ ActivityLifecycleSplitScreenTests \ ActivityLifecycleTopResumedStateTests \ PinnedStackTests \ SplitScreenTests \ ActivityTaskManagerServiceTests \ RecentsAnimationTest \ AssistantStackTests \ StartActivityTests \ ActivityVisibilityTests \ MultiDisplaySecurityTests \ MultiDisplaySystemDecorationTests Change-Id: Ibe032b5e50ba5c6d6bc44ebb54d07ac974ebe656 --- core/java/android/app/ActivityThread.java | 73 ++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 26 deletions(-) (limited to 'core/java/android/app/ActivityThread.java') diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 51eaff1ae99f..73566d93afa0 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -17,6 +17,8 @@ package android.app; import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; +import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE; import static android.app.servertransaction.ActivityLifecycleItem.ON_DESTROY; import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE; @@ -407,6 +409,9 @@ public final class ActivityThread extends ClientTransactionHandler { @GuardedBy("this") private @Nullable Map mRemoteCancellations; + private final Map mLastReportedWindowingMode = Collections.synchronizedMap( + new ArrayMap<>()); + private static final class ProviderKey { final String authority; final int userId; @@ -3324,6 +3329,8 @@ public final class ActivityThread extends ClientTransactionHandler { " did not call through to super.onCreate()"); } r.activity = activity; + mLastReportedWindowingMode.put(activity.getActivityToken(), + config.windowConfiguration.getWindowingMode()); } r.setState(ON_CREATE); @@ -3746,32 +3753,6 @@ public final class ActivityThread extends ClientTransactionHandler { } } - @Override - public void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode, - Configuration overrideConfig) { - final ActivityClientRecord r = mActivities.get(token); - if (r != null) { - final Configuration newConfig = new Configuration(mConfiguration); - if (overrideConfig != null) { - newConfig.updateFrom(overrideConfig); - } - r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig); - } - } - - @Override - public void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode, - Configuration overrideConfig) { - final ActivityClientRecord r = mActivities.get(token); - if (r != null) { - final Configuration newConfig = new Configuration(mConfiguration); - if (overrideConfig != null) { - newConfig.updateFrom(overrideConfig); - } - r.activity.dispatchPictureInPictureModeChanged(isInPipMode, newConfig); - } - } - @Override public void handlePictureInPictureRequested(IBinder token) { final ActivityClientRecord r = mActivities.get(token); @@ -5269,8 +5250,15 @@ public final class ActivityThread extends ClientTransactionHandler { throw e.rethrowFromSystemServer(); } + // Save the current windowing mode to be restored and compared to the new configuration's + // windowing mode (needed because we update the last reported windowing mode when launching + // an activity and we can't tell inside performLaunchActivity whether we are relaunching) + final int oldWindowingMode = mLastReportedWindowingMode.getOrDefault( + r.activity.getActivityToken(), WINDOWING_MODE_UNDEFINED); handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents, pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity"); + mLastReportedWindowingMode.put(r.activity.getActivityToken(), oldWindowingMode); + handleWindowingModeChangeIfNeeded(r.activity, r.activity.mCurrentConfig); if (pendingActions != null) { // Only report a successful relaunch to WindowManager. @@ -5553,6 +5541,10 @@ public final class ActivityThread extends ClientTransactionHandler { throw new IllegalArgumentException("Activity token not set. Is the activity attached?"); } + // multi-window / pip mode changes, if any, should be sent before the configuration change + // callback, see also PinnedStackTests#testConfigurationChangeOrderDuringTransition + handleWindowingModeChangeIfNeeded(activity, newConfig); + boolean shouldChangeConfig = false; if (activity.mCurrentConfig == null) { shouldChangeConfig = true; @@ -5746,6 +5738,35 @@ public final class ActivityThread extends ClientTransactionHandler { } } + /** + * Sends windowing mode change callbacks to {@link Activity} if applicable. + * + * See also {@link Activity#onMultiWindowModeChanged(boolean, Configuration)} and + * {@link Activity#onPictureInPictureModeChanged(boolean, Configuration)} + */ + private void handleWindowingModeChangeIfNeeded(Activity activity, + Configuration newConfiguration) { + final int newWindowingMode = newConfiguration.windowConfiguration.getWindowingMode(); + final IBinder token = activity.getActivityToken(); + final int oldWindowingMode = mLastReportedWindowingMode.getOrDefault(token, + WINDOWING_MODE_UNDEFINED); + if (oldWindowingMode == newWindowingMode) return; + // PiP callback is sent before the MW one. + if (newWindowingMode == WINDOWING_MODE_PINNED) { + activity.dispatchPictureInPictureModeChanged(true, newConfiguration); + } else if (oldWindowingMode == WINDOWING_MODE_PINNED) { + activity.dispatchPictureInPictureModeChanged(false, newConfiguration); + } + final boolean wasInMultiWindowMode = WindowConfiguration.inMultiWindowMode( + oldWindowingMode); + final boolean nowInMultiWindowMode = WindowConfiguration.inMultiWindowMode( + newWindowingMode); + if (wasInMultiWindowMode != nowInMultiWindowMode) { + activity.dispatchMultiWindowModeChanged(nowInMultiWindowMode, newConfiguration); + } + mLastReportedWindowingMode.put(token, newWindowingMode); + } + /** * Updates the application info. * -- cgit v1.2.3