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