Home | History | Annotate | Download | only in cellbroadcastreceiver
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * 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, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.android.cellbroadcastreceiver;
     18 
     19 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.os.Bundle;
     22 import android.os.PersistableBundle;
     23 import android.os.UserManager;
     24 import android.preference.CheckBoxPreference;
     25 import android.preference.ListPreference;
     26 import android.preference.Preference;
     27 import android.preference.PreferenceActivity;
     28 import android.preference.PreferenceCategory;
     29 import android.preference.PreferenceFragment;
     30 import android.preference.PreferenceScreen;
     31 import android.provider.Settings;
     32 import android.telephony.CarrierConfigManager;
     33 import android.telephony.SubscriptionManager;
     34 import android.telephony.TelephonyManager;
     35 import android.util.Log;
     36 
     37 /**
     38  * Settings activity for the cell broadcast receiver.
     39  */
     40 public class CellBroadcastSettings extends PreferenceActivity {
     41 
     42     private static final String TAG = "CellBroadcastSettings";
     43 
     44     // Preference key for whether to enable emergency notifications (default enabled).
     45     public static final String KEY_ENABLE_EMERGENCY_ALERTS = "enable_emergency_alerts";
     46 
     47     // Duration of alert sound (in seconds).
     48     public static final String KEY_ALERT_SOUND_DURATION = "alert_sound_duration";
     49 
     50     // Default alert duration (in seconds).
     51     public static final String ALERT_SOUND_DEFAULT_DURATION = "4";
     52 
     53     // Enable vibration on alert (unless master volume is silent).
     54     public static final String KEY_ENABLE_ALERT_VIBRATE = "enable_alert_vibrate";
     55 
     56     // Speak contents of alert after playing the alert sound.
     57     public static final String KEY_ENABLE_ALERT_SPEECH = "enable_alert_speech";
     58 
     59     // Preference category for emergency alert and CMAS settings.
     60     public static final String KEY_CATEGORY_ALERT_SETTINGS = "category_alert_settings";
     61 
     62     // Preference category for ETWS related settings.
     63     public static final String KEY_CATEGORY_ETWS_SETTINGS = "category_etws_settings";
     64 
     65     // Whether to display CMAS extreme threat notifications (default is enabled).
     66     public static final String KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS =
     67             "enable_cmas_extreme_threat_alerts";
     68 
     69     // Whether to display CMAS severe threat notifications (default is enabled).
     70     public static final String KEY_ENABLE_CMAS_SEVERE_THREAT_ALERTS =
     71             "enable_cmas_severe_threat_alerts";
     72 
     73     // Whether to display CMAS amber alert messages (default is enabled).
     74     public static final String KEY_ENABLE_CMAS_AMBER_ALERTS = "enable_cmas_amber_alerts";
     75 
     76     // Preference category for development settings (enabled by settings developer options toggle).
     77     public static final String KEY_CATEGORY_DEV_SETTINGS = "category_dev_settings";
     78 
     79     // Whether to display ETWS test messages (default is disabled).
     80     public static final String KEY_ENABLE_ETWS_TEST_ALERTS = "enable_etws_test_alerts";
     81 
     82     // Whether to display CMAS monthly test messages (default is disabled).
     83     public static final String KEY_ENABLE_CMAS_TEST_ALERTS = "enable_cmas_test_alerts";
     84 
     85     // Preference category for Brazil specific settings.
     86     public static final String KEY_CATEGORY_BRAZIL_SETTINGS = "category_brazil_settings";
     87 
     88     // Preference key for whether to enable channel 50 notifications
     89     // Enabled by default for phones sold in Brazil, otherwise this setting may be hidden.
     90     public static final String KEY_ENABLE_CHANNEL_50_ALERTS = "enable_channel_50_alerts";
     91 
     92     // Preference key for initial opt-in/opt-out dialog.
     93     public static final String KEY_SHOW_CMAS_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog";
     94 
     95     // Alert reminder interval ("once" = single 2 minute reminder).
     96     public static final String KEY_ALERT_REMINDER_INTERVAL = "alert_reminder_interval";
     97 
     98     // Default reminder interval.
     99     public static final String ALERT_REMINDER_INTERVAL = "0";
    100 
    101     // First time use
    102     public static final String KEY_FIRST_TIME = "first_time";
    103 
    104     // Brazil country code
    105     private static final String COUNTRY_BRAZIL = "br";
    106 
    107     @Override
    108     public void onCreate(Bundle savedInstanceState) {
    109         super.onCreate(savedInstanceState);
    110 
    111         UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
    112         if (userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS)) {
    113             setContentView(R.layout.cell_broadcast_disallowed_preference_screen);
    114             return;
    115         }
    116 
    117         // Display the fragment as the main content.
    118         getFragmentManager().beginTransaction().replace(android.R.id.content,
    119                 new CellBroadcastSettingsFragment()).commit();
    120     }
    121 
    122     /**
    123      * New fragment-style implementation of preferences.
    124      */
    125     public static class CellBroadcastSettingsFragment extends PreferenceFragment {
    126 
    127         private CheckBoxPreference mExtremeCheckBox;
    128         private CheckBoxPreference mSevereCheckBox;
    129         private CheckBoxPreference mAmberCheckBox;
    130         private CheckBoxPreference mEmergencyCheckBox;
    131         private ListPreference mAlertDuration;
    132         private ListPreference mReminderInterval;
    133         private CheckBoxPreference mSpeechCheckBox;
    134         private CheckBoxPreference mEtwsTestCheckBox;
    135         private CheckBoxPreference mChannel50CheckBox;
    136         private CheckBoxPreference mCmasTestCheckBox;
    137         private PreferenceCategory mAlertCategory;
    138         private PreferenceCategory mETWSSettingCategory;
    139 
    140         @Override
    141         public void onCreate(Bundle savedInstanceState) {
    142             super.onCreate(savedInstanceState);
    143 
    144             // Load the preferences from an XML resource
    145             addPreferencesFromResource(R.xml.preferences);
    146 
    147             PreferenceScreen preferenceScreen = getPreferenceScreen();
    148 
    149             mExtremeCheckBox = (CheckBoxPreference)
    150                     findPreference(KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS);
    151             mSevereCheckBox = (CheckBoxPreference)
    152                     findPreference(KEY_ENABLE_CMAS_SEVERE_THREAT_ALERTS);
    153             mAmberCheckBox = (CheckBoxPreference)
    154                     findPreference(KEY_ENABLE_CMAS_AMBER_ALERTS);
    155             mEmergencyCheckBox = (CheckBoxPreference)
    156                     findPreference(KEY_ENABLE_EMERGENCY_ALERTS);
    157             mAlertDuration = (ListPreference)
    158                     findPreference(KEY_ALERT_SOUND_DURATION);
    159             mReminderInterval = (ListPreference)
    160                     findPreference(KEY_ALERT_REMINDER_INTERVAL);
    161             mSpeechCheckBox = (CheckBoxPreference)
    162                     findPreference(KEY_ENABLE_ALERT_SPEECH);
    163             mEtwsTestCheckBox = (CheckBoxPreference)
    164                     findPreference(KEY_ENABLE_ETWS_TEST_ALERTS);
    165             mChannel50CheckBox = (CheckBoxPreference)
    166                     findPreference(KEY_ENABLE_CHANNEL_50_ALERTS);
    167             mCmasTestCheckBox = (CheckBoxPreference)
    168                     findPreference(KEY_ENABLE_CMAS_TEST_ALERTS);
    169             mAlertCategory = (PreferenceCategory)
    170                     findPreference(KEY_CATEGORY_ALERT_SETTINGS);
    171             mETWSSettingCategory = (PreferenceCategory)
    172                     findPreference(KEY_CATEGORY_ETWS_SETTINGS);
    173 
    174             // Handler for settings that require us to reconfigure enabled channels in radio
    175             Preference.OnPreferenceChangeListener startConfigServiceListener =
    176                     new Preference.OnPreferenceChangeListener() {
    177                         @Override
    178                         public boolean onPreferenceChange(Preference pref, Object newValue) {
    179                             CellBroadcastReceiver.startConfigService(pref.getContext());
    180 
    181                             if (pref.getKey().equals(KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS)) {
    182                                 boolean isExtremeAlertChecked = (Boolean)newValue;
    183                                 if (mSevereCheckBox != null) {
    184                                     mSevereCheckBox.setEnabled(isExtremeAlertChecked);
    185                                     mSevereCheckBox.setChecked(false);
    186                                 }
    187                             }
    188 
    189                             return true;
    190                         }
    191                     };
    192 
    193             // Show extra settings when developer options is enabled in settings.
    194             boolean enableDevSettings = Settings.Global.getInt(getActivity().getContentResolver(),
    195                     Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
    196 
    197             Resources res = getResources();
    198             boolean showEtwsSettings = res.getBoolean(R.bool.show_etws_settings);
    199 
    200             // alert reminder interval
    201             mReminderInterval.setSummary(mReminderInterval.getEntry());
    202             mReminderInterval.setOnPreferenceChangeListener(
    203                     new Preference.OnPreferenceChangeListener() {
    204                 @Override
    205                 public boolean onPreferenceChange(Preference pref, Object newValue) {
    206                     final ListPreference listPref = (ListPreference) pref;
    207                     final int idx = listPref.findIndexOfValue((String) newValue);
    208                     listPref.setSummary(listPref.getEntries()[idx]);
    209                     return true;
    210                 }
    211             });
    212 
    213             boolean forceDisableEtwsCmasTest =
    214                     isEtwsCmasTestMessageForcedDisabled(getActivity());
    215 
    216             boolean emergencyAlertOnOffOptionEnabled =
    217                     isEmergencyAlertOnOffOptionEnabled(getActivity());
    218 
    219             if (enableDevSettings || showEtwsSettings || emergencyAlertOnOffOptionEnabled) {
    220                 // enable/disable all alerts except CMAS presidential alerts.
    221                 if (mEmergencyCheckBox != null) {
    222                     mEmergencyCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    223                 }
    224             } else {
    225                 mAlertCategory.removePreference(mEmergencyCheckBox);
    226             }
    227 
    228             // Show alert settings and ETWS categories for ETWS builds and developer mode.
    229             if (enableDevSettings || showEtwsSettings) {
    230                 // alert sound duration
    231                 ListPreference duration = mAlertDuration;
    232                 duration.setSummary(duration.getEntry());
    233                 duration.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
    234                     @Override
    235                     public boolean onPreferenceChange(Preference pref, Object newValue) {
    236                         final ListPreference listPref = (ListPreference) pref;
    237                         final int idx = listPref.findIndexOfValue((String) newValue);
    238                         listPref.setSummary(listPref.getEntries()[idx]);
    239                         return true;
    240                     }
    241                 });
    242 
    243                 if (forceDisableEtwsCmasTest) {
    244                     // Remove ETWS test preference.
    245                     preferenceScreen.removePreference(mETWSSettingCategory);
    246 
    247                     PreferenceCategory devSettingCategory =
    248                             (PreferenceCategory) findPreference(KEY_CATEGORY_DEV_SETTINGS);
    249 
    250                     // Remove CMAS test preference.
    251                     if (devSettingCategory != null) {
    252                         devSettingCategory.removePreference(mCmasTestCheckBox);
    253                     }
    254                 }
    255             } else {
    256                 mAlertCategory.removePreference(mAlertDuration);
    257                 mAlertCategory.removePreference(mSpeechCheckBox);
    258                 // Remove ETWS test preference category.
    259                 preferenceScreen.removePreference(mETWSSettingCategory);
    260             }
    261 
    262             if (!res.getBoolean(R.bool.show_cmas_settings)) {
    263                 // Remove CMAS preference items in emergency alert category.
    264                 mAlertCategory.removePreference(mExtremeCheckBox);
    265                 mAlertCategory.removePreference(mSevereCheckBox);
    266                 mAlertCategory.removePreference(mAmberCheckBox);
    267             }
    268 
    269             TelephonyManager tm = (TelephonyManager) getActivity().getSystemService(
    270                     Context.TELEPHONY_SERVICE);
    271 
    272             int subId = SubscriptionManager.getDefaultSmsSubscriptionId();
    273             if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
    274                 subId = SubscriptionManager.getDefaultSubscriptionId();
    275             }
    276 
    277             boolean enableChannel50Support = res.getBoolean(R.bool.show_brazil_settings) ||
    278                     COUNTRY_BRAZIL.equals(tm.getSimCountryIso(subId));
    279 
    280             if (!enableChannel50Support) {
    281                 preferenceScreen.removePreference(findPreference(KEY_CATEGORY_BRAZIL_SETTINGS));
    282             }
    283             if (!enableDevSettings) {
    284                 preferenceScreen.removePreference(findPreference(KEY_CATEGORY_DEV_SETTINGS));
    285             }
    286 
    287             if (mChannel50CheckBox != null) {
    288                 mChannel50CheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    289             }
    290             if (mEtwsTestCheckBox != null) {
    291                 mEtwsTestCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    292             }
    293             if (mExtremeCheckBox != null) {
    294                 mExtremeCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    295             }
    296             if (mSevereCheckBox != null) {
    297                 mSevereCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    298                 if (mExtremeCheckBox != null) {
    299                     mSevereCheckBox.setEnabled(mExtremeCheckBox.isChecked());
    300                 }
    301             }
    302             if (mAmberCheckBox != null) {
    303                 mAmberCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    304             }
    305             if (mCmasTestCheckBox != null) {
    306                 mCmasTestCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    307             }
    308         }
    309     }
    310 
    311     // Check if ETWS/CMAS test message is forced disabled on the device.
    312     public static boolean isEtwsCmasTestMessageForcedDisabled(Context context) {
    313 
    314         if (context == null) {
    315             return false;
    316         }
    317 
    318         int subId = SubscriptionManager.getDefaultSmsSubscriptionId();
    319         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
    320             subId = SubscriptionManager.getDefaultSubscriptionId();
    321             if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
    322                 return false;
    323         }
    324 
    325         CarrierConfigManager configManager =
    326                 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
    327 
    328         if (configManager != null) {
    329             PersistableBundle carrierConfig =
    330                     configManager.getConfigForSubId(subId);
    331 
    332             if (carrierConfig != null) {
    333                 return carrierConfig.getBoolean(
    334                         CarrierConfigManager.KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL);
    335             }
    336         }
    337 
    338         return false;
    339     }
    340 
    341     // Check if "Turn on Notifications" option should be always displayed regardless of developer
    342     // options turned on or not.
    343     public static boolean isEmergencyAlertOnOffOptionEnabled(Context context) {
    344 
    345         if (context == null) {
    346             return false;
    347         }
    348 
    349         int subId = SubscriptionManager.getDefaultSmsSubscriptionId();
    350         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
    351             subId = SubscriptionManager.getDefaultSubscriptionId();
    352             if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
    353                 return false;
    354         }
    355 
    356         CarrierConfigManager configManager =
    357                 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
    358 
    359         if (configManager != null) {
    360             PersistableBundle carrierConfig =
    361                     configManager.getConfigForSubId(subId);
    362 
    363             if (carrierConfig != null) {
    364                 return carrierConfig.getBoolean(
    365                     CarrierConfigManager.KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL);
    366             }
    367         }
    368 
    369         return false;
    370     }
    371 }
    372