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