Home | History | Annotate | Download | only in settings
      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.ContentResolver;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.pm.PackageManager;
     23 import android.content.pm.ResolveInfo;
     24 import android.database.Cursor;
     25 import android.database.sqlite.SQLiteException;
     26 import android.media.AudioManager;
     27 import android.media.RingtoneManager;
     28 import android.media.audiofx.AudioEffect;
     29 import android.net.Uri;
     30 import android.os.Bundle;
     31 import android.os.Handler;
     32 import android.os.Message;
     33 import android.os.Vibrator;
     34 import android.preference.CheckBoxPreference;
     35 import android.preference.ListPreference;
     36 import android.preference.Preference;
     37 import android.preference.PreferenceGroup;
     38 import android.preference.PreferenceScreen;
     39 import android.provider.MediaStore;
     40 import android.provider.Settings;
     41 import android.telephony.TelephonyManager;
     42 import android.util.Log;
     43 
     44 import java.util.List;
     45 
     46 public class SoundSettings extends SettingsPreferenceFragment implements
     47         Preference.OnPreferenceChangeListener {
     48     private static final String TAG = "SoundSettings";
     49 
     50     /** If there is no setting in the provider, use this. */
     51     private static final int FALLBACK_EMERGENCY_TONE_VALUE = 0;
     52 
     53     private static final String KEY_VIBRATE = "vibrate_when_ringing";
     54     private static final String KEY_RING_VOLUME = "ring_volume";
     55     private static final String KEY_MUSICFX = "musicfx";
     56     private static final String KEY_DTMF_TONE = "dtmf_tone";
     57     private static final String KEY_SOUND_EFFECTS = "sound_effects";
     58     private static final String KEY_HAPTIC_FEEDBACK = "haptic_feedback";
     59     private static final String KEY_EMERGENCY_TONE = "emergency_tone";
     60     private static final String KEY_SOUND_SETTINGS = "sound_settings";
     61     private static final String KEY_LOCK_SOUNDS = "lock_sounds";
     62     private static final String KEY_RINGTONE = "ringtone";
     63     private static final String KEY_NOTIFICATION_SOUND = "notification_sound";
     64     private static final String KEY_CATEGORY_CALLS = "category_calls_and_notification";
     65 
     66     private static final String[] NEED_VOICE_CAPABILITY = {
     67             KEY_RINGTONE, KEY_DTMF_TONE, KEY_CATEGORY_CALLS,
     68             KEY_EMERGENCY_TONE
     69     };
     70 
     71     private static final int MSG_UPDATE_RINGTONE_SUMMARY = 1;
     72     private static final int MSG_UPDATE_NOTIFICATION_SUMMARY = 2;
     73 
     74     private CheckBoxPreference mVibrateWhenRinging;
     75     private CheckBoxPreference mDtmfTone;
     76     private CheckBoxPreference mSoundEffects;
     77     private CheckBoxPreference mHapticFeedback;
     78     private Preference mMusicFx;
     79     private CheckBoxPreference mLockSounds;
     80     private Preference mRingtonePreference;
     81     private Preference mNotificationPreference;
     82 
     83     private Runnable mRingtoneLookupRunnable;
     84 
     85     private AudioManager mAudioManager;
     86 
     87     private Handler mHandler = new Handler() {
     88         public void handleMessage(Message msg) {
     89             switch (msg.what) {
     90             case MSG_UPDATE_RINGTONE_SUMMARY:
     91                 mRingtonePreference.setSummary((CharSequence) msg.obj);
     92                 break;
     93             case MSG_UPDATE_NOTIFICATION_SUMMARY:
     94                 mNotificationPreference.setSummary((CharSequence) msg.obj);
     95                 break;
     96             }
     97         }
     98     };
     99 
    100     private PreferenceGroup mSoundSettings;
    101 
    102     @Override
    103     public void onCreate(Bundle savedInstanceState) {
    104         super.onCreate(savedInstanceState);
    105         ContentResolver resolver = getContentResolver();
    106         int activePhoneType = TelephonyManager.getDefault().getCurrentPhoneType();
    107 
    108         mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    109 
    110         addPreferencesFromResource(R.xml.sound_settings);
    111 
    112         if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType) {
    113             // device is not CDMA, do not display CDMA emergency_tone
    114             getPreferenceScreen().removePreference(findPreference(KEY_EMERGENCY_TONE));
    115         }
    116 
    117         if (!getResources().getBoolean(R.bool.has_silent_mode)) {
    118             findPreference(KEY_RING_VOLUME).setDependency(null);
    119         }
    120 
    121         mVibrateWhenRinging = (CheckBoxPreference) findPreference(KEY_VIBRATE);
    122         mVibrateWhenRinging.setPersistent(false);
    123         mVibrateWhenRinging.setChecked(Settings.System.getInt(resolver,
    124                 Settings.System.VIBRATE_WHEN_RINGING, 0) != 0);
    125 
    126         mDtmfTone = (CheckBoxPreference) findPreference(KEY_DTMF_TONE);
    127         mDtmfTone.setPersistent(false);
    128         mDtmfTone.setChecked(Settings.System.getInt(resolver,
    129                 Settings.System.DTMF_TONE_WHEN_DIALING, 1) != 0);
    130         mSoundEffects = (CheckBoxPreference) findPreference(KEY_SOUND_EFFECTS);
    131         mSoundEffects.setPersistent(false);
    132         mSoundEffects.setChecked(Settings.System.getInt(resolver,
    133                 Settings.System.SOUND_EFFECTS_ENABLED, 1) != 0);
    134         mHapticFeedback = (CheckBoxPreference) findPreference(KEY_HAPTIC_FEEDBACK);
    135         mHapticFeedback.setPersistent(false);
    136         mHapticFeedback.setChecked(Settings.System.getInt(resolver,
    137                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 1) != 0);
    138         mLockSounds = (CheckBoxPreference) findPreference(KEY_LOCK_SOUNDS);
    139         mLockSounds.setPersistent(false);
    140         mLockSounds.setChecked(Settings.System.getInt(resolver,
    141                 Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) != 0);
    142 
    143         mRingtonePreference = findPreference(KEY_RINGTONE);
    144         mNotificationPreference = findPreference(KEY_NOTIFICATION_SOUND);
    145 
    146         Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    147         if (vibrator == null || !vibrator.hasVibrator()) {
    148             getPreferenceScreen().removePreference(mVibrateWhenRinging);
    149             getPreferenceScreen().removePreference(mHapticFeedback);
    150         }
    151 
    152         if (TelephonyManager.PHONE_TYPE_CDMA == activePhoneType) {
    153             ListPreference emergencyTonePreference =
    154                 (ListPreference) findPreference(KEY_EMERGENCY_TONE);
    155             emergencyTonePreference.setValue(String.valueOf(Settings.System.getInt(
    156                 resolver, Settings.System.EMERGENCY_TONE, FALLBACK_EMERGENCY_TONE_VALUE)));
    157             emergencyTonePreference.setOnPreferenceChangeListener(this);
    158         }
    159 
    160         mSoundSettings = (PreferenceGroup) findPreference(KEY_SOUND_SETTINGS);
    161 
    162         mMusicFx = mSoundSettings.findPreference(KEY_MUSICFX);
    163         Intent i = new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL);
    164         PackageManager p = getPackageManager();
    165         List<ResolveInfo> ris = p.queryIntentActivities(i, PackageManager.GET_DISABLED_COMPONENTS);
    166         if (ris.size() <= 2) {
    167             // no need to show the item if there is no choice for the user to make
    168             // note: the built in musicfx panel has two activities (one being a
    169             // compatibility shim that launches either the other activity, or a
    170             // third party one), hence the check for <=2. If the implementation
    171             // of the compatbility layer changes, this check may need to be updated.
    172             mSoundSettings.removePreference(mMusicFx);
    173         }
    174 
    175         if (!Utils.isVoiceCapable(getActivity())) {
    176             for (String prefKey : NEED_VOICE_CAPABILITY) {
    177                 Preference pref = findPreference(prefKey);
    178                 if (pref != null) {
    179                     getPreferenceScreen().removePreference(pref);
    180                 }
    181             }
    182         }
    183 
    184         mRingtoneLookupRunnable = new Runnable() {
    185             public void run() {
    186                 if (mRingtonePreference != null) {
    187                     updateRingtoneName(RingtoneManager.TYPE_RINGTONE, mRingtonePreference,
    188                             MSG_UPDATE_RINGTONE_SUMMARY);
    189                 }
    190                 if (mNotificationPreference != null) {
    191                     updateRingtoneName(RingtoneManager.TYPE_NOTIFICATION, mNotificationPreference,
    192                             MSG_UPDATE_NOTIFICATION_SUMMARY);
    193                 }
    194             }
    195         };
    196     }
    197 
    198     @Override
    199     public void onResume() {
    200         super.onResume();
    201 
    202         lookupRingtoneNames();
    203     }
    204 
    205     private void updateRingtoneName(int type, Preference preference, int msg) {
    206         if (preference == null) return;
    207         Context context = getActivity();
    208         if (context == null) return;
    209         Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(context, type);
    210         CharSequence summary = context.getString(com.android.internal.R.string.ringtone_unknown);
    211         // Is it a silent ringtone?
    212         if (ringtoneUri == null) {
    213             summary = context.getString(com.android.internal.R.string.ringtone_silent);
    214         } else {
    215             // Fetch the ringtone title from the media provider
    216             try {
    217                 Cursor cursor = context.getContentResolver().query(ringtoneUri,
    218                         new String[] { MediaStore.Audio.Media.TITLE }, null, null, null);
    219                 if (cursor != null) {
    220                     if (cursor.moveToFirst()) {
    221                         summary = cursor.getString(0);
    222                     }
    223                     cursor.close();
    224                 }
    225             } catch (SQLiteException sqle) {
    226                 // Unknown title for the ringtone
    227             }
    228         }
    229         mHandler.sendMessage(mHandler.obtainMessage(msg, summary));
    230     }
    231 
    232     private void lookupRingtoneNames() {
    233         new Thread(mRingtoneLookupRunnable).start();
    234     }
    235 
    236     @Override
    237     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
    238         if (preference == mVibrateWhenRinging) {
    239             Settings.System.putInt(getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING,
    240                     mVibrateWhenRinging.isChecked() ? 1 : 0);
    241         } else if (preference == mDtmfTone) {
    242             Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
    243                     mDtmfTone.isChecked() ? 1 : 0);
    244 
    245         } else if (preference == mSoundEffects) {
    246             if (mSoundEffects.isChecked()) {
    247                 mAudioManager.loadSoundEffects();
    248             } else {
    249                 mAudioManager.unloadSoundEffects();
    250             }
    251             Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED,
    252                     mSoundEffects.isChecked() ? 1 : 0);
    253 
    254         } else if (preference == mHapticFeedback) {
    255             Settings.System.putInt(getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED,
    256                     mHapticFeedback.isChecked() ? 1 : 0);
    257 
    258         } else if (preference == mLockSounds) {
    259             Settings.System.putInt(getContentResolver(), Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
    260                     mLockSounds.isChecked() ? 1 : 0);
    261 
    262         } else if (preference == mMusicFx) {
    263             // let the framework fire off the intent
    264             return false;
    265         }
    266 
    267         return true;
    268     }
    269 
    270     public boolean onPreferenceChange(Preference preference, Object objValue) {
    271         final String key = preference.getKey();
    272         if (KEY_EMERGENCY_TONE.equals(key)) {
    273             try {
    274                 int value = Integer.parseInt((String) objValue);
    275                 Settings.System.putInt(getContentResolver(),
    276                         Settings.System.EMERGENCY_TONE, value);
    277             } catch (NumberFormatException e) {
    278                 Log.e(TAG, "could not persist emergency tone setting", e);
    279             }
    280         }
    281 
    282         return true;
    283     }
    284 
    285     @Override
    286     protected int getHelpResource() {
    287         return R.string.help_url_sound;
    288     }
    289 }
    290