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.core.PreferenceController;
35 import com.android.settings.core.lifecycle.Lifecycle;
36 import com.android.settings.dashboard.DashboardFragment;
37 import com.android.settings.search.BaseSearchIndexProvider;
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 SELECTED_PREFERENCE_KEY = "selected_preference";
47 private static final int REQUEST_CODE = 200;
49 private static final int SAMPLE_CUTOFF = 2000; // manually cap sample playback at 2 seconds
51 private final VolumePreferenceCallback mVolumeCallback = new VolumePreferenceCallback();
52 private final H mHandler = new H();
54 private RingtonePreference mRequestPreference;
57 public void onAttach(Context context) {
58 super.onAttach(context);
59 mProgressiveDisclosureMixin.setTileLimit(6);
63 public int getMetricsCategory() {
64 return MetricsEvent.SOUND;
68 public void onCreate(Bundle savedInstanceState) {
69 super.onCreate(savedInstanceState);
70 if (savedInstanceState != null) {
71 String selectedPreference = savedInstanceState.getString(SELECTED_PREFERENCE_KEY, null);
72 if (!TextUtils.isEmpty(selectedPreference)) {
73 mRequestPreference = (RingtonePreference) findPreference(selectedPreference);
79 protected int getHelpResource() {
80 return R.string.help_url_sound;
84 public void onPause() {
86 mVolumeCallback.stopSample();
90 public boolean onPreferenceTreeClick(Preference preference) {
91 if (preference instanceof RingtonePreference) {
92 mRequestPreference = (RingtonePreference) preference;
93 mRequestPreference.onPrepareRingtonePickerIntent(mRequestPreference.getIntent());
94 startActivityForResultAsUser(
95 mRequestPreference.getIntent(),
98 UserHandle.of(mRequestPreference.getUserId()));
101 return super.onPreferenceTreeClick(preference);
105 protected String getLogTag() {
110 protected int getPreferenceScreenResId() {
111 return R.xml.sound_settings;
115 protected List<PreferenceController> getPreferenceControllers(Context context) {
116 return buildPreferenceControllers(context, this, mVolumeCallback, getLifecycle());
120 public void onActivityResult(int requestCode, int resultCode, Intent data) {
121 if (mRequestPreference != null) {
122 mRequestPreference.onActivityResult(requestCode, resultCode, data);
123 mRequestPreference = null;
128 public void onSaveInstanceState(Bundle outState) {
129 super.onSaveInstanceState(outState);
130 if (mRequestPreference != null) {
131 outState.putString(SELECTED_PREFERENCE_KEY, mRequestPreference.getKey());
137 final class VolumePreferenceCallback implements VolumeSeekBarPreference.Callback {
138 private SeekBarVolumizer mCurrent;
141 public void onSampleStarting(SeekBarVolumizer sbv) {
142 if (mCurrent != null && mCurrent != sbv) {
143 mCurrent.stopSample();
146 if (mCurrent != null) {
147 mHandler.removeMessages(H.STOP_SAMPLE);
148 mHandler.sendEmptyMessageDelayed(H.STOP_SAMPLE, SAMPLE_CUTOFF);
153 public void onStreamValueChanged(int stream, int progress) {
157 public void stopSample() {
158 if (mCurrent != null) {
159 mCurrent.stopSample();
167 private final class H extends Handler {
168 private static final int STOP_SAMPLE = 1;
171 super(Looper.getMainLooper());
175 public void handleMessage(Message msg) {
178 mVolumeCallback.stopSample();
184 private static List<PreferenceController> buildPreferenceControllers(Context context,
185 SoundSettings fragment, VolumeSeekBarPreference.Callback callback,
186 Lifecycle lifecycle) {
187 final List<PreferenceController> controllers = new ArrayList<>();
188 controllers.add(new ZenModePreferenceController(context));
189 controllers.add(new EmergencyBroadcastPreferenceController(
190 context, "cell_broadcast_settings"));
191 controllers.add(new VibrateWhenRingPreferenceController(context));
194 controllers.add(new AlarmVolumePreferenceController(context, callback, lifecycle));
195 controllers.add(new MediaVolumePreferenceController(context, callback, lifecycle));
197 new NotificationVolumePreferenceController(context, callback, lifecycle));
198 controllers.add(new RingVolumePreferenceController(context, callback, lifecycle));
200 // === Phone & notification ringtone ===
201 controllers.add(new PhoneRingtonePreferenceController(context));
202 controllers.add(new AlarmRingtonePreferenceController(context));
203 controllers.add(new NotificationRingtonePreferenceController(context));
205 // === Work Sound Settings ===
206 controllers.add(new WorkSoundPreferenceController(context, fragment, lifecycle));
208 // === Other Sound Settings ===
209 controllers.add(new DialPadTonePreferenceController(context, fragment, lifecycle));
210 controllers.add(new ScreenLockSoundPreferenceController(context, fragment, lifecycle));
211 controllers.add(new ChargingSoundPreferenceController(context, fragment, lifecycle));
212 controllers.add(new DockingSoundPreferenceController(context, fragment, lifecycle));
213 controllers.add(new TouchSoundPreferenceController(context, fragment, lifecycle));
214 controllers.add(new VibrateOnTouchPreferenceController(context, fragment, lifecycle));
215 controllers.add(new DockAudioMediaPreferenceController(context, fragment, lifecycle));
216 controllers.add(new BootSoundPreferenceController(context));
217 controllers.add(new EmergencyTonePreferenceController(context, fragment, lifecycle));
224 public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
225 new BaseSearchIndexProvider() {
227 public List<SearchIndexableResource> getXmlResourcesToIndex(
228 Context context, boolean enabled) {
229 final SearchIndexableResource sir = new SearchIndexableResource(context);
230 sir.xmlResId = R.xml.sound_settings;
231 return Arrays.asList(sir);
235 public List<PreferenceController> getPreferenceControllers(Context context) {
236 return buildPreferenceControllers(context, null /* fragment */,
237 null /* callback */, null /* lifecycle */);
241 // === Work Sound Settings ===
243 void enableWorkSync() {
244 final WorkSoundPreferenceController workSoundController =
245 getPreferenceController(WorkSoundPreferenceController.class);
246 if (workSoundController != null) {
247 workSoundController.enableWorkSync();