content: /*
   * 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);
      }
  }
  