Add developer option for back animation DO NOT MERGE
Bug: 228936326 Test: BackAnimationControllerTest#animationDisabledFromSettings Change-Id: I857a480e7375cada9171712d737162c7876c087e Merged-In: Ie7a3acc5674080a22ccdcd0fe31a158a30ee9040
This commit is contained in:
@@ -15020,6 +15020,14 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public static final String DEVICE_CONFIG_SYNC_DISABLED = "device_config_sync_disabled";
|
public static final String DEVICE_CONFIG_SYNC_DISABLED = "device_config_sync_disabled";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether back preview animations are played when user does a back gesture or presses
|
||||||
|
* the back button.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final String ENABLE_BACK_ANIMATION = "enable_back_animation";
|
||||||
|
|
||||||
/** @hide */ public static String zenModeToString(int mode) {
|
/** @hide */ public static String zenModeToString(int mode) {
|
||||||
if (mode == ZEN_MODE_IMPORTANT_INTERRUPTIONS) return "ZEN_MODE_IMPORTANT_INTERRUPTIONS";
|
if (mode == ZEN_MODE_IMPORTANT_INTERRUPTIONS) return "ZEN_MODE_IMPORTANT_INTERRUPTIONS";
|
||||||
if (mode == ZEN_MODE_ALARMS) return "ZEN_MODE_ALARMS";
|
if (mode == ZEN_MODE_ALARMS) return "ZEN_MODE_ALARMS";
|
||||||
|
|||||||
@@ -24,12 +24,18 @@ import android.annotation.Nullable;
|
|||||||
import android.app.ActivityTaskManager;
|
import android.app.ActivityTaskManager;
|
||||||
import android.app.IActivityTaskManager;
|
import android.app.IActivityTaskManager;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.database.ContentObserver;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.hardware.HardwareBuffer;
|
import android.hardware.HardwareBuffer;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.provider.Settings.Global;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.RemoteAnimationTarget;
|
import android.view.RemoteAnimationTarget;
|
||||||
@@ -42,22 +48,27 @@ import com.android.internal.annotations.VisibleForTesting;
|
|||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
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.annotations.ShellBackgroundThread;
|
||||||
import com.android.wm.shell.common.annotations.ShellMainThread;
|
import com.android.wm.shell.common.annotations.ShellMainThread;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the window animation run when a user initiates a back gesture.
|
* Controls the window animation run when a user initiates a back gesture.
|
||||||
*/
|
*/
|
||||||
public class BackAnimationController implements RemoteCallable<BackAnimationController> {
|
public class BackAnimationController implements RemoteCallable<BackAnimationController> {
|
||||||
private static final String TAG = "BackAnimationController";
|
private static final String TAG = "BackAnimationController";
|
||||||
|
private static final int SETTING_VALUE_OFF = 0;
|
||||||
|
private static final int SETTING_VALUE_ON = 1;
|
||||||
private static final String PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP =
|
private static final String PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP =
|
||||||
"persist.wm.debug.predictive_back_progress_threshold";
|
"persist.wm.debug.predictive_back_progress_threshold";
|
||||||
public static final boolean IS_ENABLED =
|
public static final boolean IS_ENABLED =
|
||||||
SystemProperties.getInt("persist.wm.debug.predictive_back", 1) != 0;
|
SystemProperties.getInt("persist.wm.debug.predictive_back",
|
||||||
|
SETTING_VALUE_ON) != SETTING_VALUE_OFF;
|
||||||
private static final int PROGRESS_THRESHOLD = SystemProperties
|
private static final int PROGRESS_THRESHOLD = SystemProperties
|
||||||
.getInt(PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP, -1);
|
.getInt(PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP, -1);
|
||||||
@VisibleForTesting
|
|
||||||
boolean mEnableAnimations = SystemProperties.getInt(
|
private final AtomicBoolean mEnableAnimations = new AtomicBoolean(false);
|
||||||
"persist.wm.debug.predictive_back_anim", 0) != 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Location of the initial touch event of the back gesture.
|
* Location of the initial touch event of the back gesture.
|
||||||
@@ -87,21 +98,50 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
private float mProgressThreshold;
|
private float mProgressThreshold;
|
||||||
|
|
||||||
public BackAnimationController(
|
public BackAnimationController(
|
||||||
@ShellMainThread ShellExecutor shellExecutor,
|
@NonNull @ShellMainThread ShellExecutor shellExecutor,
|
||||||
|
@NonNull @ShellBackgroundThread Handler backgroundHandler,
|
||||||
Context context) {
|
Context context) {
|
||||||
this(shellExecutor, new SurfaceControl.Transaction(), ActivityTaskManager.getService(),
|
this(shellExecutor, backgroundHandler, new SurfaceControl.Transaction(),
|
||||||
context);
|
ActivityTaskManager.getService(), context, context.getContentResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
BackAnimationController(@NonNull ShellExecutor shellExecutor,
|
BackAnimationController(@NonNull @ShellMainThread ShellExecutor shellExecutor,
|
||||||
|
@NonNull @ShellBackgroundThread Handler handler,
|
||||||
@NonNull SurfaceControl.Transaction transaction,
|
@NonNull SurfaceControl.Transaction transaction,
|
||||||
@NonNull IActivityTaskManager activityTaskManager,
|
@NonNull IActivityTaskManager activityTaskManager,
|
||||||
Context context) {
|
Context context, ContentResolver contentResolver) {
|
||||||
mShellExecutor = shellExecutor;
|
mShellExecutor = shellExecutor;
|
||||||
mTransaction = transaction;
|
mTransaction = transaction;
|
||||||
mActivityTaskManager = activityTaskManager;
|
mActivityTaskManager = activityTaskManager;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
setupAnimationDeveloperSettingsObserver(contentResolver, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupAnimationDeveloperSettingsObserver(
|
||||||
|
@NonNull ContentResolver contentResolver,
|
||||||
|
@NonNull @ShellBackgroundThread final Handler backgroundHandler) {
|
||||||
|
ContentObserver settingsObserver = new ContentObserver(backgroundHandler) {
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange, Uri uri) {
|
||||||
|
updateEnableAnimationFromSetting();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
contentResolver.registerContentObserver(
|
||||||
|
Global.getUriFor(Global.ENABLE_BACK_ANIMATION),
|
||||||
|
false, settingsObserver, UserHandle.USER_SYSTEM
|
||||||
|
);
|
||||||
|
updateEnableAnimationFromSetting();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ShellBackgroundThread
|
||||||
|
private void updateEnableAnimationFromSetting() {
|
||||||
|
int settingValue = Global.getInt(mContext.getContentResolver(),
|
||||||
|
Global.ENABLE_BACK_ANIMATION, SETTING_VALUE_OFF);
|
||||||
|
boolean isEnabled = settingValue == SETTING_VALUE_ON;
|
||||||
|
mEnableAnimations.set(isEnabled);
|
||||||
|
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Back animation enabled=%s",
|
||||||
|
isEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BackAnimation getBackAnimationImpl() {
|
public BackAnimation getBackAnimationImpl() {
|
||||||
@@ -340,12 +380,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
private boolean shouldDispatchToLauncher(int backType) {
|
private boolean shouldDispatchToLauncher(int backType) {
|
||||||
return backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
|
return backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
|
||||||
&& mBackToLauncherCallback != null
|
&& mBackToLauncherCallback != null
|
||||||
&& mEnableAnimations;
|
&& mEnableAnimations.get();
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void setEnableAnimations(boolean shouldEnable) {
|
|
||||||
mEnableAnimations = shouldEnable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void dispatchOnBackStarted(IOnBackInvokedCallback callback) {
|
private static void dispatchOnBackStarted(IOnBackInvokedCallback callback) {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import com.android.wm.shell.common.SystemWindows;
|
|||||||
import com.android.wm.shell.common.TaskStackListenerImpl;
|
import com.android.wm.shell.common.TaskStackListenerImpl;
|
||||||
import com.android.wm.shell.common.TransactionPool;
|
import com.android.wm.shell.common.TransactionPool;
|
||||||
import com.android.wm.shell.common.annotations.ShellAnimationThread;
|
import com.android.wm.shell.common.annotations.ShellAnimationThread;
|
||||||
|
import com.android.wm.shell.common.annotations.ShellBackgroundThread;
|
||||||
import com.android.wm.shell.common.annotations.ShellMainThread;
|
import com.android.wm.shell.common.annotations.ShellMainThread;
|
||||||
import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
|
import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
|
||||||
import com.android.wm.shell.compatui.CompatUI;
|
import com.android.wm.shell.compatui.CompatUI;
|
||||||
@@ -734,11 +735,12 @@ public abstract class WMShellBaseModule {
|
|||||||
@Provides
|
@Provides
|
||||||
static Optional<BackAnimationController> provideBackAnimationController(
|
static Optional<BackAnimationController> provideBackAnimationController(
|
||||||
Context context,
|
Context context,
|
||||||
@ShellMainThread ShellExecutor shellExecutor
|
@ShellMainThread ShellExecutor shellExecutor,
|
||||||
|
@ShellBackgroundThread Handler backgroundHandler
|
||||||
) {
|
) {
|
||||||
if (BackAnimationController.IS_ENABLED) {
|
if (BackAnimationController.IS_ENABLED) {
|
||||||
return Optional.of(
|
return Optional.of(
|
||||||
new BackAnimationController(shellExecutor, context));
|
new BackAnimationController(shellExecutor, backgroundHandler, context));
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ android_test {
|
|||||||
"truth-prebuilt",
|
"truth-prebuilt",
|
||||||
"testables",
|
"testables",
|
||||||
"platform-test-annotations",
|
"platform-test-annotations",
|
||||||
|
"frameworks-base-testutils",
|
||||||
],
|
],
|
||||||
|
|
||||||
libs: [
|
libs: [
|
||||||
|
|||||||
@@ -26,17 +26,23 @@ import static org.mockito.Mockito.atLeastOnce;
|
|||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.app.IActivityTaskManager;
|
import android.app.IActivityTaskManager;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
import android.content.Context;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.hardware.HardwareBuffer;
|
import android.hardware.HardwareBuffer;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.RemoteCallback;
|
import android.os.RemoteCallback;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
|
import android.testing.TestableContentResolver;
|
||||||
|
import android.testing.TestableContext;
|
||||||
|
import android.testing.TestableLooper;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.RemoteAnimationTarget;
|
import android.view.RemoteAnimationTarget;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
@@ -45,12 +51,14 @@ import android.window.BackNavigationInfo;
|
|||||||
import android.window.IOnBackInvokedCallback;
|
import android.window.IOnBackInvokedCallback;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
|
||||||
|
import com.android.internal.util.test.FakeSettingsProvider;
|
||||||
import com.android.wm.shell.TestShellExecutor;
|
import com.android.wm.shell.TestShellExecutor;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
@@ -60,14 +68,17 @@ import org.mockito.MockitoAnnotations;
|
|||||||
/**
|
/**
|
||||||
* atest WMShellUnitTests:BackAnimationControllerTest
|
* atest WMShellUnitTests:BackAnimationControllerTest
|
||||||
*/
|
*/
|
||||||
|
@TestableLooper.RunWithLooper
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
public class BackAnimationControllerTest {
|
public class BackAnimationControllerTest {
|
||||||
|
|
||||||
private final ShellExecutor mShellExecutor = new TestShellExecutor();
|
private static final String ANIMATION_ENABLED = "1";
|
||||||
|
private final TestShellExecutor mShellExecutor = new TestShellExecutor();
|
||||||
|
|
||||||
@Mock
|
@Rule
|
||||||
private Context mContext;
|
public TestableContext mContext =
|
||||||
|
new TestableContext(InstrumentationRegistry.getInstrumentation().getContext());
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private SurfaceControl.Transaction mTransaction;
|
private SurfaceControl.Transaction mTransaction;
|
||||||
@@ -80,18 +91,32 @@ public class BackAnimationControllerTest {
|
|||||||
|
|
||||||
private BackAnimationController mController;
|
private BackAnimationController mController;
|
||||||
|
|
||||||
|
private int mEventTime = 0;
|
||||||
|
private TestableContentResolver mContentResolver;
|
||||||
|
private TestableLooper mTestableLooper;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mContext.getApplicationInfo().privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
|
||||||
|
mContentResolver = new TestableContentResolver(mContext);
|
||||||
|
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
|
||||||
|
Settings.Global.putString(mContentResolver, Settings.Global.ENABLE_BACK_ANIMATION,
|
||||||
|
ANIMATION_ENABLED);
|
||||||
|
mTestableLooper = TestableLooper.get(this);
|
||||||
mController = new BackAnimationController(
|
mController = new BackAnimationController(
|
||||||
mShellExecutor, mTransaction, mActivityTaskManager, mContext);
|
mShellExecutor, new Handler(mTestableLooper.getLooper()), mTransaction,
|
||||||
mController.setEnableAnimations(true);
|
mActivityTaskManager, mContext,
|
||||||
|
mContentResolver);
|
||||||
|
mEventTime = 0;
|
||||||
|
mShellExecutor.flushAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createNavigationInfo(RemoteAnimationTarget topAnimationTarget,
|
private void createNavigationInfo(RemoteAnimationTarget topAnimationTarget,
|
||||||
SurfaceControl screenshotSurface,
|
SurfaceControl screenshotSurface,
|
||||||
HardwareBuffer hardwareBuffer,
|
HardwareBuffer hardwareBuffer,
|
||||||
int backType) {
|
int backType,
|
||||||
|
IOnBackInvokedCallback onBackInvokedCallback) {
|
||||||
BackNavigationInfo navigationInfo = new BackNavigationInfo(
|
BackNavigationInfo navigationInfo = new BackNavigationInfo(
|
||||||
backType,
|
backType,
|
||||||
topAnimationTarget,
|
topAnimationTarget,
|
||||||
@@ -99,7 +124,7 @@ public class BackAnimationControllerTest {
|
|||||||
hardwareBuffer,
|
hardwareBuffer,
|
||||||
new WindowConfiguration(),
|
new WindowConfiguration(),
|
||||||
new RemoteCallback((bundle) -> {}),
|
new RemoteCallback((bundle) -> {}),
|
||||||
null);
|
onBackInvokedCallback);
|
||||||
try {
|
try {
|
||||||
doReturn(navigationInfo).when(mActivityTaskManager).startBackNavigation();
|
doReturn(navigationInfo).when(mActivityTaskManager).startBackNavigation();
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
@@ -124,15 +149,10 @@ public class BackAnimationControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void triggerBackGesture() {
|
private void triggerBackGesture() {
|
||||||
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
|
doMotionEvent(MotionEvent.ACTION_DOWN, 0);
|
||||||
mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
|
doMotionEvent(MotionEvent.ACTION_MOVE, 0);
|
||||||
|
|
||||||
event = MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0);
|
|
||||||
mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
|
|
||||||
|
|
||||||
mController.setTriggerBack(true);
|
mController.setTriggerBack(true);
|
||||||
event = MotionEvent.obtain(10, 0, MotionEvent.ACTION_UP, 100, 100, 0);
|
doMotionEvent(MotionEvent.ACTION_UP, 0);
|
||||||
mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -141,11 +161,8 @@ public class BackAnimationControllerTest {
|
|||||||
SurfaceControl screenshotSurface = new SurfaceControl();
|
SurfaceControl screenshotSurface = new SurfaceControl();
|
||||||
HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
|
HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
|
||||||
createNavigationInfo(createAnimationTarget(), screenshotSurface, hardwareBuffer,
|
createNavigationInfo(createAnimationTarget(), screenshotSurface, hardwareBuffer,
|
||||||
BackNavigationInfo.TYPE_CROSS_ACTIVITY);
|
BackNavigationInfo.TYPE_CROSS_ACTIVITY, null);
|
||||||
mController.onMotionEvent(
|
doMotionEvent(MotionEvent.ACTION_DOWN, 0);
|
||||||
MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0),
|
|
||||||
MotionEvent.ACTION_DOWN,
|
|
||||||
BackEvent.EDGE_LEFT);
|
|
||||||
verify(mTransaction).setBuffer(screenshotSurface, hardwareBuffer);
|
verify(mTransaction).setBuffer(screenshotSurface, hardwareBuffer);
|
||||||
verify(mTransaction).setVisibility(screenshotSurface, true);
|
verify(mTransaction).setVisibility(screenshotSurface, true);
|
||||||
verify(mTransaction).apply();
|
verify(mTransaction).apply();
|
||||||
@@ -157,15 +174,9 @@ public class BackAnimationControllerTest {
|
|||||||
HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
|
HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
|
||||||
RemoteAnimationTarget animationTarget = createAnimationTarget();
|
RemoteAnimationTarget animationTarget = createAnimationTarget();
|
||||||
createNavigationInfo(animationTarget, screenshotSurface, hardwareBuffer,
|
createNavigationInfo(animationTarget, screenshotSurface, hardwareBuffer,
|
||||||
BackNavigationInfo.TYPE_CROSS_ACTIVITY);
|
BackNavigationInfo.TYPE_CROSS_ACTIVITY, null);
|
||||||
mController.onMotionEvent(
|
doMotionEvent(MotionEvent.ACTION_DOWN, 0);
|
||||||
MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0),
|
doMotionEvent(MotionEvent.ACTION_MOVE, 100);
|
||||||
MotionEvent.ACTION_DOWN,
|
|
||||||
BackEvent.EDGE_LEFT);
|
|
||||||
mController.onMotionEvent(
|
|
||||||
MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
|
|
||||||
MotionEvent.ACTION_MOVE,
|
|
||||||
BackEvent.EDGE_LEFT);
|
|
||||||
// b/207481538, we check that the surface is not moved for now, we can re-enable this once
|
// b/207481538, we check that the surface is not moved for now, we can re-enable this once
|
||||||
// we implement the animation
|
// we implement the animation
|
||||||
verify(mTransaction, never()).setScale(eq(screenshotSurface), anyInt(), anyInt());
|
verify(mTransaction, never()).setScale(eq(screenshotSurface), anyInt(), anyInt());
|
||||||
@@ -196,30 +207,56 @@ public class BackAnimationControllerTest {
|
|||||||
mController.setBackToLauncherCallback(mIOnBackInvokedCallback);
|
mController.setBackToLauncherCallback(mIOnBackInvokedCallback);
|
||||||
RemoteAnimationTarget animationTarget = createAnimationTarget();
|
RemoteAnimationTarget animationTarget = createAnimationTarget();
|
||||||
createNavigationInfo(animationTarget, null, null,
|
createNavigationInfo(animationTarget, null, null,
|
||||||
BackNavigationInfo.TYPE_RETURN_TO_HOME);
|
BackNavigationInfo.TYPE_RETURN_TO_HOME, null);
|
||||||
|
|
||||||
// Check that back start is dispatched.
|
// Check that back start is dispatched.
|
||||||
mController.onMotionEvent(
|
doMotionEvent(MotionEvent.ACTION_DOWN, 0);
|
||||||
MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0),
|
|
||||||
MotionEvent.ACTION_DOWN,
|
|
||||||
BackEvent.EDGE_LEFT);
|
|
||||||
verify(mIOnBackInvokedCallback).onBackStarted();
|
verify(mIOnBackInvokedCallback).onBackStarted();
|
||||||
|
|
||||||
// Check that back progress is dispatched.
|
// Check that back progress is dispatched.
|
||||||
mController.onMotionEvent(
|
doMotionEvent(MotionEvent.ACTION_MOVE, 100);
|
||||||
MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
|
|
||||||
MotionEvent.ACTION_MOVE,
|
|
||||||
BackEvent.EDGE_LEFT);
|
|
||||||
ArgumentCaptor<BackEvent> backEventCaptor = ArgumentCaptor.forClass(BackEvent.class);
|
ArgumentCaptor<BackEvent> backEventCaptor = ArgumentCaptor.forClass(BackEvent.class);
|
||||||
verify(mIOnBackInvokedCallback).onBackProgressed(backEventCaptor.capture());
|
verify(mIOnBackInvokedCallback).onBackProgressed(backEventCaptor.capture());
|
||||||
assertEquals(animationTarget, backEventCaptor.getValue().getDepartingAnimationTarget());
|
assertEquals(animationTarget, backEventCaptor.getValue().getDepartingAnimationTarget());
|
||||||
|
|
||||||
// Check that back invocation is dispatched.
|
// Check that back invocation is dispatched.
|
||||||
mController.setTriggerBack(true); // Fake trigger back
|
mController.setTriggerBack(true); // Fake trigger back
|
||||||
mController.onMotionEvent(
|
doMotionEvent(MotionEvent.ACTION_UP, 0);
|
||||||
MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0),
|
|
||||||
MotionEvent.ACTION_UP,
|
|
||||||
BackEvent.EDGE_LEFT);
|
|
||||||
verify(mIOnBackInvokedCallback).onBackInvoked();
|
verify(mIOnBackInvokedCallback).onBackInvoked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void animationDisabledFromSettings() throws RemoteException {
|
||||||
|
// Toggle the setting off
|
||||||
|
Settings.Global.putString(mContentResolver, Settings.Global.ENABLE_BACK_ANIMATION, "0");
|
||||||
|
mController = new BackAnimationController(
|
||||||
|
mShellExecutor, new Handler(mTestableLooper.getLooper()), mTransaction,
|
||||||
|
mActivityTaskManager, mContext,
|
||||||
|
mContentResolver);
|
||||||
|
mController.setBackToLauncherCallback(mIOnBackInvokedCallback);
|
||||||
|
|
||||||
|
RemoteAnimationTarget animationTarget = createAnimationTarget();
|
||||||
|
IOnBackInvokedCallback appCallback = mock(IOnBackInvokedCallback.class);
|
||||||
|
ArgumentCaptor<BackEvent> backEventCaptor = ArgumentCaptor.forClass(BackEvent.class);
|
||||||
|
createNavigationInfo(animationTarget, null, null,
|
||||||
|
BackNavigationInfo.TYPE_RETURN_TO_HOME, appCallback);
|
||||||
|
|
||||||
|
triggerBackGesture();
|
||||||
|
|
||||||
|
verify(appCallback, never()).onBackStarted();
|
||||||
|
verify(appCallback, never()).onBackProgressed(backEventCaptor.capture());
|
||||||
|
verify(appCallback, times(1)).onBackInvoked();
|
||||||
|
|
||||||
|
verify(mIOnBackInvokedCallback, never()).onBackStarted();
|
||||||
|
verify(mIOnBackInvokedCallback, never()).onBackProgressed(backEventCaptor.capture());
|
||||||
|
verify(mIOnBackInvokedCallback, never()).onBackInvoked();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doMotionEvent(int actionDown, int coordinate) {
|
||||||
|
mController.onMotionEvent(
|
||||||
|
MotionEvent.obtain(0, mEventTime, actionDown, coordinate, coordinate, 0),
|
||||||
|
actionDown,
|
||||||
|
BackEvent.EDGE_LEFT);
|
||||||
|
mEventTime += 10;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1604,4 +1604,11 @@
|
|||||||
<string name="bt_le_audio_broadcast_dialog_switch_app">Broadcast <xliff:g id="switchApp" example="App Name 2">%1$s</xliff:g></string>
|
<string name="bt_le_audio_broadcast_dialog_switch_app">Broadcast <xliff:g id="switchApp" example="App Name 2">%1$s</xliff:g></string>
|
||||||
<!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, different output. -->
|
<!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, different output. -->
|
||||||
<string name="bt_le_audio_broadcast_dialog_different_output">Change output</string>
|
<string name="bt_le_audio_broadcast_dialog_different_output">Change output</string>
|
||||||
|
|
||||||
|
<!-- Developer setting: enable animations when a back gesture is executed [CHAR LIMIT=50] -->
|
||||||
|
<string name="back_navigation_animation">Predictive back animations</string>
|
||||||
|
<!-- Developer setting: enable animations when a back gesture is executed [CHAR LIMIT=150] -->
|
||||||
|
<string name="back_navigation_animation_summary">Enable system animations for predictive back.</string>
|
||||||
|
<!-- Developer setting: enable animations when a back gesture is executed, full explanation[CHAR LIMIT=NONE] -->
|
||||||
|
<string name="back_navigation_animation_dialog">This setting enables system animations for predictive gesture animation. It requires setting per-app "enableOnBackInvokedCallback" to true in the manifest file.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -598,6 +598,7 @@ public class SettingsBackupTest {
|
|||||||
Settings.Global.WATCHDOG_TIMEOUT_MILLIS,
|
Settings.Global.WATCHDOG_TIMEOUT_MILLIS,
|
||||||
Settings.Global.MANAGED_PROVISIONING_DEFER_PROVISIONING_TO_ROLE_HOLDER,
|
Settings.Global.MANAGED_PROVISIONING_DEFER_PROVISIONING_TO_ROLE_HOLDER,
|
||||||
Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
|
Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
|
||||||
|
Settings.Global.ENABLE_BACK_ANIMATION, // Temporary for T, dev option only
|
||||||
Settings.Global.Wearable.BATTERY_SAVER_MODE,
|
Settings.Global.Wearable.BATTERY_SAVER_MODE,
|
||||||
Settings.Global.Wearable.COMBINED_LOCATION_ENABLED,
|
Settings.Global.Wearable.COMBINED_LOCATION_ENABLED,
|
||||||
Settings.Global.Wearable.HAS_PAY_TOKENS,
|
Settings.Global.Wearable.HAS_PAY_TOKENS,
|
||||||
|
|||||||
Reference in New Issue
Block a user