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