• Home
  • History
  • Annotate
  • 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 import com.android.carrierdefaultapp.R;
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 
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             default:
96                 loge("unsupported carrier action index: " + actionIdx);
97         }
98     }
99 
onDisableAllMeteredApns(Intent intent, Context context)100     private static void onDisableAllMeteredApns(Intent intent, Context context) {
101         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
102                 SubscriptionManager.getDefaultVoiceSubscriptionId());
103         logd("onDisableAllMeteredApns subId: " + subId);
104         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
105         telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, !ENABLE);
106     }
107 
onEnableAllMeteredApns(Intent intent, Context context)108     private static void onEnableAllMeteredApns(Intent intent, Context context) {
109         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
110                 SubscriptionManager.getDefaultVoiceSubscriptionId());
111         logd("onEnableAllMeteredApns subId: " + subId);
112         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
113         telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
114     }
115 
onEnableDefaultURLHandler(Context context)116     private static void onEnableDefaultURLHandler(Context context) {
117         logd("onEnableDefaultURLHandler");
118         final PackageManager pm = context.getPackageManager();
119         pm.setComponentEnabledSetting(
120                 new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
121                 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
122     }
123 
onDisableDefaultURLHandler(Context context)124     private static void onDisableDefaultURLHandler(Context context) {
125         logd("onDisableDefaultURLHandler");
126         final PackageManager pm = context.getPackageManager();
127         pm.setComponentEnabledSetting(
128                 new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
129                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
130     }
131 
onRegisterDefaultNetworkAvail(Intent intent, Context context)132     private static void onRegisterDefaultNetworkAvail(Intent intent, Context context) {
133         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
134                 SubscriptionManager.getDefaultVoiceSubscriptionId());
135         logd("onRegisterDefaultNetworkAvail subId: " + subId);
136         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
137         telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, true);
138     }
139 
onDeregisterDefaultNetworkAvail(Intent intent, Context context)140     private static void onDeregisterDefaultNetworkAvail(Intent intent, Context context) {
141         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
142                 SubscriptionManager.getDefaultVoiceSubscriptionId());
143         logd("onDeregisterDefaultNetworkAvail subId: " + subId);
144         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
145         telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, false);
146     }
147 
onDisableRadio(Intent intent, Context context)148     private static void onDisableRadio(Intent intent, Context context) {
149         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
150                 SubscriptionManager.getDefaultVoiceSubscriptionId());
151         logd("onDisableRadio subId: " + subId);
152         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
153         telephonyMgr.carrierActionSetRadioEnabled(subId, !ENABLE);
154     }
155 
onEnableRadio(Intent intent, Context context)156     private static void onEnableRadio(Intent intent, Context context) {
157         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
158                 SubscriptionManager.getDefaultVoiceSubscriptionId());
159         logd("onEnableRadio subId: " + subId);
160         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
161         telephonyMgr.carrierActionSetRadioEnabled(subId, ENABLE);
162     }
163 
onShowCaptivePortalNotification(Intent intent, Context context)164     private static void onShowCaptivePortalNotification(Intent intent, Context context) {
165         logd("onShowCaptivePortalNotification");
166         Intent portalIntent = new Intent(context, CaptivePortalLoginActivity.class);
167         portalIntent.putExtras(intent);
168         portalIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
169                 | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
170         PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, portalIntent,
171                 PendingIntent.FLAG_UPDATE_CURRENT);
172         Notification notification = getNotification(context, R.string.portal_notification_id,
173                 R.string.portal_notification_detail, pendingIntent);
174         try {
175             context.getSystemService(NotificationManager.class)
176                     .notify(PORTAL_NOTIFICATION_TAG, PORTAL_NOTIFICATION_ID, notification);
177         } catch (NullPointerException npe) {
178             loge("setNotificationVisible: " + npe);
179         }
180     }
181 
onShowNoDataServiceNotification(Context context)182     private static void onShowNoDataServiceNotification(Context context) {
183         logd("onShowNoDataServiceNotification");
184         Notification notification = getNotification(context, R.string.no_data_notification_id,
185                 R.string.no_data_notification_detail, null);
186         try {
187             context.getSystemService(NotificationManager.class)
188                     .notify(NO_DATA_NOTIFICATION_TAG, NO_DATA_NOTIFICATION_ID, notification);
189         } catch (NullPointerException npe) {
190             loge("setNotificationVisible: " + npe);
191         }
192     }
193 
onCancelAllNotifications(Context context)194     private static void onCancelAllNotifications(Context context) {
195         logd("onCancelAllNotifications");
196         context.getSystemService(NotificationManager.class).cancelAll();
197     }
198 
getNotification(Context context, int titleId, int textId, PendingIntent pendingIntent)199     private static Notification getNotification(Context context, int titleId, int textId,
200                                          PendingIntent pendingIntent) {
201         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
202         final Resources resources = context.getResources();
203         String spn = telephonyMgr.getSimOperatorName();
204         if (TextUtils.isEmpty(spn)) {
205             // There is no consistent way to get the current carrier name as MNOs didn't
206             // bother to set EF_SPN. in the long term, we should display a generic wording if
207             // spn from subscription is not set.
208             spn = telephonyMgr.getNetworkOperatorName();
209         }
210         final Bundle extras = Bundle.forPair(Notification.EXTRA_SUBSTITUTE_APP_NAME,
211                 resources.getString(R.string.android_system_label));
212         createNotificationChannels(context);
213         Notification.Builder builder = new Notification.Builder(context)
214                 .setContentTitle(resources.getString(titleId))
215                 .setContentText(String.format(resources.getString(textId), spn))
216                 .setSmallIcon(R.drawable.ic_sim_card)
217                 .setColor(context.getColor(
218                         com.android.internal.R.color.system_notification_accent_color))
219                 .setOngoing(true)
220                 .setPriority(Notification.PRIORITY_HIGH)
221                 .setDefaults(Notification.DEFAULT_ALL)
222                 .setVisibility(Notification.VISIBILITY_PUBLIC)
223                 .setLocalOnly(true)
224                 .setWhen(System.currentTimeMillis())
225                 .setShowWhen(false)
226                 .setExtras(extras)
227                 .setChannel(NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS);
228 
229         if (pendingIntent != null) {
230             builder.setContentIntent(pendingIntent);
231         }
232         return builder.build();
233     }
234 
235     /**
236      * Creates the notification channel and registers it with NotificationManager. Also used to
237      * update an existing channel's name.
238      */
createNotificationChannels(Context context)239     static void createNotificationChannels(Context context) {
240         context.getSystemService(NotificationManager.class)
241                 .createNotificationChannel(new NotificationChannel(
242                 NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS,
243                 context.getResources().getString(
244                         R.string.mobile_data_status_notification_channel_name),
245                 NotificationManager.IMPORTANCE_DEFAULT));
246     }
247 
logd(String s)248     private static void logd(String s) {
249         Log.d(TAG, s);
250     }
251 
loge(String s)252     private static void loge(String s) {
253         Log.e(TAG, s);
254     }
255 }
256