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

Commit 6b872bb8 authored by Chun-Ku Lin's avatar Chun-Ku Lin Committed by Android (Google) Code Review
Browse files

Merge "Add `enableShortcutTypeForTargets` method in the A11yManager" into main

parents 3034ebdc 750d750f
Loading
Loading
Loading
Loading
+77 −1
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
@@ -67,6 +68,8 @@ import android.view.View;
import android.view.accessibility.AccessibilityEvent.EventType;

import com.android.internal.R;
import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IntPair;

@@ -78,6 +81,8 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;

/**
@@ -189,11 +194,13 @@ public final class AccessibilityManager {
     * <p>Note: Keep in sync with {@link #SHORTCUT_TYPES}.</p>
     * @hide
     */
    // TODO(b/323686675): reuse the one defined in ShortcutConstants
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(value = {
            // LINT.IfChange(shortcut_type_intdef)
            ACCESSIBILITY_BUTTON,
            ACCESSIBILITY_SHORTCUT_KEY
            ACCESSIBILITY_SHORTCUT_KEY,
            UserShortcutType.QUICK_SETTINGS,
            // LINT.ThenChange(:shortcut_type_array)
    })
    public @interface ShortcutType {}
@@ -207,6 +214,7 @@ public final class AccessibilityManager {
            // LINT.IfChange(shortcut_type_array)
            ACCESSIBILITY_BUTTON,
            ACCESSIBILITY_SHORTCUT_KEY,
            UserShortcutType.QUICK_SETTINGS,
            // LINT.ThenChange(:shortcut_type_intdef)
    };

@@ -1630,6 +1638,74 @@ public final class AccessibilityManager {
        }
    }

    /**
     * Turns on or off a shortcut type of the accessibility features. The shortcut type is one
     * of the shortcut defined in the {@link ShortcutConstants.USER_SHORTCUT_TYPES}.
     *
     * @throws SecurityException if the app does not hold the
     *                           {@link Manifest.permission#MANAGE_ACCESSIBILITY} permission
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
    public void enableShortcutsForTargets(boolean enable,
            @UserShortcutType int shortcutTypes, @NonNull Set<String> targets,
            @UserIdInt int userId) {
        final IAccessibilityManager service;
        synchronized (mLock) {
            service = getServiceLocked();
            if (service == null) {
                return;
            }
        }
        try {
            service.enableShortcutsForTargets(
                    enable, shortcutTypes, targets.stream().toList(), userId);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Returns accessibility feature's component and the provided tile map. This includes the
     * TileService provided by the AccessibilityService or Accessibility Activity and the tile
     * component provided by the framework's feature.
     *
     * @return a map of a feature's component name, and its provided tile's component name. The
     * returned map's keys and values are not null. If a feature doesn't provide a tile, it won't
     * have an entry in this map.
     * @hide
     * @see ShortcutConstants.A11Y_FEATURE_TO_FRAMEWORK_TILE
     */
    @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
    @NonNull
    public Map<ComponentName, ComponentName> getA11yFeatureToTileMap(@UserIdInt int userId) {
        final IAccessibilityManager service;
        Map<ComponentName, ComponentName> a11yFeatureToTileMap = new ArrayMap<>();
        synchronized (mLock) {
            service = getServiceLocked();
            if (service == null) {
                return a11yFeatureToTileMap;
            }
        }
        try {
            Bundle a11yFeatureToTile = service.getA11yFeatureToTileMap(userId);
            for (String key : a11yFeatureToTile.keySet()) {
                ComponentName feature = ComponentName.unflattenFromString(key);
                if (feature == null) {
                    continue;
                }
                ComponentName tileService = a11yFeatureToTile.getParcelable(key,
                        ComponentName.class);
                if (tileService != null) {
                    a11yFeatureToTileMap.put(feature, tileService);
                }
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return a11yFeatureToTileMap;
    }

    /**
     * Register the provided {@link RemoteAction} with the given actionId
     * <p>
+7 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.accessibilityservice.IAccessibilityServiceConnection;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.content.ComponentName;
import android.content.pm.ParceledListSlice;
import android.os.Bundle;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -143,4 +144,10 @@ interface IAccessibilityManager {

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE)")
    oneway void notifyQuickSettingsTilesChanged(int userId, in List<ComponentName> tileComponentNames);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY)")
    oneway void enableShortcutsForTargets(boolean enable, int shortcutTypes, in List<String> shortcutTargets, int userId);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY)")
    Bundle getA11yFeatureToTileMap(int userId);
}
+57 −4
Original line number Diff line number Diff line
@@ -16,10 +16,23 @@

package com.android.internal.accessibility.common;

import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_TILE_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_TILE_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.FONT_SIZE_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.FONT_SIZE_TILE_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_TILE_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_TILE_SERVICE_COMPONENT_NAME;

import android.annotation.IntDef;
import android.content.ComponentName;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Map;

/**
 * Collection of common constants for accessibility shortcut.
@@ -44,6 +57,10 @@ public final class ShortcutConstants {
     * choose accessibility shortcut as preferred shortcut.
     * {@code TRIPLETAP} for displaying specifying magnification to be toggled via quickly
     * tapping screen 3 times as preferred shortcut.
     * {@code TWOFINGER_DOUBLETAP} for displaying specifying magnification to be toggled via
     * quickly tapping screen 2 times with two fingers as preferred shortcut.
     * {@code QUICK_SETTINGS} for displaying specifying the accessibility services or features which
     * choose Quick Settings as preferred shortcut.
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
@@ -51,12 +68,18 @@ public final class ShortcutConstants {
            UserShortcutType.SOFTWARE,
            UserShortcutType.HARDWARE,
            UserShortcutType.TRIPLETAP,
            UserShortcutType.TWOFINGER_DOUBLETAP,
            UserShortcutType.QUICK_SETTINGS,
    })
    public @interface UserShortcutType {
        int DEFAULT = 0;
        int SOFTWARE = 1; // 1 << 0
        int HARDWARE = 2; // 1 << 1
        int TRIPLETAP = 4; // 1 << 2
        // LINT.IfChange(shortcut_type_intdef)
        int SOFTWARE = 1 << 0;
        int HARDWARE = 1 << 1;
        int TRIPLETAP = 1 << 2;
        int TWOFINGER_DOUBLETAP = 1 << 3;
        int QUICK_SETTINGS = 1 << 4;
        // LINT.ThenChange(:shortcut_type_array)
    }

    /**
@@ -64,9 +87,13 @@ public final class ShortcutConstants {
     * non-default IntDef types.
     */
    public static final int[] USER_SHORTCUT_TYPES = {
            // LINT.IfChange(shortcut_type_array)
            UserShortcutType.SOFTWARE,
            UserShortcutType.HARDWARE,
            UserShortcutType.TRIPLETAP
            UserShortcutType.TRIPLETAP,
            UserShortcutType.TWOFINGER_DOUBLETAP,
            UserShortcutType.QUICK_SETTINGS,
            // LINT.ThenChange(:shortcut_type_intdef)
    };


@@ -109,4 +136,30 @@ public final class ShortcutConstants {
        int LAUNCH = 0;
        int EDIT = 1;
    }

    /**
     * Annotation for different FAB shortcut type's menu size
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            FloatingMenuSize.UNKNOWN,
            FloatingMenuSize.SMALL,
            FloatingMenuSize.LARGE,
    })
    public @interface FloatingMenuSize {
        int UNKNOWN = -1;
        int SMALL = 0;
        int LARGE = 1;
    }

    /**
     * A map of a11y feature to its qs tile component
     */
    public static final Map<ComponentName, ComponentName> A11Y_FEATURE_TO_FRAMEWORK_TILE = Map.of(
            COLOR_INVERSION_COMPONENT_NAME, COLOR_INVERSION_TILE_COMPONENT_NAME,
            DALTONIZER_COMPONENT_NAME, DALTONIZER_TILE_COMPONENT_NAME,
            ONE_HANDED_COMPONENT_NAME, ONE_HANDED_TILE_COMPONENT_NAME,
            REDUCE_BRIGHT_COLORS_COMPONENT_NAME, REDUCE_BRIGHT_COLORS_TILE_SERVICE_COMPONENT_NAME,
            FONT_SIZE_COMPONENT_NAME, FONT_SIZE_TILE_COMPONENT_NAME
    );
}
+7 −0
Original line number Diff line number Diff line
@@ -70,6 +70,13 @@ public final class AccessibilityUtils {
    public @interface A11yTextChangeType {
    }

    /** Denotes the accessibility enabled status */
    @Retention(RetentionPolicy.SOURCE)
    public @interface State {
        int OFF = 0;
        int ON = 1;
    }

    /** Specifies no content has been changed for accessibility. */
    public static final int NONE = 0;
    /** Specifies some readable sequence has been changed. */
+17 −3
Original line number Diff line number Diff line
@@ -56,7 +56,10 @@ public final class ShortcutUtils {
     * @param context      The current context.
     * @param shortcutType The preferred shortcut type user selected.
     * @param componentId  The component id that need to be opted in Settings.
     * @deprecated Use
     * {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)}
     */
    @Deprecated
    public static void optInValueToSettings(Context context, @UserShortcutType int shortcutType,
            @NonNull String componentId) {
        final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
@@ -83,7 +86,11 @@ public final class ShortcutUtils {
     * @param context The current context.
     * @param shortcutType The preferred shortcut type user selected.
     * @param componentId The component id that need to be opted out of Settings.
     *
     * @deprecated Use
     * {@link AccessibilityManager#enableShortcutForTargets(boolean, int, Set, int)}
     */
    @Deprecated
    public static void optOutValueFromSettings(
            Context context, @UserShortcutType int shortcutType, @NonNull String componentId) {
        final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
@@ -166,6 +173,10 @@ public final class ShortcutUtils {
                return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
            case UserShortcutType.TRIPLETAP:
                return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
            case UserShortcutType.TWOFINGER_DOUBLETAP:
                return Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED;
            case UserShortcutType.QUICK_SETTINGS:
                return Settings.Secure.ACCESSIBILITY_QS_TARGETS;
            default:
                throw new IllegalArgumentException(
                        "Unsupported user shortcut type: " + type);
@@ -252,10 +263,13 @@ public final class ShortcutUtils {
     * If you just want to know the current state, you can use
     * {@link AccessibilityManager#getAccessibilityShortcutTargets(int)}
     */
    @NonNull
    public static Set<String> getShortcutTargetsFromSettings(
            Context context, @UserShortcutType int shortcutType, int userId) {
        final String targetKey = convertToKey(shortcutType);
        if (Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED.equals(targetKey)) {
        if (Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED.equals(targetKey)
                || Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED
                .equals(targetKey)) {
            boolean magnificationEnabled = Settings.Secure.getIntForUser(
                    context.getContentResolver(), targetKey, /* def= */ 0, userId) == 1;
            return magnificationEnabled ? Set.of(MAGNIFICATION_CONTROLLER_NAME)
Loading