1 /* 2 * Copyright (C) 2021 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.telephony.qns; 18 19 import android.content.Context; 20 import android.net.NetworkCapabilities; 21 import android.os.Handler; 22 import android.os.HandlerThread; 23 import android.os.Looper; 24 import android.os.Message; 25 import android.telephony.AccessNetworkConstants; 26 import android.telephony.AccessNetworkConstants.AccessNetworkType; 27 import android.telephony.TelephonyManager; 28 import android.telephony.data.ApnSetting; 29 import android.telephony.ims.ImsReasonInfo; 30 import android.telephony.ims.ProvisioningManager; 31 import android.util.Log; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.android.telephony.qns.AccessNetworkSelectionPolicy.GuardingPreCondition; 35 import com.android.telephony.qns.AccessNetworkSelectionPolicy.PreCondition; 36 import com.android.telephony.qns.IwlanNetworkStatusTracker.IwlanAvailabilityInfo; 37 import com.android.telephony.qns.QualifiedNetworksServiceImpl.QualifiedNetworksInfo; 38 39 import java.io.PrintWriter; 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.HashMap; 43 import java.util.LinkedHashSet; 44 import java.util.List; 45 import java.util.Map; 46 import java.util.Map.Entry; 47 import java.util.concurrent.Executor; 48 49 /** 50 * AccessNetworkEvaluator evaluates prioritized AccessNetwork list base on Cellular/Wi-Fi network 51 * status and configurations from carrier/user. 52 */ 53 class AccessNetworkEvaluator { 54 private static final boolean DBG = true; 55 private static final int EVENT_BASE = 10000; 56 private static final int EVENT_IWLAN_NETWORK_STATUS_CHANGED = EVENT_BASE; 57 private static final int EVENT_QNS_TELEPHONY_INFO_CHANGED = EVENT_BASE + 1; 58 private static final int EVENT_RESTRICT_INFO_CHANGED = EVENT_BASE + 4; 59 private static final int EVENT_SET_CALL_TYPE = EVENT_BASE + 5; 60 private static final int EVENT_DATA_CONNECTION_STATE_CHANGED = EVENT_BASE + 6; 61 private static final int EVENT_PROVISIONING_INFO_CHANGED = EVENT_BASE + 8; 62 private static final int EVENT_IMS_REGISTRATION_STATE_CHANGED = EVENT_BASE + 10; 63 private static final int EVENT_WIFI_RTT_STATUS_CHANGED = EVENT_BASE + 11; 64 private static final int EVENT_SIP_DIALOG_SESSION_STATE_CHANGED = EVENT_BASE + 12; 65 private static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = EVENT_BASE + 13; 66 private static final int EVALUATE_SPECIFIC_REASON_NONE = 0; 67 private static final int EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE = 1; 68 private static final int EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED = 2; 69 private static final int EVALUATE_SPECIFIC_REASON_DATA_FAILED = 3; 70 private static final int EVALUATE_SPECIFIC_REASON_DATA_CONNECTED = 4; 71 72 protected final int mSlotIndex; 73 protected final Context mContext; 74 private final String mLogTag; 75 private final int mNetCapability; 76 @VisibleForTesting 77 protected final Handler mHandler; 78 private final HandlerThread mHandlerThread; 79 private final RestrictManager mRestrictManager; 80 protected QnsCarrierConfigManager mConfigManager; 81 protected QnsComponents mQnsComponents; 82 protected QualityMonitor mWifiQualityMonitor; 83 protected QualityMonitor mCellularQualityMonitor; 84 protected CellularNetworkStatusTracker mCellularNetworkStatusTracker; 85 protected IwlanNetworkStatusTracker mIwlanNetworkStatusTracker; 86 protected DataConnectionStatusTracker mDataConnectionStatusTracker; 87 protected QnsEventDispatcher mQnsEventDispatcher; 88 protected QnsCallStatusTracker mCallStatusTracker; 89 protected QnsProvisioningListener mQnsProvisioningListener; 90 protected QnsImsManager mQnsImsManager; 91 protected WifiBackhaulMonitor mWifiBackhaulMonitor; 92 protected QnsTelephonyListener mQnsTelephonyListener; 93 // for metric 94 protected QnsMetrics mQnsMetrics; 95 96 protected int mCellularAccessNetworkType = AccessNetworkType.UNKNOWN; 97 protected boolean mCellularAvailable = false; 98 protected boolean mIwlanAvailable = false; 99 private boolean mIsCrossWfc = false; 100 101 protected QnsRegistrantList mQualifiedNetworksChangedRegistrants = new QnsRegistrantList(); 102 // pre-conditions 103 private int mCallType; 104 private int mCoverage; 105 private int mLatestAvailableCellularAccessNetwork = AccessNetworkType.UNKNOWN; 106 private List<AccessNetworkSelectionPolicy> mAccessNetworkSelectionPolicies = new ArrayList<>(); 107 private List<Integer> mLastQualifiedAccessNetworkTypes; 108 private boolean mIsNotifiedLastQualifiedAccessNetworkTypes = false; 109 private boolean mWfcPlatformEnabled = false; 110 private boolean mSettingWfcEnabled = false; 111 private int mSettingWfcMode = QnsConstants.CELL_PREF; 112 private boolean mSettingWfcRoamingEnabled = false; 113 private int mSettingWfcRoamingMode = QnsConstants.WIFI_PREF; 114 private boolean mAllowIwlanForWfcActivation = false; 115 private Map<PreCondition, List<AccessNetworkSelectionPolicy>> mAnspPolicyMap = null; 116 private ThresholdListener mThresholdListener; 117 private boolean mInitialized = false; 118 private boolean mIsRttCheckSuccess = false; 119 private QnsProvisioningListener.QnsProvisioningInfo mLastProvisioningInfo = 120 new QnsProvisioningListener.QnsProvisioningInfo(); 121 private boolean mSipDialogSessionState = false; 122 private int mCachedTransportTypeForEmergencyInitialConnect = 123 AccessNetworkConstants.TRANSPORT_TYPE_INVALID; 124 private int mLastEvaluateSpecificReason = EVALUATE_SPECIFIC_REASON_NONE; 125 AccessNetworkEvaluator(QnsComponents qnsComponents, int netCapability, int slotIndex)126 AccessNetworkEvaluator(QnsComponents qnsComponents, int netCapability, int slotIndex) { 127 mNetCapability = netCapability; 128 mQnsComponents = qnsComponents; 129 mSlotIndex = slotIndex; 130 mContext = mQnsComponents.getContext(); 131 mLogTag = 132 QnsConstants.QNS_TAG 133 + "_" 134 + AccessNetworkEvaluator.class.getSimpleName() 135 + "_" 136 + mSlotIndex 137 + "_" 138 + QnsUtils.getNameOfNetCapability(netCapability); 139 // load configurations & sort by purpose. 140 141 log("created AccessNetworkEvaluator"); 142 143 // make handler to handle events for evaluate available AccessNetworks. 144 mHandlerThread = 145 new HandlerThread(AccessNetworkEvaluator.class.getSimpleName() + mNetCapability); 146 mHandlerThread.start(); 147 mHandler = new EvaluatorEventHandler(mHandlerThread.getLooper()); 148 Executor executor = new QnsUtils.QnsExecutor(mHandler); 149 150 mConfigManager = mQnsComponents.getQnsCarrierConfigManager(mSlotIndex); 151 mCallStatusTracker = mQnsComponents.getQnsCallStatusTracker(mSlotIndex); 152 mQnsProvisioningListener = mQnsComponents.getQnsProvisioningListener(mSlotIndex); 153 mIwlanNetworkStatusTracker = mQnsComponents.getIwlanNetworkStatusTracker(); 154 mDataConnectionStatusTracker = 155 new DataConnectionStatusTracker( 156 mQnsComponents.getQnsTelephonyListener(mSlotIndex), 157 mHandlerThread.getLooper(), 158 mSlotIndex, 159 mNetCapability); 160 mQnsImsManager = mQnsComponents.getQnsImsManager(mSlotIndex); 161 mWifiBackhaulMonitor = mQnsComponents.getWifiBackhaulMonitor(mSlotIndex); 162 mQnsTelephonyListener = mQnsComponents.getQnsTelephonyListener(mSlotIndex); 163 mQnsMetrics = mQnsComponents.getQnsMetrics(); 164 165 // Pre-Conditions 166 mCellularNetworkStatusTracker = mQnsComponents.getCellularNetworkStatusTracker(mSlotIndex); 167 mQnsEventDispatcher = mQnsComponents.getQnsEventDispatcher(mSlotIndex); 168 mThresholdListener = new ThresholdListener(executor); 169 170 // Post-Conditions 171 mWifiQualityMonitor = mQnsComponents.getWifiQualityMonitor(); 172 mCellularQualityMonitor = mQnsComponents.getCellularQualityMonitor(mSlotIndex); 173 174 // Evaluates 175 mRestrictManager = 176 new RestrictManager( 177 mQnsComponents, 178 mHandler.getLooper(), 179 mNetCapability, 180 mDataConnectionStatusTracker, 181 mSlotIndex); 182 183 mHandler.post(() -> buildAccessNetworkSelectionPolicy(false)); 184 initLastNotifiedQualifiedNetwork(); 185 initSettings(); 186 registerListeners(); 187 } 188 189 @VisibleForTesting AccessNetworkEvaluator( QnsComponents qnsComponents, int netCapability, RestrictManager restrictManager, DataConnectionStatusTracker dataConnectionStatusTracker, int slotIndex)190 AccessNetworkEvaluator( 191 QnsComponents qnsComponents, 192 int netCapability, 193 RestrictManager restrictManager, 194 DataConnectionStatusTracker dataConnectionStatusTracker, 195 int slotIndex) { 196 mQnsComponents = qnsComponents; 197 mSlotIndex = slotIndex; 198 mLogTag = 199 QnsConstants.QNS_TAG 200 + "_" 201 + AccessNetworkEvaluator.class.getSimpleName() 202 + "_" 203 + mSlotIndex 204 + "_" 205 + QnsUtils.getNameOfNetCapability(netCapability); 206 // load configurations & sort by purpose. 207 mNetCapability = netCapability; 208 mContext = mQnsComponents.getContext(); 209 mRestrictManager = restrictManager; 210 mConfigManager = mQnsComponents.getQnsCarrierConfigManager(mSlotIndex); 211 mWifiQualityMonitor = mQnsComponents.getWifiQualityMonitor(); 212 mCellularQualityMonitor = mQnsComponents.getCellularQualityMonitor(mSlotIndex); 213 mCellularNetworkStatusTracker = mQnsComponents.getCellularNetworkStatusTracker(mSlotIndex); 214 mIwlanNetworkStatusTracker = mQnsComponents.getIwlanNetworkStatusTracker(); 215 mDataConnectionStatusTracker = dataConnectionStatusTracker; 216 mQnsEventDispatcher = mQnsComponents.getQnsEventDispatcher(mSlotIndex); 217 mCallStatusTracker = mQnsComponents.getQnsCallStatusTracker(mSlotIndex); 218 mQnsProvisioningListener = mQnsComponents.getQnsProvisioningListener(mSlotIndex); 219 mQnsImsManager = mQnsComponents.getQnsImsManager(mSlotIndex); 220 mWifiBackhaulMonitor = mQnsComponents.getWifiBackhaulMonitor(mSlotIndex); 221 mQnsTelephonyListener = mQnsComponents.getQnsTelephonyListener(mSlotIndex); 222 mQnsMetrics = mQnsComponents.getQnsMetrics(); 223 mHandlerThread = 224 new HandlerThread(AccessNetworkEvaluator.class.getSimpleName() + mNetCapability); 225 mHandlerThread.start(); 226 mHandler = new EvaluatorEventHandler(mHandlerThread.getLooper()); 227 mHandler.post(() -> buildAccessNetworkSelectionPolicy(false)); 228 initLastNotifiedQualifiedNetwork(); 229 initSettings(); 230 registerListeners(); 231 } 232 rebuild()233 void rebuild() { 234 log("rebuild"); 235 initSettings(); 236 mLastProvisioningInfo.clear(); 237 mConfigManager.setQnsProvisioningInfo(mLastProvisioningInfo); 238 mHandler.post(() -> buildAccessNetworkSelectionPolicy(true)); 239 mRestrictManager.clearRestrictions(); 240 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) { 241 if (mWifiBackhaulMonitor.isRttCheckEnabled()) { 242 mWifiBackhaulMonitor.registerForRttStatusChange( 243 mHandler, EVENT_WIFI_RTT_STATUS_CHANGED); 244 } else { 245 mWifiBackhaulMonitor.clearAll(); 246 } 247 } 248 reportQualifiedNetwork(getInitialAccessNetworkTypes()); 249 initLastNotifiedQualifiedNetwork(); 250 unregisterThresholdToQualityMonitor(); 251 252 if (isAllowed(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) 253 && evaluateAvailability( 254 AccessNetworkConstants.TRANSPORT_TYPE_WLAN, 255 isAllowed(AccessNetworkConstants.TRANSPORT_TYPE_WWAN))) { 256 mHandler.post(this::evaluate); 257 } 258 mLastEvaluateSpecificReason = EVALUATE_SPECIFIC_REASON_NONE; 259 } 260 close()261 void close() { 262 log("close"); 263 mHandler.post(this::onClose); 264 mHandlerThread.quitSafely(); 265 } 266 onClose()267 private void onClose() { 268 notifyForQualifiedNetworksChanged(getInitialAccessNetworkTypes()); 269 initLastNotifiedQualifiedNetwork(); 270 unregisterListeners(); 271 mQualifiedNetworksChangedRegistrants.removeAll(); 272 mDataConnectionStatusTracker.close(); 273 mRestrictManager.close(); 274 } 275 registerForQualifiedNetworksChanged(Handler h, int what)276 void registerForQualifiedNetworksChanged(Handler h, int what) { 277 mInitialized = true; 278 mQualifiedNetworksChangedRegistrants.addUnique(h, what, null); 279 if (isNotifiedQualifiedAccessNetworkTypes()) { 280 if (DBG) { 281 log( 282 "registerForQualifiedNetworksChanged, report:" 283 + QnsUtils.getStringAccessNetworkTypes( 284 mLastQualifiedAccessNetworkTypes)); 285 } 286 notifyForQualifiedNetworksChanged(mLastQualifiedAccessNetworkTypes); 287 } 288 mHandler.post(this::evaluate); 289 } 290 unregisterForQualifiedNetworksChanged(Handler h)291 void unregisterForQualifiedNetworksChanged(Handler h) { 292 mQualifiedNetworksChangedRegistrants.remove(h); 293 } 294 getInitialAccessNetworkTypes()295 private List<Integer> getInitialAccessNetworkTypes() { 296 // The framework treats empty lists as WWAN. 297 return List.of(); 298 } 299 getLastQualifiedTransportType()300 protected int getLastQualifiedTransportType() { 301 if (mLastQualifiedAccessNetworkTypes.size() > 0 302 && mLastQualifiedAccessNetworkTypes.get(0) == AccessNetworkType.IWLAN) { 303 return AccessNetworkConstants.TRANSPORT_TYPE_WLAN; 304 } 305 // otherwise, returns WWAN. (includes an empty list) 306 return AccessNetworkConstants.TRANSPORT_TYPE_WWAN; 307 } 308 isNotifiedQualifiedAccessNetworkTypes()309 protected boolean isNotifiedQualifiedAccessNetworkTypes() { 310 return mIsNotifiedLastQualifiedAccessNetworkTypes; 311 } 312 initLastNotifiedQualifiedNetwork()313 protected void initLastNotifiedQualifiedNetwork() { 314 mIsNotifiedLastQualifiedAccessNetworkTypes = false; 315 mLastQualifiedAccessNetworkTypes = getInitialAccessNetworkTypes(); 316 log( 317 "initLastNotifiedQualifiedNetwork mLastQualifiedAccessNetworkTypes:" 318 + QnsUtils.getStringAccessNetworkTypes(mLastQualifiedAccessNetworkTypes)); 319 } 320 equalsLastNotifiedQualifiedNetwork(List<Integer> accessNetworkTypes)321 protected boolean equalsLastNotifiedQualifiedNetwork(List<Integer> accessNetworkTypes) { 322 return mLastQualifiedAccessNetworkTypes.equals(accessNetworkTypes); 323 } 324 updateLastNotifiedQualifiedNetwork(List<Integer> accessNetworkTypes)325 protected void updateLastNotifiedQualifiedNetwork(List<Integer> accessNetworkTypes) { 326 mLastQualifiedAccessNetworkTypes = accessNetworkTypes; 327 mRestrictManager.updateLastNotifiedTransportType(getLastQualifiedTransportType()); 328 log( 329 "updateLastNotifiedQualifiedNetwork mLastQualifiedAccessNetworkTypes:" 330 + QnsUtils.getStringAccessNetworkTypes(mLastQualifiedAccessNetworkTypes)); 331 } 332 notifyForQualifiedNetworksChanged(List<Integer> accessNetworkTypes)333 protected void notifyForQualifiedNetworksChanged(List<Integer> accessNetworkTypes) { 334 mIsNotifiedLastQualifiedAccessNetworkTypes = true; 335 QualifiedNetworksInfo info = new QualifiedNetworksInfo(mNetCapability, accessNetworkTypes); 336 QnsAsyncResult ar = new QnsAsyncResult(null, info, null); 337 mQualifiedNetworksChangedRegistrants.notifyRegistrants(ar); 338 339 // metrics 340 sendMetricsForQualifiedNetworks(info); 341 } 342 initSettings()343 private void initSettings() { 344 mWfcPlatformEnabled = QnsUtils.isWfcEnabledByPlatform(mQnsImsManager); 345 mSettingWfcEnabled = QnsUtils.isWfcEnabled(mQnsImsManager, mQnsProvisioningListener, false); 346 mSettingWfcMode = QnsUtils.getWfcMode(mQnsImsManager, false); 347 mSettingWfcRoamingEnabled = 348 QnsUtils.isWfcEnabled(mQnsImsManager, mQnsProvisioningListener, true); 349 mSettingWfcRoamingMode = QnsUtils.getWfcMode(mQnsImsManager, true); 350 mAllowIwlanForWfcActivation = false; 351 mSipDialogSessionState = false; 352 mCachedTransportTypeForEmergencyInitialConnect = 353 AccessNetworkConstants.TRANSPORT_TYPE_INVALID; 354 log( 355 "WfcSettings. mWfcPlatformEnabled:" 356 + mWfcPlatformEnabled 357 + " WfcEnabled:" 358 + mSettingWfcEnabled 359 + " WfcMode:" 360 + QnsConstants.preferenceToString(mSettingWfcMode) 361 + " WfcRoamingEnabled:" 362 + mSettingWfcRoamingEnabled 363 + " WfcRoamingMode:" 364 + QnsConstants.preferenceToString(mSettingWfcRoamingMode)); 365 } 366 registerListeners()367 protected void registerListeners() { 368 log("registerListeners"); 369 mWifiQualityMonitor.registerThresholdChange( 370 mThresholdListener, mNetCapability, null, mSlotIndex); 371 mCellularQualityMonitor.registerThresholdChange( 372 mThresholdListener, mNetCapability, null, mSlotIndex); 373 mIwlanNetworkStatusTracker.registerIwlanNetworksChanged( 374 mSlotIndex, mHandler, EVENT_IWLAN_NETWORK_STATUS_CHANGED); 375 mDataConnectionStatusTracker.registerDataConnectionStatusChanged( 376 mHandler, EVENT_DATA_CONNECTION_STATE_CHANGED); 377 mQnsImsManager.registerImsRegistrationStatusChanged( 378 mHandler, EVENT_IMS_REGISTRATION_STATE_CHANGED); 379 mQnsImsManager.registerSipDialogSessionStateChanged( 380 mHandler, EVENT_SIP_DIALOG_SESSION_STATE_CHANGED); 381 mCellularNetworkStatusTracker.registerQnsTelephonyInfoChanged( 382 mNetCapability, mHandler, EVENT_QNS_TELEPHONY_INFO_CHANGED); 383 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 384 || mNetCapability == NetworkCapabilities.NET_CAPABILITY_EIMS) { 385 mCallStatusTracker.registerCallTypeChangedListener( 386 mNetCapability, mHandler, EVENT_SET_CALL_TYPE, null); 387 } 388 389 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) { 390 if (mWifiBackhaulMonitor.isRttCheckEnabled()) { 391 mWifiBackhaulMonitor.registerForRttStatusChange( 392 mHandler, EVENT_WIFI_RTT_STATUS_CHANGED); 393 } 394 } 395 mQnsProvisioningListener.registerProvisioningItemInfoChanged( 396 mHandler, EVENT_PROVISIONING_INFO_CHANGED, null, true); 397 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) { 398 mQnsTelephonyListener.registerImsCallDropDisconnectCauseListener( 399 mHandler, EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED, null); 400 } 401 List<Integer> events = new ArrayList<>(); 402 events.add(QnsEventDispatcher.QNS_EVENT_WFC_ENABLED); 403 events.add(QnsEventDispatcher.QNS_EVENT_WFC_DISABLED); 404 events.add(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY); 405 events.add(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_CELLULAR_PREFERRED); 406 events.add(QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_PREFERRED); 407 events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED); 408 events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_DISABLED); 409 events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_ONLY); 410 events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_CELLULAR_PREFERRED); 411 events.add(QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_PREFERRED); 412 events.add(QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_ENABLED); 413 events.add(QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_DISABLED); 414 events.add(QnsEventDispatcher.QNS_EVENT_SIM_ABSENT); 415 events.add(QnsEventDispatcher.QNS_EVENT_TRY_WFC_ACTIVATION); 416 events.add(QnsEventDispatcher.QNS_EVENT_CANCEL_TRY_WFC_ACTIVATION); 417 mQnsEventDispatcher.registerEvent(events, mHandler); 418 mRestrictManager.registerRestrictInfoChanged(mHandler, EVENT_RESTRICT_INFO_CHANGED); 419 } 420 unregisterListeners()421 protected void unregisterListeners() { 422 log("unregisterListeners"); 423 mWifiQualityMonitor.unregisterThresholdChange(mNetCapability, mSlotIndex); 424 mCellularQualityMonitor.unregisterThresholdChange(mNetCapability, mSlotIndex); 425 mDataConnectionStatusTracker.unRegisterDataConnectionStatusChanged(mHandler); 426 mQnsImsManager.unregisterImsRegistrationStatusChanged(mHandler); 427 mQnsImsManager.unregisterSipDialogSessionStateChanged(mHandler); 428 mCellularNetworkStatusTracker.unregisterQnsTelephonyInfoChanged(mNetCapability, mHandler); 429 mIwlanNetworkStatusTracker.unregisterIwlanNetworksChanged(mSlotIndex, mHandler); 430 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 431 || mNetCapability == NetworkCapabilities.NET_CAPABILITY_EIMS) { 432 mCallStatusTracker.unregisterCallTypeChangedListener(mNetCapability, mHandler); 433 if (mWifiBackhaulMonitor.isRttCheckEnabled()) { 434 mWifiBackhaulMonitor.unRegisterForRttStatusChange(mHandler); 435 } 436 } 437 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) { 438 mQnsTelephonyListener.unregisterImsCallDropDisconnectCauseListener(mHandler); 439 } 440 mQnsProvisioningListener.unregisterProvisioningItemInfoChanged(mHandler); 441 mQnsEventDispatcher.unregisterEvent(mHandler); 442 mRestrictManager.unRegisterRestrictInfoChanged(mHandler); 443 } 444 isIwlanAvailableWithoutRestrict()445 private boolean isIwlanAvailableWithoutRestrict() { 446 return (mIwlanAvailable 447 && !mRestrictManager.isRestricted(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)); 448 } 449 isCellularAvailableWithoutRestrict()450 private boolean isCellularAvailableWithoutRestrict() { 451 return (mCellularAvailable 452 && !mRestrictManager.isRestricted(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)); 453 } 454 log(String s)455 protected void log(String s) { 456 Log.d(mLogTag, s); 457 } 458 onQnsTelephonyInfoChanged(QnsTelephonyListener.QnsTelephonyInfo info)459 protected void onQnsTelephonyInfoChanged(QnsTelephonyListener.QnsTelephonyInfo info) { 460 boolean needEvaluate = false; 461 462 if (info instanceof QnsTelephonyListener.QnsTelephonyInfoIms) { 463 QnsTelephonyListener.QnsTelephonyInfoIms infoIms = 464 (QnsTelephonyListener.QnsTelephonyInfoIms) info; 465 boolean checkVoPs = false; 466 boolean volteRoamingSupported = true; 467 int cellularAccessNetworkType = 468 QnsUtils.getCellularAccessNetworkType( 469 infoIms.getDataRegState(), infoIms.getDataNetworkType()); 470 471 int coverage = getCoverage(infoIms); 472 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 473 && infoIms.isCellularAvailable()) { 474 checkVoPs = vopsCheckRequired(cellularAccessNetworkType, coverage, mCallType); 475 volteRoamingSupported = mConfigManager.isVolteRoamingSupported(coverage); 476 } 477 boolean checkBarring = mConfigManager.isServiceBarringCheckSupported(); 478 if (DBG) { 479 log( 480 "checkVoPs:" 481 + checkVoPs 482 + ", checkBarring:" 483 + checkBarring 484 + ", volteRoamingSupported:" 485 + volteRoamingSupported); 486 } 487 boolean cellAvailable = 488 infoIms.isCellularAvailable( 489 mNetCapability, checkVoPs, checkBarring, volteRoamingSupported); 490 if (mCellularAvailable != cellAvailable) { 491 mCellularAvailable = cellAvailable; 492 needEvaluate = true; 493 log("onQnsTelephonyInfoChanged cellularAvailableIms:" + mCellularAvailable); 494 } 495 } else if (mCellularAvailable != info.isCellularAvailable()) { 496 mCellularAvailable = info.isCellularAvailable(); 497 needEvaluate = true; 498 log("onQnsTelephonyInfoChanged cellularAvailable:" + mCellularAvailable); 499 } 500 if (mCellularAccessNetworkType 501 != QnsUtils.getCellularAccessNetworkType( 502 info.getDataRegState(), info.getDataNetworkType())) { 503 mCellularAccessNetworkType = 504 QnsUtils.getCellularAccessNetworkType( 505 info.getDataRegState(), info.getDataNetworkType()); 506 mRestrictManager.setCellularAccessNetwork(mCellularAccessNetworkType); 507 if (mCellularAccessNetworkType != AccessNetworkType.UNKNOWN) { 508 mLatestAvailableCellularAccessNetwork = mCellularAccessNetworkType; 509 } 510 511 needEvaluate = true; 512 log( 513 "onQnsTelephonyInfoChanged cellularAccessNetworkType:" 514 + mCellularAccessNetworkType); 515 } 516 int coverage = getCoverage(info); 517 if (mCoverage != coverage) { 518 mCoverage = coverage; 519 needEvaluate = true; 520 mRestrictManager.setCellularCoverage(mCoverage); 521 log("onQnsTelephonyInfoChanged Coverage:" + mCoverage); 522 } 523 524 if (needEvaluate) { 525 evaluate(); 526 } 527 } 528 529 @VisibleForTesting getCoverage(QnsTelephonyListener.QnsTelephonyInfo info)530 int getCoverage(QnsTelephonyListener.QnsTelephonyInfo info) { 531 if (DBG) { 532 log("getCoverage roaming=" + info.isCoverage()); 533 } 534 if (info.isCoverage()) { 535 return QnsConstants.COVERAGE_ROAM; 536 } else { 537 return QnsConstants.COVERAGE_HOME; 538 } 539 } 540 onIwlanNetworkStatusChanged(IwlanAvailabilityInfo info)541 protected void onIwlanNetworkStatusChanged(IwlanAvailabilityInfo info) { 542 if (info != null) { 543 if (mIwlanAvailable != info.getIwlanAvailable()) { 544 mIwlanAvailable = info.getIwlanAvailable(); 545 } 546 mIsCrossWfc = info.isCrossWfc(); 547 log("onIwlanNetworkStatusChanged IwlanAvailable:" + mIwlanAvailable); 548 if (info.getNotifyIwlanDisabled()) { 549 evaluate(EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE); 550 } else { 551 evaluate(); 552 } 553 } 554 } 555 onWfcEnabledChanged(boolean enabled, boolean roaming)556 private void onWfcEnabledChanged(boolean enabled, boolean roaming) { 557 StringBuilder sb = new StringBuilder("onWfcEnabledChanged"); 558 sb.append(" enabled:").append(enabled); 559 sb.append(" coverage:") 560 .append( 561 QnsConstants.coverageToString( 562 roaming ? QnsConstants.COVERAGE_ROAM : QnsConstants.COVERAGE_HOME)); 563 564 boolean needEvaluate = false; 565 if (!roaming && mSettingWfcEnabled != enabled) { 566 if (mCoverage == QnsConstants.COVERAGE_HOME) { 567 needEvaluate = true; 568 } 569 mSettingWfcEnabled = enabled; 570 sb.append(" mSettingWfcEnabled:").append(mSettingWfcEnabled); 571 } else if (roaming && mSettingWfcRoamingEnabled != enabled) { 572 if (mCoverage == QnsConstants.COVERAGE_ROAM) { 573 needEvaluate = true; 574 } 575 mSettingWfcRoamingEnabled = enabled; 576 sb.append(" mSettingWfcRoamingEnabled:").append(mSettingWfcRoamingEnabled); 577 } 578 579 if (needEvaluate) { 580 sb.append(" evaluate."); 581 log(sb.toString()); 582 if (enabled) { 583 evaluate(); 584 } else { 585 evaluate(EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE); 586 } 587 } else { 588 log(sb.toString()); 589 } 590 } 591 onWfcModeChanged(int mode, boolean roaming)592 private void onWfcModeChanged(int mode, boolean roaming) { 593 StringBuilder sb = new StringBuilder("onWfcModeChanged"); 594 sb.append(" mode:").append(QnsConstants.preferenceToString(mode)); 595 sb.append(" coverage:") 596 .append( 597 QnsConstants.coverageToString( 598 roaming ? QnsConstants.COVERAGE_ROAM : QnsConstants.COVERAGE_HOME)); 599 600 boolean needEvaluate = false; 601 if (!roaming && mSettingWfcMode != mode) { 602 if (mCoverage == QnsConstants.COVERAGE_HOME) { 603 needEvaluate = true; 604 } 605 mSettingWfcMode = mode; 606 sb.append(" mSettingWfcMode:").append(QnsConstants.preferenceToString(mSettingWfcMode)); 607 } else if (roaming && mSettingWfcRoamingMode != mode) { 608 if (mCoverage == QnsConstants.COVERAGE_ROAM) { 609 needEvaluate = true; 610 } 611 mSettingWfcRoamingMode = mode; 612 sb.append(" mSettingWfcRoamingMode:"); 613 sb.append(QnsConstants.preferenceToString(mSettingWfcRoamingMode)); 614 } 615 616 if (needEvaluate) { 617 sb.append(" evaluate."); 618 log(sb.toString()); 619 evaluate(); 620 } else { 621 log(sb.toString()); 622 } 623 } 624 onWfcPlatformChanged(boolean bWfcPlatformEnabled)625 private void onWfcPlatformChanged(boolean bWfcPlatformEnabled) { 626 StringBuilder sb = new StringBuilder("onWfcPlatformChanged"); 627 sb.append(" bWfcPlatformEnabled:").append(bWfcPlatformEnabled); 628 if (mWfcPlatformEnabled == bWfcPlatformEnabled) { 629 sb.append(" no changes"); 630 log(sb.toString()); 631 } else { 632 mWfcPlatformEnabled = bWfcPlatformEnabled; 633 if (bWfcPlatformEnabled) { 634 sb.append(" evaluate."); 635 log(sb.toString()); 636 evaluate(); 637 } else { 638 sb.append(" report cellular as qualified network directly."); 639 log(sb.toString()); 640 reportQualifiedNetwork(new ArrayList<>(List.of(mCellularAccessNetworkType))); 641 } 642 } 643 } 644 onSimAbsent()645 private void onSimAbsent() { 646 log("onSimAbsent"); 647 648 // report default qualified access network. 649 reportQualifiedNetwork(getInitialAccessNetworkTypes()); 650 } 651 onRestrictInfoChanged()652 private void onRestrictInfoChanged() { 653 // TODO 654 log("onRestrictInfoChanged"); 655 evaluate(); 656 } 657 658 @VisibleForTesting onTryWfcConnectionStateChanged(boolean isEnabled)659 void onTryWfcConnectionStateChanged(boolean isEnabled) { 660 log("onTryWfcConnectionStateChanged enabled:" + isEnabled); 661 int timeout = mConfigManager.getVowifiRegistrationTimerForVowifiActivation(); 662 663 if (mAllowIwlanForWfcActivation == isEnabled) { 664 return; 665 } 666 if (isEnabled) { 667 mHandler.sendEmptyMessageDelayed( 668 QnsEventDispatcher.QNS_EVENT_CANCEL_TRY_WFC_ACTIVATION, 669 timeout + /* milliseconds */ 3000); 670 } else { 671 mHandler.removeMessages(QnsEventDispatcher.QNS_EVENT_CANCEL_TRY_WFC_ACTIVATION); 672 } 673 mAllowIwlanForWfcActivation = isEnabled; 674 evaluate(); 675 } 676 677 @VisibleForTesting onSetCallType(@nsConstants.QnsCallType int callType)678 void onSetCallType(@QnsConstants.QnsCallType int callType) { 679 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 680 && callType == QnsConstants.CALL_TYPE_EMERGENCY) { 681 if (!mDataConnectionStatusTracker.isActiveState()) return; 682 } 683 684 // metrics 685 sendMetricsForCallTypeChanged(mCallType, callType); 686 687 mCallType = callType; 688 mRestrictManager.setQnsCallType(mCallType); 689 log("onSetCallType CallType:" + mCallType); 690 691 // call type from service manager API 692 693 // TODO 694 evaluate(); 695 } 696 onEmergencyPreferredTransportTypeChanged( @ccessNetworkConstants.TransportType int transport)697 void onEmergencyPreferredTransportTypeChanged( 698 @AccessNetworkConstants.TransportType int transport) { 699 if (mNetCapability != NetworkCapabilities.NET_CAPABILITY_EIMS) { 700 return; 701 } 702 mHandler.post(() -> { 703 log( 704 "onEmergencyPreferredTransportTypeChanged transport:" 705 + QnsConstants.transportTypeToString(transport)); 706 if (mDataConnectionStatusTracker.isInactiveState() 707 || (mDataConnectionStatusTracker.isActiveState() 708 && mCallType == QnsConstants.CALL_TYPE_IDLE)) { 709 // If data network state is inactive OR active but call is not active yet, 710 // QNS will follow domain selection's decision. 711 enforceNotifyQualifiedNetworksWithTransportType(transport); 712 } else { 713 log( 714 "cache transportType for emergency: " 715 + QnsConstants.transportTypeToString(transport)); 716 mCachedTransportTypeForEmergencyInitialConnect = transport; 717 } 718 } 719 ); 720 } 721 enforceNotifyQualifiedNetworksWithTransportType( @ccessNetworkConstants.TransportType int transportType)722 private void enforceNotifyQualifiedNetworksWithTransportType( 723 @AccessNetworkConstants.TransportType int transportType) { 724 List<Integer> accessNetworkTypes = new ArrayList<>(); 725 if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 726 accessNetworkTypes.add(AccessNetworkType.IWLAN); 727 } else if (mCellularAccessNetworkType != AccessNetworkType.UNKNOWN) { 728 accessNetworkTypes.add(mCellularAccessNetworkType); 729 } 730 updateLastNotifiedQualifiedNetwork(accessNetworkTypes); 731 notifyForQualifiedNetworksChanged(accessNetworkTypes); 732 } 733 734 @VisibleForTesting onDataConnectionStateChanged( DataConnectionStatusTracker.DataConnectionChangedInfo info)735 void onDataConnectionStateChanged( 736 DataConnectionStatusTracker.DataConnectionChangedInfo info) { 737 log("onDataConnectionStateChanged info:" + info); 738 boolean needEvaluate = false; 739 int evaluateSpecificReason = EVALUATE_SPECIFIC_REASON_NONE; 740 switch (info.getEvent()) { 741 case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_DISCONNECTED: 742 evaluateSpecificReason = EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED; 743 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_EIMS) { 744 // If FWK guided emergency's transport type during data connected state, notify 745 // the transport type when the data connection is disconnected. 746 notifyCachedTransportTypeForEmergency(); 747 // When cellular is not available, CellularQualityMonitor will stop listening to 748 // TelephonyCallback. Thresholds for Emergency apn may not be reset as ANE for 749 // emergency only evaluates while data is connected. CellularQualityMonitor will 750 // not listen to TelephonyCallback again until the set of threshold values 751 // changed. Resetting thresholds for emergency after the emergency connection 752 // disconnects. 753 unregisterThresholdToQualityMonitor(); 754 } else { 755 needEvaluate = true; 756 initLastNotifiedQualifiedNetwork(); 757 } 758 break; 759 case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_CONNECTED: 760 evaluateSpecificReason = EVALUATE_SPECIFIC_REASON_DATA_CONNECTED; 761 mHandler.post(() -> onDataConnectionConnected(info.getTransportType())); 762 break; 763 case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_FAILED: 764 evaluateSpecificReason = EVALUATE_SPECIFIC_REASON_DATA_FAILED; 765 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_EIMS) { 766 // If FWK guided emergency's transport type during data connecting state, notify 767 // the transport type when the data connection is failed. 768 notifyCachedTransportTypeForEmergency(); 769 // When cellular is not available, CellularQualityMonitor will stop listening to 770 // TelephonyCallback. Thresholds for Emergency apn may not be reset as ANE for 771 // emergency only evaluates while data is connected. CellularQualityMonitor will 772 // not listen to TelephonyCallback again until the set of threshold values 773 // changed. Resetting thresholds for emergency after the emergency connection 774 // disconnects. 775 unregisterThresholdToQualityMonitor(); 776 } else { 777 needEvaluate = true; 778 } 779 break; 780 } 781 782 // metrics 783 sendMetricsForDataConnectionChanged(info); 784 785 if (needEvaluate) { 786 evaluate(evaluateSpecificReason); 787 } 788 } 789 notifyCachedTransportTypeForEmergency()790 private void notifyCachedTransportTypeForEmergency() { 791 if (mCachedTransportTypeForEmergencyInitialConnect 792 != AccessNetworkConstants.TRANSPORT_TYPE_INVALID) { 793 enforceNotifyQualifiedNetworksWithTransportType( 794 mCachedTransportTypeForEmergencyInitialConnect); 795 mCachedTransportTypeForEmergencyInitialConnect = 796 AccessNetworkConstants.TRANSPORT_TYPE_INVALID; 797 } 798 } 799 onDataConnectionConnected(int transportType)800 private void onDataConnectionConnected(int transportType) { 801 int otherTransportType; 802 if (DBG) { 803 log("onDataConnectionConnected :" + QnsConstants.transportTypeToString(transportType)); 804 } 805 if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) { 806 log("Error: onDataConnectionConnected invalid transport type."); 807 return; 808 } else { 809 otherTransportType = 810 transportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 811 ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN 812 : AccessNetworkConstants.TRANSPORT_TYPE_WLAN; 813 } 814 if (!mRestrictManager.isRestricted(otherTransportType)) { 815 evaluate(); 816 } // else case : evaluate() will process when restrictions released. 817 } 818 onProvisioningInfoChanged(QnsProvisioningListener.QnsProvisioningInfo info)819 protected void onProvisioningInfoChanged(QnsProvisioningListener.QnsProvisioningInfo info) { 820 boolean needBuildAnsp = false; 821 boolean needEvaluate = false; 822 823 log("onProvisioningInfoChanged info:" + info); 824 825 if (!info.equalsIntegerItem( 826 mLastProvisioningInfo, ProvisioningManager.KEY_LTE_THRESHOLD_1)) { 827 log( 828 "onProvisioningInfoChanged, KEY_LTE_THRESHOLD_1(" 829 + ProvisioningManager.KEY_LTE_THRESHOLD_1 830 + ") is provisioned to " 831 + info.getIntegerItem(ProvisioningManager.KEY_LTE_THRESHOLD_1)); 832 mConfigManager.setQnsProvisioningInfo(info); 833 needBuildAnsp = true; 834 needEvaluate = true; 835 } 836 if (!info.equalsIntegerItem( 837 mLastProvisioningInfo, ProvisioningManager.KEY_LTE_THRESHOLD_2)) { 838 log( 839 "onProvisioningInfoChanged, KEY_LTE_THRESHOLD_2(" 840 + ProvisioningManager.KEY_LTE_THRESHOLD_2 841 + ") is provisioned to " 842 + info.getIntegerItem(ProvisioningManager.KEY_LTE_THRESHOLD_2)); 843 mConfigManager.setQnsProvisioningInfo(info); 844 needBuildAnsp = true; 845 needEvaluate = true; 846 } 847 if (!info.equalsIntegerItem( 848 mLastProvisioningInfo, ProvisioningManager.KEY_LTE_THRESHOLD_3)) { 849 log( 850 "onProvisioningInfoChanged, KEY_LTE_THRESHOLD_3(" 851 + ProvisioningManager.KEY_LTE_THRESHOLD_3 852 + ") is provisioned to " 853 + info.getIntegerItem(ProvisioningManager.KEY_LTE_THRESHOLD_3)); 854 mConfigManager.setQnsProvisioningInfo(info); 855 needBuildAnsp = true; 856 needEvaluate = true; 857 } 858 if (!info.equalsIntegerItem( 859 mLastProvisioningInfo, ProvisioningManager.KEY_WIFI_THRESHOLD_A)) { 860 log( 861 "onProvisioningInfoChanged, KEY_WIFI_THRESHOLD_A(" 862 + ProvisioningManager.KEY_WIFI_THRESHOLD_A 863 + ") is provisioned to " 864 + info.getIntegerItem(ProvisioningManager.KEY_WIFI_THRESHOLD_A)); 865 mConfigManager.setQnsProvisioningInfo(info); 866 needBuildAnsp = true; 867 needEvaluate = true; 868 } 869 if (!info.equalsIntegerItem( 870 mLastProvisioningInfo, ProvisioningManager.KEY_WIFI_THRESHOLD_B)) { 871 log( 872 "onProvisioningInfoChanged, KEY_WIFI_THRESHOLD_B(" 873 + ProvisioningManager.KEY_WIFI_THRESHOLD_B 874 + ") is provisioned to " 875 + info.getIntegerItem(ProvisioningManager.KEY_WIFI_THRESHOLD_B)); 876 mConfigManager.setQnsProvisioningInfo(info); 877 needBuildAnsp = true; 878 needEvaluate = true; 879 } 880 881 if (!info.equalsIntegerItem( 882 mLastProvisioningInfo, ProvisioningManager.KEY_LTE_EPDG_TIMER_SEC)) { 883 log( 884 "onProvisioningInfoChanged, KEY_LTE_EPDG_TIMER_SEC(" 885 + ProvisioningManager.KEY_LTE_EPDG_TIMER_SEC 886 + ") is provisioned to " 887 + info.getIntegerItem(ProvisioningManager.KEY_LTE_EPDG_TIMER_SEC)); 888 mConfigManager.setQnsProvisioningInfo(info); 889 needEvaluate = true; 890 } 891 if (!info.equalsIntegerItem( 892 mLastProvisioningInfo, ProvisioningManager.KEY_WIFI_EPDG_TIMER_SEC)) { 893 log( 894 "onProvisioningInfoChanged, KEY_WIFI_EPDG_TIMER_SEC(" 895 + ProvisioningManager.KEY_WIFI_EPDG_TIMER_SEC 896 + ") is provisioned to " 897 + info.getIntegerItem(ProvisioningManager.KEY_WIFI_EPDG_TIMER_SEC)); 898 mConfigManager.setQnsProvisioningInfo(info); 899 needEvaluate = true; 900 } 901 902 mLastProvisioningInfo = info; 903 904 if (needBuildAnsp) { 905 buildAccessNetworkSelectionPolicy(true); 906 } 907 if (needEvaluate) { 908 evaluate(); 909 } 910 911 /* TODO to be checked 912 ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS 913 ProvisioningManager.KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID 914 */ 915 } 916 onImsRegStateChanged(QnsImsManager.ImsRegistrationState imsRegEvent)917 private void onImsRegStateChanged(QnsImsManager.ImsRegistrationState imsRegEvent) { 918 if (mConfigManager.getRatPreference(mNetCapability) 919 != QnsConstants.RAT_PREFERENCE_WIFI_WHEN_WFC_AVAILABLE) { 920 return; 921 } 922 int transportType = imsRegEvent.getTransportType(); 923 int event = imsRegEvent.getEvent(); 924 if (event == QnsConstants.IMS_REGISTRATION_CHANGED_REGISTERED 925 || event == QnsConstants.IMS_REGISTRATION_CHANGED_UNREGISTERED) { 926 log( 927 "onImsRegStateChanged, " 928 + QnsConstants.transportTypeToString(transportType) 929 + "," 930 + QnsConstants.imsRegistrationEventToString(event)); 931 evaluate(); 932 } 933 } 934 onSipDialogSessionStateChanged(boolean isActive)935 protected void onSipDialogSessionStateChanged(boolean isActive) { 936 if (mConfigManager.getSipDialogSessionPolicy() 937 == QnsConstants.SIP_DIALOG_SESSION_POLICY_NONE) { 938 mSipDialogSessionState = false; 939 return; 940 } 941 if (mSipDialogSessionState != isActive) { 942 mSipDialogSessionState = isActive; 943 log("onSipDialogSessionStateChanged isActive:" + isActive); 944 evaluate(); 945 } 946 } 947 onImsCallDisconnectCauseChanged(ImsReasonInfo imsReasonInfo)948 protected void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReasonInfo) { 949 if (imsReasonInfo == null) { 950 return; 951 } 952 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 953 && imsReasonInfo.getCode() == ImsReasonInfo.CODE_MEDIA_NO_DATA) { 954 log( 955 "onImsCallDisconnectCauseChanged: iwlanAvailable=" 956 + mIwlanAvailable 957 + " cellularAvailable=" 958 + mCellularAvailable 959 + " imsReasonInfo=" 960 + imsReasonInfo); 961 if (mIwlanAvailable && mCellularAvailable) { 962 // metrics 963 sendMetricsForImsCallDropStats(); 964 } 965 } 966 } 967 onCellularQualityChanged(Threshold[] ths)968 protected void onCellularQualityChanged(Threshold[] ths) { 969 if (ths == null || ths.length == 0) { 970 log("onCellularQualityChanged: E threshold is null"); 971 return; 972 } 973 log("onCellularQualityChanged Threshold:" + Arrays.toString(ths)); 974 // TODO 975 evaluate(); 976 } 977 onWiFiQualityChanged(Threshold[] ths)978 protected void onWiFiQualityChanged(Threshold[] ths) { 979 if (ths == null || ths.length == 0) { 980 log("onCellularQualityChanged: E threshold is null"); 981 return; 982 } 983 log("onWiFiQualityChanged Threshold:" + Arrays.toString(ths)); 984 // TODO 985 evaluate(); 986 } 987 onRttStatusChanged(boolean result)988 private void onRttStatusChanged(boolean result) { 989 log("onRttStatusChanged status: " + result); 990 if (result != mIsRttCheckSuccess) { 991 mIsRttCheckSuccess = result; 992 if (mIsRttCheckSuccess) { 993 evaluate(); 994 } 995 } 996 } 997 isWfcEnabled()998 protected boolean isWfcEnabled() { 999 1000 validateWfcSettingsAndUpdate(); 1001 1002 if (mAllowIwlanForWfcActivation) { 1003 return true; 1004 } 1005 if (!mWfcPlatformEnabled) { 1006 log("isWfcPlatformEnabled:false"); 1007 return false; 1008 } 1009 if (mCoverage == QnsConstants.COVERAGE_HOME && mSettingWfcEnabled) { 1010 return true; 1011 } 1012 if ((mCoverage == QnsConstants.COVERAGE_ROAM 1013 || mIwlanNetworkStatusTracker.isInternationalRoaming(mSlotIndex)) 1014 && mSettingWfcRoamingEnabled) { 1015 return true; 1016 } 1017 1018 if (mConfigManager.allowImsOverIwlanCellularLimitedCase() 1019 && !isAccessNetworkAllowed(mCellularAccessNetworkType, mNetCapability) 1020 && mCallType == QnsConstants.CALL_TYPE_IDLE 1021 && mIwlanAvailable) { 1022 log("isWfcEnabled:true for idle, allow wfc"); 1023 return true; 1024 } 1025 1026 if (mConfigManager.allowVideoOverIWLANWithCellularLimitedCase() 1027 && mCallType == QnsConstants.CALL_TYPE_VIDEO 1028 && mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) { 1029 log("isWfcEnabled:true for video"); 1030 return true; 1031 } 1032 1033 return false; 1034 } 1035 validateWfcSettingsAndUpdate()1036 private void validateWfcSettingsAndUpdate() { 1037 boolean roaming = (mCoverage == QnsConstants.COVERAGE_ROAM); 1038 boolean wfcSetting = 1039 QnsUtils.isWfcEnabled(mQnsImsManager, mQnsProvisioningListener, roaming); 1040 if (roaming && mSettingWfcRoamingEnabled != wfcSetting) { 1041 log("validateWfcSettingsAndUpdate, found wfc roaming setting mismatch"); 1042 if (wfcSetting) { 1043 mWfcPlatformEnabled = true; 1044 mSettingWfcRoamingEnabled = true; 1045 } else { 1046 mWfcPlatformEnabled = QnsUtils.isWfcEnabledByPlatform(mQnsImsManager); 1047 mSettingWfcRoamingEnabled = false; 1048 } 1049 mSettingWfcRoamingMode = QnsUtils.getWfcMode(mQnsImsManager, true); 1050 } else if (!roaming && mSettingWfcEnabled != wfcSetting) { 1051 log("validateWfcSettingsAndUpdate, found wfc setting mismatch"); 1052 if (wfcSetting) { 1053 mWfcPlatformEnabled = true; 1054 mSettingWfcEnabled = true; 1055 } else { 1056 mWfcPlatformEnabled = QnsUtils.isWfcEnabledByPlatform(mQnsImsManager); 1057 mSettingWfcEnabled = false; 1058 } 1059 mSettingWfcMode = QnsUtils.getWfcMode(mQnsImsManager, false); 1060 } 1061 } 1062 isAccessNetworkAllowed(int accessNetwork, int netCapability)1063 private boolean isAccessNetworkAllowed(int accessNetwork, int netCapability) { 1064 switch (netCapability) { 1065 case NetworkCapabilities.NET_CAPABILITY_EIMS: 1066 case NetworkCapabilities.NET_CAPABILITY_IMS: 1067 case NetworkCapabilities.NET_CAPABILITY_XCAP: 1068 return mConfigManager.isAccessNetworkAllowed(accessNetwork, netCapability); 1069 default: 1070 if (accessNetwork == AccessNetworkType.UNKNOWN) { 1071 return false; 1072 } 1073 } 1074 return true; 1075 } 1076 isAllowed(int transportType)1077 private boolean isAllowed(int transportType) { 1078 StringBuilder sb = new StringBuilder(); 1079 sb.append(" evaluate isAllowed for transportType:") 1080 .append(QnsConstants.transportTypeToString(transportType)); 1081 1082 if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1083 boolean isWfcEnabled = isWfcEnabled(); 1084 sb.append(" isWfcEnabled:").append(isWfcEnabled); 1085 if (!isWfcEnabled) { 1086 log(sb.toString()); 1087 return false; 1088 } 1089 1090 if (mQnsEventDispatcher.isAirplaneModeToggleOn()) { 1091 boolean isWfcAllowInAirplaneMode = mConfigManager.allowWFCOnAirplaneModeOn(); 1092 sb.append(" isWfcAllowInAirplaneMode:").append(isWfcAllowInAirplaneMode); 1093 if (!isWfcAllowInAirplaneMode) { 1094 log(sb.toString()); 1095 return false; 1096 } 1097 } 1098 1099 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 1100 && (mQnsEventDispatcher.isAirplaneModeToggleOn() 1101 || !mQnsComponents 1102 .getQnsTelephonyListener(mSlotIndex) 1103 .getLastQnsTelephonyInfo() 1104 .isCellularAvailable()) 1105 && mIwlanNetworkStatusTracker.isInternationalRoaming(mSlotIndex)) { 1106 boolean isBlockIwlan = mConfigManager.blockIwlanInInternationalRoamWithoutWwan(); 1107 sb.append(" isBlockIwlanInInternationalRoamWithoutWwan:").append(isBlockIwlan); 1108 if (isBlockIwlan) { 1109 log(sb.toString()); 1110 return false; 1111 } 1112 } 1113 } 1114 1115 if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1116 if (mQnsEventDispatcher.isAirplaneModeToggleOn()) { 1117 sb.append(" AirplaneModeOn"); 1118 log(sb.toString()); 1119 return false; 1120 } 1121 1122 if (getPreferredMode() == QnsConstants.WIFI_ONLY) { 1123 sb.append(" isWiFiOnly:false"); 1124 log(sb.toString()); 1125 return false; 1126 } 1127 } 1128 1129 if (mConfigManager.getRatPreference(mNetCapability) 1130 != QnsConstants.RAT_PREFERENCE_DEFAULT) { 1131 switch (mConfigManager.getRatPreference(mNetCapability)) { 1132 case QnsConstants.RAT_PREFERENCE_WIFI_ONLY: 1133 if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1134 sb.append(" isAllowRatPrefWiFiOnly:false"); 1135 log(sb.toString()); 1136 return false; 1137 } 1138 sb.append(" isAllowRatPrefWiFiOnly:true"); 1139 break; 1140 case QnsConstants.RAT_PREFERENCE_WIFI_WHEN_WFC_AVAILABLE: 1141 if ((transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1142 && mQnsImsManager.isImsRegistered( 1143 AccessNetworkConstants.TRANSPORT_TYPE_WLAN)) 1144 || (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1145 && !mQnsImsManager.isImsRegistered( 1146 AccessNetworkConstants.TRANSPORT_TYPE_WLAN))) { 1147 sb.append(" isAllowRatPrefWfcAvail:false"); 1148 log(sb.toString()); 1149 return false; 1150 } 1151 sb.append(" isAllowRatPrefWfcAvail:true"); 1152 break; 1153 case QnsConstants.RAT_PREFERENCE_WIFI_WHEN_NO_CELLULAR: 1154 if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1155 && mCellularAvailable) { 1156 sb.append(" isAllowRatPrefNoCell:false"); 1157 log(sb.toString()); 1158 return false; 1159 } 1160 sb.append(" isAllowRatPrefNoCell:true"); 1161 break; 1162 case QnsConstants.RAT_PREFERENCE_WIFI_WHEN_HOME_IS_NOT_AVAILABLE: 1163 if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1164 && (!mCellularAvailable || mCoverage != QnsConstants.COVERAGE_HOME)) { 1165 sb.append(" isAllowRatPrefNotHome:false"); 1166 log(sb.toString()); 1167 return false; 1168 } 1169 sb.append(" isAllowRatPrefNotHome:true"); 1170 break; 1171 } 1172 } 1173 1174 log(sb.toString()); 1175 return true; 1176 } 1177 evaluateAvailability(int transportType, boolean isAllowedForOtherType)1178 private boolean evaluateAvailability(int transportType, boolean isAllowedForOtherType) { 1179 boolean isAvailable = 1180 (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) 1181 ? mIwlanAvailable 1182 : mCellularAvailable; 1183 boolean isOtherTypeAvailable = 1184 isAllowedForOtherType 1185 && ((transportType != AccessNetworkConstants.TRANSPORT_TYPE_WLAN) 1186 ? mIwlanAvailable 1187 : mCellularAvailable); 1188 boolean isRestricted = mRestrictManager.isRestricted(transportType); 1189 boolean isAllowedOnSingleTransport = 1190 mRestrictManager.isAllowedOnSingleTransport(transportType); 1191 1192 StringBuilder sb = new StringBuilder(); 1193 sb.append(" evaluate Available for transportType:") 1194 .append(QnsConstants.transportTypeToString(transportType)); 1195 1196 sb.append(" isAvailable:").append(isAvailable); 1197 if (!isAvailable) { 1198 log(sb.toString()); 1199 return false; 1200 } else if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1201 && mIsCrossWfc 1202 && !isCrossWfcAllowed(mCellularAvailable)) { 1203 sb.append(" CrossWfc is not allowed. mCellularAvailable:").append(mCellularAvailable); 1204 log(sb.toString()); 1205 return false; 1206 } 1207 1208 if (isRestricted) { 1209 PreCondition cond = getMatchingPreCondition(); 1210 if (cond instanceof GuardingPreCondition 1211 && ((GuardingPreCondition) cond).getGuarding() != QnsConstants.GUARDING_NONE) { 1212 isRestricted = mRestrictManager.isRestrictedExceptGuarding(transportType); 1213 sb.append(" isRestrictedExceptGuarding:").append(isRestricted); 1214 } else { 1215 sb.append(" isRestricted:").append(isRestricted); 1216 } 1217 } else { 1218 sb.append(" isRestricted:").append(isRestricted); 1219 } 1220 if (!isRestricted) { 1221 log(sb.toString()); 1222 return true; 1223 } 1224 1225 sb.append(" hasIgnorableRestriction:").append(isAllowedOnSingleTransport); 1226 if (!isAllowedOnSingleTransport) { 1227 log(sb.toString()); 1228 return false; 1229 } 1230 1231 sb.append(" isOtherTypeAvailable:").append(isOtherTypeAvailable); 1232 log(sb.toString()); 1233 return !isOtherTypeAvailable; 1234 } 1235 evaluate()1236 protected void evaluate() { 1237 evaluate(EVALUATE_SPECIFIC_REASON_NONE); 1238 } 1239 evaluate(int specificReason)1240 protected synchronized void evaluate(int specificReason) { 1241 if (!mInitialized) { 1242 if (DBG) log("ANE is not initialized yet."); 1243 return; 1244 } 1245 mLastEvaluateSpecificReason = specificReason; 1246 log("evaluate reason:" + evaluateSpecificReasonToString(specificReason)); 1247 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_EIMS) { 1248 if (!mDataConnectionStatusTracker.isActiveState()) { 1249 log("QNS only handles HO of EMERGENCY data connection"); 1250 return; 1251 } 1252 } 1253 1254 /* Check handover policy */ 1255 if (needHandoverPolicyCheck()) { 1256 if (!moveTransportTypeAllowed()) { 1257 log("Handover is not allowed. Skip this evaluation."); 1258 return; 1259 } 1260 } 1261 1262 /* Check network Availability */ 1263 boolean isAllowedForIwlan = isAllowed(AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 1264 boolean isAllowedForCellular = isAllowed(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1265 boolean availabilityIwlan = 1266 isAllowedForIwlan 1267 && evaluateAvailability( 1268 AccessNetworkConstants.TRANSPORT_TYPE_WLAN, isAllowedForCellular); 1269 boolean availabilityCellular = 1270 isAllowedForCellular 1271 && evaluateAvailability( 1272 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, isAllowedForIwlan); 1273 log(" availability Iwlan:" + availabilityIwlan + " Cellular:" + availabilityCellular); 1274 1275 if (mWifiBackhaulMonitor.isRttCheckEnabled() 1276 && mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) { 1277 mWifiBackhaulMonitor.setCellularAvailable( 1278 availabilityCellular 1279 && isAccessNetworkAllowed(mCellularAccessNetworkType, mNetCapability)); 1280 } 1281 // QualifiedNetworksService checks AccessNetworkSelectionPolicy only in the case both 1282 // networks(cellular and iwlan) are available. If only one network is available, no 1283 // evaluation is run. Available network of accessNetworkType will be reported immediately. 1284 if (availabilityIwlan && availabilityCellular) { 1285 updateAccessNetworkSelectionPolicy(); 1286 List<Integer> accessNetworkTypes = 1287 evaluateAccessNetworkSelectionPolicy(availabilityIwlan, availabilityCellular); 1288 reportSatisfiedAccessNetworkTypesByState(accessNetworkTypes, true); 1289 reevaluateLastNotifiedSecondAccessNetwork(); 1290 } else if (availabilityIwlan) { 1291 updateAccessNetworkSelectionPolicy(); 1292 if (!mIsCrossWfc && hasWifiThresholdWithoutCellularCondition()) { 1293 List<Integer> accessNetworkTypes = 1294 evaluateAccessNetworkSelectionPolicy( 1295 availabilityIwlan, availabilityCellular); 1296 reportSatisfiedAccessNetworkTypesByState(accessNetworkTypes, true); 1297 } else { 1298 reportSatisfiedAccessNetworkTypesByState(List.of(AccessNetworkType.IWLAN), false); 1299 } 1300 } else if (availabilityCellular) { 1301 reportSatisfiedAccessNetworkTypesByState( 1302 new ArrayList<>(List.of(mCellularAccessNetworkType)), false); 1303 } else { 1304 // TODO Is it better to report to cellular when there is nothing? 1305 log("evaluate nothing without an available network."); 1306 if (specificReason == EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE) { 1307 reportQualifiedNetwork(getInitialAccessNetworkTypes()); 1308 } 1309 } 1310 } 1311 1312 @VisibleForTesting vopsCheckRequired(int cellularAccessNetworkType, int coverage, int callType)1313 boolean vopsCheckRequired(int cellularAccessNetworkType, int coverage, int callType) { 1314 boolean checkVoPs = false; 1315 if (mConfigManager.isMmtelCapabilityRequired(coverage) 1316 && (cellularAccessNetworkType == AccessNetworkType.EUTRAN 1317 || cellularAccessNetworkType == AccessNetworkType.NGRAN)) { 1318 if (mDataConnectionStatusTracker.isInactiveState()) { 1319 checkVoPs = true; 1320 } else if (mDataConnectionStatusTracker.getLastTransportType() 1321 == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1322 if (callType == QnsConstants.CALL_TYPE_IDLE 1323 || !mConfigManager.isInCallHoDecisionWlanToWwanWithoutVopsCondition()) { 1324 checkVoPs = true; 1325 } 1326 } else if (mDataConnectionStatusTracker.getLastTransportType() 1327 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1328 // If there is an on-going call and UE is moving into an area which does not support 1329 // VoPS, don't consider VoPS condition and let AccessNetworkEvaluator decide a 1330 // preferred RAT. 1331 if (callType == QnsConstants.CALL_TYPE_IDLE) { 1332 checkVoPs = true; 1333 } 1334 } 1335 } 1336 return checkVoPs; 1337 } 1338 hasWifiThresholdWithoutCellularCondition()1339 private boolean hasWifiThresholdWithoutCellularCondition() { 1340 if (mAccessNetworkSelectionPolicies == null || mAccessNetworkSelectionPolicies.isEmpty()) { 1341 return false; 1342 } 1343 for (AccessNetworkSelectionPolicy policy : mAccessNetworkSelectionPolicies) { 1344 if (policy.hasWifiThresholdWithoutCellularCondition()) { 1345 return true; 1346 } 1347 } 1348 return false; 1349 } 1350 reportSatisfiedAccessNetworkTypesByState( List<Integer> satisfiedAccessNetworkTypes, boolean needMonitor)1351 protected synchronized void reportSatisfiedAccessNetworkTypesByState( 1352 List<Integer> satisfiedAccessNetworkTypes, boolean needMonitor) { 1353 if (needMonitor) { 1354 if (mDataConnectionStatusTracker.isInactiveState()) { 1355 if (satisfiedAccessNetworkTypes.size() > 0) { 1356 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1357 updateAccessNetworkSelectionPolicy(); 1358 } 1359 updateQualityMonitor(); 1360 } else if (!mDataConnectionStatusTracker.isConnectionInProgress()) { 1361 if (isHandoverNeeded(satisfiedAccessNetworkTypes)) { 1362 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1363 unregisterThresholdToQualityMonitor(); 1364 } else if (isFallbackCase(satisfiedAccessNetworkTypes)) { 1365 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1366 updateAccessNetworkSelectionPolicy(); 1367 updateQualityMonitor(); 1368 } else { 1369 updateQualityMonitor(); 1370 } 1371 } 1372 } else { 1373 if (mDataConnectionStatusTracker.isInactiveState()) { 1374 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1375 } else if (!mDataConnectionStatusTracker.isConnectionInProgress()) { 1376 if (isHandoverNeeded(satisfiedAccessNetworkTypes)) { 1377 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1378 } else if (isFallbackCase(satisfiedAccessNetworkTypes)) { 1379 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1380 } 1381 } 1382 unregisterThresholdToQualityMonitor(); 1383 } 1384 } 1385 getTargetTransportType(List<Integer> accessNetworkTypes)1386 protected int getTargetTransportType(List<Integer> accessNetworkTypes) { 1387 if (accessNetworkTypes == null || accessNetworkTypes.size() == 0) { 1388 return AccessNetworkConstants.TRANSPORT_TYPE_INVALID; 1389 } 1390 if (accessNetworkTypes.get(0) == AccessNetworkType.IWLAN) { 1391 return AccessNetworkConstants.TRANSPORT_TYPE_WLAN; 1392 } 1393 return AccessNetworkConstants.TRANSPORT_TYPE_WWAN; 1394 } 1395 1396 @VisibleForTesting needHandoverPolicyCheck()1397 boolean needHandoverPolicyCheck() { 1398 if (mDataConnectionStatusTracker.isActiveState()) { 1399 int srcTransportType = mDataConnectionStatusTracker.getLastTransportType(); 1400 boolean targetNetworkAvailable = 1401 srcTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1402 ? mCellularAvailable 1403 : mIwlanAvailable; 1404 if (srcTransportType == getLastQualifiedTransportType() && targetNetworkAvailable) { 1405 log("Need to check handover policy for this evaluation."); 1406 return true; 1407 } 1408 } 1409 log("No need to check handover policy for this evaluation."); 1410 return false; 1411 } 1412 1413 @VisibleForTesting moveTransportTypeAllowed()1414 boolean moveTransportTypeAllowed() { 1415 int srcAccessNetwork = 1416 mDataConnectionStatusTracker.getLastTransportType() 1417 == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1418 ? AccessNetworkType.IWLAN 1419 : mLatestAvailableCellularAccessNetwork; 1420 int dstAccessNetwork = 1421 srcAccessNetwork == AccessNetworkType.IWLAN 1422 ? mCellularAccessNetworkType 1423 : AccessNetworkType.IWLAN; 1424 if (mConfigManager.isHandoverAllowedByPolicy( 1425 mNetCapability, srcAccessNetwork, dstAccessNetwork, mCoverage)) { 1426 return true; 1427 } else { 1428 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 1429 && mCallStatusTracker.isCallIdle(NetworkCapabilities.NET_CAPABILITY_IMS)) { 1430 // Telephony will make new connection with preferred AccessNetwork 1431 log("handover is not allowed. but need to move to target Transport."); 1432 return true; 1433 } 1434 if (dstAccessNetwork == AccessNetworkType.IWLAN && useDifferentApnOverIwlan()) { 1435 // Telephony will make new connection when change transport type 1436 log( 1437 "handover is not allowed. but need to move to target Transport using" 1438 + " different apn over IWLAN."); 1439 return true; 1440 } 1441 if (dstAccessNetwork != AccessNetworkType.IWLAN 1442 && mCellularAvailable 1443 && mConfigManager.getRatPreference(mNetCapability) 1444 == QnsConstants.RAT_PREFERENCE_WIFI_WHEN_NO_CELLULAR) { 1445 // Telephony will make new connection when change transport type 1446 log( 1447 "handover is not allowed. but need to move to target Transport for the" 1448 + " RAT_PREFERENCE_WIFI_WHEN_NO_CELLULAR."); 1449 return true; 1450 } 1451 } 1452 return false; 1453 } 1454 useDifferentApnOverIwlan()1455 private boolean useDifferentApnOverIwlan() { 1456 // supports MMS, XCAP and CBS 1457 if (mNetCapability != NetworkCapabilities.NET_CAPABILITY_MMS 1458 && mNetCapability != NetworkCapabilities.NET_CAPABILITY_XCAP 1459 && mNetCapability != NetworkCapabilities.NET_CAPABILITY_CBS) { 1460 return false; 1461 } 1462 1463 ApnSetting apnSetting = 1464 mDataConnectionStatusTracker.getLastApnSetting( 1465 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1466 if (apnSetting != null 1467 && (apnSetting.getApnTypeBitmask() & ApnSetting.TYPE_DEFAULT) != 0 1468 && (apnSetting.getNetworkTypeBitmask() 1469 & (1 << (TelephonyManager.NETWORK_TYPE_IWLAN - 1))) 1470 == 0) { 1471 log("useDifferentApnOverIwlan true"); 1472 return true; 1473 } 1474 log("useDifferentApnOverIwlan false"); 1475 return false; 1476 } 1477 isHandoverNeeded(List<Integer> accessNetworkTypes)1478 protected boolean isHandoverNeeded(List<Integer> accessNetworkTypes) { 1479 if (mDataConnectionStatusTracker.isInactiveState() 1480 || mDataConnectionStatusTracker.isHandoverState()) { 1481 return false; 1482 } 1483 1484 int targetTransportType = getTargetTransportType(accessNetworkTypes); 1485 if (targetTransportType == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) { 1486 return false; 1487 } 1488 1489 // Handover case 1490 int sourceTransportType = mDataConnectionStatusTracker.getLastTransportType(); 1491 return sourceTransportType != targetTransportType; 1492 } 1493 isFallbackCase(List<Integer> accessNetworkTypes)1494 protected boolean isFallbackCase(List<Integer> accessNetworkTypes) { 1495 if (mDataConnectionStatusTracker.isInactiveState()) { 1496 return false; 1497 } 1498 1499 int targetTransportType = getTargetTransportType(accessNetworkTypes); 1500 if (targetTransportType == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) { 1501 return false; 1502 } 1503 if (targetTransportType != mDataConnectionStatusTracker.getLastTransportType()) { 1504 return false; 1505 } 1506 1507 if (getLastQualifiedTransportType() == targetTransportType) { 1508 return false; 1509 } 1510 1511 log("isFallbackcase:true"); 1512 return true; 1513 } 1514 reportQualifiedNetwork(List<Integer> accessNetworkTypes)1515 protected void reportQualifiedNetwork(List<Integer> accessNetworkTypes) { 1516 if (accessNetworkTypes.contains(AccessNetworkType.UNKNOWN)) { 1517 log( 1518 "reportQualifiedNetwork, remove UNKNOWN access network." 1519 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1520 accessNetworkTypes.remove(AccessNetworkType.UNKNOWN); 1521 } 1522 List<Integer> supportAccessNetworkTypes = new ArrayList<>(); 1523 if (mConfigManager.allowImsOverIwlanCellularLimitedCase()) { 1524 for (Integer accessNetwork : accessNetworkTypes) { 1525 if (accessNetwork == AccessNetworkType.IWLAN 1526 || isAccessNetworkAllowed(accessNetwork, mNetCapability)) { 1527 supportAccessNetworkTypes.add(accessNetwork); 1528 } 1529 } 1530 if (!accessNetworkTypes.isEmpty() && supportAccessNetworkTypes.isEmpty()) { 1531 log("supportAccessNetworkTypes is empty"); 1532 return; 1533 } 1534 } else { 1535 supportAccessNetworkTypes.addAll(accessNetworkTypes); 1536 } 1537 1538 log( 1539 "reportQualifiedNetwork supportAccessNetworkTypes:" 1540 + QnsUtils.getStringAccessNetworkTypes(supportAccessNetworkTypes)); 1541 1542 if (equalsLastNotifiedQualifiedNetwork(supportAccessNetworkTypes)) { 1543 return; 1544 } else { 1545 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 1546 && mWifiBackhaulMonitor.isRttCheckEnabled()) { 1547 if (supportAccessNetworkTypes.contains(AccessNetworkType.IWLAN)) { 1548 if (!isRttSuccess()) { 1549 mWifiBackhaulMonitor.requestRttCheck(); 1550 return; 1551 } 1552 } else { 1553 mIsRttCheckSuccess = false; 1554 } 1555 } 1556 } 1557 1558 updateLastNotifiedQualifiedNetwork(supportAccessNetworkTypes); 1559 notifyForQualifiedNetworksChanged(supportAccessNetworkTypes); 1560 } 1561 findUnmatchedThresholds()1562 private List<Threshold> findUnmatchedThresholds() { 1563 List<Threshold> unmatchedThresholds = new ArrayList<>(); 1564 if (mAccessNetworkSelectionPolicies == null 1565 || mAccessNetworkSelectionPolicies.size() == 0) { 1566 return unmatchedThresholds; 1567 } 1568 1569 List<Integer> excludeThresholdGroup = new ArrayList<>(); 1570 boolean bIwlanRegistrable = isIwlanAvailableWithoutRestrict(); 1571 boolean bCellularRegistrable = isCellularAvailableWithoutRestrict(); 1572 for (AccessNetworkSelectionPolicy policy : mAccessNetworkSelectionPolicies) { 1573 List<Threshold> policyUnmatchedThresholds = 1574 policy.findUnmatchedThresholds(mWifiQualityMonitor, mCellularQualityMonitor); 1575 if (policyUnmatchedThresholds == null || policyUnmatchedThresholds.size() == 0) { 1576 continue; 1577 } 1578 for (Threshold threshold : policyUnmatchedThresholds) { 1579 if (bIwlanRegistrable && threshold.getAccessNetwork() == AccessNetworkType.IWLAN) { 1580 unmatchedThresholds.add(threshold); 1581 } 1582 if (bCellularRegistrable 1583 && threshold.getAccessNetwork() != AccessNetworkType.IWLAN) { 1584 if (threshold.getAccessNetwork() == mCellularAccessNetworkType) { 1585 unmatchedThresholds.add(threshold); 1586 } else if (threshold.getGroupId() >= 0) { 1587 // If the current cellular access network and the access network of 1588 // cellular threshold are different, it is not necessary to monitor the 1589 // entire threshold of this group. 1590 excludeThresholdGroup.add(threshold.getGroupId()); 1591 } 1592 } 1593 } 1594 } 1595 for (int excludeGid : excludeThresholdGroup) { 1596 unmatchedThresholds.removeIf(threshold -> threshold.getGroupId() == excludeGid); 1597 } 1598 return unmatchedThresholds; 1599 } 1600 updateQualityMonitor()1601 private void updateQualityMonitor() { 1602 List<Threshold> unmatchedThresholds = findUnmatchedThresholds(); 1603 if (unmatchedThresholds.size() == 0) { 1604 log("updateQualityMonitor empty unmatchedThresholds."); 1605 unregisterThresholdToQualityMonitor(); 1606 return; 1607 } 1608 1609 log("updateQualityMonitor"); 1610 1611 LinkedHashSet<Integer> unmatchedGroupIdSet = new LinkedHashSet<>(); 1612 HashMap<Integer, Integer> unmatchedMonitorTypeMap = new HashMap<>(); 1613 LinkedHashSet<Integer> unmatchedMonitorTypeSet = new LinkedHashSet<>(); 1614 for (Threshold th : unmatchedThresholds) { 1615 if (th.getGroupId() < 0) { 1616 continue; 1617 } 1618 unmatchedGroupIdSet.add(th.getGroupId()); 1619 int key = th.getAccessNetwork() << 16 | th.getMeasurementType(); 1620 unmatchedMonitorTypeMap.put(key, unmatchedMonitorTypeMap.getOrDefault(key, 0) + 1); 1621 } 1622 1623 List<Map.Entry<Integer, Integer>> list_entries = 1624 new ArrayList<>(unmatchedMonitorTypeMap.entrySet()); 1625 list_entries.sort(Entry.comparingByValue()); 1626 for (Entry<Integer, Integer> entry : list_entries) { 1627 unmatchedMonitorTypeSet.add(entry.getKey()); 1628 } 1629 1630 LinkedHashSet<Integer> reducedGroupIdSet = new LinkedHashSet<>(); 1631 for (int type : unmatchedMonitorTypeSet) { 1632 reducedGroupIdSet.clear(); 1633 boolean skipReduce = false; 1634 for (Threshold th : unmatchedThresholds) { 1635 if (type == (th.getAccessNetwork() << 16 | th.getMeasurementType())) { 1636 if (th.getGroupId() < 0) { 1637 skipReduce = true; 1638 break; 1639 } 1640 } else { 1641 reducedGroupIdSet.add(th.getGroupId()); 1642 } 1643 } 1644 if (skipReduce) { 1645 continue; 1646 } 1647 1648 if (reducedGroupIdSet.containsAll(unmatchedGroupIdSet)) { 1649 unmatchedThresholds.removeIf( 1650 threshold -> 1651 type 1652 == (threshold.getAccessNetwork() << 16 1653 | threshold.getMeasurementType())); 1654 } 1655 } 1656 1657 registerThresholdsToQualityMonitor(unmatchedThresholds); 1658 } 1659 unregisterThresholdToQualityMonitor()1660 private void unregisterThresholdToQualityMonitor() { 1661 mWifiQualityMonitor.updateThresholdsForNetCapability(mNetCapability, mSlotIndex, null); 1662 mCellularQualityMonitor.updateThresholdsForNetCapability(mNetCapability, mSlotIndex, null); 1663 } 1664 registerThresholdsToQualityMonitor(List<Threshold> thresholds)1665 private void registerThresholdsToQualityMonitor(List<Threshold> thresholds) { 1666 if (thresholds == null) { 1667 thresholds = new ArrayList<>(); 1668 } 1669 1670 List<Threshold> monitorWiFiThresholds = new ArrayList<>(); 1671 List<Threshold> monitorCellThresholds = new ArrayList<>(); 1672 for (Threshold th : thresholds) { 1673 if (th.getAccessNetwork() == AccessNetworkType.IWLAN) { 1674 monitorWiFiThresholds.add(th); 1675 } else { 1676 monitorCellThresholds.add(th); 1677 } 1678 } 1679 1680 for (Threshold th : monitorWiFiThresholds) { 1681 log(" monitorWiFiThresholds th:" + th.toShortString()); 1682 } 1683 for (Threshold th : monitorCellThresholds) { 1684 log(" monitorCellThresholds th:" + th.toShortString()); 1685 } 1686 1687 // refresh threshold to be monitored. 1688 mWifiQualityMonitor.updateThresholdsForNetCapability( 1689 mNetCapability, mSlotIndex, monitorWiFiThresholds.toArray(new Threshold[0])); 1690 mCellularQualityMonitor.updateThresholdsForNetCapability( 1691 mNetCapability, mSlotIndex, monitorCellThresholds.toArray(new Threshold[0])); 1692 } 1693 updateThrottleStatus( boolean isThrottle, long throttleTimeMillis, int transportType)1694 protected void updateThrottleStatus( 1695 boolean isThrottle, long throttleTimeMillis, int transportType) { 1696 mRestrictManager.notifyThrottling(isThrottle, throttleTimeMillis, transportType); 1697 } 1698 getPreferredMode()1699 protected int getPreferredMode() { 1700 if (mAllowIwlanForWfcActivation) { 1701 return QnsConstants.WIFI_PREF; 1702 } 1703 if (mCoverage == QnsConstants.COVERAGE_ROAM) { 1704 return mSettingWfcRoamingMode; 1705 } 1706 return mSettingWfcMode; 1707 } 1708 getPreferredAccessNetwork()1709 private int getPreferredAccessNetwork() { 1710 switch (getPreferredMode()) { 1711 case QnsConstants.CELL_PREF: 1712 return mCellularAccessNetworkType; 1713 case QnsConstants.WIFI_PREF: 1714 case QnsConstants.WIFI_ONLY: 1715 return AccessNetworkType.IWLAN; 1716 } 1717 return mCellularAccessNetworkType; 1718 } 1719 isRttSuccess()1720 private boolean isRttSuccess() { 1721 return !isAccessNetworkAllowed( 1722 mCellularAccessNetworkType, NetworkCapabilities.NET_CAPABILITY_IMS) 1723 || mIsRttCheckSuccess; 1724 } 1725 evaluateAccessNetworkSelectionPolicy( boolean availabilityIwlan, boolean availabilityCellular)1726 private List<Integer> evaluateAccessNetworkSelectionPolicy( 1727 boolean availabilityIwlan, boolean availabilityCellular) { 1728 log("evaluateAccessNetworkSelectionPolicy"); 1729 1730 if (mAccessNetworkSelectionPolicies == null || mAccessNetworkSelectionPolicies.isEmpty()) { 1731 return new ArrayList<>(); 1732 } 1733 List<Integer> accessNetworkTypes = new ArrayList<>(); 1734 for (AccessNetworkSelectionPolicy policy : mAccessNetworkSelectionPolicies) { 1735 if (policy.satisfiedByThreshold( 1736 mWifiQualityMonitor, 1737 mCellularQualityMonitor, 1738 availabilityIwlan, 1739 availabilityCellular, 1740 mCellularAccessNetworkType)) { 1741 log( 1742 " satisfiedByThreshold TargetTransportType:" 1743 + QnsConstants.transportTypeToString( 1744 policy.getTargetTransportType())); 1745 if (policy.getTargetTransportType() == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1746 if (!accessNetworkTypes.contains(AccessNetworkType.IWLAN)) { 1747 accessNetworkTypes.add(AccessNetworkType.IWLAN); 1748 } 1749 1750 } else { 1751 if (!accessNetworkTypes.contains(mCellularAccessNetworkType)) { 1752 if (availabilityCellular) { 1753 accessNetworkTypes.add(mCellularAccessNetworkType); 1754 } else { 1755 accessNetworkTypes.add(AccessNetworkType.UNKNOWN); 1756 } 1757 } 1758 if ((mCallType == QnsConstants.CALL_TYPE_VOICE 1759 || mCallType == QnsConstants.CALL_TYPE_EMERGENCY) 1760 && policy.satisfiedWithWifiLowSignalStrength()) { 1761 int reason = mConfigManager.getQnsIwlanHoRestrictReason(); 1762 if (reason == QnsConstants.FALLBACK_REASON_RTP_OR_WIFI 1763 || reason == QnsConstants.FALLBACK_REASON_WIFI_ONLY) { 1764 log("WWAN decision with Wi-Fi low signalStrength in Voice call"); 1765 mRestrictManager.increaseCounterToRestrictIwlanInCall(); 1766 } 1767 } 1768 } 1769 } 1770 } 1771 1772 // If the evaluator has not yet reported a Qualified Networks, report preferred. 1773 if (!isNotifiedQualifiedAccessNetworkTypes()) { 1774 if (accessNetworkTypes.size() == 0) { 1775 accessNetworkTypes.add(getPreferredAccessNetwork()); 1776 log( 1777 " no candidate access network, use preferred:" 1778 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1779 } else if (accessNetworkTypes.size() > 1) { 1780 accessNetworkTypes.remove(Integer.valueOf(getPreferredAccessNetwork())); 1781 accessNetworkTypes.add(0, getPreferredAccessNetwork()); 1782 log( 1783 " two more candidate access network, use preferred:" 1784 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1785 } 1786 } 1787 1788 // TODO. need to be improved handling the second access network 1789 // Add a second access network, if the preferred access network does not exist in list. 1790 if (availabilityIwlan 1791 && availabilityCellular 1792 && mConfigManager.isOverrideImsPreferenceSupported()) { 1793 if (!accessNetworkTypes.isEmpty() 1794 && accessNetworkTypes.get(0) != AccessNetworkType.IWLAN 1795 && getPreferredMode() == QnsConstants.CELL_PREF 1796 && isAccessNetworkAllowed(accessNetworkTypes.get(0), mNetCapability)) { 1797 if (!accessNetworkTypes.contains(AccessNetworkType.IWLAN)) { 1798 accessNetworkTypes.add(AccessNetworkType.IWLAN); 1799 log( 1800 " add a second accessNetworkTypes : " 1801 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1802 } 1803 } else if (accessNetworkTypes.isEmpty() 1804 && !mLastQualifiedAccessNetworkTypes.isEmpty() 1805 && mLastQualifiedAccessNetworkTypes.get(0) != AccessNetworkType.IWLAN 1806 && getPreferredMode() == QnsConstants.CELL_PREF 1807 && isAccessNetworkAllowed( 1808 mLastQualifiedAccessNetworkTypes.get(0), mNetCapability)) { 1809 if (!mLastQualifiedAccessNetworkTypes.contains(AccessNetworkType.IWLAN)) { 1810 accessNetworkTypes.addAll(mLastQualifiedAccessNetworkTypes); 1811 accessNetworkTypes.add(AccessNetworkType.IWLAN); 1812 log( 1813 " add a second accessNetworkTypes in existing " 1814 + "mLastQualifiedAccessNetworkTypes : " 1815 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1816 } 1817 } 1818 } 1819 1820 log(" accessNetworkTypes:" + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1821 return accessNetworkTypes; 1822 } 1823 1824 // TODO. need to be improved handling the second access network 1825 // A qualified conditions are required for the second access network. 1826 // What threshold conditions are qualified for the second access network? (like rove in) 1827 // What are the threshold conditions for exiting the second access network? (like a rove out) reevaluateLastNotifiedSecondAccessNetwork()1828 private void reevaluateLastNotifiedSecondAccessNetwork() { 1829 if (mConfigManager.isOverrideImsPreferenceSupported() 1830 && mLastQualifiedAccessNetworkTypes.size() > 1 1831 && mLastQualifiedAccessNetworkTypes.get(1) == AccessNetworkType.IWLAN) { 1832 if (!isAccessNetworkAllowed(mCellularAccessNetworkType, mNetCapability) 1833 || getPreferredMode() != QnsConstants.CELL_PREF) { 1834 log("reevaluateLastNotifiedSecondAccessNetwork, Removed a second access network"); 1835 reportQualifiedNetwork( 1836 new ArrayList<>(List.of(mLastQualifiedAccessNetworkTypes.get(0)))); 1837 } 1838 } 1839 } 1840 buildAccessNetworkSelectionPolicy( boolean bForceUpdate)1841 private Map<PreCondition, List<AccessNetworkSelectionPolicy>> buildAccessNetworkSelectionPolicy( 1842 boolean bForceUpdate) { 1843 if (mAnspPolicyMap == null || bForceUpdate) { 1844 log("Building list of AccessNetworkSelectionPolicy."); 1845 mAnspPolicyMap = 1846 AccessNetworkSelectionPolicyBuilder.build(mConfigManager, mNetCapability); 1847 1848 if (DBG) { 1849 mAnspPolicyMap 1850 .values() 1851 .forEach( 1852 list -> 1853 list.stream() 1854 .map(policy -> " retriMap ANSP=" + policy) 1855 .forEach(this::log)); 1856 } 1857 } 1858 return mAnspPolicyMap; 1859 } 1860 updateAccessNetworkSelectionPolicy()1861 private void updateAccessNetworkSelectionPolicy() { 1862 Map<PreCondition, List<AccessNetworkSelectionPolicy>> map = 1863 buildAccessNetworkSelectionPolicy(false); 1864 if (map == null) { 1865 map = new HashMap<>(); 1866 } 1867 1868 log("Create a list of AccessNetworkSelectionPolicy that match the preconditions."); 1869 1870 PreCondition preCondition = getMatchingPreCondition(); 1871 List<AccessNetworkSelectionPolicy> matchedPolicies = new ArrayList<>(); 1872 List<AccessNetworkSelectionPolicy> list = map.get(preCondition); 1873 if (list != null) { 1874 for (AccessNetworkSelectionPolicy policy : list) { 1875 if (policy.satisfyPrecondition(preCondition) 1876 && !mDataConnectionStatusTracker.isConnectionInProgress() 1877 && (!isNotifiedQualifiedAccessNetworkTypes() 1878 || getLastQualifiedTransportType() 1879 != policy.getTargetTransportType())) { 1880 matchedPolicies.add(policy); 1881 } 1882 } 1883 } 1884 1885 if (mAccessNetworkSelectionPolicies.equals(matchedPolicies)) { 1886 for (AccessNetworkSelectionPolicy policy : matchedPolicies) { 1887 log(" Matched ANSP=" + policy); 1888 } 1889 } 1890 1891 for (AccessNetworkSelectionPolicy policy : matchedPolicies) { 1892 log(" Found new ANSP=" + policy); 1893 } 1894 1895 mAccessNetworkSelectionPolicies = matchedPolicies; 1896 } 1897 getMatchingPreCondition()1898 private PreCondition getMatchingPreCondition() { 1899 int callType = mCallType; 1900 if ((mNetCapability == NetworkCapabilities.NET_CAPABILITY_EIMS 1901 || mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) 1902 && mCallType == QnsConstants.CALL_TYPE_EMERGENCY) { 1903 callType = QnsConstants.CALL_TYPE_VOICE; 1904 } 1905 int sipDialogPolicy = mConfigManager.getSipDialogSessionPolicy(); 1906 if (callType == QnsConstants.CALL_TYPE_IDLE && mSipDialogSessionState) { 1907 if (sipDialogPolicy > QnsConstants.SIP_DIALOG_SESSION_POLICY_NONE) { 1908 log("apply sipDialogPolicy:" 1909 + QnsConstants.qnsSipDialogSessionPolicyToString(sipDialogPolicy)); 1910 } 1911 switch (sipDialogPolicy) { 1912 case QnsConstants.SIP_DIALOG_SESSION_POLICY_FOLLOW_VOICE_CALL: 1913 callType = QnsConstants.CALL_TYPE_VOICE; 1914 break; 1915 case QnsConstants.SIP_DIALOG_SESSION_POLICY_FOLLOW_VIDEO_CALL: 1916 callType = QnsConstants.CALL_TYPE_VIDEO; 1917 break; 1918 case QnsConstants.SIP_DIALOG_SESSION_POLICY_NONE: 1919 // fall-through 1920 default: 1921 // do-nothing 1922 break; 1923 } 1924 } 1925 1926 if (mConfigManager.hasThresholdGapWithGuardTimer()) { 1927 @QnsConstants.QnsGuarding int guarding = QnsConstants.GUARDING_NONE; 1928 int source = getLastQualifiedTransportType(); 1929 if (source != AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1930 && mRestrictManager.hasRestrictionType( 1931 AccessNetworkConstants.TRANSPORT_TYPE_WLAN, 1932 RestrictManager.RESTRICT_TYPE_GUARDING)) { 1933 guarding = QnsConstants.GUARDING_WIFI; 1934 } else if (source != AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1935 && mRestrictManager.hasRestrictionType( 1936 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 1937 RestrictManager.RESTRICT_TYPE_GUARDING)) { 1938 guarding = QnsConstants.GUARDING_CELLULAR; 1939 } 1940 return new GuardingPreCondition(callType, getPreferredMode(), mCoverage, guarding); 1941 } 1942 return new PreCondition(callType, getPreferredMode(), mCoverage); 1943 } 1944 evaluateSpecificReasonToString(int specificReason)1945 private String evaluateSpecificReasonToString(int specificReason) { 1946 if (specificReason == EVALUATE_SPECIFIC_REASON_NONE) { 1947 return "EVALUATE_SPECIFIC_REASON_NONE"; 1948 } else if (specificReason == EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE) { 1949 return "EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE"; 1950 } else if (specificReason == EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED) { 1951 return "EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED"; 1952 } else if (specificReason == EVALUATE_SPECIFIC_REASON_DATA_FAILED) { 1953 return "EVALUATE_SPECIFIC_REASON_DATA_FAILED"; 1954 } else if (specificReason == EVALUATE_SPECIFIC_REASON_DATA_CONNECTED) { 1955 return "EVALUATE_SPECIFIC_REASON_DATA_CONNECTED"; 1956 } 1957 return "UNKNOWN"; 1958 } 1959 isCrossWfcAllowed(boolean cellularAvailable)1960 private boolean isCrossWfcAllowed(boolean cellularAvailable) { 1961 if (mConfigManager.getRatPreference(mNetCapability) 1962 == QnsConstants.RAT_PREFERENCE_WIFI_WHEN_WFC_AVAILABLE) { 1963 // Should follow RAT_PREFERENCE_WIFI_WHEN_WFC_AVAILABLE and do not block CST when IMS 1964 // connected to CST 1965 return true; 1966 } 1967 return !cellularAvailable; 1968 } 1969 1970 private class EvaluatorEventHandler extends Handler { EvaluatorEventHandler(Looper l)1971 EvaluatorEventHandler(Looper l) { 1972 super(l); 1973 } 1974 1975 @Override handleMessage(Message message)1976 public void handleMessage(Message message) { 1977 log("handleMessage msg=" + message.what); 1978 QnsAsyncResult ar = (QnsAsyncResult) message.obj; 1979 switch (message.what) { 1980 case EVENT_IWLAN_NETWORK_STATUS_CHANGED: 1981 onIwlanNetworkStatusChanged((IwlanAvailabilityInfo) ar.mResult); 1982 break; 1983 case EVENT_QNS_TELEPHONY_INFO_CHANGED: 1984 onQnsTelephonyInfoChanged((QnsTelephonyListener.QnsTelephonyInfo) ar.mResult); 1985 break; 1986 case EVENT_RESTRICT_INFO_CHANGED: 1987 onRestrictInfoChanged(); 1988 break; 1989 case EVENT_SET_CALL_TYPE: 1990 onSetCallType((int) ar.mResult); 1991 break; 1992 case EVENT_DATA_CONNECTION_STATE_CHANGED: 1993 onDataConnectionStateChanged( 1994 (DataConnectionStatusTracker.DataConnectionChangedInfo) ar.mResult); 1995 break; 1996 case EVENT_PROVISIONING_INFO_CHANGED: 1997 onProvisioningInfoChanged( 1998 (QnsProvisioningListener.QnsProvisioningInfo) ar.mResult); 1999 break; 2000 case EVENT_IMS_REGISTRATION_STATE_CHANGED: 2001 onImsRegStateChanged((QnsImsManager.ImsRegistrationState) ar.mResult); 2002 break; 2003 case EVENT_SIP_DIALOG_SESSION_STATE_CHANGED: 2004 onSipDialogSessionStateChanged((boolean) ar.mResult); 2005 break; 2006 case EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED: 2007 onImsCallDisconnectCauseChanged((ImsReasonInfo) ar.mResult); 2008 break; 2009 case QnsEventDispatcher.QNS_EVENT_WFC_ENABLED: 2010 onWfcEnabledChanged(true, false); 2011 break; 2012 case QnsEventDispatcher.QNS_EVENT_WFC_DISABLED: 2013 onWfcEnabledChanged(false, false); 2014 break; 2015 case QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY: 2016 onWfcModeChanged(QnsConstants.WIFI_ONLY, false); 2017 break; 2018 case QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_CELLULAR_PREFERRED: 2019 onWfcModeChanged(QnsConstants.CELL_PREF, false); 2020 break; 2021 case QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_PREFERRED: 2022 onWfcModeChanged(QnsConstants.WIFI_PREF, false); 2023 break; 2024 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED: 2025 onWfcEnabledChanged(true, true); 2026 break; 2027 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_DISABLED: 2028 onWfcEnabledChanged(false, true); 2029 break; 2030 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_ONLY: 2031 onWfcModeChanged(QnsConstants.WIFI_ONLY, true); 2032 break; 2033 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_CELLULAR_PREFERRED: 2034 onWfcModeChanged(QnsConstants.CELL_PREF, true); 2035 break; 2036 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_PREFERRED: 2037 onWfcModeChanged(QnsConstants.WIFI_PREF, true); 2038 break; 2039 case QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_ENABLED: 2040 onWfcPlatformChanged(true); 2041 break; 2042 case QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_DISABLED: 2043 onWfcPlatformChanged(false); 2044 break; 2045 case QnsEventDispatcher.QNS_EVENT_SIM_ABSENT: 2046 onSimAbsent(); 2047 break; 2048 case EVENT_WIFI_RTT_STATUS_CHANGED: 2049 onRttStatusChanged((boolean) ar.mResult); 2050 break; 2051 case QnsEventDispatcher.QNS_EVENT_TRY_WFC_ACTIVATION: 2052 onTryWfcConnectionStateChanged(true); 2053 break; 2054 case QnsEventDispatcher.QNS_EVENT_CANCEL_TRY_WFC_ACTIVATION: 2055 onTryWfcConnectionStateChanged(false); 2056 break; 2057 default: 2058 log("never reach here msg=" + message.what); 2059 } 2060 } 2061 } 2062 2063 private class ThresholdListener extends ThresholdCallback 2064 implements ThresholdCallback.WifiThresholdListener, 2065 ThresholdCallback.CellularThresholdListener { 2066 ThresholdListener(Executor executor)2067 ThresholdListener(Executor executor) { 2068 this.init(executor); 2069 } 2070 2071 @Override onWifiThresholdChanged(Threshold[] thresholds)2072 public void onWifiThresholdChanged(Threshold[] thresholds) { 2073 onWiFiQualityChanged(thresholds); 2074 } 2075 2076 @Override onCellularThresholdChanged(Threshold[] thresholds)2077 public void onCellularThresholdChanged(Threshold[] thresholds) { 2078 onCellularQualityChanged(thresholds); 2079 } 2080 } 2081 2082 /** 2083 * Dumps the state of {@link QualityMonitor} 2084 * 2085 * @param pw {@link PrintWriter} to write the state of the object. 2086 * @param prefix String to append at start of dumped log. 2087 */ dump(PrintWriter pw, String prefix)2088 void dump(PrintWriter pw, String prefix) { 2089 pw.println(prefix + "------------------------------"); 2090 pw.println( 2091 prefix 2092 + "ANE[" 2093 + QnsUtils.getNameOfNetCapability(mNetCapability) 2094 + "_" 2095 + mSlotIndex 2096 + "]:"); 2097 pw.println(prefix + "mInitialized=" + mInitialized); 2098 pw.println( 2099 prefix 2100 + "mQualifiedNetworksChangedRegistrant size=" 2101 + mQualifiedNetworksChangedRegistrants.size()); 2102 pw.println( 2103 prefix 2104 + "mCellularAccessNetworkType=" 2105 + QnsConstants.accessNetworkTypeToString(mCellularAccessNetworkType) 2106 + ", mLatestAvailableCellularAccessNetwork=" 2107 + QnsConstants.accessNetworkTypeToString( 2108 mLatestAvailableCellularAccessNetwork) 2109 + ", mIsNotifiedLastQualifiedAccessNetworkTypes=" 2110 + mIsNotifiedLastQualifiedAccessNetworkTypes); 2111 pw.print(prefix + "mLastQualifiedAccessNetworkTypes="); 2112 mLastQualifiedAccessNetworkTypes.forEach( 2113 accessNetwork -> 2114 pw.print(QnsConstants.accessNetworkTypeToString(accessNetwork) + "|")); 2115 pw.println( 2116 ", mIsNotifiedLastQualifiedAccessNetworkTypes=" 2117 + mIsNotifiedLastQualifiedAccessNetworkTypes); 2118 pw.println( 2119 prefix 2120 + "mCellularAvailable=" 2121 + mCellularAvailable 2122 + ", mIwlanAvailable=" 2123 + mIwlanAvailable 2124 + ", mIsCrossWfc=" 2125 + QnsConstants.callTypeToString(mCallType) 2126 + ", mCoverage" 2127 + QnsConstants.coverageToString(mCoverage)); 2128 pw.println( 2129 prefix 2130 + "mWfcPlatformEnabled=" 2131 + mWfcPlatformEnabled 2132 + ", mSettingWfcEnabled=" 2133 + mSettingWfcEnabled 2134 + ", mSettingWfcMode=" 2135 + QnsConstants.preferenceToString(mSettingWfcMode) 2136 + ", mSettingWfcRoamingEnabled=" 2137 + mSettingWfcRoamingEnabled 2138 + ", mSettingWfcRoamingMode=" 2139 + QnsConstants.preferenceToString(mSettingWfcRoamingMode) 2140 + ", mAllowIwlanForWfcActivation=" 2141 + mAllowIwlanForWfcActivation); 2142 pw.println(prefix + "mLastProvisioningInfo=" + mLastProvisioningInfo); 2143 pw.println(prefix + "mAccessNetworkSelectionPolicies=" + mAccessNetworkSelectionPolicies); 2144 pw.println(prefix + "mAnspPolicyMap=" + mAnspPolicyMap); 2145 pw.println(prefix + "mCachedTransportTypeForEmergencyInitialConnect" 2146 + mCachedTransportTypeForEmergencyInitialConnect); 2147 mRestrictManager.dump(pw, prefix + " "); 2148 } 2149 2150 @VisibleForTesting getSipDialogSessionState()2151 boolean getSipDialogSessionState() { 2152 return mSipDialogSessionState; 2153 } 2154 sendMetricsForQualifiedNetworks(QualifiedNetworksInfo info)2155 private void sendMetricsForQualifiedNetworks(QualifiedNetworksInfo info) { 2156 if (!mCellularAvailable 2157 || !mIwlanAvailable 2158 || mCellularAccessNetworkType == AccessNetworkType.UNKNOWN 2159 || mLastEvaluateSpecificReason == EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED) { 2160 // b/268557926, decided to cut off if WWAN and WLAN are not in contention. 2161 return; 2162 } 2163 mQnsMetrics.reportAtomForQualifiedNetworks( 2164 info, 2165 mSlotIndex, 2166 mDataConnectionStatusTracker.getLastTransportType(), 2167 mCoverage, 2168 mSettingWfcEnabled, 2169 mSettingWfcRoamingEnabled, 2170 mSettingWfcMode, 2171 mSettingWfcRoamingMode, 2172 mCellularAccessNetworkType, 2173 mIwlanAvailable, 2174 mIsCrossWfc, 2175 mRestrictManager, 2176 mCellularQualityMonitor, 2177 mWifiQualityMonitor, 2178 mCallType); 2179 } 2180 sendMetricsForCallTypeChanged(int oldCallType, int newCallType)2181 private void sendMetricsForCallTypeChanged(int oldCallType, int newCallType) { 2182 int transportTypeOfCall = mDataConnectionStatusTracker.getLastTransportType(); 2183 mQnsMetrics.reportAtomForCallTypeChanged(mNetCapability, mSlotIndex, 2184 oldCallType, newCallType, mRestrictManager, transportTypeOfCall); 2185 } 2186 sendMetricsForDataConnectionChanged( DataConnectionStatusTracker.DataConnectionChangedInfo info)2187 private void sendMetricsForDataConnectionChanged( 2188 DataConnectionStatusTracker.DataConnectionChangedInfo info) { 2189 mQnsMetrics.reportAtomForDataConnectionChanged( 2190 mNetCapability, mSlotIndex, info, mConfigManager.getCarrierId()); 2191 } 2192 sendMetricsForImsCallDropStats()2193 private void sendMetricsForImsCallDropStats() { 2194 int transportTypeOfCall = mDataConnectionStatusTracker.getLastTransportType(); 2195 mQnsMetrics.reportAtomForImsCallDropStats(mNetCapability, mSlotIndex, mRestrictManager, 2196 mCellularQualityMonitor, mWifiQualityMonitor, transportTypeOfCall, 2197 mCellularAccessNetworkType); 2198 } 2199 2200 } 2201