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 import static android.provider.Settings.System.COMPATIBILITY_MODE; 21 22 import android.content.BroadcastReceiver; 23 import android.content.ContentResolver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.IntentFilter; 27 import android.media.AudioManager; 28 import android.os.Bundle; 29 import android.os.IMountService; 30 import android.os.RemoteException; 31 import android.os.ServiceManager; 32 import android.preference.ListPreference; 33 import android.preference.Preference; 34 import android.preference.PreferenceActivity; 35 import android.preference.PreferenceScreen; 36 import android.preference.CheckBoxPreference; 37 import android.provider.Settings; 38 import android.util.Log; 39 import android.view.IWindowManager; 40 import android.telephony.TelephonyManager; 41 42 public class SoundAndDisplaySettings 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_SCREEN_TIMEOUT = "screen_timeout"; 53 private static final String KEY_DTMF_TONE = "dtmf_tone"; 54 private static final String KEY_SOUND_EFFECTS = "sound_effects"; 55 private static final String KEY_HAPTIC_FEEDBACK = "haptic_feedback"; 56 private static final String KEY_ANIMATIONS = "animations"; 57 private static final String KEY_ACCELEROMETER = "accelerometer"; 58 private static final String KEY_PLAY_MEDIA_NOTIFICATION_SOUNDS = "play_media_notification_sounds"; 59 private static final String KEY_EMERGENCY_TONE ="emergency_tone"; 60 61 private CheckBoxPreference mSilent; 62 63 private CheckBoxPreference mPlayMediaNotificationSounds; 64 65 private IMountService mMountService = null; 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 CheckBoxPreference mVibrate; 75 private CheckBoxPreference mDtmfTone; 76 private CheckBoxPreference mSoundEffects; 77 private CheckBoxPreference mHapticFeedback; 78 private ListPreference mAnimations; 79 private CheckBoxPreference mAccelerometer; 80 private float[] mAnimationScales; 81 82 private AudioManager mAudioManager; 83 84 private IWindowManager mWindowManager; 85 86 private BroadcastReceiver mReceiver = new BroadcastReceiver() { 87 @Override 88 public void onReceive(Context context, Intent intent) { 89 updateState(false); 90 } 91 }; 92 93 @Override onCreate(Bundle savedInstanceState)94 protected void onCreate(Bundle savedInstanceState) { 95 super.onCreate(savedInstanceState); 96 ContentResolver resolver = getContentResolver(); 97 int activePhoneType = TelephonyManager.getDefault().getPhoneType(); 98 99 mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 100 mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 101 102 mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); 103 104 addPreferencesFromResource(R.xml.sound_and_display_settings); 105 106 if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType) { 107 // device is not CDMA, do not display CDMA emergency_tone 108 getPreferenceScreen().removePreference(findPreference(KEY_EMERGENCY_TONE)); 109 } 110 111 mSilent = (CheckBoxPreference) findPreference(KEY_SILENT); 112 mPlayMediaNotificationSounds = (CheckBoxPreference) findPreference(KEY_PLAY_MEDIA_NOTIFICATION_SOUNDS); 113 114 mVibrate = (CheckBoxPreference) findPreference(KEY_VIBRATE); 115 mDtmfTone = (CheckBoxPreference) findPreference(KEY_DTMF_TONE); 116 mDtmfTone.setPersistent(false); 117 mDtmfTone.setChecked(Settings.System.getInt(resolver, 118 Settings.System.DTMF_TONE_WHEN_DIALING, 1) != 0); 119 mSoundEffects = (CheckBoxPreference) findPreference(KEY_SOUND_EFFECTS); 120 mSoundEffects.setPersistent(false); 121 mSoundEffects.setChecked(Settings.System.getInt(resolver, 122 Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0); 123 mHapticFeedback = (CheckBoxPreference) findPreference(KEY_HAPTIC_FEEDBACK); 124 mHapticFeedback.setPersistent(false); 125 mHapticFeedback.setChecked(Settings.System.getInt(resolver, 126 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) != 0); 127 mAnimations = (ListPreference) findPreference(KEY_ANIMATIONS); 128 mAnimations.setOnPreferenceChangeListener(this); 129 mAccelerometer = (CheckBoxPreference) findPreference(KEY_ACCELEROMETER); 130 mAccelerometer.setPersistent(false); 131 132 ListPreference screenTimeoutPreference = 133 (ListPreference) findPreference(KEY_SCREEN_TIMEOUT); 134 screenTimeoutPreference.setValue(String.valueOf(Settings.System.getInt( 135 resolver, SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE))); 136 screenTimeoutPreference.setOnPreferenceChangeListener(this); 137 138 if (TelephonyManager.PHONE_TYPE_CDMA == activePhoneType) { 139 ListPreference emergencyTonePreference = 140 (ListPreference) findPreference(KEY_EMERGENCY_TONE); 141 emergencyTonePreference.setValue(String.valueOf(Settings.System.getInt( 142 resolver, Settings.System.EMERGENCY_TONE, FALLBACK_EMERGENCY_TONE_VALUE))); 143 emergencyTonePreference.setOnPreferenceChangeListener(this); 144 } 145 } 146 147 @Override onResume()148 protected void onResume() { 149 super.onResume(); 150 151 updateState(true); 152 153 IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); 154 registerReceiver(mReceiver, filter); 155 } 156 157 @Override onPause()158 protected void onPause() { 159 super.onPause(); 160 161 unregisterReceiver(mReceiver); 162 } 163 updateState(boolean force)164 private void updateState(boolean force) { 165 final int ringerMode = mAudioManager.getRingerMode(); 166 final boolean silentOrVibrateMode = 167 ringerMode != AudioManager.RINGER_MODE_NORMAL; 168 169 if (silentOrVibrateMode != mSilent.isChecked() || force) { 170 mSilent.setChecked(silentOrVibrateMode); 171 } 172 173 try { 174 mPlayMediaNotificationSounds.setChecked(mMountService.getPlayNotificationSounds()); 175 } catch (RemoteException e) { 176 } 177 178 boolean vibrateSetting; 179 if (silentOrVibrateMode) { 180 vibrateSetting = ringerMode == AudioManager.RINGER_MODE_VIBRATE; 181 } else { 182 vibrateSetting = mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER) 183 == AudioManager.VIBRATE_SETTING_ON; 184 } 185 if (vibrateSetting != mVibrate.isChecked() || force) { 186 mVibrate.setChecked(vibrateSetting); 187 } 188 189 int silentModeStreams = Settings.System.getInt(getContentResolver(), 190 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); 191 boolean isAlarmInclSilentMode = (silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0; 192 mSilent.setSummary(isAlarmInclSilentMode ? 193 R.string.silent_mode_incl_alarm_summary : 194 R.string.silent_mode_summary); 195 196 int animations = 0; 197 try { 198 mAnimationScales = mWindowManager.getAnimationScales(); 199 } catch (RemoteException e) { 200 } 201 if (mAnimationScales != null) { 202 if (mAnimationScales.length >= 1) { 203 animations = ((int)(mAnimationScales[0]+.5f)) % 10; 204 } 205 if (mAnimationScales.length >= 2) { 206 animations += (((int)(mAnimationScales[1]+.5f)) & 0x7) * 10; 207 } 208 } 209 int idx = 0; 210 int best = 0; 211 CharSequence[] aents = mAnimations.getEntryValues(); 212 for (int i=0; i<aents.length; i++) { 213 int val = Integer.parseInt(aents[i].toString()); 214 if (val <= animations && val > best) { 215 best = val; 216 idx = i; 217 } 218 } 219 mAnimations.setValueIndex(idx); 220 updateAnimationsSummary(mAnimations.getValue()); 221 mAccelerometer.setChecked(Settings.System.getInt( 222 getContentResolver(), 223 Settings.System.ACCELEROMETER_ROTATION, 0) != 0); 224 } 225 updateAnimationsSummary(Object value)226 private void updateAnimationsSummary(Object value) { 227 CharSequence[] summaries = getResources().getTextArray(R.array.animations_summaries); 228 CharSequence[] values = mAnimations.getEntryValues(); 229 for (int i=0; i<values.length; i++) { 230 //Log.i("foo", "Comparing entry "+ values[i] + " to current " 231 // + mAnimations.getValue()); 232 if (values[i].equals(value)) { 233 mAnimations.setSummary(summaries[i]); 234 break; 235 } 236 } 237 } 238 setRingerMode(boolean silent, boolean vibrate)239 private void setRingerMode(boolean silent, boolean vibrate) { 240 if (silent) { 241 mAudioManager.setRingerMode(vibrate ? AudioManager.RINGER_MODE_VIBRATE : 242 AudioManager.RINGER_MODE_SILENT); 243 } else { 244 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); 245 mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, 246 vibrate ? AudioManager.VIBRATE_SETTING_ON 247 : AudioManager.VIBRATE_SETTING_OFF); 248 } 249 } 250 251 @Override onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)252 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 253 if (preference == mSilent || preference == mVibrate) { 254 setRingerMode(mSilent.isChecked(), mVibrate.isChecked()); 255 if (preference == mSilent) updateState(false); 256 } else if (preference == mPlayMediaNotificationSounds) { 257 try { 258 mMountService.setPlayNotificationSounds(mPlayMediaNotificationSounds.isChecked()); 259 } catch (RemoteException e) { 260 } 261 } else if (preference == mDtmfTone) { 262 Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 263 mDtmfTone.isChecked() ? 1 : 0); 264 265 } else if (preference == mSoundEffects) { 266 if (mSoundEffects.isChecked()) { 267 mAudioManager.loadSoundEffects(); 268 } else { 269 mAudioManager.unloadSoundEffects(); 270 } 271 Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 272 mSoundEffects.isChecked() ? 1 : 0); 273 274 } else if (preference == mHapticFeedback) { 275 Settings.System.putInt(getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 276 mHapticFeedback.isChecked() ? 1 : 0); 277 278 } else if (preference == mAccelerometer) { 279 Settings.System.putInt(getContentResolver(), 280 Settings.System.ACCELEROMETER_ROTATION, 281 mAccelerometer.isChecked() ? 1 : 0); 282 } 283 return true; 284 } 285 onPreferenceChange(Preference preference, Object objValue)286 public boolean onPreferenceChange(Preference preference, Object objValue) { 287 if (KEY_ANIMATIONS.equals(preference.getKey())) { 288 try { 289 int value = Integer.parseInt((String) objValue); 290 if (mAnimationScales.length >= 1) { 291 mAnimationScales[0] = value%10; 292 } 293 if (mAnimationScales.length >= 2) { 294 mAnimationScales[1] = (value/10)%10; 295 } 296 try { 297 mWindowManager.setAnimationScales(mAnimationScales); 298 } catch (RemoteException e) { 299 } 300 updateAnimationsSummary(objValue); 301 } catch (NumberFormatException e) { 302 Log.e(TAG, "could not persist animation setting", e); 303 } 304 305 } 306 if (KEY_SCREEN_TIMEOUT.equals(preference.getKey())) { 307 int value = Integer.parseInt((String) objValue); 308 try { 309 Settings.System.putInt(getContentResolver(), 310 SCREEN_OFF_TIMEOUT, value); 311 } catch (NumberFormatException e) { 312 Log.e(TAG, "could not persist screen timeout setting", e); 313 } 314 } else if (KEY_EMERGENCY_TONE.equals(preference.getKey())) { 315 int value = Integer.parseInt((String) objValue); 316 try { 317 Settings.System.putInt(getContentResolver(), 318 Settings.System.EMERGENCY_TONE, value); 319 } catch (NumberFormatException e) { 320 Log.e(TAG, "could not persist emergency tone setting", e); 321 } 322 } 323 324 return true; 325 } 326 327 } 328