OSDN Git Service

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