| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2006 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.phone; | 
 | 18 |  | 
| Ta-wei Yen | afca2d6 | 2017-07-18 17:20:59 -0700 | [diff] [blame] | 19 | import static android.Manifest.permission.READ_PHONE_STATE; | 
 | 20 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 21 | import android.app.Notification; | 
 | 22 | import android.app.NotificationManager; | 
 | 23 | import android.app.PendingIntent; | 
 | 24 | import android.app.StatusBarManager; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 25 | import android.content.ComponentName; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 26 | import android.content.Context; | 
 | 27 | import android.content.Intent; | 
 | 28 | import android.content.SharedPreferences; | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 29 | import android.content.pm.ResolveInfo; | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 30 | import android.content.pm.UserInfo; | 
| Nancy Chen | b4a9270 | 2014-12-04 15:57:29 -0800 | [diff] [blame] | 31 | import android.content.res.Resources; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 32 | import android.net.Uri; | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 33 | import android.os.Handler; | 
 | 34 | import android.os.Message; | 
| Jonathan Basseri | c31f1f3 | 2015-05-12 10:13:03 -0700 | [diff] [blame] | 35 | import android.os.PersistableBundle; | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 36 | import android.os.SystemClock; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 37 | import android.os.SystemProperties; | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 38 | import android.os.UserHandle; | 
 | 39 | import android.os.UserManager; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 40 | import android.preference.PreferenceManager; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 41 | import android.provider.ContactsContract.PhoneLookup; | 
| Jeff Davidson | 6d9bf52 | 2017-11-03 14:51:13 -0700 | [diff] [blame] | 42 | import android.provider.Settings; | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 43 | import android.telecom.DefaultDialerManager; | 
| Tyler Gunn | 4d45d1c | 2014-09-12 22:17:53 -0700 | [diff] [blame] | 44 | import android.telecom.PhoneAccount; | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 45 | import android.telecom.PhoneAccountHandle; | 
 | 46 | import android.telecom.TelecomManager; | 
| Jonathan Basseri | 3649bdb | 2015-04-30 22:39:11 -0700 | [diff] [blame] | 47 | import android.telephony.CarrierConfigManager; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 48 | import android.telephony.PhoneNumberUtils; | 
 | 49 | import android.telephony.ServiceState; | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 50 | import android.telephony.SubscriptionInfo; | 
| Andrew Lee | a82b820 | 2014-11-21 16:18:28 -0800 | [diff] [blame] | 51 | import android.telephony.SubscriptionManager; | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 52 | import android.telephony.TelephonyManager; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 53 | import android.text.TextUtils; | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 54 | import android.util.ArrayMap; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 55 | import android.util.Log; | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 56 | import android.util.SparseArray; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 57 | import android.widget.Toast; | 
| Ta-wei Yen | b29425b | 2016-09-21 17:28:14 -0700 | [diff] [blame] | 58 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 59 | import com.android.internal.telephony.Phone; | 
| Jayachandran C | 2ef9a48 | 2017-05-12 22:07:47 -0700 | [diff] [blame] | 60 | import com.android.internal.telephony.PhoneFactory; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 61 | import com.android.internal.telephony.TelephonyCapabilities; | 
| fionaxu | 8b7620d | 2017-05-01 16:22:17 -0700 | [diff] [blame] | 62 | import com.android.internal.telephony.util.NotificationChannelController; | 
| Andrew Lee | bf07f76 | 2015-04-07 19:05:50 -0700 | [diff] [blame] | 63 | import com.android.phone.settings.VoicemailSettingsActivity; | 
| Ta-wei Yen | b29425b | 2016-09-21 17:28:14 -0700 | [diff] [blame] | 64 |  | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 65 | import java.util.Iterator; | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 66 | import java.util.List; | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 67 | import java.util.Set; | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 68 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 69 | /** | 
 | 70 |  * NotificationManager-related utility code for the Phone app. | 
 | 71 |  * | 
 | 72 |  * This is a singleton object which acts as the interface to the | 
 | 73 |  * framework's NotificationManager, and is used to display status bar | 
 | 74 |  * icons and control other status bar-related behavior. | 
 | 75 |  * | 
 | 76 |  * @see PhoneGlobals.notificationMgr | 
 | 77 |  */ | 
| Chiao Cheng | 312b9c9 | 2013-09-16 15:40:53 -0700 | [diff] [blame] | 78 | public class NotificationMgr { | 
| Andrew Lee | a82b820 | 2014-11-21 16:18:28 -0800 | [diff] [blame] | 79 |     private static final String LOG_TAG = NotificationMgr.class.getSimpleName(); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 80 |     private static final boolean DBG = | 
 | 81 |             (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1); | 
 | 82 |     // Do not check in with VDBG = true, since that may write PII to the system log. | 
 | 83 |     private static final boolean VDBG = false; | 
 | 84 |  | 
| Ta-wei Yen | b29425b | 2016-09-21 17:28:14 -0700 | [diff] [blame] | 85 |     private static final String MWI_SHOULD_CHECK_VVM_CONFIGURATION_KEY_PREFIX = | 
 | 86 |             "mwi_should_check_vvm_configuration_state_"; | 
 | 87 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 88 |     // notification types | 
| Santos Cordon | f68db2e | 2014-07-02 14:40:44 -0700 | [diff] [blame] | 89 |     static final int MMI_NOTIFICATION = 1; | 
 | 90 |     static final int NETWORK_SELECTION_NOTIFICATION = 2; | 
 | 91 |     static final int VOICEMAIL_NOTIFICATION = 3; | 
 | 92 |     static final int CALL_FORWARD_NOTIFICATION = 4; | 
| Jordan Liu | ff2ccd7 | 2019-07-23 15:54:41 -0700 | [diff] [blame] | 93 |     static final int DATA_ROAMING_NOTIFICATION = 5; | 
| Santos Cordon | f68db2e | 2014-07-02 14:40:44 -0700 | [diff] [blame] | 94 |     static final int SELECTED_OPERATOR_FAIL_NOTIFICATION = 6; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 95 |  | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 96 |     // Event for network selection notification. | 
 | 97 |     private static final int EVENT_PENDING_NETWORK_SELECTION_NOTIFICATION = 1; | 
 | 98 |  | 
 | 99 |     private static final long NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIME_IN_MS = 10000L; | 
 | 100 |     private static final int NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIMES = 10; | 
 | 101 |  | 
 | 102 |     private static final int STATE_UNKNOWN_SERVICE = -1; | 
 | 103 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 104 |     /** The singleton NotificationMgr instance. */ | 
 | 105 |     private static NotificationMgr sInstance; | 
 | 106 |  | 
 | 107 |     private PhoneGlobals mApp; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 108 |  | 
 | 109 |     private Context mContext; | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 110 |     private NotificationManager mNotificationManager; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 111 |     private StatusBarManager mStatusBarManager; | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 112 |     private UserManager mUserManager; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 113 |     private Toast mToast; | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 114 |     private SubscriptionManager mSubscriptionManager; | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 115 |     private TelecomManager mTelecomManager; | 
 | 116 |     private TelephonyManager mTelephonyManager; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 117 |  | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 118 |     // used to track the notification of selected network unavailable, per subscription id. | 
 | 119 |     private SparseArray<Boolean> mSelectedUnavailableNotify = new SparseArray<>(); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 120 |  | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 121 |     // used to track whether the message waiting indicator is visible, per subscription id. | 
 | 122 |     private ArrayMap<Integer, Boolean> mMwiVisible = new ArrayMap<Integer, Boolean>(); | 
 | 123 |  | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 124 |     // those flags are used to track whether to show network selection notification or not. | 
 | 125 |     private SparseArray<Integer> mPreviousServiceState = new SparseArray<>(); | 
 | 126 |     private SparseArray<Long> mOOSTimestamp = new SparseArray<>(); | 
 | 127 |     private SparseArray<Integer> mPendingEventCounter = new SparseArray<>(); | 
 | 128 |     // maps each subId to selected network operator name. | 
 | 129 |     private SparseArray<String> mSelectedNetworkOperatorName = new SparseArray<>(); | 
 | 130 |  | 
 | 131 |     private final Handler mHandler = new Handler() { | 
 | 132 |         @Override | 
 | 133 |         public void handleMessage(Message msg) { | 
 | 134 |             switch (msg.what) { | 
 | 135 |                 case EVENT_PENDING_NETWORK_SELECTION_NOTIFICATION: | 
 | 136 |                     int subId = (int) msg.obj; | 
 | 137 |                     TelephonyManager telephonyManager = | 
 | 138 |                             mTelephonyManager.createForSubscriptionId(subId); | 
 | 139 |                     if (telephonyManager.getServiceState() != null) { | 
 | 140 |                         shouldShowNotification(telephonyManager.getServiceState().getState(), | 
 | 141 |                                 subId); | 
 | 142 |                     } | 
 | 143 |                     break; | 
 | 144 |             } | 
 | 145 |         } | 
 | 146 |     }; | 
 | 147 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 148 |     /** | 
 | 149 |      * Private constructor (this is a singleton). | 
| Santos Cordon | f68db2e | 2014-07-02 14:40:44 -0700 | [diff] [blame] | 150 |      * @see #init(PhoneGlobals) | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 151 |      */ | 
 | 152 |     private NotificationMgr(PhoneGlobals app) { | 
 | 153 |         mApp = app; | 
 | 154 |         mContext = app; | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 155 |         mNotificationManager = | 
 | 156 |                 (NotificationManager) app.getSystemService(Context.NOTIFICATION_SERVICE); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 157 |         mStatusBarManager = | 
 | 158 |                 (StatusBarManager) app.getSystemService(Context.STATUS_BAR_SERVICE); | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 159 |         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE); | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 160 |         mSubscriptionManager = SubscriptionManager.from(mContext); | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 161 |         mTelecomManager = TelecomManager.from(mContext); | 
 | 162 |         mTelephonyManager = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 163 |     } | 
 | 164 |  | 
 | 165 |     /** | 
 | 166 |      * Initialize the singleton NotificationMgr instance. | 
 | 167 |      * | 
 | 168 |      * This is only done once, at startup, from PhoneApp.onCreate(). | 
 | 169 |      * From then on, the NotificationMgr instance is available via the | 
 | 170 |      * PhoneApp's public "notificationMgr" field, which is why there's no | 
 | 171 |      * getInstance() method here. | 
 | 172 |      */ | 
 | 173 |     /* package */ static NotificationMgr init(PhoneGlobals app) { | 
 | 174 |         synchronized (NotificationMgr.class) { | 
 | 175 |             if (sInstance == null) { | 
 | 176 |                 sInstance = new NotificationMgr(app); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 177 |             } else { | 
 | 178 |                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance); | 
 | 179 |             } | 
 | 180 |             return sInstance; | 
 | 181 |         } | 
 | 182 |     } | 
 | 183 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 184 |     /** The projection to use when querying the phones table */ | 
 | 185 |     static final String[] PHONES_PROJECTION = new String[] { | 
 | 186 |         PhoneLookup.NUMBER, | 
 | 187 |         PhoneLookup.DISPLAY_NAME, | 
 | 188 |         PhoneLookup._ID | 
 | 189 |     }; | 
 | 190 |  | 
 | 191 |     /** | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 192 |      * Re-creates the message waiting indicator (voicemail) notification if it is showing.  Used to | 
 | 193 |      * refresh the voicemail intent on the indicator when the user changes it via the voicemail | 
 | 194 |      * settings screen.  The voicemail notification sound is suppressed. | 
 | 195 |      * | 
 | 196 |      * @param subId The subscription Id. | 
 | 197 |      */ | 
 | 198 |     /* package */ void refreshMwi(int subId) { | 
 | 199 |         // In a single-sim device, subId can be -1 which means "no sub id".  In this case we will | 
 | 200 |         // reference the single subid stored in the mMwiVisible map. | 
| Ta-wei Yen | a1390d4 | 2017-12-04 15:11:33 -0800 | [diff] [blame] | 201 |         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 202 |             if (mMwiVisible.keySet().size() == 1) { | 
 | 203 |                 Set<Integer> keySet = mMwiVisible.keySet(); | 
 | 204 |                 Iterator<Integer> keyIt = keySet.iterator(); | 
 | 205 |                 if (!keyIt.hasNext()) { | 
 | 206 |                     return; | 
 | 207 |                 } | 
 | 208 |                 subId = keyIt.next(); | 
 | 209 |             } | 
 | 210 |         } | 
 | 211 |         if (mMwiVisible.containsKey(subId)) { | 
 | 212 |             boolean mwiVisible = mMwiVisible.get(subId); | 
 | 213 |             if (mwiVisible) { | 
| Kazuya Ohshiro | 263737d | 2017-10-06 19:42:03 +0900 | [diff] [blame] | 214 |                 mApp.notifier.updatePhoneStateListeners(true); | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 215 |             } | 
 | 216 |         } | 
 | 217 |     } | 
 | 218 |  | 
| Ta-wei Yen | b29425b | 2016-09-21 17:28:14 -0700 | [diff] [blame] | 219 |     public void setShouldCheckVisualVoicemailConfigurationForMwi(int subId, boolean enabled) { | 
 | 220 |         if (!SubscriptionManager.isValidSubscriptionId(subId)) { | 
 | 221 |             Log.e(LOG_TAG, "setShouldCheckVisualVoicemailConfigurationForMwi: invalid subId" | 
 | 222 |                     + subId); | 
 | 223 |             return; | 
 | 224 |         } | 
 | 225 |  | 
 | 226 |         PreferenceManager.getDefaultSharedPreferences(mContext).edit() | 
 | 227 |                 .putBoolean(MWI_SHOULD_CHECK_VVM_CONFIGURATION_KEY_PREFIX + subId, enabled) | 
 | 228 |                 .apply(); | 
 | 229 |     } | 
 | 230 |  | 
 | 231 |     private boolean shouldCheckVisualVoicemailConfigurationForMwi(int subId) { | 
 | 232 |         if (!SubscriptionManager.isValidSubscriptionId(subId)) { | 
 | 233 |             Log.e(LOG_TAG, "shouldCheckVisualVoicemailConfigurationForMwi: invalid subId" + subId); | 
 | 234 |             return true; | 
 | 235 |         } | 
 | 236 |         return PreferenceManager | 
 | 237 |                 .getDefaultSharedPreferences(mContext) | 
 | 238 |                 .getBoolean(MWI_SHOULD_CHECK_VVM_CONFIGURATION_KEY_PREFIX + subId, true); | 
 | 239 |     } | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 240 |     /** | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 241 |      * Updates the message waiting indicator (voicemail) notification. | 
 | 242 |      * | 
 | 243 |      * @param visible true if there are messages waiting | 
 | 244 |      */ | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 245 |     /* package */ void updateMwi(int subId, boolean visible) { | 
| Ta-wei Yen | 282a970 | 2017-05-30 17:32:29 -0700 | [diff] [blame] | 246 |         updateMwi(subId, visible, false /* isRefresh */); | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 247 |     } | 
 | 248 |  | 
 | 249 |     /** | 
 | 250 |      * Updates the message waiting indicator (voicemail) notification. | 
 | 251 |      * | 
 | 252 |      * @param subId the subId to update. | 
 | 253 |      * @param visible true if there are messages waiting | 
| Ta-wei Yen | 282a970 | 2017-05-30 17:32:29 -0700 | [diff] [blame] | 254 |      * @param isRefresh {@code true} if the notification is a refresh and the user should not be | 
 | 255 |      * notified again. | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 256 |      */ | 
| Ta-wei Yen | 282a970 | 2017-05-30 17:32:29 -0700 | [diff] [blame] | 257 |     void updateMwi(int subId, boolean visible, boolean isRefresh) { | 
| Andrew Lee | a82b820 | 2014-11-21 16:18:28 -0800 | [diff] [blame] | 258 |         if (!PhoneGlobals.sVoiceCapable) { | 
 | 259 |             // Do not show the message waiting indicator on devices which are not voice capable. | 
 | 260 |             // These events *should* be blocked at the telephony layer for such devices. | 
 | 261 |             Log.w(LOG_TAG, "Called updateMwi() on non-voice-capable device! Ignoring..."); | 
 | 262 |             return; | 
 | 263 |         } | 
 | 264 |  | 
| Nancy Chen | 2cf7f29 | 2015-05-15 11:00:10 -0700 | [diff] [blame] | 265 |         Phone phone = PhoneGlobals.getPhone(subId); | 
| Yorke Lee | 67a62a2 | 2014-12-15 18:46:17 -0800 | [diff] [blame] | 266 |         Log.i(LOG_TAG, "updateMwi(): subId " + subId + " update to " + visible); | 
| Andrew Lee | f8ad78f | 2014-12-15 16:17:29 -0800 | [diff] [blame] | 267 |         mMwiVisible.put(subId, visible); | 
 | 268 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 269 |         if (visible) { | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 270 |             if (phone == null) { | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 271 |                 Log.w(LOG_TAG, "Found null phone for: " + subId); | 
 | 272 |                 return; | 
 | 273 |             } | 
 | 274 |  | 
 | 275 |             SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId); | 
 | 276 |             if (subInfo == null) { | 
 | 277 |                 Log.w(LOG_TAG, "Found null subscription info for: " + subId); | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 278 |                 return; | 
 | 279 |             } | 
 | 280 |  | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 281 |             int resId = android.R.drawable.stat_notify_voicemail; | 
| Kazuya Ohshiro | 263737d | 2017-10-06 19:42:03 +0900 | [diff] [blame] | 282 |             if (mTelephonyManager.getPhoneCount() > 1) { | 
 | 283 |                 resId = (phone.getPhoneId() == 0) ? R.drawable.stat_notify_voicemail_sub1 | 
 | 284 |                         : R.drawable.stat_notify_voicemail_sub2; | 
 | 285 |             } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 286 |  | 
 | 287 |             // This Notification can get a lot fancier once we have more | 
 | 288 |             // information about the current voicemail messages. | 
 | 289 |             // (For example, the current voicemail system can't tell | 
 | 290 |             // us the caller-id or timestamp of a message, or tell us the | 
 | 291 |             // message count.) | 
 | 292 |  | 
 | 293 |             // But for now, the UI is ultra-simple: if the MWI indication | 
 | 294 |             // is supposed to be visible, just show a single generic | 
 | 295 |             // notification. | 
 | 296 |  | 
 | 297 |             String notificationTitle = mContext.getString(R.string.notification_voicemail_title); | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 298 |             String vmNumber = phone.getVoiceMailNumber(); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 299 |             if (DBG) log("- got vm number: '" + vmNumber + "'"); | 
 | 300 |  | 
| Andrew Lee | a82b820 | 2014-11-21 16:18:28 -0800 | [diff] [blame] | 301 |             // The voicemail number may be null because: | 
 | 302 |             //   (1) This phone has no voicemail number. | 
 | 303 |             //   (2) This phone has a voicemail number, but the SIM isn't ready yet. This may | 
 | 304 |             //       happen when the device first boots if we get a MWI notification when we | 
 | 305 |             //       register on the network before the SIM has loaded. In this case, the | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 306 |             //       SubscriptionListener in CallNotifier will update this once the SIM is loaded. | 
 | 307 |             if ((vmNumber == null) && !phone.getIccRecordsLoaded()) { | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 308 |                 if (DBG) log("- Null vm number: SIM records not loaded (yet)..."); | 
| Andrew Lee | a82b820 | 2014-11-21 16:18:28 -0800 | [diff] [blame] | 309 |                 return; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 310 |             } | 
 | 311 |  | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 312 |             Integer vmCount = null; | 
 | 313 |  | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 314 |             if (TelephonyCapabilities.supportsVoiceMessageCount(phone)) { | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 315 |                 vmCount = phone.getVoiceMessageCount(); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 316 |                 String titleFormat = mContext.getString(R.string.notification_voicemail_title_count); | 
 | 317 |                 notificationTitle = String.format(titleFormat, vmCount); | 
 | 318 |             } | 
 | 319 |  | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 320 |             // This pathway only applies to PSTN accounts; only SIMS have subscription ids. | 
 | 321 |             PhoneAccountHandle phoneAccountHandle = PhoneUtils.makePstnPhoneAccountHandle(phone); | 
 | 322 |  | 
 | 323 |             Intent intent; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 324 |             String notificationText; | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 325 |             boolean isSettingsIntent = TextUtils.isEmpty(vmNumber); | 
 | 326 |  | 
 | 327 |             if (isSettingsIntent) { | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 328 |                 notificationText = mContext.getString( | 
 | 329 |                         R.string.notification_voicemail_no_vm_number); | 
 | 330 |  | 
 | 331 |                 // If the voicemail number if unknown, instead of calling voicemail, take the user | 
 | 332 |                 // to the voicemail settings. | 
 | 333 |                 notificationText = mContext.getString( | 
 | 334 |                         R.string.notification_voicemail_no_vm_number); | 
| Andrew Lee | bf07f76 | 2015-04-07 19:05:50 -0700 | [diff] [blame] | 335 |                 intent = new Intent(VoicemailSettingsActivity.ACTION_ADD_VOICEMAIL); | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 336 |                 intent.putExtra(SubscriptionInfoHelper.SUB_ID_EXTRA, subId); | 
| Andrew Lee | bf07f76 | 2015-04-07 19:05:50 -0700 | [diff] [blame] | 337 |                 intent.setClass(mContext, VoicemailSettingsActivity.class); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 338 |             } else { | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 339 |                 if (mTelephonyManager.getPhoneCount() > 1) { | 
 | 340 |                     notificationText = subInfo.getDisplayName().toString(); | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 341 |                 } else { | 
 | 342 |                     notificationText = String.format( | 
 | 343 |                             mContext.getString(R.string.notification_voicemail_text_format), | 
 | 344 |                             PhoneNumberUtils.formatNumber(vmNumber)); | 
 | 345 |                 } | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 346 |                 intent = new Intent( | 
 | 347 |                         Intent.ACTION_CALL, Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", | 
| Jonathan Basseri | 3649bdb | 2015-04-30 22:39:11 -0700 | [diff] [blame] | 348 |                                 null)); | 
| Tyler Gunn | 9c1071f | 2014-12-09 10:07:54 -0800 | [diff] [blame] | 349 |                 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 350 |             } | 
 | 351 |  | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 352 |             PendingIntent pendingIntent = | 
 | 353 |                     PendingIntent.getActivity(mContext, subId /* requestCode */, intent, 0); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 354 |  | 
| Nancy Chen | b4a9270 | 2014-12-04 15:57:29 -0800 | [diff] [blame] | 355 |             Resources res = mContext.getResources(); | 
| Jonathan Basseri | c31f1f3 | 2015-05-12 10:13:03 -0700 | [diff] [blame] | 356 |             PersistableBundle carrierConfig = PhoneGlobals.getInstance().getCarrierConfigForSubId( | 
| Ta-wei Yen | 9b37a87 | 2016-05-27 12:16:58 -0700 | [diff] [blame] | 357 |                     subId); | 
| fionaxu | 8b7620d | 2017-05-01 16:22:17 -0700 | [diff] [blame] | 358 |             Notification.Builder builder = new Notification.Builder(mContext); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 359 |             builder.setSmallIcon(resId) | 
 | 360 |                     .setWhen(System.currentTimeMillis()) | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 361 |                     .setColor(subInfo.getIconTint()) | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 362 |                     .setContentTitle(notificationTitle) | 
 | 363 |                     .setContentText(notificationText) | 
 | 364 |                     .setContentIntent(pendingIntent) | 
| Nancy Chen | b4a9270 | 2014-12-04 15:57:29 -0800 | [diff] [blame] | 365 |                     .setColor(res.getColor(R.color.dialer_theme_color)) | 
| Jonathan Basseri | 3649bdb | 2015-04-30 22:39:11 -0700 | [diff] [blame] | 366 |                     .setOngoing(carrierConfig.getBoolean( | 
| fionaxu | 75b66a7 | 2017-04-19 19:01:56 -0700 | [diff] [blame] | 367 |                             CarrierConfigManager.KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL)) | 
| Jordan Liu | 575c0d0 | 2019-07-09 16:29:48 -0700 | [diff] [blame] | 368 |                     .setChannelId(NotificationChannelController.CHANNEL_ID_VOICE_MAIL) | 
| Ta-wei Yen | 282a970 | 2017-05-30 17:32:29 -0700 | [diff] [blame] | 369 |                     .setOnlyAlertOnce(isRefresh); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 370 |  | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 371 |             final Notification notification = builder.build(); | 
 | 372 |             List<UserInfo> users = mUserManager.getUsers(true); | 
 | 373 |             for (int i = 0; i < users.size(); i++) { | 
| Yorke Lee | 047b1f9 | 2014-10-24 10:22:41 -0700 | [diff] [blame] | 374 |                 final UserInfo user = users.get(i); | 
 | 375 |                 final UserHandle userHandle = user.getUserHandle(); | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 376 |                 if (!mUserManager.hasUserRestriction( | 
| Yorke Lee | 047b1f9 | 2014-10-24 10:22:41 -0700 | [diff] [blame] | 377 |                         UserManager.DISALLOW_OUTGOING_CALLS, userHandle) | 
| Jonathan Basseri | 3649bdb | 2015-04-30 22:39:11 -0700 | [diff] [blame] | 378 |                         && !user.isManagedProfile()) { | 
| Ta-wei Yen | a71a38b | 2017-02-24 18:19:27 -0800 | [diff] [blame] | 379 |                     if (!maybeSendVoicemailNotificationUsingDefaultDialer(phone, vmCount, vmNumber, | 
| Ta-wei Yen | 282a970 | 2017-05-30 17:32:29 -0700 | [diff] [blame] | 380 |                             pendingIntent, isSettingsIntent, userHandle, isRefresh)) { | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 381 |                         mNotificationManager.notifyAsUser( | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 382 |                                 Integer.toString(subId) /* tag */, | 
 | 383 |                                 VOICEMAIL_NOTIFICATION, | 
 | 384 |                                 notification, | 
 | 385 |                                 userHandle); | 
 | 386 |                     } | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 387 |                 } | 
 | 388 |             } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 389 |         } else { | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 390 |             List<UserInfo> users = mUserManager.getUsers(true /* excludeDying */); | 
 | 391 |             for (int i = 0; i < users.size(); i++) { | 
 | 392 |                 final UserInfo user = users.get(i); | 
 | 393 |                 final UserHandle userHandle = user.getUserHandle(); | 
 | 394 |                 if (!mUserManager.hasUserRestriction( | 
 | 395 |                         UserManager.DISALLOW_OUTGOING_CALLS, userHandle) | 
 | 396 |                         && !user.isManagedProfile()) { | 
| Ta-wei Yen | a71a38b | 2017-02-24 18:19:27 -0800 | [diff] [blame] | 397 |                     if (!maybeSendVoicemailNotificationUsingDefaultDialer(phone, 0, null, null, | 
| Ta-wei Yen | 282a970 | 2017-05-30 17:32:29 -0700 | [diff] [blame] | 398 |                             false, userHandle, isRefresh)) { | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 399 |                         mNotificationManager.cancelAsUser( | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 400 |                                 Integer.toString(subId) /* tag */, | 
 | 401 |                                 VOICEMAIL_NOTIFICATION, | 
 | 402 |                                 userHandle); | 
 | 403 |                     } | 
 | 404 |                 } | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 405 |             } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 406 |         } | 
 | 407 |     } | 
 | 408 |  | 
 | 409 |     /** | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 410 |      * Sends a broadcast with the voicemail notification information to the default dialer. This | 
 | 411 |      * method is also used to indicate to the default dialer when to clear the | 
 | 412 |      * notification. A pending intent can be passed to the default dialer to indicate an action to | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 413 |      * be taken as it would by a notification produced in this class. | 
| Ta-wei Yen | a71a38b | 2017-02-24 18:19:27 -0800 | [diff] [blame] | 414 |      * @param phone The phone the notification is sent from | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 415 |      * @param count The number of pending voicemail messages to indicate on the notification. A | 
 | 416 |      *              Value of 0 is passed here to indicate that the notification should be cleared. | 
 | 417 |      * @param number The voicemail phone number if specified. | 
 | 418 |      * @param pendingIntent The intent that should be passed as the action to be taken. | 
 | 419 |      * @param isSettingsIntent {@code true} to indicate the pending intent is to launch settings. | 
 | 420 |      *                         otherwise, {@code false} to indicate the intent launches voicemail. | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 421 |      * @param userHandle The user to receive the notification. Each user can have their own default | 
 | 422 |      *                   dialer. | 
 | 423 |      * @return {@code true} if the default was notified of the notification. | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 424 |      */ | 
| Ta-wei Yen | a71a38b | 2017-02-24 18:19:27 -0800 | [diff] [blame] | 425 |     private boolean maybeSendVoicemailNotificationUsingDefaultDialer(Phone phone, Integer count, | 
 | 426 |             String number, PendingIntent pendingIntent, boolean isSettingsIntent, | 
| Ta-wei Yen | 282a970 | 2017-05-30 17:32:29 -0700 | [diff] [blame] | 427 |             UserHandle userHandle, boolean isRefresh) { | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 428 |  | 
 | 429 |         if (shouldManageNotificationThroughDefaultDialer(userHandle)) { | 
 | 430 |             Intent intent = getShowVoicemailIntentForDefaultDialer(userHandle); | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 431 |             intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 432 |             intent.setAction(TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION); | 
| Ta-wei Yen | a71a38b | 2017-02-24 18:19:27 -0800 | [diff] [blame] | 433 |             intent.putExtra(TelephonyManager.EXTRA_PHONE_ACCOUNT_HANDLE, | 
 | 434 |                     PhoneUtils.makePstnPhoneAccountHandle(phone)); | 
| Ta-wei Yen | afca2d6 | 2017-07-18 17:20:59 -0700 | [diff] [blame] | 435 |             intent.putExtra(TelephonyManager.EXTRA_IS_REFRESH, isRefresh); | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 436 |             if (count != null) { | 
 | 437 |                 intent.putExtra(TelephonyManager.EXTRA_NOTIFICATION_COUNT, count); | 
 | 438 |             } | 
 | 439 |  | 
 | 440 |             // Additional information about the voicemail notification beyond the count is only | 
 | 441 |             // present when the count not specified or greater than 0. The value of 0 represents | 
 | 442 |             // clearing the notification, which does not require additional information. | 
 | 443 |             if (count == null || count > 0) { | 
 | 444 |                 if (!TextUtils.isEmpty(number)) { | 
 | 445 |                     intent.putExtra(TelephonyManager.EXTRA_VOICEMAIL_NUMBER, number); | 
 | 446 |                 } | 
 | 447 |  | 
 | 448 |                 if (pendingIntent != null) { | 
 | 449 |                     intent.putExtra(isSettingsIntent | 
 | 450 |                             ? TelephonyManager.EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT | 
 | 451 |                             : TelephonyManager.EXTRA_CALL_VOICEMAIL_INTENT, | 
 | 452 |                             pendingIntent); | 
 | 453 |                 } | 
 | 454 |             } | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 455 |             mContext.sendBroadcastAsUser(intent, userHandle, READ_PHONE_STATE); | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 456 |             return true; | 
 | 457 |         } | 
 | 458 |  | 
 | 459 |         return false; | 
 | 460 |     } | 
 | 461 |  | 
| Ta-wei Yen | 5bb1956 | 2016-11-16 11:05:37 -0800 | [diff] [blame] | 462 |     private Intent getShowVoicemailIntentForDefaultDialer(UserHandle userHandle) { | 
 | 463 |         String dialerPackage = DefaultDialerManager | 
 | 464 |                 .getDefaultDialerApplication(mContext, userHandle.getIdentifier()); | 
 | 465 |         return new Intent(TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION) | 
 | 466 |                 .setPackage(dialerPackage); | 
 | 467 |     } | 
 | 468 |  | 
 | 469 |     private boolean shouldManageNotificationThroughDefaultDialer(UserHandle userHandle) { | 
 | 470 |         Intent intent = getShowVoicemailIntentForDefaultDialer(userHandle); | 
 | 471 |         if (intent == null) { | 
 | 472 |             return false; | 
 | 473 |         } | 
 | 474 |  | 
 | 475 |         List<ResolveInfo> receivers = mContext.getPackageManager() | 
 | 476 |                 .queryBroadcastReceivers(intent, 0); | 
 | 477 |         return receivers.size() > 0; | 
 | 478 |     } | 
 | 479 |  | 
| Bryce Lee | 5dc9084 | 2015-08-11 07:57:14 -0700 | [diff] [blame] | 480 |     /** | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 481 |      * Updates the message call forwarding indicator notification. | 
 | 482 |      * | 
| Srikanth Chintala | 4baf0b9 | 2017-11-14 15:52:47 +0530 | [diff] [blame] | 483 |      * @param visible true if call forwarding enabled | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 484 |      */ | 
| Srikanth Chintala | 4baf0b9 | 2017-11-14 15:52:47 +0530 | [diff] [blame] | 485 |  | 
 | 486 |      /* package */ void updateCfi(int subId, boolean visible) { | 
 | 487 |         updateCfi(subId, visible, false /* isRefresh */); | 
 | 488 |     } | 
 | 489 |  | 
 | 490 |     /** | 
 | 491 |      * Updates the message call forwarding indicator notification. | 
 | 492 |      * | 
 | 493 |      * @param visible true if call forwarding enabled | 
 | 494 |      */ | 
 | 495 |     /* package */ void updateCfi(int subId, boolean visible, boolean isRefresh) { | 
| Tyler Gunn | a584e2c | 2017-09-19 11:40:12 -0700 | [diff] [blame] | 496 |         logi("updateCfi: subId= " + subId + ", visible=" + (visible ? "Y" : "N")); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 497 |         if (visible) { | 
 | 498 |             // If Unconditional Call Forwarding (forward all calls) for VOICE | 
 | 499 |             // is enabled, just show a notification.  We'll default to expanded | 
 | 500 |             // view for now, so the there is less confusion about the icon.  If | 
 | 501 |             // it is deemed too weird to have CF indications as expanded views, | 
 | 502 |             // then we'll flip the flag back. | 
 | 503 |  | 
 | 504 |             // TODO: We may want to take a look to see if the notification can | 
 | 505 |             // display the target to forward calls to.  This will require some | 
 | 506 |             // effort though, since there are multiple layers of messages that | 
 | 507 |             // will need to propagate that information. | 
 | 508 |  | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 509 |             SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId); | 
 | 510 |             if (subInfo == null) { | 
 | 511 |                 Log.w(LOG_TAG, "Found null subscription info for: " + subId); | 
 | 512 |                 return; | 
 | 513 |             } | 
 | 514 |  | 
 | 515 |             String notificationTitle; | 
| Kazuya Ohshiro | 263737d | 2017-10-06 19:42:03 +0900 | [diff] [blame] | 516 |             int resId = R.drawable.stat_sys_phone_call_forward; | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 517 |             if (mTelephonyManager.getPhoneCount() > 1) { | 
| Kazuya Ohshiro | 263737d | 2017-10-06 19:42:03 +0900 | [diff] [blame] | 518 |                 int slotId = SubscriptionManager.getSlotIndex(subId); | 
 | 519 |                 resId = (slotId == 0) ? R.drawable.stat_sys_phone_call_forward_sub1 | 
 | 520 |                         : R.drawable.stat_sys_phone_call_forward_sub2; | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 521 |                 notificationTitle = subInfo.getDisplayName().toString(); | 
 | 522 |             } else { | 
 | 523 |                 notificationTitle = mContext.getString(R.string.labelCF); | 
 | 524 |             } | 
 | 525 |  | 
| fionaxu | 8b7620d | 2017-05-01 16:22:17 -0700 | [diff] [blame] | 526 |             Notification.Builder builder = new Notification.Builder(mContext) | 
| Kazuya Ohshiro | 263737d | 2017-10-06 19:42:03 +0900 | [diff] [blame] | 527 |                     .setSmallIcon(resId) | 
| Andrew Lee | d5165b0 | 2014-12-05 15:53:58 -0800 | [diff] [blame] | 528 |                     .setColor(subInfo.getIconTint()) | 
 | 529 |                     .setContentTitle(notificationTitle) | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 530 |                     .setContentText(mContext.getString(R.string.sum_cfu_enabled_indicator)) | 
 | 531 |                     .setShowWhen(false) | 
| fionaxu | 75b66a7 | 2017-04-19 19:01:56 -0700 | [diff] [blame] | 532 |                     .setOngoing(true) | 
| Jordan Liu | 575c0d0 | 2019-07-09 16:29:48 -0700 | [diff] [blame] | 533 |                     .setChannelId(NotificationChannelController.CHANNEL_ID_CALL_FORWARD) | 
| Srikanth Chintala | 4baf0b9 | 2017-11-14 15:52:47 +0530 | [diff] [blame] | 534 |                     .setOnlyAlertOnce(isRefresh); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 535 |  | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 536 |             Intent intent = new Intent(Intent.ACTION_MAIN); | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 537 |             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 538 |             intent.setClassName("com.android.phone", "com.android.phone.CallFeaturesSetting"); | 
| Andrew Lee | 2fcb6c3 | 2014-12-04 14:52:35 -0800 | [diff] [blame] | 539 |             SubscriptionInfoHelper.addExtrasToIntent( | 
 | 540 |                     intent, mSubscriptionManager.getActiveSubscriptionInfo(subId)); | 
| fionaxu | 96ceebd | 2017-08-24 12:12:32 -0700 | [diff] [blame] | 541 |             builder.setContentIntent(PendingIntent.getActivity(mContext, subId /* requestCode */, | 
 | 542 |                     intent, 0)); | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 543 |             mNotificationManager.notifyAsUser( | 
| fionaxu | 96ceebd | 2017-08-24 12:12:32 -0700 | [diff] [blame] | 544 |                     Integer.toString(subId) /* tag */, | 
 | 545 |                     CALL_FORWARD_NOTIFICATION, | 
 | 546 |                     builder.build(), | 
 | 547 |                     UserHandle.ALL); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 548 |         } else { | 
| Kazuya Ohshiro | 263737d | 2017-10-06 19:42:03 +0900 | [diff] [blame] | 549 |             List<UserInfo> users = mUserManager.getUsers(true); | 
 | 550 |             for (UserInfo user : users) { | 
 | 551 |                 if (user.isManagedProfile()) { | 
 | 552 |                     continue; | 
 | 553 |                 } | 
 | 554 |                 UserHandle userHandle = user.getUserHandle(); | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 555 |                 mNotificationManager.cancelAsUser( | 
| Kazuya Ohshiro | 263737d | 2017-10-06 19:42:03 +0900 | [diff] [blame] | 556 |                         Integer.toString(subId) /* tag */, | 
 | 557 |                         CALL_FORWARD_NOTIFICATION, | 
 | 558 |                         userHandle); | 
 | 559 |             } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 560 |         } | 
 | 561 |     } | 
 | 562 |  | 
 | 563 |     /** | 
| Jordan Liu | ff2ccd7 | 2019-07-23 15:54:41 -0700 | [diff] [blame] | 564 |      * Shows either: | 
 | 565 |      * 1) the "Data roaming is on" notification, which | 
 | 566 |      * appears when you're roaming and you have the "data roaming" feature turned on for the | 
 | 567 |      * given {@code subId}. | 
 | 568 |      * or | 
 | 569 |      * 2) the "data disconnected due to roaming" notification, which | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 570 |      * appears when you lose data connectivity because you're roaming and | 
| Pengquan Meng | 8783d93 | 2017-10-16 14:57:40 -0700 | [diff] [blame] | 571 |      * you have the "data roaming" feature turned off for the given {@code subId}. | 
| Jordan Liu | ff2ccd7 | 2019-07-23 15:54:41 -0700 | [diff] [blame] | 572 |      * @param subId which subscription it's notifying about. | 
 | 573 |      * @param roamingOn whether currently roaming is on or off. If true, we show notification | 
 | 574 |      *                  1) above; else we show notification 2). | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 575 |      */ | 
| Jordan Liu | ff2ccd7 | 2019-07-23 15:54:41 -0700 | [diff] [blame] | 576 |     /* package */ void showDataRoamingNotification(int subId, boolean roamingOn) { | 
 | 577 |         if (DBG) { | 
 | 578 |             log("showDataRoamingNotification() roaming " + (roamingOn ? "on" : "off") | 
 | 579 |                     + " on subId " + subId); | 
 | 580 |         } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 581 |  | 
 | 582 |         // "Mobile network settings" screen / dialog | 
| Nazanin Bakhshi | 682c77d | 2019-05-02 17:22:27 -0700 | [diff] [blame] | 583 |         Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS); | 
| Jeff Davidson | 6d9bf52 | 2017-11-03 14:51:13 -0700 | [diff] [blame] | 584 |         intent.putExtra(Settings.EXTRA_SUB_ID, subId); | 
| Pengquan Meng | 8783d93 | 2017-10-16 14:57:40 -0700 | [diff] [blame] | 585 |         PendingIntent contentIntent = PendingIntent.getActivity(mContext, subId, intent, 0); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 586 |  | 
| Jordan Liu | ff2ccd7 | 2019-07-23 15:54:41 -0700 | [diff] [blame] | 587 |         CharSequence contentTitle = mContext.getText(roamingOn | 
 | 588 |                 ? R.string.roaming_on_notification_title | 
 | 589 |                 : R.string.roaming_notification_title); | 
 | 590 |         CharSequence contentText = mContext.getText(roamingOn | 
 | 591 |                 ? R.string.roaming_enabled_message | 
 | 592 |                 : R.string.roaming_reenable_message); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 593 |  | 
| fionaxu | 8b7620d | 2017-05-01 16:22:17 -0700 | [diff] [blame] | 594 |         final Notification.Builder builder = new Notification.Builder(mContext) | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 595 |                 .setSmallIcon(android.R.drawable.stat_sys_warning) | 
| Jordan Liu | ff2ccd7 | 2019-07-23 15:54:41 -0700 | [diff] [blame] | 596 |                 .setContentTitle(contentTitle) | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 597 |                 .setColor(mContext.getResources().getColor(R.color.dialer_theme_color)) | 
| fionaxu | 75b66a7 | 2017-04-19 19:01:56 -0700 | [diff] [blame] | 598 |                 .setContentText(contentText) | 
| Jordan Liu | 575c0d0 | 2019-07-09 16:29:48 -0700 | [diff] [blame] | 599 |                 .setChannelId(NotificationChannelController.CHANNEL_ID_MOBILE_DATA_STATUS) | 
| fionaxu | 96ceebd | 2017-08-24 12:12:32 -0700 | [diff] [blame] | 600 |                 .setContentIntent(contentIntent); | 
 | 601 |         final Notification notif = | 
 | 602 |                 new Notification.BigTextStyle(builder).bigText(contentText).build(); | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 603 |         mNotificationManager.notifyAsUser( | 
 | 604 |                 null /* tag */, DATA_ROAMING_NOTIFICATION, notif, UserHandle.ALL); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 605 |     } | 
 | 606 |  | 
 | 607 |     /** | 
| Jordan Liu | ff2ccd7 | 2019-07-23 15:54:41 -0700 | [diff] [blame] | 608 |      * Turns off the "data disconnected due to roaming" or "Data roaming is on" notification. | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 609 |      */ | 
| Jordan Liu | ff2ccd7 | 2019-07-23 15:54:41 -0700 | [diff] [blame] | 610 |     /* package */ void hideDataRoamingNotification() { | 
 | 611 |         if (DBG) log("hideDataRoamingNotification()..."); | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 612 |         mNotificationManager.cancel(DATA_ROAMING_NOTIFICATION); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 613 |     } | 
 | 614 |  | 
 | 615 |     /** | 
 | 616 |      * Display the network selection "no service" notification | 
 | 617 |      * @param operator is the numeric operator number | 
| Jayachandran C | 2ef9a48 | 2017-05-12 22:07:47 -0700 | [diff] [blame] | 618 |      * @param subId is the subscription ID | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 619 |      */ | 
| Jayachandran C | 2ef9a48 | 2017-05-12 22:07:47 -0700 | [diff] [blame] | 620 |     private void showNetworkSelection(String operator, int subId) { | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 621 |         if (DBG) log("showNetworkSelection(" + operator + ")..."); | 
 | 622 |  | 
| Youming Ye | 0509b53 | 2018-09-14 16:21:17 -0700 | [diff] [blame] | 623 |         if (!TextUtils.isEmpty(operator)) { | 
 | 624 |             operator = String.format(" (%s)", operator); | 
 | 625 |         } | 
| fionaxu | 8b7620d | 2017-05-01 16:22:17 -0700 | [diff] [blame] | 626 |         Notification.Builder builder = new Notification.Builder(mContext) | 
| Andrew Lee | 99d0ac2 | 2014-10-10 13:18:04 -0700 | [diff] [blame] | 627 |                 .setSmallIcon(android.R.drawable.stat_sys_warning) | 
 | 628 |                 .setContentTitle(mContext.getString(R.string.notification_network_selection_title)) | 
 | 629 |                 .setContentText( | 
 | 630 |                         mContext.getString(R.string.notification_network_selection_text, operator)) | 
 | 631 |                 .setShowWhen(false) | 
| fionaxu | 75b66a7 | 2017-04-19 19:01:56 -0700 | [diff] [blame] | 632 |                 .setOngoing(true) | 
| Jordan Liu | 575c0d0 | 2019-07-09 16:29:48 -0700 | [diff] [blame] | 633 |                 .setChannelId(NotificationChannelController.CHANNEL_ID_ALERT); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 634 |  | 
 | 635 |         // create the target network operators settings intent | 
 | 636 |         Intent intent = new Intent(Intent.ACTION_MAIN); | 
 | 637 |         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | | 
 | 638 |                 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); | 
| Malcolm Chen | 34d4fa5 | 2017-06-05 19:02:16 -0700 | [diff] [blame] | 639 |         // Use MobileNetworkSettings to handle the selection intent | 
| Wei Liu | be96458 | 2015-08-21 11:57:00 -0700 | [diff] [blame] | 640 |         intent.setComponent(new ComponentName( | 
| Malcolm Chen | 34d4fa5 | 2017-06-05 19:02:16 -0700 | [diff] [blame] | 641 |                 mContext.getString(R.string.mobile_network_settings_package), | 
 | 642 |                 mContext.getString(R.string.mobile_network_settings_class))); | 
| Jayachandran C | 2ef9a48 | 2017-05-12 22:07:47 -0700 | [diff] [blame] | 643 |         intent.putExtra(GsmUmtsOptions.EXTRA_SUB_ID, subId); | 
| fionaxu | 96ceebd | 2017-08-24 12:12:32 -0700 | [diff] [blame] | 644 |         builder.setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0)); | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 645 |         mNotificationManager.notifyAsUser( | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 646 |                 Integer.toString(subId) /* tag */, | 
| fionaxu | 96ceebd | 2017-08-24 12:12:32 -0700 | [diff] [blame] | 647 |                 SELECTED_OPERATOR_FAIL_NOTIFICATION, | 
 | 648 |                 builder.build(), | 
 | 649 |                 UserHandle.ALL); | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 650 |         mSelectedUnavailableNotify.put(subId, true); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 651 |     } | 
 | 652 |  | 
 | 653 |     /** | 
 | 654 |      * Turn off the network selection "no service" notification | 
 | 655 |      */ | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 656 |     private void cancelNetworkSelection(int subId) { | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 657 |         if (DBG) log("cancelNetworkSelection()..."); | 
| Jordan Liu | 3ccf59c | 2019-08-07 07:10:27 +0000 | [diff] [blame] | 658 |         mNotificationManager.cancelAsUser( | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 659 |                 Integer.toString(subId) /* tag */, SELECTED_OPERATOR_FAIL_NOTIFICATION, | 
 | 660 |                 UserHandle.ALL); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 661 |     } | 
 | 662 |  | 
 | 663 |     /** | 
 | 664 |      * Update notification about no service of user selected operator | 
 | 665 |      * | 
 | 666 |      * @param serviceState Phone service state | 
| Jayachandran C | 2ef9a48 | 2017-05-12 22:07:47 -0700 | [diff] [blame] | 667 |      * @param subId The subscription ID | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 668 |      */ | 
| Jayachandran C | 2ef9a48 | 2017-05-12 22:07:47 -0700 | [diff] [blame] | 669 |     void updateNetworkSelection(int serviceState, int subId) { | 
 | 670 |         int phoneId = SubscriptionManager.getPhoneId(subId); | 
 | 671 |         Phone phone = SubscriptionManager.isValidPhoneId(phoneId) ? | 
 | 672 |                 PhoneFactory.getPhone(phoneId) : PhoneFactory.getDefaultPhone(); | 
 | 673 |         if (TelephonyCapabilities.supportsNetworkSelection(phone)) { | 
| Amit Mahajan | a60be87 | 2015-01-15 16:05:08 -0800 | [diff] [blame] | 674 |             if (SubscriptionManager.isValidSubscriptionId(subId)) { | 
| fionaxu | 996a1c3 | 2018-04-13 15:00:37 -0700 | [diff] [blame] | 675 |                 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); | 
 | 676 |                 String selectedNetworkOperatorName = | 
 | 677 |                         sp.getString(Phone.NETWORK_SELECTION_NAME_KEY + subId, ""); | 
 | 678 |                 // get the shared preference of network_selection. | 
 | 679 |                 // empty is auto mode, otherwise it is the operator alpha name | 
 | 680 |                 // in case there is no operator name, check the operator numeric | 
 | 681 |                 if (TextUtils.isEmpty(selectedNetworkOperatorName)) { | 
 | 682 |                     selectedNetworkOperatorName = | 
 | 683 |                             sp.getString(Phone.NETWORK_SELECTION_KEY + subId, ""); | 
 | 684 |                 } | 
 | 685 |                 boolean isManualSelection; | 
| fionaxu | d6aac66 | 2018-03-14 16:44:29 -0700 | [diff] [blame] | 686 |                 // if restoring manual selection is controlled by framework, then get network | 
 | 687 |                 // selection from shared preference, otherwise get from real network indicators. | 
 | 688 |                 boolean restoreSelection = !mContext.getResources().getBoolean( | 
 | 689 |                         com.android.internal.R.bool.skip_restoring_network_selection); | 
| fionaxu | d6aac66 | 2018-03-14 16:44:29 -0700 | [diff] [blame] | 690 |                 if (restoreSelection) { | 
| fionaxu | d6aac66 | 2018-03-14 16:44:29 -0700 | [diff] [blame] | 691 |                     isManualSelection = !TextUtils.isEmpty(selectedNetworkOperatorName); | 
 | 692 |                 } else { | 
| fionaxu | d6aac66 | 2018-03-14 16:44:29 -0700 | [diff] [blame] | 693 |                     isManualSelection = phone.getServiceStateTracker().mSS.getIsManualSelection(); | 
| Amit Mahajan | a60be87 | 2015-01-15 16:05:08 -0800 | [diff] [blame] | 694 |                 } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 695 |  | 
| fionaxu | d6aac66 | 2018-03-14 16:44:29 -0700 | [diff] [blame] | 696 |                 if (DBG) { | 
 | 697 |                     log("updateNetworkSelection()..." + "state = " + serviceState + " new network " | 
 | 698 |                             + (isManualSelection ? selectedNetworkOperatorName : "")); | 
 | 699 |                 } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 700 |  | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 701 |                 if (isManualSelection) { | 
 | 702 |                     mSelectedNetworkOperatorName.put(subId, selectedNetworkOperatorName); | 
 | 703 |                     shouldShowNotification(serviceState, subId); | 
| Amit Mahajan | a60be87 | 2015-01-15 16:05:08 -0800 | [diff] [blame] | 704 |                 } else { | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 705 |                     dismissNetworkSelectionNotification(subId); | 
 | 706 |                     clearUpNetworkSelectionNotificationParam(subId); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 707 |                 } | 
 | 708 |             } else { | 
| Amit Mahajan | a60be87 | 2015-01-15 16:05:08 -0800 | [diff] [blame] | 709 |                 if (DBG) log("updateNetworkSelection()..." + "state = " + | 
 | 710 |                         serviceState + " not updating network due to invalid subId " + subId); | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 711 |                 dismissNetworkSelectionNotificationForInactiveSubId(); | 
 | 712 |             } | 
 | 713 |         } | 
 | 714 |     } | 
 | 715 |  | 
 | 716 |     private void dismissNetworkSelectionNotification(int subId) { | 
 | 717 |         if (mSelectedUnavailableNotify.get(subId, false)) { | 
 | 718 |             cancelNetworkSelection(subId); | 
 | 719 |             mSelectedUnavailableNotify.remove(subId); | 
 | 720 |         } | 
 | 721 |     } | 
 | 722 |  | 
 | 723 |     private void dismissNetworkSelectionNotificationForInactiveSubId() { | 
 | 724 |         for (int i = 0; i < mSelectedUnavailableNotify.size(); i++) { | 
 | 725 |             int subId = mSelectedUnavailableNotify.keyAt(i); | 
 | 726 |             if (!mSubscriptionManager.isActiveSubId(subId)) { | 
 | 727 |                 dismissNetworkSelectionNotification(subId); | 
 | 728 |                 clearUpNetworkSelectionNotificationParam(subId); | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 729 |             } | 
 | 730 |         } | 
 | 731 |     } | 
 | 732 |  | 
 | 733 |     /* package */ void postTransientNotification(int notifyId, CharSequence msg) { | 
 | 734 |         if (mToast != null) { | 
 | 735 |             mToast.cancel(); | 
 | 736 |         } | 
 | 737 |  | 
 | 738 |         mToast = Toast.makeText(mContext, msg, Toast.LENGTH_LONG); | 
 | 739 |         mToast.show(); | 
 | 740 |     } | 
 | 741 |  | 
 | 742 |     private void log(String msg) { | 
 | 743 |         Log.d(LOG_TAG, msg); | 
 | 744 |     } | 
| Tyler Gunn | a584e2c | 2017-09-19 11:40:12 -0700 | [diff] [blame] | 745 |  | 
 | 746 |     private void logi(String msg) { | 
 | 747 |         Log.i(LOG_TAG, msg); | 
 | 748 |     } | 
| irisykyang | 2520246 | 2018-11-13 14:49:54 +0800 | [diff] [blame] | 749 |  | 
 | 750 |     /** | 
 | 751 |      * In case network selection notification shows up repeatedly under | 
 | 752 |      * unstable network condition. The logic is to check whether or not | 
 | 753 |      * the service state keeps in no service condition for at least | 
 | 754 |      * {@link #NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIME_IN_MS}. | 
 | 755 |      * And checking {@link #NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIMES} times. | 
 | 756 |      * To avoid the notification showing up for the momentary state. | 
 | 757 |      */ | 
 | 758 |     private void shouldShowNotification(int serviceState, int subId) { | 
 | 759 |         if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) { | 
 | 760 |             if (mPreviousServiceState.get(subId, STATE_UNKNOWN_SERVICE) | 
 | 761 |                     != ServiceState.STATE_OUT_OF_SERVICE) { | 
 | 762 |                 mOOSTimestamp.put(subId, getTimeStamp()); | 
 | 763 |             } | 
 | 764 |             if ((getTimeStamp() - mOOSTimestamp.get(subId, 0L) | 
 | 765 |                     >= NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIME_IN_MS) | 
 | 766 |                     || mPendingEventCounter.get(subId, 0) | 
 | 767 |                     > NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIMES) { | 
 | 768 |                 showNetworkSelection(mSelectedNetworkOperatorName.get(subId), subId); | 
 | 769 |                 clearUpNetworkSelectionNotificationParam(subId); | 
 | 770 |             } else { | 
 | 771 |                 startPendingNetworkSelectionNotification(subId); | 
 | 772 |             } | 
 | 773 |         } else { | 
 | 774 |             dismissNetworkSelectionNotification(subId); | 
 | 775 |         } | 
 | 776 |         mPreviousServiceState.put(subId, serviceState); | 
 | 777 |         if (DBG) { | 
 | 778 |             log("shouldShowNotification()..." + " subId = " + subId | 
 | 779 |                     + " serviceState = " + serviceState | 
 | 780 |                     + " mOOSTimestamp = " + mOOSTimestamp | 
 | 781 |                     + " mPendingEventCounter = " + mPendingEventCounter); | 
 | 782 |         } | 
 | 783 |     } | 
 | 784 |  | 
 | 785 |     private void startPendingNetworkSelectionNotification(int subId) { | 
 | 786 |         if (!mHandler.hasMessages(EVENT_PENDING_NETWORK_SELECTION_NOTIFICATION, subId)) { | 
 | 787 |             if (DBG) { | 
 | 788 |                 log("startPendingNetworkSelectionNotification: subId = " + subId); | 
 | 789 |             } | 
 | 790 |             mHandler.sendMessageDelayed( | 
 | 791 |                     mHandler.obtainMessage(EVENT_PENDING_NETWORK_SELECTION_NOTIFICATION, subId), | 
 | 792 |                     NETWORK_SELECTION_NOTIFICATION_MAX_PENDING_TIME_IN_MS); | 
 | 793 |             mPendingEventCounter.put(subId, mPendingEventCounter.get(subId, 0) + 1); | 
 | 794 |         } | 
 | 795 |     } | 
 | 796 |  | 
 | 797 |     private void clearUpNetworkSelectionNotificationParam(int subId) { | 
 | 798 |         if (mHandler.hasMessages(EVENT_PENDING_NETWORK_SELECTION_NOTIFICATION, subId)) { | 
 | 799 |             mHandler.removeMessages(EVENT_PENDING_NETWORK_SELECTION_NOTIFICATION, subId); | 
 | 800 |         } | 
 | 801 |         mPreviousServiceState.remove(subId); | 
 | 802 |         mOOSTimestamp.remove(subId); | 
 | 803 |         mPendingEventCounter.remove(subId); | 
 | 804 |         mSelectedNetworkOperatorName.remove(subId); | 
 | 805 |     } | 
 | 806 |  | 
 | 807 |     private static long getTimeStamp() { | 
 | 808 |         return SystemClock.elapsedRealtime(); | 
 | 809 |     } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 810 | } |