Merge "PiP: Implement auto-rotate w/ button nav for Shell Transitions." into sc-v2-dev
This commit is contained in:
@@ -38,6 +38,7 @@ import android.view.SurfaceSession;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
|
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
|
||||||
import com.android.wm.shell.animation.Interpolators;
|
import com.android.wm.shell.animation.Interpolators;
|
||||||
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -617,14 +618,28 @@ public class PipAnimationController {
|
|||||||
setCurrentValue(bounds);
|
setCurrentValue(bounds);
|
||||||
final Rect insets = computeInsets(fraction);
|
final Rect insets = computeInsets(fraction);
|
||||||
final float degree, x, y;
|
final float degree, x, y;
|
||||||
if (rotationDelta == ROTATION_90) {
|
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||||
degree = 90 * fraction;
|
if (rotationDelta == ROTATION_90) {
|
||||||
x = fraction * (end.right - start.left) + start.left;
|
degree = 90 * (1 - fraction);
|
||||||
y = fraction * (end.top - start.top) + start.top;
|
x = fraction * (end.left - start.left)
|
||||||
|
+ start.left + start.right * (1 - fraction);
|
||||||
|
y = fraction * (end.top - start.top) + start.top;
|
||||||
|
} else {
|
||||||
|
degree = -90 * (1 - fraction);
|
||||||
|
x = fraction * (end.left - start.left) + start.left;
|
||||||
|
y = fraction * (end.top - start.top)
|
||||||
|
+ start.top + start.bottom * (1 - fraction);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
degree = -90 * fraction;
|
if (rotationDelta == ROTATION_90) {
|
||||||
x = fraction * (end.left - start.left) + start.left;
|
degree = 90 * fraction;
|
||||||
y = fraction * (end.bottom - start.top) + start.top;
|
x = fraction * (end.right - start.left) + start.left;
|
||||||
|
y = fraction * (end.top - start.top) + start.top;
|
||||||
|
} else {
|
||||||
|
degree = -90 * fraction;
|
||||||
|
x = fraction * (end.left - start.left) + start.left;
|
||||||
|
y = fraction * (end.bottom - start.top) + start.top;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
getSurfaceTransactionHelper()
|
getSurfaceTransactionHelper()
|
||||||
.rotateAndScaleWithCrop(tx, leash, initialContainerRect, bounds,
|
.rotateAndScaleWithCrop(tx, leash, initialContainerRect, bounds,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.graphics.RectF;
|
|||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
|
|
||||||
import com.android.wm.shell.R;
|
import com.android.wm.shell.R;
|
||||||
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition.
|
* Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition.
|
||||||
@@ -137,7 +138,8 @@ public class PipSurfaceTransactionHelper {
|
|||||||
// destination are different.
|
// destination are different.
|
||||||
final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH;
|
final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH;
|
||||||
final Rect crop = mTmpDestinationRect;
|
final Rect crop = mTmpDestinationRect;
|
||||||
crop.set(0, 0, destW, destH);
|
crop.set(0, 0, Transitions.ENABLE_SHELL_TRANSITIONS ? destH
|
||||||
|
: destW, Transitions.ENABLE_SHELL_TRANSITIONS ? destW : destH);
|
||||||
// Inverse scale for crop to fit in screen coordinates.
|
// Inverse scale for crop to fit in screen coordinates.
|
||||||
crop.scale(1 / scale);
|
crop.scale(1 / scale);
|
||||||
crop.offset(insets.left, insets.top);
|
crop.offset(insets.left, insets.top);
|
||||||
|
|||||||
@@ -242,17 +242,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
|
|
||||||
private @Surface.Rotation int mCurrentRotation;
|
private @Surface.Rotation int mCurrentRotation;
|
||||||
|
|
||||||
/**
|
|
||||||
* If set to {@code true}, no entering PiP transition would be kicked off and most likely
|
|
||||||
* it's due to the fact that Launcher is handling the transition directly when swiping
|
|
||||||
* auto PiP-able Activity to home.
|
|
||||||
* See also {@link #startSwipePipToHome(ComponentName, ActivityInfo, PictureInPictureParams)}.
|
|
||||||
*/
|
|
||||||
private boolean mInSwipePipToHomeTransition;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An optional overlay used to mask content changing between an app in/out of PiP, only set if
|
* An optional overlay used to mask content changing between an app in/out of PiP, only set if
|
||||||
* {@link #mInSwipePipToHomeTransition} is true.
|
* {@link PipTransitionState#getInSwipePipToHomeTransition()} is true.
|
||||||
*/
|
*/
|
||||||
private SurfaceControl mSwipePipToHomeOverlay;
|
private SurfaceControl mSwipePipToHomeOverlay;
|
||||||
|
|
||||||
@@ -343,7 +335,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
*/
|
*/
|
||||||
public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
|
public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
|
||||||
PictureInPictureParams pictureInPictureParams) {
|
PictureInPictureParams pictureInPictureParams) {
|
||||||
mInSwipePipToHomeTransition = true;
|
mPipTransitionState.setInSwipePipToHomeTransition(true);
|
||||||
sendOnPipTransitionStarted(TRANSITION_DIRECTION_TO_PIP);
|
sendOnPipTransitionStarted(TRANSITION_DIRECTION_TO_PIP);
|
||||||
setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo);
|
setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo);
|
||||||
return mPipBoundsAlgorithm.getEntryDestinationBounds();
|
return mPipBoundsAlgorithm.getEntryDestinationBounds();
|
||||||
@@ -356,7 +348,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
|
public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
|
||||||
SurfaceControl overlay) {
|
SurfaceControl overlay) {
|
||||||
// do nothing if there is no startSwipePipToHome being called before
|
// do nothing if there is no startSwipePipToHome being called before
|
||||||
if (mInSwipePipToHomeTransition) {
|
if (mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||||
mPipBoundsState.setBounds(destinationBounds);
|
mPipBoundsState.setBounds(destinationBounds);
|
||||||
mSwipePipToHomeOverlay = overlay;
|
mSwipePipToHomeOverlay = overlay;
|
||||||
}
|
}
|
||||||
@@ -517,7 +509,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
mOnDisplayIdChangeCallback.accept(info.displayId);
|
mOnDisplayIdChangeCallback.accept(info.displayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mInSwipePipToHomeTransition) {
|
if (mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||||
if (!mWaitForFixedRotation) {
|
if (!mWaitForFixedRotation) {
|
||||||
onEndOfSwipePipToHomeTransition();
|
onEndOfSwipePipToHomeTransition();
|
||||||
} else {
|
} else {
|
||||||
@@ -626,7 +618,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
|
|
||||||
private void onEndOfSwipePipToHomeTransition() {
|
private void onEndOfSwipePipToHomeTransition() {
|
||||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||||
mInSwipePipToHomeTransition = false;
|
mPipTransitionState.setInSwipePipToHomeTransition(false);
|
||||||
mSwipePipToHomeOverlay = null;
|
mSwipePipToHomeOverlay = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -650,7 +642,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
null /* callback */, false /* withStartDelay */);
|
null /* callback */, false /* withStartDelay */);
|
||||||
}
|
}
|
||||||
}, tx);
|
}, tx);
|
||||||
mInSwipePipToHomeTransition = false;
|
mPipTransitionState.setInSwipePipToHomeTransition(false);
|
||||||
mSwipePipToHomeOverlay = null;
|
mSwipePipToHomeOverlay = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,7 +710,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clearWaitForFixedRotation();
|
clearWaitForFixedRotation();
|
||||||
mInSwipePipToHomeTransition = false;
|
mPipTransitionState.setInSwipePipToHomeTransition(false);
|
||||||
mPictureInPictureParams = null;
|
mPictureInPictureParams = null;
|
||||||
mPipTransitionState.setTransitionState(PipTransitionState.UNDEFINED);
|
mPipTransitionState.setTransitionState(PipTransitionState.UNDEFINED);
|
||||||
// Re-set the PIP bounds to none.
|
// Re-set the PIP bounds to none.
|
||||||
@@ -793,7 +785,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mPipTransitionState.getTransitionState() == PipTransitionState.TASK_APPEARED) {
|
if (mPipTransitionState.getTransitionState() == PipTransitionState.TASK_APPEARED) {
|
||||||
if (mInSwipePipToHomeTransition) {
|
if (mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||||
onEndOfSwipePipToHomeTransition();
|
onEndOfSwipePipToHomeTransition();
|
||||||
} else {
|
} else {
|
||||||
// Schedule a regular animation to ensure all the callbacks are still being sent.
|
// Schedule a regular animation to ensure all the callbacks are still being sent.
|
||||||
@@ -859,10 +851,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
|||||||
// Skip this entirely if that's the case.
|
// Skip this entirely if that's the case.
|
||||||
final boolean waitForFixedRotationOnEnteringPip = mWaitForFixedRotation
|
final boolean waitForFixedRotationOnEnteringPip = mWaitForFixedRotation
|
||||||
&& (mPipTransitionState.getTransitionState() != PipTransitionState.ENTERED_PIP);
|
&& (mPipTransitionState.getTransitionState() != PipTransitionState.ENTERED_PIP);
|
||||||
if ((mInSwipePipToHomeTransition || waitForFixedRotationOnEnteringPip) && fromRotation) {
|
if ((mPipTransitionState.getInSwipePipToHomeTransition()
|
||||||
|
|| waitForFixedRotationOnEnteringPip) && fromRotation) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Skip onMovementBoundsChanged on rotation change"
|
Log.d(TAG, "Skip onMovementBoundsChanged on rotation change"
|
||||||
+ " mInSwipePipToHomeTransition=" + mInSwipePipToHomeTransition
|
+ " InSwipePipToHomeTransition="
|
||||||
|
+ mPipTransitionState.getInSwipePipToHomeTransition()
|
||||||
+ " mWaitForFixedRotation=" + mWaitForFixedRotation
|
+ " mWaitForFixedRotation=" + mWaitForFixedRotation
|
||||||
+ " getTransitionState=" + mPipTransitionState.getTransitionState());
|
+ " getTransitionState=" + mPipTransitionState.getTransitionState());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.wm.shell.pip;
|
|||||||
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||||
|
import static android.util.RotationUtils.deltaRotation;
|
||||||
import static android.view.WindowManager.TRANSIT_PIP;
|
import static android.view.WindowManager.TRANSIT_PIP;
|
||||||
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
|
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
|
||||||
|
|
||||||
@@ -151,7 +152,8 @@ public class PipTransition extends PipTransitionController {
|
|||||||
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
|
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
|
||||||
mFinishCallback = finishCallback;
|
mFinishCallback = finishCallback;
|
||||||
return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
|
return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
|
||||||
startTransaction, finishTransaction);
|
startTransaction, finishTransaction, enterPip.getStartRotation(),
|
||||||
|
enterPip.getEndRotation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -208,7 +210,8 @@ public class PipTransition extends PipTransitionController {
|
|||||||
|
|
||||||
private boolean startEnterAnimation(final TaskInfo taskInfo, final SurfaceControl leash,
|
private boolean startEnterAnimation(final TaskInfo taskInfo, final SurfaceControl leash,
|
||||||
final SurfaceControl.Transaction startTransaction,
|
final SurfaceControl.Transaction startTransaction,
|
||||||
final SurfaceControl.Transaction finishTransaction) {
|
final SurfaceControl.Transaction finishTransaction,
|
||||||
|
final int startRotation, final int endRotation) {
|
||||||
setBoundsStateForEntry(taskInfo.topActivity, taskInfo.pictureInPictureParams,
|
setBoundsStateForEntry(taskInfo.topActivity, taskInfo.pictureInPictureParams,
|
||||||
taskInfo.topActivityInfo);
|
taskInfo.topActivityInfo);
|
||||||
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
|
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
|
||||||
@@ -216,7 +219,8 @@ public class PipTransition extends PipTransitionController {
|
|||||||
PipAnimationController.PipTransitionAnimator animator;
|
PipAnimationController.PipTransitionAnimator animator;
|
||||||
finishTransaction.setPosition(leash, destinationBounds.left, destinationBounds.top);
|
finishTransaction.setPosition(leash, destinationBounds.left, destinationBounds.top);
|
||||||
if (taskInfo.pictureInPictureParams != null
|
if (taskInfo.pictureInPictureParams != null
|
||||||
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled()) {
|
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled()
|
||||||
|
&& mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||||
|
|
||||||
// PiP menu is attached late in the process here to avoid any artifacts on the leash
|
// PiP menu is attached late in the process here to avoid any artifacts on the leash
|
||||||
@@ -234,13 +238,21 @@ public class PipTransition extends PipTransitionController {
|
|||||||
mFinishCallback = null;
|
mFinishCallback = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rotationDelta = deltaRotation(endRotation, startRotation);
|
||||||
|
if (rotationDelta != Surface.ROTATION_0) {
|
||||||
|
Matrix tmpTransform = new Matrix();
|
||||||
|
tmpTransform.postRotate(rotationDelta == Surface.ROTATION_90
|
||||||
|
? Surface.ROTATION_270 : Surface.ROTATION_90);
|
||||||
|
startTransaction.setMatrix(leash, tmpTransform, new float[9]);
|
||||||
|
}
|
||||||
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
|
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
|
||||||
final Rect sourceHintRect =
|
final Rect sourceHintRect =
|
||||||
PipBoundsAlgorithm.getValidSourceHintRect(
|
PipBoundsAlgorithm.getValidSourceHintRect(
|
||||||
taskInfo.pictureInPictureParams, currentBounds);
|
taskInfo.pictureInPictureParams, currentBounds);
|
||||||
animator = mPipAnimationController.getAnimator(taskInfo, leash, currentBounds,
|
animator = mPipAnimationController.getAnimator(taskInfo, leash, currentBounds,
|
||||||
currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
|
currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
|
||||||
0 /* startingAngle */, Surface.ROTATION_0);
|
0 /* startingAngle */, rotationDelta);
|
||||||
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||||
startTransaction.setAlpha(leash, 0f);
|
startTransaction.setAlpha(leash, 0f);
|
||||||
// PiP menu is attached late in the process here to avoid any artifacts on the leash
|
// PiP menu is attached late in the process here to avoid any artifacts on the leash
|
||||||
@@ -258,6 +270,7 @@ public class PipTransition extends PipTransitionController {
|
|||||||
.setPipAnimationCallback(mPipAnimationCallback)
|
.setPipAnimationCallback(mPipAnimationCallback)
|
||||||
.setDuration(mEnterExitAnimationDuration)
|
.setDuration(mEnterExitAnimationDuration)
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
package com.android.wm.shell.pip;
|
package com.android.wm.shell.pip;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
|
import android.app.PictureInPictureParams;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -34,6 +37,15 @@ public class PipTransitionState {
|
|||||||
public static final int ENTERED_PIP = 4;
|
public static final int ENTERED_PIP = 4;
|
||||||
public static final int EXITING_PIP = 5;
|
public static final int EXITING_PIP = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to {@code true}, no entering PiP transition would be kicked off and most likely
|
||||||
|
* it's due to the fact that Launcher is handling the transition directly when swiping
|
||||||
|
* auto PiP-able Activity to home.
|
||||||
|
* See also {@link PipTaskOrganizer#startSwipePipToHome(ComponentName, ActivityInfo,
|
||||||
|
* PictureInPictureParams)}.
|
||||||
|
*/
|
||||||
|
private boolean mInSwipePipToHomeTransition;
|
||||||
|
|
||||||
// Not a complete set of states but serves what we want right now.
|
// Not a complete set of states but serves what we want right now.
|
||||||
@IntDef(prefix = { "TRANSITION_STATE_" }, value = {
|
@IntDef(prefix = { "TRANSITION_STATE_" }, value = {
|
||||||
UNDEFINED,
|
UNDEFINED,
|
||||||
@@ -65,6 +77,13 @@ public class PipTransitionState {
|
|||||||
&& mState != EXITING_PIP;
|
&& mState != EXITING_PIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setInSwipePipToHomeTransition(boolean inSwipePipToHomeTransition) {
|
||||||
|
mInSwipePipToHomeTransition = inSwipePipToHomeTransition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getInSwipePipToHomeTransition() {
|
||||||
|
return mInSwipePipToHomeTransition;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Resize request can be initiated in other component, ignore if we are no longer in PIP,
|
* Resize request can be initiated in other component, ignore if we are no longer in PIP,
|
||||||
* still waiting for animation or we're exiting from it.
|
* still waiting for animation or we're exiting from it.
|
||||||
|
|||||||
@@ -211,7 +211,9 @@ class PinnedTaskController {
|
|||||||
}
|
}
|
||||||
mFreezingTaskConfig = true;
|
mFreezingTaskConfig = true;
|
||||||
mDestRotatedBounds = new Rect(bounds);
|
mDestRotatedBounds = new Rect(bounds);
|
||||||
continueOrientationChange();
|
if (!mService.mAtmService.getTransitionController().isShellTransitionsEnabled()) {
|
||||||
|
continueOrientationChange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4634,7 +4634,8 @@ class Task extends TaskFragment {
|
|||||||
|
|
||||||
// From fullscreen to PiP.
|
// From fullscreen to PiP.
|
||||||
if (topActivity != null && currentMode == WINDOWING_MODE_FULLSCREEN
|
if (topActivity != null && currentMode == WINDOWING_MODE_FULLSCREEN
|
||||||
&& windowingMode == WINDOWING_MODE_PINNED) {
|
&& windowingMode == WINDOWING_MODE_PINNED
|
||||||
|
&& !mAtmService.getTransitionController().isShellTransitionsEnabled()) {
|
||||||
mDisplayContent.mPinnedTaskController
|
mDisplayContent.mPinnedTaskController
|
||||||
.deferOrientationChangeForEnteringPipFromFullScreenIfNeeded();
|
.deferOrientationChangeForEnteringPipFromFullScreenIfNeeded();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user