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");
      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.cellbroadcastreceiver;
     18 
     19 import android.app.IntentService;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.SharedPreferences;
     23 import android.content.res.Resources;
     24 import android.preference.PreferenceManager;
     25 import android.telephony.CarrierConfigManager;
     26 import android.telephony.SmsManager;
     27 import android.telephony.SubscriptionManager;
     28 import android.telephony.TelephonyManager;
     29 import android.util.Log;
     30 
     31 import com.android.cellbroadcastreceiver.CellBroadcastOtherChannelsManager.CellBroadcastChannelRange;
     32 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
     33 import com.android.internal.telephony.gsm.SmsCbConstants;
     34 
     35 import java.util.ArrayList;
     36 
     37 import static com.android.cellbroadcastreceiver.CellBroadcastReceiver.DBG;
     38 
     39 /**
     40  * This service manages enabling and disabling ranges of message identifiers
     41  * that the radio should listen for. It operates independently of the other
     42  * services and runs at boot time and after exiting airplane mode.
     43  *
     44  * Note that the entire range of emergency channels is enabled. Test messages
     45  * and lower priority broadcasts are filtered out in CellBroadcastAlertService
     46  * if the user has not enabled them in settings.
     47  *
     48  * TODO: add notification to re-enable channels after a radio reset.
     49  */
     50 public class CellBroadcastConfigService extends IntentService {
     51     private static final String TAG = "CellBroadcastConfigService";
     52 
     53     static final String ACTION_ENABLE_CHANNELS = "ACTION_ENABLE_CHANNELS";
     54 
     55     private static final String COUNTRY_TAIWAN = "tw";
     56     private static final String COUNTRY_ISRAEL = "ir";
     57     private static final String COUNTRY_BRAZIL = "br";
     58 
     59     public CellBroadcastConfigService() {
     60         super(TAG);          // use class name for worker thread name
     61     }
     62 
     63     @Override
     64     protected void onHandleIntent(Intent intent) {
     65         if (ACTION_ENABLE_CHANNELS.equals(intent.getAction())) {
     66             try {
     67 
     68                 SubscriptionManager subManager = SubscriptionManager.from(getApplicationContext());
     69                 int subId = SubscriptionManager.getDefaultSmsSubscriptionId();
     70                 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
     71                     subId = SubscriptionManager.getDefaultSubscriptionId();
     72                     if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
     73                             subManager != null) {
     74                         int [] subIds = subManager.getActiveSubscriptionIdList();
     75                         if (subIds.length != 0) {
     76                             subId = subIds[0];
     77                         }
     78                     }
     79                 }
     80 
     81                 if (subManager != null) {
     82                     // Retrieve all the active sub ids. We only want to enable
     83                     // cell broadcast on the sub we are interested in and we'll disable
     84                     // it on other subs so the users will not receive duplicate messages from
     85                     // multiple carriers (e.g. for multi-sim users).
     86                     int [] subIds = subManager.getActiveSubscriptionIdList();
     87                     if (subIds.length != 0)
     88                     {
     89                         for (int id : subIds) {
     90                             SmsManager manager = SmsManager.getSmsManagerForSubscriptionId(id);
     91                             if (manager != null) {
     92                                 if (id == subId) {
     93                                     // Enable cell broadcast messages on this sub.
     94                                     log("Enable CellBroadcast on sub " + id);
     95                                     setCellBroadcastOnSub(manager, id, true);
     96                                 }
     97                                 else {
     98                                     // Disable all cell broadcast message on this sub.
     99                                     // This is only for multi-sim scenario. For single SIM device
    100                                     // we should not reach here.
    101                                     log("Disable CellBroadcast on sub " + id);
    102                                     setCellBroadcastOnSub(manager, id, false);
    103                                 }
    104                             }
    105                         }
    106                     }
    107                     else {
    108                         // For no sim scenario.
    109                         SmsManager manager = SmsManager.getDefault();
    110                         if (manager != null) {
    111                             setCellBroadcastOnSub(manager,
    112                                     SubscriptionManager.INVALID_SUBSCRIPTION_ID, true);
    113                         }
    114                     }
    115                 }
    116             } catch (Exception ex) {
    117                 Log.e(TAG, "exception enabling cell broadcast channels", ex);
    118             }
    119         }
    120     }
    121 
    122     /**
    123      * Enable/disable cell broadcast messages id on one subscription
    124      * This includes all ETWS and CMAS alerts.
    125      * @param manager SMS manager
    126      * @param subId Subscription id
    127      * @param enableForSub True if want to enable messages on this sub (e.g default SMS). False
    128      *                     will disable all messages
    129      */
    130     private void setCellBroadcastOnSub(SmsManager manager, int subId, boolean enableForSub) {
    131 
    132         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    133         Resources res = getResources();
    134 
    135         // boolean for each user preference checkbox, true for checked, false for unchecked
    136         // Note: If enableEmergencyAlerts is false, it disables ALL emergency broadcasts
    137         // except for CMAS presidential. i.e. to receive CMAS severe alerts, both
    138         // enableEmergencyAlerts AND enableCmasSevereAlerts must be true.
    139         boolean enableEmergencyAlerts = enableForSub && prefs.getBoolean(
    140                 CellBroadcastSettings.KEY_ENABLE_EMERGENCY_ALERTS, true);
    141 
    142         boolean enableEtwsAlerts = enableEmergencyAlerts;
    143 
    144         // CMAS Presidential must be always on (See 3GPP TS 22.268 Section 6.2) regardless
    145         // user's preference
    146         boolean enablePresidential = enableForSub;
    147 
    148         boolean enableCmasExtremeAlerts = enableEmergencyAlerts && prefs.getBoolean(
    149                 CellBroadcastSettings.KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS, true);
    150 
    151         boolean enableCmasSevereAlerts = enableEmergencyAlerts && prefs.getBoolean(
    152                 CellBroadcastSettings.KEY_ENABLE_CMAS_SEVERE_THREAT_ALERTS, true);
    153 
    154         boolean enableCmasAmberAlerts = enableEmergencyAlerts && prefs.getBoolean(
    155                 CellBroadcastSettings.KEY_ENABLE_CMAS_AMBER_ALERTS, true);
    156 
    157         // Check if ETWS/CMAS test message is forced disabled on the device.
    158         boolean forceDisableEtwsCmasTest =
    159                 CellBroadcastSettings.isFeatureEnabled(this,
    160                         CarrierConfigManager.KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false);
    161 
    162         boolean enableEtwsTestAlerts = !forceDisableEtwsCmasTest &&
    163                 enableEmergencyAlerts &&
    164                 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_ETWS_TEST_ALERTS, false);
    165 
    166         boolean enableCmasTestAlerts = !forceDisableEtwsCmasTest &&
    167                 enableEmergencyAlerts &&
    168                 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_CMAS_TEST_ALERTS, false);
    169 
    170         TelephonyManager tm = (TelephonyManager) getSystemService(
    171                 Context.TELEPHONY_SERVICE);
    172 
    173         boolean enableChannel50Support = res.getBoolean(R.bool.show_brazil_settings) ||
    174                 COUNTRY_BRAZIL.equals(tm.getSimCountryIso(subId));
    175 
    176         boolean enableChannel50Alerts = enableChannel50Support &&
    177                 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_CHANNEL_50_ALERTS, true);
    178 
    179         // Current Israel requires enable certain CMAS messages ids.
    180         boolean supportIsraelPwsAlerts = (COUNTRY_ISRAEL.equals(tm.getSimCountryIso(subId))
    181                 || COUNTRY_ISRAEL.equals(tm.getNetworkCountryIso(subId)));
    182 
    183         boolean supportTaiwanPwsAlerts = (COUNTRY_TAIWAN.equals(tm.getSimCountryIso(subId))
    184                 || COUNTRY_TAIWAN.equals(tm.getNetworkCountryIso(subId)));
    185 
    186         if (DBG) {
    187             log("enableEmergencyAlerts = " + enableEmergencyAlerts);
    188             log("enableEtwsAlerts = " + enableEtwsAlerts);
    189             log("enablePresidential = " + enablePresidential);
    190             log("enableCmasExtremeAlerts = " + enableCmasExtremeAlerts);
    191             log("enableCmasSevereAlerts = " + enableCmasExtremeAlerts);
    192             log("enableCmasAmberAlerts = " + enableCmasAmberAlerts);
    193             log("forceDisableEtwsCmasTest = " + forceDisableEtwsCmasTest);
    194             log("enableEtwsTestAlerts = " + enableEtwsTestAlerts);
    195             log("enableCmasTestAlerts = " + enableCmasTestAlerts);
    196             log("enableChannel50Alerts = " + enableChannel50Alerts);
    197             log("supportIsraelPwsAlerts = " + supportIsraelPwsAlerts);
    198             log("supportTaiwanPwsAlerts = " + supportTaiwanPwsAlerts);
    199         }
    200 
    201         /** Enable CDMA CMAS series messages. */
    202 
    203         // Enable/Disable CDMA Presidential messages.
    204         setCellBroadcastRange(manager, enablePresidential,
    205                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
    206                 SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
    207                 SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT);
    208 
    209         // Enable/Disable CDMA CMAS extreme messages.
    210         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
    211                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
    212                 SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
    213                 SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT);
    214 
    215         // Enable/Disable CDMA CMAS severe messages.
    216         setCellBroadcastRange(manager, enableCmasSevereAlerts,
    217                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
    218                 SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT,
    219                 SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT);
    220 
    221         // Enable/Disable CDMA CMAS amber alert messages.
    222         setCellBroadcastRange(manager, enableCmasAmberAlerts,
    223                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
    224                 SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
    225                 SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY);
    226 
    227         // Enable/Disable CDMA CMAS test messages.
    228         setCellBroadcastRange(manager, enableCmasTestAlerts,
    229                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
    230                 SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE,
    231                 SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
    232 
    233         /** Enable GSM ETWS series messages. */
    234 
    235         // Enable/Disable GSM ETWS messages (4352~4354).
    236         setCellBroadcastRange(manager, enableEtwsAlerts,
    237                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    238                 SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING,
    239                 SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING);
    240 
    241         // Enable/Disable GSM ETWS messages (4356)
    242         setCellBroadcastRange(manager, enableEtwsAlerts,
    243                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    244                 SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE,
    245                 SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE);
    246 
    247         // Enable/Disable GSM ETWS test messages (4355).
    248         setCellBroadcastRange(manager, enableEtwsTestAlerts,
    249                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    250                 SmsCbConstants.MESSAGE_ID_ETWS_TEST_MESSAGE,
    251                 SmsCbConstants.MESSAGE_ID_ETWS_TEST_MESSAGE);
    252 
    253         /** Enable GSM CMAS series messages. */
    254 
    255         // Enable/Disable GSM CMAS presidential message (4370).
    256         setCellBroadcastRange(manager, enablePresidential,
    257                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    258                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL,
    259                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL);
    260 
    261         // Enable/Disable GSM CMAS extreme messages (4371~4372).
    262         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
    263                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    264                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED,
    265                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY);
    266 
    267         // Enable/Disable GSM CMAS severe messages (4373~4378).
    268         setCellBroadcastRange(manager, enableCmasSevereAlerts,
    269                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    270                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED,
    271                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY);
    272 
    273         // Enable/Disable GSM CMAS amber alert messages (4379).
    274         setCellBroadcastRange(manager, enableCmasAmberAlerts,
    275                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    276                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY,
    277                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY);
    278 
    279         // Enable/Disable GSM CMAS test messages (4380~4382).
    280         setCellBroadcastRange(manager, enableCmasTestAlerts,
    281                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    282                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST,
    283                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE);
    284 
    285 
    286         /** Enable GSM CMAS series messages for additional languages. */
    287 
    288         // Enable/Disable GSM CMAS presidential messages for additional languages (4383).
    289         setCellBroadcastRange(manager, enablePresidential,
    290                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    291                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE,
    292                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE);
    293 
    294         // Enable/Disable GSM CMAS extreme messages for additional languages (4384~4385).
    295         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
    296                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    297                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE,
    298                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE);
    299 
    300         // Enable/Disable GSM CMAS severe messages for additional languages (4386~4391).
    301         setCellBroadcastRange(manager, enableCmasSevereAlerts,
    302                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    303                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE,
    304                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE);
    305 
    306         // Enable/Disable GSM CMAS amber alert messages for additional languages (4392).
    307         setCellBroadcastRange(manager, enableCmasAmberAlerts,
    308                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    309                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE,
    310                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE);
    311 
    312         // Enable/Disable GSM CMAS test messages for additional languages (4393~4395).
    313         setCellBroadcastRange(manager, enableCmasTestAlerts,
    314                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    315                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE,
    316                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE_LANGUAGE);
    317 
    318         // Enable/Disable channel 50 messages for Brazil (50).
    319         setCellBroadcastRange(manager, enableChannel50Alerts,
    320                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    321                 SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50,
    322                 SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50);
    323 
    324         // Enable/Disable additional channels based on carrier specific requirement.
    325         ArrayList<CellBroadcastChannelRange> ranges = CellBroadcastOtherChannelsManager.
    326                 getInstance().getCellBroadcastChannelRanges(getApplicationContext(), subId);
    327 
    328         if (ranges != null) {
    329             for (CellBroadcastChannelRange range: ranges) {
    330                 setCellBroadcastRange(manager, enableEmergencyAlerts,
    331                         SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    332                         range.mStartId, range.mEndId);
    333             }
    334         }
    335 
    336         // Enable/Disable additional channels based on country specific requirement.
    337         if (supportIsraelPwsAlerts) {
    338             // Enable/Disable Israel PWS channels (919~928).
    339             setCellBroadcastRange(manager, enableEmergencyAlerts,
    340                     SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    341                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_919,
    342                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_928);
    343         } else if (supportTaiwanPwsAlerts) {
    344             // Enable/Disable Taiwan PWS Chinese channel (911).
    345             setCellBroadcastRange(manager, enableEmergencyAlerts,
    346                     SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    347                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_911,
    348                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_911);
    349 
    350             // Enable/Disable Taiwan PWS English channel (919).
    351             setCellBroadcastRange(manager, enableEmergencyAlerts,
    352                     SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
    353                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_919,
    354                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_919);
    355         }
    356     }
    357     /**
    358      * Enable/disable cell broadcast with messages id range
    359      * @param manager SMS manager
    360      * @param enable True for enabling cell broadcast with id range, otherwise for disabling.
    361      * @param type GSM or CDMA
    362      * @param start Cell broadcast id range start
    363      * @param end Cell broadcast id range end
    364      */
    365     private boolean setCellBroadcastRange(
    366             SmsManager manager, boolean enable, int type, int start, int end) {
    367         if (enable) {
    368             return manager.enableCellBroadcastRange(start, end, type);
    369         } else {
    370             return manager.disableCellBroadcastRange(start, end, type);
    371         }
    372     }
    373 
    374     private static void log(String msg) {
    375         Log.d(TAG, msg);
    376     }
    377 }
    378