Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2014 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.dialer.settings;
     18 
     19 import android.content.Context;
     20 import android.media.RingtoneManager;
     21 import android.os.Build;
     22 import android.os.Bundle;
     23 import android.os.Handler;
     24 import android.os.Message;
     25 import android.os.Vibrator;
     26 import android.preference.CheckBoxPreference;
     27 import android.preference.ListPreference;
     28 import android.preference.Preference;
     29 import android.preference.PreferenceFragment;
     30 import android.preference.PreferenceScreen;
     31 import android.provider.Settings;
     32 import android.telephony.CarrierConfigManager;
     33 import android.telephony.TelephonyManager;
     34 import android.widget.Toast;
     35 
     36 import com.android.contacts.common.compat.SdkVersionOverride;
     37 import com.android.dialer.R;
     38 import com.android.dialer.compat.SettingsCompat;
     39 import com.android.phone.common.util.SettingsUtil;
     40 
     41 public class SoundSettingsFragment extends PreferenceFragment
     42         implements Preference.OnPreferenceChangeListener {
     43 
     44     private static final int NO_DTMF_TONE = 0;
     45     private static final int PLAY_DTMF_TONE = 1;
     46 
     47     private static final int NO_VIBRATION_FOR_CALLS = 0;
     48     private static final int DO_VIBRATION_FOR_CALLS = 1;
     49 
     50 
     51     private static final int DTMF_TONE_TYPE_NORMAL = 0;
     52 
     53     private static final int SHOW_CARRIER_SETTINGS = 0;
     54     private static final int HIDE_CARRIER_SETTINGS = 1;
     55 
     56     private static final int MSG_UPDATE_RINGTONE_SUMMARY = 1;
     57 
     58     private Preference mRingtonePreference;
     59     private CheckBoxPreference mVibrateWhenRinging;
     60     private CheckBoxPreference mPlayDtmfTone;
     61     private ListPreference mDtmfToneLength;
     62 
     63     private final Runnable mRingtoneLookupRunnable = new Runnable() {
     64         @Override
     65         public void run() {
     66             updateRingtonePreferenceSummary();
     67         }
     68     };
     69 
     70     private final Handler mRingtoneLookupComplete = new Handler() {
     71         @Override
     72         public void handleMessage(Message msg) {
     73             switch (msg.what) {
     74                 case MSG_UPDATE_RINGTONE_SUMMARY:
     75                     mRingtonePreference.setSummary((CharSequence) msg.obj);
     76                     break;
     77             }
     78         }
     79     };
     80 
     81     @Override
     82     public Context getContext() {
     83         return getActivity();
     84     }
     85 
     86     @Override
     87     public void onCreate(Bundle savedInstanceState) {
     88         super.onCreate(savedInstanceState);
     89 
     90         addPreferencesFromResource(R.xml.sound_settings);
     91 
     92         Context context = getActivity();
     93 
     94         mRingtonePreference = findPreference(context.getString(R.string.ringtone_preference_key));
     95         mVibrateWhenRinging = (CheckBoxPreference) findPreference(
     96                 context.getString(R.string.vibrate_on_preference_key));
     97         mPlayDtmfTone = (CheckBoxPreference) findPreference(
     98                 context.getString(R.string.play_dtmf_preference_key));
     99         mDtmfToneLength = (ListPreference) findPreference(
    100                 context.getString(R.string.dtmf_tone_length_preference_key));
    101 
    102         if (hasVibrator()) {
    103             mVibrateWhenRinging.setOnPreferenceChangeListener(this);
    104         } else {
    105             getPreferenceScreen().removePreference(mVibrateWhenRinging);
    106             mVibrateWhenRinging = null;
    107         }
    108 
    109         mPlayDtmfTone.setOnPreferenceChangeListener(this);
    110         mPlayDtmfTone.setChecked(shouldPlayDtmfTone());
    111 
    112         TelephonyManager telephonyManager =
    113                 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
    114         if (SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M) >= Build.VERSION_CODES.M
    115                 && telephonyManager.canChangeDtmfToneLength()
    116                 && (telephonyManager.isWorldPhone() || !shouldHideCarrierSettings())) {
    117             mDtmfToneLength.setOnPreferenceChangeListener(this);
    118             mDtmfToneLength.setValueIndex(
    119                     Settings.System.getInt(context.getContentResolver(),
    120                         Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
    121                         DTMF_TONE_TYPE_NORMAL));
    122         } else {
    123             getPreferenceScreen().removePreference(mDtmfToneLength);
    124             mDtmfToneLength = null;
    125         }
    126     }
    127 
    128     @Override
    129     public void onResume() {
    130         super.onResume();
    131 
    132         if (!SettingsCompat.System.canWrite(getContext())) {
    133             // If the user launches this setting fragment, then toggles the WRITE_SYSTEM_SETTINGS
    134             // AppOp, then close the fragment since there is nothing useful to do.
    135             getActivity().onBackPressed();
    136             return;
    137         }
    138 
    139         if (mVibrateWhenRinging != null) {
    140             mVibrateWhenRinging.setChecked(shouldVibrateWhenRinging());
    141         }
    142 
    143         // Lookup the ringtone name asynchronously.
    144         new Thread(mRingtoneLookupRunnable).start();
    145     }
    146 
    147     /**
    148      * Supports onPreferenceChangeListener to look for preference changes.
    149      *
    150      * @param preference The preference to be changed
    151      * @param objValue The value of the selection, NOT its localized display value.
    152      */
    153     @Override
    154     public boolean onPreferenceChange(Preference preference, Object objValue) {
    155         if (!SettingsCompat.System.canWrite(getContext())) {
    156             // A user shouldn't be able to get here, but this protects against monkey crashes.
    157             Toast.makeText(
    158                     getContext(),
    159                     getResources().getString(R.string.toast_cannot_write_system_settings),
    160                     Toast.LENGTH_SHORT).show();
    161             return true;
    162         }
    163         if (preference == mVibrateWhenRinging) {
    164             boolean doVibrate = (Boolean) objValue;
    165             Settings.System.putInt(getActivity().getContentResolver(),
    166                     Settings.System.VIBRATE_WHEN_RINGING,
    167                     doVibrate ? DO_VIBRATION_FOR_CALLS : NO_VIBRATION_FOR_CALLS);
    168         } else if (preference == mDtmfToneLength) {
    169             int index = mDtmfToneLength.findIndexOfValue((String) objValue);
    170             Settings.System.putInt(getActivity().getContentResolver(),
    171                     Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, index);
    172         }
    173         return true;
    174     }
    175 
    176     /**
    177      * Click listener for toggle events.
    178      */
    179     @Override
    180     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
    181         if (!SettingsCompat.System.canWrite(getContext())) {
    182             Toast.makeText(
    183                     getContext(),
    184                     getResources().getString(R.string.toast_cannot_write_system_settings),
    185                     Toast.LENGTH_SHORT).show();
    186             return true;
    187         }
    188         if (preference == mPlayDtmfTone) {
    189             Settings.System.putInt(getActivity().getContentResolver(),
    190                     Settings.System.DTMF_TONE_WHEN_DIALING,
    191                     mPlayDtmfTone.isChecked() ? PLAY_DTMF_TONE : NO_DTMF_TONE);
    192         }
    193         return true;
    194     }
    195 
    196     /**
    197      * Updates the summary text on the ringtone preference with the name of the ringtone.
    198      */
    199     private void updateRingtonePreferenceSummary() {
    200         SettingsUtil.updateRingtoneName(
    201                 getActivity(),
    202                 mRingtoneLookupComplete,
    203                 RingtoneManager.TYPE_RINGTONE,
    204                 mRingtonePreference.getKey(),
    205                 MSG_UPDATE_RINGTONE_SUMMARY);
    206     }
    207 
    208     /**
    209      * Obtain the value for "vibrate when ringing" setting. The default value is false.
    210      *
    211      * Watch out: if the setting is missing in the device, this will try obtaining the old
    212      * "vibrate on ring" setting from AudioManager, and save the previous setting to the new one.
    213      */
    214     private boolean shouldVibrateWhenRinging() {
    215         int vibrateWhenRingingSetting = Settings.System.getInt(getActivity().getContentResolver(),
    216                 Settings.System.VIBRATE_WHEN_RINGING,
    217                 NO_VIBRATION_FOR_CALLS);
    218         return hasVibrator() && (vibrateWhenRingingSetting == DO_VIBRATION_FOR_CALLS);
    219     }
    220 
    221     /**
    222      * Obtains the value for dialpad/DTMF tones. The default value is true.
    223      */
    224     private boolean shouldPlayDtmfTone() {
    225         int dtmfToneSetting = Settings.System.getInt(getActivity().getContentResolver(),
    226                 Settings.System.DTMF_TONE_WHEN_DIALING,
    227                 PLAY_DTMF_TONE);
    228         return dtmfToneSetting == PLAY_DTMF_TONE;
    229     }
    230 
    231     /**
    232      * Whether the device hardware has a vibrator.
    233      */
    234     private boolean hasVibrator() {
    235         Vibrator vibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
    236         return vibrator != null && vibrator.hasVibrator();
    237     }
    238 
    239     private boolean shouldHideCarrierSettings() {
    240         CarrierConfigManager configManager = (CarrierConfigManager) getActivity().getSystemService(
    241                 Context.CARRIER_CONFIG_SERVICE);
    242         return configManager.getConfig().getBoolean(
    243                 CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL);
    244     }
    245 }
    246