2 * Copyright (C) 2018 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.android.settings.accessibility;
18 import static android.os.Vibrator.VibrationIntensity;
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;
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;
39 import java.util.ArrayList;
40 import java.util.Comparator;
41 import java.util.List;
45 * Fragment for changing vibration settings.
47 public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragment {
48 private static final String TAG = "VibrationPreferenceFragment";
51 final static String KEY_INTENSITY_OFF = "intensity_off";
53 final static String KEY_INTENSITY_LOW = "intensity_low";
55 final static String KEY_INTENSITY_MEDIUM = "intensity_medium";
57 final static String KEY_INTENSITY_HIGH = "intensity_high";
59 private final Map<String, VibrationIntensityCandidateInfo> mCandidates;
60 private final SettingsObserver mSettingsObserver;
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();
84 public void onAttach(Context context) {
85 super.onAttach(context);
86 mSettingsObserver.register();
90 public void onDetach() {
92 mSettingsObserver.unregister();
96 * Get the setting string of the vibration intensity setting this preference is dealing with.
98 protected abstract String getVibrationIntensitySetting();
101 * Get the default intensity for the desired setting.
103 protected abstract int getDefaultVibrationIntensity();
106 * When a new vibration intensity is selected by the user.
108 protected void onVibrationIntensitySelected(int intensity) { }
111 * Play a vibration effect with intensity just selected by user
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());
122 * Get the AudioAttributes usage for vibration preview.
124 protected int getPreviewVibrationAudioAttributesUsage() {
125 return AudioAttributes.USAGE_UNKNOWN;
129 protected List<? extends CandidateInfo> getCandidates() {
130 List<VibrationIntensityCandidateInfo> candidates = new ArrayList<>(mCandidates.values());
132 Comparator.comparing(VibrationIntensityCandidateInfo::getIntensity).reversed());
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();
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 + ")!");
155 Settings.System.putInt(getContext().getContentResolver(),
156 getVibrationIntensitySetting(), candidate.getIntensity());
157 onVibrationIntensitySelected(candidate.getIntensity());
162 class VibrationIntensityCandidateInfo extends CandidateInfo {
164 private int mLabelId;
166 private int mIntensity;
168 public VibrationIntensityCandidateInfo(String key, int labelId, int intensity) {
169 super(true /* enabled */);
172 mIntensity = intensity;
176 public CharSequence loadLabel() {
177 return getContext().getString(mLabelId);
181 public Drawable loadIcon() {
186 public String getKey() {
190 public int getIntensity() {
195 private class SettingsObserver extends ContentObserver {
196 public SettingsObserver() {
197 super(new Handler());
200 public void register() {
201 getContext().getContentResolver().registerContentObserver(
202 Settings.System.getUriFor(getVibrationIntensitySetting()), false, this);
205 public void unregister() {
206 getContext().getContentResolver().unregisterContentObserver(this);
210 public void onChange(boolean selfChange, Uri uri) {
212 playVibrationPreview();