Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDoubleTapHelper.java→libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java +6 −8 Original line number Original line Diff line number Diff line /* /* * 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"); * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License. Loading @@ -14,14 +14,12 @@ * limitations under the License. * 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.IntDef; import android.annotation.NonNull; import android.annotation.NonNull; import android.graphics.Rect; import android.graphics.Rect; import com.android.wm.shell.common.pip.PipBoundsState; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -50,9 +48,9 @@ public class PipDoubleTapHelper { @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE) @interface PipSizeSpec {} @interface PipSizeSpec {} static final int SIZE_SPEC_DEFAULT = 0; public static final int SIZE_SPEC_DEFAULT = 0; static final int SIZE_SPEC_MAX = 1; public static final int SIZE_SPEC_MAX = 1; static final int SIZE_SPEC_CUSTOM = 2; public static final int SIZE_SPEC_CUSTOM = 2; /** /** * Returns MAX or DEFAULT {@link PipSizeSpec} to toggle to/from. * Returns MAX or DEFAULT {@link PipSizeSpec} to toggle to/from. Loading Loading @@ -84,7 +82,7 @@ public class PipDoubleTapHelper { * @return pip screen size to switch to * @return pip screen size to switch to */ */ @PipSizeSpec @PipSizeSpec static int nextSizeSpec(@NonNull PipBoundsState mPipBoundsState, public static int nextSizeSpec(@NonNull PipBoundsState mPipBoundsState, @NonNull Rect userResizeBounds) { @NonNull Rect userResizeBounds) { // is pip screen at its maximum // is pip screen at its maximum boolean isScreenMax = mPipBoundsState.getBounds().width() boolean isScreenMax = mPipBoundsState.getBounds().width() Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -50,15 +50,16 @@ import java.util.Optional; public abstract class Pip2Module { public abstract class Pip2Module { @WMSingleton @WMSingleton @Provides @Provides static PipTransition providePipTransition(@NonNull ShellInit shellInit, static PipTransition providePipTransition(Context context, @NonNull ShellInit shellInit, @NonNull ShellTaskOrganizer shellTaskOrganizer, @NonNull ShellTaskOrganizer shellTaskOrganizer, @NonNull Transitions transitions, @NonNull Transitions transitions, PipBoundsState pipBoundsState, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, Optional<PipController> pipController, Optional<PipController> pipController, @NonNull PipScheduler pipScheduler) { @NonNull PipScheduler pipScheduler) { return new PipTransition(shellInit, shellTaskOrganizer, transitions, pipBoundsState, null, return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, pipBoundsAlgorithm, pipScheduler); pipBoundsState, null, pipBoundsAlgorithm, pipScheduler); } } @WMSingleton @WMSingleton Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +12 −0 Original line number Original line Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.wm.shell.transition.Transitions; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.List; import java.util.List; import java.util.function.Consumer; /** /** * Responsible supplying PiP Transitions. * Responsible supplying PiP Transitions. Loading Loading @@ -115,6 +116,17 @@ public abstract class PipTransitionController implements Transitions.TransitionH // Default implementation does nothing. // Default implementation does nothing. } } /** * 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 * Called when the transition animation can't continue (eg. task is removed during * animation) * animation) Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -52,6 +52,7 @@ import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; 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.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.common.pip.SizeSpecSource; import com.android.wm.shell.common.pip.SizeSpecSource; Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +50 −3 Original line number Original line Diff line number Diff line Loading @@ -24,10 +24,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.graphics.Rect; import android.view.SurfaceControl; import android.view.SurfaceControl; import android.window.WindowContainerToken; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction; import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat; Loading @@ -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.common.pip.PipUtils; import com.android.wm.shell.pip.PipTransitionController; 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. * Scheduler for Shell initiated PiP transitions and animations. */ */ Loading @@ -58,13 +64,37 @@ public class PipScheduler { private SurfaceControl mPinnedTaskLeash; private SurfaceControl mPinnedTaskLeash; /** /** * A temporary broadcast receiver to initiate exit PiP via expand. * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell. * This will later be modified to be triggered by the PiP menu. * 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 { private class PipSchedulerReceiver extends BroadcastReceiver { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { int userJourneyCode = intent.getIntExtra("cuj_code_extra", 0); switch (userJourneyCode) { case PIP_EXIT_VIA_EXPAND_CODE: scheduleExitPipViaExpand(); scheduleExitPipViaExpand(); break; case PIP_DOUBLE_TAP: scheduleDoubleTapToResize(); break; default: throw new IllegalStateException("unexpected CUJ code=" + userJourneyCode); } } } } } Loading Loading @@ -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() { void onExitPip() { mPipTaskToken = null; mPipTaskToken = null; mPinnedTaskLeash = null; mPinnedTaskLeash = null; Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDoubleTapHelper.java→libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDoubleTapHelper.java +6 −8 Original line number Original line Diff line number Diff line /* /* * 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"); * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License. Loading @@ -14,14 +14,12 @@ * limitations under the License. * 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.IntDef; import android.annotation.NonNull; import android.annotation.NonNull; import android.graphics.Rect; import android.graphics.Rect; import com.android.wm.shell.common.pip.PipBoundsState; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -50,9 +48,9 @@ public class PipDoubleTapHelper { @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE) @interface PipSizeSpec {} @interface PipSizeSpec {} static final int SIZE_SPEC_DEFAULT = 0; public static final int SIZE_SPEC_DEFAULT = 0; static final int SIZE_SPEC_MAX = 1; public static final int SIZE_SPEC_MAX = 1; static final int SIZE_SPEC_CUSTOM = 2; public static final int SIZE_SPEC_CUSTOM = 2; /** /** * Returns MAX or DEFAULT {@link PipSizeSpec} to toggle to/from. * Returns MAX or DEFAULT {@link PipSizeSpec} to toggle to/from. Loading Loading @@ -84,7 +82,7 @@ public class PipDoubleTapHelper { * @return pip screen size to switch to * @return pip screen size to switch to */ */ @PipSizeSpec @PipSizeSpec static int nextSizeSpec(@NonNull PipBoundsState mPipBoundsState, public static int nextSizeSpec(@NonNull PipBoundsState mPipBoundsState, @NonNull Rect userResizeBounds) { @NonNull Rect userResizeBounds) { // is pip screen at its maximum // is pip screen at its maximum boolean isScreenMax = mPipBoundsState.getBounds().width() boolean isScreenMax = mPipBoundsState.getBounds().width() Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -50,15 +50,16 @@ import java.util.Optional; public abstract class Pip2Module { public abstract class Pip2Module { @WMSingleton @WMSingleton @Provides @Provides static PipTransition providePipTransition(@NonNull ShellInit shellInit, static PipTransition providePipTransition(Context context, @NonNull ShellInit shellInit, @NonNull ShellTaskOrganizer shellTaskOrganizer, @NonNull ShellTaskOrganizer shellTaskOrganizer, @NonNull Transitions transitions, @NonNull Transitions transitions, PipBoundsState pipBoundsState, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, Optional<PipController> pipController, Optional<PipController> pipController, @NonNull PipScheduler pipScheduler) { @NonNull PipScheduler pipScheduler) { return new PipTransition(shellInit, shellTaskOrganizer, transitions, pipBoundsState, null, return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, pipBoundsAlgorithm, pipScheduler); pipBoundsState, null, pipBoundsAlgorithm, pipScheduler); } } @WMSingleton @WMSingleton Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +12 −0 Original line number Original line Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.wm.shell.transition.Transitions; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.List; import java.util.List; import java.util.function.Consumer; /** /** * Responsible supplying PiP Transitions. * Responsible supplying PiP Transitions. Loading Loading @@ -115,6 +116,17 @@ public abstract class PipTransitionController implements Transitions.TransitionH // Default implementation does nothing. // Default implementation does nothing. } } /** * 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 * Called when the transition animation can't continue (eg. task is removed during * animation) * animation) Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -52,6 +52,7 @@ import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; 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.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.common.pip.SizeSpecSource; import com.android.wm.shell.common.pip.SizeSpecSource; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +50 −3 Original line number Original line Diff line number Diff line Loading @@ -24,10 +24,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.graphics.Rect; import android.view.SurfaceControl; import android.view.SurfaceControl; import android.window.WindowContainerToken; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction; import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat; Loading @@ -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.common.pip.PipUtils; import com.android.wm.shell.pip.PipTransitionController; 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. * Scheduler for Shell initiated PiP transitions and animations. */ */ Loading @@ -58,13 +64,37 @@ public class PipScheduler { private SurfaceControl mPinnedTaskLeash; private SurfaceControl mPinnedTaskLeash; /** /** * A temporary broadcast receiver to initiate exit PiP via expand. * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell. * This will later be modified to be triggered by the PiP menu. * 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 { private class PipSchedulerReceiver extends BroadcastReceiver { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { int userJourneyCode = intent.getIntExtra("cuj_code_extra", 0); switch (userJourneyCode) { case PIP_EXIT_VIA_EXPAND_CODE: scheduleExitPipViaExpand(); scheduleExitPipViaExpand(); break; case PIP_DOUBLE_TAP: scheduleDoubleTapToResize(); break; default: throw new IllegalStateException("unexpected CUJ code=" + userJourneyCode); } } } } } Loading Loading @@ -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() { void onExitPip() { mPipTaskToken = null; mPipTaskToken = null; mPinnedTaskLeash = null; mPinnedTaskLeash = null; Loading