• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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;
18 
19 import android.app.Notification;
20 import android.app.NotificationManager;
21 import android.app.PendingIntent;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.res.Resources;
25 import android.os.Handler;
26 import android.os.HandlerExecutor;
27 import android.os.Message;
28 import android.os.PersistableBundle;
29 import android.provider.Settings;
30 import android.telephony.CarrierConfigManager;
31 import android.telephony.RadioAccessFamily;
32 import android.telephony.ServiceState;
33 import android.telephony.SubscriptionManager;
34 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
35 import android.telephony.TelephonyCallback;
36 import android.telephony.TelephonyManager;
37 import android.telephony.TelephonyManager.NetworkTypeBitMask;
38 
39 import com.android.internal.annotations.VisibleForTesting;
40 import com.android.internal.telephony.util.ArrayUtils;
41 import com.android.internal.telephony.util.NotificationChannelController;
42 import com.android.telephony.Rlog;
43 
44 import java.util.HashMap;
45 import java.util.Map;
46 
47 /**
48  * This contains Carrier specific logic based on the states/events
49  * managed in ServiceStateTracker.
50  * {@hide}
51  */
52 public class CarrierServiceStateTracker extends Handler {
53     private static final String LOG_TAG = "CSST";
54     protected static final int CARRIER_EVENT_BASE = 100;
55     protected static final int CARRIER_EVENT_VOICE_REGISTRATION = CARRIER_EVENT_BASE + 1;
56     protected static final int CARRIER_EVENT_VOICE_DEREGISTRATION = CARRIER_EVENT_BASE + 2;
57     protected static final int CARRIER_EVENT_DATA_REGISTRATION = CARRIER_EVENT_BASE + 3;
58     protected static final int CARRIER_EVENT_DATA_DEREGISTRATION = CARRIER_EVENT_BASE + 4;
59     protected static final int CARRIER_EVENT_IMS_CAPABILITIES_CHANGED = CARRIER_EVENT_BASE + 5;
60 
61     private static final int UNINITIALIZED_DELAY_VALUE = -1;
62     private Phone mPhone;
63     private ServiceStateTracker mSST;
64     private final Map<Integer, NotificationType> mNotificationTypeMap = new HashMap<>();
65     private int mPreviousSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
66     public static final int NOTIFICATION_PREF_NETWORK = 1000;
67     public static final int NOTIFICATION_EMERGENCY_NETWORK = 1001;
68 
69     @VisibleForTesting
70     public static final String EMERGENCY_NOTIFICATION_TAG = "EmergencyNetworkNotification";
71 
72     @VisibleForTesting
73     public static final String PREF_NETWORK_NOTIFICATION_TAG = "PrefNetworkNotification";
74 
75     private long mAllowedNetworkType = -1;
76     private AllowedNetworkTypesListener mAllowedNetworkTypesListener;
77     private TelephonyManager mTelephonyManager;
78 
79     /**
80      * The listener for allowed network types changed
81      */
82     @VisibleForTesting
83     public class AllowedNetworkTypesListener extends TelephonyCallback
84             implements TelephonyCallback.AllowedNetworkTypesListener {
85         @Override
onAllowedNetworkTypesChanged(int reason, long newAllowedNetworkType)86         public void onAllowedNetworkTypesChanged(int reason, long newAllowedNetworkType) {
87             if (reason != TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER) {
88                 return;
89             }
90 
91             if (mAllowedNetworkType != newAllowedNetworkType) {
92                 mAllowedNetworkType = newAllowedNetworkType;
93                 handleAllowedNetworkTypeChanged();
94             }
95         }
96     }
97 
CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst)98     public CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst) {
99         this.mPhone = phone;
100         this.mSST = sst;
101         mTelephonyManager = mPhone.getContext().getSystemService(
102                 TelephonyManager.class).createForSubscriptionId(mPhone.getSubId());
103         CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
104         ccm.registerCarrierConfigChangeListener(
105                 mPhone.getContext().getMainExecutor(),
106                 (slotIndex, subId, carrierId, specificCarrierId) -> {
107                     if (slotIndex != mPhone.getPhoneId()) return;
108 
109                     Rlog.d(LOG_TAG, "onCarrierConfigChanged: slotIndex=" + slotIndex
110                             + ", subId=" + subId + ", carrierId=" + carrierId);
111 
112                     // Only get carrier configs used for EmergencyNetworkNotification
113                     // and PrefNetworkNotification
114                     PersistableBundle b =
115                             CarrierConfigManager.getCarrierConfigSubset(
116                                     mPhone.getContext(),
117                                     mPhone.getSubId(),
118                                     CarrierConfigManager.KEY_EMERGENCY_NOTIFICATION_DELAY_INT,
119                                     CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT,
120                                     CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL);
121                     if (b.isEmpty()) return;
122 
123                     for (Map.Entry<Integer, NotificationType> entry :
124                             mNotificationTypeMap.entrySet()) {
125                         NotificationType notificationType = entry.getValue();
126                         notificationType.setDelay(b);
127                         notificationType.setEnabled(b);
128                     }
129                     handleConfigChanges();
130                 });
131 
132         // Listen for subscriber changes
133         SubscriptionManager.from(mPhone.getContext()).addOnSubscriptionsChangedListener(
134                 new OnSubscriptionsChangedListener(this.getLooper()) {
135                     @Override
136                     public void onSubscriptionsChanged() {
137                         int subId = mPhone.getSubId();
138                         if (mPreviousSubId != subId) {
139                             mPreviousSubId = subId;
140                             mTelephonyManager = mTelephonyManager.createForSubscriptionId(
141                                     mPhone.getSubId());
142                             registerAllowedNetworkTypesListener();
143                         }
144                     }
145                 });
146 
147         registerNotificationTypes();
148         mAllowedNetworkType = RadioAccessFamily.getNetworkTypeFromRaf(
149                 (int) mPhone.getAllowedNetworkTypes(
150                         TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER));
151         mAllowedNetworkTypesListener = new AllowedNetworkTypesListener();
152         registerAllowedNetworkTypesListener();
153     }
154 
155     /**
156      * Return preferred network mode listener
157      */
158     @VisibleForTesting
getAllowedNetworkTypesChangedListener()159     public AllowedNetworkTypesListener getAllowedNetworkTypesChangedListener() {
160         return mAllowedNetworkTypesListener;
161     }
162 
registerAllowedNetworkTypesListener()163     private void registerAllowedNetworkTypesListener() {
164         int subId = mPhone.getSubId();
165         unregisterAllowedNetworkTypesListener();
166         if (SubscriptionManager.isValidSubscriptionId(subId)) {
167             if (mTelephonyManager != null) {
168                 mTelephonyManager.registerTelephonyCallback(new HandlerExecutor(this),
169                         mAllowedNetworkTypesListener);
170             }
171         }
172     }
173 
unregisterAllowedNetworkTypesListener()174     private void unregisterAllowedNetworkTypesListener() {
175         mTelephonyManager.unregisterTelephonyCallback(mAllowedNetworkTypesListener);
176     }
177 
178     /**
179      * Returns mNotificationTypeMap
180      */
181     @VisibleForTesting
getNotificationTypeMap()182     public Map<Integer, NotificationType> getNotificationTypeMap() {
183         return mNotificationTypeMap;
184     }
185 
registerNotificationTypes()186     private void registerNotificationTypes() {
187         mNotificationTypeMap.put(NOTIFICATION_PREF_NETWORK,
188                 new PrefNetworkNotification(NOTIFICATION_PREF_NETWORK));
189         mNotificationTypeMap.put(NOTIFICATION_EMERGENCY_NETWORK,
190                 new EmergencyNetworkNotification(NOTIFICATION_EMERGENCY_NETWORK));
191     }
192 
193     @Override
handleMessage(Message msg)194     public void handleMessage(Message msg) {
195         switch (msg.what) {
196             case CARRIER_EVENT_VOICE_REGISTRATION:
197             case CARRIER_EVENT_DATA_REGISTRATION:
198             case CARRIER_EVENT_VOICE_DEREGISTRATION:
199             case CARRIER_EVENT_DATA_DEREGISTRATION:
200                 handleConfigChanges();
201                 break;
202             case CARRIER_EVENT_IMS_CAPABILITIES_CHANGED:
203                 handleImsCapabilitiesChanged();
204                 break;
205             case NOTIFICATION_EMERGENCY_NETWORK:
206             case NOTIFICATION_PREF_NETWORK:
207                 Rlog.d(LOG_TAG, "sending notification after delay: " + msg.what);
208                 NotificationType notificationType = mNotificationTypeMap.get(msg.what);
209                 if (notificationType != null) {
210                     sendNotification(notificationType);
211                 }
212                 break;
213         }
214     }
215 
isPhoneStillRegistered()216     private boolean isPhoneStillRegistered() {
217         if (mSST.mSS == null) {
218             return true; //something has gone wrong, return true and not show the notification.
219         }
220         return (mSST.mSS.getState() == ServiceState.STATE_IN_SERVICE
221                 || mSST.mSS.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE);
222     }
223 
isPhoneRegisteredForWifiCalling()224     private boolean isPhoneRegisteredForWifiCalling() {
225         Rlog.d(LOG_TAG, "isPhoneRegisteredForWifiCalling: " + mPhone.isWifiCallingEnabled());
226         return mPhone.isWifiCallingEnabled();
227     }
228 
229     /**
230      * Returns true if the radio is off or in Airplane Mode else returns false.
231      */
232     @VisibleForTesting
isRadioOffOrAirplaneMode()233     public boolean isRadioOffOrAirplaneMode() {
234         Context context = mPhone.getContext();
235         int airplaneMode = -1;
236         try {
237             airplaneMode = Settings.Global.getInt(context.getContentResolver(),
238                     Settings.Global.AIRPLANE_MODE_ON, 0);
239         } catch (Exception e) {
240             Rlog.e(LOG_TAG, "Unable to get AIRPLACE_MODE_ON.");
241             return true;
242         }
243         return (!mSST.isRadioOn() || (airplaneMode != 0));
244     }
245 
246     /**
247      * Returns true if the preferred network is set to 'Global'.
248      */
isGlobalMode()249     private boolean isGlobalMode() {
250         int preferredNetworkSetting = -1;
251         try {
252             preferredNetworkSetting = PhoneFactory.calculatePreferredNetworkType(
253                     mPhone.getPhoneId());
254         } catch (Exception e) {
255             Rlog.e(LOG_TAG, "Unable to get PREFERRED_NETWORK_MODE.");
256             return true;
257         }
258 
259         if (isNrSupported()) {
260             return (preferredNetworkSetting
261                     == RadioAccessFamily.getRafFromNetworkType(
262                     RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA));
263         } else {
264             return (preferredNetworkSetting == RadioAccessFamily.getRafFromNetworkType(
265                     RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
266         }
267     }
268 
isNrSupported()269     private boolean isNrSupported() {
270         Context context = mPhone.getContext();
271         TelephonyManager tm = ((TelephonyManager) context.getSystemService(
272                 Context.TELEPHONY_SERVICE)).createForSubscriptionId(mPhone.getSubId());
273 
274         boolean isCarrierConfigEnabled = isCarrierConfigEnableNr();
275         boolean isRadioAccessFamilySupported = checkSupportedBitmask(
276                 tm.getSupportedRadioAccessFamily(), TelephonyManager.NETWORK_TYPE_BITMASK_NR);
277         boolean isNrNetworkTypeAllowed = checkSupportedBitmask(
278                 tm.getAllowedNetworkTypesForReason(
279                         TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER),
280                 TelephonyManager.NETWORK_TYPE_BITMASK_NR);
281 
282         Rlog.i(LOG_TAG, "isNrSupported: " + " carrierConfigEnabled: " + isCarrierConfigEnabled
283                 + ", AccessFamilySupported: " + isRadioAccessFamilySupported
284                 + ", isNrNetworkTypeAllowed: " + isNrNetworkTypeAllowed);
285 
286         return (isCarrierConfigEnabled && isRadioAccessFamilySupported && isNrNetworkTypeAllowed);
287     }
288 
isCarrierConfigEnableNr()289     private boolean isCarrierConfigEnableNr() {
290         PersistableBundle config =
291                 CarrierConfigManager.getCarrierConfigSubset(
292                         mPhone.getContext(),
293                         mPhone.getSubId(),
294                         CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
295         if (config.isEmpty()) {
296             Rlog.e(LOG_TAG, "isCarrierConfigEnableNr: Cannot get config " + mPhone.getSubId());
297             return false;
298         }
299         int[] nrAvailabilities = config.getIntArray(
300                 CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
301         return !ArrayUtils.isEmpty(nrAvailabilities);
302     }
303 
checkSupportedBitmask(@etworkTypeBitMask long supportedBitmask, @NetworkTypeBitMask long targetBitmask)304     private boolean checkSupportedBitmask(@NetworkTypeBitMask long supportedBitmask,
305             @NetworkTypeBitMask long targetBitmask) {
306         return (targetBitmask & supportedBitmask) == targetBitmask;
307     }
308 
handleConfigChanges()309     private void handleConfigChanges() {
310         for (Map.Entry<Integer, NotificationType> entry : mNotificationTypeMap.entrySet()) {
311             NotificationType notificationType = entry.getValue();
312             evaluateSendingMessageOrCancelNotification(notificationType);
313         }
314     }
315 
handleAllowedNetworkTypeChanged()316     private void handleAllowedNetworkTypeChanged() {
317         NotificationType notificationType = mNotificationTypeMap.get(NOTIFICATION_PREF_NETWORK);
318         if (notificationType != null) {
319             evaluateSendingMessageOrCancelNotification(notificationType);
320         }
321     }
322 
handleImsCapabilitiesChanged()323     private void handleImsCapabilitiesChanged() {
324         NotificationType notificationType = mNotificationTypeMap
325                 .get(NOTIFICATION_EMERGENCY_NETWORK);
326         if (notificationType != null) {
327             evaluateSendingMessageOrCancelNotification(notificationType);
328         }
329     }
330 
evaluateSendingMessageOrCancelNotification(NotificationType notificationType)331     private void evaluateSendingMessageOrCancelNotification(NotificationType notificationType) {
332         if (evaluateSendingMessage(notificationType)) {
333             Message notificationMsg = obtainMessage(notificationType.getTypeId(), null);
334             Rlog.i(LOG_TAG, "starting timer for notifications." + notificationType.getTypeId());
335             sendMessageDelayed(notificationMsg, getDelay(notificationType));
336         } else {
337             cancelNotification(notificationType);
338             Rlog.i(LOG_TAG, "canceling notifications: " + notificationType.getTypeId());
339         }
340     }
341 
342     /**
343      * This method adds a level of indirection, and was created so we can unit the class.
344      **/
345     @VisibleForTesting
evaluateSendingMessage(NotificationType notificationType)346     public boolean evaluateSendingMessage(NotificationType notificationType) {
347         return notificationType.sendMessage();
348     }
349 
350     /**
351      * This method adds a level of indirection, and was created so we can unit the class.
352      **/
353     @VisibleForTesting
getDelay(NotificationType notificationType)354     public int getDelay(NotificationType notificationType) {
355         return notificationType.getDelay();
356     }
357 
358     /**
359      * This method adds a level of indirection, and was created so we can unit the class.
360      **/
361     @VisibleForTesting
getNotificationBuilder(NotificationType notificationType)362     public Notification.Builder getNotificationBuilder(NotificationType notificationType) {
363         return notificationType.getNotificationBuilder();
364     }
365 
366     /**
367      * This method adds a level of indirection, and was created so we can unit the class.
368      **/
369     @VisibleForTesting
getNotificationManager(Context context)370     public NotificationManager getNotificationManager(Context context) {
371         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
372     }
373 
374     /**
375      * Post a notification to the NotificationManager for changing network type.
376      */
377     @VisibleForTesting
sendNotification(NotificationType notificationType)378     public void sendNotification(NotificationType notificationType) {
379         if (!evaluateSendingMessage(notificationType)) {
380             return;
381         }
382 
383         Context context = mPhone.getContext();
384         Notification.Builder builder = getNotificationBuilder(notificationType);
385         // set some common attributes
386         builder.setWhen(System.currentTimeMillis())
387                 .setShowWhen(true)
388                 .setAutoCancel(true)
389                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
390                 .setColor(context.getResources().getColor(
391                        com.android.internal.R.color.system_notification_accent_color));
392         getNotificationManager(context).notify(notificationType.getNotificationTag(),
393                 notificationType.getNotificationId(), builder.build());
394     }
395 
396     /**
397      * Cancel notifications if a registration is pending or has been sent.
398      **/
cancelNotification(NotificationType notificationType)399     public void cancelNotification(NotificationType notificationType) {
400         Context context = mPhone.getContext();
401         removeMessages(notificationType.getTypeId());
402         getNotificationManager(context).cancel(
403                 notificationType.getNotificationTag(), notificationType.getNotificationId());
404     }
405 
406     /**
407      * Dispose the CarrierServiceStateTracker.
408      */
dispose()409     public void dispose() {
410         unregisterAllowedNetworkTypesListener();
411     }
412 
413     /**
414      * Class that defines the different types of notifications.
415      */
416     public interface NotificationType {
417 
418         /**
419          * decides if the message should be sent, Returns boolean
420          **/
sendMessage()421         boolean sendMessage();
422 
423         /**
424          * returns the interval by which the message is delayed.
425          **/
getDelay()426         int getDelay();
427 
428         /** sets the interval by which the message is delayed.
429          * @param bundle PersistableBundle
430         **/
setDelay(PersistableBundle bundle)431         void setDelay(PersistableBundle bundle);
432 
433         /**
434          * Checks whether this Notification is enabled.
435          * @return {@code true} if this Notification is enabled, false otherwise
436          */
isEnabled()437         boolean isEnabled();
438 
439         /**
440          * Sets whether this Notification is enabled. If disabled, it will not build notification.
441          * @param bundle PersistableBundle
442          */
setEnabled(PersistableBundle bundle)443         void setEnabled(PersistableBundle bundle);
444 
445         /**
446          * returns notification type id.
447          **/
getTypeId()448         int getTypeId();
449 
450         /**
451          * returns notification id.
452          **/
getNotificationId()453         int getNotificationId();
454 
455         /**
456          * returns notification tag.
457          **/
getNotificationTag()458         String getNotificationTag();
459 
460         /**
461          * returns the notification builder, for the notification to be displayed.
462          **/
getNotificationBuilder()463         Notification.Builder getNotificationBuilder();
464     }
465 
466     /**
467      * Class that defines the network notification, which is shown when the phone cannot camp on
468      * a network, and has 'preferred mode' set to global.
469      */
470     public class PrefNetworkNotification implements NotificationType {
471 
472         private final int mTypeId;
473         private int mDelay = UNINITIALIZED_DELAY_VALUE;
474         private boolean mEnabled = false;
475 
PrefNetworkNotification(int typeId)476         PrefNetworkNotification(int typeId) {
477             this.mTypeId = typeId;
478         }
479 
480         /** sets the interval by which the message is delayed.
481          * @param bundle PersistableBundle
482          **/
setDelay(PersistableBundle bundle)483         public void setDelay(PersistableBundle bundle) {
484             if (bundle == null) {
485                 Rlog.e(LOG_TAG, "bundle is null");
486                 return;
487             }
488             this.mDelay = bundle.getInt(
489                     CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT);
490             Rlog.i(LOG_TAG, "reading time to delay notification pref network: " + mDelay);
491         }
492 
getDelay()493         public int getDelay() {
494             return mDelay;
495         }
496 
497         /**
498          * Checks whether this Notification is enabled.
499          * @return {@code true} if this Notification is enabled, false otherwise
500          */
isEnabled()501         public boolean isEnabled() {
502             return mEnabled;
503         }
504 
505         /**
506          * Sets whether this Notification is enabled. If disabled, it will not build notification.
507          * @param bundle PersistableBundle
508          */
setEnabled(PersistableBundle bundle)509         public void setEnabled(PersistableBundle bundle) {
510             if (bundle == null) {
511                 Rlog.e(LOG_TAG, "bundle is null");
512                 return;
513             }
514             mEnabled = !bundle.getBoolean(
515                     CarrierConfigManager.KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL);
516             Rlog.i(LOG_TAG, "reading enabled notification pref network: " + mEnabled);
517         }
518 
getTypeId()519         public int getTypeId() {
520             return mTypeId;
521         }
522 
getNotificationId()523         public int getNotificationId() {
524             return mPhone.getSubId();
525         }
526 
getNotificationTag()527         public String getNotificationTag() {
528             return PREF_NETWORK_NOTIFICATION_TAG;
529         }
530 
531         /**
532          * Contains logic on sending notifications.
533          */
sendMessage()534         public boolean sendMessage() {
535             Rlog.i(LOG_TAG, "PrefNetworkNotification: sendMessage() w/values: "
536                     + "," + mEnabled + "," + isPhoneStillRegistered() + "," + mDelay
537                     + "," + isGlobalMode() + "," + mSST.isRadioOn());
538             if (!mEnabled || mDelay == UNINITIALIZED_DELAY_VALUE || isPhoneStillRegistered()
539                     || isGlobalMode() || isRadioOffOrAirplaneMode()) {
540                 return false;
541             }
542             return true;
543         }
544 
545         /**
546          * Builds a partial notificaiton builder, and returns it.
547          */
getNotificationBuilder()548         public Notification.Builder getNotificationBuilder() {
549             Context context = mPhone.getContext();
550             Intent notificationIntent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
551             notificationIntent.putExtra("expandable", true);
552             PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, notificationIntent,
553                     PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
554             Resources res = SubscriptionManager.getResourcesForSubId(context, mPhone.getSubId());
555             CharSequence title = res.getText(
556                     com.android.internal.R.string.NetworkPreferenceSwitchTitle);
557             CharSequence details = res.getText(
558                     com.android.internal.R.string.NetworkPreferenceSwitchSummary);
559             return new Notification.Builder(context)
560                     .setContentTitle(title)
561                     .setStyle(new Notification.BigTextStyle().bigText(details))
562                     .setContentText(details)
563                     .setChannelId(NotificationChannelController.CHANNEL_ID_ALERT)
564                     .setContentIntent(settingsIntent);
565         }
566     }
567 
568     /**
569      * Class that defines the emergency notification, which is shown when Wi-Fi Calling is
570      * available.
571      */
572     public class EmergencyNetworkNotification implements NotificationType {
573 
574         private final int mTypeId;
575         private int mDelay = UNINITIALIZED_DELAY_VALUE;
576 
EmergencyNetworkNotification(int typeId)577         EmergencyNetworkNotification(int typeId) {
578             this.mTypeId = typeId;
579         }
580 
581         /** sets the interval by which the message is delayed.
582          * @param bundle PersistableBundle
583          **/
setDelay(PersistableBundle bundle)584         public void setDelay(PersistableBundle bundle) {
585             if (bundle == null) {
586                 Rlog.e(LOG_TAG, "bundle is null");
587                 return;
588             }
589             this.mDelay = bundle.getInt(
590                     CarrierConfigManager.KEY_EMERGENCY_NOTIFICATION_DELAY_INT);
591             Rlog.i(LOG_TAG, "reading time to delay notification emergency: " + mDelay);
592         }
593 
getDelay()594         public int getDelay() {
595             return mDelay;
596         }
597 
598         /**
599          * Checks whether this Notification is enabled.
600          * @return {@code true} if this Notification is enabled, false otherwise
601          */
isEnabled()602         public boolean isEnabled() {
603             return true;
604         }
605 
606         /**
607          * Sets whether this Notification is enabled. If disabled, it will not build notification.
608          * @param bundle PersistableBundle
609          */
setEnabled(PersistableBundle bundle)610         public void setEnabled(PersistableBundle bundle) {
611             // always allowed. There is no config to hide notifications.
612         }
613 
getTypeId()614         public int getTypeId() {
615             return mTypeId;
616         }
617 
getNotificationId()618         public int getNotificationId() {
619             return mPhone.getSubId();
620         }
621 
getNotificationTag()622         public String getNotificationTag() {
623             return EMERGENCY_NOTIFICATION_TAG;
624         }
625 
626         /**
627          * Contains logic on sending notifications,
628          */
sendMessage()629         public boolean sendMessage() {
630             Rlog.i(LOG_TAG, "EmergencyNetworkNotification: sendMessage() w/values: "
631                     + "," + mDelay + "," + isPhoneRegisteredForWifiCalling() + ","
632                     + mSST.isRadioOn());
633             if (mDelay == UNINITIALIZED_DELAY_VALUE || !isPhoneRegisteredForWifiCalling()) {
634                 return false;
635             }
636             return true;
637         }
638 
639         /**
640          * Builds a partial notificaiton builder, and returns it.
641          */
getNotificationBuilder()642         public Notification.Builder getNotificationBuilder() {
643             Context context = mPhone.getContext();
644             Resources res = SubscriptionManager.getResourcesForSubId(context, mPhone.getSubId());
645             CharSequence title = res.getText(
646                     com.android.internal.R.string.EmergencyCallWarningTitle);
647             CharSequence details = res.getText(
648                     com.android.internal.R.string.EmergencyCallWarningSummary);
649             return new Notification.Builder(context)
650                     .setContentTitle(title)
651                     .setStyle(new Notification.BigTextStyle().bigText(details))
652                     .setContentText(details)
653                     .setOngoing(true)
654                     .setChannelId(NotificationChannelController.CHANNEL_ID_WFC);
655         }
656     }
657 }
658