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 if (mDataConnectionStatusTracker.isActiveState()) { 1255 /* Check handover policy */ 1256 if (isHandoverPolicyCheckAvailable()) { 1257 if (!moveTransportTypeAllowed()) { 1258 log("Handover is not allowed. Skip this evaluation."); 1259 return; 1260 } 1261 } else { 1262 if (specificReason == EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE 1263 && !mCellularAvailable) { 1264 log("Allow evaluation without handover policy check"); 1265 } else { 1266 log("Handover policy check is not available. Skip this evaluation."); 1267 return; 1268 } 1269 } 1270 } 1271 1272 /* Check network Availability */ 1273 boolean isAllowedForIwlan = isAllowed(AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 1274 boolean isAllowedForCellular = isAllowed(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1275 boolean availabilityIwlan = 1276 isAllowedForIwlan 1277 && evaluateAvailability( 1278 AccessNetworkConstants.TRANSPORT_TYPE_WLAN, isAllowedForCellular); 1279 boolean availabilityCellular = 1280 isAllowedForCellular 1281 && evaluateAvailability( 1282 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, isAllowedForIwlan); 1283 log(" availability Iwlan:" + availabilityIwlan + " Cellular:" + availabilityCellular); 1284 1285 if (mWifiBackhaulMonitor.isRttCheckEnabled() 1286 && mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) { 1287 mWifiBackhaulMonitor.setCellularAvailable( 1288 availabilityCellular 1289 && isAccessNetworkAllowed(mCellularAccessNetworkType, mNetCapability)); 1290 } 1291 // QualifiedNetworksService checks AccessNetworkSelectionPolicy only in the case both 1292 // networks(cellular and iwlan) are available. If only one network is available, no 1293 // evaluation is run. Available network of accessNetworkType will be reported immediately. 1294 if (availabilityIwlan && availabilityCellular) { 1295 updateAccessNetworkSelectionPolicy(); 1296 List<Integer> accessNetworkTypes = 1297 evaluateAccessNetworkSelectionPolicy(availabilityIwlan, availabilityCellular); 1298 reportSatisfiedAccessNetworkTypesByState(accessNetworkTypes, true); 1299 reevaluateLastNotifiedSecondAccessNetwork(); 1300 } else if (availabilityIwlan) { 1301 updateAccessNetworkSelectionPolicy(); 1302 if (!mIsCrossWfc && hasWifiThresholdWithoutCellularCondition()) { 1303 List<Integer> accessNetworkTypes = 1304 evaluateAccessNetworkSelectionPolicy( 1305 availabilityIwlan, availabilityCellular); 1306 reportSatisfiedAccessNetworkTypesByState(accessNetworkTypes, true); 1307 } else { 1308 reportSatisfiedAccessNetworkTypesByState(List.of(AccessNetworkType.IWLAN), false); 1309 } 1310 } else if (availabilityCellular) { 1311 reportSatisfiedAccessNetworkTypesByState( 1312 new ArrayList<>(List.of(mCellularAccessNetworkType)), false); 1313 } else { 1314 // TODO Is it better to report to cellular when there is nothing? 1315 log("evaluate nothing without an available network."); 1316 if (specificReason == EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE) { 1317 reportQualifiedNetwork(getInitialAccessNetworkTypes()); 1318 } 1319 } 1320 } 1321 1322 @VisibleForTesting vopsCheckRequired(int cellularAccessNetworkType, int coverage, int callType)1323 boolean vopsCheckRequired(int cellularAccessNetworkType, int coverage, int callType) { 1324 boolean checkVoPs = false; 1325 if (mConfigManager.isMmtelCapabilityRequired(coverage) 1326 && (cellularAccessNetworkType == AccessNetworkType.EUTRAN 1327 || cellularAccessNetworkType == AccessNetworkType.NGRAN)) { 1328 if (mDataConnectionStatusTracker.isInactiveState()) { 1329 checkVoPs = true; 1330 } else if (mDataConnectionStatusTracker.getLastTransportType() 1331 == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1332 if (callType == QnsConstants.CALL_TYPE_IDLE 1333 || !mConfigManager.isInCallHoDecisionWlanToWwanWithoutVopsCondition()) { 1334 checkVoPs = true; 1335 } 1336 } else if (mDataConnectionStatusTracker.getLastTransportType() 1337 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 1338 // If there is an on-going call and UE is moving into an area which does not support 1339 // VoPS, don't consider VoPS condition and let AccessNetworkEvaluator decide a 1340 // preferred RAT. 1341 if (callType == QnsConstants.CALL_TYPE_IDLE) { 1342 checkVoPs = true; 1343 } 1344 } 1345 } 1346 return checkVoPs; 1347 } 1348 hasWifiThresholdWithoutCellularCondition()1349 private boolean hasWifiThresholdWithoutCellularCondition() { 1350 if (mAccessNetworkSelectionPolicies == null || mAccessNetworkSelectionPolicies.isEmpty()) { 1351 return false; 1352 } 1353 for (AccessNetworkSelectionPolicy policy : mAccessNetworkSelectionPolicies) { 1354 if (policy.hasWifiThresholdWithoutCellularCondition()) { 1355 return true; 1356 } 1357 } 1358 return false; 1359 } 1360 reportSatisfiedAccessNetworkTypesByState( List<Integer> satisfiedAccessNetworkTypes, boolean needMonitor)1361 protected synchronized void reportSatisfiedAccessNetworkTypesByState( 1362 List<Integer> satisfiedAccessNetworkTypes, boolean needMonitor) { 1363 if (needMonitor) { 1364 if (mDataConnectionStatusTracker.isInactiveState()) { 1365 if (satisfiedAccessNetworkTypes.size() > 0) { 1366 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1367 updateAccessNetworkSelectionPolicy(); 1368 } 1369 updateQualityMonitor(); 1370 } else if (!mDataConnectionStatusTracker.isConnectionInProgress()) { 1371 if (isHandoverNeeded(satisfiedAccessNetworkTypes)) { 1372 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1373 unregisterThresholdToQualityMonitor(); 1374 } else if (isFallbackCase(satisfiedAccessNetworkTypes)) { 1375 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1376 updateAccessNetworkSelectionPolicy(); 1377 updateQualityMonitor(); 1378 } else { 1379 updateQualityMonitor(); 1380 } 1381 } 1382 } else { 1383 if (mDataConnectionStatusTracker.isInactiveState()) { 1384 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1385 } else if (!mDataConnectionStatusTracker.isConnectionInProgress()) { 1386 if (isHandoverNeeded(satisfiedAccessNetworkTypes)) { 1387 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1388 } else if (isFallbackCase(satisfiedAccessNetworkTypes)) { 1389 reportQualifiedNetwork(satisfiedAccessNetworkTypes); 1390 } 1391 } 1392 unregisterThresholdToQualityMonitor(); 1393 } 1394 } 1395 getTargetTransportType(List<Integer> accessNetworkTypes)1396 protected int getTargetTransportType(List<Integer> accessNetworkTypes) { 1397 if (accessNetworkTypes == null || accessNetworkTypes.size() == 0) { 1398 return AccessNetworkConstants.TRANSPORT_TYPE_INVALID; 1399 } 1400 if (accessNetworkTypes.get(0) == AccessNetworkType.IWLAN) { 1401 return AccessNetworkConstants.TRANSPORT_TYPE_WLAN; 1402 } 1403 return AccessNetworkConstants.TRANSPORT_TYPE_WWAN; 1404 } 1405 1406 @VisibleForTesting isHandoverPolicyCheckAvailable()1407 boolean isHandoverPolicyCheckAvailable() { 1408 if (mDataConnectionStatusTracker.isActiveState()) { 1409 int srcTransportType = mDataConnectionStatusTracker.getLastTransportType(); 1410 boolean targetNetworkAvailable = 1411 srcTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1412 ? mCellularAvailable 1413 : mIwlanAvailable; 1414 if (srcTransportType == getLastQualifiedTransportType() && targetNetworkAvailable) { 1415 log(" handover policy check is available for this evaluation."); 1416 return true; 1417 } 1418 } 1419 log("handover policy check is not available for this evaluation."); 1420 return false; 1421 } 1422 1423 @VisibleForTesting moveTransportTypeAllowed()1424 boolean moveTransportTypeAllowed() { 1425 int srcAccessNetwork = 1426 mDataConnectionStatusTracker.getLastTransportType() 1427 == AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1428 ? AccessNetworkType.IWLAN 1429 : mLatestAvailableCellularAccessNetwork; 1430 int dstAccessNetwork = 1431 srcAccessNetwork == AccessNetworkType.IWLAN 1432 ? mCellularAccessNetworkType 1433 : AccessNetworkType.IWLAN; 1434 if (mConfigManager.isHandoverAllowedByPolicy( 1435 mNetCapability, srcAccessNetwork, dstAccessNetwork, mCoverage)) { 1436 return true; 1437 } else { 1438 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 1439 && mCallStatusTracker.isCallIdle(NetworkCapabilities.NET_CAPABILITY_IMS)) { 1440 // Telephony will make new connection with preferred AccessNetwork 1441 log("handover is not allowed. but need to move to target Transport."); 1442 return true; 1443 } 1444 if (dstAccessNetwork == AccessNetworkType.IWLAN && useDifferentApnOverIwlan()) { 1445 // Telephony will make new connection when change transport type 1446 log( 1447 "handover is not allowed. but need to move to target Transport using" 1448 + " different apn over IWLAN."); 1449 return true; 1450 } 1451 if (dstAccessNetwork != AccessNetworkType.IWLAN 1452 && mCellularAvailable 1453 && mConfigManager.getRatPreference(mNetCapability) 1454 == QnsConstants.RAT_PREFERENCE_WIFI_WHEN_NO_CELLULAR) { 1455 // Telephony will make new connection when change transport type 1456 log( 1457 "handover is not allowed. but need to move to target Transport for the" 1458 + " RAT_PREFERENCE_WIFI_WHEN_NO_CELLULAR."); 1459 return true; 1460 } 1461 } 1462 return false; 1463 } 1464 useDifferentApnOverIwlan()1465 private boolean useDifferentApnOverIwlan() { 1466 // supports MMS, XCAP and CBS 1467 if (mNetCapability != NetworkCapabilities.NET_CAPABILITY_MMS 1468 && mNetCapability != NetworkCapabilities.NET_CAPABILITY_XCAP 1469 && mNetCapability != NetworkCapabilities.NET_CAPABILITY_CBS) { 1470 return false; 1471 } 1472 1473 ApnSetting apnSetting = 1474 mDataConnectionStatusTracker.getLastApnSetting( 1475 AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 1476 if (apnSetting != null 1477 && (apnSetting.getApnTypeBitmask() & ApnSetting.TYPE_DEFAULT) != 0 1478 && (apnSetting.getNetworkTypeBitmask() 1479 & (1 << (TelephonyManager.NETWORK_TYPE_IWLAN - 1))) 1480 == 0) { 1481 log("useDifferentApnOverIwlan true"); 1482 return true; 1483 } 1484 log("useDifferentApnOverIwlan false"); 1485 return false; 1486 } 1487 isHandoverNeeded(List<Integer> accessNetworkTypes)1488 protected boolean isHandoverNeeded(List<Integer> accessNetworkTypes) { 1489 if (mDataConnectionStatusTracker.isInactiveState() 1490 || mDataConnectionStatusTracker.isHandoverState()) { 1491 return false; 1492 } 1493 1494 int targetTransportType = getTargetTransportType(accessNetworkTypes); 1495 if (targetTransportType == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) { 1496 return false; 1497 } 1498 1499 // Handover case 1500 int sourceTransportType = mDataConnectionStatusTracker.getLastTransportType(); 1501 return sourceTransportType != targetTransportType; 1502 } 1503 isFallbackCase(List<Integer> accessNetworkTypes)1504 protected boolean isFallbackCase(List<Integer> accessNetworkTypes) { 1505 if (mDataConnectionStatusTracker.isInactiveState()) { 1506 return false; 1507 } 1508 1509 int targetTransportType = getTargetTransportType(accessNetworkTypes); 1510 if (targetTransportType == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) { 1511 return false; 1512 } 1513 if (targetTransportType != mDataConnectionStatusTracker.getLastTransportType()) { 1514 return false; 1515 } 1516 1517 if (getLastQualifiedTransportType() == targetTransportType) { 1518 return false; 1519 } 1520 1521 log("isFallbackcase:true"); 1522 return true; 1523 } 1524 reportQualifiedNetwork(List<Integer> accessNetworkTypes)1525 protected void reportQualifiedNetwork(List<Integer> accessNetworkTypes) { 1526 if (accessNetworkTypes.contains(AccessNetworkType.UNKNOWN)) { 1527 log( 1528 "reportQualifiedNetwork, remove UNKNOWN access network." 1529 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1530 accessNetworkTypes.remove(AccessNetworkType.UNKNOWN); 1531 } 1532 List<Integer> supportAccessNetworkTypes = new ArrayList<>(); 1533 if (mConfigManager.allowImsOverIwlanCellularLimitedCase()) { 1534 for (Integer accessNetwork : accessNetworkTypes) { 1535 if (accessNetwork == AccessNetworkType.IWLAN 1536 || isAccessNetworkAllowed(accessNetwork, mNetCapability)) { 1537 supportAccessNetworkTypes.add(accessNetwork); 1538 } 1539 } 1540 if (!accessNetworkTypes.isEmpty() && supportAccessNetworkTypes.isEmpty()) { 1541 log("supportAccessNetworkTypes is empty"); 1542 return; 1543 } 1544 } else { 1545 supportAccessNetworkTypes.addAll(accessNetworkTypes); 1546 } 1547 1548 log( 1549 "reportQualifiedNetwork supportAccessNetworkTypes:" 1550 + QnsUtils.getStringAccessNetworkTypes(supportAccessNetworkTypes)); 1551 1552 if (equalsLastNotifiedQualifiedNetwork(supportAccessNetworkTypes)) { 1553 return; 1554 } else { 1555 if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS 1556 && mWifiBackhaulMonitor.isRttCheckEnabled()) { 1557 if (supportAccessNetworkTypes.contains(AccessNetworkType.IWLAN)) { 1558 if (!isRttSuccess()) { 1559 mWifiBackhaulMonitor.requestRttCheck(); 1560 return; 1561 } 1562 } else { 1563 mIsRttCheckSuccess = false; 1564 } 1565 } 1566 } 1567 1568 updateLastNotifiedQualifiedNetwork(supportAccessNetworkTypes); 1569 notifyForQualifiedNetworksChanged(supportAccessNetworkTypes); 1570 } 1571 findUnmatchedThresholds()1572 private List<Threshold> findUnmatchedThresholds() { 1573 List<Threshold> unmatchedThresholds = new ArrayList<>(); 1574 if (mAccessNetworkSelectionPolicies == null 1575 || mAccessNetworkSelectionPolicies.size() == 0) { 1576 return unmatchedThresholds; 1577 } 1578 1579 List<Integer> excludeThresholdGroup = new ArrayList<>(); 1580 boolean bIwlanRegistrable = isIwlanAvailableWithoutRestrict(); 1581 boolean bCellularRegistrable = isCellularAvailableWithoutRestrict(); 1582 for (AccessNetworkSelectionPolicy policy : mAccessNetworkSelectionPolicies) { 1583 List<Threshold> policyUnmatchedThresholds = 1584 policy.findUnmatchedThresholds(mWifiQualityMonitor, mCellularQualityMonitor); 1585 if (policyUnmatchedThresholds == null || policyUnmatchedThresholds.size() == 0) { 1586 continue; 1587 } 1588 for (Threshold threshold : policyUnmatchedThresholds) { 1589 if (bIwlanRegistrable && threshold.getAccessNetwork() == AccessNetworkType.IWLAN) { 1590 unmatchedThresholds.add(threshold); 1591 } 1592 if (bCellularRegistrable 1593 && threshold.getAccessNetwork() != AccessNetworkType.IWLAN) { 1594 if (threshold.getAccessNetwork() == mCellularAccessNetworkType) { 1595 unmatchedThresholds.add(threshold); 1596 } else if (threshold.getGroupId() >= 0) { 1597 // If the current cellular access network and the access network of 1598 // cellular threshold are different, it is not necessary to monitor the 1599 // entire threshold of this group. 1600 excludeThresholdGroup.add(threshold.getGroupId()); 1601 } 1602 } 1603 } 1604 } 1605 for (int excludeGid : excludeThresholdGroup) { 1606 unmatchedThresholds.removeIf(threshold -> threshold.getGroupId() == excludeGid); 1607 } 1608 return unmatchedThresholds; 1609 } 1610 updateQualityMonitor()1611 private void updateQualityMonitor() { 1612 List<Threshold> unmatchedThresholds = findUnmatchedThresholds(); 1613 if (unmatchedThresholds.size() == 0) { 1614 log("updateQualityMonitor empty unmatchedThresholds."); 1615 unregisterThresholdToQualityMonitor(); 1616 return; 1617 } 1618 1619 log("updateQualityMonitor"); 1620 1621 LinkedHashSet<Integer> unmatchedGroupIdSet = new LinkedHashSet<>(); 1622 HashMap<Integer, Integer> unmatchedMonitorTypeMap = new HashMap<>(); 1623 LinkedHashSet<Integer> unmatchedMonitorTypeSet = new LinkedHashSet<>(); 1624 for (Threshold th : unmatchedThresholds) { 1625 if (th.getGroupId() < 0) { 1626 continue; 1627 } 1628 unmatchedGroupIdSet.add(th.getGroupId()); 1629 int key = th.getAccessNetwork() << 16 | th.getMeasurementType(); 1630 unmatchedMonitorTypeMap.put(key, unmatchedMonitorTypeMap.getOrDefault(key, 0) + 1); 1631 } 1632 1633 List<Map.Entry<Integer, Integer>> list_entries = 1634 new ArrayList<>(unmatchedMonitorTypeMap.entrySet()); 1635 list_entries.sort(Entry.comparingByValue()); 1636 for (Entry<Integer, Integer> entry : list_entries) { 1637 unmatchedMonitorTypeSet.add(entry.getKey()); 1638 } 1639 1640 LinkedHashSet<Integer> reducedGroupIdSet = new LinkedHashSet<>(); 1641 for (int type : unmatchedMonitorTypeSet) { 1642 reducedGroupIdSet.clear(); 1643 boolean skipReduce = false; 1644 for (Threshold th : unmatchedThresholds) { 1645 if (type == (th.getAccessNetwork() << 16 | th.getMeasurementType())) { 1646 if (th.getGroupId() < 0) { 1647 skipReduce = true; 1648 break; 1649 } 1650 } else { 1651 reducedGroupIdSet.add(th.getGroupId()); 1652 } 1653 } 1654 if (skipReduce) { 1655 continue; 1656 } 1657 1658 if (reducedGroupIdSet.containsAll(unmatchedGroupIdSet)) { 1659 unmatchedThresholds.removeIf( 1660 threshold -> 1661 type 1662 == (threshold.getAccessNetwork() << 16 1663 | threshold.getMeasurementType())); 1664 } 1665 } 1666 1667 registerThresholdsToQualityMonitor(unmatchedThresholds); 1668 } 1669 unregisterThresholdToQualityMonitor()1670 private void unregisterThresholdToQualityMonitor() { 1671 mWifiQualityMonitor.updateThresholdsForNetCapability(mNetCapability, mSlotIndex, null); 1672 mCellularQualityMonitor.updateThresholdsForNetCapability(mNetCapability, mSlotIndex, null); 1673 } 1674 registerThresholdsToQualityMonitor(List<Threshold> thresholds)1675 private void registerThresholdsToQualityMonitor(List<Threshold> thresholds) { 1676 if (thresholds == null) { 1677 thresholds = new ArrayList<>(); 1678 } 1679 1680 List<Threshold> monitorWiFiThresholds = new ArrayList<>(); 1681 List<Threshold> monitorCellThresholds = new ArrayList<>(); 1682 for (Threshold th : thresholds) { 1683 if (th.getAccessNetwork() == AccessNetworkType.IWLAN) { 1684 monitorWiFiThresholds.add(th); 1685 } else { 1686 monitorCellThresholds.add(th); 1687 } 1688 } 1689 1690 for (Threshold th : monitorWiFiThresholds) { 1691 log(" monitorWiFiThresholds th:" + th.toShortString()); 1692 } 1693 for (Threshold th : monitorCellThresholds) { 1694 log(" monitorCellThresholds th:" + th.toShortString()); 1695 } 1696 1697 // refresh threshold to be monitored. 1698 mWifiQualityMonitor.updateThresholdsForNetCapability( 1699 mNetCapability, mSlotIndex, monitorWiFiThresholds.toArray(new Threshold[0])); 1700 mCellularQualityMonitor.updateThresholdsForNetCapability( 1701 mNetCapability, mSlotIndex, monitorCellThresholds.toArray(new Threshold[0])); 1702 } 1703 updateThrottleStatus( boolean isThrottle, long throttleTimeMillis, int transportType)1704 protected void updateThrottleStatus( 1705 boolean isThrottle, long throttleTimeMillis, int transportType) { 1706 mRestrictManager.notifyThrottling(isThrottle, throttleTimeMillis, transportType); 1707 } 1708 getPreferredMode()1709 protected int getPreferredMode() { 1710 if (mAllowIwlanForWfcActivation) { 1711 return QnsConstants.WIFI_PREF; 1712 } 1713 if (mCoverage == QnsConstants.COVERAGE_ROAM) { 1714 return mSettingWfcRoamingMode; 1715 } 1716 return mSettingWfcMode; 1717 } 1718 getPreferredAccessNetwork()1719 private int getPreferredAccessNetwork() { 1720 switch (getPreferredMode()) { 1721 case QnsConstants.CELL_PREF: 1722 return mCellularAccessNetworkType; 1723 case QnsConstants.WIFI_PREF: 1724 case QnsConstants.WIFI_ONLY: 1725 return AccessNetworkType.IWLAN; 1726 } 1727 return mCellularAccessNetworkType; 1728 } 1729 isRttSuccess()1730 private boolean isRttSuccess() { 1731 return !isAccessNetworkAllowed( 1732 mCellularAccessNetworkType, NetworkCapabilities.NET_CAPABILITY_IMS) 1733 || mIsRttCheckSuccess; 1734 } 1735 evaluateAccessNetworkSelectionPolicy( boolean availabilityIwlan, boolean availabilityCellular)1736 private List<Integer> evaluateAccessNetworkSelectionPolicy( 1737 boolean availabilityIwlan, boolean availabilityCellular) { 1738 log("evaluateAccessNetworkSelectionPolicy"); 1739 1740 if (mAccessNetworkSelectionPolicies == null || mAccessNetworkSelectionPolicies.isEmpty()) { 1741 return new ArrayList<>(); 1742 } 1743 List<Integer> accessNetworkTypes = new ArrayList<>(); 1744 for (AccessNetworkSelectionPolicy policy : mAccessNetworkSelectionPolicies) { 1745 if (policy.satisfiedByThreshold( 1746 mWifiQualityMonitor, 1747 mCellularQualityMonitor, 1748 availabilityIwlan, 1749 availabilityCellular, 1750 mCellularAccessNetworkType)) { 1751 log( 1752 " satisfiedByThreshold TargetTransportType:" 1753 + QnsConstants.transportTypeToString( 1754 policy.getTargetTransportType())); 1755 if (policy.getTargetTransportType() == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1756 if (!accessNetworkTypes.contains(AccessNetworkType.IWLAN)) { 1757 accessNetworkTypes.add(AccessNetworkType.IWLAN); 1758 } 1759 1760 } else { 1761 if (!accessNetworkTypes.contains(mCellularAccessNetworkType)) { 1762 if (availabilityCellular) { 1763 accessNetworkTypes.add(mCellularAccessNetworkType); 1764 } else { 1765 accessNetworkTypes.add(AccessNetworkType.UNKNOWN); 1766 } 1767 } 1768 if ((mCallType == QnsConstants.CALL_TYPE_VOICE 1769 || mCallType == QnsConstants.CALL_TYPE_EMERGENCY) 1770 && policy.satisfiedWithWifiLowSignalStrength()) { 1771 int reason = mConfigManager.getQnsIwlanHoRestrictReason(); 1772 if (reason == QnsConstants.FALLBACK_REASON_RTP_OR_WIFI 1773 || reason == QnsConstants.FALLBACK_REASON_WIFI_ONLY) { 1774 log("WWAN decision with Wi-Fi low signalStrength in Voice call"); 1775 mRestrictManager.increaseCounterToRestrictIwlanInCall(); 1776 } 1777 } 1778 } 1779 } 1780 } 1781 1782 // If the evaluator has not yet reported a Qualified Networks, report preferred. 1783 if (!isNotifiedQualifiedAccessNetworkTypes()) { 1784 if (accessNetworkTypes.size() == 0) { 1785 accessNetworkTypes.add(getPreferredAccessNetwork()); 1786 log( 1787 " no candidate access network, use preferred:" 1788 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1789 } else if (accessNetworkTypes.size() > 1) { 1790 accessNetworkTypes.remove(Integer.valueOf(getPreferredAccessNetwork())); 1791 accessNetworkTypes.add(0, getPreferredAccessNetwork()); 1792 log( 1793 " two more candidate access network, use preferred:" 1794 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1795 } 1796 } 1797 1798 // TODO. need to be improved handling the second access network 1799 // Add a second access network, if the preferred access network does not exist in list. 1800 if (availabilityIwlan 1801 && availabilityCellular 1802 && mConfigManager.isOverrideImsPreferenceSupported()) { 1803 if (!accessNetworkTypes.isEmpty() 1804 && accessNetworkTypes.get(0) != AccessNetworkType.IWLAN 1805 && getPreferredMode() == QnsConstants.CELL_PREF 1806 && isAccessNetworkAllowed(accessNetworkTypes.get(0), mNetCapability)) { 1807 if (!accessNetworkTypes.contains(AccessNetworkType.IWLAN)) { 1808 accessNetworkTypes.add(AccessNetworkType.IWLAN); 1809 log( 1810 " add a second accessNetworkTypes : " 1811 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1812 } 1813 } else if (accessNetworkTypes.isEmpty() 1814 && !mLastQualifiedAccessNetworkTypes.isEmpty() 1815 && mLastQualifiedAccessNetworkTypes.get(0) != AccessNetworkType.IWLAN 1816 && getPreferredMode() == QnsConstants.CELL_PREF 1817 && isAccessNetworkAllowed( 1818 mLastQualifiedAccessNetworkTypes.get(0), mNetCapability)) { 1819 if (!mLastQualifiedAccessNetworkTypes.contains(AccessNetworkType.IWLAN)) { 1820 accessNetworkTypes.addAll(mLastQualifiedAccessNetworkTypes); 1821 accessNetworkTypes.add(AccessNetworkType.IWLAN); 1822 log( 1823 " add a second accessNetworkTypes in existing " 1824 + "mLastQualifiedAccessNetworkTypes : " 1825 + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1826 } 1827 } 1828 } 1829 1830 log(" accessNetworkTypes:" + QnsUtils.getStringAccessNetworkTypes(accessNetworkTypes)); 1831 return accessNetworkTypes; 1832 } 1833 1834 // TODO. need to be improved handling the second access network 1835 // A qualified conditions are required for the second access network. 1836 // What threshold conditions are qualified for the second access network? (like rove in) 1837 // What are the threshold conditions for exiting the second access network? (like a rove out) reevaluateLastNotifiedSecondAccessNetwork()1838 private void reevaluateLastNotifiedSecondAccessNetwork() { 1839 if (mConfigManager.isOverrideImsPreferenceSupported() 1840 && mLastQualifiedAccessNetworkTypes.size() > 1 1841 && mLastQualifiedAccessNetworkTypes.get(1) == AccessNetworkType.IWLAN) { 1842 if (!isAccessNetworkAllowed(mCellularAccessNetworkType, mNetCapability) 1843 || getPreferredMode() != QnsConstants.CELL_PREF) { 1844 log("reevaluateLastNotifiedSecondAccessNetwork, Removed a second access network"); 1845 reportQualifiedNetwork( 1846 new ArrayList<>(List.of(mLastQualifiedAccessNetworkTypes.get(0)))); 1847 } 1848 } 1849 } 1850 buildAccessNetworkSelectionPolicy( boolean bForceUpdate)1851 private Map<PreCondition, List<AccessNetworkSelectionPolicy>> buildAccessNetworkSelectionPolicy( 1852 boolean bForceUpdate) { 1853 if (mAnspPolicyMap == null || bForceUpdate) { 1854 log("Building list of AccessNetworkSelectionPolicy."); 1855 mAnspPolicyMap = 1856 AccessNetworkSelectionPolicyBuilder.build(mConfigManager, mNetCapability); 1857 1858 if (DBG) { 1859 mAnspPolicyMap 1860 .values() 1861 .forEach( 1862 list -> 1863 list.stream() 1864 .map(policy -> " retriMap ANSP=" + policy) 1865 .forEach(this::log)); 1866 } 1867 } 1868 return mAnspPolicyMap; 1869 } 1870 updateAccessNetworkSelectionPolicy()1871 private void updateAccessNetworkSelectionPolicy() { 1872 Map<PreCondition, List<AccessNetworkSelectionPolicy>> map = 1873 buildAccessNetworkSelectionPolicy(false); 1874 if (map == null) { 1875 map = new HashMap<>(); 1876 } 1877 1878 log("Create a list of AccessNetworkSelectionPolicy that match the preconditions."); 1879 1880 PreCondition preCondition = getMatchingPreCondition(); 1881 List<AccessNetworkSelectionPolicy> matchedPolicies = new ArrayList<>(); 1882 List<AccessNetworkSelectionPolicy> list = map.get(preCondition); 1883 if (list != null) { 1884 for (AccessNetworkSelectionPolicy policy : list) { 1885 if (policy.satisfyPrecondition(preCondition) 1886 && !mDataConnectionStatusTracker.isConnectionInProgress() 1887 && (!isNotifiedQualifiedAccessNetworkTypes() 1888 || getLastQualifiedTransportType() 1889 != policy.getTargetTransportType())) { 1890 matchedPolicies.add(policy); 1891 } 1892 } 1893 } 1894 1895 if (mAccessNetworkSelectionPolicies.equals(matchedPolicies)) { 1896 for (AccessNetworkSelectionPolicy policy : matchedPolicies) { 1897 log(" Matched ANSP=" + policy); 1898 } 1899 } 1900 1901 for (AccessNetworkSelectionPolicy policy : matchedPolicies) { 1902 log(" Found new ANSP=" + policy); 1903 } 1904 1905 mAccessNetworkSelectionPolicies = matchedPolicies; 1906 } 1907 getMatchingPreCondition()1908 private PreCondition getMatchingPreCondition() { 1909 int callType = mCallType; 1910 if ((mNetCapability == NetworkCapabilities.NET_CAPABILITY_EIMS 1911 || mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) 1912 && mCallType == QnsConstants.CALL_TYPE_EMERGENCY) { 1913 callType = QnsConstants.CALL_TYPE_VOICE; 1914 } 1915 int sipDialogPolicy = mConfigManager.getSipDialogSessionPolicy(); 1916 if (callType == QnsConstants.CALL_TYPE_IDLE && mSipDialogSessionState) { 1917 if (sipDialogPolicy > QnsConstants.SIP_DIALOG_SESSION_POLICY_NONE) { 1918 log("apply sipDialogPolicy:" 1919 + QnsConstants.qnsSipDialogSessionPolicyToString(sipDialogPolicy)); 1920 } 1921 switch (sipDialogPolicy) { 1922 case QnsConstants.SIP_DIALOG_SESSION_POLICY_FOLLOW_VOICE_CALL: 1923 callType = QnsConstants.CALL_TYPE_VOICE; 1924 break; 1925 case QnsConstants.SIP_DIALOG_SESSION_POLICY_FOLLOW_VIDEO_CALL: 1926 callType = QnsConstants.CALL_TYPE_VIDEO; 1927 break; 1928 case QnsConstants.SIP_DIALOG_SESSION_POLICY_NONE: 1929 // fall-through 1930 default: 1931 // do-nothing 1932 break; 1933 } 1934 } 1935 1936 if (mConfigManager.hasThresholdGapWithGuardTimer()) { 1937 @QnsConstants.QnsGuarding int guarding = QnsConstants.GUARDING_NONE; 1938 int source = getLastQualifiedTransportType(); 1939 if (source != AccessNetworkConstants.TRANSPORT_TYPE_WLAN 1940 && mRestrictManager.hasRestrictionType( 1941 AccessNetworkConstants.TRANSPORT_TYPE_WLAN, 1942 RestrictManager.RESTRICT_TYPE_GUARDING)) { 1943 guarding = QnsConstants.GUARDING_WIFI; 1944 } else if (source != AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1945 && mRestrictManager.hasRestrictionType( 1946 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 1947 RestrictManager.RESTRICT_TYPE_GUARDING)) { 1948 guarding = QnsConstants.GUARDING_CELLULAR; 1949 } 1950 return new GuardingPreCondition(callType, getPreferredMode(), mCoverage, guarding); 1951 } 1952 return new PreCondition(callType, getPreferredMode(), mCoverage); 1953 } 1954 evaluateSpecificReasonToString(int specificReason)1955 private String evaluateSpecificReasonToString(int specificReason) { 1956 if (specificReason == EVALUATE_SPECIFIC_REASON_NONE) { 1957 return "EVALUATE_SPECIFIC_REASON_NONE"; 1958 } else if (specificReason == EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE) { 1959 return "EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE"; 1960 } else if (specificReason == EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED) { 1961 return "EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED"; 1962 } else if (specificReason == EVALUATE_SPECIFIC_REASON_DATA_FAILED) { 1963 return "EVALUATE_SPECIFIC_REASON_DATA_FAILED"; 1964 } else if (specificReason == EVALUATE_SPECIFIC_REASON_DATA_CONNECTED) { 1965 return "EVALUATE_SPECIFIC_REASON_DATA_CONNECTED"; 1966 } 1967 return "UNKNOWN"; 1968 } 1969 isCrossWfcAllowed(boolean cellularAvailable)1970 private boolean isCrossWfcAllowed(boolean cellularAvailable) { 1971 if (mConfigManager.getRatPreference(mNetCapability) 1972 == QnsConstants.RAT_PREFERENCE_WIFI_WHEN_WFC_AVAILABLE) { 1973 // Should follow RAT_PREFERENCE_WIFI_WHEN_WFC_AVAILABLE and do not block CST when IMS 1974 // connected to CST 1975 return true; 1976 } 1977 return !cellularAvailable; 1978 } 1979 1980 private class EvaluatorEventHandler extends Handler { EvaluatorEventHandler(Looper l)1981 EvaluatorEventHandler(Looper l) { 1982 super(l); 1983 } 1984 1985 @Override handleMessage(Message message)1986 public void handleMessage(Message message) { 1987 log("handleMessage msg=" + message.what); 1988 QnsAsyncResult ar = (QnsAsyncResult) message.obj; 1989 switch (message.what) { 1990 case EVENT_IWLAN_NETWORK_STATUS_CHANGED: 1991 onIwlanNetworkStatusChanged((IwlanAvailabilityInfo) ar.mResult); 1992 break; 1993 case EVENT_QNS_TELEPHONY_INFO_CHANGED: 1994 onQnsTelephonyInfoChanged((QnsTelephonyListener.QnsTelephonyInfo) ar.mResult); 1995 break; 1996 case EVENT_RESTRICT_INFO_CHANGED: 1997 onRestrictInfoChanged(); 1998 break; 1999 case EVENT_SET_CALL_TYPE: 2000 onSetCallType((int) ar.mResult); 2001 break; 2002 case EVENT_DATA_CONNECTION_STATE_CHANGED: 2003 onDataConnectionStateChanged( 2004 (DataConnectionStatusTracker.DataConnectionChangedInfo) ar.mResult); 2005 break; 2006 case EVENT_PROVISIONING_INFO_CHANGED: 2007 onProvisioningInfoChanged( 2008 (QnsProvisioningListener.QnsProvisioningInfo) ar.mResult); 2009 break; 2010 case EVENT_IMS_REGISTRATION_STATE_CHANGED: 2011 onImsRegStateChanged((QnsImsManager.ImsRegistrationState) ar.mResult); 2012 break; 2013 case EVENT_SIP_DIALOG_SESSION_STATE_CHANGED: 2014 onSipDialogSessionStateChanged((boolean) ar.mResult); 2015 break; 2016 case EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED: 2017 onImsCallDisconnectCauseChanged((ImsReasonInfo) ar.mResult); 2018 break; 2019 case QnsEventDispatcher.QNS_EVENT_WFC_ENABLED: 2020 onWfcEnabledChanged(true, false); 2021 break; 2022 case QnsEventDispatcher.QNS_EVENT_WFC_DISABLED: 2023 onWfcEnabledChanged(false, false); 2024 break; 2025 case QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_ONLY: 2026 onWfcModeChanged(QnsConstants.WIFI_ONLY, false); 2027 break; 2028 case QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_CELLULAR_PREFERRED: 2029 onWfcModeChanged(QnsConstants.CELL_PREF, false); 2030 break; 2031 case QnsEventDispatcher.QNS_EVENT_WFC_MODE_TO_WIFI_PREFERRED: 2032 onWfcModeChanged(QnsConstants.WIFI_PREF, false); 2033 break; 2034 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_ENABLED: 2035 onWfcEnabledChanged(true, true); 2036 break; 2037 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_DISABLED: 2038 onWfcEnabledChanged(false, true); 2039 break; 2040 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_ONLY: 2041 onWfcModeChanged(QnsConstants.WIFI_ONLY, true); 2042 break; 2043 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_CELLULAR_PREFERRED: 2044 onWfcModeChanged(QnsConstants.CELL_PREF, true); 2045 break; 2046 case QnsEventDispatcher.QNS_EVENT_WFC_ROAMING_MODE_TO_WIFI_PREFERRED: 2047 onWfcModeChanged(QnsConstants.WIFI_PREF, true); 2048 break; 2049 case QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_ENABLED: 2050 onWfcPlatformChanged(true); 2051 break; 2052 case QnsEventDispatcher.QNS_EVENT_WFC_PLATFORM_DISABLED: 2053 onWfcPlatformChanged(false); 2054 break; 2055 case QnsEventDispatcher.QNS_EVENT_SIM_ABSENT: 2056 onSimAbsent(); 2057 break; 2058 case EVENT_WIFI_RTT_STATUS_CHANGED: 2059 onRttStatusChanged((boolean) ar.mResult); 2060 break; 2061 case QnsEventDispatcher.QNS_EVENT_TRY_WFC_ACTIVATION: 2062 onTryWfcConnectionStateChanged(true); 2063 break; 2064 case QnsEventDispatcher.QNS_EVENT_CANCEL_TRY_WFC_ACTIVATION: 2065 onTryWfcConnectionStateChanged(false); 2066 break; 2067 default: 2068 log("never reach here msg=" + message.what); 2069 } 2070 } 2071 } 2072 2073 private class ThresholdListener extends ThresholdCallback 2074 implements ThresholdCallback.WifiThresholdListener, 2075 ThresholdCallback.CellularThresholdListener { 2076 ThresholdListener(Executor executor)2077 ThresholdListener(Executor executor) { 2078 this.init(executor); 2079 } 2080 2081 @Override onWifiThresholdChanged(Threshold[] thresholds)2082 public void onWifiThresholdChanged(Threshold[] thresholds) { 2083 onWiFiQualityChanged(thresholds); 2084 } 2085 2086 @Override onCellularThresholdChanged(Threshold[] thresholds)2087 public void onCellularThresholdChanged(Threshold[] thresholds) { 2088 onCellularQualityChanged(thresholds); 2089 } 2090 } 2091 2092 /** 2093 * Dumps the state of {@link QualityMonitor} 2094 * 2095 * @param pw {@link PrintWriter} to write the state of the object. 2096 * @param prefix String to append at start of dumped log. 2097 */ dump(PrintWriter pw, String prefix)2098 void dump(PrintWriter pw, String prefix) { 2099 pw.println(prefix + "------------------------------"); 2100 pw.println( 2101 prefix 2102 + "ANE[" 2103 + QnsUtils.getNameOfNetCapability(mNetCapability) 2104 + "_" 2105 + mSlotIndex 2106 + "]:"); 2107 pw.println(prefix + "mInitialized=" + mInitialized); 2108 pw.println( 2109 prefix 2110 + "mQualifiedNetworksChangedRegistrant size=" 2111 + mQualifiedNetworksChangedRegistrants.size()); 2112 pw.println( 2113 prefix 2114 + "mCellularAccessNetworkType=" 2115 + QnsConstants.accessNetworkTypeToString(mCellularAccessNetworkType) 2116 + ", mLatestAvailableCellularAccessNetwork=" 2117 + QnsConstants.accessNetworkTypeToString( 2118 mLatestAvailableCellularAccessNetwork) 2119 + ", mIsNotifiedLastQualifiedAccessNetworkTypes=" 2120 + mIsNotifiedLastQualifiedAccessNetworkTypes); 2121 pw.print(prefix + "mLastQualifiedAccessNetworkTypes="); 2122 mLastQualifiedAccessNetworkTypes.forEach( 2123 accessNetwork -> 2124 pw.print(QnsConstants.accessNetworkTypeToString(accessNetwork) + "|")); 2125 pw.println( 2126 ", mIsNotifiedLastQualifiedAccessNetworkTypes=" 2127 + mIsNotifiedLastQualifiedAccessNetworkTypes); 2128 pw.println( 2129 prefix 2130 + "mCellularAvailable=" 2131 + mCellularAvailable 2132 + ", mIwlanAvailable=" 2133 + mIwlanAvailable 2134 + ", mIsCrossWfc=" 2135 + QnsConstants.callTypeToString(mCallType) 2136 + ", mCoverage" 2137 + QnsConstants.coverageToString(mCoverage)); 2138 pw.println( 2139 prefix 2140 + "mWfcPlatformEnabled=" 2141 + mWfcPlatformEnabled 2142 + ", mSettingWfcEnabled=" 2143 + mSettingWfcEnabled 2144 + ", mSettingWfcMode=" 2145 + QnsConstants.preferenceToString(mSettingWfcMode) 2146 + ", mSettingWfcRoamingEnabled=" 2147 + mSettingWfcRoamingEnabled 2148 + ", mSettingWfcRoamingMode=" 2149 + QnsConstants.preferenceToString(mSettingWfcRoamingMode) 2150 + ", mAllowIwlanForWfcActivation=" 2151 + mAllowIwlanForWfcActivation); 2152 pw.println(prefix + "mLastProvisioningInfo=" + mLastProvisioningInfo); 2153 pw.println(prefix + "mAccessNetworkSelectionPolicies=" + mAccessNetworkSelectionPolicies); 2154 pw.println(prefix + "mAnspPolicyMap=" + mAnspPolicyMap); 2155 pw.println(prefix + "mCachedTransportTypeForEmergencyInitialConnect" 2156 + mCachedTransportTypeForEmergencyInitialConnect); 2157 mRestrictManager.dump(pw, prefix + " "); 2158 } 2159 2160 @VisibleForTesting getSipDialogSessionState()2161 boolean getSipDialogSessionState() { 2162 return mSipDialogSessionState; 2163 } 2164 sendMetricsForQualifiedNetworks(QualifiedNetworksInfo info)2165 private void sendMetricsForQualifiedNetworks(QualifiedNetworksInfo info) { 2166 if (!mCellularAvailable 2167 || !mIwlanAvailable 2168 || mCellularAccessNetworkType == AccessNetworkType.UNKNOWN 2169 || mLastEvaluateSpecificReason == EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED) { 2170 // b/268557926, decided to cut off if WWAN and WLAN are not in contention. 2171 return; 2172 } 2173 mQnsMetrics.reportAtomForQualifiedNetworks( 2174 info, 2175 mSlotIndex, 2176 mDataConnectionStatusTracker.getLastTransportType(), 2177 mCoverage, 2178 mSettingWfcEnabled, 2179 mSettingWfcRoamingEnabled, 2180 mSettingWfcMode, 2181 mSettingWfcRoamingMode, 2182 mCellularAccessNetworkType, 2183 mIwlanAvailable, 2184 mIsCrossWfc, 2185 mRestrictManager, 2186 mCellularQualityMonitor, 2187 mWifiQualityMonitor, 2188 mCallType); 2189 } 2190 sendMetricsForCallTypeChanged(int oldCallType, int newCallType)2191 private void sendMetricsForCallTypeChanged(int oldCallType, int newCallType) { 2192 int transportTypeOfCall = mDataConnectionStatusTracker.getLastTransportType(); 2193 mQnsMetrics.reportAtomForCallTypeChanged(mNetCapability, mSlotIndex, 2194 oldCallType, newCallType, mRestrictManager, transportTypeOfCall); 2195 } 2196 sendMetricsForDataConnectionChanged( DataConnectionStatusTracker.DataConnectionChangedInfo info)2197 private void sendMetricsForDataConnectionChanged( 2198 DataConnectionStatusTracker.DataConnectionChangedInfo info) { 2199 mQnsMetrics.reportAtomForDataConnectionChanged( 2200 mNetCapability, mSlotIndex, info, mConfigManager.getCarrierId()); 2201 } 2202 sendMetricsForImsCallDropStats()2203 private void sendMetricsForImsCallDropStats() { 2204 int transportTypeOfCall = mDataConnectionStatusTracker.getLastTransportType(); 2205 mQnsMetrics.reportAtomForImsCallDropStats(mNetCapability, mSlotIndex, mRestrictManager, 2206 mCellularQualityMonitor, mWifiQualityMonitor, transportTypeOfCall, 2207 mCellularAccessNetworkType); 2208 } 2209 2210 } 2211