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.os.Handler; 23 import android.os.Looper; 24 import android.provider.Settings; 25 import android.util.ArrayMap; 26 27 import androidx.annotation.IntDef; 28 import androidx.annotation.VisibleForTesting; 29 import androidx.preference.ListPreference; 30 import androidx.preference.Preference; 31 import androidx.preference.PreferenceScreen; 32 33 import com.android.settings.R; 34 import com.android.settings.core.BasePreferenceController; 35 import com.android.settingslib.core.lifecycle.LifecycleObserver; 36 import com.android.settingslib.core.lifecycle.events.OnPause; 37 import com.android.settingslib.core.lifecycle.events.OnResume; 38 39 import com.google.common.primitives.Ints; 40 41 import java.lang.annotation.Retention; 42 import java.lang.annotation.RetentionPolicy; 43 44 /** Preference controller that controls the preferred size in accessibility button page. */ 45 public class FloatingMenuSizePreferenceController extends BasePreferenceController 46 implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause { 47 48 private final ContentResolver mContentResolver; 49 @VisibleForTesting 50 final ContentObserver mContentObserver; 51 52 @VisibleForTesting 53 ListPreference mPreference; 54 55 private final ArrayMap<String, String> mValueTitleMap = new ArrayMap<>(); 56 private int mDefaultSize; 57 58 @Retention(RetentionPolicy.SOURCE) 59 @IntDef({ 60 Size.SMALL, 61 Size.LARGE, 62 }) 63 @VisibleForTesting 64 @interface Size { 65 int SMALL = 0; 66 int LARGE = 1; 67 } 68 FloatingMenuSizePreferenceController(Context context, String preferenceKey)69 public FloatingMenuSizePreferenceController(Context context, String preferenceKey) { 70 super(context, preferenceKey); 71 mContentResolver = context.getContentResolver(); 72 mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { 73 @Override 74 public void onChange(boolean selfChange) { 75 updateAvailabilityStatus(); 76 } 77 }; 78 79 initValueTitleMap(); 80 } 81 82 @Override getAvailabilityStatus()83 public int getAvailabilityStatus() { 84 return AccessibilityUtil.isFloatingMenuEnabled(mContext) 85 ? AVAILABLE : DISABLED_DEPENDENT_SETTING; 86 } 87 88 @Override displayPreference(PreferenceScreen screen)89 public void displayPreference(PreferenceScreen screen) { 90 super.displayPreference(screen); 91 92 mPreference = screen.findPreference(getPreferenceKey()); 93 } 94 95 @Override onPreferenceChange(Preference preference, Object newValue)96 public boolean onPreferenceChange(Preference preference, Object newValue) { 97 final ListPreference listPreference = (ListPreference) preference; 98 final Integer value = Ints.tryParse((String) newValue); 99 if (value != null) { 100 putAccessibilityFloatingMenuSize(value); 101 updateState(listPreference); 102 } 103 return true; 104 } 105 106 @Override updateState(Preference preference)107 public void updateState(Preference preference) { 108 super.updateState(preference); 109 final ListPreference listPreference = (ListPreference) preference; 110 111 listPreference.setValue(String.valueOf(getAccessibilityFloatingMenuSize(mDefaultSize))); 112 } 113 114 @Override onResume()115 public void onResume() { 116 mContentResolver.registerContentObserver( 117 Settings.Secure.getUriFor( 118 Settings.Secure.ACCESSIBILITY_BUTTON_MODE), /* notifyForDescendants= */ 119 false, mContentObserver); 120 121 } 122 123 @Override onPause()124 public void onPause() { 125 mContentResolver.unregisterContentObserver(mContentObserver); 126 } 127 updateAvailabilityStatus()128 private void updateAvailabilityStatus() { 129 mPreference.setEnabled(AccessibilityUtil.isFloatingMenuEnabled(mContext)); 130 } 131 initValueTitleMap()132 private void initValueTitleMap() { 133 if (mValueTitleMap.size() == 0) { 134 final String[] values = mContext.getResources().getStringArray( 135 R.array.accessibility_button_size_selector_values); 136 final String[] titles = mContext.getResources().getStringArray( 137 R.array.accessibility_button_size_selector_titles); 138 final int mapSize = values.length; 139 140 mDefaultSize = Integer.parseInt(values[0]); 141 for (int i = 0; i < mapSize; i++) { 142 mValueTitleMap.put(values[i], titles[i]); 143 } 144 } 145 } 146 147 @Size getAccessibilityFloatingMenuSize(@ize int defaultValue)148 private int getAccessibilityFloatingMenuSize(@Size int defaultValue) { 149 return Settings.Secure.getInt(mContentResolver, 150 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, defaultValue); 151 } 152 putAccessibilityFloatingMenuSize(@ize int value)153 private void putAccessibilityFloatingMenuSize(@Size int value) { 154 Settings.Secure.putInt(mContentResolver, 155 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, value); 156 } 157 } 158