2 * Copyright (C) 2014 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.
17 package com.android.settings.notification;
19 import android.content.Context;
20 import android.content.Intent;
21 import android.os.Bundle;
22 import android.os.Handler;
23 import android.os.Looper;
24 import android.os.Message;
25 import android.os.UserHandle;
26 import android.preference.SeekBarVolumizer;
27 import android.provider.SearchIndexableResource;
28 import android.support.v7.preference.Preference;
29 import android.text.TextUtils;
31 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
32 import com.android.settings.R;
33 import com.android.settings.RingtonePreference;
34 import com.android.settings.dashboard.DashboardFragment;
35 import com.android.settings.search.BaseSearchIndexProvider;
36 import com.android.settingslib.core.AbstractPreferenceController;
37 import com.android.settingslib.core.lifecycle.Lifecycle;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.List;
43 public class SoundSettings extends DashboardFragment {
44 private static final String TAG = "SoundSettings";
46 private static final String KEY_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
47 private static final String SELECTED_PREFERENCE_KEY = "selected_preference";
48 private static final int REQUEST_CODE = 200;
50 private static final int SAMPLE_CUTOFF = 2000; // manually cap sample playback at 2 seconds
52 private final VolumePreferenceCallback mVolumeCallback = new VolumePreferenceCallback();
53 private final H mHandler = new H();
55 private RingtonePreference mRequestPreference;
58 public void onAttach(Context context) {
59 super.onAttach(context);
60 mProgressiveDisclosureMixin.setTileLimit(1);
64 public int getMetricsCategory() {
65 return MetricsEvent.SOUND;
69 public void onCreate(Bundle savedInstanceState) {
70 super.onCreate(savedInstanceState);
71 if (savedInstanceState != null) {
72 String selectedPreference = savedInstanceState.getString(SELECTED_PREFERENCE_KEY, null);
73 if (!TextUtils.isEmpty(selectedPreference)) {
74 mRequestPreference = (RingtonePreference) findPreference(selectedPreference);
80 protected int getHelpResource() {
81 return R.string.help_url_sound;
85 public void onPause() {
87 mVolumeCallback.stopSample();
91 public boolean onPreferenceTreeClick(Preference preference) {
92 if (preference instanceof RingtonePreference) {
93 mRequestPreference = (RingtonePreference) preference;
94 mRequestPreference.onPrepareRingtonePickerIntent(mRequestPreference.getIntent());
95 startActivityForResultAsUser(
96 mRequestPreference.getIntent(),
99 UserHandle.of(mRequestPreference.getUserId()));
102 return super.onPreferenceTreeClick(preference);
106 protected String getLogTag() {
111 protected int getPreferenceScreenResId() {
112 return R.xml.sound_settings;
116 protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
117 return buildPreferenceControllers(context, this, mVolumeCallback, getLifecycle());
121 public void onActivityResult(int requestCode, int resultCode, Intent data) {
122 if (mRequestPreference != null) {
123 mRequestPreference.onActivityResult(requestCode, resultCode, data);
124 mRequestPreference = null;
129 public void onSaveInstanceState(Bundle outState) {
130 super.onSaveInstanceState(outState);
131 if (mRequestPreference != null) {
132 outState.putString(SELECTED_PREFERENCE_KEY, mRequestPreference.getKey());
138 final class VolumePreferenceCallback implements VolumeSeekBarPreference.Callback {
139 private SeekBarVolumizer mCurrent;
142 public void onSampleStarting(SeekBarVolumizer sbv) {
143 if (mCurrent != null && mCurrent != sbv) {
144 mCurrent.stopSample();
147 if (mCurrent != null) {
148 mHandler.removeMessages(H.STOP_SAMPLE);
149 mHandler.sendEmptyMessageDelayed(H.STOP_SAMPLE, SAMPLE_CUTOFF);
154 public void onStreamValueChanged(int stream, int progress) {
158 public void stopSample() {
159 if (mCurrent != null) {
160 mCurrent.stopSample();
168 private final class H extends Handler {
169 private static final int STOP_SAMPLE = 1;
172 super(Looper.getMainLooper());
176 public void handleMessage(Message msg) {
179 mVolumeCallback.stopSample();
185 private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
186 SoundSettings fragment, VolumeSeekBarPreference.Callback callback,
187 Lifecycle lifecycle) {
188 final List<AbstractPreferenceController> controllers = new ArrayList<>();
189 controllers.add(new ZenModePreferenceController(context));
190 controllers.add(new EmergencyBroadcastPreferenceController(
191 context, KEY_CELL_BROADCAST_SETTINGS));
192 controllers.add(new VibrateWhenRingPreferenceController(context));
195 controllers.add(new AlarmVolumePreferenceController(context, callback, lifecycle));
196 controllers.add(new MediaVolumePreferenceController(context, callback, lifecycle));
198 new NotificationVolumePreferenceController(context, callback, lifecycle));
199 controllers.add(new RingVolumePreferenceController(context, callback, lifecycle));
201 // === Phone & notification ringtone ===
202 controllers.add(new PhoneRingtonePreferenceController(context));
203 controllers.add(new AlarmRingtonePreferenceController(context));
204 controllers.add(new NotificationRingtonePreferenceController(context));
206 // === Work Sound Settings ===
207 controllers.add(new WorkSoundPreferenceController(context, fragment, lifecycle));
209 // === Other Sound Settings ===
210 controllers.add(new DialPadTonePreferenceController(context, fragment, lifecycle));
211 controllers.add(new ScreenLockSoundPreferenceController(context, fragment, lifecycle));
212 controllers.add(new ChargingSoundPreferenceController(context, fragment, lifecycle));
213 controllers.add(new DockingSoundPreferenceController(context, fragment, lifecycle));
214 controllers.add(new TouchSoundPreferenceController(context, fragment, lifecycle));
215 controllers.add(new VibrateOnTouchPreferenceController(context, fragment, lifecycle));
216 controllers.add(new DockAudioMediaPreferenceController(context, fragment, lifecycle));
217 controllers.add(new BootSoundPreferenceController(context));
218 controllers.add(new EmergencyTonePreferenceController(context, fragment, lifecycle));
225 public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
226 new BaseSearchIndexProvider() {
228 public List<SearchIndexableResource> getXmlResourcesToIndex(
229 Context context, boolean enabled) {
230 final SearchIndexableResource sir = new SearchIndexableResource(context);
231 sir.xmlResId = R.xml.sound_settings;
232 return Arrays.asList(sir);
236 public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
237 return buildPreferenceControllers(context, null /* fragment */,
238 null /* callback */, null /* lifecycle */);
242 public List<String> getNonIndexableKeys(Context context) {
243 List<String> keys = super.getNonIndexableKeys(context);
245 keys.add((new ZenModePreferenceController(context)).getPreferenceKey());
246 keys.add(ZenModeSettings.KEY_VISUAL_SETTINGS);
247 keys.add(KEY_CELL_BROADCAST_SETTINGS);
252 // === Work Sound Settings ===
254 void enableWorkSync() {
255 final WorkSoundPreferenceController workSoundController =
256 getPreferenceController(WorkSoundPreferenceController.class);
257 if (workSoundController != null) {
258 workSoundController.enableWorkSync();