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

Commit da0cc3e8 authored by Alan Viverette's avatar Alan Viverette
Browse files

Add accessibility display adjustments to Quick Settings

BUG: 9057596
Change-Id: I5bb4513c3b3c59d1948ff5e8df2416ec6448534b
parent 410d4e33
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -496,6 +496,12 @@
    <string name="quick_settings_brightness_dialog_title">Brightness</string>
    <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
    <string name="quick_settings_brightness_dialog_auto_brightness_label">AUTO</string>
    <!-- QuickSettings: Color inversion mode [CHAR LIMIT=NONE] -->
    <string name="quick_settings_inversion_label">Color inversion mode</string>
    <!-- QuickSettings: Enhanced contrast mode [CHAR LIMIT=NONE] -->
    <string name="quick_settings_contrast_label">Enhanced contrast mode</string>
    <!-- QuickSettings: Color correction mode [CHAR LIMIT=NONE] -->
    <string name="quick_settings_color_space_label">Color correction mode</string>


    <!-- Glyph to be overlaid atop the battery when the level is extremely low. Do not translate. -->
+135 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.app.admin.DevicePolicyManager;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
@@ -84,6 +85,7 @@ class QuickSettings {
    static final boolean DEBUG_GONE_TILES = false;
    private static final String TAG = "QuickSettings";
    public static final boolean SHOW_IME_TILE = false;
    public static final boolean SHOW_ACCESSIBILITY_TILES = true;

    public static final boolean LONG_PRESS_TOGGLES = true;

@@ -399,6 +401,35 @@ class QuickSettings {
                new QuickSettingsModel.BasicRefreshCallback(settingsTile));
        parent.addView(settingsTile);
        mDynamicSpannedTiles.add(settingsTile);

        if (SHOW_ACCESSIBILITY_TILES) {
            // Color inversion tile
            final SystemSettingTile inversionTile = new SystemSettingTile(mContext);
            inversionTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
                    SystemSettingTile.TYPE_SECURE);
            inversionTile.setFragment("Settings$AccessibilityInversionSettingsActivity");
            mModel.addInversionTile(inversionTile, inversionTile.getRefreshCallback());
            parent.addView(inversionTile);
            mDynamicSpannedTiles.add(inversionTile);

            // Contrast enhancement tile
            final SystemSettingTile contrastTile = new SystemSettingTile(mContext);
            contrastTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED,
                    SystemSettingTile.TYPE_SECURE);
            contrastTile.setFragment("Settings$AccessibilityContrastSettingsActivity");
            mModel.addContrastTile(contrastTile, contrastTile.getRefreshCallback());
            parent.addView(contrastTile);
            mDynamicSpannedTiles.add(contrastTile);

            // Color space adjustment tile
            final SystemSettingTile colorSpaceTile = new SystemSettingTile(mContext);
            colorSpaceTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
                    SystemSettingTile.TYPE_SECURE);
            colorSpaceTile.setFragment("Settings$AccessibilityDaltonizerSettingsActivity");
            mModel.addColorSpaceTile(colorSpaceTile, colorSpaceTile.getRefreshCallback());
            parent.addView(colorSpaceTile);
            mDynamicSpannedTiles.add(colorSpaceTile);
        }
    }

    private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
@@ -933,4 +964,108 @@ class QuickSettings {
            }
        }
    }

    /**
     * Quick Setting tile that represents a secure setting. This type of tile
     * can toggle a URI within Settings.Secure on click and launch a Settings
     * fragment on long-click.
     */
    public class SystemSettingTile extends QuickSettingsBasicTile {
        private static final int TYPE_GLOBAL = 0;
        private static final int TYPE_SECURE = 1;
        private static final int TYPE_SYSTEM = 2;

        private final QuickSettingsModel.BasicRefreshCallback mRefreshCallback;

        private String mFragment;
        private String mName;
        private int mType;

        public SystemSettingTile(Context context) {
            super(context);

            mRefreshCallback = new QuickSettingsModel.BasicRefreshCallback(this);
            mRefreshCallback.setShowWhenEnabled(true);
        }

        @Override
        public boolean performLongClick() {
            if (mFragment != null) {
                collapsePanels();

                final Intent intent = new Intent();
                intent.setComponent(new ComponentName(
                        "com.android.settings", "com.android.settings." + mFragment));
                startSettingsActivity(intent);
                return true;
            }
            return false;
        }

        @Override
        public boolean performClick() {
            if (mName != null) {
                collapsePanels();

                final ContentResolver cr = mContext.getContentResolver();
                switch (mType) {
                    case TYPE_GLOBAL: {
                        final boolean enable = Settings.Global.getInt(cr, mName, 0) == 0;
                        Settings.Global.putInt(cr, mName, enable ? 1 : 0);
                    } break;
                    case TYPE_SECURE: {
                        final boolean enable = Settings.Secure.getIntForUser(
                                cr, mName, 0, UserHandle.USER_CURRENT) == 0;
                        Settings.Secure.putIntForUser(
                                cr, mName, enable ? 1 : 0, UserHandle.USER_CURRENT);
                    } break;
                    case TYPE_SYSTEM: {
                        final boolean enable = Settings.System.getIntForUser(
                                cr, mName, 0, UserHandle.USER_CURRENT) == 0;
                        Settings.System.putIntForUser(
                                cr, mName, enable ? 1 : 0, UserHandle.USER_CURRENT);
                    } break;
                }
                return true;
            }
            return false;
        }

        /**
         * Specifies the fragment within the com.android.settings package to
         * launch when this tile is long-clicked.
         *
         * @param fragment a fragment name within the com.android.settings
         *            package
         */
        public void setFragment(String fragment) {
            mFragment = fragment;
            setLongClickable(fragment != null);
        }

        /**
         * Specifies the setting name and type to toggle when this tile is
         * clicked.
         *
         * @param name a setting name
         * @param type the type of setting, one of:
         *            <ul>
         *            <li>{@link #TYPE_GLOBAL}
         *            <li>{@link #TYPE_SECURE}
         *            <li>{@link #TYPE_SYSTEM}
         *            </ul>
         */
        public void setUri(String name, int type) {
            mName = name;
            mType = type;
            setClickable(mName != null);
        }

        /**
         * @return the refresh callback for this tile
         */
        public QuickSettingsModel.BasicRefreshCallback getRefreshCallback() {
            return mRefreshCallback;
        }
    }
}
+207 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
import android.hardware.display.WifiDisplayStatus;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
@@ -90,6 +91,19 @@ class QuickSettingsModel implements BluetoothStateChangeCallback,
    static class BrightnessState extends State {
        boolean autoBrightness;
    }
    static class InversionState extends State {
        boolean toggled;
        int type;
    }
    static class ContrastState extends State {
        boolean toggled;
        float contrast;
        float brightness;
    }
    static class ColorSpaceState extends State {
        boolean toggled;
        int type;
    }
    public static class BluetoothState extends State {
        boolean connected = false;
        String stateContentDescription;
@@ -198,12 +212,96 @@ class QuickSettingsModel implements BluetoothStateChangeCallback,
        }
    }

    /** ContentObserver to watch display inversion */
    private class DisplayInversionObserver extends ContentObserver {
        public DisplayInversionObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            onInversionChanged();
        }

        public void startObserving() {
            final ContentResolver cr = mContext.getContentResolver();
            cr.unregisterContentObserver(this);
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
                    false, this, mUserTracker.getCurrentUserId());
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED),
                    false, this, mUserTracker.getCurrentUserId());
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION),
                    false, this, mUserTracker.getCurrentUserId());
        }
    }

    /** ContentObserver to watch display contrast */
    private class DisplayContrastObserver extends ContentObserver {
        public DisplayContrastObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            onContrastChanged();
        }

        public void startObserving() {
            final ContentResolver cr = mContext.getContentResolver();
            cr.unregisterContentObserver(this);
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED),
                    false, this, mUserTracker.getCurrentUserId());
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED),
                    false, this, mUserTracker.getCurrentUserId());
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST),
                    false, this, mUserTracker.getCurrentUserId());
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS),
                    false, this, mUserTracker.getCurrentUserId());
        }
    }

    /** ContentObserver to watch display color space adjustment */
    private class DisplayColorSpaceObserver extends ContentObserver {
        public DisplayColorSpaceObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            onColorSpaceChanged();
        }

        public void startObserving() {
            final ContentResolver cr = mContext.getContentResolver();
            cr.unregisterContentObserver(this);
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
                    false, this, mUserTracker.getCurrentUserId());
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED),
                    false, this, mUserTracker.getCurrentUserId());
            cr.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER),
                    false, this, mUserTracker.getCurrentUserId());
        }
    }

    private final Context mContext;
    private final Handler mHandler;
    private final CurrentUserTracker mUserTracker;
    private final NextAlarmObserver mNextAlarmObserver;
    private final BugreportObserver mBugreportObserver;
    private final BrightnessObserver mBrightnessObserver;
    private final DisplayInversionObserver mInversionObserver;
    private final DisplayContrastObserver mContrastObserver;
    private final DisplayColorSpaceObserver mColorSpaceObserver;

    private final boolean mHasMobileData;

@@ -259,6 +357,18 @@ class QuickSettingsModel implements BluetoothStateChangeCallback,
    private RefreshCallback mBrightnessCallback;
    private BrightnessState mBrightnessState = new BrightnessState();

    private QuickSettingsTileView mInversionTile;
    private RefreshCallback mInversionCallback;
    private InversionState mInversionState = new InversionState();

    private QuickSettingsTileView mContrastTile;
    private RefreshCallback mContrastCallback;
    private ContrastState mContrastState = new ContrastState();

    private QuickSettingsTileView mColorSpaceTile;
    private RefreshCallback mColorSpaceCallback;
    private ColorSpaceState mColorSpaceState = new ColorSpaceState();

    private QuickSettingsTileView mBugreportTile;
    private RefreshCallback mBugreportCallback;
    private State mBugreportState = new State();
@@ -277,10 +387,17 @@ class QuickSettingsModel implements BluetoothStateChangeCallback,
        mContext = context;
        mHandler = new Handler();
        mUserTracker = new CurrentUserTracker(mContext) {
            @Override
            public void onUserSwitched(int newUserId) {
                mBrightnessObserver.startObserving();
                mInversionObserver.startObserving();
                mContrastObserver.startObserving();
                mColorSpaceObserver.startObserving();
                onRotationLockChanged();
                onBrightnessLevelChanged();
                onInversionChanged();
                onContrastChanged();
                onColorSpaceChanged();
                onNextAlarmChanged();
                onBugreportChanged();
            }
@@ -292,6 +409,12 @@ class QuickSettingsModel implements BluetoothStateChangeCallback,
        mBugreportObserver.startObserving();
        mBrightnessObserver = new BrightnessObserver(mHandler);
        mBrightnessObserver.startObserving();
        mInversionObserver = new DisplayInversionObserver(mHandler);
        mInversionObserver.startObserving();
        mContrastObserver = new DisplayContrastObserver(mHandler);
        mContrastObserver.startObserving();
        mColorSpaceObserver = new DisplayColorSpaceObserver(mHandler);
        mColorSpaceObserver.startObserving();

        ConnectivityManager cm = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -762,6 +885,90 @@ class QuickSettingsModel implements BluetoothStateChangeCallback,
        onBrightnessLevelChanged();
    }

    // Color inversion
    void addInversionTile(QuickSettingsTileView view, RefreshCallback cb) {
        mInversionTile = view;
        mInversionCallback = cb;
        onInversionChanged();
    }
    public void onInversionChanged() {
        final Resources res = mContext.getResources();
        final ContentResolver cr = mContext.getContentResolver();
        final int currentUserId = mUserTracker.getCurrentUserId();
        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED, 0,
                currentUserId) == 1;
        final boolean enabled = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, currentUserId) == 1;
        final int type = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION, 0, currentUserId);
        mInversionState.enabled = quickSettingEnabled;
        mInversionState.toggled = enabled;
        mInversionState.type = type;
        // TODO: Add real icon assets.
        mInversionState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
                : R.drawable.ic_qs_bluetooth_off;
        mInversionState.label = res.getString(R.string.quick_settings_inversion_label);
        mInversionCallback.refreshView(mInversionTile, mInversionState);
    }

    // Contrast enhancement
    void addContrastTile(QuickSettingsTileView view, RefreshCallback cb) {
        mContrastTile = view;
        mContrastCallback = cb;
        onContrastChanged();
    }
    public void onContrastChanged() {
        final Resources res = mContext.getResources();
        final ContentResolver cr = mContext.getContentResolver();
        final int currentUserId = mUserTracker.getCurrentUserId();
        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED, 0,
                currentUserId) == 1;
        final boolean enabled = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED, 0, currentUserId) == 1;
        final float contrast = Settings.Secure.getFloatForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST, 1, currentUserId);
        final float brightness = Settings.Secure.getFloatForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS, 0, currentUserId);
        mContrastState.enabled = quickSettingEnabled;
        mContrastState.toggled = enabled;
        mContrastState.contrast = contrast;
        mContrastState.brightness = brightness;
        // TODO: Add real icon assets.
        mContrastState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
                : R.drawable.ic_qs_bluetooth_off;
        mContrastState.label = res.getString(R.string.quick_settings_contrast_label);
        mContrastCallback.refreshView(mContrastTile, mContrastState);
    }

    // Color space adjustment
    void addColorSpaceTile(QuickSettingsTileView view, RefreshCallback cb) {
        mColorSpaceTile = view;
        mColorSpaceCallback = cb;
        onColorSpaceChanged();
    }
    public void onColorSpaceChanged() {
        final Resources res = mContext.getResources();
        final ContentResolver cr = mContext.getContentResolver();
        final int currentUserId = mUserTracker.getCurrentUserId();
        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED, 0,
                currentUserId) == 1;
        final boolean enabled = Settings.Secure.getIntForUser(cr,
                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, currentUserId) == 1;
        final int type = Settings.Secure.getIntForUser(
                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, 0, currentUserId);
        mColorSpaceState.enabled = quickSettingEnabled;
        mColorSpaceState.toggled = enabled;
        mColorSpaceState.type = type;
        // TODO: Add real icon assets.
        mColorSpaceState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
                : R.drawable.ic_qs_bluetooth_off;
        mColorSpaceState.label = res.getString(R.string.quick_settings_color_space_label);
        mColorSpaceCallback.refreshView(mColorSpaceTile, mColorSpaceState);
    }

    // SSL CA Cert warning.
    public void addSslCaCertWarningTile(QuickSettingsTileView view, RefreshCallback cb) {
        mSslCaCertWarningTile = view;