Merge "Ignores entering PiP animation on seamless rotation" into rvc-dev
This commit is contained in:
@@ -46,4 +46,13 @@ oneway interface IDisplayWindowListener {
|
|||||||
*/
|
*/
|
||||||
void onDisplayRemoved(int displayId);
|
void onDisplayRemoved(int displayId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when fixed rotation is started on a display.
|
||||||
|
*/
|
||||||
|
void onFixedRotationStarted(int displayId, int newRotation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the previous fixed rotation on a display is finished.
|
||||||
|
*/
|
||||||
|
void onFixedRotationFinished(int displayId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import com.android.internal.os.SomeArgs;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.pip.phone.PipUpdateThread;
|
import com.android.systemui.pip.phone.PipUpdateThread;
|
||||||
import com.android.systemui.stackdivider.Divider;
|
import com.android.systemui.stackdivider.Divider;
|
||||||
|
import com.android.systemui.wm.DisplayController;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -82,8 +83,10 @@ import javax.inject.Singleton;
|
|||||||
* see also {@link com.android.systemui.pip.phone.PipMotionHelper}.
|
* see also {@link com.android.systemui.pip.phone.PipMotionHelper}.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class PipTaskOrganizer extends TaskOrganizer {
|
public class PipTaskOrganizer extends TaskOrganizer implements
|
||||||
|
DisplayController.OnDisplaysChangedListener {
|
||||||
private static final String TAG = PipTaskOrganizer.class.getSimpleName();
|
private static final String TAG = PipTaskOrganizer.class.getSimpleName();
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
private static final int MSG_RESIZE_IMMEDIATE = 1;
|
private static final int MSG_RESIZE_IMMEDIATE = 1;
|
||||||
private static final int MSG_RESIZE_ANIMATE = 2;
|
private static final int MSG_RESIZE_ANIMATE = 2;
|
||||||
@@ -206,10 +209,17 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
mSurfaceControlTransactionFactory;
|
mSurfaceControlTransactionFactory;
|
||||||
private PictureInPictureParams mPictureInPictureParams;
|
private PictureInPictureParams mPictureInPictureParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to {@code true}, the entering animation will be skipped and we will wait for
|
||||||
|
* {@link #onFixedRotationFinished(int)} callback to actually enter PiP.
|
||||||
|
*/
|
||||||
|
private boolean mShouldDeferEnteringPip;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
|
public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
|
||||||
@NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
|
@NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
|
||||||
@Nullable Divider divider) {
|
@Nullable Divider divider,
|
||||||
|
@NonNull DisplayController displayController) {
|
||||||
mMainHandler = new Handler(Looper.getMainLooper());
|
mMainHandler = new Handler(Looper.getMainLooper());
|
||||||
mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
|
mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
|
||||||
mPipBoundsHandler = boundsHandler;
|
mPipBoundsHandler = boundsHandler;
|
||||||
@@ -219,6 +229,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper);
|
mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper);
|
||||||
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
|
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
|
||||||
mSplitDivider = divider;
|
mSplitDivider = divider;
|
||||||
|
displayController.addDisplayWindowListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Handler getUpdateHandler() {
|
public Handler getUpdateHandler() {
|
||||||
@@ -281,7 +292,8 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
final int direction = syncWithSplitScreenBounds(destinationBounds)
|
final int direction = syncWithSplitScreenBounds(destinationBounds)
|
||||||
? TRANSITION_DIRECTION_TO_SPLIT_SCREEN
|
? TRANSITION_DIRECTION_TO_SPLIT_SCREEN
|
||||||
: TRANSITION_DIRECTION_TO_FULLSCREEN;
|
: TRANSITION_DIRECTION_TO_FULLSCREEN;
|
||||||
final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
|
final SurfaceControl.Transaction tx =
|
||||||
|
mSurfaceControlTransactionFactory.getTransaction();
|
||||||
mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds,
|
mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds,
|
||||||
mLastReportedBounds);
|
mLastReportedBounds);
|
||||||
tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
|
tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
|
||||||
@@ -325,29 +337,47 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
@Override
|
@Override
|
||||||
public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
|
public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
|
||||||
Objects.requireNonNull(info, "Requires RunningTaskInfo");
|
Objects.requireNonNull(info, "Requires RunningTaskInfo");
|
||||||
mPictureInPictureParams = info.pictureInPictureParams;
|
|
||||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
|
||||||
info.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
|
|
||||||
null /* bounds */, getMinimalSize(info.topActivityInfo));
|
|
||||||
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
|
|
||||||
mTaskInfo = info;
|
mTaskInfo = info;
|
||||||
mToken = mTaskInfo.token;
|
mToken = mTaskInfo.token;
|
||||||
mInPip = true;
|
mInPip = true;
|
||||||
mLeash = leash;
|
mLeash = leash;
|
||||||
|
|
||||||
// TODO: Skip enter animation when entering pip from another orientation
|
|
||||||
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
|
|
||||||
mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
|
mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
|
||||||
|
mPictureInPictureParams = mTaskInfo.pictureInPictureParams;
|
||||||
|
|
||||||
|
if (mShouldDeferEnteringPip) {
|
||||||
|
if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing");
|
||||||
|
// if deferred, hide the surface till fixed rotation is completed
|
||||||
|
final SurfaceControl.Transaction tx =
|
||||||
|
mSurfaceControlTransactionFactory.getTransaction();
|
||||||
|
tx.setAlpha(mLeash, 0f);
|
||||||
|
tx.apply();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||||
|
mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
|
||||||
|
null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
|
||||||
|
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
|
||||||
|
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
|
||||||
|
|
||||||
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
|
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
|
||||||
scheduleAnimateResizePip(currentBounds, destinationBounds,
|
scheduleAnimateResizePip(currentBounds, destinationBounds,
|
||||||
TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration,
|
TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration,
|
||||||
null /* updateBoundsCallback */);
|
null /* updateBoundsCallback */);
|
||||||
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
|
||||||
|
enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration);
|
||||||
|
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enterPipWithAlphaAnimation(Rect destinationBounds, long durationMs) {
|
||||||
// If we are fading the PIP in, then we should move the pip to the final location as
|
// If we are fading the PIP in, then we should move the pip to the final location as
|
||||||
// soon as possible, but set the alpha immediately since the transaction can take a
|
// soon as possible, but set the alpha immediately since the transaction can take a
|
||||||
// while to process
|
// while to process
|
||||||
final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
|
final SurfaceControl.Transaction tx =
|
||||||
|
mSurfaceControlTransactionFactory.getTransaction();
|
||||||
tx.setAlpha(mLeash, 0f);
|
tx.setAlpha(mLeash, 0f);
|
||||||
tx.apply();
|
tx.apply();
|
||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
@@ -362,14 +392,10 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
.getAnimator(mLeash, destinationBounds, 0f, 1f)
|
.getAnimator(mLeash, destinationBounds, 0f, 1f)
|
||||||
.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
|
.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
|
||||||
.setPipAnimationCallback(mPipAnimationCallback)
|
.setPipAnimationCallback(mPipAnimationCallback)
|
||||||
.setDuration(mEnterExitAnimationDuration)
|
.setDuration(durationMs)
|
||||||
.start());
|
.start());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -391,6 +417,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
Log.wtf(TAG, "Unrecognized token: " + token);
|
Log.wtf(TAG, "Unrecognized token: " + token);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mShouldDeferEnteringPip = false;
|
||||||
mPictureInPictureParams = null;
|
mPictureInPictureParams = null;
|
||||||
mInPip = false;
|
mInPip = false;
|
||||||
}
|
}
|
||||||
@@ -416,6 +443,23 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFixedRotationStarted(int displayId, int newRotation) {
|
||||||
|
mShouldDeferEnteringPip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFixedRotationFinished(int displayId) {
|
||||||
|
if (mShouldDeferEnteringPip && mInPip) {
|
||||||
|
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||||
|
mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
|
||||||
|
null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
|
||||||
|
// schedule a regular animation to ensure all the callbacks are still being sent
|
||||||
|
enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */);
|
||||||
|
}
|
||||||
|
mShouldDeferEnteringPip = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO(b/152809058): consolidate the display info handling logic in SysUI
|
* TODO(b/152809058): consolidate the display info handling logic in SysUI
|
||||||
*
|
*
|
||||||
@@ -476,6 +520,10 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
*/
|
*/
|
||||||
public void scheduleAnimateResizePip(Rect toBounds, int duration,
|
public void scheduleAnimateResizePip(Rect toBounds, int duration,
|
||||||
Consumer<Rect> updateBoundsCallback) {
|
Consumer<Rect> updateBoundsCallback) {
|
||||||
|
if (mShouldDeferEnteringPip) {
|
||||||
|
Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
|
||||||
|
return;
|
||||||
|
}
|
||||||
scheduleAnimateResizePip(mLastReportedBounds, toBounds,
|
scheduleAnimateResizePip(mLastReportedBounds, toBounds,
|
||||||
TRANSITION_DIRECTION_NONE, duration, updateBoundsCallback);
|
TRANSITION_DIRECTION_NONE, duration, updateBoundsCallback);
|
||||||
}
|
}
|
||||||
@@ -567,6 +615,10 @@ public class PipTaskOrganizer extends TaskOrganizer {
|
|||||||
// can be initiated in other component, ignore if we are no longer in PIP
|
// can be initiated in other component, ignore if we are no longer in PIP
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mShouldDeferEnteringPip) {
|
||||||
|
Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred");
|
||||||
|
return;
|
||||||
|
}
|
||||||
SomeArgs args = SomeArgs.obtain();
|
SomeArgs args = SomeArgs.obtain();
|
||||||
args.arg1 = updateBoundsCallback;
|
args.arg1 = updateBoundsCallback;
|
||||||
args.arg2 = originalBounds;
|
args.arg2 = originalBounds;
|
||||||
|
|||||||
@@ -134,6 +134,39 @@ public class DisplayController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFixedRotationStarted(int displayId, int newRotation) {
|
||||||
|
mHandler.post(() -> {
|
||||||
|
synchronized (mDisplays) {
|
||||||
|
if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
|
||||||
|
Slog.w(TAG, "Skipping onFixedRotationStarted on unknown"
|
||||||
|
+ " display, displayId=" + displayId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
|
||||||
|
mDisplayChangedListeners.get(i).onFixedRotationStarted(
|
||||||
|
displayId, newRotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFixedRotationFinished(int displayId) {
|
||||||
|
mHandler.post(() -> {
|
||||||
|
synchronized (mDisplays) {
|
||||||
|
if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
|
||||||
|
Slog.w(TAG, "Skipping onFixedRotationFinished on unknown"
|
||||||
|
+ " display, displayId=" + displayId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
|
||||||
|
mDisplayChangedListeners.get(i).onFixedRotationFinished(displayId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -232,5 +265,15 @@ public class DisplayController {
|
|||||||
* Called when a display is removed.
|
* Called when a display is removed.
|
||||||
*/
|
*/
|
||||||
default void onDisplayRemoved(int displayId) {}
|
default void onDisplayRemoved(int displayId) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when fixed rotation on a display is started.
|
||||||
|
*/
|
||||||
|
default void onFixedRotationStarted(int displayId, int newRotation) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when fixed rotation on a display is finished.
|
||||||
|
*/
|
||||||
|
default void onFixedRotationFinished(int displayId) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -493,10 +493,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
* The launching activity which is using fixed rotation transformation.
|
* The launching activity which is using fixed rotation transformation.
|
||||||
*
|
*
|
||||||
* @see #handleTopActivityLaunchingInDifferentOrientation
|
* @see #handleTopActivityLaunchingInDifferentOrientation
|
||||||
* @see #setFixedRotationLaunchingApp
|
* @see #setFixedRotationLaunchingApp(ActivityRecord, int)
|
||||||
* @see DisplayRotation#shouldRotateSeamlessly
|
* @see DisplayRotation#shouldRotateSeamlessly
|
||||||
*/
|
*/
|
||||||
ActivityRecord mFixedRotationLaunchingApp;
|
private ActivityRecord mFixedRotationLaunchingApp;
|
||||||
|
|
||||||
final FixedRotationTransitionListener mFixedRotationTransitionListener =
|
final FixedRotationTransitionListener mFixedRotationTransitionListener =
|
||||||
new FixedRotationTransitionListener();
|
new FixedRotationTransitionListener();
|
||||||
@@ -1475,6 +1475,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable ActivityRecord getFixedRotationLaunchingApp() {
|
||||||
|
return mFixedRotationLaunchingApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r) {
|
||||||
|
setFixedRotationLaunchingAppUnchecked(r, ROTATION_UNDEFINED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r, int rotation) {
|
||||||
|
if (mFixedRotationLaunchingApp == null && r != null) {
|
||||||
|
mWmService.mDisplayNotificationController.dispatchFixedRotationStarted(this, rotation);
|
||||||
|
} else if (mFixedRotationLaunchingApp != null && r == null) {
|
||||||
|
mWmService.mDisplayNotificationController.dispatchFixedRotationFinished(this);
|
||||||
|
}
|
||||||
|
mFixedRotationLaunchingApp = r;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the provided record to {@link mFixedRotationLaunchingApp} if possible to apply fixed
|
* Sets the provided record to {@link mFixedRotationLaunchingApp} if possible to apply fixed
|
||||||
* rotation transform to it and indicate that the display may be rotated after it is launched.
|
* rotation transform to it and indicate that the display may be rotated after it is launched.
|
||||||
@@ -1496,7 +1513,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
if (!r.hasFixedRotationTransform()) {
|
if (!r.hasFixedRotationTransform()) {
|
||||||
startFixedRotationTransform(r, rotation);
|
startFixedRotationTransform(r, rotation);
|
||||||
}
|
}
|
||||||
mFixedRotationLaunchingApp = r;
|
setFixedRotationLaunchingAppUnchecked(r, rotation);
|
||||||
if (prevRotatedLaunchingApp != null) {
|
if (prevRotatedLaunchingApp != null) {
|
||||||
prevRotatedLaunchingApp.finishFixedRotationTransform();
|
prevRotatedLaunchingApp.finishFixedRotationTransform();
|
||||||
}
|
}
|
||||||
@@ -1524,7 +1541,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the {@link mFixedRotationLaunchingApp} without applying rotation to display. It is
|
* Clears the {@link #mFixedRotationLaunchingApp} without applying rotation to display. It is
|
||||||
* used when the display won't rotate (e.g. the orientation from sensor has updated again before
|
* used when the display won't rotate (e.g. the orientation from sensor has updated again before
|
||||||
* applying rotation to display) but the launching app has been transformed. So the record need
|
* applying rotation to display) but the launching app has been transformed. So the record need
|
||||||
* to be cleared and restored to stop using seamless rotation and rotated configuration.
|
* to be cleared and restored to stop using seamless rotation and rotated configuration.
|
||||||
@@ -1534,7 +1551,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mFixedRotationLaunchingApp.finishFixedRotationTransform();
|
mFixedRotationLaunchingApp.finishFixedRotationTransform();
|
||||||
mFixedRotationLaunchingApp = null;
|
setFixedRotationLaunchingAppUnchecked(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startFixedRotationTransform(WindowToken token, int rotation) {
|
private void startFixedRotationTransform(WindowToken token, int rotation) {
|
||||||
@@ -5260,7 +5277,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
|
|
||||||
rotatedLaunchingApp.finishFixedRotationTransform(
|
rotatedLaunchingApp.finishFixedRotationTransform(
|
||||||
() -> applyRotation(oldRotation, newRotation));
|
() -> applyRotation(oldRotation, newRotation));
|
||||||
mFixedRotationLaunchingApp = null;
|
setFixedRotationLaunchingAppUnchecked(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks whether the given activity is in size compatibility mode and notifies the change. */
|
/** Checks whether the given activity is in size compatibility mode and notifies the change. */
|
||||||
@@ -5574,7 +5591,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) {
|
if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) {
|
||||||
// Because it won't affect display orientation, just finish the transform.
|
// Because it won't affect display orientation, just finish the transform.
|
||||||
animatingRecents.finishFixedRotationTransform();
|
animatingRecents.finishFixedRotationTransform();
|
||||||
mFixedRotationLaunchingApp = null;
|
setFixedRotationLaunchingAppUnchecked(null);
|
||||||
} else {
|
} else {
|
||||||
// If there is already a launching activity that is not the recents, before its
|
// If there is already a launching activity that is not the recents, before its
|
||||||
// transition is completed, the recents animation may be started. So if the recents
|
// transition is completed, the recents animation may be started. So if the recents
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ public class DisplayRotation {
|
|||||||
boolean shouldRotateSeamlessly(int oldRotation, int newRotation, boolean forceUpdate) {
|
boolean shouldRotateSeamlessly(int oldRotation, int newRotation, boolean forceUpdate) {
|
||||||
// Display doesn't need to be frozen because application has been started in correct
|
// Display doesn't need to be frozen because application has been started in correct
|
||||||
// rotation already, so the rest of the windows can use seamless rotation.
|
// rotation already, so the rest of the windows can use seamless rotation.
|
||||||
if (mDisplayContent.mFixedRotationLaunchingApp != null) {
|
if (mDisplayContent.getFixedRotationLaunchingApp() != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,4 +95,27 @@ class DisplayWindowListenerController {
|
|||||||
}
|
}
|
||||||
mDisplayListeners.finishBroadcast();
|
mDisplayListeners.finishBroadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dispatchFixedRotationStarted(DisplayContent display, int newRotation) {
|
||||||
|
int count = mDisplayListeners.beginBroadcast();
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
try {
|
||||||
|
mDisplayListeners.getBroadcastItem(i).onFixedRotationStarted(
|
||||||
|
display.mDisplayId, newRotation);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDisplayListeners.finishBroadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispatchFixedRotationFinished(DisplayContent display) {
|
||||||
|
int count = mDisplayListeners.beginBroadcast();
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
try {
|
||||||
|
mDisplayListeners.getBroadcastItem(i).onFixedRotationFinished(display.mDisplayId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDisplayListeners.finishBroadcast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1405,14 +1405,14 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
|||||||
mActivity.setVisibility(true);
|
mActivity.setVisibility(true);
|
||||||
|
|
||||||
display.rotateInDifferentOrientationIfNeeded(mActivity);
|
display.rotateInDifferentOrientationIfNeeded(mActivity);
|
||||||
display.mFixedRotationLaunchingApp = mActivity;
|
display.setFixedRotationLaunchingAppUnchecked(mActivity);
|
||||||
displayRotation.updateRotationUnchecked(true /* forceUpdate */);
|
displayRotation.updateRotationUnchecked(true /* forceUpdate */);
|
||||||
|
|
||||||
assertTrue(displayRotation.isRotatingSeamlessly());
|
assertTrue(displayRotation.isRotatingSeamlessly());
|
||||||
|
|
||||||
// The launching rotated app should not be cleared when waiting for remote rotation.
|
// The launching rotated app should not be cleared when waiting for remote rotation.
|
||||||
display.continueUpdateOrientationForDiffOrienLaunchingApp();
|
display.continueUpdateOrientationForDiffOrienLaunchingApp();
|
||||||
assertNotNull(display.mFixedRotationLaunchingApp);
|
assertNotNull(display.getFixedRotationLaunchingApp());
|
||||||
|
|
||||||
// Simulate the rotation has been updated to previous one, e.g. sensor updates before the
|
// Simulate the rotation has been updated to previous one, e.g. sensor updates before the
|
||||||
// remote rotation is completed.
|
// remote rotation is completed.
|
||||||
@@ -1438,10 +1438,10 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
|||||||
displayRotation.updateRotationUnchecked(true /* forceUpdate */);
|
displayRotation.updateRotationUnchecked(true /* forceUpdate */);
|
||||||
doReturn(false).when(displayRotation).isWaitingForRemoteRotation();
|
doReturn(false).when(displayRotation).isWaitingForRemoteRotation();
|
||||||
clearInvocations(mActivity);
|
clearInvocations(mActivity);
|
||||||
display.mFixedRotationLaunchingApp = mActivity;
|
display.setFixedRotationLaunchingAppUnchecked(mActivity);
|
||||||
display.sendNewConfiguration();
|
display.sendNewConfiguration();
|
||||||
|
|
||||||
assertNull(display.mFixedRotationLaunchingApp);
|
assertNull(display.getFixedRotationLaunchingApp());
|
||||||
assertFalse(mActivity.hasFixedRotationTransform());
|
assertFalse(mActivity.hasFixedRotationTransform());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1497,7 +1497,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
|||||||
// rotation should be applied when creating snapshot surface if the display rotation may be
|
// rotation should be applied when creating snapshot surface if the display rotation may be
|
||||||
// changed according to the activity orientation.
|
// changed according to the activity orientation.
|
||||||
assertTrue(mActivity.hasFixedRotationTransform());
|
assertTrue(mActivity.hasFixedRotationTransform());
|
||||||
assertEquals(mActivity, mActivity.mDisplayContent.mFixedRotationLaunchingApp);
|
assertEquals(mActivity, mActivity.mDisplayContent.getFixedRotationLaunchingApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -140,6 +140,12 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
|
|||||||
public void onDisplayRemoved(int displayId) {
|
public void onDisplayRemoved(int displayId) {
|
||||||
removed.add(displayId);
|
removed.add(displayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFixedRotationStarted(int displayId, int newRotation) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFixedRotationFinished(int displayId) {}
|
||||||
};
|
};
|
||||||
mService.mWindowManager.registerDisplayWindowListener(listener);
|
mService.mWindowManager.registerDisplayWindowListener(listener);
|
||||||
// Check that existing displays call added
|
// Check that existing displays call added
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
|||||||
|
|
||||||
initializeRecentsAnimationController(mController, homeActivity);
|
initializeRecentsAnimationController(mController, homeActivity);
|
||||||
|
|
||||||
assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp);
|
assertEquals(homeActivity, mDefaultDisplay.getFixedRotationLaunchingApp());
|
||||||
|
|
||||||
// Check that the home app is in portrait
|
// Check that the home app is in portrait
|
||||||
assertEquals(Configuration.ORIENTATION_PORTRAIT,
|
assertEquals(Configuration.ORIENTATION_PORTRAIT,
|
||||||
@@ -353,7 +353,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
|||||||
// top rotated record should be cleared.
|
// top rotated record should be cleared.
|
||||||
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||||
assertFalse(homeActivity.hasFixedRotationTransform());
|
assertFalse(homeActivity.hasFixedRotationTransform());
|
||||||
assertNull(mDefaultDisplay.mFixedRotationLaunchingApp);
|
assertNull(mDefaultDisplay.getFixedRotationLaunchingApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -367,7 +367,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
|||||||
(mDefaultDisplay.getRotation() + 1) % 4);
|
(mDefaultDisplay.getRotation() + 1) % 4);
|
||||||
|
|
||||||
assertTrue(activity.hasFixedRotationTransform());
|
assertTrue(activity.hasFixedRotationTransform());
|
||||||
assertEquals(activity, mDefaultDisplay.mFixedRotationLaunchingApp);
|
assertEquals(activity, mDefaultDisplay.getFixedRotationLaunchingApp());
|
||||||
|
|
||||||
// Before the transition is done, the recents animation is triggered.
|
// Before the transition is done, the recents animation is triggered.
|
||||||
initializeRecentsAnimationController(mController, homeActivity);
|
initializeRecentsAnimationController(mController, homeActivity);
|
||||||
@@ -377,7 +377,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
|||||||
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||||
// The rotation transform should be cleared after updating orientation with display.
|
// The rotation transform should be cleared after updating orientation with display.
|
||||||
assertFalse(activity.hasFixedRotationTransform());
|
assertFalse(activity.hasFixedRotationTransform());
|
||||||
assertNull(mDefaultDisplay.mFixedRotationLaunchingApp);
|
assertNull(mDefaultDisplay.getFixedRotationLaunchingApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -436,7 +436,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
|||||||
// The transform state should keep because we expect to listen the signal from the
|
// The transform state should keep because we expect to listen the signal from the
|
||||||
// transition executed by moving the task to front.
|
// transition executed by moving the task to front.
|
||||||
assertTrue(homeActivity.hasFixedRotationTransform());
|
assertTrue(homeActivity.hasFixedRotationTransform());
|
||||||
assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp);
|
assertEquals(homeActivity, mDefaultDisplay.getFixedRotationLaunchingApp());
|
||||||
|
|
||||||
mDefaultDisplay.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(
|
mDefaultDisplay.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(
|
||||||
homeActivity.token);
|
homeActivity.token);
|
||||||
|
|||||||
Reference in New Issue
Block a user