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