blob: 33cb596415d5abfb7987344cc8212a45ede84bef [file] [log] [blame]
/*
* Copyright (C) 2016 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.carrierdefaultapp;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.telephony.PhoneConstants;
import com.android.carrierdefaultapp.R;
/**
* This util class provides common logic for carrier actions
*/
public class CarrierActionUtils {
private static final String TAG = CarrierActionUtils.class.getSimpleName();
private static final String PORTAL_NOTIFICATION_TAG = "CarrierDefault.Portal.Notification";
private static final String NO_DATA_NOTIFICATION_TAG = "CarrierDefault.NoData.Notification";
private static final String NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS = "mobile_data_status";
private static final int PORTAL_NOTIFICATION_ID = 0;
private static final int NO_DATA_NOTIFICATION_ID = 1;
private static boolean ENABLE = true;
// A list of supported carrier action idx
public static final int CARRIER_ACTION_ENABLE_METERED_APNS = 0;
public static final int CARRIER_ACTION_DISABLE_METERED_APNS = 1;
public static final int CARRIER_ACTION_DISABLE_RADIO = 2;
public static final int CARRIER_ACTION_ENABLE_RADIO = 3;
public static final int CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION = 4;
public static final int CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION = 5;
public static final int CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS = 6;
public static final int CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER = 7;
public static final int CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER = 8;
public static final int CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL = 9;
public static final int CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL = 10;
public static void applyCarrierAction(int actionIdx, Intent intent, Context context) {
switch (actionIdx) {
case CARRIER_ACTION_ENABLE_METERED_APNS:
onEnableAllMeteredApns(intent, context);
break;
case CARRIER_ACTION_DISABLE_METERED_APNS:
onDisableAllMeteredApns(intent, context);
break;
case CARRIER_ACTION_DISABLE_RADIO:
onDisableRadio(intent, context);
break;
case CARRIER_ACTION_ENABLE_RADIO:
onEnableRadio(intent, context);
break;
case CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION:
onShowCaptivePortalNotification(intent, context);
break;
case CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION:
onShowNoDataServiceNotification(context);
break;
case CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS:
onCancelAllNotifications(context);
break;
case CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER:
onEnableDefaultURLHandler(context);
break;
case CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER:
onDisableDefaultURLHandler(context);
break;
case CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL:
onRegisterDefaultNetworkAvail(intent, context);
break;
case CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL:
onDeregisterDefaultNetworkAvail(intent, context);
break;
default:
loge("unsupported carrier action index: " + actionIdx);
}
}
private static void onDisableAllMeteredApns(Intent intent, Context context) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.getDefaultVoiceSubscriptionId());
logd("onDisableAllMeteredApns subId: " + subId);
final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, !ENABLE);
}
private static void onEnableAllMeteredApns(Intent intent, Context context) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.getDefaultVoiceSubscriptionId());
logd("onEnableAllMeteredApns subId: " + subId);
final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
}
private static void onEnableDefaultURLHandler(Context context) {
logd("onEnableDefaultURLHandler");
final PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(
new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
private static void onDisableDefaultURLHandler(Context context) {
logd("onDisableDefaultURLHandler");
final PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(
new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
private static void onRegisterDefaultNetworkAvail(Intent intent, Context context) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.getDefaultVoiceSubscriptionId());
logd("onRegisterDefaultNetworkAvail subId: " + subId);
final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, true);
}
private static void onDeregisterDefaultNetworkAvail(Intent intent, Context context) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.getDefaultVoiceSubscriptionId());
logd("onDeregisterDefaultNetworkAvail subId: " + subId);
final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, false);
}
private static void onDisableRadio(Intent intent, Context context) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.getDefaultVoiceSubscriptionId());
logd("onDisableRadio subId: " + subId);
final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
telephonyMgr.carrierActionSetRadioEnabled(subId, !ENABLE);
}
private static void onEnableRadio(Intent intent, Context context) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.getDefaultVoiceSubscriptionId());
logd("onEnableRadio subId: " + subId);
final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
telephonyMgr.carrierActionSetRadioEnabled(subId, ENABLE);
}
private static void onShowCaptivePortalNotification(Intent intent, Context context) {
logd("onShowCaptivePortalNotification");
Intent portalIntent = new Intent(context, CaptivePortalLoginActivity.class);
portalIntent.putExtras(intent);
portalIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
| Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, portalIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = getNotification(context, R.string.portal_notification_id,
R.string.portal_notification_detail, pendingIntent);
try {
context.getSystemService(NotificationManager.class)
.notify(PORTAL_NOTIFICATION_TAG, PORTAL_NOTIFICATION_ID, notification);
} catch (NullPointerException npe) {
loge("setNotificationVisible: " + npe);
}
}
private static void onShowNoDataServiceNotification(Context context) {
logd("onShowNoDataServiceNotification");
Notification notification = getNotification(context, R.string.no_data_notification_id,
R.string.no_data_notification_detail, null);
try {
context.getSystemService(NotificationManager.class)
.notify(NO_DATA_NOTIFICATION_TAG, NO_DATA_NOTIFICATION_ID, notification);
} catch (NullPointerException npe) {
loge("setNotificationVisible: " + npe);
}
}
private static void onCancelAllNotifications(Context context) {
logd("onCancelAllNotifications");
context.getSystemService(NotificationManager.class).cancelAll();
}
private static Notification getNotification(Context context, int titleId, int textId,
PendingIntent pendingIntent) {
final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
final Resources resources = context.getResources();
String spn = telephonyMgr.getSimOperatorName();
if (TextUtils.isEmpty(spn)) {
// There is no consistent way to get the current carrier name as MNOs didn't
// bother to set EF_SPN. in the long term, we should display a generic wording if
// spn from subscription is not set.
spn = telephonyMgr.getNetworkOperatorName();
}
final Bundle extras = Bundle.forPair(Notification.EXTRA_SUBSTITUTE_APP_NAME,
resources.getString(R.string.android_system_label));
createNotificationChannels(context);
Notification.Builder builder = new Notification.Builder(context)
.setContentTitle(resources.getString(titleId))
.setContentText(String.format(resources.getString(textId), spn))
.setSmallIcon(R.drawable.ic_sim_card)
.setColor(context.getColor(
com.android.internal.R.color.system_notification_accent_color))
.setOngoing(true)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(Notification.DEFAULT_ALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true)
.setWhen(System.currentTimeMillis())
.setShowWhen(false)
.setExtras(extras)
.setChannel(NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS);
if (pendingIntent != null) {
builder.setContentIntent(pendingIntent);
}
return builder.build();
}
/**
* Creates the notification channel and registers it with NotificationManager. Also used to
* update an existing channel's name.
*/
static void createNotificationChannels(Context context) {
context.getSystemService(NotificationManager.class)
.createNotificationChannel(new NotificationChannel(
NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS,
context.getResources().getString(
R.string.mobile_data_status_notification_channel_name),
NotificationManager.IMPORTANCE_DEFAULT));
}
private static void logd(String s) {
Log.d(TAG, s);
}
private static void loge(String s) {
Log.e(TAG, s);
}
}