diff options
-rw-r--r-- | java/com/android/dialer/app/settings/DialerSettingsActivity.java | 21 | ||||
-rw-r--r-- | java/com/android/dialer/app/settings/SoundSettingsFragment.java | 240 |
2 files changed, 246 insertions, 15 deletions
diff --git a/java/com/android/dialer/app/settings/DialerSettingsActivity.java b/java/com/android/dialer/app/settings/DialerSettingsActivity.java index d9bcd6ba5..cdea6faa5 100644 --- a/java/com/android/dialer/app/settings/DialerSettingsActivity.java +++ b/java/com/android/dialer/app/settings/DialerSettingsActivity.java @@ -102,6 +102,7 @@ public class DialerSettingsActivity extends AppCompatPreferenceActivity { Header soundSettingsHeader = new Header(); soundSettingsHeader.titleRes = R.string.sounds_and_vibration_title; + soundSettingsHeader.fragment = SoundSettingsFragment.class.getName(); soundSettingsHeader.id = R.id.settings_header_sounds_and_vibration; target.add(soundSettingsHeader); @@ -271,32 +272,22 @@ public class DialerSettingsActivity extends AppCompatPreferenceActivity { && getResources().getBoolean(R.bool.config_sort_order_user_changeable); } - /** - * For the "sounds and vibration" setting, we go directly to the system sound settings fragment. - * This helps since: - * <li>We don't need a separate Dialer sounds and vibrations fragment, as everything we need is - * present in the system sounds fragment. - * <li>OEM's e.g Moto that support dual sim ring-tones no longer need to update the dialer sound - * and settings fragment. - * - * <p>For all other settings, we launch our our preferences fragment. - */ @Override public void onHeaderClick(Header header, int position) { if (header.id == R.id.settings_header_sounds_and_vibration) { - + // If we don't have the permission to write to system settings, go to system sound + // settings instead. Otherwise, perform the super implementation (which launches our + // own preference fragment. if (!Settings.System.canWrite(this)) { Toast.makeText( this, getResources().getString(R.string.toast_cannot_write_system_settings), Toast.LENGTH_SHORT) .show(); + startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS)); + return; } - - startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS)); - return; } - super.onHeaderClick(header, position); } diff --git a/java/com/android/dialer/app/settings/SoundSettingsFragment.java b/java/com/android/dialer/app/settings/SoundSettingsFragment.java new file mode 100644 index 000000000..9d564416c --- /dev/null +++ b/java/com/android/dialer/app/settings/SoundSettingsFragment.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.dialer.app.settings; + +import android.content.Context; +import android.media.RingtoneManager; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Vibrator; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.preference.PreferenceScreen; +import android.preference.SwitchPreference; +import android.provider.Settings; +import android.telephony.CarrierConfigManager; +import android.telephony.TelephonyManager; +import android.widget.Toast; +import com.android.dialer.app.R; +import com.android.dialer.util.SettingsUtil; + +public class SoundSettingsFragment extends PreferenceFragment + implements Preference.OnPreferenceChangeListener { + + private static final int NO_DTMF_TONE = 0; + private static final int PLAY_DTMF_TONE = 1; + + private static final int NO_VIBRATION_FOR_CALLS = 0; + private static final int DO_VIBRATION_FOR_CALLS = 1; + + private static final int DTMF_TONE_TYPE_NORMAL = 0; + + private static final int MSG_UPDATE_RINGTONE_SUMMARY = 1; + + private Preference ringtonePreference; + private final Handler ringtoneLookupComplete = + new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE_RINGTONE_SUMMARY: + ringtonePreference.setSummary((CharSequence) msg.obj); + break; + } + } + }; + private final Runnable ringtoneLookupRunnable = + new Runnable() { + @Override + public void run() { + updateRingtonePreferenceSummary(); + } + }; + private SwitchPreference vibrateWhenRinging; + private SwitchPreference playDtmfTone; + private ListPreference dtmfToneLength; + + @Override + public Context getContext() { + return getActivity(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.sound_settings); + + Context context = getActivity(); + + ringtonePreference = findPreference(context.getString(R.string.ringtone_preference_key)); + vibrateWhenRinging = + (SwitchPreference) findPreference(context.getString(R.string.vibrate_on_preference_key)); + playDtmfTone = + (SwitchPreference) findPreference(context.getString(R.string.play_dtmf_preference_key)); + dtmfToneLength = + (ListPreference) + findPreference(context.getString(R.string.dtmf_tone_length_preference_key)); + + if (hasVibrator()) { + vibrateWhenRinging.setOnPreferenceChangeListener(this); + } else { + getPreferenceScreen().removePreference(vibrateWhenRinging); + vibrateWhenRinging = null; + } + + playDtmfTone.setOnPreferenceChangeListener(this); + playDtmfTone.setChecked(shouldPlayDtmfTone()); + + TelephonyManager telephonyManager = + (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE); + if (telephonyManager.canChangeDtmfToneLength() + && (telephonyManager.isWorldPhone() || !shouldHideCarrierSettings())) { + dtmfToneLength.setOnPreferenceChangeListener(this); + dtmfToneLength.setValueIndex( + Settings.System.getInt( + context.getContentResolver(), + Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, + DTMF_TONE_TYPE_NORMAL)); + } else { + getPreferenceScreen().removePreference(dtmfToneLength); + dtmfToneLength = null; + } + } + + @Override + public void onResume() { + super.onResume(); + + if (!Settings.System.canWrite(getContext())) { + // If the user launches this setting fragment, then toggles the WRITE_SYSTEM_SETTINGS + // AppOp, then close the fragment since there is nothing useful to do. + getActivity().onBackPressed(); + return; + } + + if (vibrateWhenRinging != null) { + vibrateWhenRinging.setChecked(shouldVibrateWhenRinging()); + } + + // Lookup the ringtone name asynchronously. + new Thread(ringtoneLookupRunnable).start(); + } + + /** + * Supports onPreferenceChangeListener to look for preference changes. + * + * @param preference The preference to be changed + * @param objValue The value of the selection, NOT its localized display value. + */ + @Override + public boolean onPreferenceChange(Preference preference, Object objValue) { + if (!Settings.System.canWrite(getContext())) { + // A user shouldn't be able to get here, but this protects against monkey crashes. + Toast.makeText( + getContext(), + getResources().getString(R.string.toast_cannot_write_system_settings), + Toast.LENGTH_SHORT) + .show(); + return true; + } + if (preference == vibrateWhenRinging) { + boolean doVibrate = (Boolean) objValue; + Settings.System.putInt( + getActivity().getContentResolver(), + Settings.System.VIBRATE_WHEN_RINGING, + doVibrate ? DO_VIBRATION_FOR_CALLS : NO_VIBRATION_FOR_CALLS); + } else if (preference == dtmfToneLength) { + int index = dtmfToneLength.findIndexOfValue((String) objValue); + Settings.System.putInt( + getActivity().getContentResolver(), Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, index); + } + return true; + } + + /** Click listener for toggle events. */ + @Override + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { + if (!Settings.System.canWrite(getContext())) { + Toast.makeText( + getContext(), + getResources().getString(R.string.toast_cannot_write_system_settings), + Toast.LENGTH_SHORT) + .show(); + return true; + } + if (preference == playDtmfTone) { + Settings.System.putInt( + getActivity().getContentResolver(), + Settings.System.DTMF_TONE_WHEN_DIALING, + playDtmfTone.isChecked() ? PLAY_DTMF_TONE : NO_DTMF_TONE); + } + return true; + } + + /** Updates the summary text on the ringtone preference with the name of the ringtone. */ + private void updateRingtonePreferenceSummary() { + SettingsUtil.updateRingtoneName( + getActivity(), + ringtoneLookupComplete, + RingtoneManager.TYPE_RINGTONE, + ringtonePreference.getKey(), + MSG_UPDATE_RINGTONE_SUMMARY); + } + + /** + * Obtain the value for "vibrate when ringing" setting. The default value is false. + * + * <p>Watch out: if the setting is missing in the device, this will try obtaining the old "vibrate + * on ring" setting from AudioManager, and save the previous setting to the new one. + */ + private boolean shouldVibrateWhenRinging() { + int vibrateWhenRingingSetting = + Settings.System.getInt( + getActivity().getContentResolver(), + Settings.System.VIBRATE_WHEN_RINGING, + NO_VIBRATION_FOR_CALLS); + return hasVibrator() && (vibrateWhenRingingSetting == DO_VIBRATION_FOR_CALLS); + } + + /** Obtains the value for dialpad/DTMF tones. The default value is true. */ + private boolean shouldPlayDtmfTone() { + int dtmfToneSetting = + Settings.System.getInt( + getActivity().getContentResolver(), + Settings.System.DTMF_TONE_WHEN_DIALING, + PLAY_DTMF_TONE); + return dtmfToneSetting == PLAY_DTMF_TONE; + } + + /** Whether the device hardware has a vibrator. */ + private boolean hasVibrator() { + Vibrator vibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE); + return vibrator != null && vibrator.hasVibrator(); + } + + private boolean shouldHideCarrierSettings() { + CarrierConfigManager configManager = + (CarrierConfigManager) getActivity().getSystemService(Context.CARRIER_CONFIG_SERVICE); + return configManager + .getConfig() + .getBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL); + } +} |