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