• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.internal.telephony.uicc;
18 
19 import static android.content.Context.ALARM_SERVICE;
20 
21 import android.app.AlarmManager;
22 import android.app.Notification;
23 import android.app.NotificationManager;
24 import android.app.PendingIntent;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.content.res.Resources;
29 import android.net.Uri;
30 import android.os.SystemClock;
31 import android.provider.Settings;
32 import android.service.notification.StatusBarNotification;
33 import android.text.TextUtils;
34 
35 import com.android.internal.R;
36 import com.android.internal.annotations.VisibleForTesting;
37 import com.android.internal.telephony.util.NotificationChannelController;
38 
39 import java.util.Arrays;
40 import java.util.List;
41 
42 /**
43  * Utility methods for installing the carrier app when a SIM is insterted without the carrier app
44  * for that SIM installed.
45  */
46 @VisibleForTesting
47 public class InstallCarrierAppUtils {
48     // TODO(b/72714040) centralize notification IDs
49     private static final int ACTIVATE_CELL_SERVICE_NOTIFICATION_ID = 12;
50     private static CarrierAppInstallReceiver sCarrierAppInstallReceiver = null;
51 
showNotification(Context context, String pkgName)52     static void showNotification(Context context, String pkgName) {
53         Resources res = Resources.getSystem();
54         String title = res.getString(
55                 com.android.internal.R.string.install_carrier_app_notification_title);
56         String appName = getAppNameFromPackageName(context, pkgName);
57         String message;
58         if (TextUtils.isEmpty(appName)) {
59             message = res.getString(R.string.install_carrier_app_notification_text);
60         } else {
61             message = res.getString(R.string.install_carrier_app_notification_text_app_name,
62                     appName);
63         }
64         String downloadButtonText = res.getString(R.string.install_carrier_app_notification_button);
65 
66         boolean persistent = Settings.Global.getInt(
67                 context.getContentResolver(),
68                 Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT, 1) == 1;
69 
70         PendingIntent goToStore = PendingIntent.getActivity(context, 0,
71                 getPlayStoreIntent(pkgName), PendingIntent.FLAG_UPDATE_CURRENT
72                         | PendingIntent.FLAG_IMMUTABLE);
73 
74         Notification.Action goToStoreAction =
75                 new Notification.Action.Builder(null, downloadButtonText, goToStore).build();
76 
77         Notification notification = new Notification.Builder(context,
78                 NotificationChannelController.CHANNEL_ID_SIM)
79                 .setContentTitle(title)
80                 .setContentText(message)
81                 .setSmallIcon(R.drawable.ic_signal_cellular_alt_24px)
82                 .addAction(goToStoreAction)
83                 .setOngoing(persistent)
84                 .setVisibility(Notification.VISIBILITY_SECRET) // Should not appear on lock screen
85                 .build();
86 
87         getNotificationManager(context).notify(
88                 pkgName,
89                 ACTIVATE_CELL_SERVICE_NOTIFICATION_ID,
90                 notification);
91     }
92 
hideAllNotifications(Context context)93     static void hideAllNotifications(Context context) {
94         NotificationManager notificationManager = getNotificationManager(context);
95         StatusBarNotification[] activeNotifications = notificationManager.getActiveNotifications();
96 
97         if (activeNotifications == null) {
98             return;
99         }
100 
101         for (StatusBarNotification notification : activeNotifications) {
102             if (notification.getId() == ACTIVATE_CELL_SERVICE_NOTIFICATION_ID) {
103                 notificationManager.cancel(notification.getTag(), notification.getId());
104             }
105         }
106     }
107 
hideNotification(Context context, String pkgName)108     static void hideNotification(Context context, String pkgName) {
109         getNotificationManager(context).cancel(pkgName, ACTIVATE_CELL_SERVICE_NOTIFICATION_ID);
110     }
111 
getPlayStoreIntent(String pkgName)112     static Intent getPlayStoreIntent(String pkgName) {
113         // Open play store to download package
114         Intent storeIntent = new Intent(Intent.ACTION_VIEW);
115         storeIntent.setData(Uri.parse("market://details?id=" + pkgName));
116         storeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
117 
118         return storeIntent;
119     }
120 
showNotificationIfNotInstalledDelayed(Context context, String pkgName, long delayMillis)121     static void showNotificationIfNotInstalledDelayed(Context context,
122             String pkgName, long delayMillis) {
123         AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
124         PendingIntent pendingIntent = PendingIntent.getBroadcast(
125                 context,
126                 0,
127                 ShowInstallAppNotificationReceiver.get(context, pkgName),
128                 PendingIntent.FLAG_IMMUTABLE);
129         alarmManager.set(AlarmManager.ELAPSED_REALTIME,
130                 SystemClock.elapsedRealtime() + delayMillis,
131                 pendingIntent);
132 
133     }
134 
registerPackageInstallReceiver(Context context)135     static void registerPackageInstallReceiver(Context context) {
136         if (sCarrierAppInstallReceiver == null) {
137             sCarrierAppInstallReceiver = new CarrierAppInstallReceiver();
138             context = context.getApplicationContext();
139             IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
140             intentFilter.addDataScheme("package");
141             context.registerReceiver(sCarrierAppInstallReceiver, intentFilter);
142         }
143     }
144 
unregisterPackageInstallReceiver(Context context)145     static void unregisterPackageInstallReceiver(Context context) {
146         if (sCarrierAppInstallReceiver == null) {
147             return;
148         }
149         context = context.getApplicationContext();
150         context.unregisterReceiver(sCarrierAppInstallReceiver);
151         sCarrierAppInstallReceiver = null;
152     }
153 
isPackageInstallNotificationActive(Context context)154     static boolean isPackageInstallNotificationActive(Context context) {
155         StatusBarNotification[] activeNotifications =
156                 getNotificationManager(context).getActiveNotifications();
157 
158         for (StatusBarNotification notification : activeNotifications) {
159             if (notification.getId() == ACTIVATE_CELL_SERVICE_NOTIFICATION_ID) {
160                 return true;
161             }
162         }
163         return false;
164     }
165 
getAppNameFromPackageName(Context context, String packageName)166     static String getAppNameFromPackageName(Context context, String packageName) {
167         String whitelistSetting = Settings.Global.getString(
168                 context.getContentResolver(),
169                 Settings.Global.CARRIER_APP_NAMES);
170         return getAppNameFromPackageName(packageName, whitelistSetting);
171     }
172 
173     /**
174      * @param packageName the name of the package.  Will be used as a key into the map
175      * @param mapString map of package name to application name in the format:
176      *                  packageName1:appName1;packageName2:appName2;
177      * @return the name of the application for the package name provided.
178      */
179     @VisibleForTesting
getAppNameFromPackageName(String packageName, String mapString)180     public static String getAppNameFromPackageName(String packageName, String mapString) {
181         packageName = packageName.toLowerCase();
182         final String pairDelim = "\\s*;\\s*";
183         final String keyValueDelim = "\\s*:\\s*";
184 
185         if (TextUtils.isEmpty(mapString)) {
186             return null;
187         }
188 
189         List<String> keyValuePairList = Arrays.asList(mapString.split(pairDelim));
190 
191         if (keyValuePairList.isEmpty()) {
192             return null;
193         }
194 
195         for (String keyValueString: keyValuePairList) {
196             String[] keyValue = keyValueString.split(keyValueDelim);
197 
198             if (keyValue.length == 2) {
199                 if (keyValue[0].equals(packageName)) {
200                     return keyValue[1];
201                 }
202             }
203         }
204         return null;
205     }
getNotificationManager(Context context)206     private static NotificationManager getNotificationManager(Context context) {
207         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
208     }
209 }
210