From 0f82863dbccadad44d0c8f8413a34bce4236c953 Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Tue, 11 Mar 2025 10:14:51 -0700 Subject: Add an option to move floating bubbles to fullscreen This option is in the bubble manage menu and triggers the bubble to fullscreen transition. Update the bubble to fullscreen transition to also check for the BubbleExpandedView if BubbleBarExpandedView isn't available. Added a test for a bubble with phone expanded view. Flag: com.android.wm.shell.enable_bubble_to_fullscreen Test: atest BubbleTransitionsTest Test: manual - enable the flag, get a floating chat bubble, tap the manage menu, tap fullscreen => bubble moves to fullscreen Bug: 400752049 Change-Id: I74dda034240eb2d83df6c324a1ff5e8862c49796 --- .../Shell/res/layout/bubble_manage_menu.xml | 31 +++++++++++++++++++ .../wm/shell/bubbles/BubbleExpandedView.java | 4 +++ .../android/wm/shell/bubbles/BubbleStackView.java | 19 +++++++++++- .../wm/shell/bubbles/BubbleTransitions.java | 23 ++++++++++---- .../bubbles/bar/BubbleBarMenuViewController.java | 4 +-- .../wm/shell/bubbles/BubbleTransitionsTest.java | 35 ++++++++++++++++++++++ 6 files changed, 108 insertions(+), 8 deletions(-) diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml index 4daaf9c6b57f..225303b2d942 100644 --- a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml +++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml @@ -103,4 +103,35 @@ + + + + + + + + + \ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java index 8ac9230c36c3..cbd1e9671825 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java @@ -606,6 +606,10 @@ public class BubbleExpandedView extends LinearLayout { updateManageButtonIfExists(); } + public float getCornerRadius() { + return mCornerRadius; + } + /** * Updates the size and visuals of the pointer if {@link #mPointerView} is initialized. * Does nothing otherwise. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index 92724178cf84..dd5a23aae7f9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -91,6 +91,7 @@ import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.shared.animation.Interpolators; import com.android.wm.shell.shared.animation.PhysicsAnimator; +import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper; import com.android.wm.shell.shared.bubbles.DeviceConfig; import com.android.wm.shell.shared.bubbles.DismissView; import com.android.wm.shell.shared.bubbles.RelativeTouchListener; @@ -1319,7 +1320,7 @@ public class BubbleStackView extends FrameLayout mBubbleContainer.bringToFront(); } - // TODO: Create ManageMenuView and move setup / animations there + // TODO (b/402196554) : Create ManageMenuView and move setup / animations there private void setUpManageMenu() { if (mManageMenu != null) { removeView(mManageMenu); @@ -1377,6 +1378,22 @@ public class BubbleStackView extends FrameLayout mManageSettingsIcon = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_icon); mManageSettingsText = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_name); + View fullscreenView = mManageMenu.findViewById( + R.id.bubble_manage_menu_fullscreen_container); + if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { + fullscreenView.setVisibility(VISIBLE); + fullscreenView.setOnClickListener( + view -> { + showManageMenu(false /* show */); + BubbleExpandedView expandedView = getExpandedView(); + if (expandedView != null && expandedView.getTaskView() != null) { + expandedView.getTaskView().moveToFullscreen(); + } + }); + } else { + fullscreenView.setVisibility(GONE); + } + // The menu itself should respect locale direction so the icons are on the correct side. mManageMenu.setLayoutDirection(LAYOUT_DIRECTION_LOCALE); addView(mManageMenu); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java index 8cd6ce020408..c1841c707a2f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java @@ -612,8 +612,7 @@ public class BubbleTransitions { mTaskLeash = taskChg.getLeash(); mRootLeash = info.getRoot(0).getLeash(); - SurfaceControl dest = - mBubble.getBubbleBarExpandedView().getViewRootImpl().getSurfaceControl(); + SurfaceControl dest = getExpandedView(mBubble).getViewRootImpl().getSurfaceControl(); final Runnable onPlucked = () -> { // Need to remove the taskview AFTER applying the startTransaction because // it isn't synchronized. @@ -623,12 +622,12 @@ public class BubbleTransitions { mBubbleData.setExpanded(false /* expanded */); }; if (dest != null) { - pluck(mTaskLeash, mBubble.getBubbleBarExpandedView(), dest, + pluck(mTaskLeash, getExpandedView(mBubble), dest, taskChg.getStartAbsBounds().left - info.getRoot(0).getOffset().x, taskChg.getStartAbsBounds().top - info.getRoot(0).getOffset().y, - mBubble.getBubbleBarExpandedView().getCornerRadius(), startTransaction, + getCornerRadius(mBubble), startTransaction, onPlucked); - mBubble.getBubbleBarExpandedView().post(() -> mTransitions.dispatchTransition( + getExpandedView(mBubble).post(() -> mTransitions.dispatchTransition( mTransition, info, startTransaction, finishTransaction, finishCallback, null)); } else { @@ -649,6 +648,20 @@ public class BubbleTransitions { t.reparent(mTaskLeash, mRootLeash); t.apply(); } + + private View getExpandedView(@NonNull Bubble bubble) { + if (bubble.getBubbleBarExpandedView() != null) { + return bubble.getBubbleBarExpandedView(); + } + return bubble.getExpandedView(); + } + + private float getCornerRadius(@NonNull Bubble bubble) { + if (bubble.getBubbleBarExpandedView() != null) { + return bubble.getBubbleBarExpandedView().getCornerRadius(); + } + return bubble.getExpandedView().getCornerRadius(); + } } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java index b7761ec75782..69009fd1606a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java @@ -28,9 +28,9 @@ import android.view.View; import android.view.ViewGroup; import com.android.app.animation.Interpolators; -import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.bubbles.Bubble; +import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper; import java.util.ArrayList; @@ -263,7 +263,7 @@ class BubbleBarMenuViewController { } )); - if (Flags.enableBubbleAnything() || Flags.enableBubbleToFullscreen()) { + if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { menuActions.add(new BubbleBarMenuView.MenuAction( Icon.createWithResource(resources, R.drawable.desktop_mode_ic_handle_menu_fullscreen), diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java index 25f17fe8a3c2..b136bed3c942 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java @@ -311,4 +311,39 @@ public class BubbleTransitionsTest extends ShellTestCase { verify(startT).apply(); assertFalse(mTaskViewTransitions.hasPending()); } + + @Test + public void convertFloatingBubbleToFullscreen() { + final BubbleExpandedView bev = mock(BubbleExpandedView.class); + final ViewRootImpl vri = mock(ViewRootImpl.class); + when(bev.getViewRootImpl()).thenReturn(vri); + when(mBubble.getBubbleBarExpandedView()).thenReturn(null); + when(mBubble.getExpandedView()).thenReturn(bev); + + ActivityManager.RunningTaskInfo taskInfo = setupBubble(); + final BubbleTransitions.BubbleTransition bt = mBubbleTransitions.startConvertFromBubble( + mBubble, taskInfo); + final BubbleTransitions.ConvertFromBubble cfb = (BubbleTransitions.ConvertFromBubble) bt; + verify(mTransitions).startTransition(anyInt(), any(), eq(cfb)); + verify(mBubble).setPreparingTransition(eq(bt)); + assertTrue(mTaskViewTransitions.hasPending()); + + final TransitionInfo info = new TransitionInfo(TRANSIT_CHANGE, 0); + final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, + mock(SurfaceControl.class)); + chg.setMode(TRANSIT_CHANGE); + chg.setTaskInfo(taskInfo); + info.addChange(chg); + info.addRoot(new TransitionInfo.Root(0, mock(SurfaceControl.class), 0, 0)); + SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); + SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); + Transitions.TransitionFinishCallback finishCb = wct -> {}; + cfb.startAnimation(cfb.mTransition, info, startT, finishT, finishCb); + + // Can really only verify that it interfaces with the taskViewTransitions queue. + // The actual functioning of this is tightly-coupled with SurfaceFlinger and renderthread + // in order to properly synchronize surface manipulation with drawing and thus can't be + // directly tested. + assertFalse(mTaskViewTransitions.hasPending()); + } } -- cgit v1.2.3-59-g8ed1b