| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.internal.telephony.uicc; |
| |
| import static android.content.Context.ALARM_SERVICE; |
| |
| import android.app.AlarmManager; |
| import android.app.Notification; |
| import android.app.NotificationManager; |
| import android.app.PendingIntent; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.content.res.Resources; |
| import android.net.Uri; |
| import android.os.SystemClock; |
| import android.provider.Settings; |
| import android.service.notification.StatusBarNotification; |
| import android.text.TextUtils; |
| |
| import com.android.internal.R; |
| import com.android.internal.annotations.VisibleForTesting; |
| import com.android.internal.telephony.util.NotificationChannelController; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| /** |
| * Utility methods for installing the carrier app when a SIM is insterted without the carrier app |
| * for that SIM installed. |
| */ |
| @VisibleForTesting |
| public class InstallCarrierAppUtils { |
| // TODO(b/72714040) centralize notification IDs |
| private static final int ACTIVATE_CELL_SERVICE_NOTIFICATION_ID = 12; |
| private static CarrierAppInstallReceiver sCarrierAppInstallReceiver = null; |
| |
| static void showNotification(Context context, String pkgName) { |
| Resources res = Resources.getSystem(); |
| String title = res.getString( |
| com.android.internal.R.string.install_carrier_app_notification_title); |
| String appName = getAppNameFromPackageName(context, pkgName); |
| String message; |
| if (TextUtils.isEmpty(appName)) { |
| message = res.getString(R.string.install_carrier_app_notification_text); |
| } else { |
| message = res.getString(R.string.install_carrier_app_notification_text_app_name, |
| appName); |
| } |
| String downloadButtonText = res.getString(R.string.install_carrier_app_notification_button); |
| |
| boolean persistent = Settings.Global.getInt( |
| context.getContentResolver(), |
| Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT, 1) == 1; |
| |
| PendingIntent goToStore = PendingIntent.getActivity(context, 0, |
| getPlayStoreIntent(pkgName), PendingIntent.FLAG_UPDATE_CURRENT); |
| |
| Notification.Action goToStoreAction = |
| new Notification.Action.Builder(null, downloadButtonText, goToStore).build(); |
| |
| Notification notification = new Notification.Builder(context, |
| NotificationChannelController.CHANNEL_ID_SIM) |
| .setContentTitle(title) |
| .setContentText(message) |
| .setSmallIcon(R.drawable.ic_signal_cellular_alt_24px) |
| .addAction(goToStoreAction) |
| .setOngoing(persistent) |
| .setVisibility(Notification.VISIBILITY_SECRET) // Should not appear on lock screen |
| .build(); |
| |
| getNotificationManager(context).notify( |
| pkgName, |
| ACTIVATE_CELL_SERVICE_NOTIFICATION_ID, |
| notification); |
| } |
| |
| static void hideAllNotifications(Context context) { |
| NotificationManager notificationManager = getNotificationManager(context); |
| StatusBarNotification[] activeNotifications = notificationManager.getActiveNotifications(); |
| |
| if (activeNotifications == null) { |
| return; |
| } |
| |
| for (StatusBarNotification notification : activeNotifications) { |
| if (notification.getId() == ACTIVATE_CELL_SERVICE_NOTIFICATION_ID) { |
| notificationManager.cancel(notification.getTag(), notification.getId()); |
| } |
| } |
| } |
| |
| static void hideNotification(Context context, String pkgName) { |
| getNotificationManager(context).cancel(pkgName, ACTIVATE_CELL_SERVICE_NOTIFICATION_ID); |
| } |
| |
| static Intent getPlayStoreIntent(String pkgName) { |
| // Open play store to download package |
| Intent storeIntent = new Intent(Intent.ACTION_VIEW); |
| storeIntent.setData(Uri.parse("market://details?id=" + pkgName)); |
| storeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| |
| return storeIntent; |
| } |
| |
| static void showNotificationIfNotInstalledDelayed(Context context, |
| String pkgName, long delayMillis) { |
| AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE); |
| PendingIntent pendingIntent = PendingIntent.getBroadcast( |
| context, |
| 0, |
| ShowInstallAppNotificationReceiver.get(context, pkgName), |
| 0); |
| alarmManager.set(AlarmManager.ELAPSED_REALTIME, |
| SystemClock.elapsedRealtime() + delayMillis, |
| pendingIntent); |
| |
| } |
| |
| static void registerPackageInstallReceiver(Context context) { |
| if (sCarrierAppInstallReceiver == null) { |
| sCarrierAppInstallReceiver = new CarrierAppInstallReceiver(); |
| context = context.getApplicationContext(); |
| IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); |
| intentFilter.addDataScheme("package"); |
| context.registerReceiver(sCarrierAppInstallReceiver, intentFilter); |
| } |
| } |
| |
| static void unregisterPackageInstallReceiver(Context context) { |
| if (sCarrierAppInstallReceiver == null) { |
| return; |
| } |
| context = context.getApplicationContext(); |
| context.unregisterReceiver(sCarrierAppInstallReceiver); |
| sCarrierAppInstallReceiver = null; |
| } |
| |
| static boolean isPackageInstallNotificationActive(Context context) { |
| StatusBarNotification[] activeNotifications = |
| getNotificationManager(context).getActiveNotifications(); |
| |
| for (StatusBarNotification notification : activeNotifications) { |
| if (notification.getId() == ACTIVATE_CELL_SERVICE_NOTIFICATION_ID) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| static String getAppNameFromPackageName(Context context, String packageName) { |
| String whitelistSetting = Settings.Global.getString( |
| context.getContentResolver(), |
| Settings.Global.CARRIER_APP_NAMES); |
| return getAppNameFromPackageName(packageName, whitelistSetting); |
| } |
| |
| /** |
| * @param packageName the name of the package. Will be used as a key into the map |
| * @param mapString map of package name to application name in the format: |
| * packageName1:appName1;packageName2:appName2; |
| * @return the name of the application for the package name provided. |
| */ |
| @VisibleForTesting |
| public static String getAppNameFromPackageName(String packageName, String mapString) { |
| packageName = packageName.toLowerCase(); |
| final String pairDelim = "\\s*;\\s*"; |
| final String keyValueDelim = "\\s*:\\s*"; |
| |
| if (TextUtils.isEmpty(mapString)) { |
| return null; |
| } |
| |
| List<String> keyValuePairList = Arrays.asList(mapString.split(pairDelim)); |
| |
| if (keyValuePairList.isEmpty()) { |
| return null; |
| } |
| |
| for (String keyValueString: keyValuePairList) { |
| String[] keyValue = keyValueString.split(keyValueDelim); |
| |
| if (keyValue.length == 2) { |
| if (keyValue[0].equals(packageName)) { |
| return keyValue[1]; |
| } |
| } |
| } |
| return null; |
| } |
| private static NotificationManager getNotificationManager(Context context) { |
| return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); |
| } |
| } |