diff options
| author | 2021-09-13 23:07:41 +0800 | |
|---|---|---|
| committer | 2021-12-06 18:24:32 +0800 | |
| commit | 7c91f43c3ad7da050caabd19b6a2978f739f7a69 (patch) | |
| tree | d86ea77566c53227af4665b61ecac6783ba5f687 | |
| parent | 06299b95e47cce00e3c93945d0fba2b52b7a3c6f (diff) | |
Adds public APIs for AccessibilityService to control magnifier by setting MagnificationConfig
See go/b200769372
AccessibilityService adds new magnificationController APIs,
setMagnificationConfig and getMagnificationConfig, to control
magnification on demand.
The service can set the magnification mode, scale, center postion
of the magnifier on the display to control magnification.
And the service controls the least recently activated magnifier
on the display if the config mode is not specified.
Bug: 199732498
Test: atest MagnificationProcessorTest,
atest AbstractAccessibilityServiceConnectionTest,
atest AccessibilityMagnificationTest,
Change-Id: I51be2bbf96411c6c54c9da30873556d09533bb65
9 files changed, 119 insertions, 35 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index ea69d212af73..7a727202631a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -3121,11 +3121,13 @@ package android.accessibilityservice { method public void addListener(@NonNull android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener, @Nullable android.os.Handler); method public float getCenterX(); method public float getCenterY(); + method @Nullable public android.accessibilityservice.MagnificationConfig getMagnificationConfig(); method @NonNull public android.graphics.Region getMagnificationRegion(); method public float getScale(); method public boolean removeListener(@NonNull android.accessibilityservice.AccessibilityService.MagnificationController.OnMagnificationChangedListener); method public boolean reset(boolean); method public boolean setCenter(float, float, boolean); + method public boolean setMagnificationConfig(@NonNull android.accessibilityservice.MagnificationConfig, boolean); method public boolean setScale(float, boolean); } diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 09af72d6cc12..ad628728fe1e 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -16,6 +16,7 @@ package android.accessibilityservice; +import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; import android.accessibilityservice.GestureDescription.MotionEventGenerator; @@ -1359,6 +1360,32 @@ public abstract class AccessibilityService extends Service { } /** + * Gets the {@link MagnificationConfig} of the controlling magnifier on the display. + * <p> + * <strong>Note:</strong> If the service is not yet connected (e.g. + * {@link AccessibilityService#onServiceConnected()} has not yet been + * called) or the service has been disconnected, this method will + * return null. + * </p> + * + * @return the magnification config that the service controls + */ + public @Nullable MagnificationConfig getMagnificationConfig() { + final IAccessibilityServiceConnection connection = + AccessibilityInteractionClient.getInstance(mService).getConnection( + mService.mConnectionId); + if (connection != null) { + try { + return connection.getMagnificationConfig(mDisplayId); + } catch (RemoteException re) { + Log.w(LOG_TAG, "Failed to obtain magnification config", re); + re.rethrowFromSystemServer(); + } + } + return null; + } + + /** * Returns the current magnification scale. * <p> * <strong>Note:</strong> If the service is not yet connected (e.g. @@ -1505,6 +1532,37 @@ public abstract class AccessibilityService extends Service { } /** + * Sets the {@link MagnificationConfig}. The service controls the magnification by + * setting the config. + * <p> + * <strong>Note:</strong> If the service is not yet connected (e.g. + * {@link AccessibilityService#onServiceConnected()} has not yet been + * called) or the service has been disconnected, this method will have + * no effect and return {@code false}. + * </p> + * + * @param config the magnification config + * @param animate {@code true} to animate from the current spec or + * {@code false} to set the spec immediately + * @return {@code true} on success, {@code false} on failure + */ + public boolean setMagnificationConfig(@NonNull MagnificationConfig config, + boolean animate) { + final IAccessibilityServiceConnection connection = + AccessibilityInteractionClient.getInstance(mService).getConnection( + mService.mConnectionId); + if (connection != null) { + try { + return connection.setMagnificationConfig(mDisplayId, config, animate); + } catch (RemoteException re) { + Log.w(LOG_TAG, "Failed to set magnification config", re); + re.rethrowFromSystemServer(); + } + } + return false; + } + + /** * Sets the magnification scale. * <p> * <strong>Note:</strong> If the service is not yet connected (e.g. @@ -1523,8 +1581,10 @@ public abstract class AccessibilityService extends Service { mService.mConnectionId); if (connection != null) { try { - return connection.setMagnificationScaleAndCenter(mDisplayId, - scale, Float.NaN, Float.NaN, animate); + final MagnificationConfig config = new MagnificationConfig.Builder() + .setMode(MAGNIFICATION_MODE_FULLSCREEN) + .setScale(scale).build(); + return connection.setMagnificationConfig(mDisplayId, config, animate); } catch (RemoteException re) { Log.w(LOG_TAG, "Failed to set scale", re); re.rethrowFromSystemServer(); @@ -1555,8 +1615,10 @@ public abstract class AccessibilityService extends Service { mService.mConnectionId); if (connection != null) { try { - return connection.setMagnificationScaleAndCenter(mDisplayId, - Float.NaN, centerX, centerY, animate); + final MagnificationConfig config = new MagnificationConfig.Builder() + .setMode(MAGNIFICATION_MODE_FULLSCREEN) + .setCenterX(centerX).setCenterY(centerY).build(); + return connection.setMagnificationConfig(mDisplayId, config, animate); } catch (RemoteException re) { Log.w(LOG_TAG, "Failed to set center", re); re.rethrowFromSystemServer(); diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl index 81457ebf2a51..124dd2ab8240 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl @@ -17,6 +17,7 @@ package android.accessibilityservice; import android.accessibilityservice.AccessibilityServiceInfo; +import android.accessibilityservice.MagnificationConfig; import android.content.pm.ParceledListSlice; import android.graphics.Bitmap; import android.graphics.Region; @@ -77,6 +78,8 @@ interface IAccessibilityServiceConnection { oneway void setOnKeyEventResult(boolean handled, int sequence); + MagnificationConfig getMagnificationConfig(int displayId); + float getMagnificationScale(int displayId); float getMagnificationCenterX(int displayId); @@ -87,8 +90,7 @@ interface IAccessibilityServiceConnection { boolean resetMagnification(int displayId, boolean animate); - boolean setMagnificationScaleAndCenter(int displayId, float scale, float centerX, float centerY, - boolean animate); + boolean setMagnificationConfig(int displayId, in MagnificationConfig config, boolean animate); void setMagnificationCallbackEnabled(int displayId, boolean enabled); diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java index c241e36dceb7..3ce79444f1f5 100644 --- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java +++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java @@ -18,6 +18,8 @@ package android.view.accessibility; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceConnection; +import android.accessibilityservice.MagnificationConfig; +import android.annotation.NonNull; import android.content.pm.ParceledListSlice; import android.graphics.Region; import android.os.Bundle; @@ -97,6 +99,10 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon public void setOnKeyEventResult(boolean handled, int sequence) {} + public MagnificationConfig getMagnificationConfig(int displayId) { + return null; + } + public float getMagnificationScale(int displayId) { return 0.0f; } @@ -117,8 +123,8 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon return false; } - public boolean setMagnificationScaleAndCenter(int displayId, float scale, float centerX, - float centerY, boolean animate) { + public boolean setMagnificationConfig(int displayId, + @NonNull MagnificationConfig config, boolean animate) { return false; } diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index f1599e4d7ffa..881c910b399b 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -976,6 +976,25 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ return false; } + @Nullable + @Override + public MagnificationConfig getMagnificationConfig(int displayId) { + if (svcConnTracingEnabled()) { + logTraceSvcConn("getMagnificationConfig", "displayId=" + displayId); + } + synchronized (mLock) { + if (!hasRightsToCurrentUserLocked()) { + return null; + } + } + final long identity = Binder.clearCallingIdentity(); + try { + return mSystemSupport.getMagnificationProcessor().getMagnificationConfig(displayId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Override public float getMagnificationScale(int displayId) { if (svcConnTracingEnabled()) { @@ -1084,12 +1103,11 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } @Override - public boolean setMagnificationScaleAndCenter(int displayId, float scale, float centerX, - float centerY, boolean animate) { + public boolean setMagnificationConfig(int displayId, + @NonNull MagnificationConfig config, boolean animate) { if (svcConnTracingEnabled()) { - logTraceSvcConn("setMagnificationScaleAndCenter", - "displayId=" + displayId + ";scale=" + scale + ";centerX=" + centerX - + ";centerY=" + centerY + ";animate=" + animate); + logTraceSvcConn("setMagnificationSpec", + "displayId=" + displayId + ", config=" + config.toString()); } synchronized (mLock) { if (!hasRightsToCurrentUserLocked()) { @@ -1102,10 +1120,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ try { MagnificationProcessor magnificationProcessor = mSystemSupport.getMagnificationProcessor(); - final MagnificationConfig config = new MagnificationConfig.Builder() - .setScale(scale) - .setCenterX(centerX) - .setCenterY(centerY).build(); return magnificationProcessor.setMagnificationConfig(displayId, config, animate, mId); } finally { diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java index 42a81e16c0f4..d430f6b032c1 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java @@ -681,7 +681,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb } else { getWindowMagnificationMgr().enableWindowMagnification(mDisplayId, mCurrentScale, mCurrentCenter.x, - mCurrentCenter.y); + mCurrentCenter.y, mAnimate ? STUB_ANIMATION_CALLBACK : null); } } } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java index cd338a498cc4..d0b989582ebe 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java @@ -21,6 +21,7 @@ import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MOD import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW; import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW; +import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK; import android.accessibilityservice.MagnificationConfig; import android.annotation.NonNull; @@ -112,7 +113,8 @@ public class MagnificationProcessor { animate, id); } else if (configMode == MAGNIFICATION_MODE_WINDOW) { return mController.getWindowMagnificationMgr().enableWindowMagnification(displayId, - config.getScale(), config.getCenterX(), config.getCenterY()); + config.getScale(), config.getCenterX(), config.getCenterY(), + animate ? STUB_ANIMATION_CALLBACK : null); } return false; } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java index a83d51b0e5e7..f92b872e1d26 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java @@ -50,6 +50,7 @@ import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -646,7 +647,7 @@ public class AbstractAccessibilityServiceConnectionTest { } @Test - public void setMagnificationScaleAndCenter_cantControlMagnification_returnFalse() { + public void setMagnificationConfig_cantControlMagnification_returnFalse() { final int displayId = 1; final float scale = 1.8f; final float centerX = 50.5f; @@ -659,13 +660,12 @@ public class AbstractAccessibilityServiceConnectionTest { SERVICE_ID)).thenReturn(true); when(mMockSecurityPolicy.canControlMagnification(mServiceConnection)).thenReturn(false); - final boolean result = mServiceConnection.setMagnificationScaleAndCenter( - displayId, scale, centerX, centerY, true); - assertThat(result, is(false)); + final boolean result = mServiceConnection.setMagnificationConfig(displayId, config, true); + assertFalse(result); } @Test - public void setMagnificationScaleAndCenter_serviceNotBelongCurrentUser_returnFalse() { + public void setMagnificationConfig_serviceNotBelongCurrentUser_returnFalse() { final int displayId = 1; final float scale = 1.8f; final float centerX = 50.5f; @@ -678,9 +678,8 @@ public class AbstractAccessibilityServiceConnectionTest { SERVICE_ID)).thenReturn(true); when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2); - final boolean result = mServiceConnection.setMagnificationScaleAndCenter( - displayId, scale, centerX, centerY, true); - assertThat(result, is(false)); + final boolean result = mServiceConnection.setMagnificationConfig(displayId, config, true); + assertFalse(result); } @Test (expected = SecurityException.class) diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java index 74dd2917691d..9ebec981fa21 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java @@ -282,16 +282,13 @@ public class MagnificationProcessorTest { } @Test - public void setMagnificationConfig_fullscreenEnabled_expectedConfigValues() { + public void getMagnificationConfig_fullscreenEnabled_expectedConfigValues() { final MagnificationConfig config = new MagnificationConfig.Builder() .setMode(MAGNIFICATION_MODE_FULLSCREEN) .setScale(TEST_SCALE) .setCenterX(TEST_CENTER_X) .setCenterY(TEST_CENTER_Y).build(); setMagnificationActivated(TEST_DISPLAY, config); - // mMockFullScreenMagnificationController.unregister(TEST_DISPLAY); - mMagnificationProcessor.setMagnificationConfig( - TEST_DISPLAY, config, true, SERVICE_ID); final MagnificationConfig result = mMagnificationProcessor.getMagnificationConfig( TEST_DISPLAY); @@ -300,7 +297,7 @@ public class MagnificationProcessorTest { } @Test - public void setMagnificationConfig_windowEnabled_expectedConfigValues() { + public void getMagnificationConfig_windowEnabled_expectedConfigValues() { final MagnificationConfig config = new MagnificationConfig.Builder() .setMode(MAGNIFICATION_MODE_WINDOW) .setScale(TEST_SCALE) @@ -308,9 +305,6 @@ public class MagnificationProcessorTest { .setCenterY(TEST_CENTER_Y).build(); setMagnificationActivated(TEST_DISPLAY, config); - mMagnificationProcessor.setMagnificationConfig( - TEST_DISPLAY, config, true, SERVICE_ID); - final MagnificationConfig result = mMagnificationProcessor.getMagnificationConfig( TEST_DISPLAY); @@ -455,6 +449,9 @@ public class MagnificationProcessorTest { doAnswer(enableWindowMagnificationStubAnswer).when( mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY), anyFloat(), anyFloat(), anyFloat()); + doAnswer(enableWindowMagnificationStubAnswer).when( + mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY), + anyFloat(), anyFloat(), anyFloat(), any()); } public void resetAndStubMethods() { |