From c52cb42e5114cfa7ec2be462d502065ce2a2c3be Mon Sep 17 00:00:00 2001 From: Ameer Armaly Date: Wed, 8 Dec 2021 11:07:34 -0800 Subject: [PATCH] Add API for services to turn off window animations. Bug: 195757359 Test: atest AccessibilityWindowReportingTest Change-Id: I5fc1c90e87de17fb770f6a3371fc341985017a61 --- core/api/current.txt | 2 ++ .../AccessibilityService.java | 27 +++++++++++++++++++ .../IAccessibilityServiceConnection.aidl | 2 ++ core/java/android/app/UiAutomation.java | 27 +++++++++++++++++++ .../AccessibilityServiceConnectionImpl.java | 2 ++ ...bstractAccessibilityServiceConnection.java | 23 +++++++++++++++- 6 files changed, 82 insertions(+), 1 deletion(-) diff --git a/core/api/current.txt b/core/api/current.txt index 40f589d6f1690..346817299d5ca 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -3074,6 +3074,7 @@ package android.accessibilityservice { method public void onSystemActionsChanged(); method public final boolean performGlobalAction(int); method public void setAccessibilityFocusAppearance(int, @ColorInt int); + method public void setAnimationScale(float); method public boolean setCacheEnabled(boolean); method public void setGestureDetectionPassthroughRegion(int, @NonNull android.graphics.Region); method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo); @@ -6949,6 +6950,7 @@ package android.app { method public boolean performGlobalAction(int); method public void revokeRuntimePermission(String, String); method public void revokeRuntimePermissionAsUser(String, String, android.os.UserHandle); + method public void setAnimationScale(float); method public void setOnAccessibilityEventListener(android.app.UiAutomation.OnAccessibilityEventListener); method public boolean setRotation(int); method public void setRunAsMonkey(boolean); diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 42d2d28ae9286..50473f1d8c845 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -3120,6 +3120,33 @@ public abstract class AccessibilityService extends Service { } } + /** + * Sets the system settings values that control the scaling factor for animations. The scale + * controls the animation playback speed for animations that respect these settings. Animations + * that do not respect the settings values will not be affected by this function. A lower scale + * value results in a faster speed. A value of 0 disables animations entirely. When + * animations are disabled services receive window change events more quickly which can reduce + * the potential by confusion by reducing the time during which windows are in transition. + * + * @see AccessibilityEvent#TYPE_WINDOWS_CHANGED + * @see AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED + * @see android.provider.Settings.Global#WINDOW_ANIMATION_SCALE + * @see android.provider.Settings.Global#TRANSITION_ANIMATION_SCALE + * @see android.provider.Settings.Global#ANIMATOR_DURATION_SCALE + * @param scale The scaling factor for all animations. + */ + public void setAnimationScale(float scale) { + final IAccessibilityServiceConnection connection = + AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId); + if (connection != null) { + try { + connection.setAnimationScale(scale); + } catch (RemoteException re) { + throw new RuntimeException(re); + } + } + } + private static class AccessibilityContext extends ContextWrapper { private final int mConnectionId; diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl index 2cc15b40106be..0d6b19941afed 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl @@ -144,4 +144,6 @@ interface IAccessibilityServiceConnection { void onDoubleTap(int displayId); void onDoubleTapAndHold(int displayId); + + void setAnimationScale(float scale); } diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index 00903a8808340..b41b5f005f1f3 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -779,6 +779,33 @@ public final class UiAutomation { return false; } + /** + * Sets the system settings values that control the scaling factor for animations. The scale + * controls the animation playback speed for animations that respect these settings. Animations + * that do not respect the settings values will not be affected by this function. A lower scale + * value results in a faster speed. A value of 0 disables animations entirely. When + * animations are disabled services receive window change events more quickly which can reduce + * the potential by confusion by reducing the time during which windows are in transition. + * + * @see AccessibilityEvent#TYPE_WINDOWS_CHANGED + * @see AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED + * @see android.provider.Settings.Global#WINDOW_ANIMATION_SCALE + * @see android.provider.Settings.Global#TRANSITION_ANIMATION_SCALE + * @see android.provider.Settings.Global#ANIMATOR_DURATION_SCALE + * @param scale The scaling factor for all animations. + */ + public void setAnimationScale(float scale) { + final IAccessibilityServiceConnection connection = + AccessibilityInteractionClient.getInstance().getConnection(mConnectionId); + if (connection != null) { + try { + connection.setAnimationScale(scale); + } catch (RemoteException re) { + throw new RuntimeException(re); + } + } + } + /** * A request for WindowManagerService to wait until all animations have completed and input * information has been sent from WindowManager to native InputManager. diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java index 02e5942a3544f..fc385a013d007 100644 --- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java +++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java @@ -204,4 +204,6 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon public void logTrace(long timestamp, String where, long loggingTypes, String callingParams, int processId, long threadId, int callingUid, Bundle serializedCallingStackInBundle) {} + + public void setAnimationScale(float scale) {} } diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index e93ac47b19402..8b62a64f57d4c 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -66,6 +66,7 @@ import android.os.RemoteCallback; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; +import android.provider.Settings; import android.util.Slog; import android.util.SparseArray; import android.view.Display; @@ -269,6 +270,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ void onDoubleTap(int displayId); void onDoubleTapAndHold(int displayId); + } public AbstractAccessibilityServiceConnection(Context context, ComponentName componentName, @@ -2164,4 +2166,23 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ public void onDoubleTapAndHold(int displayId) { mSystemSupport.onDoubleTapAndHold(displayId); } -} + + /** + * Sets the scaling factor for animations. + */ + public void setAnimationScale(float scale) { + final long identity = Binder.clearCallingIdentity(); + try { + Settings.Global.putFloat( + mContext.getContentResolver(), Settings.Global.WINDOW_ANIMATION_SCALE, scale); + Settings.Global.putFloat( + mContext.getContentResolver(), + Settings.Global.TRANSITION_ANIMATION_SCALE, + scale); + Settings.Global.putFloat( + mContext.getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, scale); + } finally { + Binder.restoreCallingIdentity(identity); + } + } +} \ No newline at end of file