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

Commit 6d1c3789 authored by Riley Jones's avatar Riley Jones Committed by Android (Google) Code Review
Browse files

Merge "Cleaning up quick settings flag in Settings app" into main

parents cda553d5 acccaff1
Loading
Loading
Loading
Loading
+0 −149
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.accessibility;

import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;

import androidx.annotation.Nullable;
import androidx.preference.PreferenceScreen;

import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.PrimarySwitchPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnDestroy;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;

/** PrimarySwitchPreferenceController that shows quick settings tooltip on first use. */
public abstract class AccessibilityQuickSettingsPrimarySwitchPreferenceController
        extends TogglePreferenceController
        implements LifecycleObserver, OnCreate, OnDestroy, OnSaveInstanceState {
    private static final String KEY_SAVED_QS_TOOLTIP_RESHOW = "qs_tooltip_reshow";
    private final Handler mHandler;
    private PrimarySwitchPreference mPreference;
    private AccessibilityQuickSettingsTooltipWindow mTooltipWindow;
    private boolean mNeedsQSTooltipReshow = false;

    /** Returns the accessibility tile component name. */
    @Nullable
    abstract ComponentName getTileComponentName();

    /** Returns the accessibility tile tooltip content. */
    abstract CharSequence getTileTooltipContent();

    public AccessibilityQuickSettingsPrimarySwitchPreferenceController(Context context,
            String preferenceKey) {
        super(context, preferenceKey);
        mHandler = new Handler(context.getMainLooper());
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // Restore the tooltip.
        if (savedInstanceState != null) {
            if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_RESHOW)) {
                mNeedsQSTooltipReshow = savedInstanceState.getBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW);
            }
        }
    }

    @Override
    public void onDestroy() {
        mHandler.removeCallbacksAndMessages(null);
        final boolean isTooltipWindowShowing = mTooltipWindow != null && mTooltipWindow.isShowing();
        if (isTooltipWindowShowing) {
            mTooltipWindow.dismiss();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        final boolean isTooltipWindowShowing = mTooltipWindow != null && mTooltipWindow.isShowing();
        if (mNeedsQSTooltipReshow || isTooltipWindowShowing) {
            outState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
        }
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = screen.findPreference(getPreferenceKey());
        if (mNeedsQSTooltipReshow) {
            mHandler.post(this::showQuickSettingsTooltipIfNeeded);
        }
    }

    @Override
    public boolean setChecked(boolean isChecked) {
        if (isChecked) {
            showQuickSettingsTooltipIfNeeded();
        }
        return isChecked;
    }

    @Override
    public boolean isChecked() {
        return false;
    }

    @Override
    public int getAvailabilityStatus() {
        return AVAILABLE;
    }

    @Override
    public int getSliceHighlightMenuRes() {
        return R.string.menu_key_accessibility;
    }

    private void showQuickSettingsTooltipIfNeeded() {
        if (mPreference == null) {
            // Returns if no preference found by slice highlight menu.
            return;
        }

        final ComponentName tileComponentName = getTileComponentName();
        if (tileComponentName == null) {
            // Returns if no tile service assigned.
            return;
        }

        if (!mNeedsQSTooltipReshow && AccessibilityQuickSettingUtils.hasValueInSharedPreferences(
                mContext, tileComponentName)) {
            // Returns if quick settings tooltip only show once.
            return;
        }

        // TODO (287728819): Move tooltip showing to SystemUI
        // Since the lifecycle of controller is independent of that of the preference, doing
        // null check on switch is a temporary solution for the case that switch view
        // is not ready when we would like to show the tooltip.  If the switch is not ready,
        // we give up showing the tooltip and also do not reshow it in the future.
        if (mPreference.getSwitch() != null) {
            mTooltipWindow = new AccessibilityQuickSettingsTooltipWindow(mContext);
            mTooltipWindow.setup(getTileTooltipContent(),
                    R.drawable.accessibility_auto_added_qs_tooltip_illustration);
            mTooltipWindow.showAtTopCenter(mPreference.getSwitch());
        }
        AccessibilityQuickSettingUtils.optInValueToSharedPreferences(mContext, tileComponentName);
        mNeedsQSTooltipReshow = false;
    }
}
+1 −3
Original line number Diff line number Diff line
@@ -177,9 +177,7 @@ public class AccessibilitySettings extends DashboardFragment implements
        // Observe changes from accessibility selection menu
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
        if (android.view.accessibility.Flags.a11yQsShortcut()) {
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS);
        }
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_STICKY_KEYS);
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SLOW_KEYS);
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS);
+7 −35
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -114,9 +113,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted
        final List<String> shortcutFeatureKeys = new ArrayList<>();
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
        if (android.view.accessibility.Flags.a11yQsShortcut()) {
        shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS);
        }
        mSettingsContentObserver = new AccessibilitySettingsContentObserver(new Handler());
        mSettingsContentObserver.registerKeysToObserverCallback(shortcutFeatureKeys, key -> {
            updateShortcutPreferenceData();
@@ -374,38 +371,13 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted
        showQuickSettingsTooltipIfNeeded();
    }

    /**
     * @deprecated made obsolete by quick settings rollout.
     *
     * (TODO 367414968: finish removal.)
     */
    @Deprecated
    private void showQuickSettingsTooltipIfNeeded() {
        if (android.view.accessibility.Flags.a11yQsShortcut()) {
            // Don't show Quick Settings tooltip
            return;
        }
        final ComponentName tileComponentName = getTileComponentName();
        if (tileComponentName == null) {
            // Returns if no tile service assigned.
            return;
        }

        if (!mNeedsQSTooltipReshow && AccessibilityQuickSettingUtils.hasValueInSharedPreferences(
                getContext(), tileComponentName)) {
            // Returns if quick settings tooltip only show once.
            return;
        }

        final CharSequence content = getTileTooltipContent(mNeedsQSTooltipType);
        if (TextUtils.isEmpty(content)) {
            // Returns if no content of tile tooltip assigned.
            return;
        }

        final int imageResId = mNeedsQSTooltipType == QuickSettingsTooltipType.GUIDE_TO_EDIT
                ? R.drawable.accessibility_qs_tooltip_illustration
                : R.drawable.accessibility_auto_added_qs_tooltip_illustration;
        mTooltipWindow = new AccessibilityQuickSettingsTooltipWindow(getContext());
        mTooltipWindow.setup(content, imageResId);
        mTooltipWindow.showAtTopCenter(getView());
        AccessibilityQuickSettingUtils.optInValueToSharedPreferences(getContext(),
                tileComponentName);
        mNeedsQSTooltipReshow = false;
    }

    /**
+0 −4
Original line number Diff line number Diff line
@@ -496,10 +496,6 @@ public final class AccessibilityShortcutsTutorial {
            if ((shortcutTypes & shortcutType) == 0) {
                continue;
            }
            if ((shortcutTypes & QUICK_SETTINGS) == QUICK_SETTINGS
                    && !android.view.accessibility.Flags.a11yQsShortcut()) {
                continue;
            }
            tutorialPages.add(
                    createShortcutTutorialPage(
                            context, shortcutType, buttonMode, featureName, inSetupWizard));
+69 −130
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.StringJoiner;

/** Provides utility methods to accessibility settings only. */
public final class AccessibilityUtil {
@@ -203,10 +202,15 @@ public final class AccessibilityUtil {
     * @param context       The current context.
     * @param shortcutTypes A combination of {@link UserShortcutType}.
     * @param componentName The component name that need to be opted in Settings.
     *
     * @deprecated use
     * {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)} instead.
     *
     * (TODO 367414968: finish removal.)
     */
    @Deprecated
    static void optInAllValuesToSettings(Context context, int shortcutTypes,
            @NonNull ComponentName componentName) {
        if (android.view.accessibility.Flags.a11yQsShortcut()) {
        AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
        if (a11yManager != null) {
            a11yManager.enableShortcutsForTargets(
@@ -216,16 +220,6 @@ public final class AccessibilityUtil {
                    UserHandle.myUserId()
            );
        }

            return;
        }

        if ((shortcutTypes & SOFTWARE) == SOFTWARE) {
            optInValueToSettings(context, SOFTWARE, componentName);
        }
        if (((shortcutTypes & HARDWARE) == HARDWARE)) {
            optInValueToSettings(context, HARDWARE, componentName);
        }
    }

    /**
@@ -234,11 +228,16 @@ public final class AccessibilityUtil {
     * @param context       The current context.
     * @param shortcutType  The preferred shortcut type user selected.
     * @param componentName The component name that need to be opted in Settings.
     *
     * @deprecated use
     * {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)} instead.
     *
     * (TODO 367414968: finish removal.)
     */
    @Deprecated
    @VisibleForTesting
    static void optInValueToSettings(Context context, @UserShortcutType int shortcutType,
            @NonNull ComponentName componentName) {
        if (android.view.accessibility.Flags.a11yQsShortcut()) {
        AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
        if (a11yManager != null) {
            a11yManager.enableShortcutsForTargets(
@@ -248,24 +247,6 @@ public final class AccessibilityUtil {
                    UserHandle.myUserId()
            );
        }
            return;
        }

        final String targetKey = convertKeyFromSettings(shortcutType);
        final String targetString = Settings.Secure.getString(context.getContentResolver(),
                targetKey);

        if (hasValueInSettings(context, shortcutType, componentName)) {
            return;
        }

        final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
        if (!TextUtils.isEmpty(targetString)) {
            joiner.add(targetString);
        }
        joiner.add(componentName.flattenToString());

        Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString());
    }

    /**
@@ -275,10 +256,15 @@ public final class AccessibilityUtil {
     * @param context       The current context.
     * @param shortcutTypes A combination of {@link UserShortcutType}.
     * @param componentName The component name that need to be opted out from Settings.
     *
     * @deprecated use
     * {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)} instead.
     *
     * (TODO 367414968: finish removal.)
     */
    @Deprecated
    static void optOutAllValuesFromSettings(Context context, int shortcutTypes,
            @NonNull ComponentName componentName) {
        if (android.view.accessibility.Flags.a11yQsShortcut()) {
        AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
        if (a11yManager != null) {
            a11yManager.enableShortcutsForTargets(
@@ -288,15 +274,6 @@ public final class AccessibilityUtil {
                    UserHandle.myUserId()
            );
        }
            return;
        }

        if ((shortcutTypes & SOFTWARE) == SOFTWARE) {
            optOutValueFromSettings(context, SOFTWARE, componentName);
        }
        if (((shortcutTypes & HARDWARE) == HARDWARE)) {
            optOutValueFromSettings(context, HARDWARE, componentName);
        }
    }

    /**
@@ -305,11 +282,16 @@ public final class AccessibilityUtil {
     * @param context       The current context.
     * @param shortcutType  The preferred shortcut type user selected.
     * @param componentName The component name that need to be opted out from Settings.
     *
     * @deprecated use
     * {@link AccessibilityManager#enableShortcutsForTargets(boolean, int, Set, int)} instead.
     *
     * (TODO 367414968: finish removal.)
     */
    @Deprecated
    @VisibleForTesting
    static void optOutValueFromSettings(Context context, @UserShortcutType int shortcutType,
            @NonNull ComponentName componentName) {
        if (android.view.accessibility.Flags.a11yQsShortcut()) {
        AccessibilityManager a11yManager = context.getSystemService(AccessibilityManager.class);
        if (a11yManager != null) {
            a11yManager.enableShortcutsForTargets(
@@ -319,28 +301,6 @@ public final class AccessibilityUtil {
                    UserHandle.myUserId()
            );
        }
            return;
        }

        final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
        final String targetKey = convertKeyFromSettings(shortcutType);
        final String targetString = Settings.Secure.getString(context.getContentResolver(),
                targetKey);

        if (TextUtils.isEmpty(targetString)) {
            return;
        }

        sStringColonSplitter.setString(targetString);
        while (sStringColonSplitter.hasNext()) {
            final String name = sStringColonSplitter.next();
            if (TextUtils.isEmpty(name) || (componentName.flattenToString()).equals(name)) {
                continue;
            }
            joiner.add(name);
        }

        Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString());
    }

    /**
@@ -354,11 +314,6 @@ public final class AccessibilityUtil {
    static boolean hasValuesInSettings(Context context, int shortcutTypes,
            @NonNull ComponentName componentName) {
        for (int shortcutType : AccessibilityUtil.SHORTCUTS_ORDER_IN_UI) {
            if (!android.view.accessibility.Flags.a11yQsShortcut()) {
                if ((shortcutType & QUICK_SETTINGS) == QUICK_SETTINGS) {
                    continue;
                }
            }
            if (!android.provider.Flags.a11yStandaloneGestureEnabled()) {
                if ((shortcutType & GESTURE) == GESTURE) {
                    continue;
@@ -379,15 +334,16 @@ public final class AccessibilityUtil {
     * @param shortcutType The preferred shortcut type user selected.
     * @param componentName The component name that need to be checked existed in Settings.
     * @return {@code true} if componentName existed in Settings.
     *
     * @deprecated use
     * {@link ShortcutUtils#isShortcutContained(Context, int, String)} instead.
     *
     * (TODO 367414968: finish removal.)
     */
    @Deprecated
    @VisibleForTesting
    static boolean hasValueInSettings(Context context, @UserShortcutType int shortcutType,
            @NonNull ComponentName componentName) {
        if (!android.view.accessibility.Flags.a11yQsShortcut()
                && (shortcutType & QUICK_SETTINGS) == QUICK_SETTINGS) {
            return false;
        }

        return ShortcutUtils.getShortcutTargetsFromSettings(
                context, shortcutType, UserHandle.myUserId()
        ).contains(componentName.flattenToString());
@@ -405,11 +361,6 @@ public final class AccessibilityUtil {
            @NonNull ComponentName componentName) {
        int shortcutTypes = DEFAULT;
        for (int shortcutType : AccessibilityUtil.SHORTCUTS_ORDER_IN_UI) {
            if (!android.view.accessibility.Flags.a11yQsShortcut()) {
                if ((shortcutType & QUICK_SETTINGS) == QUICK_SETTINGS) {
                    continue;
                }
            }
            if (!android.provider.Flags.a11yStandaloneGestureEnabled()) {
                if ((shortcutType & GESTURE) == GESTURE) {
                    continue;
@@ -428,25 +379,17 @@ public final class AccessibilityUtil {
     *
     * @param shortcutType The shortcut type.
     * @return Mapping key in Settings.
     *
     * @deprecated use
     * {@link ShortcutUtils#convertToKey(int)} instead.
     *
     * (TODO 367414968: finish removal.)
     */
    @Deprecated
    static String convertKeyFromSettings(@UserShortcutType int shortcutType) {
        if (android.view.accessibility.Flags.a11yQsShortcut()) {
        return ShortcutUtils.convertToKey(shortcutType);
    }

        switch (shortcutType) {
            case SOFTWARE:
                return Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
            case HARDWARE:
                return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
            case TRIPLETAP:
                return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
            default:
                throw new IllegalArgumentException(
                        "Unsupported userShortcutType " + shortcutType);
        }
    }

    /**
     * Gets the width of the screen.
     *
@@ -521,10 +464,6 @@ public final class AccessibilityUtil {
        final List<CharSequence> list = new ArrayList<>();

        for (int shortcutType : AccessibilityUtil.SHORTCUTS_ORDER_IN_UI) {
            if (!android.view.accessibility.Flags.a11yQsShortcut()
                    && (shortcutType & QUICK_SETTINGS) == QUICK_SETTINGS) {
                continue;
            }
            if (!android.provider.Flags.a11yStandaloneGestureEnabled()
                    && (shortcutType & GESTURE) == GESTURE) {
                continue;
Loading