1 /* 2 * Copyright (C) 2016 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 package com.android.carrierdefaultapp; 17 18 import android.app.Notification; 19 import android.app.NotificationChannel; 20 import android.app.NotificationManager; 21 import android.app.PendingIntent; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.pm.PackageManager; 26 import android.content.res.Resources; 27 import android.os.Bundle; 28 import android.telephony.SubscriptionManager; 29 import android.telephony.TelephonyManager; 30 import android.text.TextUtils; 31 import android.util.Log; 32 33 /** 34 * This util class provides common logic for carrier actions 35 */ 36 public class CarrierActionUtils { 37 private static final String TAG = CarrierActionUtils.class.getSimpleName(); 38 39 private static final String PORTAL_NOTIFICATION_TAG = "CarrierDefault.Portal.Notification"; 40 private static final String NO_DATA_NOTIFICATION_TAG = "CarrierDefault.NoData.Notification"; 41 private static final String NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS = "mobile_data_status"; 42 private static final int PORTAL_NOTIFICATION_ID = 0; 43 private static final int NO_DATA_NOTIFICATION_ID = 1; 44 private static boolean ENABLE = true; 45 46 // A list of supported carrier action idx 47 public static final int CARRIER_ACTION_ENABLE_METERED_APNS = 0; 48 public static final int CARRIER_ACTION_DISABLE_METERED_APNS = 1; 49 public static final int CARRIER_ACTION_DISABLE_RADIO = 2; 50 public static final int CARRIER_ACTION_ENABLE_RADIO = 3; 51 public static final int CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION = 4; 52 public static final int CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION = 5; 53 public static final int CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS = 6; 54 public static final int CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER = 7; 55 public static final int CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER = 8; 56 public static final int CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL = 9; 57 public static final int CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL = 10; 58 public static final int CARRIER_ACTION_RESET_ALL = 11; 59 applyCarrierAction(int actionIdx, Intent intent, Context context)60 public static void applyCarrierAction(int actionIdx, Intent intent, Context context) { 61 switch (actionIdx) { 62 case CARRIER_ACTION_ENABLE_METERED_APNS: 63 onEnableAllMeteredApns(intent, context); 64 break; 65 case CARRIER_ACTION_DISABLE_METERED_APNS: 66 onDisableAllMeteredApns(intent, context); 67 break; 68 case CARRIER_ACTION_DISABLE_RADIO: 69 onDisableRadio(intent, context); 70 break; 71 case CARRIER_ACTION_ENABLE_RADIO: 72 onEnableRadio(intent, context); 73 break; 74 case CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION: 75 onShowCaptivePortalNotification(intent, context); 76 break; 77 case CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION: 78 onShowNoDataServiceNotification(context); 79 break; 80 case CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS: 81 onCancelAllNotifications(context); 82 break; 83 case CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER: 84 onEnableDefaultURLHandler(context); 85 break; 86 case CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER: 87 onDisableDefaultURLHandler(context); 88 break; 89 case CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL: 90 onRegisterDefaultNetworkAvail(intent, context); 91 break; 92 case CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL: 93 onDeregisterDefaultNetworkAvail(intent, context); 94 break; 95 case CARRIER_ACTION_RESET_ALL: 96 onResetAllCarrierActions(intent, context); 97 break; 98 default: 99 loge("unsupported carrier action index: " + actionIdx); 100 } 101 } 102 onDisableAllMeteredApns(Intent intent, Context context)103 private static void onDisableAllMeteredApns(Intent intent, Context context) { 104 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 105 SubscriptionManager.getDefaultVoiceSubscriptionId()); 106 logd("onDisableAllMeteredApns subId: " + subId); 107 final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); 108 telephonyMgr.createForSubscriptionId(subId).setCarrierDataEnabled(!ENABLE); 109 } 110 onEnableAllMeteredApns(Intent intent, Context context)111 private static void onEnableAllMeteredApns(Intent intent, Context context) { 112 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 113 SubscriptionManager.getDefaultVoiceSubscriptionId()); 114 logd("onEnableAllMeteredApns subId: " + subId); 115 final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); 116 telephonyMgr.createForSubscriptionId(subId).setCarrierDataEnabled(ENABLE); 117 } 118 onEnableDefaultURLHandler(Context context)119 private static void onEnableDefaultURLHandler(Context context) { 120 logd("onEnableDefaultURLHandler"); 121 final PackageManager pm = context.getPackageManager(); 122 pm.setComponentEnabledSetting( 123 new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)), 124 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); 125 } 126 onDisableDefaultURLHandler(Context context)127 private static void onDisableDefaultURLHandler(Context context) { 128 logd("onDisableDefaultURLHandler"); 129 final PackageManager pm = context.getPackageManager(); 130 pm.setComponentEnabledSetting( 131 new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)), 132 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 133 } 134 onRegisterDefaultNetworkAvail(Intent intent, Context context)135 private static void onRegisterDefaultNetworkAvail(Intent intent, Context context) { 136 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 137 SubscriptionManager.getDefaultVoiceSubscriptionId()); 138 logd("onRegisterDefaultNetworkAvail subId: " + subId); 139 final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); 140 telephonyMgr.createForSubscriptionId(subId).reportDefaultNetworkStatus(true); 141 } 142 onDeregisterDefaultNetworkAvail(Intent intent, Context context)143 private static void onDeregisterDefaultNetworkAvail(Intent intent, Context context) { 144 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 145 SubscriptionManager.getDefaultVoiceSubscriptionId()); 146 logd("onDeregisterDefaultNetworkAvail subId: " + subId); 147 final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); 148 telephonyMgr.createForSubscriptionId(subId).reportDefaultNetworkStatus(false); 149 } 150 onDisableRadio(Intent intent, Context context)151 private static void onDisableRadio(Intent intent, Context context) { 152 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 153 SubscriptionManager.getDefaultVoiceSubscriptionId()); 154 logd("onDisableRadio subId: " + subId); 155 final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); 156 telephonyMgr.createForSubscriptionId(subId).setRadioEnabled(!ENABLE); 157 } 158 onEnableRadio(Intent intent, Context context)159 private static void onEnableRadio(Intent intent, Context context) { 160 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 161 SubscriptionManager.getDefaultVoiceSubscriptionId()); 162 logd("onEnableRadio subId: " + subId); 163 final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); 164 telephonyMgr.createForSubscriptionId(subId).setRadioEnabled(ENABLE); 165 } 166 onShowCaptivePortalNotification(Intent intent, Context context)167 private static void onShowCaptivePortalNotification(Intent intent, Context context) { 168 logd("onShowCaptivePortalNotification"); 169 Intent portalIntent = new Intent(context, CaptivePortalLoginActivity.class); 170 portalIntent.putExtras(intent); 171 portalIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT 172 | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 173 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, portalIntent, 174 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED); 175 Notification notification = getNotification(context, R.string.portal_notification_id, 176 R.string.portal_notification_detail, pendingIntent); 177 try { 178 context.getSystemService(NotificationManager.class) 179 .notify(PORTAL_NOTIFICATION_TAG, PORTAL_NOTIFICATION_ID, notification); 180 } catch (NullPointerException npe) { 181 loge("setNotificationVisible: " + npe); 182 } 183 } 184 onShowNoDataServiceNotification(Context context)185 private static void onShowNoDataServiceNotification(Context context) { 186 logd("onShowNoDataServiceNotification"); 187 Notification notification = getNotification(context, R.string.no_data_notification_id, 188 R.string.no_data_notification_detail, null); 189 try { 190 context.getSystemService(NotificationManager.class) 191 .notify(NO_DATA_NOTIFICATION_TAG, NO_DATA_NOTIFICATION_ID, notification); 192 } catch (NullPointerException npe) { 193 loge("setNotificationVisible: " + npe); 194 } 195 } 196 onCancelAllNotifications(Context context)197 private static void onCancelAllNotifications(Context context) { 198 logd("onCancelAllNotifications"); 199 context.getSystemService(NotificationManager.class).cancelAll(); 200 } 201 onResetAllCarrierActions(Intent intent, Context context)202 private static void onResetAllCarrierActions(Intent intent, Context context) { 203 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 204 SubscriptionManager.getDefaultVoiceSubscriptionId()); 205 logd("onResetAllCarrierActions subId: " + subId); 206 final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); 207 telephonyMgr.createForSubscriptionId(subId).resetAllCarrierActions(); 208 } 209 getNotification(Context context, int titleId, int textId, PendingIntent pendingIntent)210 private static Notification getNotification(Context context, int titleId, int textId, 211 PendingIntent pendingIntent) { 212 final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); 213 final Resources resources = context.getResources(); 214 String spn = telephonyMgr.getSimOperatorName(); 215 if (TextUtils.isEmpty(spn)) { 216 // There is no consistent way to get the current carrier name as MNOs didn't 217 // bother to set EF_SPN. in the long term, we should display a generic wording if 218 // spn from subscription is not set. 219 spn = telephonyMgr.getNetworkOperatorName(); 220 } 221 final Bundle extras = Bundle.forPair(Notification.EXTRA_SUBSTITUTE_APP_NAME, 222 resources.getString(R.string.android_system_label)); 223 createNotificationChannels(context); 224 Notification.Builder builder = new Notification.Builder(context) 225 .setContentTitle(resources.getString(titleId)) 226 .setContentText(String.format(resources.getString(textId), spn)) 227 .setSmallIcon(R.drawable.ic_sim_card) 228 .setColor(context.getColor( 229 com.android.internal.R.color.system_notification_accent_color)) 230 .setOngoing(true) 231 .setPriority(Notification.PRIORITY_HIGH) 232 .setDefaults(Notification.DEFAULT_ALL) 233 .setVisibility(Notification.VISIBILITY_PUBLIC) 234 .setLocalOnly(true) 235 .setWhen(System.currentTimeMillis()) 236 .setShowWhen(false) 237 .setExtras(extras) 238 .setChannel(NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS); 239 240 if (pendingIntent != null) { 241 builder.setContentIntent(pendingIntent); 242 } 243 return builder.build(); 244 } 245 246 /** 247 * Creates the notification channel and registers it with NotificationManager. Also used to 248 * update an existing channel's name. 249 */ createNotificationChannels(Context context)250 static void createNotificationChannels(Context context) { 251 context.getSystemService(NotificationManager.class) 252 .createNotificationChannel(new NotificationChannel( 253 NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS, 254 context.getResources().getString( 255 R.string.mobile_data_status_notification_channel_name), 256 NotificationManager.IMPORTANCE_DEFAULT)); 257 } 258 logd(String s)259 private static void logd(String s) { 260 Log.d(TAG, s); 261 } 262 loge(String s)263 private static void loge(String s) { 264 Log.e(TAG, s); 265 } 266 } 267