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 onCreate(Bundle savedInstanceState)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 onCreate(Bundle savedInstanceState)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. isEtwsCmasTestMessageForcedDisabled(Context context)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. isEmergencyAlertOnOffOptionEnabled(Context context)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