OSDN Git Service

93fd7f5c8dab58e294b13e5855f81581253c6fdd
[android-x86/packages-apps-Settings.git] / src / com / android / settings / accessibility / VibrationPreferenceFragment.java
1 /*
2  * Copyright (C) 2018 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 package com.android.settings.accessibility;
17
18 import static android.os.Vibrator.VibrationIntensity;
19
20 import android.support.annotation.VisibleForTesting;
21 import android.content.Context;
22 import android.database.ContentObserver;
23 import android.graphics.drawable.Drawable;
24 import android.media.AudioAttributes;
25 import android.net.Uri;
26 import android.os.Handler;
27 import android.os.VibrationEffect;
28 import android.os.Vibrator;
29 import android.provider.Settings;
30 import android.util.ArrayMap;
31 import android.util.Log;
32
33 import com.android.internal.accessibility.AccessibilityShortcutController;
34 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
35 import com.android.settings.R;
36 import com.android.settings.widget.RadioButtonPickerFragment;
37 import com.android.settingslib.widget.CandidateInfo;
38
39 import java.util.ArrayList;
40 import java.util.Comparator;
41 import java.util.List;
42 import java.util.Map;
43
44 /**
45  * Fragment for changing vibration settings.
46  */
47 public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragment {
48     private static final String TAG = "VibrationPreferenceFragment";
49
50     @VisibleForTesting
51     final static String KEY_INTENSITY_OFF = "intensity_off";
52     @VisibleForTesting
53     final static String KEY_INTENSITY_LOW = "intensity_low";
54     @VisibleForTesting
55     final static String KEY_INTENSITY_MEDIUM = "intensity_medium";
56     @VisibleForTesting
57     final static String KEY_INTENSITY_HIGH = "intensity_high";
58
59     private final Map<String, VibrationIntensityCandidateInfo> mCandidates;
60     private final SettingsObserver mSettingsObserver;
61
62     public VibrationPreferenceFragment() {
63         mCandidates = new ArrayMap<>();
64         mCandidates.put(KEY_INTENSITY_OFF,
65                 new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
66                     R.string.accessibility_vibration_intensity_off,
67                     Vibrator.VIBRATION_INTENSITY_OFF));
68         mCandidates.put(KEY_INTENSITY_LOW,
69                 new VibrationIntensityCandidateInfo(KEY_INTENSITY_LOW,
70                     R.string.accessibility_vibration_intensity_low,
71                     Vibrator.VIBRATION_INTENSITY_LOW));
72         mCandidates.put(KEY_INTENSITY_MEDIUM,
73                 new VibrationIntensityCandidateInfo(KEY_INTENSITY_MEDIUM,
74                     R.string.accessibility_vibration_intensity_medium,
75                     Vibrator.VIBRATION_INTENSITY_MEDIUM));
76         mCandidates.put(KEY_INTENSITY_HIGH,
77                 new VibrationIntensityCandidateInfo(KEY_INTENSITY_HIGH,
78                     R.string.accessibility_vibration_intensity_high,
79                     Vibrator.VIBRATION_INTENSITY_HIGH));
80         mSettingsObserver = new SettingsObserver();
81     }
82
83     @Override
84     public void onAttach(Context context) {
85         super.onAttach(context);
86         mSettingsObserver.register();
87     }
88
89     @Override
90     public void onDetach() {
91         super.onDetach();
92         mSettingsObserver.unregister();
93     }
94
95     /**
96      * Get the setting string of the vibration intensity setting this preference is dealing with.
97      */
98     protected abstract String getVibrationIntensitySetting();
99
100     /**
101      * Get the default intensity for the desired setting.
102      */
103     protected abstract int getDefaultVibrationIntensity();
104
105     /**
106      * When a new vibration intensity is selected by the user.
107      */
108     protected void onVibrationIntensitySelected(int intensity) { }
109
110     /**
111      * Play a vibration effect with intensity just selected by user
112      */
113     protected void playVibrationPreview() {
114         Vibrator vibrator = getContext().getSystemService(Vibrator.class);
115         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
116         AudioAttributes.Builder builder = new AudioAttributes.Builder();
117         builder.setUsage(getPreviewVibrationAudioAttributesUsage());
118         vibrator.vibrate(effect, builder.build());
119     }
120
121     /**
122      * Get the AudioAttributes usage for vibration preview.
123      */
124     protected int getPreviewVibrationAudioAttributesUsage() {
125         return AudioAttributes.USAGE_UNKNOWN;
126     }
127
128     @Override
129     protected List<? extends CandidateInfo> getCandidates() {
130         List<VibrationIntensityCandidateInfo> candidates = new ArrayList<>(mCandidates.values());
131         candidates.sort(
132                 Comparator.comparing(VibrationIntensityCandidateInfo::getIntensity).reversed());
133         return candidates;
134     }
135
136     @Override
137     protected String getDefaultKey() {
138         final int vibrationIntensity = Settings.System.getInt(getContext().getContentResolver(),
139                 getVibrationIntensitySetting(), getDefaultVibrationIntensity());
140         for (VibrationIntensityCandidateInfo candidate : mCandidates.values()) {
141             if (candidate.getIntensity() == vibrationIntensity) {
142                 return candidate.getKey();
143             }
144         }
145         return null;
146     }
147
148     @Override
149     protected boolean setDefaultKey(String key) {
150         VibrationIntensityCandidateInfo candidate = mCandidates.get(key);
151         if (candidate == null) {
152             Log.e(TAG, "Tried to set unknown intensity (key=" + key + ")!");
153             return false;
154         }
155         Settings.System.putInt(getContext().getContentResolver(),
156                 getVibrationIntensitySetting(), candidate.getIntensity());
157         onVibrationIntensitySelected(candidate.getIntensity());
158         return true;
159     }
160
161     @VisibleForTesting
162     class VibrationIntensityCandidateInfo extends CandidateInfo {
163         private String mKey;
164         private int mLabelId;
165         @VibrationIntensity
166         private int mIntensity;
167
168         public VibrationIntensityCandidateInfo(String key, int labelId, int intensity) {
169             super(true /* enabled */);
170             mKey = key;
171             mLabelId = labelId;
172             mIntensity = intensity;
173         }
174
175         @Override
176         public CharSequence loadLabel() {
177             return getContext().getString(mLabelId);
178         }
179
180         @Override
181         public Drawable loadIcon() {
182             return null;
183         }
184
185         @Override
186         public String getKey() {
187             return mKey;
188         }
189
190         public int getIntensity() {
191             return mIntensity;
192         }
193     }
194
195     private class SettingsObserver extends ContentObserver {
196         public SettingsObserver() {
197             super(new Handler());
198         }
199
200         public void register() {
201             getContext().getContentResolver().registerContentObserver(
202                     Settings.System.getUriFor(getVibrationIntensitySetting()), false, this);
203         }
204
205         public void unregister() {
206             getContext().getContentResolver().unregisterContentObserver(this);
207         }
208
209         @Override
210         public void onChange(boolean selfChange, Uri uri) {
211             updateCandidates();
212             playVibrationPreview();
213         }
214     }
215 }