Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +18 −5 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.FloatingContentCoordinator; 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.SystemWindows; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TaskStackListenerImpl; 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.PipDisplayLayoutState; import com.android.wm.shell.common.pip.PipDisplayLayoutState; Loading @@ -43,6 +44,7 @@ import com.android.wm.shell.pip2.phone.PipMotionHelper; import com.android.wm.shell.pip2.phone.PipScheduler; import com.android.wm.shell.pip2.phone.PipScheduler; import com.android.wm.shell.pip2.phone.PipTouchHandler; import com.android.wm.shell.pip2.phone.PipTouchHandler; import com.android.wm.shell.pip2.phone.PipTransition; import com.android.wm.shell.pip2.phone.PipTransition; import com.android.wm.shell.pip2.phone.PipTransitionState; import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.sysui.ShellInit; Loading @@ -69,9 +71,11 @@ public abstract class Pip2Module { PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, Optional<PipController> pipController, Optional<PipController> pipController, PipTouchHandler pipTouchHandler, PipTouchHandler pipTouchHandler, @NonNull PipScheduler pipScheduler) { @NonNull PipScheduler pipScheduler, @NonNull PipTransitionState pipStackListenerController) { return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, pipBoundsState, null, pipBoundsAlgorithm, pipScheduler); pipBoundsState, null, pipBoundsAlgorithm, pipScheduler, pipStackListenerController); } } @WMSingleton @WMSingleton Loading @@ -85,6 +89,9 @@ public abstract class Pip2Module { PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, PipDisplayLayoutState pipDisplayLayoutState, PipScheduler pipScheduler, PipScheduler pipScheduler, TaskStackListenerImpl taskStackListener, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, @ShellMainThread ShellExecutor mainExecutor) { @ShellMainThread ShellExecutor mainExecutor) { if (!PipUtils.isPip2ExperimentEnabled()) { if (!PipUtils.isPip2ExperimentEnabled()) { return Optional.empty(); return Optional.empty(); Loading @@ -92,7 +99,7 @@ public abstract class Pip2Module { return Optional.ofNullable(PipController.create( return Optional.ofNullable(PipController.create( context, shellInit, shellController, displayController, displayInsetsController, context, shellInit, shellController, displayController, displayInsetsController, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, pipScheduler, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, pipScheduler, mainExecutor)); taskStackListener, shellTaskOrganizer, pipTransitionState, mainExecutor)); } } } } Loading @@ -101,8 +108,8 @@ public abstract class Pip2Module { static PipScheduler providePipScheduler(Context context, static PipScheduler providePipScheduler(Context context, PipBoundsState pipBoundsState, PipBoundsState pipBoundsState, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread ShellExecutor mainExecutor, ShellTaskOrganizer shellTaskOrganizer) { PipTransitionState pipTransitionState) { return new PipScheduler(context, pipBoundsState, mainExecutor, shellTaskOrganizer); return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState); } } @WMSingleton @WMSingleton Loading Loading @@ -146,4 +153,10 @@ public abstract class Pip2Module { return new PipMotionHelper(context, pipBoundsState, menuController, pipSnapAlgorithm, return new PipMotionHelper(context, pipBoundsState, menuController, pipSnapAlgorithm, floatingContentCoordinator, pipPerfHintControllerOptional); floatingContentCoordinator, pipPerfHintControllerOptional); } } @WMSingleton @Provides static PipTransitionState providePipStackListenerController() { return new PipTransitionState(); } } } libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +1 −6 Original line number Original line Diff line number Diff line Loading @@ -54,7 +54,6 @@ 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 @@ -125,12 +124,8 @@ public abstract class PipTransitionController implements Transitions.TransitionH /** /** * Called when the Shell wants to start resizing Pip transition/animation. * 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, public void startResizeTransition(WindowContainerTransaction wct) { Consumer<Rect> onFinishResizeCallback) { // Default implementation does nothing. // Default implementation does nothing. } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java +74 −3 Original line number Original line Diff line number Diff line Loading @@ -16,25 +16,31 @@ package com.android.wm.shell.pip2.phone; package com.android.wm.shell.pip2.phone; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_PIP; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_PIP; import android.app.ActivityManager; import android.app.PictureInPictureParams; import android.app.PictureInPictureParams; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Rect; import android.os.Bundle; import android.view.InsetsState; import android.view.InsetsState; import android.view.SurfaceControl; import android.view.SurfaceControl; import androidx.annotation.BinderThread; import androidx.annotation.BinderThread; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.Preconditions; import com.android.wm.shell.R; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout; Loading @@ -42,6 +48,8 @@ import com.android.wm.shell.common.ExternalInterfaceBinder; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.pip.IPip; import com.android.wm.shell.common.pip.IPip; import com.android.wm.shell.common.pip.IPipAnimationListener; import com.android.wm.shell.common.pip.IPipAnimationListener; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; Loading @@ -57,8 +65,11 @@ import com.android.wm.shell.sysui.ShellInit; * Manages the picture-in-picture (PIP) UI and states for Phones. * Manages the picture-in-picture (PIP) UI and states for Phones. */ */ public class PipController implements ConfigurationChangeListener, public class PipController implements ConfigurationChangeListener, PipTransitionState.PipTransitionStateChangedListener, DisplayController.OnDisplaysChangedListener, RemoteCallable<PipController> { DisplayController.OnDisplaysChangedListener, RemoteCallable<PipController> { private static final String TAG = PipController.class.getSimpleName(); private static final String TAG = PipController.class.getSimpleName(); private static final String SWIPE_TO_PIP_APP_BOUNDS = "pip_app_bounds"; private static final String SWIPE_TO_PIP_OVERLAY = "swipe_to_pip_overlay"; private final Context mContext; private final Context mContext; private final ShellController mShellController; private final ShellController mShellController; Loading @@ -68,6 +79,9 @@ public class PipController implements ConfigurationChangeListener, private final PipBoundsAlgorithm mPipBoundsAlgorithm; private final PipBoundsAlgorithm mPipBoundsAlgorithm; private final PipDisplayLayoutState mPipDisplayLayoutState; private final PipDisplayLayoutState mPipDisplayLayoutState; private final PipScheduler mPipScheduler; private final PipScheduler mPipScheduler; private final TaskStackListenerImpl mTaskStackListener; private final ShellTaskOrganizer mShellTaskOrganizer; private final PipTransitionState mPipTransitionState; private final ShellExecutor mMainExecutor; private final ShellExecutor mMainExecutor; // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents. // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents. Loading Loading @@ -104,6 +118,9 @@ public class PipController implements ConfigurationChangeListener, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, PipDisplayLayoutState pipDisplayLayoutState, PipScheduler pipScheduler, PipScheduler pipScheduler, TaskStackListenerImpl taskStackListener, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, ShellExecutor mainExecutor) { ShellExecutor mainExecutor) { mContext = context; mContext = context; mShellController = shellController; mShellController = shellController; Loading @@ -113,6 +130,10 @@ public class PipController implements ConfigurationChangeListener, mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipDisplayLayoutState = pipDisplayLayoutState; mPipDisplayLayoutState = pipDisplayLayoutState; mPipScheduler = pipScheduler; mPipScheduler = pipScheduler; mTaskStackListener = taskStackListener; mShellTaskOrganizer = shellTaskOrganizer; mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this); mMainExecutor = mainExecutor; mMainExecutor = mainExecutor; if (PipUtils.isPip2ExperimentEnabled()) { if (PipUtils.isPip2ExperimentEnabled()) { Loading @@ -132,6 +153,9 @@ public class PipController implements ConfigurationChangeListener, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, PipDisplayLayoutState pipDisplayLayoutState, PipScheduler pipScheduler, PipScheduler pipScheduler, TaskStackListenerImpl taskStackListener, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, ShellExecutor mainExecutor) { ShellExecutor mainExecutor) { if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, Loading @@ -140,7 +164,8 @@ public class PipController implements ConfigurationChangeListener, } } return new PipController(context, shellInit, shellController, displayController, return new PipController(context, shellInit, shellController, displayController, displayInsetsController, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, displayInsetsController, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, pipScheduler, mainExecutor); pipScheduler, taskStackListener, shellTaskOrganizer, pipTransitionState, mainExecutor); } } private void onInit() { private void onInit() { Loading @@ -164,6 +189,17 @@ public class PipController implements ConfigurationChangeListener, mShellController.addExternalInterface(KEY_EXTRA_SHELL_PIP, mShellController.addExternalInterface(KEY_EXTRA_SHELL_PIP, this::createExternalInterface, this); this::createExternalInterface, this); mShellController.addConfigurationChangeListener(this); mShellController.addConfigurationChangeListener(this); mTaskStackListener.addListener(new TaskStackListenerCallback() { @Override public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { if (task.getWindowingMode() != WINDOWING_MODE_PINNED) { return; } mPipScheduler.scheduleExitPipViaExpand(); } }); } } private ExternalInterfaceBinder createExternalInterface() { private ExternalInterfaceBinder createExternalInterface() { Loading Loading @@ -245,11 +281,46 @@ public class PipController implements ConfigurationChangeListener, Rect destinationBounds, SurfaceControl overlay, Rect appBounds) { Rect destinationBounds, SurfaceControl overlay, Rect appBounds) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "onSwipePipToHomeAnimationStart: %s", componentName); "onSwipePipToHomeAnimationStart: %s", componentName); mPipScheduler.onSwipePipToHomeAnimationStart(taskId, componentName, destinationBounds, Bundle extra = new Bundle(); overlay, appBounds); extra.putParcelable(SWIPE_TO_PIP_OVERLAY, overlay); extra.putParcelable(SWIPE_TO_PIP_APP_BOUNDS, appBounds); mPipTransitionState.setState(PipTransitionState.SWIPING_TO_PIP, extra); if (overlay != null) { // Shell transitions might use a root animation leash, which will be removed when // the Recents transition is finished. Launcher attaches the overlay leash to this // animation target leash; thus, we need to reparent it to the actual Task surface now. // PipTransition is responsible to fade it out and cleanup when finishing the enter PIP // transition. SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); mShellTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, tx); tx.setLayer(overlay, Integer.MAX_VALUE); tx.apply(); } mPipRecentsAnimationListener.onPipAnimationStarted(); mPipRecentsAnimationListener.onPipAnimationStarted(); } } @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { if (newState == PipTransitionState.SWIPING_TO_PIP) { Preconditions.checkState(extra != null, "No extra bundle for " + mPipTransitionState); SurfaceControl overlay = extra.getParcelable( SWIPE_TO_PIP_OVERLAY, SurfaceControl.class); Rect appBounds = extra.getParcelable( SWIPE_TO_PIP_APP_BOUNDS, Rect.class); Preconditions.checkState(appBounds != null, "App bounds can't be null for " + mPipTransitionState); mPipTransitionState.setSwipePipToHomeState(overlay, appBounds); } else if (newState == PipTransitionState.ENTERED_PIP) { if (mPipTransitionState.isInSwipePipToHomeTransition()) { mPipTransitionState.resetSwipePipToHomeState(); } } } // // // IPipAnimationListener Binder proxy helpers // IPipAnimationListener Binder proxy helpers // // Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +10 −76 Original line number Original line Diff line number Diff line Loading @@ -21,21 +21,16 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.ComponentName; 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.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction; import androidx.annotation.IntDef; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.common.pip.PipUtils; Loading @@ -43,7 +38,6 @@ import com.android.wm.shell.pip.PipTransitionController; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; 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 @@ -55,31 +49,10 @@ public class PipScheduler { private final Context mContext; private final Context mContext; private final PipBoundsState mPipBoundsState; private final PipBoundsState mPipBoundsState; private final ShellExecutor mMainExecutor; private final ShellExecutor mMainExecutor; private final ShellTaskOrganizer mShellTaskOrganizer; private final PipTransitionState mPipTransitionState; private PipSchedulerReceiver mSchedulerReceiver; private PipSchedulerReceiver mSchedulerReceiver; private PipTransitionController mPipTransitionController; private PipTransitionController mPipTransitionController; // pinned PiP task's WC token @Nullable private WindowContainerToken mPipTaskToken; // pinned PiP task's leash @Nullable private SurfaceControl mPinnedTaskLeash; // true if Launcher has started swipe PiP to home animation private boolean mInSwipePipToHomeTransition; // Overlay leash potentially used during swipe PiP to home transition; // if null while mInSwipePipToHomeTransition is true, then srcRectHint was invalid. @Nullable SurfaceControl mSwipePipToHomeOverlay; // App bounds used when as a starting point to swipe PiP to home animation in Launcher; // these are also used to calculate the app icon overlay buffer size. @NonNull final Rect mSwipePipToHomeAppBounds = new Rect(); /** /** * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell. * 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 * This is used for a broadcast receiver to resolve intents. This should be removed once Loading Loading @@ -118,11 +91,11 @@ public class PipScheduler { public PipScheduler(Context context, public PipScheduler(Context context, PipBoundsState pipBoundsState, PipBoundsState pipBoundsState, ShellExecutor mainExecutor, ShellExecutor mainExecutor, ShellTaskOrganizer shellTaskOrganizer) { PipTransitionState pipTransitionState) { mContext = context; mContext = context; mPipBoundsState = pipBoundsState; mPipBoundsState = pipBoundsState; mMainExecutor = mainExecutor; mMainExecutor = mainExecutor; mShellTaskOrganizer = shellTaskOrganizer; mPipTransitionState = pipTransitionState; if (PipUtils.isPip2ExperimentEnabled()) { if (PipUtils.isPip2ExperimentEnabled()) { // temporary broadcast receiver to initiate exit PiP via expand // temporary broadcast receiver to initiate exit PiP via expand Loading @@ -140,25 +113,17 @@ public class PipScheduler { mPipTransitionController = pipTransitionController; mPipTransitionController = pipTransitionController; } } void setPinnedTaskLeash(SurfaceControl pinnedTaskLeash) { mPinnedTaskLeash = pinnedTaskLeash; } void setPipTaskToken(@Nullable WindowContainerToken pipTaskToken) { mPipTaskToken = pipTaskToken; } @Nullable @Nullable private WindowContainerTransaction getExitPipViaExpandTransaction() { private WindowContainerTransaction getExitPipViaExpandTransaction() { if (mPipTaskToken == null) { if (mPipTransitionState.mPipTaskToken == null) { return null; return null; } } WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction(); // final expanded bounds to be inherited from the parent // final expanded bounds to be inherited from the parent wct.setBounds(mPipTaskToken, null); wct.setBounds(mPipTransitionState.mPipTaskToken, null); // if we are hitting a multi-activity case // if we are hitting a multi-activity case // windowing mode change will reparent to original host task // windowing mode change will reparent to original host task wct.setWindowingMode(mPipTaskToken, WINDOWING_MODE_UNDEFINED); wct.setWindowingMode(mPipTransitionState.mPipTaskToken, WINDOWING_MODE_UNDEFINED); return wct; return wct; } } Loading @@ -183,43 +148,12 @@ public class PipScheduler { /** /** * Animates resizing of the pinned stack given the duration. * Animates resizing of the pinned stack given the duration. */ */ public void scheduleAnimateResizePip(Rect toBounds, Consumer<Rect> onFinishResizeCallback) { public void scheduleAnimateResizePip(Rect toBounds) { if (mPipTaskToken == null) { if (mPipTransitionState.mPipTaskToken == null || !mPipTransitionState.isInPip()) { return; return; } } WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setBounds(mPipTaskToken, toBounds); wct.setBounds(mPipTransitionState.mPipTaskToken, toBounds); mPipTransitionController.startResizeTransition(wct, onFinishResizeCallback); mPipTransitionController.startResizeTransition(wct); } void onSwipePipToHomeAnimationStart(int taskId, ComponentName componentName, Rect destinationBounds, SurfaceControl overlay, Rect appBounds) { mInSwipePipToHomeTransition = true; mSwipePipToHomeOverlay = overlay; mSwipePipToHomeAppBounds.set(appBounds); if (overlay != null) { // Shell transitions might use a root animation leash, which will be removed when // the Recents transition is finished. Launcher attaches the overlay leash to this // animation target leash; thus, we need to reparent it to the actual Task surface now. // PipTransition is responsible to fade it out and cleanup when finishing the enter PIP // transition. SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); mShellTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, tx); tx.setLayer(overlay, Integer.MAX_VALUE); tx.apply(); } } void setInSwipePipToHomeTransition(boolean inSwipePipToHome) { mInSwipePipToHomeTransition = inSwipePipToHome; } boolean isInSwipePipToHomeTransition() { return mInSwipePipToHomeTransition; } void onExitPip() { mPipTaskToken = null; mPinnedTaskLeash = null; } } } } libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +120 −51 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +18 −5 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.FloatingContentCoordinator; 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.SystemWindows; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TaskStackListenerImpl; 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.PipDisplayLayoutState; import com.android.wm.shell.common.pip.PipDisplayLayoutState; Loading @@ -43,6 +44,7 @@ import com.android.wm.shell.pip2.phone.PipMotionHelper; import com.android.wm.shell.pip2.phone.PipScheduler; import com.android.wm.shell.pip2.phone.PipScheduler; import com.android.wm.shell.pip2.phone.PipTouchHandler; import com.android.wm.shell.pip2.phone.PipTouchHandler; import com.android.wm.shell.pip2.phone.PipTransition; import com.android.wm.shell.pip2.phone.PipTransition; import com.android.wm.shell.pip2.phone.PipTransitionState; import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.sysui.ShellInit; Loading @@ -69,9 +71,11 @@ public abstract class Pip2Module { PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, Optional<PipController> pipController, Optional<PipController> pipController, PipTouchHandler pipTouchHandler, PipTouchHandler pipTouchHandler, @NonNull PipScheduler pipScheduler) { @NonNull PipScheduler pipScheduler, @NonNull PipTransitionState pipStackListenerController) { return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, pipBoundsState, null, pipBoundsAlgorithm, pipScheduler); pipBoundsState, null, pipBoundsAlgorithm, pipScheduler, pipStackListenerController); } } @WMSingleton @WMSingleton Loading @@ -85,6 +89,9 @@ public abstract class Pip2Module { PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, PipDisplayLayoutState pipDisplayLayoutState, PipScheduler pipScheduler, PipScheduler pipScheduler, TaskStackListenerImpl taskStackListener, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, @ShellMainThread ShellExecutor mainExecutor) { @ShellMainThread ShellExecutor mainExecutor) { if (!PipUtils.isPip2ExperimentEnabled()) { if (!PipUtils.isPip2ExperimentEnabled()) { return Optional.empty(); return Optional.empty(); Loading @@ -92,7 +99,7 @@ public abstract class Pip2Module { return Optional.ofNullable(PipController.create( return Optional.ofNullable(PipController.create( context, shellInit, shellController, displayController, displayInsetsController, context, shellInit, shellController, displayController, displayInsetsController, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, pipScheduler, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, pipScheduler, mainExecutor)); taskStackListener, shellTaskOrganizer, pipTransitionState, mainExecutor)); } } } } Loading @@ -101,8 +108,8 @@ public abstract class Pip2Module { static PipScheduler providePipScheduler(Context context, static PipScheduler providePipScheduler(Context context, PipBoundsState pipBoundsState, PipBoundsState pipBoundsState, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread ShellExecutor mainExecutor, ShellTaskOrganizer shellTaskOrganizer) { PipTransitionState pipTransitionState) { return new PipScheduler(context, pipBoundsState, mainExecutor, shellTaskOrganizer); return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState); } } @WMSingleton @WMSingleton Loading Loading @@ -146,4 +153,10 @@ public abstract class Pip2Module { return new PipMotionHelper(context, pipBoundsState, menuController, pipSnapAlgorithm, return new PipMotionHelper(context, pipBoundsState, menuController, pipSnapAlgorithm, floatingContentCoordinator, pipPerfHintControllerOptional); floatingContentCoordinator, pipPerfHintControllerOptional); } } @WMSingleton @Provides static PipTransitionState providePipStackListenerController() { return new PipTransitionState(); } } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +1 −6 Original line number Original line Diff line number Diff line Loading @@ -54,7 +54,6 @@ 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 @@ -125,12 +124,8 @@ public abstract class PipTransitionController implements Transitions.TransitionH /** /** * Called when the Shell wants to start resizing Pip transition/animation. * 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, public void startResizeTransition(WindowContainerTransaction wct) { Consumer<Rect> onFinishResizeCallback) { // Default implementation does nothing. // Default implementation does nothing. } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java +74 −3 Original line number Original line Diff line number Diff line Loading @@ -16,25 +16,31 @@ package com.android.wm.shell.pip2.phone; package com.android.wm.shell.pip2.phone; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_PIP; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_PIP; import android.app.ActivityManager; import android.app.PictureInPictureParams; import android.app.PictureInPictureParams; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Rect; import android.os.Bundle; import android.view.InsetsState; import android.view.InsetsState; import android.view.SurfaceControl; import android.view.SurfaceControl; import androidx.annotation.BinderThread; import androidx.annotation.BinderThread; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.Preconditions; import com.android.wm.shell.R; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout; Loading @@ -42,6 +48,8 @@ import com.android.wm.shell.common.ExternalInterfaceBinder; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.pip.IPip; import com.android.wm.shell.common.pip.IPip; import com.android.wm.shell.common.pip.IPipAnimationListener; import com.android.wm.shell.common.pip.IPipAnimationListener; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; Loading @@ -57,8 +65,11 @@ import com.android.wm.shell.sysui.ShellInit; * Manages the picture-in-picture (PIP) UI and states for Phones. * Manages the picture-in-picture (PIP) UI and states for Phones. */ */ public class PipController implements ConfigurationChangeListener, public class PipController implements ConfigurationChangeListener, PipTransitionState.PipTransitionStateChangedListener, DisplayController.OnDisplaysChangedListener, RemoteCallable<PipController> { DisplayController.OnDisplaysChangedListener, RemoteCallable<PipController> { private static final String TAG = PipController.class.getSimpleName(); private static final String TAG = PipController.class.getSimpleName(); private static final String SWIPE_TO_PIP_APP_BOUNDS = "pip_app_bounds"; private static final String SWIPE_TO_PIP_OVERLAY = "swipe_to_pip_overlay"; private final Context mContext; private final Context mContext; private final ShellController mShellController; private final ShellController mShellController; Loading @@ -68,6 +79,9 @@ public class PipController implements ConfigurationChangeListener, private final PipBoundsAlgorithm mPipBoundsAlgorithm; private final PipBoundsAlgorithm mPipBoundsAlgorithm; private final PipDisplayLayoutState mPipDisplayLayoutState; private final PipDisplayLayoutState mPipDisplayLayoutState; private final PipScheduler mPipScheduler; private final PipScheduler mPipScheduler; private final TaskStackListenerImpl mTaskStackListener; private final ShellTaskOrganizer mShellTaskOrganizer; private final PipTransitionState mPipTransitionState; private final ShellExecutor mMainExecutor; private final ShellExecutor mMainExecutor; // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents. // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents. Loading Loading @@ -104,6 +118,9 @@ public class PipController implements ConfigurationChangeListener, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, PipDisplayLayoutState pipDisplayLayoutState, PipScheduler pipScheduler, PipScheduler pipScheduler, TaskStackListenerImpl taskStackListener, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, ShellExecutor mainExecutor) { ShellExecutor mainExecutor) { mContext = context; mContext = context; mShellController = shellController; mShellController = shellController; Loading @@ -113,6 +130,10 @@ public class PipController implements ConfigurationChangeListener, mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipDisplayLayoutState = pipDisplayLayoutState; mPipDisplayLayoutState = pipDisplayLayoutState; mPipScheduler = pipScheduler; mPipScheduler = pipScheduler; mTaskStackListener = taskStackListener; mShellTaskOrganizer = shellTaskOrganizer; mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this); mMainExecutor = mainExecutor; mMainExecutor = mainExecutor; if (PipUtils.isPip2ExperimentEnabled()) { if (PipUtils.isPip2ExperimentEnabled()) { Loading @@ -132,6 +153,9 @@ public class PipController implements ConfigurationChangeListener, PipBoundsAlgorithm pipBoundsAlgorithm, PipBoundsAlgorithm pipBoundsAlgorithm, PipDisplayLayoutState pipDisplayLayoutState, PipDisplayLayoutState pipDisplayLayoutState, PipScheduler pipScheduler, PipScheduler pipScheduler, TaskStackListenerImpl taskStackListener, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, ShellExecutor mainExecutor) { ShellExecutor mainExecutor) { if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, Loading @@ -140,7 +164,8 @@ public class PipController implements ConfigurationChangeListener, } } return new PipController(context, shellInit, shellController, displayController, return new PipController(context, shellInit, shellController, displayController, displayInsetsController, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, displayInsetsController, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, pipScheduler, mainExecutor); pipScheduler, taskStackListener, shellTaskOrganizer, pipTransitionState, mainExecutor); } } private void onInit() { private void onInit() { Loading @@ -164,6 +189,17 @@ public class PipController implements ConfigurationChangeListener, mShellController.addExternalInterface(KEY_EXTRA_SHELL_PIP, mShellController.addExternalInterface(KEY_EXTRA_SHELL_PIP, this::createExternalInterface, this); this::createExternalInterface, this); mShellController.addConfigurationChangeListener(this); mShellController.addConfigurationChangeListener(this); mTaskStackListener.addListener(new TaskStackListenerCallback() { @Override public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { if (task.getWindowingMode() != WINDOWING_MODE_PINNED) { return; } mPipScheduler.scheduleExitPipViaExpand(); } }); } } private ExternalInterfaceBinder createExternalInterface() { private ExternalInterfaceBinder createExternalInterface() { Loading Loading @@ -245,11 +281,46 @@ public class PipController implements ConfigurationChangeListener, Rect destinationBounds, SurfaceControl overlay, Rect appBounds) { Rect destinationBounds, SurfaceControl overlay, Rect appBounds) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "onSwipePipToHomeAnimationStart: %s", componentName); "onSwipePipToHomeAnimationStart: %s", componentName); mPipScheduler.onSwipePipToHomeAnimationStart(taskId, componentName, destinationBounds, Bundle extra = new Bundle(); overlay, appBounds); extra.putParcelable(SWIPE_TO_PIP_OVERLAY, overlay); extra.putParcelable(SWIPE_TO_PIP_APP_BOUNDS, appBounds); mPipTransitionState.setState(PipTransitionState.SWIPING_TO_PIP, extra); if (overlay != null) { // Shell transitions might use a root animation leash, which will be removed when // the Recents transition is finished. Launcher attaches the overlay leash to this // animation target leash; thus, we need to reparent it to the actual Task surface now. // PipTransition is responsible to fade it out and cleanup when finishing the enter PIP // transition. SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); mShellTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, tx); tx.setLayer(overlay, Integer.MAX_VALUE); tx.apply(); } mPipRecentsAnimationListener.onPipAnimationStarted(); mPipRecentsAnimationListener.onPipAnimationStarted(); } } @Override public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState, @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) { if (newState == PipTransitionState.SWIPING_TO_PIP) { Preconditions.checkState(extra != null, "No extra bundle for " + mPipTransitionState); SurfaceControl overlay = extra.getParcelable( SWIPE_TO_PIP_OVERLAY, SurfaceControl.class); Rect appBounds = extra.getParcelable( SWIPE_TO_PIP_APP_BOUNDS, Rect.class); Preconditions.checkState(appBounds != null, "App bounds can't be null for " + mPipTransitionState); mPipTransitionState.setSwipePipToHomeState(overlay, appBounds); } else if (newState == PipTransitionState.ENTERED_PIP) { if (mPipTransitionState.isInSwipePipToHomeTransition()) { mPipTransitionState.resetSwipePipToHomeState(); } } } // // // IPipAnimationListener Binder proxy helpers // IPipAnimationListener Binder proxy helpers // // Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +10 −76 Original line number Original line Diff line number Diff line Loading @@ -21,21 +21,16 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.ComponentName; 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.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction; import androidx.annotation.IntDef; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.common.pip.PipUtils; Loading @@ -43,7 +38,6 @@ import com.android.wm.shell.pip.PipTransitionController; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; 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 @@ -55,31 +49,10 @@ public class PipScheduler { private final Context mContext; private final Context mContext; private final PipBoundsState mPipBoundsState; private final PipBoundsState mPipBoundsState; private final ShellExecutor mMainExecutor; private final ShellExecutor mMainExecutor; private final ShellTaskOrganizer mShellTaskOrganizer; private final PipTransitionState mPipTransitionState; private PipSchedulerReceiver mSchedulerReceiver; private PipSchedulerReceiver mSchedulerReceiver; private PipTransitionController mPipTransitionController; private PipTransitionController mPipTransitionController; // pinned PiP task's WC token @Nullable private WindowContainerToken mPipTaskToken; // pinned PiP task's leash @Nullable private SurfaceControl mPinnedTaskLeash; // true if Launcher has started swipe PiP to home animation private boolean mInSwipePipToHomeTransition; // Overlay leash potentially used during swipe PiP to home transition; // if null while mInSwipePipToHomeTransition is true, then srcRectHint was invalid. @Nullable SurfaceControl mSwipePipToHomeOverlay; // App bounds used when as a starting point to swipe PiP to home animation in Launcher; // these are also used to calculate the app icon overlay buffer size. @NonNull final Rect mSwipePipToHomeAppBounds = new Rect(); /** /** * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell. * 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 * This is used for a broadcast receiver to resolve intents. This should be removed once Loading Loading @@ -118,11 +91,11 @@ public class PipScheduler { public PipScheduler(Context context, public PipScheduler(Context context, PipBoundsState pipBoundsState, PipBoundsState pipBoundsState, ShellExecutor mainExecutor, ShellExecutor mainExecutor, ShellTaskOrganizer shellTaskOrganizer) { PipTransitionState pipTransitionState) { mContext = context; mContext = context; mPipBoundsState = pipBoundsState; mPipBoundsState = pipBoundsState; mMainExecutor = mainExecutor; mMainExecutor = mainExecutor; mShellTaskOrganizer = shellTaskOrganizer; mPipTransitionState = pipTransitionState; if (PipUtils.isPip2ExperimentEnabled()) { if (PipUtils.isPip2ExperimentEnabled()) { // temporary broadcast receiver to initiate exit PiP via expand // temporary broadcast receiver to initiate exit PiP via expand Loading @@ -140,25 +113,17 @@ public class PipScheduler { mPipTransitionController = pipTransitionController; mPipTransitionController = pipTransitionController; } } void setPinnedTaskLeash(SurfaceControl pinnedTaskLeash) { mPinnedTaskLeash = pinnedTaskLeash; } void setPipTaskToken(@Nullable WindowContainerToken pipTaskToken) { mPipTaskToken = pipTaskToken; } @Nullable @Nullable private WindowContainerTransaction getExitPipViaExpandTransaction() { private WindowContainerTransaction getExitPipViaExpandTransaction() { if (mPipTaskToken == null) { if (mPipTransitionState.mPipTaskToken == null) { return null; return null; } } WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction(); // final expanded bounds to be inherited from the parent // final expanded bounds to be inherited from the parent wct.setBounds(mPipTaskToken, null); wct.setBounds(mPipTransitionState.mPipTaskToken, null); // if we are hitting a multi-activity case // if we are hitting a multi-activity case // windowing mode change will reparent to original host task // windowing mode change will reparent to original host task wct.setWindowingMode(mPipTaskToken, WINDOWING_MODE_UNDEFINED); wct.setWindowingMode(mPipTransitionState.mPipTaskToken, WINDOWING_MODE_UNDEFINED); return wct; return wct; } } Loading @@ -183,43 +148,12 @@ public class PipScheduler { /** /** * Animates resizing of the pinned stack given the duration. * Animates resizing of the pinned stack given the duration. */ */ public void scheduleAnimateResizePip(Rect toBounds, Consumer<Rect> onFinishResizeCallback) { public void scheduleAnimateResizePip(Rect toBounds) { if (mPipTaskToken == null) { if (mPipTransitionState.mPipTaskToken == null || !mPipTransitionState.isInPip()) { return; return; } } WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setBounds(mPipTaskToken, toBounds); wct.setBounds(mPipTransitionState.mPipTaskToken, toBounds); mPipTransitionController.startResizeTransition(wct, onFinishResizeCallback); mPipTransitionController.startResizeTransition(wct); } void onSwipePipToHomeAnimationStart(int taskId, ComponentName componentName, Rect destinationBounds, SurfaceControl overlay, Rect appBounds) { mInSwipePipToHomeTransition = true; mSwipePipToHomeOverlay = overlay; mSwipePipToHomeAppBounds.set(appBounds); if (overlay != null) { // Shell transitions might use a root animation leash, which will be removed when // the Recents transition is finished. Launcher attaches the overlay leash to this // animation target leash; thus, we need to reparent it to the actual Task surface now. // PipTransition is responsible to fade it out and cleanup when finishing the enter PIP // transition. SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); mShellTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, tx); tx.setLayer(overlay, Integer.MAX_VALUE); tx.apply(); } } void setInSwipePipToHomeTransition(boolean inSwipePipToHome) { mInSwipePipToHomeTransition = inSwipePipToHome; } boolean isInSwipePipToHomeTransition() { return mInSwipePipToHomeTransition; } void onExitPip() { mPipTaskToken = null; mPinnedTaskLeash = null; } } } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +120 −51 File changed.Preview size limit exceeded, changes collapsed. Show changes