1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.accessibility;
18 
19 import android.content.ContentResolver;
20 import android.content.Context;
21 import android.database.ContentObserver;
22 import android.graphics.drawable.Drawable;
23 import android.os.Handler;
24 import android.os.Looper;
25 import android.provider.Settings;
26 import android.view.accessibility.AccessibilityManager;
27 
28 import androidx.annotation.VisibleForTesting;
29 import androidx.preference.PreferenceScreen;
30 
31 import com.android.settings.R;
32 import com.android.settings.core.BasePreferenceController;
33 import com.android.settingslib.core.lifecycle.LifecycleObserver;
34 import com.android.settingslib.core.lifecycle.events.OnPause;
35 import com.android.settingslib.core.lifecycle.events.OnResume;
36 import com.android.settingslib.widget.IllustrationPreference;
37 
38 /** Preference controller that controls the preview effect in accessibility button page. */
39 public class AccessibilityButtonPreviewPreferenceController extends BasePreferenceController
40         implements LifecycleObserver, OnResume, OnPause {
41 
42     private static final int SMALL_SIZE = 0;
43     private static final float DEFAULT_OPACITY = 0.55f;
44     private static final int DEFAULT_SIZE = 0;
45 
46     private final ContentResolver mContentResolver;
47     @VisibleForTesting
48     final ContentObserver mContentObserver;
49     @VisibleForTesting
50     IllustrationPreference mIllustrationPreference;
51 
52     private AccessibilityManager.TouchExplorationStateChangeListener
53             mTouchExplorationStateChangeListener;
54 
AccessibilityButtonPreviewPreferenceController(Context context, String preferenceKey)55     public AccessibilityButtonPreviewPreferenceController(Context context, String preferenceKey) {
56         super(context, preferenceKey);
57         mContentResolver = context.getContentResolver();
58         mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
59             @Override
60             public void onChange(boolean selfChange) {
61                 updatePreviewPreference();
62             }
63         };
64         mTouchExplorationStateChangeListener = isTouchExplorationEnabled -> {
65             updatePreviewPreference();
66         };
67     }
68 
69     @Override
getAvailabilityStatus()70     public int getAvailabilityStatus() {
71         return AVAILABLE;
72     }
73 
74     @Override
displayPreference(PreferenceScreen screen)75     public void displayPreference(PreferenceScreen screen) {
76         super.displayPreference(screen);
77         mIllustrationPreference = screen.findPreference(getPreferenceKey());
78 
79         updatePreviewPreference();
80     }
81 
82     @Override
onResume()83     public void onResume() {
84         final AccessibilityManager am = mContext.getSystemService(AccessibilityManager.class);
85         am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
86 
87         mContentResolver.registerContentObserver(
88                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE),
89                 /* notifyForDescendants= */ false, mContentObserver);
90         mContentResolver.registerContentObserver(
91                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE),
92                 /* notifyForDescendants= */ false, mContentObserver);
93         mContentResolver.registerContentObserver(
94                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY),
95                 /* notifyForDescendants= */ false, mContentObserver);
96     }
97 
98     @Override
onPause()99     public void onPause() {
100         final AccessibilityManager am = mContext.getSystemService(AccessibilityManager.class);
101         am.removeTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
102 
103         mContentResolver.unregisterContentObserver(mContentObserver);
104     }
105 
updatePreviewPreference()106     private void updatePreviewPreference() {
107         if (AccessibilityUtil.isFloatingMenuEnabled(mContext)) {
108             final int size = Settings.Secure.getInt(mContentResolver,
109                     Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, DEFAULT_SIZE);
110             // The alpha range when set on a drawable is [0-255]
111             final int opacity = (int) (Settings.Secure.getFloat(mContentResolver,
112                     Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, DEFAULT_OPACITY) * 255);
113             final int floatingMenuIconId = (size == SMALL_SIZE)
114                     ? R.drawable.accessibility_shortcut_type_fab_size_small_preview
115                     : R.drawable.accessibility_shortcut_type_fab_size_large_preview;
116             Drawable fabDrawable = mContext.getDrawable(floatingMenuIconId);
117             fabDrawable.setAlpha(opacity);
118             mIllustrationPreference.setImageDrawable(fabDrawable);
119         } else if (AccessibilityUtil.isGestureNavigateEnabled(mContext)) {
120             mIllustrationPreference.setImageDrawable(mContext.getDrawable(
121                     AccessibilityUtil.isTouchExploreEnabled(mContext)
122                             ? R.drawable.accessibility_shortcut_type_gesture_touch_explore_on
123                             : R.drawable.accessibility_shortcut_type_gesture));
124         } else {
125             mIllustrationPreference.setImageDrawable(
126                     mContext.getDrawable(R.drawable.accessibility_shortcut_type_navbar));
127         }
128     }
129 }
130