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

Commit 6fcd7dd7 authored by Ryan Lin's avatar Ryan Lin Committed by Android (Google) Code Review
Browse files

Merge "Disable volume-key-accessibility shortcut upon exiting setup wizard" into tm-dev

parents fa0b6921 7efe0b9b
Loading
Loading
Loading
Loading
+106 −10
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.accessibility;

import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;

@@ -107,6 +108,8 @@ public class AccessibilityShortcutController {

    private final Context mContext;
    private final Handler mHandler;
    private final UserSetupCompleteObserver  mUserSetupCompleteObserver;

    private AlertDialog mAlertDialog;
    private boolean mIsShortcutEnabled;
    private boolean mEnabledOnLockScreen;
@@ -114,11 +117,11 @@ public class AccessibilityShortcutController {

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            DialogStaus.NOT_SHOWN,
            DialogStaus.SHOWN,
            DialogStatus.NOT_SHOWN,
            DialogStatus.SHOWN,
    })
    /** Denotes the user shortcut type. */
    private @interface DialogStaus {
    private @interface DialogStatus {
        int NOT_SHOWN = 0;
        int SHOWN  = 1;
    }
@@ -163,6 +166,7 @@ public class AccessibilityShortcutController {
        mContext = context;
        mHandler = handler;
        mUserId = initialUserId;
        mUserSetupCompleteObserver = new UserSetupCompleteObserver(handler, initialUserId);

        // Keep track of state of shortcut settings
        final ContentObserver co = new ContentObserver(handler) {
@@ -188,6 +192,7 @@ public class AccessibilityShortcutController {
    public void setCurrentUser(int currentUserId) {
        mUserId = currentUserId;
        onSettingsChanged();
        mUserSetupCompleteObserver.onUserSwitched(currentUserId);
    }

    /**
@@ -206,7 +211,7 @@ public class AccessibilityShortcutController {
        final ContentResolver cr = mContext.getContentResolver();
        // Enable the shortcut from the lockscreen by default if the dialog has been shown
        final int dialogAlreadyShown = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.NOT_SHOWN,
                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.NOT_SHOWN,
                mUserId);
        mEnabledOnLockScreen = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
@@ -222,7 +227,7 @@ public class AccessibilityShortcutController {
        final ContentResolver cr = mContext.getContentResolver();
        final int userId = ActivityManager.getCurrentUser();
        final int dialogAlreadyShown = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.NOT_SHOWN,
                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.NOT_SHOWN,
                userId);
        // Play a notification vibration
        Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
@@ -234,7 +239,7 @@ public class AccessibilityShortcutController {
            vibrator.vibrate(vibePattern, -1, VIBRATION_ATTRIBUTES);
        }

        if (dialogAlreadyShown == 0) {
        if (dialogAlreadyShown == DialogStatus.NOT_SHOWN) {
            // The first time, we show a warning rather than toggle the service to give the user a
            // chance to turn off this feature before stuff gets enabled.
            mAlertDialog = createShortcutWarningDialog(userId);
@@ -250,7 +255,7 @@ public class AccessibilityShortcutController {
            w.setAttributes(attr);
            mAlertDialog.show();
            Settings.Secure.putIntForUser(
                    cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.SHOWN,
                    cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.SHOWN,
                    userId);
        } else {
            playNotificationTone();
@@ -320,13 +325,13 @@ public class AccessibilityShortcutController {
                            // If canceled, treat as if the dialog has never been shown
                            Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                    Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
                                    DialogStaus.NOT_SHOWN, userId);
                                    DialogStatus.NOT_SHOWN, userId);
                        })
                .setOnCancelListener((DialogInterface d) -> {
                    // If canceled, treat as if the dialog has never been shown
                    Settings.Secure.putIntForUser(mContext.getContentResolver(),
                            Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
                            DialogStaus.NOT_SHOWN, userId);
                            DialogStatus.NOT_SHOWN, userId);
                })
                .create();
        return alertDialog;
@@ -398,7 +403,7 @@ public class AccessibilityShortcutController {
        AccessibilityManager accessibilityManager =
                mFrameworkObjectProvider.getAccessibilityManagerInstance(mContext);
        return accessibilityManager.getEnabledAccessibilityServiceList(
                AccessibilityServiceInfo.FEEDBACK_ALL_MASK).contains(serviceInfo);
                FEEDBACK_ALL_MASK).contains(serviceInfo);
    }

    private boolean hasFeatureLeanback() {
@@ -559,6 +564,97 @@ public class AccessibilityShortcutController {
        }
    }

    private class UserSetupCompleteObserver extends ContentObserver {

        private boolean mIsRegistered = false;
        private int mUserId;

        /**
         * Creates a content observer.
         *
         * @param handler The handler to run {@link #onChange} on, or null if none.
         * @param userId The current user id.
         */
        UserSetupCompleteObserver(Handler handler, int userId) {
            super(handler);
            mUserId = userId;
            if (!isUserSetupComplete()) {
                registerObserver();
            }
        }

        private boolean isUserSetupComplete() {
            return Settings.Secure.getIntForUser(mContext.getContentResolver(),
                    Settings.Secure.USER_SETUP_COMPLETE, 0, mUserId) == 1;
        }

        private void registerObserver() {
            if (mIsRegistered) {
                return;
            }
            mContext.getContentResolver().registerContentObserver(
                    Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE),
                    false, this, mUserId);
            mIsRegistered = true;
        }

        @Override
        public void onChange(boolean selfChange) {
            if (isUserSetupComplete()) {
                unregisterObserver();
                setEmptyShortcutTargetIfNeeded();
            }
        }

        private void unregisterObserver() {
            if (!mIsRegistered) {
                return;
            }
            mContext.getContentResolver().unregisterContentObserver(this);
            mIsRegistered = false;
        }

        /**
         * Sets empty shortcut target if shortcut targets is not assigned and there is no any
         * enabled service matching the default target after the setup wizard completed.
         *
         */
        private void setEmptyShortcutTargetIfNeeded() {
            final ContentResolver contentResolver = mContext.getContentResolver();

            final String shortcutTargets = Settings.Secure.getStringForUser(contentResolver,
                    Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, mUserId);
            if (shortcutTargets != null) {
                return;
            }

            final String defaultShortcutTarget = mContext.getString(
                    R.string.config_defaultAccessibilityService);
            final List<AccessibilityServiceInfo> enabledServices =
                    mFrameworkObjectProvider.getAccessibilityManagerInstance(
                            mContext).getEnabledAccessibilityServiceList(FEEDBACK_ALL_MASK);
            for (int i = enabledServices.size() - 1; i >= 0; i--) {
                if (TextUtils.equals(defaultShortcutTarget, enabledServices.get(i).getId())) {
                    return;
                }
            }

            Settings.Secure.putStringForUser(contentResolver,
                    Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "", mUserId);
        }

        void onUserSwitched(int userId) {
            if (mUserId == userId) {
                return;
            }
            unregisterObserver();
            mUserId = userId;
            if (!isUserSetupComplete()) {
                registerObserver();
            }
        }
    }

    /**
     * Immutable class to hold info about framework features that can be controlled by shortcut
     */