• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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;
18 
19 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
20 
21 import android.content.BroadcastReceiver;
22 import android.content.ContentResolver;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.media.AudioManager;
27 import android.os.Bundle;
28 import android.os.RemoteException;
29 import android.os.ServiceManager;
30 import android.preference.CheckBoxPreference;
31 import android.preference.ListPreference;
32 import android.preference.Preference;
33 import android.preference.PreferenceActivity;
34 import android.preference.PreferenceGroup;
35 import android.preference.PreferenceScreen;
36 import android.provider.Settings;
37 import android.provider.Settings.SettingNotFoundException;
38 import android.telephony.TelephonyManager;
39 import android.util.Log;
40 import android.view.IWindowManager;
41 
42 public class SoundSettings extends PreferenceActivity implements
43         Preference.OnPreferenceChangeListener {
44     private static final String TAG = "SoundAndDisplaysSettings";
45 
46     /** If there is no setting in the provider, use this. */
47     private static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
48     private static final int FALLBACK_EMERGENCY_TONE_VALUE = 0;
49 
50     private static final String KEY_SILENT = "silent";
51     private static final String KEY_VIBRATE = "vibrate";
52     private static final String KEY_DTMF_TONE = "dtmf_tone";
53     private static final String KEY_SOUND_EFFECTS = "sound_effects";
54     private static final String KEY_HAPTIC_FEEDBACK = "haptic_feedback";
55     private static final String KEY_EMERGENCY_TONE = "emergency_tone";
56     private static final String KEY_SOUND_SETTINGS = "sound_settings";
57     private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
58     private static final String KEY_LOCK_SOUNDS = "lock_sounds";
59 
60     private static final String VALUE_VIBRATE_NEVER = "never";
61     private static final String VALUE_VIBRATE_ALWAYS = "always";
62     private static final String VALUE_VIBRATE_ONLY_SILENT = "silent";
63     private static final String VALUE_VIBRATE_UNLESS_SILENT = "notsilent";
64 
65     private CheckBoxPreference mSilent;
66 
67     /*
68      * If we are currently in one of the silent modes (the ringer mode is set to either
69      * "silent mode" or "vibrate mode"), then toggling the "Phone vibrate"
70      * preference will switch between "silent mode" and "vibrate mode".
71      * Otherwise, it will adjust the normal ringer mode's ring or ring+vibrate
72      * setting.
73      */
74     private ListPreference mVibrate;
75     private CheckBoxPreference mDtmfTone;
76     private CheckBoxPreference mSoundEffects;
77     private CheckBoxPreference mHapticFeedback;
78     private CheckBoxPreference mNotificationPulse;
79     private CheckBoxPreference mLockSounds;
80 
81     private AudioManager mAudioManager;
82 
83     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
84         @Override
85         public void onReceive(Context context, Intent intent) {
86             if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
87                 updateState(false);
88             }
89         }
90     };
91 
92     private PreferenceGroup mSoundSettings;
93 
94     @Override
onCreate(Bundle savedInstanceState)95     protected void onCreate(Bundle savedInstanceState) {
96         super.onCreate(savedInstanceState);
97         ContentResolver resolver = getContentResolver();
98         int activePhoneType = TelephonyManager.getDefault().getPhoneType();
99 
100         mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
101 
102         addPreferencesFromResource(R.xml.sound_settings);
103 
104         if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType) {
105             // device is not CDMA, do not display CDMA emergency_tone
106             getPreferenceScreen().removePreference(findPreference(KEY_EMERGENCY_TONE));
107         }
108 
109         mSilent = (CheckBoxPreference) findPreference(KEY_SILENT);
110 
111         mVibrate = (ListPreference) findPreference(KEY_VIBRATE);
112         mVibrate.setOnPreferenceChangeListener(this);
113 
114         mDtmfTone = (CheckBoxPreference) findPreference(KEY_DTMF_TONE);
115         mDtmfTone.setPersistent(false);
116         mDtmfTone.setChecked(Settings.System.getInt(resolver,
117                 Settings.System.DTMF_TONE_WHEN_DIALING, 1) != 0);
118         mSoundEffects = (CheckBoxPreference) findPreference(KEY_SOUND_EFFECTS);
119         mSoundEffects.setPersistent(false);
120         mSoundEffects.setChecked(Settings.System.getInt(resolver,
121                 Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0);
122         mHapticFeedback = (CheckBoxPreference) findPreference(KEY_HAPTIC_FEEDBACK);
123         mHapticFeedback.setPersistent(false);
124         mHapticFeedback.setChecked(Settings.System.getInt(resolver,
125                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) != 0);
126         mLockSounds = (CheckBoxPreference) findPreference(KEY_LOCK_SOUNDS);
127         mLockSounds.setPersistent(false);
128         mLockSounds.setChecked(Settings.System.getInt(resolver,
129                 Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) != 0);
130 
131         if (TelephonyManager.PHONE_TYPE_CDMA == activePhoneType) {
132             ListPreference emergencyTonePreference =
133                 (ListPreference) findPreference(KEY_EMERGENCY_TONE);
134             emergencyTonePreference.setValue(String.valueOf(Settings.System.getInt(
135                 resolver, Settings.System.EMERGENCY_TONE, FALLBACK_EMERGENCY_TONE_VALUE)));
136             emergencyTonePreference.setOnPreferenceChangeListener(this);
137         }
138 
139         mSoundSettings = (PreferenceGroup) findPreference(KEY_SOUND_SETTINGS);
140         mNotificationPulse = (CheckBoxPreference)
141                 mSoundSettings.findPreference(KEY_NOTIFICATION_PULSE);
142         if (mNotificationPulse != null &&
143                 getResources().getBoolean(R.bool.has_intrusive_led) == false) {
144             mSoundSettings.removePreference(mNotificationPulse);
145         } else {
146             try {
147                 mNotificationPulse.setChecked(Settings.System.getInt(resolver,
148                         Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
149                 mNotificationPulse.setOnPreferenceChangeListener(this);
150             } catch (SettingNotFoundException snfe) {
151                 Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
152             }
153         }
154 
155     }
156 
157     @Override
onResume()158     protected void onResume() {
159         super.onResume();
160 
161         updateState(true);
162 
163         IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
164         registerReceiver(mReceiver, filter);
165     }
166 
167     @Override
onPause()168     protected void onPause() {
169         super.onPause();
170 
171         unregisterReceiver(mReceiver);
172     }
173 
getPhoneVibrateSettingValue()174     private String getPhoneVibrateSettingValue() {
175         boolean vibeInSilent = (Settings.System.getInt(
176             getContentResolver(),
177             Settings.System.VIBRATE_IN_SILENT,
178             1) == 1);
179 
180         // Control phone vibe independent of silent mode
181         int callsVibrateSetting =
182             mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
183 
184         if (vibeInSilent) {
185             if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_OFF) {
186                 // this state does not make sense; fix it up for the user
187                 mAudioManager.setVibrateSetting(
188                     AudioManager.VIBRATE_TYPE_RINGER,
189                     AudioManager.VIBRATE_SETTING_ONLY_SILENT);
190             }
191             if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ON) {
192                 return VALUE_VIBRATE_ALWAYS;
193             } else {
194                 return VALUE_VIBRATE_ONLY_SILENT;
195             }
196         } else {
197             if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ONLY_SILENT) {
198                 // this state does not make sense; fix it up
199                 mAudioManager.setVibrateSetting(
200                     AudioManager.VIBRATE_TYPE_RINGER,
201                     AudioManager.VIBRATE_SETTING_OFF);
202             }
203             if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ON) {
204                 return VALUE_VIBRATE_UNLESS_SILENT;
205             } else {
206                 return VALUE_VIBRATE_NEVER;
207             }
208         }
209     }
210 
setPhoneVibrateSettingValue(String value)211     private void setPhoneVibrateSettingValue(String value) {
212         boolean vibeInSilent;
213         int callsVibrateSetting;
214 
215         if (value.equals(VALUE_VIBRATE_UNLESS_SILENT)) {
216             callsVibrateSetting = AudioManager.VIBRATE_SETTING_ON;
217             vibeInSilent = false;
218         } else if (value.equals(VALUE_VIBRATE_NEVER)) {
219             callsVibrateSetting = AudioManager.VIBRATE_SETTING_OFF;
220             vibeInSilent = false;
221         } else if (value.equals(VALUE_VIBRATE_ONLY_SILENT)) {
222             callsVibrateSetting = AudioManager.VIBRATE_SETTING_ONLY_SILENT;
223             vibeInSilent = true;
224         } else { //VALUE_VIBRATE_ALWAYS
225             callsVibrateSetting = AudioManager.VIBRATE_SETTING_ON;
226             vibeInSilent = true;
227         }
228 
229         Settings.System.putInt(getContentResolver(),
230             Settings.System.VIBRATE_IN_SILENT,
231             vibeInSilent ? 1 : 0);
232 
233         // might need to switch the ringer mode from one kind of "silent" to
234         // another
235         if (mSilent.isChecked()) {
236             mAudioManager.setRingerMode(
237                 vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
238                              : AudioManager.RINGER_MODE_SILENT);
239         }
240 
241         mAudioManager.setVibrateSetting(
242             AudioManager.VIBRATE_TYPE_RINGER,
243             callsVibrateSetting);
244     }
245 
246     // updateState in fact updates the UI to reflect the system state
updateState(boolean force)247     private void updateState(boolean force) {
248         final int ringerMode = mAudioManager.getRingerMode();
249 
250         // NB: in the UI we now simply call this "silent mode". A separate
251         // setting controls whether we're in RINGER_MODE_SILENT or
252         // RINGER_MODE_VIBRATE.
253         final boolean silentOrVibrateMode =
254                 ringerMode != AudioManager.RINGER_MODE_NORMAL;
255 
256         if (silentOrVibrateMode != mSilent.isChecked() || force) {
257             mSilent.setChecked(silentOrVibrateMode);
258         }
259 
260         String phoneVibrateSetting = getPhoneVibrateSettingValue();
261 
262         if (! phoneVibrateSetting.equals(mVibrate.getValue()) || force) {
263             mVibrate.setValue(phoneVibrateSetting);
264         }
265         mVibrate.setSummary(mVibrate.getEntry());
266 
267         int silentModeStreams = Settings.System.getInt(getContentResolver(),
268                 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
269         boolean isAlarmInclSilentMode = (silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0;
270         mSilent.setSummary(isAlarmInclSilentMode ?
271                 R.string.silent_mode_incl_alarm_summary :
272                 R.string.silent_mode_summary);
273     }
274 
275     @Override
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)276     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
277         if (preference == mSilent) {
278             if (mSilent.isChecked()) {
279                 boolean vibeInSilent = (1 == Settings.System.getInt(
280                     getContentResolver(),
281                     Settings.System.VIBRATE_IN_SILENT,
282                     1));
283                 mAudioManager.setRingerMode(
284                     vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
285                                  : AudioManager.RINGER_MODE_SILENT);
286             } else {
287                 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
288             }
289             updateState(false);
290         } else if (preference == mDtmfTone) {
291             Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
292                     mDtmfTone.isChecked() ? 1 : 0);
293 
294         } else if (preference == mSoundEffects) {
295             if (mSoundEffects.isChecked()) {
296                 mAudioManager.loadSoundEffects();
297             } else {
298                 mAudioManager.unloadSoundEffects();
299             }
300             Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED,
301                     mSoundEffects.isChecked() ? 1 : 0);
302 
303         } else if (preference == mHapticFeedback) {
304             Settings.System.putInt(getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED,
305                     mHapticFeedback.isChecked() ? 1 : 0);
306 
307         } else if (preference == mLockSounds) {
308             Settings.System.putInt(getContentResolver(), Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
309                     mLockSounds.isChecked() ? 1 : 0);
310 
311         } else if (preference == mNotificationPulse) {
312             boolean value = mNotificationPulse.isChecked();
313             Settings.System.putInt(getContentResolver(),
314                     Settings.System.NOTIFICATION_LIGHT_PULSE, value ? 1 : 0);
315         }
316 
317         return true;
318     }
319 
onPreferenceChange(Preference preference, Object objValue)320     public boolean onPreferenceChange(Preference preference, Object objValue) {
321         final String key = preference.getKey();
322         if (KEY_EMERGENCY_TONE.equals(key)) {
323             int value = Integer.parseInt((String) objValue);
324             try {
325                 Settings.System.putInt(getContentResolver(),
326                         Settings.System.EMERGENCY_TONE, value);
327             } catch (NumberFormatException e) {
328                 Log.e(TAG, "could not persist emergency tone setting", e);
329             }
330         } else if (preference == mVibrate) {
331             setPhoneVibrateSettingValue(objValue.toString());
332             updateState(false);
333         }
334 
335         return true;
336     }
337 }
338