• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.settings.sim;
18 
19 import static android.content.Context.MODE_PRIVATE;
20 
21 import android.annotation.IntDef;
22 import android.app.Notification;
23 import android.app.NotificationChannel;
24 import android.app.NotificationManager;
25 import android.app.PendingIntent;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.SharedPreferences;
29 import android.telephony.CarrierConfigManager;
30 import android.telephony.SubscriptionInfo;
31 import android.telephony.SubscriptionManager;
32 import android.telephony.TelephonyManager;
33 import android.text.TextUtils;
34 import android.util.Log;
35 
36 import androidx.core.app.TaskStackBuilder;
37 
38 import com.android.settings.R;
39 import com.android.settings.Settings;
40 import com.android.settings.network.SubscriptionUtil;
41 
42 import java.lang.annotation.Retention;
43 import java.lang.annotation.RetentionPolicy;
44 
45 import javax.annotation.Nullable;
46 
47 /**
48  * This class manages the notification of SIM activation notification including creating and
49  * canceling the notifications.
50  */
51 public class SimActivationNotifier {
52 
53     private static final String TAG = "SimActivationNotifier";
54     private static final String SIM_SETUP_CHANNEL_ID = "sim_setup";
55     private static final String SWITCH_SLOT_CHANNEL_ID = "carrier_switching";
56     private static final String SIM_PREFS = "sim_prefs";
57     private static final String KEY_SHOW_SIM_SETTINGS_NOTIFICATION =
58             "show_sim_settings_notification";
59 
60     public static final int SIM_ACTIVATION_NOTIFICATION_ID = 1;
61     public static final int SWITCH_TO_REMOVABLE_SLOT_NOTIFICATION_ID = 2;
62 
63     /** Notification types */
64     @Retention(RetentionPolicy.SOURCE)
65     @IntDef(
66             value = {
67                 NotificationType.NETWORK_CONFIG,
68                 NotificationType.SWITCH_TO_REMOVABLE_SLOT,
69                 NotificationType.ENABLE_DSDS,
70             })
71     public @interface NotificationType {
72         // The notification to remind users to config network Settings.
73         int NETWORK_CONFIG = 1;
74         // The notification to notify users that the device is switched to the removable slot.
75         int SWITCH_TO_REMOVABLE_SLOT = 2;
76         // The notification to notify users that the device is capable of DSDS.
77         int ENABLE_DSDS = 3;
78     }
79 
80     private final Context mContext;
81     private final NotificationManager mNotificationManager;
82 
SimActivationNotifier(Context context)83     public SimActivationNotifier(Context context) {
84         mContext = context;
85         mNotificationManager = context.getSystemService(NotificationManager.class);
86         mNotificationManager.createNotificationChannel(
87                 new NotificationChannel(
88                         SIM_SETUP_CHANNEL_ID,
89                         mContext.getString(R.string.sim_setup_channel_id),
90                         NotificationManager.IMPORTANCE_HIGH));
91         mNotificationManager.createNotificationChannel(
92                 new NotificationChannel(
93                         SWITCH_SLOT_CHANNEL_ID,
94                         mContext.getString(R.string.sim_switch_channel_id),
95                         NotificationManager.IMPORTANCE_HIGH));
96     }
97 
98     /**
99      * Sets whether Settings should send a push notification for the SIM activation.
100      *
101      * @param context
102      * @param showNotification whether Settings should send a push notification for the SIM
103      *     activation.
104      */
setShowSimSettingsNotification(Context context, boolean showNotification)105     public static void setShowSimSettingsNotification(Context context, boolean showNotification) {
106         final SharedPreferences prefs = context.getSharedPreferences(SIM_PREFS, MODE_PRIVATE);
107         prefs.edit().putBoolean(KEY_SHOW_SIM_SETTINGS_NOTIFICATION, showNotification).apply();
108     }
109 
110     /**
111      * Gets whether Settings should send a push notification for the SIM activation.
112      *
113      * @param context
114      * @return true if Settings should send a push notification for SIM activation. Otherwise,
115      *     return false.
116      */
getShowSimSettingsNotification(Context context)117     public static boolean getShowSimSettingsNotification(Context context) {
118         final SharedPreferences prefs = context.getSharedPreferences(SIM_PREFS, MODE_PRIVATE);
119         return prefs.getBoolean(KEY_SHOW_SIM_SETTINGS_NOTIFICATION, false);
120     }
121 
122     /** Sends a push notification for the SIM activation. It should be called after DSDS reboot. */
sendNetworkConfigNotification()123     public void sendNetworkConfigNotification() {
124         SubscriptionInfo activeRemovableSub = getActiveRemovableSub();
125 
126         if (activeRemovableSub == null) {
127             Log.e(TAG, "No removable subscriptions found. Do not show notification.");
128             return;
129         }
130 
131         CharSequence displayName =
132                 SubscriptionUtil.getUniqueSubscriptionDisplayName(activeRemovableSub, mContext);
133         String carrierName =
134                 TextUtils.isEmpty(displayName)
135                         ? mContext.getString(R.string.sim_card_label)
136                         : displayName.toString();
137         String title =
138                 mContext.getString(
139                         R.string.post_dsds_reboot_notification_title_with_carrier, carrierName);
140         String text = mContext.getString(R.string.post_dsds_reboot_notification_text);
141         Intent clickIntent = new Intent(mContext, Settings.MobileNetworkListActivity.class);
142         TaskStackBuilder stackBuilder =
143                 TaskStackBuilder.create(mContext).addNextIntent(clickIntent);
144         PendingIntent contentIntent =
145                 stackBuilder.getPendingIntent(
146                         0 /* requestCode */,
147                         PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
148 
149         Notification.Builder builder =
150                 new Notification.Builder(mContext, SIM_SETUP_CHANNEL_ID)
151                         .setContentTitle(title)
152                         .setContentText(text)
153                         .setContentIntent(contentIntent)
154                         .setSmallIcon(R.drawable.ic_sim_alert)
155                         .setAutoCancel(true);
156         mNotificationManager.notify(SIM_ACTIVATION_NOTIFICATION_ID, builder.build());
157     }
158 
159     /** Sends a push notification for switching to the removable slot. */
sendSwitchedToRemovableSlotNotification()160     public void sendSwitchedToRemovableSlotNotification() {
161         String carrierName = getActiveCarrierName();
162         Intent clickIntent = new Intent(mContext, Settings.MobileNetworkListActivity.class);
163         TaskStackBuilder stackBuilder =
164                 TaskStackBuilder.create(mContext).addNextIntent(clickIntent);
165         PendingIntent contentIntent =
166                 stackBuilder.getPendingIntent(
167                         0 /* requestCode */,
168                         PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
169         String titleText =
170                 TextUtils.isEmpty(carrierName)
171                         ? mContext.getString(
172                                 R.string.switch_to_removable_notification_no_carrier_name)
173                         : mContext.getString(
174                                 R.string.switch_to_removable_notification, carrierName);
175         Notification.Builder builder =
176                 new Notification.Builder(mContext, SWITCH_SLOT_CHANNEL_ID)
177                         .setContentTitle(titleText)
178                         .setContentText(
179                                 mContext.getString(R.string.network_changed_notification_text))
180                         .setContentIntent(contentIntent)
181                         .setSmallIcon(R.drawable.ic_sim_alert)
182                         .setColor(
183                                 mContext.getResources()
184                                         .getColor(
185                                                 R.color.homepage_generic_icon_background,
186                                                 null /* theme */))
187                         .setAutoCancel(true);
188         mNotificationManager.notify(SWITCH_TO_REMOVABLE_SLOT_NOTIFICATION_ID, builder.build());
189     }
190 
191     /** Sends a push notification for enabling DSDS. */
sendEnableDsdsNotification()192     public void sendEnableDsdsNotification() {
193         Intent parentIntent = new Intent(mContext, Settings.MobileNetworkListActivity.class);
194 
195         Intent clickIntent = new Intent(mContext, DsdsDialogActivity.class);
196 
197         TaskStackBuilder stackBuilder =
198                 TaskStackBuilder.create(mContext)
199                         .addNextIntentWithParentStack(parentIntent)
200                         .addNextIntent(clickIntent);
201         PendingIntent contentIntent =
202                 stackBuilder.getPendingIntent(
203                         0 /* requestCode */,
204                         PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
205 
206         Notification.Builder builder =
207                 new Notification.Builder(mContext, SIM_SETUP_CHANNEL_ID)
208                         .setContentTitle(
209                                 mContext.getString(R.string.dsds_notification_after_suw_title))
210                         .setContentText(
211                                 mContext.getString(R.string.dsds_notification_after_suw_text))
212                         .setContentIntent(contentIntent)
213                         .setSmallIcon(R.drawable.ic_sim_alert)
214                         .setAutoCancel(true);
215         mNotificationManager.notify(SIM_ACTIVATION_NOTIFICATION_ID, builder.build());
216     }
217 
218     @Nullable
getActiveRemovableSub()219     private SubscriptionInfo getActiveRemovableSub() {
220         SubscriptionManager subscriptionManager =
221                 mContext.getSystemService(SubscriptionManager.class);
222         return SubscriptionUtil.getActiveSubscriptions(subscriptionManager).stream()
223                 .filter(sub -> !sub.isEmbedded())
224                 .findFirst()
225                 .orElse(null);
226     }
227 
228     @Nullable
getActiveCarrierName()229     private String getActiveCarrierName() {
230         CarrierConfigManager configManager = mContext.getSystemService(CarrierConfigManager.class);
231         TelephonyManager telManager = mContext.getSystemService(TelephonyManager.class);
232         String telName = telManager.getSimOperatorName();
233         if (configManager != null && configManager.getConfig() != null) {
234             boolean override =
235                     configManager
236                             .getConfig()
237                             .getBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL);
238             String configName =
239                     configManager
240                             .getConfig()
241                             .getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
242 
243             return override || TextUtils.isEmpty(telName) ? configName : telName;
244         }
245         return telName;
246     }
247 }
248