Merge "Support Magnification capabilities Settings value"

This commit is contained in:
Ryan Lin
2020-05-15 02:28:55 +00:00
committed by Android (Google) Code Review
9 changed files with 162 additions and 17 deletions

View File

@@ -562,17 +562,22 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
}
/**
* Called when the magnification mode is changed on specific display.
* Called to refresh the magnification mode on the given display.
* It's responsible for changing {@link MagnificationGestureHandler} based on the current mode.
*
* @param display The logical display
*/
@MainThread
public void onMagnificationModeChanged(Display display) {
public void refreshMagnificationMode(Display display) {
final int displayId = display.getDisplayId();
final MagnificationGestureHandler magnificationGestureHandler =
mMagnificationGestureHandler.get(displayId);
if (magnificationGestureHandler == null) {
return;
}
if (magnificationGestureHandler.getMode() == mAms.getMagnificationMode(displayId)) {
return;
}
magnificationGestureHandler.onDestroy();
final MagnificationGestureHandler currentMagnificationGestureHandler =
createMagnificationGestureHandler(displayId,

View File

@@ -108,6 +108,7 @@ import com.android.internal.accessibility.dialog.AccessibilityShortcutChooserAct
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IntPair;
@@ -1392,20 +1393,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (userState.mUserId != mCurrentUserId) {
return;
}
final boolean windowMagnificationEnabled = userState.isShortcutMagnificationEnabledLocked()
&& (userState.getMagnificationModeLocked()
== Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
if (!getWindowMagnificationMgr().requestConnection(windowMagnificationEnabled)) {
// New mode is invalid, so ignore and restore it.
if (fallBackMagnificationModeSettingsLocked(userState)) {
return;
}
mMainHandler.sendMessage(obtainMessage(
AccessibilityManagerService::notifyMagnificationModeChangeToInputFilter,
AccessibilityManagerService::notifyRefreshMagnificationModeToInputFilter,
this));
}
private void notifyMagnificationModeChangeToInputFilter() {
private void notifyRefreshMagnificationModeToInputFilter() {
synchronized (mLock) {
if (!mHasInputFilter) {
return;
@@ -1415,7 +1412,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
for (int i = 0; i < displays.size(); i++) {
final Display display = displays.get(i);
if (display != null) {
mInputFilter.onMagnificationModeChanged(display);
mInputFilter.refreshMagnificationMode(display);
}
}
}
@@ -1797,6 +1794,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
scheduleUpdateClientsIfNeededLocked(userState);
updateAccessibilityShortcutKeyTargetsLocked(userState);
updateAccessibilityButtonTargetsLocked(userState);
// Update the capabilities before the mode.
updateMagnificationCapabilitiesSettingsChangeLocked(userState);
updateMagnificationModeChangeSettingsLocked(userState);
}
@@ -1896,6 +1895,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
somethingChanged |= readAccessibilityButtonTargetComponentLocked(userState);
somethingChanged |= readUserRecommendedUiTimeoutSettingsLocked(userState);
somethingChanged |= readMagnificationModeLocked(userState);
somethingChanged |= readMagnificationCapabilitiesLocked(userState);
return somethingChanged;
}
@@ -2162,6 +2162,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
private void updateWindowMagnificationConnectionIfNeeded(AccessibilityUserState userState) {
final boolean connect = (userState.isShortcutMagnificationEnabledLocked()
|| userState.isDisplayMagnificationEnabledLocked())
&& (userState.getMagnificationCapabilitiesLocked()
!= Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
getWindowMagnificationMgr().requestConnection(connect);
}
/**
* Returns whether the specified user has any services that are capable of
* controlling magnification.
@@ -2787,6 +2795,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
pw.println();
pw.append("currentUserId=").append(String.valueOf(mCurrentUserId));
pw.println();
pw.append("hasWindowMagnificationConnection=").append(
String.valueOf(getWindowMagnificationMgr().isConnected()));
pw.println();
final int userCount = mUserStates.size();
for (int i = 0; i < userCount; i++) {
mUserStates.valueAt(i).dump(fd, pw, args);
@@ -3109,6 +3120,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private final Uri mMagnificationModeUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE);
private final Uri mMagnificationCapabilityUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY);
public AccessibilityContentObserver(Handler handler) {
super(handler);
}
@@ -3143,6 +3157,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mUserInteractiveUiTimeoutUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
mMagnificationModeUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
mMagnificationCapabilityUri, false, this, UserHandle.USER_ALL);
}
@Override
@@ -3199,14 +3215,50 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (readMagnificationModeLocked(userState)) {
updateMagnificationModeChangeSettingsLocked(userState);
}
} else if (mMagnificationCapabilityUri.equals(uri)) {
if (readMagnificationCapabilitiesLocked(userState)) {
updateMagnificationCapabilitiesSettingsChangeLocked(userState);
}
}
}
}
}
private void updateMagnificationCapabilitiesSettingsChangeLocked(
AccessibilityUserState userState) {
if (fallBackMagnificationModeSettingsLocked(userState)) {
updateMagnificationModeChangeSettingsLocked(userState);
}
updateWindowMagnificationConnectionIfNeeded(userState);
}
private boolean fallBackMagnificationModeSettingsLocked(AccessibilityUserState userState) {
if (userState.isValidMagnificationModeLocked()) {
return false;
}
Slog.w(LOG_TAG, "invalid magnification mode:" + userState.getMagnificationModeLocked());
final int capabilities = userState.getMagnificationCapabilitiesLocked();
userState.setMagnificationModeLocked(capabilities);
persistMagnificationModeSettingLocked(capabilities);
return true;
}
private void persistMagnificationModeSettingLocked(int mode) {
BackgroundThread.getHandler().post(() -> {
final long identity = Binder.clearCallingIdentity();
try {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, mode, mCurrentUserId);
} finally {
Binder.restoreCallingIdentity(identity);
}
});
}
//TODO: support multi-display.
/**
* Gets the magnification mode of the specified display.
*
* @param displayId The logical displayId.
* @return magnification mode. It's either ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN or
* ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW.
@@ -3229,6 +3281,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return false;
}
private boolean readMagnificationCapabilitiesLocked(AccessibilityUserState userState) {
final int capabilities = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, userState.mUserId);
if (capabilities != userState.getMagnificationCapabilitiesLocked()) {
userState.setMagnificationCapabilitiesLocked(capabilities);
return true;
}
return false;
}
@Override
public void setGestureDetectionPassthroughRegion(int displayId, Region region) {
mMainHandler.sendMessage(

View File

@@ -116,12 +116,18 @@ class AccessibilityUserState {
private int mLastSentClientState = -1;
// The magnification mode of default display.
private int mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
// The magnification capabilities used to know magnification mode could be switched.
private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
private Context mContext;
@SoftKeyboardShowMode
private int mSoftKeyboardShowMode = SHOW_MODE_AUTO;
boolean isValidMagnificationModeLocked() {
return (mMagnificationCapabilities & mMagnificationMode) != 0;
}
interface ServiceInfoChangeListener {
void onServiceInfoChangedLocked(AccessibilityUserState userState);
}
@@ -455,6 +461,9 @@ class AccessibilityUserState {
pw.append(", nonInteractiveUiTimeout=").append(String.valueOf(mNonInteractiveUiTimeout));
pw.append(", interactiveUiTimeout=").append(String.valueOf(mInteractiveUiTimeout));
pw.append(", installedServiceCount=").append(String.valueOf(mInstalledServices.size()));
pw.append(", magnificationMode=").append(String.valueOf(mMagnificationMode));
pw.append(", magnificationCapabilities=")
.append(String.valueOf(mMagnificationCapabilities));
pw.append("}");
pw.println();
pw.append(" shortcut key:{");
@@ -588,6 +597,31 @@ class AccessibilityUserState {
return mMagnificationMode;
}
/**
* Gets the magnification capabilities setting of current user.
*
* @return magnification capabilities
*
* @see Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
* @see Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
* @see Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_ALL
*/
int getMagnificationCapabilitiesLocked() {
return mMagnificationCapabilities;
}
/**
* Sets the magnification capabilities from Settings value.
*
* @see Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
* @see Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
* @see Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_ALL
*/
public void setMagnificationCapabilitiesLocked(int capabilities) {
mMagnificationCapabilities = capabilities;
}
/**
* Sets the magnification mode of default display.
* @param mode The magnification mode.

View File

@@ -41,6 +41,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
@@ -279,6 +280,11 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler
}
}
@Override
public int getMode() {
return Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
}
void clearAndTransitionToStateDetecting() {
mCurrentState = mDetectingState;
mDetectingState.clear();

View File

@@ -27,4 +27,14 @@ public abstract class MagnificationGestureHandler extends BaseEventStreamTransfo
* Called when the shortcut target is magnification.
*/
public abstract void notifyShortcutTriggered();
/**
* Indicates the magnification mode.
*
* @return the magnification mode of the handler
*
* @see android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
* @see android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
*/
public abstract int getMode();
}

View File

@@ -25,6 +25,7 @@ import static java.util.Arrays.copyOfRange;
import android.annotation.Nullable;
import android.content.Context;
import android.provider.Settings;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
@@ -162,6 +163,11 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
}
}
@Override
public int getMode() {
return Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
}
private void enableWindowMagnifier(float centerX, float centerY) {
if (DEBUG_ALL) {
Slog.i(LOG_TAG, "enableWindowMagnifier :" + centerX + ", " + centerY);

View File

@@ -114,9 +114,10 @@ public final class WindowMagnificationManager implements
*
* @return {@code true} if {@link IWindowMagnificationConnection} is available
*/
@GuardedBy("mLock")
private boolean isConnected() {
return mConnectionWrapper != null;
public boolean isConnected() {
synchronized (mLock) {
return mConnectionWrapper != null;
}
}
/**
@@ -385,8 +386,8 @@ public final class WindowMagnificationManager implements
@Override
public void binderDied() {
synchronized (mLock) {
Slog.w(TAG, "binderDied DeathRecipient :" + mExpiredDeathRecipient);
if (mExpiredDeathRecipient) {
Slog.w(TAG, "binderDied DeathRecipient is expired");
return;
}
mConnectionWrapper.unlinkToDeath(this);

View File

@@ -272,7 +272,7 @@ public class AccessibilityInputFilterTest {
EventStreamTransformation nextEventStream = getMagnificationGestureHandlerFromEventHandler(
DEFAULT_DISPLAY).getNext();
mA11yInputFilter.onMagnificationModeChanged(mDisplayList.get(DEFAULT_DISPLAY));
mA11yInputFilter.refreshMagnificationMode(mDisplayList.get(DEFAULT_DISPLAY));
MagnificationGestureHandler handler =
getMagnificationGestureHandlerFromEventHandler(DEFAULT_DISPLAY);
@@ -295,7 +295,7 @@ public class AccessibilityInputFilterTest {
EventStreamTransformation nextEventStream = getMagnificationGestureHandlerFromEventHandler(
DEFAULT_DISPLAY).getNext();
mA11yInputFilter.onMagnificationModeChanged(mDisplayList.get(DEFAULT_DISPLAY));
mA11yInputFilter.refreshMagnificationMode(mDisplayList.get(DEFAULT_DISPLAY));
MagnificationGestureHandler handler =
getMagnificationGestureHandlerFromEventHandler(DEFAULT_DISPLAY);

View File

@@ -18,7 +18,9 @@ package com.android.server.accessibility.magnification;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -52,6 +54,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
/**
* Tests for WindowMagnificationManager.
@@ -77,6 +80,13 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager = new WindowMagnificationManager(mContext, CURRENT_USER_ID);
when(mContext.getContentResolver()).thenReturn(mResolver);
doAnswer((InvocationOnMock invocation) -> {
final boolean connect = (Boolean) invocation.getArguments()[0];
mWindowMagnificationManager.setConnection(
connect ? mMockConnection.getConnection() : null);
return null;
}).when(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(anyBoolean());
mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Settings.Secure.putFloatForUser(mResolver,
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.5f,
@@ -281,6 +291,15 @@ public class WindowMagnificationManagerTest {
verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(true);
}
@Test
public void isConnected_requestConnection_expectedValue() throws RemoteException {
mWindowMagnificationManager.requestConnection(true);
assertTrue(mWindowMagnificationManager.isConnected());
mWindowMagnificationManager.requestConnection(false);
assertFalse(mWindowMagnificationManager.isConnected());
}
private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {
final int len = pointersLocation.length;