• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onCreate(Bundle savedInstanceState)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
onCreate(Bundle savedInstanceState)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 
initReminderIntervalList()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 
isFeatureEnabled(Context context, String feature, boolean defaultValue)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