• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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