Use IS_U_ANIMATION_ENABLED to enable animators for U

Use `IS_U_ANIMATION_ENABLED` to control the new animatiors for U
except `TYPE_RETURN_TO_HOME` that already enabled in previous version.

Bug: 131727607
Test: atest BackAnimationControllerTest
Change-Id: I612d4e8ce312be6dee36776b63cee33e72875908
This commit is contained in:
Arthur Hung
2022-11-14 07:54:39 +00:00
parent 184933690e
commit 104cb59497
2 changed files with 125 additions and 55 deletions

View File

@@ -116,7 +116,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
private final TouchTracker mTouchTracker = new TouchTracker();
private final SparseArray<BackAnimationRunner> mAnimationDefinition = new SparseArray<>();
@Nullable
private IOnBackInvokedCallback mActiveCallback;
@VisibleForTesting
@@ -180,6 +180,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
private void initBackAnimationRunners() {
if (!IS_U_ANIMATION_ENABLED) {
return;
}
final CrossTaskBackAnimation crossTaskAnimation = new CrossTaskBackAnimation(mContext);
mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_TASK,
new BackAnimationRunner(crossTaskAnimation.mCallback, crossTaskAnimation.mRunner));
@@ -207,7 +211,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
private void updateEnableAnimationFromSetting() {
int settingValue = Global.getInt(mContext.getContentResolver(),
Global.ENABLE_BACK_ANIMATION, SETTING_VALUE_OFF);
boolean isEnabled = settingValue == SETTING_VALUE_ON && IS_U_ANIMATION_ENABLED;
boolean isEnabled = settingValue == SETTING_VALUE_ON;
mEnableAnimations.set(isEnabled);
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Back animation enabled=%s", isEnabled);
}
@@ -350,10 +354,14 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
return;
}
final int backType = backNavigationInfo.getType();
final boolean shouldDispatchToAnimator = shouldDispatchToAnimator(backType);
final boolean shouldDispatchToAnimator = shouldDispatchToAnimator();
if (shouldDispatchToAnimator) {
mActiveCallback = mAnimationDefinition.get(backType).getCallback();
mAnimationDefinition.get(backType).startGesture();
if (mAnimationDefinition.contains(backType)) {
mActiveCallback = mAnimationDefinition.get(backType).getCallback();
mAnimationDefinition.get(backType).startGesture();
} else {
mActiveCallback = null;
}
} else {
mActiveCallback = mBackNavigationInfo.getOnBackInvokedCallback();
dispatchOnBackStarted(mActiveCallback, mTouchTracker.createStartEvent(null));
@@ -361,9 +369,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
private void onMove() {
if (!mBackGestureStarted || mBackNavigationInfo == null || !mEnableAnimations.get()) {
if (!mBackGestureStarted || mBackNavigationInfo == null || !mEnableAnimations.get()
|| mActiveCallback == null) {
return;
}
final BackEvent backEvent = mTouchTracker.createProgressEvent();
dispatchOnBackProgressed(mActiveCallback, backEvent);
}
@@ -387,11 +397,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
}
private boolean shouldDispatchToAnimator(int backType) {
private boolean shouldDispatchToAnimator() {
return mEnableAnimations.get()
&& mBackNavigationInfo != null
&& mBackNavigationInfo.isPrepareRemoteAnimation()
&& mAnimationDefinition.contains(backType);
&& mBackNavigationInfo.isPrepareRemoteAnimation();
}
private void dispatchOnBackStarted(IOnBackInvokedCallback callback,
@@ -461,6 +470,30 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mTouchTracker.setProgressThreshold(progressThreshold);
}
private void invokeOrCancelBack() {
// Make a synchronized call to core before dispatch back event to client side.
// If the close transition happens before the core receives onAnimationFinished, there will
// play a second close animation for that transition.
if (mBackAnimationFinishedCallback != null) {
try {
mBackAnimationFinishedCallback.onAnimationFinished(mTriggerBack);
} catch (RemoteException e) {
Log.e(TAG, "Failed call IBackAnimationFinishedCallback", e);
}
mBackAnimationFinishedCallback = null;
}
if (mBackNavigationInfo != null) {
final IOnBackInvokedCallback callback = mBackNavigationInfo.getOnBackInvokedCallback();
if (mTriggerBack) {
dispatchOnBackInvoked(callback);
} else {
dispatchOnBackCancelled(callback);
}
}
finishBackNavigation();
}
/**
* Called when the gesture is released, then it could start the post commit animation.
*/
@@ -493,15 +526,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
final int backType = mBackNavigationInfo.getType();
// Directly finish back navigation if no animator defined.
if (!shouldDispatchToAnimator(backType)) {
if (mTriggerBack) {
dispatchOnBackInvoked(mActiveCallback);
} else {
dispatchOnBackCancelled(mActiveCallback);
}
// Animation missing. Simply finish back navigation.
finishBackNavigation();
// Simply trigger and finish back navigation when no animator defined.
if (!shouldDispatchToAnimator() || mActiveCallback == null) {
invokeOrCancelBack();
return;
}
@@ -549,16 +576,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: onBackAnimationFinished()");
// Trigger the real back.
if (mBackNavigationInfo != null) {
IOnBackInvokedCallback callback = mBackNavigationInfo.getOnBackInvokedCallback();
if (mTriggerBack) {
dispatchOnBackInvoked(callback);
} else {
dispatchOnBackCancelled(callback);
}
}
finishBackNavigation();
invokeOrCancelBack();
}
/**
@@ -567,25 +585,14 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
@VisibleForTesting
void finishBackNavigation() {
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: finishBackNavigation()");
BackNavigationInfo backNavigationInfo = mBackNavigationInfo;
boolean triggerBack = mTriggerBack;
mBackNavigationInfo = null;
mTriggerBack = false;
mShouldStartOnNextMoveEvent = false;
mTouchTracker.reset();
mActiveCallback = null;
if (backNavigationInfo == null) {
return;
if (mBackNavigationInfo != null) {
mBackNavigationInfo.onBackNavigationFinished(mTriggerBack);
mBackNavigationInfo = null;
}
if (mBackAnimationFinishedCallback != null) {
try {
mBackAnimationFinishedCallback.onAnimationFinished(triggerBack);
} catch (RemoteException e) {
Log.e(TAG, "Failed call IBackAnimationFinishedCallback", e);
}
mBackAnimationFinishedCallback = null;
}
backNavigationInfo.onBackNavigationFinished(triggerBack);
mTriggerBack = false;
}
private void createAdapter() {

View File

@@ -38,6 +38,7 @@ import android.app.WindowConfiguration;
import android.content.pm.ApplicationInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
@@ -56,6 +57,7 @@ import android.window.BackNavigationInfo;
import android.window.IBackAnimationFinishedCallback;
import android.window.IOnBackInvokedCallback;
import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -189,31 +191,23 @@ public class BackAnimationControllerTest extends ShellTestCase {
}
for (int type: testTypes) {
boolean[] backNavigationDone = new boolean[]{false};
boolean[] triggerBack = new boolean[]{false};
final ResultListener result = new ResultListener();
createNavigationInfo(new BackNavigationInfo.Builder()
.setType(type)
.setOnBackInvokedCallback(mAppCallback)
.setPrepareRemoteAnimation(true)
.setOnBackNavigationDone(
new RemoteCallback(result -> {
backNavigationDone[0] = true;
triggerBack[0] = result.getBoolean(KEY_TRIGGER_BACK);
})));
.setOnBackNavigationDone(new RemoteCallback(result)));
triggerBackGesture();
simulateRemoteAnimationStart(type);
simulateRemoteAnimationFinished();
mShellExecutor.flushAll();
assertTrue("Navigation Done callback not called for "
+ BackNavigationInfo.typeToString(type), backNavigationDone[0]);
assertTrue("TriggerBack should have been true", triggerBack[0]);
+ BackNavigationInfo.typeToString(type), result.mBackNavigationDone);
assertTrue("TriggerBack should have been true", result.mTriggerBack);
}
}
@Test
public void backToHome_dispatchesEvents() throws RemoteException {
registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
@@ -351,6 +345,65 @@ public class BackAnimationControllerTest extends ShellTestCase {
verify(mAnimatorCallback, never()).onBackInvoked();
}
@Test
public void animationNotDefined() throws RemoteException {
final int[] testTypes = new int[] {
BackNavigationInfo.TYPE_RETURN_TO_HOME,
BackNavigationInfo.TYPE_CROSS_TASK,
BackNavigationInfo.TYPE_CROSS_ACTIVITY,
BackNavigationInfo.TYPE_DIALOG_CLOSE};
for (int type: testTypes) {
final ResultListener result = new ResultListener();
createNavigationInfo(new BackNavigationInfo.Builder()
.setType(type)
.setOnBackInvokedCallback(mAppCallback)
.setPrepareRemoteAnimation(true)
.setOnBackNavigationDone(new RemoteCallback(result)));
triggerBackGesture();
simulateRemoteAnimationStart(type);
mShellExecutor.flushAll();
assertTrue("Navigation Done callback not called for "
+ BackNavigationInfo.typeToString(type), result.mBackNavigationDone);
assertTrue("TriggerBack should have been true", result.mTriggerBack);
}
verify(mAppCallback, never()).onBackStarted(any());
verify(mAppCallback, never()).onBackProgressed(any());
verify(mAppCallback, times(testTypes.length)).onBackInvoked();
verify(mAnimatorCallback, never()).onBackStarted(any());
verify(mAnimatorCallback, never()).onBackProgressed(any());
verify(mAnimatorCallback, never()).onBackInvoked();
}
@Test
public void callbackShouldDeliverProgress() throws RemoteException {
registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
final int type = BackNavigationInfo.TYPE_CALLBACK;
final ResultListener result = new ResultListener();
createNavigationInfo(new BackNavigationInfo.Builder()
.setType(type)
.setOnBackInvokedCallback(mAppCallback)
.setOnBackNavigationDone(new RemoteCallback(result)));
triggerBackGesture();
mShellExecutor.flushAll();
assertTrue("Navigation Done callback not called for "
+ BackNavigationInfo.typeToString(type), result.mBackNavigationDone);
assertTrue("TriggerBack should have been true", result.mTriggerBack);
verify(mAppCallback, times(1)).onBackStarted(any());
verify(mAppCallback, times(1)).onBackProgressed(any());
verify(mAppCallback, times(1)).onBackInvoked();
verify(mAnimatorCallback, never()).onBackStarted(any());
verify(mAnimatorCallback, never()).onBackProgressed(any());
verify(mAnimatorCallback, never()).onBackInvoked();
}
private void doMotionEvent(int actionDown, int coordinate) {
mController.onMotionEvent(
coordinate, coordinate,
@@ -377,4 +430,14 @@ public class BackAnimationControllerTest extends ShellTestCase {
mController.registerAnimation(type,
new BackAnimationRunner(mAnimatorCallback, mBackAnimationRunner));
}
private static class ResultListener implements RemoteCallback.OnResultListener {
boolean mBackNavigationDone = false;
boolean mTriggerBack = false;
@Override
public void onResult(@Nullable Bundle result) {
mBackNavigationDone = true;
mTriggerBack = result.getBoolean(KEY_TRIGGER_BACK);
}
};
}