Updates magnification button after an accessibility action is performed

To switch magnification mode, a user has to click the magnifcation
button UI. However magnification button UI is visible only when
there is an user touch interaction or the magnification shortcut
triggered event.
However some a11y services like switch-access or voice-access
can only interact with magnification UI by performing
accessibility actions. To make magnification button showing and
able to interact with a user, we also trigger updating
magnification button UI when an accessibility action is performed.

Bug: 179442890
Test: atest WindowMagnificationControllerTest;
atest WindowMagnificationTest;atest MagnificationControllerTest;atest WindowMagnificationManagerTest

Change-Id: I8d762096c9cb6a4421d024a7a1af99b3a48a3462
This commit is contained in:
mincheli
2021-03-24 17:49:26 +08:00
committed by Minche Li
parent 8b23eff356
commit 80a35549c8
11 changed files with 138 additions and 29 deletions

View File

@@ -60,4 +60,11 @@ import android.graphics.Rect;
*/
void onPerformScaleAction(int displayId, float scale);
/**
* Called when the accessibility action is performed.
*
* @param displayId The logical display id.
*/
void onAccessibilityActionPerformed(int displayId);
}

View File

@@ -194,6 +194,13 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
}
}
@Override
public void onAccessibilityActionPerformed(int displayId) {
if (mWindowMagnificationConnectionImpl != null) {
mWindowMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
}
}
@Override
public void requestWindowMagnificationConnection(boolean connect) {
if (connect) {

View File

@@ -120,4 +120,14 @@ class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.S
}
}
}
void onAccessibilityActionPerformed(int displayId) {
if (mConnectionCallback != null) {
try {
mConnectionCallback.onAccessibilityActionPerformed(displayId);
} catch (RemoteException e) {
Log.e(TAG, "Failed to inform an accessibility action is already performed", e);
}
}
}
}

View File

@@ -756,31 +756,23 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
final float scale = mScale + A11Y_CHANGE_SCALE_DIFFERENCE;
mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
A11Y_ACTION_SCALE_RANGE.clamp(scale));
return true;
}
if (action == R.id.accessibility_action_zoom_out) {
} else if (action == R.id.accessibility_action_zoom_out) {
final float scale = mScale - A11Y_CHANGE_SCALE_DIFFERENCE;
mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
A11Y_ACTION_SCALE_RANGE.clamp(scale));
return true;
}
if (action == R.id.accessibility_action_move_up) {
} else if (action == R.id.accessibility_action_move_up) {
move(0, -mSourceBounds.height());
return true;
}
if (action == R.id.accessibility_action_move_down) {
} else if (action == R.id.accessibility_action_move_down) {
move(0, mSourceBounds.height());
return true;
}
if (action == R.id.accessibility_action_move_left) {
} else if (action == R.id.accessibility_action_move_left) {
move(-mSourceBounds.width(), 0);
return true;
}
if (action == R.id.accessibility_action_move_right) {
} else if (action == R.id.accessibility_action_move_right) {
move(mSourceBounds.width(), 0);
return true;
} else {
return false;
}
return false;
mWindowMagnifierCallback.onAccessibilityActionPerformed(mDisplayId);
return true;
}
}
}

View File

@@ -46,4 +46,11 @@ interface WindowMagnifierCallback {
* @param scale the target scale, or {@link Float#NaN} to leave unchanged
*/
void onPerformScaleAction(int displayId, float scale);
/**
* Called when the accessibility action is performed.
*
* @param displayId The logical display id.
*/
void onAccessibilityActionPerformed(int displayId);
}

View File

@@ -302,6 +302,19 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
mMirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null));
}
@Test
public void performA11yActions_visible_notifyAccessibilityActionPerformed() {
final int displayId = mContext.getDisplayId();
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.enableWindowMagnification(2.5f, Float.NaN,
Float.NaN);
});
mMirrorView.performAccessibilityAction(R.id.accessibility_action_move_up, null);
verify(mWindowMagnifierCallback).onAccessibilityActionPerformed(eq(displayId));
}
@Test
public void onNavigationModeChanged_updateMirrorViewLayout() {
mInstrumentation.runOnMainSync(() -> {

View File

@@ -117,6 +117,16 @@ public class WindowMagnificationTest extends SysuiTestCase {
eq(newScale));
}
@Test
public void onAccessibilityActionPerformed_enabled_notifyCallback() throws RemoteException {
mCommandQueue.requestWindowMagnificationConnection(true);
waitForIdleSync();
mWindowMagnification.onAccessibilityActionPerformed(Display.DEFAULT_DISPLAY);
verify(mConnectionCallback).onAccessibilityActionPerformed(eq(Display.DEFAULT_DISPLAY));
}
@Test
public void onConfigurationChanged_updateModeSwitches() {
final Configuration config = new Configuration();

View File

@@ -115,6 +115,11 @@ public class MagnificationController implements WindowMagnificationManager.Callb
getWindowMagnificationMgr().persistScale(displayId);
}
@Override
public void onAccessibilityActionPerformed(int displayId) {
updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
}
@Override
public void onTouchInteractionStart(int displayId, int mode) {
handleUserInteractionChanged(displayId, mode);
@@ -145,8 +150,13 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
private void updateMagnificationButton(int displayId, int mode) {
if (isActivated(displayId, mode) && mMagnificationCapabilities
== Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) {
final boolean isActivated = isActivated(displayId, mode);
final boolean showButton;
synchronized (mLock) {
showButton = isActivated && mMagnificationCapabilities
== Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
}
if (showButton) {
getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
} else {
getWindowMagnificationMgr().removeMagnificationButton(displayId);
@@ -414,13 +424,22 @@ public class MagnificationController implements WindowMagnificationManager.Callb
private boolean isActivated(int displayId, int mode) {
boolean isActivated = false;
if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
&& mFullScreenMagnificationController != null) {
isActivated = mFullScreenMagnificationController.isMagnifying(displayId)
|| mFullScreenMagnificationController.isForceShowMagnifiableBounds(displayId);
} else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
&& mWindowMagnificationMgr != null) {
isActivated = mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
synchronized (mLock) {
if (mFullScreenMagnificationController == null) {
return false;
}
isActivated = mFullScreenMagnificationController.isMagnifying(displayId)
|| mFullScreenMagnificationController.isForceShowMagnifiableBounds(
displayId);
}
} else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
synchronized (mLock) {
if (mWindowMagnificationMgr == null) {
return false;
}
isActivated = mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
}
}
return isActivated;
}

View File

@@ -94,6 +94,13 @@ public class WindowMagnificationManager implements
*/
void onPerformScaleAction(int displayId, float scale);
/**
* Called when the accessibility action is performed.
*
* @param displayId The logical display id.
*/
void onAccessibilityActionPerformed(int displayId);
/**
* Called when the state of the magnification activation is changed.
*
@@ -535,9 +542,12 @@ public class WindowMagnificationManager implements
@Override
public void onPerformScaleAction(int displayId, float scale) {
synchronized (mLock) {
mCallback.onPerformScaleAction(displayId, scale);
}
mCallback.onPerformScaleAction(displayId, scale);
}
@Override
public void onAccessibilityActionPerformed(int displayId) {
mCallback.onAccessibilityActionPerformed(displayId);
}
@Override

View File

@@ -303,6 +303,29 @@ public class MagnificationControllerTest {
verify(mWindowMagnificationManager).persistScale(eq(TEST_DISPLAY));
}
@Test
public void onAccessibilityActionPerformed_magnifierEnabled_showMagnificationButton()
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
mMagnificationController.onAccessibilityActionPerformed(TEST_DISPLAY);
verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@Test
public void onAccessibilityActionPerformed_capabilityNotAll_removeMagnificationButton()
throws RemoteException {
mMagnificationController.setMagnificationCapabilities(
ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
setMagnificationEnabled(MODE_WINDOW);
mMagnificationController.onAccessibilityActionPerformed(TEST_DISPLAY);
verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
}
@Test
public void onWindowMagnificationActivationState_windowActivated_logWindowDuration() {
mMagnificationController.onWindowMagnificationActivationState(true);

View File

@@ -312,6 +312,17 @@ public class WindowMagnificationManagerTest {
verify(mMockCallback).onPerformScaleAction(eq(TEST_DISPLAY), eq(newScale));
}
@Test
public void onAccessibilityActionPerformed_magnifierEnabled_notifyAction()
throws RemoteException {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
mMockConnection.getConnectionCallback().onAccessibilityActionPerformed(TEST_DISPLAY);
verify(mMockCallback).onAccessibilityActionPerformed(eq(TEST_DISPLAY));
}
@Test
public void binderDied_windowMagnifierIsEnabled_resetState() throws RemoteException {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());