1 /* 2 * Copyright (C) 2014 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.settings.sim; 18 19 import static android.provider.Settings.ENABLE_MMS_DATA_REQUEST_REASON_INCOMING_MMS; 20 import static android.provider.Settings.ENABLE_MMS_DATA_REQUEST_REASON_OUTGOING_MMS; 21 import static android.provider.Settings.EXTRA_ENABLE_MMS_DATA_REQUEST_REASON; 22 import static android.provider.Settings.EXTRA_SUB_ID; 23 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE; 24 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL; 25 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA; 26 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS; 27 import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE; 28 import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_NAMES; 29 import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE; 30 import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA; 31 import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE; 32 import static android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID; 33 import static android.telephony.data.ApnSetting.TYPE_MMS; 34 35 import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME; 36 import static com.android.settings.sim.SimDialogActivity.PICK_DISMISS; 37 38 import android.app.Notification; 39 import android.app.NotificationChannel; 40 import android.app.NotificationManager; 41 import android.app.PendingIntent; 42 import android.content.BroadcastReceiver; 43 import android.content.Context; 44 import android.content.Intent; 45 import android.content.res.Resources; 46 import android.provider.Settings; 47 import android.telephony.SubscriptionInfo; 48 import android.telephony.SubscriptionManager; 49 import android.telephony.TelephonyManager; 50 import android.util.Log; 51 52 import com.android.internal.annotations.VisibleForTesting; 53 import com.android.settings.HelpTrampoline; 54 import com.android.settings.R; 55 import com.android.settings.network.MobileNetworkTwoPaneUtils; 56 import com.android.settings.network.SubscriptionUtil; 57 import com.android.settings.network.telephony.MobileNetworkActivity; 58 59 public class SimSelectNotification extends BroadcastReceiver { 60 private static final String TAG = "SimSelectNotification"; 61 @VisibleForTesting 62 public static final int SIM_SELECT_NOTIFICATION_ID = 1; 63 @VisibleForTesting 64 public static final int ENABLE_MMS_NOTIFICATION_ID = 2; 65 @VisibleForTesting 66 public static final int SIM_WARNING_NOTIFICATION_ID = 3; 67 68 @VisibleForTesting 69 public static final String SIM_SELECT_NOTIFICATION_CHANNEL = 70 "sim_select_notification_channel"; 71 72 @VisibleForTesting 73 public static final String ENABLE_MMS_NOTIFICATION_CHANNEL = 74 "enable_mms_notification_channel"; 75 76 @VisibleForTesting 77 public static final String SIM_WARNING_NOTIFICATION_CHANNEL = 78 "sim_warning_notification_channel"; 79 80 @Override onReceive(Context context, Intent intent)81 public void onReceive(Context context, Intent intent) { 82 String action = intent.getAction(); 83 84 if (action == null) { 85 Log.w(TAG, "Received unexpected intent with null action."); 86 return; 87 } 88 89 switch (action) { 90 case TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED: 91 onPrimarySubscriptionListChanged(context, intent); 92 break; 93 case Settings.ACTION_ENABLE_MMS_DATA_REQUEST: 94 onEnableMmsDataRequest(context, intent); 95 break; 96 default: 97 Log.w(TAG, "Received unexpected intent " + intent.getAction()); 98 } 99 } 100 onEnableMmsDataRequest(Context context, Intent intent)101 private void onEnableMmsDataRequest(Context context, Intent intent) { 102 // Getting subId from extra. 103 int subId = intent.getIntExtra(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 104 if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 105 subId = SubscriptionManager.getDefaultSmsSubscriptionId(); 106 } 107 108 SubscriptionManager subscriptionManager = ((SubscriptionManager) context.getSystemService( 109 Context.TELEPHONY_SUBSCRIPTION_SERVICE)); 110 if (!subscriptionManager.isActiveSubscriptionId(subId)) { 111 Log.w(TAG, "onEnableMmsDataRequest invalid sub ID " + subId); 112 return; 113 } 114 final SubscriptionInfo info = subscriptionManager.getActiveSubscriptionInfo(subId); 115 if (info == null) { 116 Log.w(TAG, "onEnableMmsDataRequest null SubscriptionInfo for sub ID " + subId); 117 return; 118 } 119 120 // Getting request reason from extra, which will determine the notification title. 121 CharSequence notificationTitle = null; 122 int requestReason = intent.getIntExtra(EXTRA_ENABLE_MMS_DATA_REQUEST_REASON, -1); 123 if (requestReason == ENABLE_MMS_DATA_REQUEST_REASON_INCOMING_MMS) { 124 notificationTitle = context.getResources().getText( 125 R.string.enable_receiving_mms_notification_title); 126 } else if (requestReason == ENABLE_MMS_DATA_REQUEST_REASON_OUTGOING_MMS) { 127 notificationTitle = context.getResources().getText( 128 R.string.enable_sending_mms_notification_title); 129 } else { 130 Log.w(TAG, "onEnableMmsDataRequest invalid request reason " + requestReason); 131 return; 132 } 133 134 TelephonyManager tm = ((TelephonyManager) context.getSystemService( 135 Context.TELEPHONY_SERVICE)).createForSubscriptionId(subId); 136 137 if (tm.isDataEnabledForApn(TYPE_MMS)) { 138 Log.w(TAG, "onEnableMmsDataRequest MMS data already enabled on sub ID " + subId); 139 return; 140 } 141 142 CharSequence notificationSummary = context.getResources().getString( 143 R.string.enable_mms_notification_summary, 144 SubscriptionUtil.getUniqueSubscriptionDisplayName(info, context)); 145 146 cancelEnableMmsNotification(context); 147 148 createEnableMmsNotification(context, notificationTitle, notificationSummary, subId); 149 } 150 onPrimarySubscriptionListChanged(Context context, Intent intent)151 private void onPrimarySubscriptionListChanged(Context context, Intent intent) { 152 startSimSelectDialogIfNeeded(context, intent); 153 sendSimCombinationWarningIfNeeded(context, intent); 154 } 155 startSimSelectDialogIfNeeded(Context context, Intent intent)156 private void startSimSelectDialogIfNeeded(Context context, Intent intent) { 157 int dialogType = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, 158 EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE); 159 160 if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE) { 161 return; 162 } 163 164 // Cancel any previous notifications 165 cancelSimSelectNotification(context); 166 167 // If the dialog type is to dismiss. 168 if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS) { 169 Intent newIntent = new Intent(context, SimDialogActivity.class); 170 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 171 newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, PICK_DISMISS); 172 context.startActivity(newIntent); 173 return; 174 } 175 176 // Create a notification to tell the user that some defaults are missing 177 createSimSelectNotification(context); 178 179 if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL) { 180 int subId = intent.getIntExtra(EXTRA_SUBSCRIPTION_ID, 181 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 182 int slotIndex = SubscriptionManager.getSlotIndex(subId); 183 // If there is only one subscription, ask if user wants to use if for everything 184 Intent newIntent = new Intent(context, SimDialogActivity.class); 185 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 186 newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, 187 SimDialogActivity.PREFERRED_PICK); 188 newIntent.putExtra(SimDialogActivity.PREFERRED_SIM, slotIndex); 189 context.startActivity(newIntent); 190 } else if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA) { 191 // If there are multiple, ensure they pick default data 192 Intent newIntent = new Intent(context, SimDialogActivity.class); 193 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 194 newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.DATA_PICK); 195 context.startActivity(newIntent); 196 } 197 } 198 sendSimCombinationWarningIfNeeded(Context context, Intent intent)199 private void sendSimCombinationWarningIfNeeded(Context context, Intent intent) { 200 final int warningType = intent.getIntExtra(EXTRA_SIM_COMBINATION_WARNING_TYPE, 201 EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE); 202 203 // Cancel any previous notifications 204 cancelSimCombinationWarningNotification(context); 205 206 if (warningType == EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA) { 207 // Create a notification to tell the user that there's a sim combination warning. 208 createSimCombinationWarningNotification(context, intent); 209 } 210 } 211 createSimSelectNotification(Context context)212 private void createSimSelectNotification(Context context){ 213 final Resources resources = context.getResources(); 214 215 NotificationChannel notificationChannel = new NotificationChannel( 216 SIM_SELECT_NOTIFICATION_CHANNEL, 217 resources.getText(R.string.sim_selection_channel_title), 218 NotificationManager.IMPORTANCE_LOW); 219 220 Notification.Builder builder = 221 new Notification.Builder(context, SIM_SELECT_NOTIFICATION_CHANNEL) 222 .setSmallIcon(R.drawable.ic_sim_alert) 223 .setColor(context.getColor(R.color.sim_noitification)) 224 .setContentTitle(resources.getText(R.string.sim_notification_title)) 225 .setContentText(resources.getText(R.string.sim_notification_summary)) 226 .setAutoCancel(true); 227 Intent resultIntent = new Intent(Settings.ACTION_WIRELESS_SETTINGS); 228 resultIntent.setPackage(SETTINGS_PACKAGE_NAME); 229 resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 230 PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, 231 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); 232 builder.setContentIntent(resultPendingIntent); 233 NotificationManager notificationManager = 234 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 235 notificationManager.createNotificationChannel(notificationChannel); 236 notificationManager.notify(SIM_SELECT_NOTIFICATION_ID, builder.build()); 237 } 238 cancelSimSelectNotification(Context context)239 public static void cancelSimSelectNotification(Context context) { 240 NotificationManager notificationManager = 241 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 242 notificationManager.cancel(SIM_SELECT_NOTIFICATION_ID); 243 } 244 createEnableMmsNotification(Context context, CharSequence titleString, CharSequence notificationSummary, int subId)245 private void createEnableMmsNotification(Context context, CharSequence titleString, 246 CharSequence notificationSummary, int subId) { 247 final Resources resources = context.getResources(); 248 249 NotificationChannel notificationChannel = new NotificationChannel( 250 ENABLE_MMS_NOTIFICATION_CHANNEL, 251 resources.getText(R.string.enable_mms_notification_channel_title), 252 NotificationManager.IMPORTANCE_HIGH); 253 254 Notification.Builder builder = 255 new Notification.Builder(context, ENABLE_MMS_NOTIFICATION_CHANNEL) 256 .setSmallIcon(R.drawable.ic_settings_24dp) 257 .setColor(context.getColor(R.color.sim_noitification)) 258 .setContentTitle(titleString) 259 .setContentText(notificationSummary) 260 .setStyle(new Notification.BigTextStyle().bigText(notificationSummary)) 261 .setAutoCancel(true); 262 263 // Create the pending intent that will lead to the subscription setting page. 264 Intent resultIntent = new Intent(Settings.ACTION_MMS_MESSAGE_SETTING); 265 resultIntent.setClass(context, MobileNetworkActivity.class); 266 resultIntent.putExtra(Settings.EXTRA_SUB_ID, subId); 267 // MobileNetworkActivity is singleTask, set SplitPairRule to show in 2-pane. 268 MobileNetworkTwoPaneUtils.registerTwoPaneForMobileNetwork(context, resultIntent, 269 Settings.ACTION_MMS_MESSAGE_SETTING); 270 PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, 271 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); 272 builder.setContentIntent(resultPendingIntent); 273 274 // Notify the notification. 275 NotificationManager notificationManager = 276 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 277 notificationManager.createNotificationChannel(notificationChannel); 278 notificationManager.notify(ENABLE_MMS_NOTIFICATION_ID, builder.build()); 279 } 280 cancelEnableMmsNotification(Context context)281 private void cancelEnableMmsNotification(Context context) { 282 NotificationManager notificationManager = 283 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 284 notificationManager.cancel(ENABLE_MMS_NOTIFICATION_ID); 285 } 286 createSimCombinationWarningNotification(Context context, Intent intent)287 private void createSimCombinationWarningNotification(Context context, Intent intent){ 288 final Resources resources = context.getResources(); 289 final String simNames = intent.getStringExtra(EXTRA_SIM_COMBINATION_NAMES); 290 291 if (simNames == null) { 292 return; 293 } 294 295 CharSequence dualCdmaSimWarningSummary = resources.getString( 296 R.string.dual_cdma_sim_warning_notification_summary, simNames); 297 298 NotificationChannel notificationChannel = new NotificationChannel( 299 SIM_WARNING_NOTIFICATION_CHANNEL, 300 resources.getText(R.string.dual_cdma_sim_warning_notification_channel_title), 301 NotificationManager.IMPORTANCE_HIGH); 302 303 Notification.Builder builder = 304 new Notification.Builder(context, SIM_WARNING_NOTIFICATION_CHANNEL) 305 .setSmallIcon(R.drawable.ic_sim_alert) 306 .setColor(context.getColor(R.color.sim_noitification)) 307 .setContentTitle(resources.getText( 308 R.string.sim_combination_warning_notification_title)) 309 .setContentText(dualCdmaSimWarningSummary) 310 .setStyle(new Notification.BigTextStyle().bigText( 311 dualCdmaSimWarningSummary)) 312 .setAutoCancel(true); 313 314 // Create the pending intent that will lead to the helper page. 315 Intent resultIntent = new Intent(context, HelpTrampoline.class); 316 resultIntent.putExtra(Intent.EXTRA_TEXT, "help_uri_sim_combination_warning"); 317 318 PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, 319 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); 320 builder.setContentIntent(resultPendingIntent); 321 322 NotificationManager notificationManager = 323 context.getSystemService(NotificationManager.class); 324 notificationManager.createNotificationChannel(notificationChannel); 325 notificationManager.notify(SIM_WARNING_NOTIFICATION_ID, builder.build()); 326 } 327 cancelSimCombinationWarningNotification(Context context)328 public static void cancelSimCombinationWarningNotification(Context context) { 329 NotificationManager notificationManager = 330 context.getSystemService(NotificationManager.class); 331 notificationManager.cancel(SIM_WARNING_NOTIFICATION_ID); 332 } 333 } 334