Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +0 −9 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ import android.view.Display; import android.view.Surface; import android.view.SurfaceControl; import android.window.TaskOrganizer; import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; Loading Loading @@ -869,14 +868,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } /** Whether the given {@link TransitionInfo.Change} is for the PIP window. */ boolean isPipChange(TransitionInfo.Change change) { if (mToken == null) { Log.e(TAG, "We no longer keep track of the PIP token"); } return mToken.equals(change.getContainer()); } private void fadeExistingPip(boolean show) { final float alphaStart = show ? 0 : 1; final float alphaEnd = show ? 1 : 0; Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +130 −66 Original line number Diff line number Diff line Loading @@ -83,7 +83,11 @@ public class PipTransition extends PipTransitionController { private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private Transitions.TransitionFinishCallback mFinishCallback; private final Rect mExitDestinationBounds = new Rect(); private IBinder mExitTransition = null; @Nullable private IBinder mExitTransition; /** The Task window that is currently in PIP windowing mode. */ @Nullable private WindowContainerToken mCurrentPipTaskToken; public PipTransition(Context context, PipBoundsState pipBoundsState, Loading Loading @@ -134,6 +138,7 @@ public class PipTransition extends PipTransitionController { @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { // Exiting PIP. final int type = info.getType(); if (transition.equals(mExitTransition)) { mExitDestinationBounds.setEmpty(); Loading @@ -145,7 +150,7 @@ public class PipTransition extends PipTransitionController { throw new RuntimeException("Previous callback not called, aborting exit PIP."); } final TransitionInfo.Change exitPipChange = findPipChange(info); final TransitionInfo.Change exitPipChange = findCurrentPipChange(info); if (exitPipChange == null) { throw new RuntimeException("Cannot find the pip window for exit-pip transition."); } Loading @@ -159,80 +164,28 @@ public class PipTransition extends PipTransitionController { finishCallback, exitPipChange); break; case TRANSIT_REMOVE_PIP: startTransaction.apply(); finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(), mPipBoundsState.getDisplayBounds()); mPipOrganizer.onExitPipFinished(exitPipChange.getTaskInfo()); finishCallback.onTransitionFinished(null, null); removePipImmediately(info, startTransaction, finishTransaction, finishCallback, exitPipChange); break; default: throw new IllegalStateException("mExitTransition with unexpected transit type=" + transitTypeToString(type)); } mCurrentPipTaskToken = null; return true; } // We only support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps // that enter PiP instantly on opening, mostly from CTS/Flicker tests) if (type != TRANSIT_PIP && type != TRANSIT_OPEN) { // In case the PIP window is part of rotation transition, reset the bounds and rounded // corner. for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getMode() == TRANSIT_CHANGE && change.getTaskInfo() != null && change.getTaskInfo().configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED) { final SurfaceControl leash = change.getLeash(); final Rect destBounds = mPipBoundsState.getBounds(); final boolean isInPip = mPipTransitionState.isInPip(); mSurfaceTransactionHelper .crop(startTransaction, leash, destBounds) .round(startTransaction, leash, isInPip); mSurfaceTransactionHelper .crop(finishTransaction, leash, destBounds) .round(finishTransaction, leash, isInPip); break; } } return false; // Entering PIP. if (isEnteringPip(info, mCurrentPipTaskToken)) { return startEnterAnimation(info, startTransaction, finishTransaction, finishCallback); } // Search for an Enter PiP transition (along with a show wallpaper one) TransitionInfo.Change enterPip = null; TransitionInfo.Change wallpaper = null; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null && change.getTaskInfo().configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED) { enterPip = change; } else if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) { wallpaper = change; } } if (enterPip == null) { // For transition that we don't animate, we may need to update the PIP surface, otherwise it // will be reset after the transition. updatePipForUnhandledTransition(info, startTransaction, finishTransaction); return false; } if (mFinishCallback != null) { mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */); mFinishCallback = null; throw new RuntimeException("Previous callback not called, aborting entering PIP."); } // Show the wallpaper if there is a wallpaper change. if (wallpaper != null) { startTransaction.show(wallpaper.getLeash()); startTransaction.setAlpha(wallpaper.getLeash(), 1.f); } mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP); mFinishCallback = finishCallback; return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(), startTransaction, finishTransaction, enterPip.getStartRotation(), enterPip.getEndRotation()); } @Nullable @Override public WindowContainerTransaction handleRequest(@NonNull IBinder transition, Loading Loading @@ -272,6 +225,7 @@ public class PipTransition extends PipTransitionController { new Rect(mExitDestinationBounds)); } mExitDestinationBounds.setEmpty(); mCurrentPipTaskToken = null; } @Override Loading Loading @@ -305,10 +259,13 @@ public class PipTransition extends PipTransitionController { } @Nullable private TransitionInfo.Change findPipChange(@NonNull TransitionInfo info) { private TransitionInfo.Change findCurrentPipChange(@NonNull TransitionInfo info) { if (mCurrentPipTaskToken == null) { return null; } for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null && mPipOrganizer.isPipChange(change)) { if (mCurrentPipTaskToken.equals(change.getContainer())) { return change; } } Loading Loading @@ -449,6 +406,87 @@ public class PipTransition extends PipTransitionController { .start(); } /** For {@link Transitions#TRANSIT_REMOVE_PIP}, we just immediately remove the PIP Task. */ private void removePipImmediately(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback, @NonNull TransitionInfo.Change pipChange) { startTransaction.apply(); finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(), mPipBoundsState.getDisplayBounds()); mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo()); finishCallback.onTransitionFinished(null, null); } /** Whether we should handle the given {@link TransitionInfo} animation as entering PIP. */ private static boolean isEnteringPip(@NonNull TransitionInfo info, @Nullable WindowContainerToken currentPipTaskToken) { for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED && !change.getContainer().equals(currentPipTaskToken)) { // We support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps // that enter PiP instantly on opening, mostly from CTS/Flicker tests) if (info.getType() == TRANSIT_PIP || info.getType() == TRANSIT_OPEN) { return true; } // This can happen if the request to enter PIP happens when we are collecting for // another transition, such as TRANSIT_CHANGE (display rotation). if (info.getType() == TRANSIT_CHANGE) { return true; } // Please file a bug to handle the unexpected transition type. throw new IllegalStateException("Entering PIP with unexpected transition type=" + transitTypeToString(info.getType())); } } return false; } private boolean startEnterAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { // Search for an Enter PiP transition (along with a show wallpaper one) TransitionInfo.Change enterPip = null; TransitionInfo.Change wallpaper = null; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED) { enterPip = change; } else if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) { wallpaper = change; } } if (enterPip == null) { return false; } // Keep track of the PIP task. mCurrentPipTaskToken = enterPip.getContainer(); if (mFinishCallback != null) { mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */); mFinishCallback = null; throw new RuntimeException("Previous callback not called, aborting entering PIP."); } // Show the wallpaper if there is a wallpaper change. if (wallpaper != null) { startTransaction.show(wallpaper.getLeash()); startTransaction.setAlpha(wallpaper.getLeash(), 1.f); } mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP); mFinishCallback = finishCallback; return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(), startTransaction, finishTransaction, enterPip.getStartRotation(), enterPip.getEndRotation()); } private boolean startEnterAnimation(final TaskInfo taskInfo, final SurfaceControl leash, final SurfaceControl.Transaction startTransaction, final SurfaceControl.Transaction finishTransaction, Loading Loading @@ -559,6 +597,32 @@ public class PipTransition extends PipTransitionController { finishCallback.onTransitionFinished(null, null); } private void updatePipForUnhandledTransition(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction) { if (mCurrentPipTaskToken == null) { return; } for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (!mCurrentPipTaskToken.equals(change.getContainer())) { continue; } // When the PIP window is visible and being a part of the transition, such as display // rotation, we need to update its bounds and rounded corner. final SurfaceControl leash = change.getLeash(); final Rect destBounds = mPipBoundsState.getBounds(); final boolean isInPip = mPipTransitionState.isInPip(); mSurfaceTransactionHelper .crop(startTransaction, leash, destBounds) .round(startTransaction, leash, isInPip); mSurfaceTransactionHelper .crop(finishTransaction, leash, destBounds) .round(finishTransaction, leash, isInPip); break; } } private void finishResizeForMenu(Rect destinationBounds) { mPipMenuController.movePipMenu(null, null, destinationBounds); mPipMenuController.updateMenuBounds(destinationBounds); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +0 −9 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ import android.view.Display; import android.view.Surface; import android.view.SurfaceControl; import android.window.TaskOrganizer; import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; Loading Loading @@ -869,14 +868,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } /** Whether the given {@link TransitionInfo.Change} is for the PIP window. */ boolean isPipChange(TransitionInfo.Change change) { if (mToken == null) { Log.e(TAG, "We no longer keep track of the PIP token"); } return mToken.equals(change.getContainer()); } private void fadeExistingPip(boolean show) { final float alphaStart = show ? 0 : 1; final float alphaEnd = show ? 1 : 0; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +130 −66 Original line number Diff line number Diff line Loading @@ -83,7 +83,11 @@ public class PipTransition extends PipTransitionController { private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private Transitions.TransitionFinishCallback mFinishCallback; private final Rect mExitDestinationBounds = new Rect(); private IBinder mExitTransition = null; @Nullable private IBinder mExitTransition; /** The Task window that is currently in PIP windowing mode. */ @Nullable private WindowContainerToken mCurrentPipTaskToken; public PipTransition(Context context, PipBoundsState pipBoundsState, Loading Loading @@ -134,6 +138,7 @@ public class PipTransition extends PipTransitionController { @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { // Exiting PIP. final int type = info.getType(); if (transition.equals(mExitTransition)) { mExitDestinationBounds.setEmpty(); Loading @@ -145,7 +150,7 @@ public class PipTransition extends PipTransitionController { throw new RuntimeException("Previous callback not called, aborting exit PIP."); } final TransitionInfo.Change exitPipChange = findPipChange(info); final TransitionInfo.Change exitPipChange = findCurrentPipChange(info); if (exitPipChange == null) { throw new RuntimeException("Cannot find the pip window for exit-pip transition."); } Loading @@ -159,80 +164,28 @@ public class PipTransition extends PipTransitionController { finishCallback, exitPipChange); break; case TRANSIT_REMOVE_PIP: startTransaction.apply(); finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(), mPipBoundsState.getDisplayBounds()); mPipOrganizer.onExitPipFinished(exitPipChange.getTaskInfo()); finishCallback.onTransitionFinished(null, null); removePipImmediately(info, startTransaction, finishTransaction, finishCallback, exitPipChange); break; default: throw new IllegalStateException("mExitTransition with unexpected transit type=" + transitTypeToString(type)); } mCurrentPipTaskToken = null; return true; } // We only support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps // that enter PiP instantly on opening, mostly from CTS/Flicker tests) if (type != TRANSIT_PIP && type != TRANSIT_OPEN) { // In case the PIP window is part of rotation transition, reset the bounds and rounded // corner. for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getMode() == TRANSIT_CHANGE && change.getTaskInfo() != null && change.getTaskInfo().configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED) { final SurfaceControl leash = change.getLeash(); final Rect destBounds = mPipBoundsState.getBounds(); final boolean isInPip = mPipTransitionState.isInPip(); mSurfaceTransactionHelper .crop(startTransaction, leash, destBounds) .round(startTransaction, leash, isInPip); mSurfaceTransactionHelper .crop(finishTransaction, leash, destBounds) .round(finishTransaction, leash, isInPip); break; } } return false; // Entering PIP. if (isEnteringPip(info, mCurrentPipTaskToken)) { return startEnterAnimation(info, startTransaction, finishTransaction, finishCallback); } // Search for an Enter PiP transition (along with a show wallpaper one) TransitionInfo.Change enterPip = null; TransitionInfo.Change wallpaper = null; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null && change.getTaskInfo().configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED) { enterPip = change; } else if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) { wallpaper = change; } } if (enterPip == null) { // For transition that we don't animate, we may need to update the PIP surface, otherwise it // will be reset after the transition. updatePipForUnhandledTransition(info, startTransaction, finishTransaction); return false; } if (mFinishCallback != null) { mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */); mFinishCallback = null; throw new RuntimeException("Previous callback not called, aborting entering PIP."); } // Show the wallpaper if there is a wallpaper change. if (wallpaper != null) { startTransaction.show(wallpaper.getLeash()); startTransaction.setAlpha(wallpaper.getLeash(), 1.f); } mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP); mFinishCallback = finishCallback; return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(), startTransaction, finishTransaction, enterPip.getStartRotation(), enterPip.getEndRotation()); } @Nullable @Override public WindowContainerTransaction handleRequest(@NonNull IBinder transition, Loading Loading @@ -272,6 +225,7 @@ public class PipTransition extends PipTransitionController { new Rect(mExitDestinationBounds)); } mExitDestinationBounds.setEmpty(); mCurrentPipTaskToken = null; } @Override Loading Loading @@ -305,10 +259,13 @@ public class PipTransition extends PipTransitionController { } @Nullable private TransitionInfo.Change findPipChange(@NonNull TransitionInfo info) { private TransitionInfo.Change findCurrentPipChange(@NonNull TransitionInfo info) { if (mCurrentPipTaskToken == null) { return null; } for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null && mPipOrganizer.isPipChange(change)) { if (mCurrentPipTaskToken.equals(change.getContainer())) { return change; } } Loading Loading @@ -449,6 +406,87 @@ public class PipTransition extends PipTransitionController { .start(); } /** For {@link Transitions#TRANSIT_REMOVE_PIP}, we just immediately remove the PIP Task. */ private void removePipImmediately(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback, @NonNull TransitionInfo.Change pipChange) { startTransaction.apply(); finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(), mPipBoundsState.getDisplayBounds()); mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo()); finishCallback.onTransitionFinished(null, null); } /** Whether we should handle the given {@link TransitionInfo} animation as entering PIP. */ private static boolean isEnteringPip(@NonNull TransitionInfo info, @Nullable WindowContainerToken currentPipTaskToken) { for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED && !change.getContainer().equals(currentPipTaskToken)) { // We support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps // that enter PiP instantly on opening, mostly from CTS/Flicker tests) if (info.getType() == TRANSIT_PIP || info.getType() == TRANSIT_OPEN) { return true; } // This can happen if the request to enter PIP happens when we are collecting for // another transition, such as TRANSIT_CHANGE (display rotation). if (info.getType() == TRANSIT_CHANGE) { return true; } // Please file a bug to handle the unexpected transition type. throw new IllegalStateException("Entering PIP with unexpected transition type=" + transitTypeToString(info.getType())); } } return false; } private boolean startEnterAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { // Search for an Enter PiP transition (along with a show wallpaper one) TransitionInfo.Change enterPip = null; TransitionInfo.Change wallpaper = null; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED) { enterPip = change; } else if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) { wallpaper = change; } } if (enterPip == null) { return false; } // Keep track of the PIP task. mCurrentPipTaskToken = enterPip.getContainer(); if (mFinishCallback != null) { mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */); mFinishCallback = null; throw new RuntimeException("Previous callback not called, aborting entering PIP."); } // Show the wallpaper if there is a wallpaper change. if (wallpaper != null) { startTransaction.show(wallpaper.getLeash()); startTransaction.setAlpha(wallpaper.getLeash(), 1.f); } mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP); mFinishCallback = finishCallback; return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(), startTransaction, finishTransaction, enterPip.getStartRotation(), enterPip.getEndRotation()); } private boolean startEnterAnimation(final TaskInfo taskInfo, final SurfaceControl leash, final SurfaceControl.Transaction startTransaction, final SurfaceControl.Transaction finishTransaction, Loading Loading @@ -559,6 +597,32 @@ public class PipTransition extends PipTransitionController { finishCallback.onTransitionFinished(null, null); } private void updatePipForUnhandledTransition(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction) { if (mCurrentPipTaskToken == null) { return; } for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (!mCurrentPipTaskToken.equals(change.getContainer())) { continue; } // When the PIP window is visible and being a part of the transition, such as display // rotation, we need to update its bounds and rounded corner. final SurfaceControl leash = change.getLeash(); final Rect destBounds = mPipBoundsState.getBounds(); final boolean isInPip = mPipTransitionState.isInPip(); mSurfaceTransactionHelper .crop(startTransaction, leash, destBounds) .round(startTransaction, leash, isInPip); mSurfaceTransactionHelper .crop(finishTransaction, leash, destBounds) .round(finishTransaction, leash, isInPip); break; } } private void finishResizeForMenu(Rect destinationBounds) { mPipMenuController.movePipMenu(null, null, destinationBounds); mPipMenuController.updateMenuBounds(destinationBounds); Loading