Adds new magnificationController API: getCurrentMagnificationRegion, resetCurrentMagnification
See go/b200769372 - the legacy public methods The legacy magnification controller methods of a11y service, getMagnificationRegion(), reset(), will keep the behavior before that control only full-screen magnification. To make the a11y service able to control the actiavted magnifier on the display, the service should use the new public APIs, 1. getCurrentMagnificationRegion(), 2. resetCurrentMagnification(), instead of the legacy APIs. Bug: 210069654 Test: atest AccessibilityMagnificationTest, atest MagnificationProcessorTest, atest AbstractAccessibilityServiceConnectionTest, Change-Id: I76bfee43cbb76a9aeec33574a8db18430903e08c
This commit is contained in:
@@ -3125,11 +3125,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 @NonNull public android.graphics.Region getCurrentMagnificationRegion();
|
||||
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 resetCurrentMagnification(boolean);
|
||||
method public boolean setCenter(float, float, boolean);
|
||||
method public boolean setMagnificationConfig(@NonNull android.accessibilityservice.MagnificationConfig, boolean);
|
||||
method public boolean setScale(float, boolean);
|
||||
|
||||
@@ -1503,6 +1503,12 @@ public abstract class AccessibilityService extends Service {
|
||||
* {@link AccessibilityService#onServiceConnected()} has not yet been
|
||||
* called) or the service has been disconnected, this method will
|
||||
* return an empty region.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>Note:</strong> This legacy API gets the magnification region of full-screen
|
||||
* magnification. To get the magnification region of the current controlling magnifier,
|
||||
* use {@link #getCurrentMagnificationRegion()} instead.
|
||||
* </p>
|
||||
*
|
||||
* @return the region of the screen currently active for magnification, or an empty region
|
||||
* if magnification is not active.
|
||||
@@ -1523,6 +1529,45 @@ public abstract class AccessibilityService extends Service {
|
||||
return Region.obtain();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the region of the screen currently active for magnification if the
|
||||
* controlling magnification is {@link MagnificationConfig#MAGNIFICATION_MODE_FULLSCREEN}.
|
||||
* Returns the region of screen projected on the magnification window if the
|
||||
* controlling magnification is {@link MagnificationConfig#MAGNIFICATION_MODE_WINDOW}.
|
||||
*
|
||||
* <p>
|
||||
* If the controlling mode is {@link MagnificationConfig#MAGNIFICATION_MODE_FULLSCREEN},
|
||||
* the returned region will be empty if the magnification is
|
||||
* not active. And the magnification is active if magnification gestures are enabled
|
||||
* or if a service is running that can control magnification.
|
||||
* </p><p>
|
||||
* If the controlling mode is {@link MagnificationConfig#MAGNIFICATION_MODE_WINDOW},
|
||||
* the returned region will be empty if the magnification is not activated.
|
||||
* </p><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 an empty region.
|
||||
* </p>
|
||||
*
|
||||
* @return the magnification region of the currently controlling magnification
|
||||
*/
|
||||
@NonNull
|
||||
public Region getCurrentMagnificationRegion() {
|
||||
final IAccessibilityServiceConnection connection =
|
||||
AccessibilityInteractionClient.getInstance(mService).getConnection(
|
||||
mService.mConnectionId);
|
||||
if (connection != null) {
|
||||
try {
|
||||
return connection.getCurrentMagnificationRegion(mDisplayId);
|
||||
} catch (RemoteException re) {
|
||||
Log.w(LOG_TAG, "Failed to obtain the current magnified region", re);
|
||||
re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
return Region.obtain();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets magnification scale and center to their default (e.g. no
|
||||
* magnification) values.
|
||||
@@ -1531,6 +1576,11 @@ public abstract class AccessibilityService extends Service {
|
||||
* {@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>
|
||||
* <strong>Note:</strong> This legacy API reset full-screen magnification.
|
||||
* To reset the current controlling magnifier, use
|
||||
* {@link #resetCurrentMagnification(boolean)} ()} instead.
|
||||
* </p>
|
||||
*
|
||||
* @param animate {@code true} to animate from the current scale and
|
||||
* center or {@code false} to reset the scale and center
|
||||
@@ -1552,6 +1602,36 @@ public abstract class AccessibilityService extends Service {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets magnification scale and center of the controlling magnification
|
||||
* to their default (e.g. no magnification) values.
|
||||
* <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 animate {@code true} to animate from the current scale and
|
||||
* center or {@code false} to reset the scale and center
|
||||
* immediately
|
||||
* @return {@code true} on success, {@code false} on failure
|
||||
*/
|
||||
public boolean resetCurrentMagnification(boolean animate) {
|
||||
final IAccessibilityServiceConnection connection =
|
||||
AccessibilityInteractionClient.getInstance(mService).getConnection(
|
||||
mService.mConnectionId);
|
||||
if (connection != null) {
|
||||
try {
|
||||
return connection.resetCurrentMagnification(mDisplayId, animate);
|
||||
} catch (RemoteException re) {
|
||||
Log.w(LOG_TAG, "Failed to reset", re);
|
||||
re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MagnificationConfig}. The service controls the magnification by
|
||||
* setting the config.
|
||||
|
||||
@@ -88,8 +88,12 @@ interface IAccessibilityServiceConnection {
|
||||
|
||||
Region getMagnificationRegion(int displayId);
|
||||
|
||||
Region getCurrentMagnificationRegion(int displayId);
|
||||
|
||||
boolean resetMagnification(int displayId, boolean animate);
|
||||
|
||||
boolean resetCurrentMagnification(int displayId, boolean animate);
|
||||
|
||||
boolean setMagnificationConfig(int displayId, in MagnificationConfig config, boolean animate);
|
||||
|
||||
void setMagnificationCallbackEnabled(int displayId, boolean enabled);
|
||||
|
||||
@@ -120,10 +120,18 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon
|
||||
return null;
|
||||
}
|
||||
|
||||
public Region getCurrentMagnificationRegion(int displayId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean resetMagnification(int displayId, boolean animate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean resetCurrentMagnification(int displayId, boolean animate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setMagnificationConfig(int displayId,
|
||||
@NonNull MagnificationConfig config, boolean animate) {
|
||||
return false;
|
||||
|
||||
@@ -1036,6 +1036,30 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Region getCurrentMagnificationRegion(int displayId) {
|
||||
if (svcConnTracingEnabled()) {
|
||||
logTraceSvcConn("getCurrentMagnificationRegion", "displayId=" + displayId);
|
||||
}
|
||||
synchronized (mLock) {
|
||||
final Region region = Region.obtain();
|
||||
if (!hasRightsToCurrentUserLocked()) {
|
||||
return region;
|
||||
}
|
||||
MagnificationProcessor magnificationProcessor =
|
||||
mSystemSupport.getMagnificationProcessor();
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
magnificationProcessor.getCurrentMagnificationRegion(displayId,
|
||||
region, mSecurityPolicy.canControlMagnification(this));
|
||||
return region;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMagnificationCenterX(int displayId) {
|
||||
if (svcConnTracingEnabled()) {
|
||||
@@ -1102,6 +1126,31 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetCurrentMagnification(int displayId, boolean animate) {
|
||||
if (svcConnTracingEnabled()) {
|
||||
logTraceSvcConn("resetCurrentMagnification",
|
||||
"displayId=" + displayId + ";animate=" + animate);
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (!hasRightsToCurrentUserLocked()) {
|
||||
return false;
|
||||
}
|
||||
if (!mSecurityPolicy.canControlMagnification(this)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
MagnificationProcessor magnificationProcessor =
|
||||
mSystemSupport.getMagnificationProcessor();
|
||||
return (magnificationProcessor.resetCurrentMagnification(displayId, animate)
|
||||
|| !magnificationProcessor.isMagnifying(displayId));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setMagnificationConfig(int displayId,
|
||||
@NonNull MagnificationConfig config, boolean animate) {
|
||||
|
||||
@@ -202,6 +202,36 @@ public class MagnificationProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the region of the screen currently active for magnification if the
|
||||
* controlling magnification is {@link MagnificationConfig#MAGNIFICATION_MODE_FULLSCREEN}.
|
||||
* Returns the region of screen projected on the magnification window if the controlling
|
||||
* magnification is {@link MagnificationConfig#MAGNIFICATION_MODE_WINDOW}.
|
||||
* <p>
|
||||
* If the controlling mode is {@link MagnificationConfig#MAGNIFICATION_MODE_FULLSCREEN},
|
||||
* the returned region will be empty if the magnification is
|
||||
* not active. And the magnification is active if magnification gestures are enabled
|
||||
* or if a service is running that can control magnification.
|
||||
* </p><p>
|
||||
* If the controlling mode is {@link MagnificationConfig#MAGNIFICATION_MODE_WINDOW},
|
||||
* the returned region will be empty if the magnification is not activated.
|
||||
* </p>
|
||||
*
|
||||
* @param displayId The logical display id
|
||||
* @param outRegion the region to populate
|
||||
* @param canControlMagnification Whether the service can control magnification
|
||||
*/
|
||||
public void getCurrentMagnificationRegion(int displayId, @NonNull Region outRegion,
|
||||
boolean canControlMagnification) {
|
||||
int currentMode = getControllingMode(displayId);
|
||||
if (currentMode == MAGNIFICATION_MODE_FULLSCREEN) {
|
||||
getFullscreenMagnificationRegion(displayId, outRegion, canControlMagnification);
|
||||
} else if (currentMode == MAGNIFICATION_MODE_WINDOW) {
|
||||
mController.getWindowMagnificationMgr().getMagnificationSourceBounds(displayId,
|
||||
outRegion);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the magnification bounds of full-screen magnification on the given display.
|
||||
*
|
||||
@@ -224,8 +254,8 @@ public class MagnificationProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the current magnification on the given display. The reset mode could be
|
||||
* full-screen or window if it is activated.
|
||||
* Resets the controlling magnifier on the given display.
|
||||
* For resetting window magnifier, it disables the magnifier by setting the scale to 1.
|
||||
*
|
||||
* @param displayId The logical display id.
|
||||
* @param animate {@code true} to animate the transition, {@code false}
|
||||
|
||||
@@ -594,6 +594,20 @@ public class AbstractAccessibilityServiceConnectionTest {
|
||||
assertThat(result.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCurrentMagnificationRegion_returnRegion() {
|
||||
final int displayId = 1;
|
||||
final Region region = new Region(10, 20, 100, 200);
|
||||
doAnswer((invocation) -> {
|
||||
((Region) invocation.getArguments()[1]).set(region);
|
||||
return null;
|
||||
}).when(mMockMagnificationProcessor).getCurrentMagnificationRegion(eq(displayId), any(),
|
||||
anyBoolean());
|
||||
|
||||
final Region result = mServiceConnection.getCurrentMagnificationRegion(displayId);
|
||||
assertEquals(result, region);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMagnificationCenterX_serviceNotBelongCurrentUser_returnZero() {
|
||||
final int displayId = 1;
|
||||
|
||||
@@ -183,6 +183,38 @@ public class MagnificationProcessorTest {
|
||||
verify(mMockFullScreenMagnificationController).unregister(TEST_DISPLAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCurrentMagnificationRegion_windowModeActivated_returnRegion() {
|
||||
final Region region = new Region(10, 20, 100, 200);
|
||||
setMagnificationActivated(TEST_DISPLAY, MAGNIFICATION_MODE_WINDOW);
|
||||
doAnswer((invocation) -> {
|
||||
((Region) invocation.getArguments()[1]).set(region);
|
||||
return null;
|
||||
}).when(mMockWindowMagnificationManager).getMagnificationSourceBounds(eq(TEST_DISPLAY),
|
||||
any());
|
||||
|
||||
final Region result = new Region();
|
||||
mMagnificationProcessor.getCurrentMagnificationRegion(TEST_DISPLAY,
|
||||
result, /* canControlMagnification= */true);
|
||||
assertEquals(region, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCurrentMagnificationRegion_fullscreenModeActivated_returnRegion() {
|
||||
final Region region = new Region(10, 20, 100, 200);
|
||||
setMagnificationActivated(TEST_DISPLAY, MAGNIFICATION_MODE_FULLSCREEN);
|
||||
doAnswer((invocation) -> {
|
||||
((Region) invocation.getArguments()[1]).set(region);
|
||||
return null;
|
||||
}).when(mMockFullScreenMagnificationController).getMagnificationRegion(eq(TEST_DISPLAY),
|
||||
any());
|
||||
|
||||
final Region result = new Region();
|
||||
mMagnificationProcessor.getCurrentMagnificationRegion(TEST_DISPLAY,
|
||||
result, /* canControlMagnification= */true);
|
||||
assertEquals(region, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMagnificationCenterX_fullscreenModeNotRegistered_shouldRegisterThenUnregister() {
|
||||
final MagnificationConfig config = new MagnificationConfig.Builder()
|
||||
@@ -222,7 +254,7 @@ public class MagnificationProcessorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reset_fullscreenMagnificationActivated() {
|
||||
public void resetFullscreenMagnification_fullscreenMagnificationActivated() {
|
||||
setMagnificationActivated(TEST_DISPLAY, MAGNIFICATION_MODE_FULLSCREEN);
|
||||
|
||||
mMagnificationProcessor.resetFullscreenMagnification(TEST_DISPLAY, /* animate= */false);
|
||||
@@ -231,7 +263,7 @@ public class MagnificationProcessorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reset_windowMagnificationActivated() {
|
||||
public void resetCurrentMagnification_windowMagnificationActivated() {
|
||||
setMagnificationActivated(TEST_DISPLAY, MAGNIFICATION_MODE_WINDOW);
|
||||
|
||||
mMagnificationProcessor.resetCurrentMagnification(TEST_DISPLAY, /* animate= */false);
|
||||
|
||||
Reference in New Issue
Block a user