Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +5 −4 Original line number Diff line number Diff line Loading @@ -2643,9 +2643,9 @@ public class BubbleController implements ConfigurationChangeListener, mBubbleData.setSelectedBubbleAndExpandStack(bubbleToSelect); } private void moveBubbleToFullscreen(String key) { private void moveDraggedBubbleToFullscreen(String key, Point dropLocation) { Bubble b = mBubbleData.getBubbleInStackWithKey(key); mBubbleTransitions.startDraggedBubbleIconToFullscreen(b); mBubbleTransitions.startDraggedBubbleIconToFullscreen(b, dropLocation); } private boolean isDeviceLocked() { Loading Loading @@ -2936,8 +2936,9 @@ public class BubbleController implements ConfigurationChangeListener, } @Override public void moveBubbleToFullscreen(String key) { mMainExecutor.execute(() -> mController.moveBubbleToFullscreen(key)); public void moveDraggedBubbleToFullscreen(String key, Point dropLocation) { mMainExecutor.execute( () -> mController.moveDraggedBubbleToFullscreen(key, dropLocation)); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java +50 −4 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.TaskInfo; import android.content.Context; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.IBinder; Loading @@ -42,6 +43,11 @@ import android.window.TransitionRequestInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import androidx.core.animation.Animator; import androidx.core.animation.Animator.AnimatorUpdateListener; import androidx.core.animation.AnimatorListenerAdapter; import androidx.core.animation.ValueAnimator; import com.android.internal.annotations.VisibleForTesting; import com.android.launcher3.icons.BubbleIconFactory; import com.android.wm.shell.ShellTaskOrganizer; Loading Loading @@ -114,8 +120,8 @@ public class BubbleTransitions { } /** Starts a transition that converts a dragged bubble icon to a full screen task. */ public BubbleTransition startDraggedBubbleIconToFullscreen(Bubble bubble) { return new DraggedBubbleIconToFullscreen(bubble); public BubbleTransition startDraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation) { return new DraggedBubbleIconToFullscreen(bubble, dropLocation); } /** Loading Loading @@ -673,9 +679,19 @@ public class BubbleTransitions { IBinder mTransition; final Bubble mBubble; final Point mDropLocation; final TransactionProvider mTransactionProvider; DraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation) { this(bubble, dropLocation, SurfaceControl.Transaction::new); } DraggedBubbleIconToFullscreen(Bubble bubble) { @VisibleForTesting DraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation, TransactionProvider transactionProvider) { mBubble = bubble; mDropLocation = dropLocation; mTransactionProvider = transactionProvider; bubble.setPreparingTransition(this); WindowContainerToken token = bubble.getTaskView().getTaskInfo().getToken(); WindowContainerTransaction wct = new WindowContainerTransaction(); Loading Loading @@ -723,8 +739,34 @@ public class BubbleTransitions { } mRepository.remove(taskViewTaskController); final SurfaceControl taskLeash = change.getLeash(); // set the initial position of the task with 0 scale startTransaction.setPosition(taskLeash, mDropLocation.x, mDropLocation.y); startTransaction.setScale(taskLeash, 0, 0); startTransaction.apply(); final SurfaceControl.Transaction animT = mTransactionProvider.get(); ValueAnimator animator = ValueAnimator.ofFloat(0, 1); animator.setDuration(250); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(@NonNull Animator animation) { float progress = animator.getAnimatedFraction(); float x = mDropLocation.x * (1 - progress); float y = mDropLocation.y * (1 - progress); animT.setPosition(taskLeash, x, y); animT.setScale(taskLeash, progress, progress); animT.apply(); } }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(@NonNull Animator animation) { animT.close(); finishCallback.onTransitionFinished(null); } }); animator.start(); taskViewTaskController.notifyTaskRemovalStarted(mBubble.getTaskView().getTaskInfo()); mTaskViewTransitions.onExternalDone(transition); return true; Loading Loading @@ -774,4 +816,8 @@ public class BubbleTransitions { mTaskViewTransitions.onExternalDone(transition); } } interface TransactionProvider { SurfaceControl.Transaction get(); } } libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.wm.shell.bubbles; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.graphics.Point; import android.graphics.Rect; import android.os.UserHandle; import com.android.wm.shell.bubbles.IBubblesListener; Loading Loading @@ -59,5 +60,5 @@ interface IBubbles { oneway void showDropTarget(in boolean show, in @nullable BubbleBarLocation location) = 15; oneway void moveBubbleToFullscreen(in String key) = 16; oneway void moveDraggedBubbleToFullscreen(in String key, in Point dropLocation) = 16; } No newline at end of file libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java +26 −6 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -37,6 +38,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.IBinder; Loading @@ -47,7 +49,9 @@ import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import androidx.core.animation.AnimatorTestRule; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.launcher3.icons.BubbleIconFactory; import com.android.wm.shell.ShellTaskOrganizer; Loading @@ -65,6 +69,7 @@ import com.android.wm.shell.taskview.TaskViewTransitions; import com.android.wm.shell.transition.Transitions; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; Loading @@ -76,6 +81,8 @@ import org.mockito.MockitoAnnotations; @SmallTest public class BubbleTransitionsTest extends ShellTestCase { @Rule public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(); private static final int FULLSCREEN_TASK_WIDTH = 200; private static final int FULLSCREEN_TASK_HEIGHT = 100; Loading Loading @@ -292,24 +299,37 @@ public class BubbleTransitionsTest extends ShellTestCase { @Test public void convertDraggedBubbleToFullscreen() { ActivityManager.RunningTaskInfo taskInfo = setupBubble(); SurfaceControl.Transaction animT = mock(SurfaceControl.Transaction.class); BubbleTransitions.TransactionProvider transactionProvider = () -> animT; final DraggedBubbleIconToFullscreen bt = (DraggedBubbleIconToFullscreen) mBubbleTransitions .startDraggedBubbleIconToFullscreen(mBubble); mBubbleTransitions.new DraggedBubbleIconToFullscreen( mBubble, new Point(100, 50), transactionProvider); verify(mTransitions).startTransition(anyInt(), any(), eq(bt)); SurfaceControl taskLeash = new SurfaceControl.Builder().setName("taskLeash").build(); final TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0); final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, mock(SurfaceControl.class)); final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, taskLeash); chg.setMode(TRANSIT_TO_FRONT); 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 -> {}; boolean[] transitionFinished = {false}; Transitions.TransitionFinishCallback finishCb = wct -> transitionFinished[0] = true; InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { bt.startAnimation(bt.mTransition, info, startT, finishT, finishCb); mAnimatorTestRule.advanceTimeBy(250); }); verify(startT).setScale(taskLeash, 0, 0); verify(startT).setPosition(taskLeash, 100, 50); verify(startT).apply(); verify(animT).setScale(taskLeash, 1, 1); verify(animT).setPosition(taskLeash, 0, 0); verify(animT, atLeastOnce()).apply(); verify(animT).close(); assertFalse(mTaskViewTransitions.hasPending()); assertTrue(transitionFinished[0]); } @Test Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +5 −4 Original line number Diff line number Diff line Loading @@ -2643,9 +2643,9 @@ public class BubbleController implements ConfigurationChangeListener, mBubbleData.setSelectedBubbleAndExpandStack(bubbleToSelect); } private void moveBubbleToFullscreen(String key) { private void moveDraggedBubbleToFullscreen(String key, Point dropLocation) { Bubble b = mBubbleData.getBubbleInStackWithKey(key); mBubbleTransitions.startDraggedBubbleIconToFullscreen(b); mBubbleTransitions.startDraggedBubbleIconToFullscreen(b, dropLocation); } private boolean isDeviceLocked() { Loading Loading @@ -2936,8 +2936,9 @@ public class BubbleController implements ConfigurationChangeListener, } @Override public void moveBubbleToFullscreen(String key) { mMainExecutor.execute(() -> mController.moveBubbleToFullscreen(key)); public void moveDraggedBubbleToFullscreen(String key, Point dropLocation) { mMainExecutor.execute( () -> mController.moveDraggedBubbleToFullscreen(key, dropLocation)); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java +50 −4 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.TaskInfo; import android.content.Context; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.IBinder; Loading @@ -42,6 +43,11 @@ import android.window.TransitionRequestInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import androidx.core.animation.Animator; import androidx.core.animation.Animator.AnimatorUpdateListener; import androidx.core.animation.AnimatorListenerAdapter; import androidx.core.animation.ValueAnimator; import com.android.internal.annotations.VisibleForTesting; import com.android.launcher3.icons.BubbleIconFactory; import com.android.wm.shell.ShellTaskOrganizer; Loading Loading @@ -114,8 +120,8 @@ public class BubbleTransitions { } /** Starts a transition that converts a dragged bubble icon to a full screen task. */ public BubbleTransition startDraggedBubbleIconToFullscreen(Bubble bubble) { return new DraggedBubbleIconToFullscreen(bubble); public BubbleTransition startDraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation) { return new DraggedBubbleIconToFullscreen(bubble, dropLocation); } /** Loading Loading @@ -673,9 +679,19 @@ public class BubbleTransitions { IBinder mTransition; final Bubble mBubble; final Point mDropLocation; final TransactionProvider mTransactionProvider; DraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation) { this(bubble, dropLocation, SurfaceControl.Transaction::new); } DraggedBubbleIconToFullscreen(Bubble bubble) { @VisibleForTesting DraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation, TransactionProvider transactionProvider) { mBubble = bubble; mDropLocation = dropLocation; mTransactionProvider = transactionProvider; bubble.setPreparingTransition(this); WindowContainerToken token = bubble.getTaskView().getTaskInfo().getToken(); WindowContainerTransaction wct = new WindowContainerTransaction(); Loading Loading @@ -723,8 +739,34 @@ public class BubbleTransitions { } mRepository.remove(taskViewTaskController); final SurfaceControl taskLeash = change.getLeash(); // set the initial position of the task with 0 scale startTransaction.setPosition(taskLeash, mDropLocation.x, mDropLocation.y); startTransaction.setScale(taskLeash, 0, 0); startTransaction.apply(); final SurfaceControl.Transaction animT = mTransactionProvider.get(); ValueAnimator animator = ValueAnimator.ofFloat(0, 1); animator.setDuration(250); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(@NonNull Animator animation) { float progress = animator.getAnimatedFraction(); float x = mDropLocation.x * (1 - progress); float y = mDropLocation.y * (1 - progress); animT.setPosition(taskLeash, x, y); animT.setScale(taskLeash, progress, progress); animT.apply(); } }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(@NonNull Animator animation) { animT.close(); finishCallback.onTransitionFinished(null); } }); animator.start(); taskViewTaskController.notifyTaskRemovalStarted(mBubble.getTaskView().getTaskInfo()); mTaskViewTransitions.onExternalDone(transition); return true; Loading Loading @@ -774,4 +816,8 @@ public class BubbleTransitions { mTaskViewTransitions.onExternalDone(transition); } } interface TransactionProvider { SurfaceControl.Transaction get(); } }
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.wm.shell.bubbles; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.graphics.Point; import android.graphics.Rect; import android.os.UserHandle; import com.android.wm.shell.bubbles.IBubblesListener; Loading Loading @@ -59,5 +60,5 @@ interface IBubbles { oneway void showDropTarget(in boolean show, in @nullable BubbleBarLocation location) = 15; oneway void moveBubbleToFullscreen(in String key) = 16; oneway void moveDraggedBubbleToFullscreen(in String key, in Point dropLocation) = 16; } No newline at end of file
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java +26 −6 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -37,6 +38,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.IBinder; Loading @@ -47,7 +49,9 @@ import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import androidx.core.animation.AnimatorTestRule; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.launcher3.icons.BubbleIconFactory; import com.android.wm.shell.ShellTaskOrganizer; Loading @@ -65,6 +69,7 @@ import com.android.wm.shell.taskview.TaskViewTransitions; import com.android.wm.shell.transition.Transitions; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; Loading @@ -76,6 +81,8 @@ import org.mockito.MockitoAnnotations; @SmallTest public class BubbleTransitionsTest extends ShellTestCase { @Rule public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(); private static final int FULLSCREEN_TASK_WIDTH = 200; private static final int FULLSCREEN_TASK_HEIGHT = 100; Loading Loading @@ -292,24 +299,37 @@ public class BubbleTransitionsTest extends ShellTestCase { @Test public void convertDraggedBubbleToFullscreen() { ActivityManager.RunningTaskInfo taskInfo = setupBubble(); SurfaceControl.Transaction animT = mock(SurfaceControl.Transaction.class); BubbleTransitions.TransactionProvider transactionProvider = () -> animT; final DraggedBubbleIconToFullscreen bt = (DraggedBubbleIconToFullscreen) mBubbleTransitions .startDraggedBubbleIconToFullscreen(mBubble); mBubbleTransitions.new DraggedBubbleIconToFullscreen( mBubble, new Point(100, 50), transactionProvider); verify(mTransitions).startTransition(anyInt(), any(), eq(bt)); SurfaceControl taskLeash = new SurfaceControl.Builder().setName("taskLeash").build(); final TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0); final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, mock(SurfaceControl.class)); final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, taskLeash); chg.setMode(TRANSIT_TO_FRONT); 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 -> {}; boolean[] transitionFinished = {false}; Transitions.TransitionFinishCallback finishCb = wct -> transitionFinished[0] = true; InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { bt.startAnimation(bt.mTransition, info, startT, finishT, finishCb); mAnimatorTestRule.advanceTimeBy(250); }); verify(startT).setScale(taskLeash, 0, 0); verify(startT).setPosition(taskLeash, 100, 50); verify(startT).apply(); verify(animT).setScale(taskLeash, 1, 1); verify(animT).setPosition(taskLeash, 0, 0); verify(animT, atLeastOnce()).apply(); verify(animT).close(); assertFalse(mTaskViewTransitions.hasPending()); assertTrue(transitionFinished[0]); } @Test Loading