Home | History | Annotate | Download | only in notification
      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.settings.notification;
     18 
     19 import android.content.ContentResolver;
     20 import android.content.Context;
     21 import android.content.res.Resources;
     22 import android.database.ContentObserver;
     23 import android.media.AudioManager;
     24 import android.net.Uri;
     25 import android.os.AsyncTask;
     26 import android.os.Bundle;
     27 import android.os.Handler;
     28 import android.os.SystemProperties;
     29 import android.os.Vibrator;
     30 import android.provider.SearchIndexableResource;
     31 import android.provider.Settings.Global;
     32 import android.provider.Settings.System;
     33 import android.support.v14.preference.SwitchPreference;
     34 import android.support.v7.preference.Preference;
     35 import android.telephony.TelephonyManager;
     36 
     37 import com.android.internal.logging.MetricsProto.MetricsEvent;
     38 import com.android.settings.R;
     39 import com.android.settings.SettingsPreferenceFragment;
     40 import com.android.settings.Utils;
     41 import com.android.settings.search.BaseSearchIndexProvider;
     42 import com.android.settings.search.Indexable;
     43 
     44 import java.util.ArrayList;
     45 import java.util.Arrays;
     46 import java.util.List;
     47 
     48 import static com.android.settings.notification.SettingPref.TYPE_GLOBAL;
     49 import static com.android.settings.notification.SettingPref.TYPE_SYSTEM;
     50 
     51 public class OtherSoundSettings extends SettingsPreferenceFragment implements Indexable {
     52     private static final String TAG = "OtherSoundSettings";
     53 
     54     private static final int DEFAULT_ON = 1;
     55 
     56     private static final int EMERGENCY_TONE_SILENT = 0;
     57     private static final int EMERGENCY_TONE_ALERT = 1;
     58     private static final int EMERGENCY_TONE_VIBRATE = 2;
     59     private static final int DEFAULT_EMERGENCY_TONE = EMERGENCY_TONE_SILENT;
     60 
     61     private static final int DOCK_AUDIO_MEDIA_DISABLED = 0;
     62     private static final int DOCK_AUDIO_MEDIA_ENABLED = 1;
     63     private static final int DEFAULT_DOCK_AUDIO_MEDIA = DOCK_AUDIO_MEDIA_DISABLED;
     64 
     65     private static final String KEY_DIAL_PAD_TONES = "dial_pad_tones";
     66     private static final String KEY_SCREEN_LOCKING_SOUNDS = "screen_locking_sounds";
     67     private static final String KEY_CHARGING_SOUNDS = "charging_sounds";
     68     private static final String KEY_DOCKING_SOUNDS = "docking_sounds";
     69     private static final String KEY_TOUCH_SOUNDS = "touch_sounds";
     70     private static final String KEY_VIBRATE_ON_TOUCH = "vibrate_on_touch";
     71     private static final String KEY_DOCK_AUDIO_MEDIA = "dock_audio_media";
     72     private static final String KEY_EMERGENCY_TONE = "emergency_tone";
     73 
     74     // Boot Sounds needs to be a system property so it can be accessed during boot.
     75     private static final String KEY_BOOT_SOUNDS = "boot_sounds";
     76     private static final String PROPERTY_BOOT_SOUNDS = "persist.sys.bootanim.play_sound";
     77 
     78     private static final SettingPref PREF_DIAL_PAD_TONES = new SettingPref(
     79             TYPE_SYSTEM, KEY_DIAL_PAD_TONES, System.DTMF_TONE_WHEN_DIALING, DEFAULT_ON) {
     80         @Override
     81         public boolean isApplicable(Context context) {
     82             return Utils.isVoiceCapable(context);
     83         }
     84     };
     85 
     86     private static final SettingPref PREF_SCREEN_LOCKING_SOUNDS = new SettingPref(
     87             TYPE_SYSTEM, KEY_SCREEN_LOCKING_SOUNDS, System.LOCKSCREEN_SOUNDS_ENABLED, DEFAULT_ON);
     88 
     89     private static final SettingPref PREF_CHARGING_SOUNDS = new SettingPref(
     90             TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_ON);
     91 
     92     private static final SettingPref PREF_DOCKING_SOUNDS = new SettingPref(
     93             TYPE_GLOBAL, KEY_DOCKING_SOUNDS, Global.DOCK_SOUNDS_ENABLED, DEFAULT_ON) {
     94         @Override
     95         public boolean isApplicable(Context context) {
     96             return hasDockSettings(context);
     97         }
     98     };
     99 
    100     private static final SettingPref PREF_TOUCH_SOUNDS = new SettingPref(
    101             TYPE_SYSTEM, KEY_TOUCH_SOUNDS, System.SOUND_EFFECTS_ENABLED, DEFAULT_ON) {
    102         @Override
    103         protected boolean setSetting(final Context context, final int value) {
    104             AsyncTask.execute(new Runnable() {
    105                 @Override
    106                 public void run() {
    107                     final AudioManager am =
    108                             (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    109                     if (value != 0) {
    110                         am.loadSoundEffects();
    111                     } else {
    112                         am.unloadSoundEffects();
    113                     }
    114                 }
    115             });
    116             return super.setSetting(context, value);
    117         }
    118     };
    119 
    120     private static final SettingPref PREF_VIBRATE_ON_TOUCH = new SettingPref(
    121             TYPE_SYSTEM, KEY_VIBRATE_ON_TOUCH, System.HAPTIC_FEEDBACK_ENABLED, DEFAULT_ON) {
    122         @Override
    123         public boolean isApplicable(Context context) {
    124             return hasHaptic(context);
    125         }
    126     };
    127 
    128     private static final SettingPref PREF_DOCK_AUDIO_MEDIA = new SettingPref(
    129             TYPE_GLOBAL, KEY_DOCK_AUDIO_MEDIA, Global.DOCK_AUDIO_MEDIA_ENABLED,
    130             DEFAULT_DOCK_AUDIO_MEDIA, DOCK_AUDIO_MEDIA_DISABLED, DOCK_AUDIO_MEDIA_ENABLED) {
    131         @Override
    132         public boolean isApplicable(Context context) {
    133             return hasDockSettings(context);
    134         }
    135 
    136         @Override
    137         protected String getCaption(Resources res, int value) {
    138             switch(value) {
    139                 case DOCK_AUDIO_MEDIA_DISABLED:
    140                     return res.getString(R.string.dock_audio_media_disabled);
    141                 case DOCK_AUDIO_MEDIA_ENABLED:
    142                     return res.getString(R.string.dock_audio_media_enabled);
    143                 default:
    144                     throw new IllegalArgumentException();
    145             }
    146         }
    147     };
    148 
    149     private static final SettingPref PREF_EMERGENCY_TONE = new SettingPref(
    150             TYPE_GLOBAL, KEY_EMERGENCY_TONE, Global.EMERGENCY_TONE, DEFAULT_EMERGENCY_TONE,
    151             EMERGENCY_TONE_ALERT, EMERGENCY_TONE_VIBRATE, EMERGENCY_TONE_SILENT) {
    152         @Override
    153         public boolean isApplicable(Context context) {
    154             final int activePhoneType = TelephonyManager.getDefault().getCurrentPhoneType();
    155             return activePhoneType == TelephonyManager.PHONE_TYPE_CDMA;
    156         }
    157 
    158         @Override
    159         protected String getCaption(Resources res, int value) {
    160             switch(value) {
    161                 case EMERGENCY_TONE_SILENT:
    162                     return res.getString(R.string.emergency_tone_silent);
    163                 case EMERGENCY_TONE_ALERT:
    164                     return res.getString(R.string.emergency_tone_alert);
    165                 case EMERGENCY_TONE_VIBRATE:
    166                     return res.getString(R.string.emergency_tone_vibrate);
    167                 default:
    168                     throw new IllegalArgumentException();
    169             }
    170         }
    171     };
    172 
    173     private static final SettingPref[] PREFS = {
    174         PREF_DIAL_PAD_TONES,
    175         PREF_SCREEN_LOCKING_SOUNDS,
    176         PREF_CHARGING_SOUNDS,
    177         PREF_DOCKING_SOUNDS,
    178         PREF_TOUCH_SOUNDS,
    179         PREF_VIBRATE_ON_TOUCH,
    180         PREF_DOCK_AUDIO_MEDIA,
    181         PREF_EMERGENCY_TONE,
    182     };
    183 
    184     private SwitchPreference mBootSounds;
    185 
    186     private final SettingsObserver mSettingsObserver = new SettingsObserver();
    187 
    188     private Context mContext;
    189 
    190     @Override
    191     protected int getMetricsCategory() {
    192         return MetricsEvent.NOTIFICATION_OTHER_SOUND;
    193     }
    194 
    195     @Override
    196     protected int getHelpResource() {
    197         return R.string.help_uri_other_sounds;
    198     }
    199 
    200     @Override
    201     public void onCreate(Bundle savedInstanceState) {
    202         super.onCreate(savedInstanceState);
    203 
    204         addPreferencesFromResource(R.xml.other_sound_settings);
    205 
    206         mContext = getActivity();
    207 
    208         for (SettingPref pref : PREFS) {
    209             pref.init(this);
    210         }
    211 
    212         mBootSounds = (SwitchPreference) findPreference(KEY_BOOT_SOUNDS);
    213         mBootSounds.setChecked(SystemProperties.getBoolean(PROPERTY_BOOT_SOUNDS, true));
    214     }
    215 
    216     @Override
    217     public void onResume() {
    218         super.onResume();
    219         mSettingsObserver.register(true);
    220     }
    221 
    222     @Override
    223     public void onPause() {
    224         super.onPause();
    225         mSettingsObserver.register(false);
    226     }
    227 
    228     @Override
    229     public boolean onPreferenceTreeClick(Preference preference) {
    230         if (preference == mBootSounds) {
    231             SystemProperties.set(PROPERTY_BOOT_SOUNDS, mBootSounds.isChecked() ? "1" : "0");
    232             return false;
    233         } else {
    234             return super.onPreferenceTreeClick(preference);
    235         }
    236     }
    237 
    238     private static boolean hasDockSettings(Context context) {
    239         return context.getResources().getBoolean(R.bool.has_dock_settings);
    240     }
    241 
    242     private static boolean hasHaptic(Context context) {
    243         final Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    244         return vibrator != null && vibrator.hasVibrator();
    245     }
    246 
    247     // === Callbacks ===
    248 
    249     private final class SettingsObserver extends ContentObserver {
    250         public SettingsObserver() {
    251             super(new Handler());
    252         }
    253 
    254         public void register(boolean register) {
    255             final ContentResolver cr = getContentResolver();
    256             if (register) {
    257                 for (SettingPref pref : PREFS) {
    258                     cr.registerContentObserver(pref.getUri(), false, this);
    259                 }
    260             } else {
    261                 cr.unregisterContentObserver(this);
    262             }
    263         }
    264 
    265         @Override
    266         public void onChange(boolean selfChange, Uri uri) {
    267             super.onChange(selfChange, uri);
    268             for (SettingPref pref : PREFS) {
    269                 if (pref.getUri().equals(uri)) {
    270                     pref.update(mContext);
    271                     return;
    272                 }
    273             }
    274         }
    275     }
    276 
    277     // === Indexing ===
    278 
    279     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
    280             new BaseSearchIndexProvider() {
    281 
    282         public List<SearchIndexableResource> getXmlResourcesToIndex(
    283                 Context context, boolean enabled) {
    284             final SearchIndexableResource sir = new SearchIndexableResource(context);
    285             sir.xmlResId = R.xml.other_sound_settings;
    286             return Arrays.asList(sir);
    287         }
    288 
    289         public List<String> getNonIndexableKeys(Context context) {
    290             final ArrayList<String> rt = new ArrayList<String>();
    291             for (SettingPref pref : PREFS) {
    292                 if (!pref.isApplicable(context)) {
    293                     rt.add(pref.getKey());
    294                 }
    295             }
    296             return rt;
    297         }
    298     };
    299 }
    300