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

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

Merge "Save the user preferred shortcut on Edit A11yShortcut screen" into main

parents 83371443 f9ae13a7
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -19,10 +19,17 @@ package com.android.settings.accessibility;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.UserHandle;
import android.util.ArrayMap;

import androidx.annotation.NonNull;

import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/** Static utility methods relating to {@link PreferredShortcut} */
@@ -80,6 +87,41 @@ public final class PreferredShortcuts {
        saveToSharedPreferences(context, info);
    }

    /**
     * Update the user preferred shortcut from Settings data
     *
     * @param context    {@link Context} to access the {@link SharedPreferences}
     * @param components contains a set of {@link ComponentName} the service or activity. The
     *                   string
     *                   representation of the ComponentName should be in the format of
     *                   {@link ComponentName#flattenToString()}.
     */
    public static void updatePreferredShortcutsFromSettings(
            @NonNull Context context, @NonNull Set<String> components) {
        final Map<Integer, Set<String>> shortcutTypeToTargets = new ArrayMap<>();
        for (int shortcutType : ShortcutConstants.USER_SHORTCUT_TYPES) {
            shortcutTypeToTargets.put(
                    shortcutType,
                    ShortcutUtils.getShortcutTargetsFromSettings(
                            context, shortcutType, UserHandle.myUserId()));
        }

        for (String target : components) {
            int shortcutTypes = ShortcutConstants.UserShortcutType.DEFAULT;
            for (Map.Entry<Integer, Set<String>> entry : shortcutTypeToTargets.entrySet()) {
                if (entry.getValue().contains(target)) {
                    shortcutTypes |= entry.getKey();
                }
            }

            if (shortcutTypes != ShortcutConstants.UserShortcutType.DEFAULT) {
                final PreferredShortcut shortcut = new PreferredShortcut(
                        target, shortcutTypes);
                PreferredShortcuts.saveUserShortcutType(context, shortcut);
            }
        }
    }

    /**
     * Returns a immutable set of {@link PreferredShortcut#toString()} list from
     * SharedPreferences.
+5 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
import com.android.settings.accessibility.AccessibilitySetupWizardUtils;
import com.android.settings.accessibility.PreferredShortcuts;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -161,6 +162,9 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment {
                } else if (TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING.equals(uri)) {
                    refreshPreferenceController(TwoFingersDoubleTapShortcutOptionController.class);
                }

                PreferredShortcuts.updatePreferredShortcutsFromSettings(
                        getContext(), mShortcutTargets);
            }
        };

@@ -212,6 +216,7 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment {
        final AccessibilityManager am = getSystemService(
                AccessibilityManager.class);
        am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
        PreferredShortcuts.updatePreferredShortcutsFromSettings(getContext(), mShortcutTargets);
    }

    @Override
+45 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settings.accessibility.AccessibilityUtil;
import com.android.settings.accessibility.PreferredShortcuts;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -369,6 +370,50 @@ public class EditShortcutsPreferenceFragmentTest {
        });
    }

    @Test
    public void fragmentResumed_preferredShortcutsUpdated() {
        mFragmentScenario = createFragScenario(/* isInSuw= */ false);
        mFragmentScenario.moveToState(Lifecycle.State.RESUMED);
        // Move the fragment to the background
        mFragmentScenario.moveToState(Lifecycle.State.CREATED);
        assertThat(
                PreferredShortcuts.retrieveUserShortcutType(
                        mContext, TARGET, ShortcutConstants.UserShortcutType.SOFTWARE)
        ).isEqualTo(ShortcutConstants.UserShortcutType.SOFTWARE);
        // Update the chosen shortcut type to Volume keys while the fragment is in the background
        ShortcutUtils.optInValueToSettings(
                mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);

        mFragmentScenario.moveToState(Lifecycle.State.RESUMED);

        assertThat(
                PreferredShortcuts.retrieveUserShortcutType(
                        mContext, TARGET, ShortcutConstants.UserShortcutType.SOFTWARE)
        ).isEqualTo(ShortcutConstants.UserShortcutType.HARDWARE);
    }

    @Test
    public void onVolumeKeysShortcutSettingChanged_preferredShortcutsUpdated() {
        mFragmentScenario = createFragScenario(/* isInSuw= */ false);
        mFragmentScenario.moveToState(Lifecycle.State.CREATED);
        assertThat(
                PreferredShortcuts.retrieveUserShortcutType(
                        mContext, TARGET, ShortcutConstants.UserShortcutType.SOFTWARE)
        ).isEqualTo(ShortcutConstants.UserShortcutType.SOFTWARE);

        ShortcutUtils.optInValueToSettings(
                mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);

        // Calls onFragment so that the change to Setting is notified to its observer
        mFragmentScenario.onFragment(fragment ->
                assertThat(
                        PreferredShortcuts.retrieveUserShortcutType(
                                mContext, TARGET, ShortcutConstants.UserShortcutType.SOFTWARE)
                ).isEqualTo(ShortcutConstants.UserShortcutType.HARDWARE)
        );

    }

    private void assertLaunchSubSettingWithCurrentTargetComponents(
            String componentName, boolean isInSuw) {
        Intent intent = shadowOf(mActivity.getApplication()).getNextStartedActivity();
+110 −1
Original line number Diff line number Diff line
@@ -16,17 +16,30 @@

package com.android.settings.accessibility;

import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;

import static com.google.common.truth.Truth.assertThat;

import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.util.ShortcutUtils;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Set;

/** Tests for {@link PreferredShortcuts} */
@RunWith(AndroidJUnit4.class)
public class PreferredShortcutsTest {
@@ -39,8 +52,20 @@ public class PreferredShortcutsTest {
    private static final String CLASS_NAME_2 = PACKAGE_NAME_2 + ".test2";
    private static final ComponentName COMPONENT_NAME_2 = new ComponentName(PACKAGE_NAME_2,
            CLASS_NAME_2);
    private static final ContentResolver sContentResolver =
            ApplicationProvider.getApplicationContext().getContentResolver();

    private final Context mContext = ApplicationProvider.getApplicationContext();

    private Context mContext = ApplicationProvider.getApplicationContext();
    @Before
    public void setUp() {
        clearShortcuts();
    }

    @AfterClass
    public static void cleanUp() {
        clearShortcuts();
    }

    @Test
    public void retrieveUserShortcutType_fromSingleData_matchSavedType() {
@@ -71,4 +96,88 @@ public class PreferredShortcutsTest {

        assertThat(retrieveType).isEqualTo(type1);
    }

    @Test
    public void updatePreferredShortcutsFromSetting_magnificationWithTripleTapAndVolumeKeyShortcuts_preferredShortcutsMatches() {
        ShortcutUtils.optInValueToSettings(mContext, ShortcutConstants.UserShortcutType.HARDWARE,
                MAGNIFICATION_CONTROLLER_NAME);
        Settings.Secure.putInt(
                sContentResolver,
                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
                AccessibilityUtil.State.ON);

        PreferredShortcuts.updatePreferredShortcutsFromSettings(mContext,
                Set.of(MAGNIFICATION_CONTROLLER_NAME));
        int expectedShortcutTypes = ShortcutConstants.UserShortcutType.HARDWARE
                | ShortcutConstants.UserShortcutType.TRIPLETAP;

        assertThat(
                PreferredShortcuts.retrieveUserShortcutType(
                        mContext, MAGNIFICATION_CONTROLLER_NAME,
                        ShortcutConstants.UserShortcutType.SOFTWARE))
                .isEqualTo(expectedShortcutTypes);
    }

    @Test
    public void updatePreferredShortcutsFromSetting_magnificationWithNoActiveShortcuts_noChangesOnPreferredShortcutTypes() {
        int expectedShortcutTypes = ShortcutConstants.UserShortcutType.HARDWARE
                | ShortcutConstants.UserShortcutType.SOFTWARE;
        PreferredShortcuts.saveUserShortcutType(mContext,
                new PreferredShortcut(MAGNIFICATION_CONTROLLER_NAME, expectedShortcutTypes));


        PreferredShortcuts.updatePreferredShortcutsFromSettings(mContext,
                Set.of(MAGNIFICATION_CONTROLLER_NAME));


        assertThat(
                PreferredShortcuts.retrieveUserShortcutType(
                        mContext, MAGNIFICATION_CONTROLLER_NAME,
                        ShortcutConstants.UserShortcutType.SOFTWARE))
                .isEqualTo(expectedShortcutTypes);
    }

    @Test
    public void updatePreferredShortcutsFromSetting_multipleComponents_preferredShortcutsMatches() {
        String target1 = COLOR_INVERSION_COMPONENT_NAME.flattenToString();
        String target2 = DALTONIZER_COMPONENT_NAME.flattenToString();

        Settings.Secure.putString(sContentResolver,
                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, target1);
        Settings.Secure.putString(sContentResolver,
                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
                target1 + ShortcutConstants.SERVICES_SEPARATOR + target2);

        int target1ShortcutTypes = ShortcutConstants.UserShortcutType.HARDWARE
                | ShortcutConstants.UserShortcutType.SOFTWARE;
        int target2ShortcutTypes = ShortcutConstants.UserShortcutType.HARDWARE;

        PreferredShortcuts.updatePreferredShortcutsFromSettings(mContext, Set.of(target1, target2));

        assertThat(
                PreferredShortcuts.retrieveUserShortcutType(
                        mContext, target1,
                        ShortcutConstants.UserShortcutType.SOFTWARE))
                .isEqualTo(target1ShortcutTypes);
        assertThat(
                PreferredShortcuts.retrieveUserShortcutType(
                        mContext, target2,
                        ShortcutConstants.UserShortcutType.SOFTWARE))
                .isEqualTo(target2ShortcutTypes);
    }

    private static void clearShortcuts() {
        Settings.Secure.putString(sContentResolver,
                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "");
        Settings.Secure.putString(sContentResolver,
                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "");
        Settings.Secure.putInt(
                sContentResolver,
                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
                AccessibilityUtil.State.OFF);
        Settings.Secure.putInt(
                sContentResolver,
                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
                AccessibilityUtil.State.OFF);
    }
}