summaryrefslogtreecommitdiff
path: root/services/QualifiedNetworksService/src/com
diff options
context:
space:
mode:
authorsangyun <sangyun@google.com>2023-02-22 06:29:06 +0900
committersangyun <sangyun@google.com>2023-03-13 18:18:37 +0900
commit3fb7100cb4ddc6d787cc3a54c9f2ad7ca094d83c (patch)
treed7b998709318001f9cc058280dee6014b32bd8d4 /services/QualifiedNetworksService/src/com
parent91bd6a427da8d68f5faf80a2dae6610a7ddeb016 (diff)
downloadTelephony-3fb7100cb4ddc6d787cc3a54c9f2ad7ca094d83c.tar.gz
[QNS] Introduction of the qns metric (QNS metric v1.3)
Atom for QualifiedRatListChanged - Pushed atom when a QNS update qualified RAT list. Atom for FallbackRestrictionChanged - Pushed atom when QNS fallback restriction changed. Atom for ImsCallDrop - Pushed atom when IMS call drop occurred in when both transport type available. Atom for RatPreferenceMismatchInfo - Pulls the history for mismatch between RAT preference and actual one. Atom for HandoverTimeMillis - Pulls for time taken from update of RAT preference until successful handover completion. Atom for HandoverPingpong - Pulls for count of handover pingpong in short time Bug: 235436630 Test: atest QualifiedNetworksServiceTests Change-Id: I5b3bd2db6c1ca00412e0cbb2a7435fde7bc28015
Diffstat (limited to 'services/QualifiedNetworksService/src/com')
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/AccessNetworkEvaluator.java103
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/QnsComponents.java13
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/QnsMetrics.java1026
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/QnsTelephonyListener.java58
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/RestrictManager.java25
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsFallbackRestrictionChangedInfo.java217
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsHandoverPingPongInfo.java159
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsHandoverTimeMillisInfo.java133
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsImsCallDropStats.java265
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsRatPreferenceMismatchInfo.java200
-rw-r--r--services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQualifiedRatListChangedInfo.java430
11 files changed, 2627 insertions, 2 deletions
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/AccessNetworkEvaluator.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/AccessNetworkEvaluator.java
index 46405b7..e8a742d 100644
--- a/services/QualifiedNetworksService/src/com/android/telephony/qns/AccessNetworkEvaluator.java
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/AccessNetworkEvaluator.java
@@ -26,6 +26,7 @@ import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
+import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ProvisioningManager;
import android.util.Log;
@@ -61,6 +62,7 @@ class AccessNetworkEvaluator {
private static final int EVENT_IMS_REGISTRATION_STATE_CHANGED = EVENT_BASE + 10;
private static final int EVENT_WIFI_RTT_STATUS_CHANGED = EVENT_BASE + 11;
private static final int EVENT_SIP_DIALOG_SESSION_STATE_CHANGED = EVENT_BASE + 12;
+ private static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = EVENT_BASE + 13;
private static final int EVALUATE_SPECIFIC_REASON_NONE = 0;
private static final int EVALUATE_SPECIFIC_REASON_IWLAN_DISABLE = 1;
private static final int EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED = 2;
@@ -88,6 +90,9 @@ class AccessNetworkEvaluator {
protected QnsProvisioningListener mQnsProvisioningListener;
protected QnsImsManager mQnsImsManager;
protected WifiBackhaulMonitor mWifiBackhaulMonitor;
+ protected QnsTelephonyListener mQnsTelephonyListener;
+ // for metric
+ protected QnsMetrics mQnsMetrics;
protected int mCellularAccessNetworkType = AccessNetworkType.UNKNOWN;
protected boolean mCellularAvailable = false;
@@ -117,6 +122,7 @@ class AccessNetworkEvaluator {
private boolean mSipDialogSessionState = false;
private int mCachedTransportTypeForEmergencyInitialConnect =
AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+ private int mLastEvaluateSpecificReason = EVALUATE_SPECIFIC_REASON_NONE;
AccessNetworkEvaluator(QnsComponents qnsComponents, int netCapability, int slotIndex) {
mNetCapability = netCapability;
@@ -155,6 +161,8 @@ class AccessNetworkEvaluator {
mNetCapability);
mQnsImsManager = mQnsComponents.getQnsImsManager(mSlotIndex);
mWifiBackhaulMonitor = mQnsComponents.getWifiBackhaulMonitor(mSlotIndex);
+ mQnsTelephonyListener = mQnsComponents.getQnsTelephonyListener(mSlotIndex);
+ mQnsMetrics = mQnsComponents.getQnsMetrics();
// Pre-Conditions
mCellularNetworkStatusTracker = mQnsComponents.getCellularNetworkStatusTracker(mSlotIndex);
@@ -213,6 +221,8 @@ class AccessNetworkEvaluator {
mQnsProvisioningListener = mQnsComponents.getQnsProvisioningListener(mSlotIndex);
mQnsImsManager = mQnsComponents.getQnsImsManager(mSlotIndex);
mWifiBackhaulMonitor = mQnsComponents.getWifiBackhaulMonitor(mSlotIndex);
+ mQnsTelephonyListener = mQnsComponents.getQnsTelephonyListener(mSlotIndex);
+ mQnsMetrics = mQnsComponents.getQnsMetrics();
mHandlerThread =
new HandlerThread(AccessNetworkEvaluator.class.getSimpleName() + mNetCapability);
mHandlerThread.start();
@@ -248,6 +258,7 @@ class AccessNetworkEvaluator {
isAllowed(AccessNetworkConstants.TRANSPORT_TYPE_WWAN))) {
mHandler.post(this::evaluate);
}
+ mLastEvaluateSpecificReason = EVALUATE_SPECIFIC_REASON_NONE;
}
void close() {
@@ -327,6 +338,9 @@ class AccessNetworkEvaluator {
QualifiedNetworksInfo info = new QualifiedNetworksInfo(mNetCapability, accessNetworkTypes);
QnsAsyncResult ar = new QnsAsyncResult(null, info, null);
mQualifiedNetworksChangedRegistrants.notifyRegistrants(ar);
+
+ // metrics
+ sendMetricsForQualifiedNetworks(info);
}
private void initSettings() {
@@ -383,6 +397,10 @@ class AccessNetworkEvaluator {
}
mQnsProvisioningListener.registerProvisioningItemInfoChanged(
mHandler, EVENT_PROVISIONING_INFO_CHANGED, null, true);
+ if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) {
+ mQnsTelephonyListener.registerImsCallDropDisconnectCauseListener(
+ mHandler, EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED, null);
+ }
List<Integer> events = new ArrayList<>();
events.add(QnsEventDispatcher.QNS_EVENT_WFC_ENABLED);
events.add(QnsEventDispatcher.QNS_EVENT_WFC_DISABLED);
@@ -419,6 +437,9 @@ class AccessNetworkEvaluator {
mWifiBackhaulMonitor.unRegisterForRttStatusChange(mHandler);
}
}
+ if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) {
+ mQnsTelephonyListener.unregisterImsCallDropDisconnectCauseListener(mHandler);
+ }
mQnsProvisioningListener.unregisterProvisioningItemInfoChanged(mHandler);
mQnsEventDispatcher.unregisterEvent(mHandler);
mRestrictManager.unRegisterRestrictInfoChanged(mHandler);
@@ -522,7 +543,9 @@ class AccessNetworkEvaluator {
protected void onIwlanNetworkStatusChanged(IwlanAvailabilityInfo info) {
if (info != null) {
- mIwlanAvailable = info.getIwlanAvailable();
+ if (mIwlanAvailable != info.getIwlanAvailable()) {
+ mIwlanAvailable = info.getIwlanAvailable();
+ }
mIsCrossWfc = info.isCrossWfc();
log("onIwlanNetworkStatusChanged IwlanAvailable:" + mIwlanAvailable);
if (info.getNotifyIwlanDisabled()) {
@@ -660,6 +683,10 @@ class AccessNetworkEvaluator {
&& callType == QnsConstants.CALL_TYPE_EMERGENCY) {
if (!mDataConnectionStatusTracker.isActiveState()) return;
}
+
+ // metrics
+ sendMetricsForCallTypeChanged(mCallType, callType);
+
mCallType = callType;
mRestrictManager.setQnsCallType(mCallType);
log("onSetCallType CallType:" + mCallType);
@@ -754,6 +781,10 @@ class AccessNetworkEvaluator {
}
break;
}
+
+ // metrics
+ sendMetricsForDataConnectionChanged(info);
+
if (needEvaluate) {
evaluate(evaluateSpecificReason);
}
@@ -917,6 +948,26 @@ class AccessNetworkEvaluator {
}
}
+ protected void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReasonInfo) {
+ if (imsReasonInfo == null) {
+ return;
+ }
+ if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS
+ && imsReasonInfo.getCode() == ImsReasonInfo.CODE_MEDIA_NO_DATA) {
+ log(
+ "onImsCallDisconnectCauseChanged: iwlanAvailable="
+ + mIwlanAvailable
+ + " cellularAvailable="
+ + mCellularAvailable
+ + " imsReasonInfo="
+ + imsReasonInfo);
+ if (mIwlanAvailable && mCellularAvailable) {
+ // metrics
+ sendMetricsForImsCallDropStats();
+ }
+ }
+ }
+
protected void onCellularQualityChanged(Threshold[] ths) {
if (ths == null || ths.length == 0) {
log("onCellularQualityChanged: E threshold is null");
@@ -1194,6 +1245,7 @@ class AccessNetworkEvaluator {
if (DBG) log("ANE is not initialized yet.");
return;
}
+ mLastEvaluateSpecificReason = specificReason;
log("evaluate reason:" + evaluateSpecificReasonToString(specificReason));
if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_EIMS) {
if (!mDataConnectionStatusTracker.isActiveState()) {
@@ -1954,6 +2006,9 @@ class AccessNetworkEvaluator {
case EVENT_SIP_DIALOG_SESSION_STATE_CHANGED:
onSipDialogSessionStateChanged((boolean) ar.mResult);
break;
+ case EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED:
+ onImsCallDisconnectCauseChanged((ImsReasonInfo) ar.mResult);
+ break;
case QnsEventDispatcher.QNS_EVENT_WFC_ENABLED:
onWfcEnabledChanged(true, false);
break;
@@ -2099,4 +2154,50 @@ class AccessNetworkEvaluator {
boolean getSipDialogSessionState() {
return mSipDialogSessionState;
}
+
+ private void sendMetricsForQualifiedNetworks(QualifiedNetworksInfo info) {
+ if (!mCellularAvailable
+ || !mIwlanAvailable
+ || mCellularAccessNetworkType == AccessNetworkType.UNKNOWN
+ || mLastEvaluateSpecificReason == EVALUATE_SPECIFIC_REASON_DATA_DISCONNECTED) {
+ // b/268557926, decided to cut off if WWAN and WLAN are not in contention.
+ return;
+ }
+ mQnsMetrics.reportAtomForQualifiedNetworks(
+ info,
+ mSlotIndex,
+ mDataConnectionStatusTracker.getLastTransportType(),
+ mCoverage,
+ mSettingWfcEnabled,
+ mSettingWfcRoamingEnabled,
+ mSettingWfcMode,
+ mSettingWfcRoamingMode,
+ mCellularAccessNetworkType,
+ mIwlanAvailable,
+ mIsCrossWfc,
+ mRestrictManager,
+ mCellularQualityMonitor,
+ mWifiQualityMonitor,
+ mCallType);
+ }
+
+ private void sendMetricsForCallTypeChanged(int oldCallType, int newCallType) {
+ int transportTypeOfCall = mDataConnectionStatusTracker.getLastTransportType();
+ mQnsMetrics.reportAtomForCallTypeChanged(mNetCapability, mSlotIndex,
+ oldCallType, newCallType, mRestrictManager, transportTypeOfCall);
+ }
+
+ private void sendMetricsForDataConnectionChanged(
+ DataConnectionStatusTracker.DataConnectionChangedInfo info) {
+ mQnsMetrics.reportAtomForDataConnectionChanged(
+ mNetCapability, mSlotIndex, info, mConfigManager.getCarrierId());
+ }
+
+ private void sendMetricsForImsCallDropStats() {
+ int transportTypeOfCall = mDataConnectionStatusTracker.getLastTransportType();
+ mQnsMetrics.reportAtomForImsCallDropStats(mNetCapability, mSlotIndex, mRestrictManager,
+ mCellularQualityMonitor, mWifiQualityMonitor, transportTypeOfCall,
+ mCellularAccessNetworkType);
+ }
+
}
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsComponents.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsComponents.java
index 1c9b898..1c14bae 100644
--- a/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsComponents.java
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsComponents.java
@@ -46,6 +46,7 @@ class QnsComponents {
private final List<Integer> mSlotIds;
private IwlanNetworkStatusTracker mIwlanNetworkStatusTracker;
private WifiQualityMonitor mWifiQualityMonitor;
+ private QnsMetrics mQnsMetrics;
/** Constructor to instantiate QnsComponents class. */
QnsComponents(Context context) {
@@ -113,6 +114,9 @@ class QnsComponents {
mQnsImsManagers.get(slotId),
mQnsTelephonyListeners.get(slotId),
slotId);
+ if (mQnsMetrics == null) {
+ mQnsMetrics = new QnsMetrics(mContext);
+ }
Log.d(mLogTag, "QnsComponents created for slot " + slotId);
}
@@ -132,6 +136,7 @@ class QnsComponents {
QnsCallStatusTracker qnsCallStatusTracker,
WifiBackhaulMonitor wifiBackhaulMonitor,
WifiQualityMonitor wifiQualityMonitor,
+ QnsMetrics qnsMetrics,
int slotId) {
this(context);
mSlotIds.add(slotId);
@@ -155,6 +160,7 @@ class QnsComponents {
qnsImsManager,
qnsTelephonyListener,
slotId);
+ mQnsMetrics = qnsMetrics;
}
/** Returns instance of AlternativeEventListener for given slotId. */
@@ -217,6 +223,11 @@ class QnsComponents {
return mWifiQualityMonitor;
}
+ /** Returns instance of WifiQualityMonitor. */
+ QnsMetrics getQnsMetrics() {
+ return mQnsMetrics;
+ }
+
/** Returns context. */
Context getContext() {
return mContext;
@@ -229,8 +240,10 @@ class QnsComponents {
if (mSlotIds.size() == 1) {
mIwlanNetworkStatusTracker.close();
mWifiQualityMonitor.close();
+ mQnsMetrics.close();
mIwlanNetworkStatusTracker = null;
mWifiQualityMonitor = null;
+ mQnsMetrics = null;
}
WifiBackhaulMonitor wifiBackhaulMonitor = mWifiBackhaulMonitors.get(slotId);
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsMetrics.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsMetrics.java
new file mode 100644
index 0000000..d936d0b
--- /dev/null
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsMetrics.java
@@ -0,0 +1,1026 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.qns;
+
+import android.content.Context;
+import android.net.NetworkCapabilities;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.SignalThresholdInfo;
+import android.telephony.qns.QnsProtoEnums;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import com.android.telephony.qns.DataConnectionStatusTracker.DataConnectionChangedInfo;
+import com.android.telephony.qns.QualifiedNetworksServiceImpl.QualifiedNetworksInfo;
+import com.android.telephony.qns.atoms.AtomsQnsFallbackRestrictionChangedInfo;
+import com.android.telephony.qns.atoms.AtomsQnsHandoverPingPongInfo;
+import com.android.telephony.qns.atoms.AtomsQnsHandoverTimeMillisInfo;
+import com.android.telephony.qns.atoms.AtomsQnsImsCallDropStats;
+import com.android.telephony.qns.atoms.AtomsQnsRatPreferenceMismatchInfo;
+import com.android.telephony.qns.atoms.AtomsQualifiedRatListChangedInfo;
+import com.android.telephony.statslib.StatsLib;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+/** QnsStats class */
+class QnsMetrics {
+
+ private StatsLib mStats;
+ private final String mLogTag;
+ private final Handler mHandler;
+ private final HandlerThread mHandlerThread;
+
+ // For HandoverTIme.
+ private final ConcurrentHashMap<Integer, HandoverTimeStateMachine> mHandoverTimeMap;
+ private final ConcurrentHashMap<Integer, PingPongTime> mPingPongTime;
+ private final ConcurrentHashMap<Integer, RatMismatchTime> mRatMismatchTime;
+ private final ConcurrentHashMap<Integer, RtpCallDrop> mRtpCallDrop;
+
+ /** Constructor */
+ QnsMetrics(Context context) {
+ mStats = new StatsLib(context);
+ mLogTag = QnsMetrics.class.getSimpleName();
+
+ mHandoverTimeMap = new ConcurrentHashMap<>();
+ mPingPongTime = new ConcurrentHashMap<>();
+ mRatMismatchTime = new ConcurrentHashMap<>();
+ mRtpCallDrop = new ConcurrentHashMap<>();
+
+ mHandlerThread = new HandlerThread(QnsMetrics.class.getSimpleName());
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ }
+
+ @VisibleForTesting
+ QnsMetrics(StatsLib statsLib) {
+ mStats = statsLib;
+ mLogTag = QnsMetrics.class.getSimpleName();
+
+ mHandoverTimeMap = new ConcurrentHashMap<>();
+ mPingPongTime = new ConcurrentHashMap<>();
+ mRatMismatchTime = new ConcurrentHashMap<>();
+ mRtpCallDrop = new ConcurrentHashMap<>();
+
+ mHandlerThread = new HandlerThread(QnsMetrics.class.getSimpleName());
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ }
+
+ @VisibleForTesting
+ Handler getHandler() {
+ return mHandler;
+ }
+
+ /** close */
+ public void close() {
+ mStats = null;
+ mHandlerThread.quitSafely();
+ }
+
+ /**
+ * Report atoms when the qualified access network is reported.
+ *
+ * @param info QualifiedNetworksInfo
+ * @param slotId slot index
+ * @param dataConnectionCurrentTransportType transportType currently stayed in.
+ * @param coverage coverage home or roam.
+ * @param settingWfcEnabled setting for wfc
+ * @param settingWfcRoamingEnabled roaming setting for wfc
+ * @param settingWfcMode setting for wfc mode
+ * @param settingWfcRoamingMode roaming setting for wfc mode
+ * @param cellularAccessNetworkType cellular rat
+ * @param iwlanAvailable iwlan available
+ * @param isCrossWfc cross sim wfc enabled
+ * @param restrictManager restriction manager
+ * @param cellularQualityMonitor cellular quality monitor
+ * @param wifiQualityMonitor wifi quality monitor
+ * @param callType call type
+ */
+ public void reportAtomForQualifiedNetworks(
+ QualifiedNetworksInfo info,
+ int slotId,
+ int dataConnectionCurrentTransportType,
+ int coverage,
+ boolean settingWfcEnabled,
+ boolean settingWfcRoamingEnabled,
+ int settingWfcMode,
+ int settingWfcRoamingMode,
+ int cellularAccessNetworkType,
+ boolean iwlanAvailable,
+ boolean isCrossWfc,
+ RestrictManager restrictManager,
+ QualityMonitor cellularQualityMonitor,
+ QualityMonitor wifiQualityMonitor,
+ int callType) {
+ mHandler.post(() -> procQualifiedNetworksForHandoverTime(info, slotId));
+ mHandler.post(() ->
+ procQualifiedRatListChanged(
+ info,
+ slotId,
+ dataConnectionCurrentTransportType,
+ coverage,
+ settingWfcEnabled,
+ settingWfcRoamingEnabled,
+ settingWfcMode,
+ settingWfcRoamingMode,
+ cellularAccessNetworkType,
+ iwlanAvailable,
+ isCrossWfc,
+ restrictManager,
+ cellularQualityMonitor,
+ wifiQualityMonitor,
+ callType));
+ }
+
+ /**
+ * Report atom when data connection is changed
+ *
+ * @param netCapability Network Capability
+ * @param slotId slot Index
+ * @param info DataConnectionChangedInfo
+ * @param carrierId carrier id.
+ */
+ public void reportAtomForDataConnectionChanged(
+ int netCapability, int slotId, DataConnectionChangedInfo info, int carrierId) {
+ mHandler.post(() -> procDataConnectionChangedForHandoverTime(netCapability, slotId, info));
+ mHandler.post(() -> procDataConnectionChangedForHandoverPingPong(
+ netCapability, slotId, info, carrierId));
+ mHandler.post(() -> procDataConnectionChangedForRatMismatch(
+ netCapability, slotId, info, carrierId));
+ }
+
+ /**
+ * Report atom when a restriction is set.
+ *
+ * @param netCapability Network Capability
+ * @param slotId slot Index
+ * @param wlanRestrictions list of restrictions on wlan
+ * @param wwanRestrictions list of restrictions on wwan
+ * @param carrierId carrier id.
+ */
+ public void reportAtomForRestrictions(
+ int netCapability,
+ int slotId,
+ List<Integer> wlanRestrictions,
+ List<Integer> wwanRestrictions,
+ int carrierId) {
+ mHandler.post(() -> procRestrictionsForFallback(
+ netCapability, slotId, wlanRestrictions, wwanRestrictions, carrierId));
+ }
+
+ /**
+ * Report atom when call type change
+ *
+ * @param netCapability Network Capability
+ * @param slotId slot Index
+ * @param oldCallType previous call type
+ * @param newCallType new call type
+ * @param restrictManager restriction manager
+ * @param transportTypeOfCall transport type in call
+ */
+ public void reportAtomForCallTypeChanged(
+ int netCapability,
+ int slotId,
+ int oldCallType,
+ int newCallType,
+ RestrictManager restrictManager,
+ int transportTypeOfCall) {
+ mHandler.post(() -> procCallTypeChangedForImsCallDrop(netCapability, slotId,
+ oldCallType, newCallType, restrictManager, transportTypeOfCall));
+ }
+
+ /**
+ * Report atom when ims call is dropped
+ *
+ * @param netCapability Network Capability
+ * @param slotId slot Index
+ * @param restrictManager restriction manager
+ * @param cellularQualityMonitor cellular quality monitor
+ * @param wifiQualityMonitor wifi quality monitor
+ * @param transportTypeOfCall transport type in call
+ * @param cellularAccessNetworkType cellular access network
+ */
+ public void reportAtomForImsCallDropStats(
+ int netCapability,
+ int slotId,
+ RestrictManager restrictManager,
+ QualityMonitor cellularQualityMonitor,
+ QualityMonitor wifiQualityMonitor,
+ int transportTypeOfCall,
+ int cellularAccessNetworkType) {
+ mHandler.post(() -> procCallDroppedForImsCallDrop(netCapability, slotId, restrictManager,
+ cellularQualityMonitor, wifiQualityMonitor, transportTypeOfCall,
+ cellularAccessNetworkType));
+ }
+
+ private void procQualifiedRatListChanged(
+ QualifiedNetworksInfo info,
+ int slotId,
+ int dataConnectedTransportType,
+ int coverage,
+ boolean settingWfcEnabled,
+ boolean settingWfcRoamingEnabled,
+ int settingWfcMode,
+ int settingWfcRoamingMode,
+ int cellularAccessNetworkType,
+ boolean iwlanAvailable,
+ boolean isCrossWfc,
+ RestrictManager restrictManager,
+ QualityMonitor cellularQualityMonitor,
+ QualityMonitor wifiQualityMonitor,
+ int callType) {
+ int netCapability = info.getNetCapability();
+ int firstQualifiedRat = getQualifiedAccessNetwork(info, 0);
+ int secondQualifiedRat = getQualifiedAccessNetwork(info, 1);
+ boolean wfcEnabled = getWfcEnabled(coverage, settingWfcEnabled, settingWfcRoamingEnabled);
+ int wfcMode = getWfcMode(coverage, settingWfcMode, settingWfcRoamingMode);
+ int iwlanNetworkType = getIwlanNetworkType(iwlanAvailable, isCrossWfc);
+ int restrictionsOnWwan = getRestrictionsBitmask(
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN, restrictManager);
+ int restrictionsOnWlan = getRestrictionsBitmask(
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN, restrictManager);
+ int signalStrength = getSignalStrength(cellularQualityMonitor, cellularAccessNetworkType);
+ int signalQuality = getSignalQuality(cellularQualityMonitor, cellularAccessNetworkType);
+ int signalNoise = getSignalNoise(cellularQualityMonitor, cellularAccessNetworkType);
+ int iwlanSignalStrength = getSignalStrength(wifiQualityMonitor, AccessNetworkType.IWLAN);
+ int updateReason = 0;
+ int imsCallQuality = 0;
+
+ writeQualifiedRatListChangedInfo(
+ netCapability,
+ slotId,
+ firstQualifiedRat,
+ secondQualifiedRat,
+ dataConnectedTransportType,
+ wfcEnabled,
+ wfcMode,
+ cellularAccessNetworkType,
+ iwlanNetworkType,
+ restrictionsOnWwan,
+ restrictionsOnWlan,
+ signalStrength,
+ signalQuality,
+ signalNoise,
+ iwlanSignalStrength,
+ updateReason,
+ callType,
+ imsCallQuality);
+ }
+
+
+ private void procQualifiedNetworksForHandoverTime(QualifiedNetworksInfo info, int slotId) {
+ if (info.getNetCapability() != NetworkCapabilities.NET_CAPABILITY_IMS) {
+ return;
+ }
+
+ HandoverTimeStateMachine handoverTimeStateMachine = mHandoverTimeMap.get(slotId);
+ if (handoverTimeStateMachine == null) {
+ handoverTimeStateMachine =
+ new HandoverTimeStateMachine(info.getNetCapability(), slotId, mHandler);
+ mHandoverTimeMap.put(slotId, handoverTimeStateMachine);
+ }
+
+ handoverTimeStateMachine.sendQualifiedRatChanged(info);
+ }
+
+ private void procDataConnectionChangedForHandoverTime(
+ int netCapability, int slotId, DataConnectionChangedInfo info) {
+ if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
+ return;
+ }
+
+ HandoverTimeStateMachine handoverTimeStateMachine = mHandoverTimeMap.get(slotId);
+ if (handoverTimeStateMachine == null) {
+ handoverTimeStateMachine =
+ new HandoverTimeStateMachine(netCapability, slotId, mHandler);
+ mHandoverTimeMap.put(slotId, handoverTimeStateMachine);
+ }
+
+ handoverTimeStateMachine.sendDataStateChanged(info);
+ }
+
+ private void procDataConnectionChangedForHandoverPingPong(int netCapability, int slotId,
+ DataConnectionChangedInfo info, int carrierId) {
+ if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
+ return;
+ }
+
+ PingPongTime pingPongTime = mPingPongTime.get(slotId);
+ if (pingPongTime == null) {
+ pingPongTime = new PingPongTime();
+ mPingPongTime.put(slotId, pingPongTime);
+ }
+
+ boolean bActiveState;
+ switch (info.getState()) {
+ case DataConnectionStatusTracker.STATE_INACTIVE:
+ case DataConnectionStatusTracker.STATE_CONNECTING:
+ bActiveState = false;
+ break;
+ case DataConnectionStatusTracker.STATE_CONNECTED:
+ case DataConnectionStatusTracker.STATE_HANDOVER:
+ default:
+ bActiveState = true;
+ break;
+ }
+ switch (info.getEvent()) {
+ case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_CONNECTED:
+ pingPongTime.mSuccessTime = QnsUtils.getSystemElapsedRealTime();
+ pingPongTime.mHandoverCount = 0;
+ break;
+ case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_HANDOVER_STARTED:
+ pingPongTime.mStartTime = QnsUtils.getSystemElapsedRealTime();
+ break;
+ case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_HANDOVER_SUCCESS:
+ pingPongTime.mHandoverCount++;
+ pingPongTime.mSuccessTime = QnsUtils.getSystemElapsedRealTime();
+ break;
+ }
+
+ if (pingPongTime.mStartTime != 0L && pingPongTime.mSuccessTime != 0L) {
+ long pingPongTimeLimit = AtomsQnsHandoverPingPongInfo.PING_PONG_TIME_IN_MILLIS;
+ long elapsed =
+ (pingPongTime.mSuccessTime > pingPongTime.mStartTime)
+ ? (pingPongTime.mSuccessTime - pingPongTime.mStartTime)
+ : (pingPongTime.mStartTime - pingPongTime.mSuccessTime);
+ if (pingPongTime.mHandoverCount > 0) {
+ log("HandoverPingPong elapsed:" + elapsed
+ + " ping-pong count:" + (pingPongTime.mHandoverCount / 2));
+ }
+ if (elapsed > pingPongTimeLimit || !bActiveState) {
+ if (pingPongTime.mHandoverCount > 1) {
+ int pingpongCount = pingPongTime.mHandoverCount / 2;
+ writeQnsHandoverPingPong(slotId, pingpongCount, carrierId);
+ }
+ pingPongTime.mHandoverCount = 0;
+ pingPongTime.mStartTime = 0L;
+ pingPongTime.mSuccessTime = 0L;
+ procDataConnectionChangedForHandoverPingPong(
+ netCapability, slotId, info, carrierId);
+ }
+ }
+ if (!bActiveState) {
+ pingPongTime.mHandoverCount = 0;
+ pingPongTime.mStartTime = 0L;
+ pingPongTime.mSuccessTime = 0L;
+ }
+ }
+
+ private void procRestrictionsForFallback(int netCapability, int slotId,
+ List<Integer> wlanRestrictions, List<Integer> wwanRestrictions, int carrierId) {
+ if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS
+ || wlanRestrictions == null
+ || wwanRestrictions == null) {
+ return;
+ }
+
+ boolean bRestrictionOnWlanByRtpThresholdBreached =
+ wlanRestrictions.contains(RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY);
+ boolean bRestrictionOnWwanByRtpThresholdBreached =
+ wwanRestrictions.contains(RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY);
+ boolean bRestrictionOnWlanByImsRegistrationFailed =
+ wlanRestrictions.contains(
+ RestrictManager.RESTRICT_TYPE_FALLBACK_TO_WWAN_IMS_REGI_FAIL);
+ boolean bRestrictionOnWlanByWifiBackhaulProblem =
+ wlanRestrictions.contains(
+ RestrictManager.RESTRICT_TYPE_FALLBACK_TO_WWAN_RTT_BACKHAUL_FAIL);
+
+ // all false will not write atom because this atom is used for count metric.
+ if (bRestrictionOnWlanByRtpThresholdBreached
+ || bRestrictionOnWwanByRtpThresholdBreached
+ || bRestrictionOnWlanByImsRegistrationFailed
+ || bRestrictionOnWlanByWifiBackhaulProblem) {
+ writeQnsFallbackRestrictionChangedInfo(
+ bRestrictionOnWlanByRtpThresholdBreached,
+ bRestrictionOnWwanByRtpThresholdBreached,
+ bRestrictionOnWlanByImsRegistrationFailed,
+ bRestrictionOnWlanByWifiBackhaulProblem,
+ carrierId,
+ slotId);
+ }
+ }
+
+ private void procDataConnectionChangedForRatMismatch(
+ int netCapability, int slotId, DataConnectionChangedInfo info, int carrierId) {
+
+ RatMismatchTime mismatchTime = mRatMismatchTime.get(slotId);
+ if (mismatchTime == null) {
+ mismatchTime = new RatMismatchTime();
+ mRatMismatchTime.put(slotId, mismatchTime);
+ }
+
+ switch (info.getEvent()) {
+ case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_HANDOVER_STARTED:
+ if (mismatchTime.mCount == 0) {
+ mismatchTime.mStartTime = QnsUtils.getSystemElapsedRealTime();
+ }
+ break;
+ case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_HANDOVER_FAILED:
+ mismatchTime.mCount++;
+ break;
+ default:
+ if (mismatchTime.mCount > 0) {
+ long duration = QnsUtils.getSystemElapsedRealTime() - mismatchTime.mStartTime;
+ int count = mismatchTime.mCount;
+
+ writeQnsRatPreferenceMismatchInfo(
+ netCapability, count, (int) duration, carrierId, slotId);
+ mismatchTime.mCount = 0;
+ mismatchTime.mStartTime = 0L;
+ }
+ break;
+ }
+ }
+
+ private void writeQualifiedRatListChangedInfo(
+ int netCapability,
+ int slotId,
+ int firstQualifiedRat,
+ int secondQualifiedRat,
+ int currentTransportType,
+ boolean wfcEnabled,
+ int wfcMode,
+ int cellularNetworkType,
+ int iwlanNetworkType,
+ int restrictionsOnWwan,
+ int restrictionsOnWlan,
+ int signalStrength,
+ int signalQuality,
+ int signalNoise,
+ int iwlanSignalStrength,
+ int updateReason,
+ int imsCallType,
+ int imsCallQuality) {
+ AtomsQualifiedRatListChangedInfo atoms =
+ new AtomsQualifiedRatListChangedInfo(
+ netCapability,
+ firstQualifiedRat,
+ secondQualifiedRat,
+ currentTransportType,
+ wfcEnabled,
+ wfcMode,
+ cellularNetworkType,
+ iwlanNetworkType,
+ restrictionsOnWwan,
+ restrictionsOnWlan,
+ signalStrength,
+ signalQuality,
+ signalNoise,
+ iwlanSignalStrength,
+ updateReason,
+ imsCallType,
+ imsCallQuality,
+ slotId);
+ mStats.write(atoms);
+ }
+
+
+ private void writeQnsHandoverTimeMillisInfo(long handoverTime, int slotIndex) {
+ AtomsQnsHandoverTimeMillisInfo atoms =
+ new AtomsQnsHandoverTimeMillisInfo((int) handoverTime, slotIndex);
+ mStats.append(atoms);
+ }
+
+ private void writeQnsHandoverPingPong(int slotId, int pingPongCount, int carrierId) {
+ AtomsQnsHandoverPingPongInfo atoms =
+ new AtomsQnsHandoverPingPongInfo(pingPongCount, carrierId, slotId);
+ mStats.append(atoms);
+ }
+
+ private void writeQnsFallbackRestrictionChangedInfo(
+ boolean bRestrictionOnWlanByRtpThresholdBreached,
+ boolean bRestrictionOnWwanByRtpThresholdBreached,
+ boolean bRestrictionOnWlanByImsRegistrationFailed,
+ boolean bRestrictionOnWlanByWifiBackhaulProblem,
+ int carrierId,
+ int slotId) {
+ AtomsQnsFallbackRestrictionChangedInfo atom =
+ new AtomsQnsFallbackRestrictionChangedInfo(
+ bRestrictionOnWlanByRtpThresholdBreached,
+ bRestrictionOnWwanByRtpThresholdBreached,
+ bRestrictionOnWlanByImsRegistrationFailed,
+ bRestrictionOnWlanByWifiBackhaulProblem,
+ carrierId,
+ slotId);
+ mStats.write(atom);
+ }
+
+ private void writeQnsRatPreferenceMismatchInfo(int netCapability, int handoverFailCount,
+ int durationMismatch, int carrierId, int slotId) {
+ AtomsQnsRatPreferenceMismatchInfo atoms = new AtomsQnsRatPreferenceMismatchInfo(
+ netCapability, handoverFailCount, durationMismatch, carrierId, slotId);
+ mStats.append(atoms);
+ }
+
+ class HandoverTimeStateMachine extends StateMachine {
+
+ private static final int EVENT_DATA_STATE_CHANGED = 0;
+ private static final int EVENT_QUALIFIED_RAT_CHANGED = 1;
+
+ private final IdleState mIdleState;
+ private final ConnectedState mConnectedState;
+ private final HandoverRequestedState mHandoverRequestedState;
+ private final HandoverInProgressState mHandoverInProgressState;
+
+ private final int mNetCapability;
+ private final int mSlotId;
+ int mDataTransportType;
+ long mHandoverRequestedTime;
+
+ HandoverTimeStateMachine(int netCapability, int slotId, Handler handler) {
+ super(mLogTag + "_" + HandoverTimeStateMachine.class.getSimpleName() + "_" + slotId
+ + "_" + QnsUtils.getNameOfNetCapability(netCapability), handler);
+
+ mIdleState = new IdleState();
+ mConnectedState = new ConnectedState();
+ mHandoverRequestedState = new HandoverRequestedState();
+ mHandoverInProgressState = new HandoverInProgressState();
+
+ mNetCapability = netCapability;
+ mSlotId = slotId;
+ mDataTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+ mHandoverRequestedTime = 0L;
+
+ addState(mIdleState);
+ addState(mConnectedState);
+ addState(mHandoverRequestedState);
+ addState(mHandoverInProgressState);
+ setInitialState(mIdleState);
+ start();
+ }
+
+ public void sendDataStateChanged(DataConnectionChangedInfo info) {
+ sendMessage(EVENT_DATA_STATE_CHANGED, info);
+ }
+
+ public void sendQualifiedRatChanged(QualifiedNetworksInfo info) {
+ sendMessage(EVENT_QUALIFIED_RAT_CHANGED, info);
+ }
+
+ private final class IdleState extends State {
+ @Override
+ public void enter() {
+ log("IdleState");
+ mDataTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+ mHandoverRequestedTime = 0L;
+ }
+
+ @Override
+ public boolean processMessage(Message msg) {
+ log("IdleState processMessage=" + msg.what);
+ switch (msg.what) {
+ case EVENT_DATA_STATE_CHANGED:
+ DataConnectionChangedInfo dataInfo = (DataConnectionChangedInfo) msg.obj;
+ switch (dataInfo.getState()) {
+ case DataConnectionStatusTracker.STATE_CONNECTED:
+ mDataTransportType = dataInfo.getTransportType();
+ transitionTo(mConnectedState);
+ return HANDLED;
+ case DataConnectionStatusTracker.STATE_HANDOVER:
+ mDataTransportType = dataInfo.getTransportType();
+ transitionTo(mConnectedState);
+ break;
+ }
+ break;
+ case EVENT_QUALIFIED_RAT_CHANGED:
+ break;
+ }
+ return super.processMessage(msg);
+ }
+
+ @Override
+ public void exit() {
+ super.exit();
+ }
+ }
+
+ private final class ConnectedState extends State {
+ @Override
+ public void enter() {
+ log("ConnectedState");
+ mHandoverRequestedTime = 0L;
+ }
+
+ @Override
+ public boolean processMessage(Message msg) {
+ log("ConnectedState processMessage=" + msg.what);
+ switch (msg.what) {
+ case EVENT_DATA_STATE_CHANGED:
+ DataConnectionChangedInfo dataInfo = (DataConnectionChangedInfo) msg.obj;
+ switch (dataInfo.getState()) {
+ case DataConnectionStatusTracker.STATE_INACTIVE:
+ case DataConnectionStatusTracker.STATE_CONNECTING:
+ transitionTo(mIdleState);
+ break;
+ case DataConnectionStatusTracker.STATE_CONNECTED:
+ case DataConnectionStatusTracker.STATE_HANDOVER:
+ mDataTransportType = dataInfo.getTransportType();
+ return HANDLED;
+ }
+ break;
+ case EVENT_QUALIFIED_RAT_CHANGED:
+ QualifiedNetworksInfo qualifiedInfo = (QualifiedNetworksInfo) msg.obj;
+ // handover trigger
+ if (mNetCapability == qualifiedInfo.getNetCapability()
+ && qualifiedInfo.getAccessNetworkTypes().stream().anyMatch(
+ accessNetwork -> QnsUtils.getTransportTypeFromAccessNetwork(
+ accessNetwork) != mDataTransportType)) {
+ mHandoverRequestedTime = QnsUtils.getSystemElapsedRealTime();
+ transitionTo(mHandoverRequestedState);
+ return HANDLED;
+ }
+ break;
+ }
+
+ return super.processMessage(msg);
+ }
+
+ @Override
+ public void exit() {
+ super.exit();
+ }
+ }
+
+ private final class HandoverRequestedState extends State {
+ @Override
+ public void enter() {
+ log("HandoverRequestedState");
+ }
+
+ @Override
+ public boolean processMessage(Message msg) {
+ log("HandoverRequestedState processMessage=" + msg.what);
+ switch (msg.what) {
+ case EVENT_DATA_STATE_CHANGED:
+ DataConnectionChangedInfo dataInfo = (DataConnectionChangedInfo) msg.obj;
+ switch (dataInfo.getState()) {
+ case DataConnectionStatusTracker.STATE_INACTIVE:
+ case DataConnectionStatusTracker.STATE_CONNECTING:
+ transitionTo(mIdleState);
+ break;
+ case DataConnectionStatusTracker.STATE_CONNECTED:
+ if (dataInfo.getTransportType() != mDataTransportType) {
+ // back to connected state, already reached to target transport.
+ mDataTransportType = dataInfo.getTransportType();
+ transitionTo(mConnectedState);
+ }
+ break;
+ case DataConnectionStatusTracker.STATE_HANDOVER:
+ if (dataInfo.getTransportType() != mDataTransportType) {
+ // back to connected state, already reached to target transport.
+ mDataTransportType = dataInfo.getTransportType();
+ transitionTo(mConnectedState);
+ }
+ transitionTo(mHandoverInProgressState);
+ break;
+ }
+ break;
+ case EVENT_QUALIFIED_RAT_CHANGED:
+ QualifiedNetworksInfo qualifiedInfo = (QualifiedNetworksInfo) msg.obj;
+ if (mNetCapability != qualifiedInfo.getNetCapability()) {
+ break;
+ }
+ if (qualifiedInfo.getAccessNetworkTypes().stream().noneMatch(
+ accessNetwork -> QnsUtils.getTransportTypeFromAccessNetwork(
+ accessNetwork) != mDataTransportType)) {
+ // back to connected state. no handover target transport.
+ transitionTo(mConnectedState);
+ return HANDLED;
+ }
+ break;
+ }
+ return super.processMessage(msg);
+ }
+
+ @Override
+ public void exit() {
+ super.exit();
+ }
+ }
+
+ private final class HandoverInProgressState extends State {
+ @Override
+ public void enter() {
+ log("HandoverInProgressState");
+ }
+
+ @Override
+ public boolean processMessage(Message msg) {
+ log("HandoverInProgressState processMessage=" + msg.what);
+ switch (msg.what) {
+ case EVENT_DATA_STATE_CHANGED:
+ DataConnectionChangedInfo dataInfo = (DataConnectionChangedInfo) msg.obj;
+ switch (dataInfo.getState()) {
+ case DataConnectionStatusTracker.STATE_INACTIVE:
+ case DataConnectionStatusTracker.STATE_CONNECTING:
+ transitionTo(mIdleState);
+ break;
+ case DataConnectionStatusTracker.STATE_CONNECTED:
+ if (dataInfo.getTransportType() != mDataTransportType) {
+ if (mHandoverRequestedTime == 0L) {
+ break;
+ }
+ // handover done.
+ long handoverTime = QnsUtils.getSystemElapsedRealTime()
+ - mHandoverRequestedTime;
+ writeQnsHandoverTimeMillisInfo(handoverTime, mSlotId);
+ mDataTransportType = dataInfo.getTransportType();
+ mHandoverRequestedTime = 0L;
+ transitionTo(mConnectedState);
+ } else {
+ // handover didn't have done yet.
+ transitionTo(mHandoverRequestedState);
+ }
+ break;
+ case DataConnectionStatusTracker.STATE_HANDOVER:
+ if (dataInfo.getTransportType() != mDataTransportType) {
+ // back to connected state, already reached to target transport.
+ mDataTransportType = dataInfo.getTransportType();
+ transitionTo(mConnectedState);
+ }
+ break;
+ }
+ break;
+ case EVENT_QUALIFIED_RAT_CHANGED:
+ QualifiedNetworksInfo qualifiedInfo = (QualifiedNetworksInfo) msg.obj;
+ if (mNetCapability == qualifiedInfo.getNetCapability()
+ && qualifiedInfo.getAccessNetworkTypes().stream().noneMatch(
+ accessNetwork -> QnsUtils.getTransportTypeFromAccessNetwork(
+ accessNetwork) != mDataTransportType)) {
+ // back to connected state. no handover request
+ transitionTo(mConnectedState);
+ return HANDLED;
+ }
+ break;
+ }
+ return super.processMessage(msg);
+ }
+
+ @Override
+ public void exit() {
+ super.exit();
+ }
+ }
+ }
+
+ private static class PingPongTime {
+ int mHandoverCount = 0;
+ long mStartTime = 0L;
+ long mSuccessTime = 0L;
+ }
+
+ private static class RatMismatchTime {
+ int mCount = 0;
+ long mStartTime = 0L;
+ }
+
+ private static class RtpCallDrop {
+ boolean mRtpThresholdBreached;
+ int mRestrictionsOnOtherTransportType;
+ }
+
+
+ private void procCallTypeChangedForImsCallDrop(
+ int netCapability,
+ int slotId,
+ int oldCallType,
+ int newCallType,
+ RestrictManager restrictManager,
+ int transportTypeOfCall) {
+ if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
+ return;
+ }
+
+ RtpCallDrop rtpCallDrop = mRtpCallDrop.get(slotId);
+ if (rtpCallDrop == null) {
+ rtpCallDrop = new RtpCallDrop();
+ mRtpCallDrop.put(slotId, rtpCallDrop);
+ }
+
+ // call ended
+ if (newCallType == QnsConstants.CALL_TYPE_IDLE
+ && oldCallType != QnsConstants.CALL_TYPE_IDLE) {
+ rtpCallDrop.mRtpThresholdBreached =
+ restrictManager.hasRestrictionType(
+ transportTypeOfCall, RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY);
+ int otherTransportType =
+ transportTypeOfCall == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
+ ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN
+ : AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
+ rtpCallDrop.mRestrictionsOnOtherTransportType =
+ getRestrictionsBitmask(otherTransportType, restrictManager);
+ } else {
+ rtpCallDrop.mRtpThresholdBreached = false;
+ rtpCallDrop.mRestrictionsOnOtherTransportType = 0;
+ }
+ }
+
+ private void procCallDroppedForImsCallDrop(
+ int netCapability,
+ int slotId,
+ RestrictManager restrictManager,
+ QualityMonitor cellularQualityMonitor,
+ QualityMonitor wifiQualityMonitor,
+ int transportTypeOfCall,
+ int cellularAccessNetworkType) {
+ if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
+ return;
+ }
+
+ RtpCallDrop rtpCallDrop = mRtpCallDrop.get(slotId);
+ if (rtpCallDrop == null) {
+ rtpCallDrop = new RtpCallDrop();
+ mRtpCallDrop.put(slotId, rtpCallDrop);
+ }
+
+ if (!rtpCallDrop.mRtpThresholdBreached
+ || rtpCallDrop.mRestrictionsOnOtherTransportType == 0) {
+ rtpCallDrop.mRtpThresholdBreached = restrictManager.hasRestrictionType(
+ transportTypeOfCall, RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY);
+ int otherTransportType =
+ transportTypeOfCall == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
+ ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN
+ : AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
+ rtpCallDrop.mRestrictionsOnOtherTransportType =
+ getRestrictionsBitmask(otherTransportType, restrictManager);
+ }
+
+ int signalStrength = getSignalStrength(cellularQualityMonitor, cellularAccessNetworkType);
+ int signalQuality = getSignalQuality(cellularQualityMonitor, cellularAccessNetworkType);
+ int signalNoise = getSignalNoise(cellularQualityMonitor, cellularAccessNetworkType);
+ int iwlanSignalStrength = getSignalStrength(wifiQualityMonitor, AccessNetworkType.IWLAN);
+
+ writeQnsImsCallDropStats(
+ transportTypeOfCall,
+ rtpCallDrop.mRtpThresholdBreached,
+ rtpCallDrop.mRestrictionsOnOtherTransportType,
+ signalStrength,
+ signalQuality,
+ signalNoise,
+ iwlanSignalStrength,
+ cellularAccessNetworkType,
+ slotId);
+ }
+
+ private void writeQnsImsCallDropStats(
+ int transportTypeCallDropped,
+ boolean rtpThresholdBreached,
+ int restrictionsOnOtherTransportType,
+ int signalStrength,
+ int signalQuality,
+ int signalNoise,
+ int iwlanSignalStrength,
+ int cellularNetworkType,
+ int slotId) {
+ AtomsQnsImsCallDropStats atoms =
+ new AtomsQnsImsCallDropStats(
+ transportTypeCallDropped,
+ rtpThresholdBreached,
+ restrictionsOnOtherTransportType,
+ signalStrength,
+ signalQuality,
+ signalNoise,
+ iwlanSignalStrength,
+ slotId,
+ cellularNetworkType);
+ mStats.write(atoms);
+ }
+
+ private int getQualifiedAccessNetwork(QualifiedNetworksInfo info, int index) {
+ List<Integer> types = info.getAccessNetworkTypes();
+ if (types == null || index >= types.size()) {
+ return QnsProtoEnums.EMPTY;
+ }
+ return types.get(index);
+ }
+
+ private boolean getWfcEnabled(int coverage, boolean wfcEnabled, boolean wfcRoamingEnabled) {
+ return coverage == QnsConstants.COVERAGE_HOME ? wfcEnabled : wfcRoamingEnabled;
+ }
+
+ private int getWfcMode(int coverage, int wfcMode, int wfcRoamingMode) {
+ return coverage == QnsConstants.COVERAGE_HOME ? wfcMode : wfcRoamingMode;
+ }
+
+ private int getIwlanNetworkType(boolean iwlanAvailable, boolean isCrossWfc) {
+ if (!iwlanAvailable) {
+ return QnsProtoEnums.IWLAN_NETWORK_TYPE_NONE;
+ } else if (isCrossWfc) {
+ return QnsProtoEnums.IWLAN_NETWORK_TYPE_CST;
+ }
+ return QnsProtoEnums.IWLAN_NETWORK_TYPE_WIFI;
+ }
+
+ static final HashMap<Integer, Integer> sAtomRestrictionsMap;
+
+ static {
+ sAtomRestrictionsMap = new HashMap<>();
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_GUARDING, QnsProtoEnums.RESTRICT_TYPE_GUARDING);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_THROTTLING, QnsProtoEnums.RESTRICT_TYPE_THROTTLING);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_HO_NOT_ALLOWED,
+ QnsProtoEnums.RESTRICT_TYPE_HO_NOT_ALLOWED);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_NON_PREFERRED_TRANSPORT,
+ QnsProtoEnums.RESTRICT_TYPE_NON_PREFERRED_TRANSPORT);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY,
+ QnsProtoEnums.RESTRICT_TYPE_RTP_LOW_QUALITY);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_RESTRICT_IWLAN_IN_CALL,
+ QnsProtoEnums.RESTRICT_TYPE_RESTRICT_IWLAN_IN_CALL);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_RESTRICT_IWLAN_CS_CALL,
+ QnsProtoEnums.RESTRICT_TYPE_RESTRICT_IWLAN_CS_CALL);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_FALLBACK_TO_WWAN_IMS_REGI_FAIL,
+ QnsProtoEnums.RESTRICT_TYPE_FALLBACK_TO_WWAN_IMS_REGI_FAIL);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_FALLBACK_ON_DATA_CONNECTION_FAIL,
+ QnsProtoEnums.RESTRICT_TYPE_FALLBACK_ON_DATA_CONNECTION_FAIL);
+ sAtomRestrictionsMap.put(
+ RestrictManager.RESTRICT_TYPE_FALLBACK_TO_WWAN_RTT_BACKHAUL_FAIL,
+ QnsProtoEnums.RESTRICT_TYPE_FALLBACK_TO_WWAN_RTT_BACKHAUL_FAIL);
+ }
+
+ private int getRestrictionsBitmask(int transportType, RestrictManager restrictManager) {
+ int restrictions = QnsProtoEnums.RESTRICT_TYPE_NONE;
+ for (int restrictionType : sAtomRestrictionsMap.keySet()) {
+ if (restrictManager.hasRestrictionType(transportType, restrictionType)) {
+ restrictions |= sAtomRestrictionsMap.get(restrictionType);
+ }
+ }
+ return restrictions;
+ }
+
+ private int getSignalStrength(QualityMonitor qm, int accessNetworkType) {
+ switch (accessNetworkType) {
+ case AccessNetworkType.GERAN:
+ case AccessNetworkType.IWLAN:
+ return qm.getCurrentQuality(
+ accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI);
+ case AccessNetworkType.UTRAN:
+ return qm.getCurrentQuality(
+ accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP);
+ case AccessNetworkType.EUTRAN:
+ return qm.getCurrentQuality(
+ accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP);
+ case AccessNetworkType.NGRAN:
+ return qm.getCurrentQuality(
+ accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP);
+ }
+ return 0;
+ }
+
+ private int getSignalQuality(QualityMonitor qm, int accessNetworkType) {
+ switch (accessNetworkType) {
+ case AccessNetworkType.EUTRAN:
+ return qm.getCurrentQuality(
+ accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ);
+ case AccessNetworkType.NGRAN:
+ return qm.getCurrentQuality(
+ accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ);
+ }
+ return 0;
+ }
+
+ private int getSignalNoise(QualityMonitor qm, int accessNetworkType) {
+ switch (accessNetworkType) {
+ case AccessNetworkType.EUTRAN:
+ return qm.getCurrentQuality(
+ accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR);
+ case AccessNetworkType.NGRAN:
+ return qm.getCurrentQuality(
+ accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR);
+ }
+ return 0;
+ }
+
+ protected void log(String s) {
+ Log.d(mLogTag, s);
+ }
+}
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsTelephonyListener.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsTelephonyListener.java
index 32883d4..9e59736 100644
--- a/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsTelephonyListener.java
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/QnsTelephonyListener.java
@@ -37,6 +37,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.telephony.VopsSupportInfo;
+import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.MediaQualityStatus;
import android.util.Log;
@@ -69,6 +70,7 @@ class QnsTelephonyListener {
QnsRegistrantList mSrvccStateListener = new QnsRegistrantList();
QnsRegistrantList mSubscriptionIdListener = new QnsRegistrantList();
QnsRegistrantList mIwlanServiceStateListener = new QnsRegistrantList();
+ QnsRegistrantList mImsCallDropDisconnectCauseListener = new QnsRegistrantList();
List<Consumer<List<CallState>>> mCallStatesConsumerList = new ArrayList<>();
List<Consumer<Integer>> mSrvccStateConsumerList = new ArrayList<>();
List<Consumer<MediaQualityStatus>> mMediaQualityConsumerList = new ArrayList<>();
@@ -327,6 +329,21 @@ class QnsTelephonyListener {
}
/**
+ * Register an event for ImsCallDropDisconnectCause changed.
+ *
+ * @param h the Handler to get event.
+ * @param what the event.
+ * @param userObj user object.
+ */
+ void registerImsCallDropDisconnectCauseListener(Handler h, int what, Object userObj) {
+ log("registerImsCallDropDisconnectCauseListener");
+ if (h != null) {
+ QnsRegistrant r = new QnsRegistrant(h, what, userObj);
+ mImsCallDropDisconnectCauseListener.add(r);
+ }
+ }
+
+ /**
* Unregister an event for QnsTelephonyInfo changed.
*
* @param netCapability Network Capability to be notified.
@@ -406,6 +423,18 @@ class QnsTelephonyListener {
}
}
+ /**
+ * Unregister an event for ImsCallDropDisconnectCause state changed.
+ *
+ * @param h the handler to get event.
+ */
+ void unregisterImsCallDropDisconnectCauseListener(Handler h) {
+ log("unregisterImsCallDropDisconnectCauseListener");
+ if (h != null) {
+ mImsCallDropDisconnectCauseListener.remove(h);
+ }
+ }
+
private void createTelephonyListener() {
if (mTelephonyListener == null) {
mTelephonyListener = new TelephonyListener(mContext.getMainExecutor());
@@ -429,6 +458,10 @@ class QnsTelephonyListener {
(int srvccState) -> {
onSrvccStateChanged(srvccState);
});
+ mTelephonyListener.setImsCallDisconnectCauseListener(
+ (ImsReasonInfo imsReasonInfo) -> {
+ onImsCallDisconnectCauseChanged(imsReasonInfo);
+ });
}
}
@@ -721,6 +754,10 @@ class QnsTelephonyListener {
mSubscriptionIdListener.notifyResult(subId);
}
+ protected void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReasonInfo) {
+ mImsCallDropDisconnectCauseListener.notifyResult(imsReasonInfo);
+ }
+
protected void log(String s) {
Log.d(mLogTag, s);
}
@@ -769,6 +806,11 @@ class QnsTelephonyListener {
void onCallStatesChanged(List<CallState> callStateList);
}
+ protected interface OnImsCallDisconnectCauseListener {
+ /** Notify the call disconnected cause changed. */
+ void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo);
+ }
+
protected static class Archiving<V> {
protected HashMap<String, V> mArchiving = new HashMap<>();
@@ -1037,7 +1079,8 @@ class QnsTelephonyListener {
TelephonyCallback.CallStateListener,
TelephonyCallback.SrvccStateListener,
TelephonyCallback.CallAttributesListener,
- TelephonyCallback.MediaQualityStatusChangedListener {
+ TelephonyCallback.MediaQualityStatusChangedListener,
+ TelephonyCallback.ImsCallDisconnectCauseListener {
private final Executor mExecutor;
private OnServiceStateListener mServiceStateListener;
private OnPreciseDataConnectionStateListener mPreciseDataConnectionStateListener;
@@ -1046,6 +1089,7 @@ class QnsTelephonyListener {
private OnSrvccStateChangedCallback mSrvccStateCallback;
private OnSrvccStateChangedCallback mSrvccStateListener;
private OnCallStatesChangedCallback mCallStatesCallback;
+ private OnImsCallDisconnectCauseListener mImsCallDisconnectCauseListener;
private TelephonyManager mTelephonyManager;
TelephonyListener(Executor executor) {
@@ -1080,6 +1124,11 @@ class QnsTelephonyListener {
void setCallStatesCallback(OnCallStatesChangedCallback listener) {
mCallStatesCallback = listener;
}
+
+ void setImsCallDisconnectCauseListener(OnImsCallDisconnectCauseListener listener) {
+ mImsCallDisconnectCauseListener = listener;
+ }
+
/**
* Register a TelephonyCallback for this listener.
*
@@ -1168,6 +1217,13 @@ class QnsTelephonyListener {
consumer.accept(status);
}
}
+
+ @Override
+ public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) {
+ if (mImsCallDisconnectCauseListener != null) {
+ mImsCallDisconnectCauseListener.onImsCallDisconnectCauseChanged(imsReasonInfo);
+ }
+ }
}
void addCallStatesChangedCallback(Consumer<List<CallState>> consumer) {
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/RestrictManager.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/RestrictManager.java
index 9ae8a1d..1c15346 100644
--- a/services/QualifiedNetworksService/src/com/android/telephony/qns/RestrictManager.java
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/RestrictManager.java
@@ -162,6 +162,7 @@ class RestrictManager {
private QnsCallStatusTracker.ActiveCallTracker mActiveCallTracker;
private QnsImsManager mQnsImsManager;
private WifiBackhaulMonitor mWifiBackhaulMonitor;
+ private QnsMetrics mQnsMetrics;
private int mNetCapability;
private int mSlotId;
private int mTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
@@ -456,6 +457,7 @@ class RestrictManager {
mDataConnectionStatusTracker = dcst;
mQnsCallStatusTracker = qnsComponents.getQnsCallStatusTracker(mSlotId);
mActiveCallTracker = qnsComponents.getQnsCallStatusTracker(mSlotId).getActiveCallTracker();
+ mQnsMetrics = qnsComponents.getQnsMetrics();
mDataConnectionStatusTracker.registerDataConnectionStatusChanged(
mHandler, EVENT_DATA_CONNECTION_CHANGED);
if (mNetCapability == NetworkCapabilities.NET_CAPABILITY_IMS) {
@@ -1440,6 +1442,9 @@ class RestrictManager {
Log.d(mLogTag, "notifyRestrictInfoChanged");
if (mRestrictInfoRegistrant != null) {
mRestrictInfoRegistrant.notifyResult(mRestrictInfos);
+
+ // metrics
+ sendRestrictionsForMetrics();
} else {
Log.d(mLogTag, "notifyRestrictInfoChanged. no Registrant.");
}
@@ -1684,4 +1689,24 @@ class RestrictManager {
+ QnsConstants.callStateToString(mCallState));
pw.println(prefix + "mRestrictInfos=" + mRestrictInfos);
}
+
+ private void sendRestrictionsForMetrics() {
+ if (mNetCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
+ return;
+ }
+ ArrayList<Integer> wlanRestrictions =
+ new ArrayList<>(
+ mRestrictInfos
+ .get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+ .getRestrictionMap()
+ .keySet());
+ ArrayList<Integer> wwanRestrictions =
+ new ArrayList<>(
+ mRestrictInfos
+ .get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+ .getRestrictionMap()
+ .keySet());
+ mQnsMetrics.reportAtomForRestrictions(mNetCapability, mSlotId,
+ wlanRestrictions, wwanRestrictions, mQnsCarrierConfigManager.getCarrierId());
+ }
}
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsFallbackRestrictionChangedInfo.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsFallbackRestrictionChangedInfo.java
new file mode 100644
index 0000000..05a2fdf
--- /dev/null
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsFallbackRestrictionChangedInfo.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.qns.atoms;
+
+import android.util.StatsEvent;
+
+import com.android.telephony.qns.stats.QnsStatsLog;
+import com.android.telephony.statslib.AtomsPushed;
+
+import java.util.Objects;
+
+/** AtomsQnsFallbackRestrictionChangedInfo class */
+public class AtomsQnsFallbackRestrictionChangedInfo extends AtomsPushed {
+
+ /** atom #1 : Restriction on WLAN caused by RTP threshold breached */
+ private boolean mRestrictionOnWlanByRtpThresholdBreached;
+
+ /** atom #2 : Restriction on WWAN caused by RTP threshold breached */
+ private boolean mRestrictionOnWwanByRtpThresholdBreached;
+
+ /** atom #3 : Restriction on WLAN caused by IMS registration fail */
+ private boolean mRestrictionOnWlanByImsRegistrationFailed;
+
+ /** atom #4 : Restriction on WLAN caused by Wi-Fi backhaul problem. */
+ private boolean mRestrictionOnWlanByWifiBackhaulProblem;
+
+ /** atom #5 : Carrier Id */
+ private int mCarrierId;
+
+ /** atom #6 : Slot Index */
+ private int mSlotIndex;
+
+ /** Constructor of AtomsQnsFallbackRestrictionChangedInfo */
+ public AtomsQnsFallbackRestrictionChangedInfo() {}
+
+ /**
+ * Constructor of AtomsQnsFallbackRestrictionChangedInfo
+ *
+ * @param restrictionOnWlanByRtpThresholdBreached Restriction on wlan caused by RTP threshold
+ * breached
+ * @param restrictionOnWwanByRtpThresholdBreached Restriction on wwan caused by RTP threshold
+ * breached
+ * @param restrictionOnWlanByImsRegistrationFailed Restriction on wlan caused by IMS
+ * registration fail
+ * @param restrictionOnWlanByWifiBackhaulProblem Restriction on wlan caused by Wifi backhaul
+ * problem.
+ * @param carrierId Carrier Id
+ * @param slotIndex Index of sim slot
+ */
+ public AtomsQnsFallbackRestrictionChangedInfo(
+ boolean restrictionOnWlanByRtpThresholdBreached,
+ boolean restrictionOnWwanByRtpThresholdBreached,
+ boolean restrictionOnWlanByImsRegistrationFailed,
+ boolean restrictionOnWlanByWifiBackhaulProblem,
+ int carrierId,
+ int slotIndex) {
+ mRestrictionOnWlanByRtpThresholdBreached = restrictionOnWlanByRtpThresholdBreached;
+ mRestrictionOnWwanByRtpThresholdBreached = restrictionOnWwanByRtpThresholdBreached;
+ mRestrictionOnWlanByImsRegistrationFailed = restrictionOnWlanByImsRegistrationFailed;
+ mRestrictionOnWlanByWifiBackhaulProblem = restrictionOnWlanByWifiBackhaulProblem;
+ mCarrierId = carrierId;
+ mSlotIndex = slotIndex;
+ }
+
+ /**
+ * Copy Constructor of AtomsQnsFallbackRestrictionChangedInfo
+ *
+ * @param info The info param to copy from.
+ */
+ public AtomsQnsFallbackRestrictionChangedInfo(AtomsQnsFallbackRestrictionChangedInfo info) {
+ mRestrictionOnWlanByRtpThresholdBreached = info.mRestrictionOnWlanByRtpThresholdBreached;
+ mRestrictionOnWwanByRtpThresholdBreached = info.mRestrictionOnWwanByRtpThresholdBreached;
+ mRestrictionOnWlanByImsRegistrationFailed = info.mRestrictionOnWlanByImsRegistrationFailed;
+ mRestrictionOnWlanByWifiBackhaulProblem = info.mRestrictionOnWlanByWifiBackhaulProblem;
+ mCarrierId = info.mCarrierId;
+ mSlotIndex = info.mSlotIndex;
+ }
+
+ /**
+ * Write the atom information to be recorded to the builder according to the type in order.
+ *
+ * @param builder Builder class for StatsEvent Builder object.
+ */
+ @Override
+ public void build(StatsEvent.Builder builder) {
+ builder.writeBoolean(mRestrictionOnWlanByRtpThresholdBreached); // atom #1
+ builder.writeBoolean(mRestrictionOnWwanByRtpThresholdBreached); // atom #2
+ builder.writeBoolean(mRestrictionOnWlanByImsRegistrationFailed); // atom #3
+ builder.writeBoolean(mRestrictionOnWlanByWifiBackhaulProblem); // atom #4
+ builder.writeInt(mCarrierId); // atom #5
+ builder.writeInt(mSlotIndex); // atom #6
+ }
+
+ /** Return atom id defined in proto. */
+ @Override
+ public int getStatsId() {
+ return QnsStatsLog.QNS_FALLBACK_RESTRICTION_CHANGED;
+ }
+
+ /** Return copy of the AtomsQnsFallbackRestrictionChangedInfo */
+ @Override
+ public AtomsPushed copy() {
+ return new AtomsQnsFallbackRestrictionChangedInfo(this);
+ }
+
+ public boolean getRestrictionOnWlanByRtpThresholdBreached() {
+ return mRestrictionOnWlanByRtpThresholdBreached;
+ }
+
+ public void setRestrictionOnWlanByRtpThresholdBreached(
+ boolean restrictionOnWlanByRtpThresholdBreached) {
+ mRestrictionOnWlanByRtpThresholdBreached = restrictionOnWlanByRtpThresholdBreached;
+ }
+
+ public boolean getRestrictionOnWwanByRtpThresholdBreached() {
+ return mRestrictionOnWwanByRtpThresholdBreached;
+ }
+
+ public void setRestrictionOnWwanByRtpThresholdBreached(
+ boolean restrictionOnWwanByRtpThresholdBreached) {
+ mRestrictionOnWwanByRtpThresholdBreached = restrictionOnWwanByRtpThresholdBreached;
+ }
+
+ public boolean getRestrictionOnWlanByImsRegistrationFailed() {
+ return mRestrictionOnWlanByImsRegistrationFailed;
+ }
+
+ public void setRestrictionOnWlanByImsRegistrationFailed(
+ boolean restrictionOnWlanByImsRegistrationFailed) {
+ mRestrictionOnWlanByImsRegistrationFailed = restrictionOnWlanByImsRegistrationFailed;
+ }
+
+ public boolean getRestrictionOnWlanByWifiBackhaulProblem() {
+ return mRestrictionOnWlanByWifiBackhaulProblem;
+ }
+
+ public void setRestrictionOnWlanByWifiBackhaulProblem(
+ boolean restrictionOnWlanByWifiBackhaulProblem) {
+ mRestrictionOnWlanByWifiBackhaulProblem = restrictionOnWlanByWifiBackhaulProblem;
+ }
+
+ public int getCarrierId() {
+ return mCarrierId;
+ }
+
+ public void setCarrierId(int carrierId) {
+ mCarrierId = carrierId;
+ }
+
+ public int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ public void setSlotIndex(int slotIndex) {
+ mSlotIndex = slotIndex;
+ }
+
+ @Override
+ public String toString() {
+ return "AtomsQnsFallbackRestrictionChangedInfo{"
+ + "mRestrictionWlanRtpThresholdBreached="
+ + mRestrictionOnWlanByRtpThresholdBreached
+ + ", mRestrictionWwanRtpThresholdBreached="
+ + mRestrictionOnWwanByRtpThresholdBreached
+ + ", mRestrictionWwanImsRegiFail="
+ + mRestrictionOnWlanByImsRegistrationFailed
+ + ", mRestrictionWwanWifiBackhaulProblem="
+ + mRestrictionOnWlanByWifiBackhaulProblem
+ + ", mCarrierId="
+ + mCarrierId
+ + ", mSlotIndex="
+ + mSlotIndex
+ + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AtomsQnsFallbackRestrictionChangedInfo)) return false;
+ AtomsQnsFallbackRestrictionChangedInfo that = (AtomsQnsFallbackRestrictionChangedInfo) o;
+ return mRestrictionOnWlanByRtpThresholdBreached
+ == that.mRestrictionOnWlanByRtpThresholdBreached
+ && mRestrictionOnWwanByRtpThresholdBreached
+ == that.mRestrictionOnWwanByRtpThresholdBreached
+ && mRestrictionOnWlanByImsRegistrationFailed
+ == that.mRestrictionOnWlanByImsRegistrationFailed
+ && mRestrictionOnWlanByWifiBackhaulProblem
+ == that.mRestrictionOnWlanByWifiBackhaulProblem
+ && mCarrierId == that.mCarrierId
+ && mSlotIndex == that.mSlotIndex;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ mRestrictionOnWlanByRtpThresholdBreached,
+ mRestrictionOnWwanByRtpThresholdBreached,
+ mRestrictionOnWlanByImsRegistrationFailed,
+ mRestrictionOnWlanByWifiBackhaulProblem,
+ mCarrierId,
+ mSlotIndex);
+ }
+}
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsHandoverPingPongInfo.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsHandoverPingPongInfo.java
new file mode 100644
index 0000000..a714e58
--- /dev/null
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsHandoverPingPongInfo.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.qns.atoms;
+
+import android.util.StatsEvent;
+
+import com.android.telephony.qns.stats.QnsStatsLog;
+import com.android.telephony.statslib.AtomsPulled;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/** AtomsQnsHandoverPingPongInfo class */
+public class AtomsQnsHandoverPingPongInfo extends AtomsPulled implements Serializable {
+
+ private static final long serialVersionUID = 815898959L; // 0x30A1A14F
+
+ /** atom #1 : Count of handover ping-pong */
+ private int mCountHandoverPingPong;
+
+ /** atom #2 : Carrier Id */
+ private int mCarrierId;
+
+ /** atom #3 : Slot Index */
+ private int mSlotIndex;
+
+ /** Constructor of AtomsQnsHandoverPingPongInfo */
+ public AtomsQnsHandoverPingPongInfo() {}
+
+ /**
+ * Constructor of AtomsQnsHandoverPingPongInfo
+ *
+ * @param countHandoverPingPong count of Handover Ping-Pong
+ * @param carrierId Carrier Id
+ * @param slotIndex Index of sim slot
+ */
+ public AtomsQnsHandoverPingPongInfo(int countHandoverPingPong, int carrierId, int slotIndex) {
+ mCountHandoverPingPong = countHandoverPingPong;
+ mCarrierId = carrierId;
+ mSlotIndex = slotIndex;
+ }
+
+ /**
+ * Copy Constructor of AtomsQnsHandoverPingPongInfo
+ *
+ * @param info The info param to copy from.
+ */
+ public AtomsQnsHandoverPingPongInfo(AtomsQnsHandoverPingPongInfo info) {
+ mCountHandoverPingPong = info.mCountHandoverPingPong;
+ mCarrierId = info.mCarrierId;
+ mSlotIndex = info.mSlotIndex;
+ }
+
+ /**
+ * Write the atom information to be recorded to the builder according to the type in order.
+ *
+ * @param builder Builder class for StatsEvent Builder object.
+ */
+ @Override
+ public void build(StatsEvent.Builder builder) {
+ builder.writeInt(mCountHandoverPingPong); // atom #1
+ builder.writeInt(mCarrierId); // atom #2
+ builder.writeInt(mSlotIndex); // atom #3
+ }
+
+ /** Return atom id defined in proto. */
+ @Override
+ public int getStatsId() {
+ return QnsStatsLog.QNS_HANDOVER_PINGPONG;
+ }
+
+ /** Return copy of the AtomsQnsHandoverPingPongInfo */
+ @Override
+ public AtomsPulled copy() {
+ return new AtomsQnsHandoverPingPongInfo(this);
+ }
+
+ @Override
+ public String getDimension() {
+ return mCarrierId + "_" + mSlotIndex;
+ }
+
+ @Override
+ public void accumulate(AtomsPulled info) {
+ if (!(info instanceof AtomsQnsHandoverPingPongInfo)) {
+ return;
+ }
+ AtomsQnsHandoverPingPongInfo atomsQnsHandoverPingPongInfo =
+ (AtomsQnsHandoverPingPongInfo) info;
+ this.mCountHandoverPingPong += atomsQnsHandoverPingPongInfo.getCountHandoverPingPong();
+ }
+
+ public int getCountHandoverPingPong() {
+ return mCountHandoverPingPong;
+ }
+
+ public void setCountHandoverPingPong(int countHandoverPingPong) {
+ mCountHandoverPingPong = countHandoverPingPong;
+ }
+
+ public int getCarrierId() {
+ return mCarrierId;
+ }
+
+ public void setCarrierId(int carrierId) {
+ mCarrierId = carrierId;
+ }
+
+ public int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ public void setSlotIndex(int slotIndex) {
+ mSlotIndex = slotIndex;
+ }
+
+ @Override
+ public String toString() {
+ return "AtomsQnsHandoverPingPongInfo{"
+ + "mCountHandoverPingPong="
+ + mCountHandoverPingPong
+ + ", mCarrierId="
+ + mCarrierId
+ + ", mSlotIndex="
+ + mSlotIndex
+ + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AtomsQnsHandoverPingPongInfo)) return false;
+ AtomsQnsHandoverPingPongInfo that = (AtomsQnsHandoverPingPongInfo) o;
+ return mCountHandoverPingPong == that.mCountHandoverPingPong
+ && mCarrierId == that.mCarrierId
+ && mSlotIndex == that.mSlotIndex;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mCountHandoverPingPong, mCarrierId, mSlotIndex);
+ }
+
+ public static long PING_PONG_TIME_IN_MILLIS = 5000L;
+}
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsHandoverTimeMillisInfo.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsHandoverTimeMillisInfo.java
new file mode 100644
index 0000000..e6924ac
--- /dev/null
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsHandoverTimeMillisInfo.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.qns.atoms;
+
+import android.util.StatsEvent;
+
+import com.android.telephony.qns.stats.QnsStatsLog;
+import com.android.telephony.statslib.AtomsPulled;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/** AtomsQnsHandoverTimeMillisInfo class */
+public class AtomsQnsHandoverTimeMillisInfo extends AtomsPulled implements Serializable {
+
+ private static final long serialVersionUID = 1379441656L; // 0x52389BF8
+
+ /** atom #1 : Time in milliseconds from QNS RAT update to successful HO completion */
+ private int mTimeForHoSuccess;
+
+ /** atom #2 : Slot Index */
+ private int mSlotIndex;
+
+ /** Constructor of AtomsQnsHandoverTimeMillisInfo */
+ public AtomsQnsHandoverTimeMillisInfo() {}
+
+ /**
+ * Constructor of AtomsQnsHandoverTimeMillisInfo
+ *
+ * @param timeForHoSuccess Time in milliseconds from QNS RAT update to successful HO completion
+ * @param slotIndex Index of sim slot
+ */
+ public AtomsQnsHandoverTimeMillisInfo(int timeForHoSuccess, int slotIndex) {
+ mTimeForHoSuccess = timeForHoSuccess;
+ mSlotIndex = slotIndex;
+ }
+
+ /**
+ * Copy Constructor of AtomsQnsHandoverTimeMillisInfo
+ *
+ * @param info The info param to copy from.
+ */
+ public AtomsQnsHandoverTimeMillisInfo(AtomsQnsHandoverTimeMillisInfo info) {
+ mTimeForHoSuccess = info.mTimeForHoSuccess;
+ mSlotIndex = info.mSlotIndex;
+ }
+
+ /**
+ * Write the atom information to be recorded to the builder according to the type in order.
+ *
+ * @param builder Builder class for StatsEvent Builder object.
+ */
+ @Override
+ public void build(StatsEvent.Builder builder) {
+ builder.writeInt(mTimeForHoSuccess); // atom #1
+ builder.writeInt(mSlotIndex); // atom #2
+ }
+
+ /** Return atom id defined in proto. */
+ @Override
+ public int getStatsId() {
+ return QnsStatsLog.QNS_HANDOVER_TIME_MILLIS;
+ }
+
+ /** Return copy of the AtomsQnsHandoverTimeMillisInfo */
+ @Override
+ public AtomsPulled copy() {
+ return new AtomsQnsHandoverTimeMillisInfo(this);
+ }
+
+ @Override
+ public String getDimension() {
+ return Integer.toString(mSlotIndex);
+ }
+
+ @Override
+ public void accumulate(AtomsPulled info) {
+ if (!(info instanceof AtomsQnsRatPreferenceMismatchInfo)) {
+ return;
+ }
+ AtomsQnsHandoverTimeMillisInfo atomsQnsHandoverTimeMillisInfo =
+ (AtomsQnsHandoverTimeMillisInfo) info;
+ this.mTimeForHoSuccess += atomsQnsHandoverTimeMillisInfo.getTimeForHoSuccess();
+ }
+
+ public int getTimeForHoSuccess() {
+ return mTimeForHoSuccess;
+ }
+
+ public void setTimeForHoSuccess(int timeForHoSuccess) {
+ mTimeForHoSuccess = timeForHoSuccess;
+ }
+
+ public int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ public void setSlotIndex(int slotIndex) {
+ mSlotIndex = slotIndex;
+ }
+
+ @Override
+ public String toString() {
+ return "AtomsQnsHandoverTimeMillisInfo{" + "mTimeForHoSuccess=" + mTimeForHoSuccess + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AtomsQnsHandoverTimeMillisInfo)) return false;
+ AtomsQnsHandoverTimeMillisInfo that = (AtomsQnsHandoverTimeMillisInfo) o;
+ return mTimeForHoSuccess == that.mTimeForHoSuccess && mSlotIndex == that.mSlotIndex;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mTimeForHoSuccess, mSlotIndex);
+ }
+}
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsImsCallDropStats.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsImsCallDropStats.java
new file mode 100644
index 0000000..991bce4
--- /dev/null
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsImsCallDropStats.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.qns.atoms;
+
+import android.util.StatsEvent;
+
+import com.android.telephony.qns.stats.QnsStatsLog;
+import com.android.telephony.statslib.AtomsPushed;
+
+import java.util.Objects;
+
+/** AtomsQnsImsCallDropStats class */
+public class AtomsQnsImsCallDropStats extends AtomsPushed {
+
+ /** atom #1 : Transport type in where IMS call drop occurred. */
+ private int mTransportTypeCallDropped;
+
+ /** atom #2 : RTP threshold breached event occurred. */
+ private boolean mRtpThresholdBreached;
+
+ /** atom #3 : Bit mask of restrictions on another transport type */
+ private int mRestrictionsOnOtherTransportType;
+
+ /** atom #4 : Cellular network signal strength {e.g. SSRSRP in NR, RSRP in LTE} */
+ private int mSignalStrength;
+
+ /** atom #5 : Cellular network signal quality {e.g. SSRSRQ in NR, RSRQ in LTE} */
+ private int mSignalQuality;
+
+ /** atom #6 : Cellular network signal noise ratio {e.g. SSSINR in NR, RSSNR in LTE} */
+ private int mSignalNoise;
+
+ /** atom #7 : Iwlan network signal strength (Wi-Fi RSSI) */
+ private int mIwlanSignalStrength;
+
+ /** atom #8 : Slot Index */
+ private int mSlotIndex;
+
+ /** atom #9 : cellular access network type. */
+ private int mCellularNetworkType;
+
+ /** Constructor of AtomsQnsImsCallDropStats */
+ public AtomsQnsImsCallDropStats() {}
+
+ /**
+ * Write the atom information to be recorded to the builder according to the type in order.
+ *
+ * @param builder Builder class for StatsEvent Builder object.
+ */
+ @Override
+ public void build(StatsEvent.Builder builder) {
+ builder.writeInt(mTransportTypeCallDropped); // atom #1
+ builder.writeBoolean(mRtpThresholdBreached); // atom #2
+ builder.writeInt(mRestrictionsOnOtherTransportType); // atom #3
+ builder.writeInt(mSignalStrength); // atom #4
+ builder.writeInt(mSignalQuality); // atom #5
+ builder.writeInt(mSignalNoise); // atom #6
+ builder.writeInt(mIwlanSignalStrength); // atom #7
+ builder.writeInt(mSlotIndex); // atom #8
+ builder.writeInt(mCellularNetworkType); // atom #9
+ }
+
+ /** Return atom id defined in proto. */
+ @Override
+ public int getStatsId() {
+ return QnsStatsLog.QNS_IMS_CALL_DROP_STATS;
+ }
+
+ /** Return copy of the AtomsQnsImsCallDropStats */
+ @Override
+ public AtomsPushed copy() {
+ return new AtomsQnsImsCallDropStats(this);
+ }
+
+ /**
+ * Constructor of AtomsQnsImsCallDropStats
+ *
+ * @param transportTypeCallDropped Transport type in where IMS call drop occurred.
+ * @param rtpThresholdBreached RTP threshold breached event occurred.
+ * @param restrictionsOnOtherTransportType Bit mask of restrictions on another transport type.
+ * @param signalStrength Cellular network signal strength.
+ * @param signalQuality Cellular network signal quality.
+ * @param signalNoise Cellular network signal noise ratio.
+ * @param iwlanSignalStrength Wi-Fi network signal strength.
+ * @param slotIndex Index of sim slot.
+ * @param cellularNetworkType cellular access network type.
+ */
+ public AtomsQnsImsCallDropStats(
+ int transportTypeCallDropped,
+ boolean rtpThresholdBreached,
+ int restrictionsOnOtherTransportType,
+ int signalStrength,
+ int signalQuality,
+ int signalNoise,
+ int iwlanSignalStrength,
+ int slotIndex,
+ int cellularNetworkType) {
+ mTransportTypeCallDropped = transportTypeCallDropped;
+ mRtpThresholdBreached = rtpThresholdBreached;
+ mRestrictionsOnOtherTransportType = restrictionsOnOtherTransportType;
+ mSignalStrength = signalStrength;
+ mSignalQuality = signalQuality;
+ mSignalNoise = signalNoise;
+ mIwlanSignalStrength = iwlanSignalStrength;
+ mSlotIndex = slotIndex;
+ mCellularNetworkType = cellularNetworkType;
+ }
+
+ /**
+ * Copy Constructor of AtomsQnsImsCallDropStats
+ *
+ * @param info The info param to copy from.
+ */
+ public AtomsQnsImsCallDropStats(AtomsQnsImsCallDropStats info) {
+ mTransportTypeCallDropped = info.mTransportTypeCallDropped;
+ mRtpThresholdBreached = info.mRtpThresholdBreached;
+ mRestrictionsOnOtherTransportType = info.mRestrictionsOnOtherTransportType;
+ mSignalStrength = info.mSignalStrength;
+ mSignalQuality = info.mSignalQuality;
+ mSignalNoise = info.mSignalNoise;
+ mIwlanSignalStrength = info.mIwlanSignalStrength;
+ mSlotIndex = info.mSlotIndex;
+ mCellularNetworkType = info.mCellularNetworkType;
+ }
+
+ public int getTransportTypeCallDropped() {
+ return mTransportTypeCallDropped;
+ }
+
+ public void setTransportTypeCallDropped(int transportTypeCallDropped) {
+ mTransportTypeCallDropped = transportTypeCallDropped;
+ }
+
+ public boolean getRtpThresholdBreached() {
+ return mRtpThresholdBreached;
+ }
+
+ public void setRtpThresholdBreached(boolean rtpThresholdBreached) {
+ mRtpThresholdBreached = rtpThresholdBreached;
+ }
+
+ public int getRestrictionsOnOtherTransportType() {
+ return mRestrictionsOnOtherTransportType;
+ }
+
+ public void setRestrictionsOnOtherTransportType(int restrictionsOnOtherTransportType) {
+ mRestrictionsOnOtherTransportType = restrictionsOnOtherTransportType;
+ }
+
+ public int getSignalStrength() {
+ return mSignalStrength;
+ }
+
+ public void setSignalStrength(int signalStrength) {
+ mSignalStrength = signalStrength;
+ }
+
+ public int getSignalQuality() {
+ return mSignalQuality;
+ }
+
+ public void setSignalQuality(int signalQuality) {
+ mSignalQuality = signalQuality;
+ }
+
+ public int getSignalNoise() {
+ return mSignalNoise;
+ }
+
+ public void setSignalNoise(int signalNoise) {
+ mSignalNoise = signalNoise;
+ }
+
+ public int getIwlanSignalStrength() {
+ return mIwlanSignalStrength;
+ }
+
+ public void setIwlanSignalStrength(int iwlanSignalStrength) {
+ mIwlanSignalStrength = iwlanSignalStrength;
+ }
+
+ public int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ public void setSlotIndex(int slotIndex) {
+ mSlotIndex = slotIndex;
+ }
+
+ public int getCellularNetworkType() {
+ return mCellularNetworkType;
+ }
+
+ public void setCellularNetworkType(int cellularNetworkType) {
+ mCellularNetworkType = cellularNetworkType;
+ }
+
+ @Override
+ public String toString() {
+ return "AtomsQnsImsCallDropStats{"
+ + "mTransportTypeCallDropped="
+ + mTransportTypeCallDropped
+ + ", mRtpThresholdBreached="
+ + mRtpThresholdBreached
+ + ", mRestrictionsOnOtherTransportType="
+ + mRestrictionsOnOtherTransportType
+ + ", mSignalStrength="
+ + mSignalStrength
+ + ", mSignalQuality="
+ + mSignalQuality
+ + ", mSignalNoise="
+ + mSignalNoise
+ + ", mIwlanSignalStrength="
+ + mIwlanSignalStrength
+ + ", mSlotIndex="
+ + mSlotIndex
+ + ", mCellularNetworkType="
+ + mCellularNetworkType
+ + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AtomsQnsImsCallDropStats)) return false;
+ AtomsQnsImsCallDropStats that = (AtomsQnsImsCallDropStats) o;
+ return mTransportTypeCallDropped == that.mTransportTypeCallDropped
+ && mRtpThresholdBreached == that.mRtpThresholdBreached
+ && mRestrictionsOnOtherTransportType == that.mRestrictionsOnOtherTransportType
+ && mSignalStrength == that.mSignalStrength
+ && mSignalQuality == that.mSignalQuality
+ && mSignalNoise == that.mSignalNoise
+ && mIwlanSignalStrength == that.mIwlanSignalStrength
+ && mSlotIndex == that.mSlotIndex
+ && mCellularNetworkType == that.mCellularNetworkType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ mTransportTypeCallDropped,
+ mRtpThresholdBreached,
+ mRestrictionsOnOtherTransportType,
+ mSignalStrength,
+ mSignalQuality,
+ mSignalNoise,
+ mIwlanSignalStrength,
+ mSlotIndex,
+ mCellularNetworkType);
+ }
+}
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsRatPreferenceMismatchInfo.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsRatPreferenceMismatchInfo.java
new file mode 100644
index 0000000..150f6a1
--- /dev/null
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQnsRatPreferenceMismatchInfo.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.qns.atoms;
+
+import android.util.StatsEvent;
+
+import com.android.telephony.qns.stats.QnsStatsLog;
+import com.android.telephony.statslib.AtomsPulled;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/** AtomsQnsRatPreferenceMismatchInfo class */
+public class AtomsQnsRatPreferenceMismatchInfo extends AtomsPulled implements Serializable {
+
+ private static final long serialVersionUID = 1913485192L; // 0x720D7788
+
+ /** atom #1 : Net capability of this information. */
+ private int mNetCapability;
+
+ /** atom #2 : Count of handover failed. */
+ private int mHandoverFailCount;
+
+ /** atom #3 : Duration of this mismatch. */
+ private int mDurationOfMismatch;
+
+ /** atom #4 : Carrier Id */
+ private int mCarrierId;
+
+ /** atom #5 : Slot Index */
+ private int mSlotIndex;
+
+ /** Constructor of AtomsQnsRatPreferenceMismatchInfo */
+ public AtomsQnsRatPreferenceMismatchInfo() {}
+
+ /**
+ * Constructor of AtomsQnsRatPreferenceMismatchInfo
+ *
+ * @param netCapability Net capability of this information.
+ * @param handoverFailCount Count of handover failed.
+ * @param durationOfMismatch Duration of this mismatch.
+ * @param carrierId Carrier Id
+ * @param slotIndex Index of sim slot
+ */
+ public AtomsQnsRatPreferenceMismatchInfo(
+ int netCapability,
+ int handoverFailCount,
+ int durationOfMismatch,
+ int carrierId,
+ int slotIndex) {
+ mNetCapability = netCapability;
+ mHandoverFailCount = handoverFailCount;
+ mDurationOfMismatch = durationOfMismatch;
+ mCarrierId = carrierId;
+ mSlotIndex = slotIndex;
+ }
+
+ /**
+ * Copy Constructor of AtomsQnsRatPreferenceMismatchInfo
+ *
+ * @param info The info param to copy from.
+ */
+ public AtomsQnsRatPreferenceMismatchInfo(AtomsQnsRatPreferenceMismatchInfo info) {
+ mNetCapability = info.mNetCapability;
+ mHandoverFailCount = info.mHandoverFailCount;
+ mDurationOfMismatch = info.mDurationOfMismatch;
+ mCarrierId = info.mCarrierId;
+ mSlotIndex = info.mSlotIndex;
+ }
+
+ /**
+ * Write the atom information to be recorded to the builder according to the type in order.
+ *
+ * @param builder Builder class for StatsEvent Builder object.
+ */
+ @Override
+ public void build(StatsEvent.Builder builder) {
+ builder.writeInt(mNetCapability); // atom #1
+ builder.writeInt(mHandoverFailCount); // atom #2
+ builder.writeInt(mDurationOfMismatch); // atom #3
+ builder.writeInt(mCarrierId); // atom #4
+ builder.writeInt(mSlotIndex); // atom #5
+ }
+
+ /** Return atom id defined in proto. */
+ @Override
+ public int getStatsId() {
+ return QnsStatsLog.QNS_RAT_PREFERENCE_MISMATCH_INFO;
+ }
+
+ /** Return copy of the AtomsQnsRatPreferenceMismatchInfo */
+ @Override
+ public AtomsPulled copy() {
+ return new AtomsQnsRatPreferenceMismatchInfo(this);
+ }
+
+ @Override
+ public String getDimension() {
+ return mNetCapability + "_" + mCarrierId + "_" + mSlotIndex;
+ }
+
+ @Override
+ public void accumulate(AtomsPulled info) {
+ if (!(info instanceof AtomsQnsRatPreferenceMismatchInfo)) {
+ return;
+ }
+ AtomsQnsRatPreferenceMismatchInfo atomsQnsRatPreferenceMismatchInfo =
+ (AtomsQnsRatPreferenceMismatchInfo) info;
+ this.mDurationOfMismatch += atomsQnsRatPreferenceMismatchInfo.getDurationOfMismatch();
+ this.mHandoverFailCount += atomsQnsRatPreferenceMismatchInfo.getHandoverFailCount();
+ }
+
+ public int getNetCapability() {
+ return mNetCapability;
+ }
+
+ public void setNetCapability(int netCapability) {
+ mNetCapability = netCapability;
+ }
+
+ public int getHandoverFailCount() {
+ return mHandoverFailCount;
+ }
+
+ public void setHandoverFailCount(int handoverFailCount) {
+ mHandoverFailCount = handoverFailCount;
+ }
+
+ public int getDurationOfMismatch() {
+ return mDurationOfMismatch;
+ }
+
+ public void setDurationOfMismatch(int durationOfMismatch) {
+ mDurationOfMismatch = durationOfMismatch;
+ }
+
+ public int getCarrierId() {
+ return mCarrierId;
+ }
+
+ public void setCarrierId(int carrierId) {
+ mCarrierId = carrierId;
+ }
+
+ public int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ public void setSlotIndex(int slotIndex) {
+ mSlotIndex = slotIndex;
+ }
+
+ @Override
+ public String toString() {
+ return "AtomsQnsRatPreferenceMismatchInfo{"
+ + "mNetCapability="
+ + mNetCapability
+ + ", mHandoverFailCount="
+ + mHandoverFailCount
+ + ", mDurationOfMismatch="
+ + mDurationOfMismatch
+ + ", mCarrierId="
+ + mCarrierId
+ + ", mSlotIndex="
+ + mSlotIndex
+ + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AtomsQnsRatPreferenceMismatchInfo)) return false;
+ AtomsQnsRatPreferenceMismatchInfo that = (AtomsQnsRatPreferenceMismatchInfo) o;
+ return mNetCapability == that.mNetCapability
+ && mHandoverFailCount == that.mHandoverFailCount
+ && mDurationOfMismatch == that.mDurationOfMismatch
+ && mCarrierId == that.mCarrierId
+ && mSlotIndex == that.mSlotIndex;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ mNetCapability, mHandoverFailCount, mDurationOfMismatch, mCarrierId, mSlotIndex);
+ }
+}
diff --git a/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQualifiedRatListChangedInfo.java b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQualifiedRatListChangedInfo.java
new file mode 100644
index 0000000..ea3ec6b
--- /dev/null
+++ b/services/QualifiedNetworksService/src/com/android/telephony/qns/atoms/AtomsQualifiedRatListChangedInfo.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.qns.atoms;
+
+import android.util.StatsEvent;
+
+import com.android.telephony.qns.stats.QnsStatsLog;
+import com.android.telephony.statslib.AtomsPushed;
+
+import java.util.Objects;
+
+/** AtomsQualifiedRatListChangedInfo class */
+public class AtomsQualifiedRatListChangedInfo extends AtomsPushed {
+
+ /** atom #1 : NetCapability of this Qualified RAT update */
+ private int mNetCapability;
+ /** atom #2 : The most preferred qualified RAT */
+ private int mFirstQualifiedRat;
+ /** atom #3 : Second preferred qualified RAT */
+ private int mSecondQualifiedRat;
+ /** atom #4 : Current actual transport type of Data session for this NetCapability */
+ private int mCurrentTransportType;
+ /** atom #5 : Indicates whether WFC is enabled */
+ private boolean mWfcEnabled;
+ /** atom #6 : Indicates the user's WFC mode */
+ private int mWfcMode;
+ /** atom #7 : Current Cellular AccessNetwork Type */
+ private int mCellularNetworkType;
+ /** atom #8 : Available IWLAN AccessNetwork */
+ private int mIwlanNetworkType;
+ /** atom #9 : Bit mask of restrictions on WWAN */
+ private int mRestrictionsOnWwan;
+ /** atom #10 : Bit mask of restrictions on WLAN */
+ private int mRestrictionsOnWlan;
+ /** atom #11 : Cellular network signal strength {e.g. SSRSRP in NR, RSRP in LTE} */
+ private int mSignalStrength;
+ /** atom #12 : Cellular network signal quality {e.g. SSRSRQ in NR, RSRQ in LTE} */
+ private int mSignalQuality;
+ /** atom #13 : Cellular network signal noise ratio {e.g. SSSINR in NR, RSSNR in LTE} */
+ private int mSignalNoise;
+ /** atom #14 : Iwlan network signal strength (Wi-Fi RSSI) */
+ private int mIwlanSignalStrength;
+ /** atom #15 : Reason for preferred RAT update */
+ private int mUpdateReason;
+ /** atom #16: IMS Call Type */
+ private int mImsCallType;
+ /** atom #17 : IMS Call Quality */
+ private int mImsCallQuality;
+ /** atom #18 : Slot Index */
+ private int mSlotIndex;
+
+ /** Constructor of AtomsQualifiedRatListChangedInfo */
+ public AtomsQualifiedRatListChangedInfo() {}
+
+ /**
+ * Constructor of AtomsQualifiedRatListChangedInfo
+ *
+ * @param netCapability NetCapability of this Qualified RAT update
+ * @param firstQualifiedRat The most preferred qualified RAT
+ * @param secondQualifiedRat Second preferred qualified RAT
+ * @param currentTransportType Current actual transport type of Data session for this
+ * NetCapability
+ * @param wfcEnabled Indicates whether WFC is enabled
+ * @param wfcMode Indicates the user's WFC mode
+ * @param cellularNetworkType Current Cellular AccessNetwork Type
+ * @param iwlanNetworkType Available IWLAN AccessNetwork
+ * @param restrictionsOnWwan Bit mask of restrictions on WWAN
+ * @param restrictionsOnWlan Bit mask of restrictions on WLAN
+ * @param signalStrength Cellular network signal strength {e.g. SSRSRP in NR, RSRP in LTE, RSCP
+ * in UMTS}
+ * @param signalQuality Cellular network signal quality {e.g. SSRSRQ in NR, RSRQ in LTE}
+ * @param signalNoise Cellular network signal noise ratio {e.g. SSSINR in NR, RSSNR in LTE}
+ * @param iwlanSignalStrength Iwlan network signal strength (Wi-Fi RSSI)
+ * @param updateReason Reason for preferred RAT update
+ * @param imsCallType Ims Call Type {e.g. IDLE, VOICE, VIDEO, E-CALL}
+ * @param imsCallQuality Ims Call Quality
+ * @param slotIndex Index of sim slot
+ */
+ public AtomsQualifiedRatListChangedInfo(
+ int netCapability,
+ int firstQualifiedRat,
+ int secondQualifiedRat,
+ int currentTransportType,
+ boolean wfcEnabled,
+ int wfcMode,
+ int cellularNetworkType,
+ int iwlanNetworkType,
+ int restrictionsOnWwan,
+ int restrictionsOnWlan,
+ int signalStrength,
+ int signalQuality,
+ int signalNoise,
+ int iwlanSignalStrength,
+ int updateReason,
+ int imsCallType,
+ int imsCallQuality,
+ int slotIndex) {
+ mNetCapability = netCapability;
+ mFirstQualifiedRat = firstQualifiedRat;
+ mSecondQualifiedRat = secondQualifiedRat;
+ mCurrentTransportType = currentTransportType;
+ mWfcEnabled = wfcEnabled;
+ mWfcMode = wfcMode;
+ mCellularNetworkType = cellularNetworkType;
+ mIwlanNetworkType = iwlanNetworkType;
+ mRestrictionsOnWwan = restrictionsOnWwan;
+ mRestrictionsOnWlan = restrictionsOnWlan;
+ mSignalStrength = signalStrength;
+ mSignalQuality = signalQuality;
+ mSignalNoise = signalNoise;
+ mIwlanSignalStrength = iwlanSignalStrength;
+ mUpdateReason = updateReason;
+ mImsCallType = imsCallType;
+ mImsCallQuality = imsCallQuality;
+ mSlotIndex = slotIndex;
+ }
+
+ /**
+ * Copy Constructor of AtomsQualifiedRatListChangedInfo
+ *
+ * @param info The info param to copy from.
+ */
+ public AtomsQualifiedRatListChangedInfo(AtomsQualifiedRatListChangedInfo info) {
+ mNetCapability = info.mNetCapability;
+ mFirstQualifiedRat = info.mFirstQualifiedRat;
+ mSecondQualifiedRat = info.mSecondQualifiedRat;
+ mCurrentTransportType = info.mCurrentTransportType;
+ mWfcEnabled = info.mWfcEnabled;
+ mWfcMode = info.mWfcMode;
+ mCellularNetworkType = info.mCellularNetworkType;
+ mIwlanNetworkType = info.mIwlanNetworkType;
+ mRestrictionsOnWwan = info.mRestrictionsOnWwan;
+ mRestrictionsOnWlan = info.mRestrictionsOnWlan;
+ mSignalStrength = info.mSignalStrength;
+ mSignalQuality = info.mSignalQuality;
+ mSignalNoise = info.mSignalNoise;
+ mIwlanSignalStrength = info.mIwlanSignalStrength;
+ mUpdateReason = info.mUpdateReason;
+ mImsCallType = info.mImsCallType;
+ mImsCallQuality = info.mImsCallQuality;
+ mSlotIndex = info.mSlotIndex;
+ }
+
+ /**
+ * Write the atom information to be recorded to the builder according to the type in order.
+ *
+ * @param builder Builder class for StatsEvent Builder object.
+ */
+ @Override
+ public void build(StatsEvent.Builder builder) {
+ builder.writeInt(mNetCapability); // atom #1
+ builder.writeInt(mFirstQualifiedRat); // atom #2
+ builder.writeInt(mSecondQualifiedRat); // atom #3
+ builder.writeInt(mCurrentTransportType); // atom #4
+ builder.writeBoolean(mWfcEnabled); // atom #5
+ builder.writeInt(mWfcMode); // atom #6
+ builder.writeInt(mCellularNetworkType); // atom #7
+ builder.writeInt(mIwlanNetworkType); // atom #8
+ builder.writeInt(mRestrictionsOnWwan); // atom #9
+ builder.writeInt(mRestrictionsOnWlan); // atom #10
+ builder.writeInt(mSignalStrength); // atom #11
+ builder.writeInt(mSignalQuality); // atom #12
+ builder.writeInt(mSignalNoise); // atom #13
+ builder.writeInt(mIwlanSignalStrength); // atom #14
+ builder.writeInt(mUpdateReason); // atom #15
+ builder.writeInt(mImsCallType); // atom #16
+ builder.writeInt(mImsCallQuality); // atom #17
+ builder.writeInt(mSlotIndex); // atom #18
+ }
+
+ /** Return atom id defined in proto. */
+ @Override
+ public int getStatsId() {
+ return QnsStatsLog.QUALIFIED_RAT_LIST_CHANGED;
+ }
+
+ /** Return copy of the AtomsQualifiedRatListChangedInfo */
+ @Override
+ public AtomsPushed copy() {
+ return new AtomsQualifiedRatListChangedInfo(this);
+ }
+
+ public int getNetCapability() {
+ return mNetCapability;
+ }
+
+ public void setNetCapability(int netCapability) {
+ mNetCapability = netCapability;
+ }
+
+ public int getFirstQualifiedRat() {
+ return mFirstQualifiedRat;
+ }
+
+ public void setFirstQualifiedRat(int firstQualifiedRat) {
+ mFirstQualifiedRat = firstQualifiedRat;
+ }
+
+ public int getSecondQualifiedRat() {
+ return mSecondQualifiedRat;
+ }
+
+ public void setSecondQualifiedRat(int secondQualifiedRat) {
+ mSecondQualifiedRat = secondQualifiedRat;
+ }
+
+ public int getCurrentTransportType() {
+ return mCurrentTransportType;
+ }
+
+ public void setCurrentTransportType(int currentTransportType) {
+ mCurrentTransportType = currentTransportType;
+ }
+
+ public boolean getWfcEnabled() {
+ return mWfcEnabled;
+ }
+
+ public void setWfcEnabled(boolean wfcEnabled) {
+ mWfcEnabled = wfcEnabled;
+ }
+
+ public int getWfcMode() {
+ return mWfcMode;
+ }
+
+ public void setWfcMode(int wfcMode) {
+ mWfcMode = wfcMode;
+ }
+
+ public int getCellularNetworkType() {
+ return mCellularNetworkType;
+ }
+
+ public void setCellularNetworkType(int cellularNetworkType) {
+ mCellularNetworkType = cellularNetworkType;
+ }
+
+ public int getIwlanNetworkType() {
+ return mIwlanNetworkType;
+ }
+
+ public void setIwlanNetworkType(int iwlanNetworkType) {
+ mIwlanNetworkType = iwlanNetworkType;
+ }
+
+ public int getRestrictionsOnWwan() {
+ return mRestrictionsOnWwan;
+ }
+
+ public void setRestrictionsOnWwan(int restrictionsOnWwan) {
+ mRestrictionsOnWwan = restrictionsOnWwan;
+ }
+
+ public int getRestrictionsOnWlan() {
+ return mRestrictionsOnWlan;
+ }
+
+ public void setRestrictionsOnWlan(int restrictionsOnWlan) {
+ mRestrictionsOnWlan = restrictionsOnWlan;
+ }
+
+ public int getSignalStrength() {
+ return mSignalStrength;
+ }
+
+ public void setSignalStrength(int signalStrength) {
+ mSignalStrength = signalStrength;
+ }
+
+ public int getSignalQuality() {
+ return mSignalQuality;
+ }
+
+ public void setSignalQuality(int signalQuality) {
+ mSignalQuality = signalQuality;
+ }
+
+ public int getSignalNoise() {
+ return mSignalNoise;
+ }
+
+ public void setSignalNoise(int signalNoise) {
+ mSignalNoise = signalNoise;
+ }
+
+ public int getIwlanSignalStrength() {
+ return mIwlanSignalStrength;
+ }
+
+ public void setIwlanSignalStrength(int iwlanSignalStrength) {
+ mIwlanSignalStrength = iwlanSignalStrength;
+ }
+
+ public int getUpdateReason() {
+ return mUpdateReason;
+ }
+
+ public void setUpdateReason(int updateReason) {
+ mUpdateReason = updateReason;
+ }
+
+ public int getImsCallType() {
+ return mImsCallType;
+ }
+
+ public void setImsCallType(int imsCallType) {
+ mImsCallType = imsCallType;
+ }
+
+ public int getImsCallQuality() {
+ return mImsCallQuality;
+ }
+
+ public void setImsCallQuality(int imsCallQuality) {
+ mImsCallQuality = imsCallQuality;
+ }
+
+ public int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ public void setSlotIndex(int slotIndex) {
+ mSlotIndex = slotIndex;
+ }
+
+ @Override
+ public String toString() {
+ return "AtomsQualifiedRatListChangedInfo{"
+ + "mNetCapability="
+ + mNetCapability
+ + ", mFirstQualifiedRat="
+ + mFirstQualifiedRat
+ + ", mSecondQualifiedRat="
+ + mSecondQualifiedRat
+ + ", mCurrentTransportType="
+ + mCurrentTransportType
+ + ", mWfcEnabled="
+ + mWfcEnabled
+ + ", mWfcMode="
+ + mWfcMode
+ + ", mCellularNetworkType="
+ + mCellularNetworkType
+ + ", mIwlanNetworkType="
+ + mIwlanNetworkType
+ + ", mRestrictionsOnWwan="
+ + mRestrictionsOnWwan
+ + ", mRestrictionsOnWlan="
+ + mRestrictionsOnWlan
+ + ", mSignalStrength="
+ + mSignalStrength
+ + ", mSignalQuality="
+ + mSignalQuality
+ + ", mSignalNoise="
+ + mSignalNoise
+ + ", mIwlanSignalStrength="
+ + mIwlanSignalStrength
+ + ", mUpdateReason="
+ + mUpdateReason
+ + ", mImsCallType="
+ + mImsCallType
+ + ", mImsCallQuality="
+ + mImsCallQuality
+ + ", mSlotIndex="
+ + mSlotIndex
+ + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AtomsQualifiedRatListChangedInfo)) return false;
+ AtomsQualifiedRatListChangedInfo that = (AtomsQualifiedRatListChangedInfo) o;
+ return mNetCapability == that.mNetCapability
+ && mFirstQualifiedRat == that.mFirstQualifiedRat
+ && mSecondQualifiedRat == that.mSecondQualifiedRat
+ && mCurrentTransportType == that.mCurrentTransportType
+ && mWfcEnabled == that.mWfcEnabled
+ && mWfcMode == that.mWfcMode
+ && mCellularNetworkType == that.mCellularNetworkType
+ && mIwlanNetworkType == that.mIwlanNetworkType
+ && mRestrictionsOnWwan == that.mRestrictionsOnWwan
+ && mRestrictionsOnWlan == that.mRestrictionsOnWlan
+ && mSignalStrength == that.mSignalStrength
+ && mSignalQuality == that.mSignalQuality
+ && mSignalNoise == that.mSignalNoise
+ && mIwlanSignalStrength == that.mIwlanSignalStrength
+ && mUpdateReason == that.mUpdateReason
+ && mImsCallType == that.mImsCallType
+ && mImsCallQuality == that.mImsCallQuality
+ && mSlotIndex == that.mSlotIndex;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ mNetCapability,
+ mFirstQualifiedRat,
+ mSecondQualifiedRat,
+ mCurrentTransportType,
+ mWfcEnabled,
+ mWfcMode,
+ mCellularNetworkType,
+ mIwlanNetworkType,
+ mRestrictionsOnWwan,
+ mRestrictionsOnWlan,
+ mSignalStrength,
+ mSignalQuality,
+ mSignalNoise,
+ mIwlanSignalStrength,
+ mUpdateReason,
+ mImsCallType,
+ mImsCallQuality,
+ mSlotIndex);
+ }
+}