Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d1743c3 authored by ryanlwlin's avatar ryanlwlin
Browse files

Support Magnification capabilities Settings value

To have more flexibility and have consistency with legacy behavior,
Uses can choose single/multiple modes in settings.

To support it, we have the following behavior
1. Switching magnification mode is allowed only when the capabilities
is all.
2. If the capabilities doesn't support currnet magnification mode,
the magnification mode will be fell back.
3. Set window magnification connection to null if the magnification
settings is not turned on or the magnification capabilities is
full-screen.

Bug: 155965892
Test: atest WindowMagnificationManagerTest
Test: manual test: select one or two magnification modes to see
      the behaviour.
Change-Id: If32e2a038e64ed7a7bab9ec5a3d444b542d30161
parent cc640dd5
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -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,
+73 −9
Original line number Diff line number Diff line
@@ -106,6 +106,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;
@@ -1386,20 +1387,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;
@@ -1409,7 +1406,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);
                }
            }
        }
@@ -1791,6 +1788,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        scheduleUpdateClientsIfNeededLocked(userState);
        updateAccessibilityShortcutKeyTargetsLocked(userState);
        updateAccessibilityButtonTargetsLocked(userState);
        // Update the capabilities before the mode.
        updateMagnificationCapabilitiesSettingsChangeLocked(userState);
        updateMagnificationModeChangeSettingsLocked(userState);
    }

@@ -1890,6 +1889,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        somethingChanged |= readAccessibilityButtonTargetComponentLocked(userState);
        somethingChanged |= readUserRecommendedUiTimeoutSettingsLocked(userState);
        somethingChanged |= readMagnificationModeLocked(userState);
        somethingChanged |= readMagnificationCapabilitiesLocked(userState);
        return somethingChanged;
    }

@@ -2156,6 +2156,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.
@@ -2765,6 +2773,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);
@@ -3087,6 +3098,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);
        }
@@ -3121,6 +3135,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
@@ -3177,14 +3193,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.
@@ -3207,6 +3259,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(
+34 −0
Original line number Diff line number Diff line
@@ -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.
+6 −0
Original line number Diff line number Diff line
@@ -40,6 +40,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;
@@ -278,6 +279,11 @@ class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler
        }
    }

    @Override
    public int getMode() {
        return Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
    }

    void clearAndTransitionToStateDetecting() {
        mCurrentState = mDetectingState;
        mDetectingState.clear();
+10 −0
Original line number Diff line number Diff line
@@ -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();
}
Loading