From 3dfe4c8e0955809ef96b1e89b87f9cabb9046b91 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Tue, 11 Jul 2023 16:20:01 -0700 Subject: [PATCH] Ensure onStop before onPictureInPictureModeChanged We have a CTS test case PinnedStackTests#testStopBeforeMultiWindowCallbacksOnDismiss that ensures onStop is always sent before onPictureInPictureModeChanged. The test itself does not simulate what user typically does and it's broken with the shell transition. Apps like YouTube may rely on such order so they can choose if they should, for instance, stop the playback when the PiP is removed. Fixing this by forcefully send onStop before setWindowingMode (which in turn results a configuration change). Video: http://recall/-/aaaaaabFQoRHlzixHdtY/eEEfu9mca0dzLyzC8jBcxb Bug: 290413333 Test: manually, see also the video Test: atest PinnedStackTests Merged-In: I0f94d4c26f7b3ccc1df6be97a0238f995438dffd Change-Id: I0f94d4c26f7b3ccc1df6be97a0238f995438dffd (cherry picked from commit 59c5d8101edc1192dfb04c73747aa210f28d3ea4) --- .../java/com/android/server/wm/ActivityTaskSupervisor.java | 7 +++++-- .../com/android/server/wm/WindowOrganizerController.java | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 0171c200b56c8..b34ae19300488 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -2186,7 +2186,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { * Processes the activities to be stopped or destroyed. This should be called when the resumed * activities are idle or drawn. */ - private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity, + void processStoppingAndFinishingActivities(ActivityRecord launchedActivity, boolean processPausingActivities, String reason) { // Stop any activities that are scheduled to do so but have been waiting for the transition // animation to finish. @@ -2194,7 +2194,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { ArrayList readyToStopActivities = null; for (int i = 0; i < mStoppingActivities.size(); i++) { final ActivityRecord s = mStoppingActivities.get(i); - final boolean animating = s.isInTransition(); + // Activity in a force hidden task should not be counted as animating, i.e., we want to + // send onStop before any configuration change when removing pip transition is ongoing. + final boolean animating = s.isInTransition() + && s.getTask() != null && !s.getTask().isForceHidden(); displaySwapping |= s.isDisplaySleepingAndSwapping(); ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b " + "finishing=%s", s, s.nowVisible, animating, s.finishing); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index a2f7ba499fdff..027ab97693fd0 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -559,6 +559,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } if (forceHiddenForPip) { wc.asTask().setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */); + // When removing pip, make sure that onStop is sent to the app ahead of + // onPictureInPictureModeChanged. + // See also PinnedStackTests#testStopBeforeMultiWindowCallbacksOnDismiss + wc.asTask().ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); + wc.asTask().mTaskSupervisor.processStoppingAndFinishingActivities( + null /* launchedActivity */, false /* processPausingActivities */, + "force-stop-on-removing-pip"); } int containerEffect = applyWindowContainerChange(wc, entry.getValue(),