diff options
| author | 2024-01-23 10:02:46 -0800 | |
|---|---|---|
| committer | 2024-01-24 10:25:03 -0800 | |
| commit | e07ac6c15cd76b0052fb5ca5f63c5b1a4d4b796c (patch) | |
| tree | 4924c64728eecb1f9e39f42136229787be13f0b2 | |
| parent | 25bde8f19773a0edb459c3ffa87f989d689fb37f (diff) | |
Implement double tap CUJ in PiP2
Implement transitions flow of double tap CUJ in PiP2
(decoupled from the upcoming animator refactoring).
The "double tap" would be triggered via a broadcast intent
to decouple it from the upcoming PipTouchHandler v2 as well.
(current version of touch handler has certain legacy dependencies,
so it will most probably be reimplemented for PiP2)
Also moved PipDoubleTapHelper into the common package
since we will use it both for pip and pip2.
Bug: 321984612
Test: adb shell am broadcast \
-a com.android.wm.shell.pip2.phone.PipScheduler \
--ei cuj_code_extra 1
Change-Id: I185d32e5a8d2ad5217afa0eca93a7ca893b84129
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java (renamed from libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDoubleTapHelper.java) | 14 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java | 7 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java | 12 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java | 1 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java | 53 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java | 156 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java | 3 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java | 11 |
8 files changed, 192 insertions, 65 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDoubleTapHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java index 1b1ebc39b558..4cbb78f2dae2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDoubleTapHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,12 @@ * limitations under the License. */ -package com.android.wm.shell.pip.phone; +package com.android.wm.shell.common.pip; import android.annotation.IntDef; import android.annotation.NonNull; import android.graphics.Rect; -import com.android.wm.shell.common.pip.PipBoundsState; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -50,9 +48,9 @@ public class PipDoubleTapHelper { @Retention(RetentionPolicy.SOURCE) @interface PipSizeSpec {} - static final int SIZE_SPEC_DEFAULT = 0; - static final int SIZE_SPEC_MAX = 1; - static final int SIZE_SPEC_CUSTOM = 2; + public static final int SIZE_SPEC_DEFAULT = 0; + public static final int SIZE_SPEC_MAX = 1; + public static final int SIZE_SPEC_CUSTOM = 2; /** * Returns MAX or DEFAULT {@link PipSizeSpec} to toggle to/from. @@ -84,7 +82,7 @@ public class PipDoubleTapHelper { * @return pip screen size to switch to */ @PipSizeSpec - static int nextSizeSpec(@NonNull PipBoundsState mPipBoundsState, + public static int nextSizeSpec(@NonNull PipBoundsState mPipBoundsState, @NonNull Rect userResizeBounds) { // is pip screen at its maximum boolean isScreenMax = mPipBoundsState.getBounds().width() diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java index 3b48c67a5bbd..7b98fa6523cb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java @@ -50,15 +50,16 @@ import java.util.Optional; public abstract class Pip2Module { @WMSingleton @Provides - static PipTransition providePipTransition(@NonNull ShellInit shellInit, + static PipTransition providePipTransition(Context context, + @NonNull ShellInit shellInit, @NonNull ShellTaskOrganizer shellTaskOrganizer, @NonNull Transitions transitions, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, Optional<PipController> pipController, @NonNull PipScheduler pipScheduler) { - return new PipTransition(shellInit, shellTaskOrganizer, transitions, pipBoundsState, null, - pipBoundsAlgorithm, pipScheduler); + return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, + pipBoundsState, null, pipBoundsAlgorithm, pipScheduler); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java index 04911c0bc064..0e7073688ec4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java @@ -47,6 +47,7 @@ import com.android.wm.shell.transition.Transitions; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; /** * Responsible supplying PiP Transitions. @@ -116,6 +117,17 @@ public abstract class PipTransitionController implements Transitions.TransitionH } /** + * Called when the Shell wants to start resizing Pip transition/animation. + * + * @param onFinishResizeCallback callback guaranteed to execute when animation ends and + * client completes any potential draws upon WM state updates. + */ + public void startResizeTransition(WindowContainerTransaction wct, + Consumer<Rect> onFinishResizeCallback) { + // Default implementation does nothing. + } + + /** * Called when the transition animation can't continue (eg. task is removed during * animation) */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index 452a41696fcf..81705e20a1df 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -52,6 +52,7 @@ import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; +import com.android.wm.shell.common.pip.PipDoubleTapHelper; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.common.pip.SizeSpecSource; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java index 0b8f60e44c7e..57b73b3019f4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java @@ -24,10 +24,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; +import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; @@ -36,6 +38,10 @@ import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip.PipTransitionController; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.function.Consumer; + /** * Scheduler for Shell initiated PiP transitions and animations. */ @@ -58,13 +64,37 @@ public class PipScheduler { private SurfaceControl mPinnedTaskLeash; /** - * A temporary broadcast receiver to initiate exit PiP via expand. - * This will later be modified to be triggered by the PiP menu. + * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell. + * This is used for a broadcast receiver to resolve intents. This should be removed once + * there is an equivalent of PipTouchHandler and PipResizeGestureHandler for PiP2. + */ + private static final int PIP_EXIT_VIA_EXPAND_CODE = 0; + private static final int PIP_DOUBLE_TAP = 1; + + @IntDef(value = { + PIP_EXIT_VIA_EXPAND_CODE, + PIP_DOUBLE_TAP + }) + @Retention(RetentionPolicy.SOURCE) + @interface PipUserJourneyCode {} + + /** + * A temporary broadcast receiver to initiate PiP CUJs. */ private class PipSchedulerReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - scheduleExitPipViaExpand(); + int userJourneyCode = intent.getIntExtra("cuj_code_extra", 0); + switch (userJourneyCode) { + case PIP_EXIT_VIA_EXPAND_CODE: + scheduleExitPipViaExpand(); + break; + case PIP_DOUBLE_TAP: + scheduleDoubleTapToResize(); + break; + default: + throw new IllegalStateException("unexpected CUJ code=" + userJourneyCode); + } } } @@ -121,6 +151,23 @@ public class PipScheduler { } } + /** + * Schedules resize PiP via double tap. + */ + public void scheduleDoubleTapToResize() {} + + /** + * Animates resizing of the pinned stack given the duration. + */ + public void scheduleAnimateResizePip(Rect toBounds, Consumer<Rect> onFinishResizeCallback) { + if (mPipTaskToken == null) { + return; + } + WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.setBounds(mPipTaskToken, toBounds); + mPipTransitionController.startResizeTransition(wct, onFinishResizeCallback); + } + void onExitPip() { mPipTaskToken = null; mPinnedTaskLeash = null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index 3b0e7c139bed..f3d178aef4ea 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -22,10 +22,12 @@ import static android.view.WindowManager.TRANSIT_PIP; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; +import static com.android.wm.shell.transition.Transitions.TRANSIT_RESIZE_PIP; import android.annotation.NonNull; import android.app.ActivityManager; import android.app.PictureInPictureParams; +import android.content.Context; import android.graphics.Rect; import android.os.IBinder; import android.view.SurfaceControl; @@ -36,6 +38,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; +import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; @@ -45,25 +48,29 @@ import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; +import java.util.function.Consumer; + /** * Implementation of transitions for PiP on phone. */ public class PipTransition extends PipTransitionController { private static final String TAG = PipTransition.class.getSimpleName(); + private final Context mContext; private final PipScheduler mPipScheduler; @Nullable private WindowContainerToken mPipTaskToken; @Nullable private IBinder mEnterTransition; @Nullable - private IBinder mAutoEnterButtonNavTransition; - @Nullable private IBinder mExitViaExpandTransition; @Nullable - private IBinder mLegacyEnterTransition; + private IBinder mResizeTransition; + + private Consumer<Rect> mFinishResizeCallback; public PipTransition( + Context context, @NonNull ShellInit shellInit, @NonNull ShellTaskOrganizer shellTaskOrganizer, @NonNull Transitions transitions, @@ -74,6 +81,7 @@ public class PipTransition extends PipTransitionController { super(shellInit, shellTaskOrganizer, transitions, pipBoundsState, pipMenuController, pipBoundsAlgorithm); + mContext = context; mPipScheduler = pipScheduler; mPipScheduler.setPipTransitionController(this); } @@ -87,7 +95,7 @@ public class PipTransition extends PipTransitionController { @Override public void startExitTransition(int type, WindowContainerTransaction out, - @android.annotation.Nullable Rect destinationBounds) { + @Nullable Rect destinationBounds) { if (out == null) { return; } @@ -97,6 +105,16 @@ public class PipTransition extends PipTransitionController { } } + @Override + public void startResizeTransition(WindowContainerTransaction wct, + Consumer<Rect> onFinishResizeCallback) { + if (wct == null) { + return; + } + mResizeTransition = mTransitions.startTransition(TRANSIT_RESIZE_PIP, wct, this); + mFinishResizeCallback = onFinishResizeCallback; + } + @Nullable @Override public WindowContainerTransaction handleRequest(@NonNull IBinder transition, @@ -126,43 +144,6 @@ public class PipTransition extends PipTransitionController { public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted, @Nullable SurfaceControl.Transaction finishT) {} - private WindowContainerTransaction getEnterPipTransaction(@NonNull IBinder transition, - @NonNull TransitionRequestInfo request) { - // cache the original task token to check for multi-activity case later - final ActivityManager.RunningTaskInfo pipTask = request.getPipTask(); - PictureInPictureParams pipParams = pipTask.pictureInPictureParams; - mPipBoundsState.setBoundsStateForEntry(pipTask.topActivity, pipTask.topActivityInfo, - pipParams, mPipBoundsAlgorithm); - - // calculate the entry bounds and notify core to move task to pinned with final bounds - final Rect entryBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); - mPipBoundsState.setBounds(entryBounds); - - WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.movePipActivityToPinnedRootTask(pipTask.token, entryBounds); - return wct; - } - - private boolean isAutoEnterInButtonNavigation(@NonNull TransitionRequestInfo requestInfo) { - final ActivityManager.RunningTaskInfo pipTask = requestInfo.getPipTask(); - if (pipTask == null) { - return false; - } - if (pipTask.pictureInPictureParams == null) { - return false; - } - - // Assuming auto-enter is enabled and pipTask is non-null, the TRANSIT_OPEN request type - // implies that we are entering PiP in button navigation mode. This is guaranteed by - // TaskFragment#startPausing()` in Core which wouldn't get called in gesture nav. - return requestInfo.getType() == TRANSIT_OPEN - && pipTask.pictureInPictureParams.isAutoEnterEnabled(); - } - - private boolean isEnterPictureInPictureModeRequest(@NonNull TransitionRequestInfo requestInfo) { - return requestInfo.getType() == TRANSIT_PIP; - } - @Override public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, @@ -182,16 +163,48 @@ public class PipTransition extends PipTransitionController { } else if (transition == mExitViaExpandTransition) { mExitViaExpandTransition = null; return startExpandAnimation(info, startTransaction, finishTransaction, finishCallback); + } else if (transition == mResizeTransition) { + mResizeTransition = null; + return startResizeAnimation(info, startTransaction, finishTransaction, finishCallback); } return false; } - private boolean isLegacyEnter(@NonNull TransitionInfo info) { + private boolean startResizeAnimation(@NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction startTransaction, + @NonNull SurfaceControl.Transaction finishTransaction, + @NonNull Transitions.TransitionFinishCallback finishCallback) { TransitionInfo.Change pipChange = getPipChange(info); - // If the only change in the changes list is a TO_FRONT mode PiP task, - // then this is legacy-enter PiP. - return pipChange != null && pipChange.getMode() == TRANSIT_TO_FRONT - && info.getChanges().size() == 1; + if (pipChange == null) { + return false; + } + SurfaceControl pipLeash = pipChange.getLeash(); + Rect destinationBounds = pipChange.getEndAbsBounds(); + + // Even though the final bounds and crop are applied with finishTransaction since + // this is a visible change, we still need to handle the app draw coming in. Snapshot + // covering app draw during collection will be removed by startTransaction. So we make + // the crop equal to the final bounds and then scale the leash back to starting bounds. + startTransaction.setWindowCrop(pipLeash, pipChange.getEndAbsBounds().width(), + pipChange.getEndAbsBounds().height()); + startTransaction.setScale(pipLeash, + (float) mPipBoundsState.getBounds().width() / destinationBounds.width(), + (float) mPipBoundsState.getBounds().height() / destinationBounds.height()); + startTransaction.apply(); + + finishTransaction.setScale(pipLeash, + (float) mPipBoundsState.getBounds().width() / destinationBounds.width(), + (float) mPipBoundsState.getBounds().height() / destinationBounds.height()); + + // We are done with the transition, but will continue animating leash to final bounds. + finishCallback.onTransitionFinished(null); + + // Animate the pip leash with the new buffer + final int duration = mContext.getResources().getInteger( + R.integer.config_pipResizeAnimationDuration); + // TODO: b/275910498 Couple this routine with a new implementation of the PiP animator. + startResizeAnimation(pipLeash, mPipBoundsState.getBounds(), destinationBounds, duration); + return true; } private boolean startBoundsTypeEnterAnimation(@NonNull TransitionInfo info, @@ -251,6 +264,57 @@ public class PipTransition extends PipTransitionController { return null; } + private WindowContainerTransaction getEnterPipTransaction(@NonNull IBinder transition, + @NonNull TransitionRequestInfo request) { + // cache the original task token to check for multi-activity case later + final ActivityManager.RunningTaskInfo pipTask = request.getPipTask(); + PictureInPictureParams pipParams = pipTask.pictureInPictureParams; + mPipBoundsState.setBoundsStateForEntry(pipTask.topActivity, pipTask.topActivityInfo, + pipParams, mPipBoundsAlgorithm); + + // calculate the entry bounds and notify core to move task to pinned with final bounds + final Rect entryBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); + mPipBoundsState.setBounds(entryBounds); + + WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.movePipActivityToPinnedRootTask(pipTask.token, entryBounds); + return wct; + } + + private boolean isAutoEnterInButtonNavigation(@NonNull TransitionRequestInfo requestInfo) { + final ActivityManager.RunningTaskInfo pipTask = requestInfo.getPipTask(); + if (pipTask == null) { + return false; + } + if (pipTask.pictureInPictureParams == null) { + return false; + } + + // Assuming auto-enter is enabled and pipTask is non-null, the TRANSIT_OPEN request type + // implies that we are entering PiP in button navigation mode. This is guaranteed by + // TaskFragment#startPausing()` in Core which wouldn't get called in gesture nav. + return requestInfo.getType() == TRANSIT_OPEN + && pipTask.pictureInPictureParams.isAutoEnterEnabled(); + } + + private boolean isEnterPictureInPictureModeRequest(@NonNull TransitionRequestInfo requestInfo) { + return requestInfo.getType() == TRANSIT_PIP; + } + + private boolean isLegacyEnter(@NonNull TransitionInfo info) { + TransitionInfo.Change pipChange = getPipChange(info); + // If the only change in the changes list is a TO_FRONT mode PiP task, + // then this is legacy-enter PiP. + return pipChange != null && pipChange.getMode() == TRANSIT_TO_FRONT + && info.getChanges().size() == 1; + } + + /** + * TODO: b/275910498 Use a new implementation of the PiP animator here. + */ + private void startResizeAnimation(SurfaceControl leash, Rect startBounds, + Rect endBounds, int duration) {} + private void onExitPip() { mPipTaskToken = null; mPipScheduler.onExitPip(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index b0d8b47b170a..f7b4214f7612 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -172,6 +172,9 @@ public class Transitions implements RemoteCallable<Transitions>, /** Transition to animate task to desktop. */ public static final int TRANSIT_MOVE_TO_DESKTOP = WindowManager.TRANSIT_FIRST_CUSTOM + 15; + /** Transition to resize PiP task. */ + public static final int TRANSIT_RESIZE_PIP = TRANSIT_FIRST_CUSTOM + 16; + private final ShellTaskOrganizer mOrganizer; private final Context mContext; private final ShellExecutor mMainExecutor; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java index 0f8db85dcef4..b583acda1c9a 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipDoubleTapHelperTest.java @@ -16,10 +16,10 @@ package com.android.wm.shell.pip.phone; -import static com.android.wm.shell.pip.phone.PipDoubleTapHelper.SIZE_SPEC_CUSTOM; -import static com.android.wm.shell.pip.phone.PipDoubleTapHelper.SIZE_SPEC_DEFAULT; -import static com.android.wm.shell.pip.phone.PipDoubleTapHelper.SIZE_SPEC_MAX; -import static com.android.wm.shell.pip.phone.PipDoubleTapHelper.nextSizeSpec; +import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_CUSTOM; +import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_DEFAULT; +import static com.android.wm.shell.common.pip.PipDoubleTapHelper.SIZE_SPEC_MAX; +import static com.android.wm.shell.common.pip.PipDoubleTapHelper.nextSizeSpec; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -30,6 +30,7 @@ import android.testing.AndroidTestingRunner; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.pip.PipBoundsState; +import com.android.wm.shell.common.pip.PipDoubleTapHelper; import org.junit.Assert; import org.junit.Before; @@ -38,7 +39,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; /** - * Unit test against {@link PipDoubleTapHelper}. + * Unit test against {@link com.android.wm.shell.common.pip.PipDoubleTapHelper}. */ @RunWith(AndroidTestingRunner.class) public class PipDoubleTapHelperTest extends ShellTestCase { |