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     private static final boolean DBG = false;
     45 
     46     // Preference key for whether to enable emergency notifications (default enabled).
     47     public static final String KEY_ENABLE_EMERGENCY_ALERTS = "enable_emergency_alerts";
     48 
     49     // Enable vibration on alert (unless master volume is silent).
     50     public static final String KEY_ENABLE_ALERT_VIBRATE = "enable_alert_vibrate";
     51 
     52     // Speak contents of alert after playing the alert sound.
     53     public static final String KEY_ENABLE_ALERT_SPEECH = "enable_alert_speech";
     54 
     55     // Preference category for emergency alert and CMAS settings.
     56     public static final String KEY_CATEGORY_ALERT_SETTINGS = "category_alert_settings";
     57 
     58     // Preference category for ETWS related settings.
     59     public static final String KEY_CATEGORY_ETWS_SETTINGS = "category_etws_settings";
     60 
     61     // Whether to display CMAS extreme threat notifications (default is enabled).
     62     public static final String KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS =
     63             "enable_cmas_extreme_threat_alerts";
     64 
     65     // Whether to display CMAS severe threat notifications (default is enabled).
     66     public static final String KEY_ENABLE_CMAS_SEVERE_THREAT_ALERTS =
     67             "enable_cmas_severe_threat_alerts";
     68 
     69     // Whether to display CMAS amber alert messages (default is enabled).
     70     public static final String KEY_ENABLE_CMAS_AMBER_ALERTS = "enable_cmas_amber_alerts";
     71 
     72     // Preference category for development settings (enabled by settings developer options toggle).
     73     public static final String KEY_CATEGORY_DEV_SETTINGS = "category_dev_settings";
     74 
     75     // Whether to display ETWS test messages (default is disabled).
     76     public static final String KEY_ENABLE_ETWS_TEST_ALERTS = "enable_etws_test_alerts";
     77 
     78     // Whether to display CMAS monthly test messages (default is disabled).
     79     public static final String KEY_ENABLE_CMAS_TEST_ALERTS = "enable_cmas_test_alerts";
     80 
     81     // Preference category for Brazil specific settings.
     82     public static final String KEY_CATEGORY_BRAZIL_SETTINGS = "category_brazil_settings";
     83 
     84     // Preference key for whether to enable channel 50 notifications
     85     // Enabled by default for phones sold in Brazil, otherwise this setting may be hidden.
     86     public static final String KEY_ENABLE_CHANNEL_50_ALERTS = "enable_channel_50_alerts";
     87 
     88     // Preference key for initial opt-in/opt-out dialog.
     89     public static final String KEY_SHOW_CMAS_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog";
     90 
     91     // Alert reminder interval ("once" = single 2 minute reminder).
     92     public static final String KEY_ALERT_REMINDER_INTERVAL = "alert_reminder_interval";
     93 
     94     // Brazil country code
     95     private static final String COUNTRY_BRAZIL = "br";
     96 
     97     @Override
     98     public void onCreate(Bundle savedInstanceState) {
     99         super.onCreate(savedInstanceState);
    100 
    101         UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
    102         if (userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS)) {
    103             setContentView(R.layout.cell_broadcast_disallowed_preference_screen);
    104             return;
    105         }
    106 
    107         // Display the fragment as the main content.
    108         getFragmentManager().beginTransaction().replace(android.R.id.content,
    109                 new CellBroadcastSettingsFragment()).commit();
    110     }
    111 
    112     /**
    113      * New fragment-style implementation of preferences.
    114      */
    115     public static class CellBroadcastSettingsFragment extends PreferenceFragment {
    116 
    117         private CheckBoxPreference mExtremeCheckBox;
    118         private CheckBoxPreference mSevereCheckBox;
    119         private CheckBoxPreference mAmberCheckBox;
    120         private CheckBoxPreference mEmergencyCheckBox;
    121         private ListPreference mReminderInterval;
    122         private CheckBoxPreference mSpeechCheckBox;
    123         private CheckBoxPreference mEtwsTestCheckBox;
    124         private CheckBoxPreference mChannel50CheckBox;
    125         private CheckBoxPreference mCmasTestCheckBox;
    126         private PreferenceCategory mAlertCategory;
    127         private PreferenceCategory mETWSSettingCategory;
    128         private boolean mDisableSevereWhenExtremeDisabled = true;
    129 
    130         @Override
    131         public void onCreate(Bundle savedInstanceState) {
    132             super.onCreate(savedInstanceState);
    133 
    134             // Load the preferences from an XML resource
    135             addPreferencesFromResource(R.xml.preferences);
    136 
    137             PreferenceScreen preferenceScreen = getPreferenceScreen();
    138 
    139             mExtremeCheckBox = (CheckBoxPreference)
    140                     findPreference(KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS);
    141             mSevereCheckBox = (CheckBoxPreference)
    142                     findPreference(KEY_ENABLE_CMAS_SEVERE_THREAT_ALERTS);
    143             mAmberCheckBox = (CheckBoxPreference)
    144                     findPreference(KEY_ENABLE_CMAS_AMBER_ALERTS);
    145             mEmergencyCheckBox = (CheckBoxPreference)
    146                     findPreference(KEY_ENABLE_EMERGENCY_ALERTS);
    147             mReminderInterval = (ListPreference)
    148                     findPreference(KEY_ALERT_REMINDER_INTERVAL);
    149             mSpeechCheckBox = (CheckBoxPreference)
    150                     findPreference(KEY_ENABLE_ALERT_SPEECH);
    151             mEtwsTestCheckBox = (CheckBoxPreference)
    152                     findPreference(KEY_ENABLE_ETWS_TEST_ALERTS);
    153             mChannel50CheckBox = (CheckBoxPreference)
    154                     findPreference(KEY_ENABLE_CHANNEL_50_ALERTS);
    155             mCmasTestCheckBox = (CheckBoxPreference)
    156                     findPreference(KEY_ENABLE_CMAS_TEST_ALERTS);
    157             mAlertCategory = (PreferenceCategory)
    158                     findPreference(KEY_CATEGORY_ALERT_SETTINGS);
    159             mETWSSettingCategory = (PreferenceCategory)
    160                     findPreference(KEY_CATEGORY_ETWS_SETTINGS);
    161 
    162             mDisableSevereWhenExtremeDisabled = isFeatureEnabled(getContext(),
    163                     CarrierConfigManager.KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true);
    164 
    165             // Handler for settings that require us to reconfigure enabled channels in radio
    166             Preference.OnPreferenceChangeListener startConfigServiceListener =
    167                     new Preference.OnPreferenceChangeListener() {
    168                         @Override
    169                         public boolean onPreferenceChange(Preference pref, Object newValue) {
    170                             CellBroadcastReceiver.startConfigService(pref.getContext());
    171 
    172                             if (mDisableSevereWhenExtremeDisabled) {
    173                                 if (pref.getKey().equals(KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS)) {
    174                                     boolean isExtremeAlertChecked = (Boolean)newValue;
    175                                     if (mSevereCheckBox != null) {
    176                                         mSevereCheckBox.setEnabled(isExtremeAlertChecked);
    177                                         mSevereCheckBox.setChecked(false);
    178                                     }
    179                                 }
    180                             }
    181 
    182                             return true;
    183                         }
    184                     };
    185 
    186             // Show extra settings when developer options is enabled in settings.
    187             boolean enableDevSettings = Settings.Global.getInt(getContext().getContentResolver(),
    188                     Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
    189 
    190             Resources res = getResources();
    191             boolean showEtwsSettings = res.getBoolean(R.bool.show_etws_settings);
    192 
    193             initReminderIntervalList();
    194 
    195             boolean forceDisableEtwsCmasTest = CellBroadcastSettings.isFeatureEnabled(getContext(),
    196                     CarrierConfigManager.KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false);
    197 
    198             boolean emergencyAlertOnOffOptionEnabled = isFeatureEnabled(getContext(),
    199                     CarrierConfigManager.KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
    200 
    201             if (enableDevSettings || showEtwsSettings || emergencyAlertOnOffOptionEnabled) {
    202                 // enable/disable all alerts except CMAS presidential alerts.
    203                 if (mEmergencyCheckBox != null) {
    204                     mEmergencyCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    205                 }
    206             } else {
    207                 mAlertCategory.removePreference(mEmergencyCheckBox);
    208             }
    209 
    210             // Show alert settings and ETWS categories for ETWS builds and developer mode.
    211             if (enableDevSettings || showEtwsSettings) {
    212 
    213                 if (forceDisableEtwsCmasTest) {
    214                     // Remove ETWS test preference.
    215                     preferenceScreen.removePreference(mETWSSettingCategory);
    216 
    217                     PreferenceCategory devSettingCategory =
    218                             (PreferenceCategory) findPreference(KEY_CATEGORY_DEV_SETTINGS);
    219 
    220                     // Remove CMAS test preference.
    221                     if (devSettingCategory != null) {
    222                         devSettingCategory.removePreference(mCmasTestCheckBox);
    223                     }
    224                 }
    225             } else {
    226                 mAlertCategory.removePreference(mSpeechCheckBox);
    227                 // Remove ETWS test preference category.
    228                 preferenceScreen.removePreference(mETWSSettingCategory);
    229             }
    230 
    231             if (!res.getBoolean(R.bool.show_cmas_settings)) {
    232                 // Remove CMAS preference items in emergency alert category.
    233                 mAlertCategory.removePreference(mExtremeCheckBox);
    234                 mAlertCategory.removePreference(mSevereCheckBox);
    235                 mAlertCategory.removePreference(mAmberCheckBox);
    236             }
    237 
    238             TelephonyManager tm = (TelephonyManager) getContext().getSystemService(
    239                     Context.TELEPHONY_SERVICE);
    240 
    241             // We display channel 50 enable/disable menu if one of the followings is true
    242             // 1. The setting through resource overlay is set to true.
    243             // 2. At least one SIM inserted is Brazilian SIM.
    244 
    245             boolean enableChannel50Support = res.getBoolean(R.bool.show_brazil_settings);
    246 
    247             if (!enableChannel50Support) {
    248                 SubscriptionManager sm = SubscriptionManager.from(getContext());
    249                 for (int subId : sm.getActiveSubscriptionIdList()) {
    250                     if (COUNTRY_BRAZIL.equals(tm.getSimCountryIso(subId))) {
    251                         enableChannel50Support = true;
    252                         break;
    253                     }
    254                 }
    255             }
    256 
    257             if (!enableChannel50Support) {
    258                 preferenceScreen.removePreference(findPreference(KEY_CATEGORY_BRAZIL_SETTINGS));
    259             }
    260             if (!enableDevSettings) {
    261                 preferenceScreen.removePreference(findPreference(KEY_CATEGORY_DEV_SETTINGS));
    262             }
    263 
    264             if (mChannel50CheckBox != null) {
    265                 mChannel50CheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    266             }
    267             if (mEtwsTestCheckBox != null) {
    268                 mEtwsTestCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    269             }
    270             if (mExtremeCheckBox != null) {
    271                 mExtremeCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    272             }
    273 
    274             if (mSevereCheckBox != null) {
    275                 mSevereCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    276                 if (mDisableSevereWhenExtremeDisabled) {
    277                     if (mExtremeCheckBox != null) {
    278                         mSevereCheckBox.setEnabled(mExtremeCheckBox.isChecked());
    279                     }
    280                 }
    281             }
    282             if (mAmberCheckBox != null) {
    283                 mAmberCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    284             }
    285             if (mCmasTestCheckBox != null) {
    286                 mCmasTestCheckBox.setOnPreferenceChangeListener(startConfigServiceListener);
    287             }
    288         }
    289 
    290         private void initReminderIntervalList() {
    291 
    292             String[] activeValues =
    293                     getResources().getStringArray(R.array.alert_reminder_interval_active_values);
    294             String[] allEntries =
    295                     getResources().getStringArray(R.array.alert_reminder_interval_entries);
    296             String[] newEntries = new String[activeValues.length];
    297 
    298             // Only add active interval to the list
    299             for (int i = 0; i < activeValues.length; i++) {
    300                 int index = mReminderInterval.findIndexOfValue(activeValues[i]);
    301                 if (index != -1) {
    302                     newEntries[i] = allEntries[index];
    303                     if (DBG) Log.d(TAG, "Added " + allEntries[index]);
    304                 } else {
    305                     Log.e(TAG, "Can't find " + activeValues[i]);
    306                 }
    307             }
    308 
    309             mReminderInterval.setEntries(newEntries);
    310             mReminderInterval.setEntryValues(activeValues);
    311             mReminderInterval.setSummary(mReminderInterval.getEntry());
    312             mReminderInterval.setOnPreferenceChangeListener(
    313                     new Preference.OnPreferenceChangeListener() {
    314                         @Override
    315                         public boolean onPreferenceChange(Preference pref, Object newValue) {
    316                             final ListPreference listPref = (ListPreference) pref;
    317                             final int idx = listPref.findIndexOfValue((String) newValue);
    318                             listPref.setSummary(listPref.getEntries()[idx]);
    319                             return true;
    320                         }
    321                     });
    322         }
    323     }
    324 
    325     public static boolean isFeatureEnabled(Context context, String feature, boolean defaultValue) {
    326         int subId = SubscriptionManager.getDefaultSmsSubscriptionId();
    327         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
    328             subId = SubscriptionManager.getDefaultSubscriptionId();
    329             if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
    330                 return defaultValue;
    331             }
    332         }
    333 
    334         CarrierConfigManager configManager =
    335                 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
    336 
    337         if (configManager != null) {
    338             PersistableBundle carrierConfig = configManager.getConfigForSubId(subId);
    339 
    340             if (carrierConfig != null) {
    341                 return carrierConfig.getBoolean(feature, defaultValue);
    342             }
    343         }
    344 
    345         return defaultValue;
    346     }
    347 }
    348