1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.telephony.qns;
18 
19 import android.content.Context;
20 import android.net.NetworkCapabilities;
21 import android.os.Handler;
22 import android.os.HandlerThread;
23 import android.os.Message;
24 import android.telephony.AccessNetworkConstants;
25 import android.telephony.AccessNetworkConstants.AccessNetworkType;
26 import android.telephony.SignalThresholdInfo;
27 import android.telephony.qns.QnsProtoEnums;
28 import android.util.Log;
29 
30 import com.android.internal.annotations.VisibleForTesting;
31 import com.android.internal.util.State;
32 import com.android.internal.util.StateMachine;
33 import com.android.telephony.qns.DataConnectionStatusTracker.DataConnectionChangedInfo;
34 import com.android.telephony.qns.QualifiedNetworksServiceImpl.QualifiedNetworksInfo;
35 import com.android.telephony.qns.atoms.AtomsQnsFallbackRestrictionChangedInfo;
36 import com.android.telephony.qns.atoms.AtomsQnsHandoverPingPongInfo;
37 import com.android.telephony.qns.atoms.AtomsQnsHandoverTimeMillisInfo;
38 import com.android.telephony.qns.atoms.AtomsQnsImsCallDropStats;
39 import com.android.telephony.qns.atoms.AtomsQnsRatPreferenceMismatchInfo;
40 import com.android.telephony.qns.atoms.AtomsQualifiedRatListChangedInfo;
41 import com.android.telephony.statslib.StatsLib;
42 
43 import java.util.HashMap;
44 import java.util.List;
45 import java.util.concurrent.ConcurrentHashMap;
46 
47 /** QnsStats class */
48 class QnsMetrics {
49 
50     private StatsLib mStats;
51     private final String mLogTag;
52     private final Handler mHandler;
53     private final HandlerThread mHandlerThread;
54 
55     // For HandoverTIme.
56     private final ConcurrentHashMap<Integer, HandoverTimeStateMachine> mHandoverTimeMap;
57     private final ConcurrentHashMap<Integer, PingPongTime> mPingPongTime;
58     private final ConcurrentHashMap<Integer, RatMismatchTime> mRatMismatchTime;
59     private final ConcurrentHashMap<Integer, RtpCallDrop> mRtpCallDrop;
60 
61     /** Constructor */
QnsMetrics(Context context)62     QnsMetrics(Context context) {
63         mStats = new StatsLib(context);
64         mLogTag = QnsMetrics.class.getSimpleName();
65 
66         mHandoverTimeMap = new ConcurrentHashMap<>();
67         mPingPongTime = new ConcurrentHashMap<>();
68         mRatMismatchTime = new ConcurrentHashMap<>();
69         mRtpCallDrop = new ConcurrentHashMap<>();
70 
71         mHandlerThread = new HandlerThread(QnsMetrics.class.getSimpleName());
72         mHandlerThread.start();
73         mHandler = new Handler(mHandlerThread.getLooper());
74     }
75 
76     @VisibleForTesting
QnsMetrics(StatsLib statsLib)77     QnsMetrics(StatsLib statsLib) {
78         mStats = statsLib;
79         mLogTag = QnsMetrics.class.getSimpleName();
80 
81         mHandoverTimeMap = new ConcurrentHashMap<>();
82         mPingPongTime = new ConcurrentHashMap<>();
83         mRatMismatchTime = new ConcurrentHashMap<>();
84         mRtpCallDrop = new ConcurrentHashMap<>();
85 
86         mHandlerThread = new HandlerThread(QnsMetrics.class.getSimpleName());
87         mHandlerThread.start();
88         mHandler = new Handler(mHandlerThread.getLooper());
89     }
90 
91     @VisibleForTesting
getHandler()92     Handler getHandler() {
93         return mHandler;
94     }
95 
96     /** close */
close()97     public void close() {
98         mStats = null;
99         mHandlerThread.quitSafely();
100     }
101 
102     /**
103      * Report atoms when the qualified access network is reported.
104      *
105      * @param info QualifiedNetworksInfo
106      * @param slotId slot index
107      * @param dataConnectionCurrentTransportType transportType currently stayed in.
108      * @param coverage coverage home or roam.
109      * @param settingWfcEnabled setting for wfc
110      * @param settingWfcRoamingEnabled roaming setting for wfc
111      * @param settingWfcMode setting for wfc mode
112      * @param settingWfcRoamingMode roaming setting for wfc mode
113      * @param cellularAccessNetworkType cellular rat
114      * @param iwlanAvailable iwlan available
115      * @param isCrossWfc cross sim wfc enabled
116      * @param restrictManager restriction manager
117      * @param cellularQualityMonitor cellular quality monitor
118      * @param wifiQualityMonitor wifi quality monitor
119      * @param callType call type
120      */
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)121     public void reportAtomForQualifiedNetworks(
122             QualifiedNetworksInfo info,
123             int slotId,
124             int dataConnectionCurrentTransportType,
125             int coverage,
126             boolean settingWfcEnabled,
127             boolean settingWfcRoamingEnabled,
128             int settingWfcMode,
129             int settingWfcRoamingMode,
130             int cellularAccessNetworkType,
131             boolean iwlanAvailable,
132             boolean isCrossWfc,
133             RestrictManager restrictManager,
134             QualityMonitor cellularQualityMonitor,
135             QualityMonitor wifiQualityMonitor,
136             int callType) {
137         mHandler.post(() -> procQualifiedNetworksForHandoverTime(info, slotId));
138         mHandler.post(() ->
139                 procQualifiedRatListChanged(
140                         info,
141                         slotId,
142                         dataConnectionCurrentTransportType,
143                         coverage,
144                         settingWfcEnabled,
145                         settingWfcRoamingEnabled,
146                         settingWfcMode,
147                         settingWfcRoamingMode,
148                         cellularAccessNetworkType,
149                         iwlanAvailable,
150                         isCrossWfc,
151                         restrictManager,
152                         cellularQualityMonitor,
153                         wifiQualityMonitor,
154                         callType));
155     }
156 
157     /**
158      * Report atom when data connection is changed
159      *
160      * @param netCapability Network Capability
161      * @param slotId slot Index
162      * @param info DataConnectionChangedInfo
163      * @param carrierId carrier id.
164      */
reportAtomForDataConnectionChanged( int netCapability, int slotId, DataConnectionChangedInfo info, int carrierId)165     public void reportAtomForDataConnectionChanged(
166             int netCapability, int slotId, DataConnectionChangedInfo info, int carrierId) {
167         mHandler.post(() -> procDataConnectionChangedForHandoverTime(netCapability, slotId, info));
168         mHandler.post(() -> procDataConnectionChangedForHandoverPingPong(
169                 netCapability, slotId, info, carrierId));
170         mHandler.post(() -> procDataConnectionChangedForRatMismatch(
171                 netCapability, slotId, info, carrierId));
172     }
173 
174     /**
175      * Report atom when a restriction is set.
176      *
177      * @param netCapability Network Capability
178      * @param slotId slot Index
179      * @param wlanRestrictions list of restrictions on wlan
180      * @param wwanRestrictions list of restrictions on wwan
181      * @param carrierId carrier id.
182      */
reportAtomForRestrictions( int netCapability, int slotId, List<Integer> wlanRestrictions, List<Integer> wwanRestrictions, int carrierId)183     public void reportAtomForRestrictions(
184             int netCapability,
185             int slotId,
186             List<Integer> wlanRestrictions,
187             List<Integer> wwanRestrictions,
188             int carrierId) {
189         mHandler.post(() -> procRestrictionsForFallback(
190                 netCapability, slotId, wlanRestrictions, wwanRestrictions, carrierId));
191     }
192 
193     /**
194      * Report atom when call type change
195      *
196      * @param netCapability Network Capability
197      * @param slotId slot Index
198      * @param oldCallType previous call type
199      * @param newCallType new call type
200      * @param restrictManager restriction manager
201      * @param transportTypeOfCall transport type in call
202      */
reportAtomForCallTypeChanged( int netCapability, int slotId, int oldCallType, int newCallType, RestrictManager restrictManager, int transportTypeOfCall)203     public void reportAtomForCallTypeChanged(
204             int netCapability,
205             int slotId,
206             int oldCallType,
207             int newCallType,
208             RestrictManager restrictManager,
209             int transportTypeOfCall) {
210         mHandler.post(() -> procCallTypeChangedForImsCallDrop(netCapability, slotId,
211                 oldCallType, newCallType, restrictManager, transportTypeOfCall));
212     }
213 
214     /**
215      * Report atom when ims call is dropped
216      *
217      * @param netCapability Network Capability
218      * @param slotId slot Index
219      * @param restrictManager restriction manager
220      * @param cellularQualityMonitor cellular quality monitor
221      * @param wifiQualityMonitor wifi quality monitor
222      * @param transportTypeOfCall transport type in call
223      * @param cellularAccessNetworkType cellular access network
224      */
reportAtomForImsCallDropStats( int netCapability, int slotId, RestrictManager restrictManager, QualityMonitor cellularQualityMonitor, QualityMonitor wifiQualityMonitor, int transportTypeOfCall, int cellularAccessNetworkType)225     public void reportAtomForImsCallDropStats(
226             int netCapability,
227             int slotId,
228             RestrictManager restrictManager,
229             QualityMonitor cellularQualityMonitor,
230             QualityMonitor wifiQualityMonitor,
231             int transportTypeOfCall,
232             int cellularAccessNetworkType) {
233         mHandler.post(() -> procCallDroppedForImsCallDrop(netCapability, slotId, restrictManager,
234                 cellularQualityMonitor, wifiQualityMonitor, transportTypeOfCall,
235                 cellularAccessNetworkType));
236     }
237 
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)238     private void procQualifiedRatListChanged(
239             QualifiedNetworksInfo info,
240             int slotId,
241             int dataConnectedTransportType,
242             int coverage,
243             boolean settingWfcEnabled,
244             boolean settingWfcRoamingEnabled,
245             int settingWfcMode,
246             int settingWfcRoamingMode,
247             int cellularAccessNetworkType,
248             boolean iwlanAvailable,
249             boolean isCrossWfc,
250             RestrictManager restrictManager,
251             QualityMonitor cellularQualityMonitor,
252             QualityMonitor wifiQualityMonitor,
253             int callType) {
254         int netCapability = info.getNetCapability();
255         int firstQualifiedRat = getQualifiedAccessNetwork(info, 0);
256         int secondQualifiedRat = getQualifiedAccessNetwork(info, 1);
257         boolean wfcEnabled = getWfcEnabled(coverage, settingWfcEnabled, settingWfcRoamingEnabled);
258         int wfcMode = getWfcMode(coverage, settingWfcMode, settingWfcRoamingMode);
259         int iwlanNetworkType = getIwlanNetworkType(iwlanAvailable, isCrossWfc);
260         int restrictionsOnWwan = getRestrictionsBitmask(
261                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, restrictManager);
262         int restrictionsOnWlan = getRestrictionsBitmask(
263                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN, restrictManager);
264         int signalStrength = getSignalStrength(cellularQualityMonitor, cellularAccessNetworkType);
265         int signalQuality = getSignalQuality(cellularQualityMonitor, cellularAccessNetworkType);
266         int signalNoise = getSignalNoise(cellularQualityMonitor, cellularAccessNetworkType);
267         int iwlanSignalStrength = getSignalStrength(wifiQualityMonitor, AccessNetworkType.IWLAN);
268         int updateReason = 0;
269         int imsCallQuality = 0;
270 
271         writeQualifiedRatListChangedInfo(
272                 netCapability,
273                 slotId,
274                 firstQualifiedRat,
275                 secondQualifiedRat,
276                 dataConnectedTransportType,
277                 wfcEnabled,
278                 wfcMode,
279                 cellularAccessNetworkType,
280                 iwlanNetworkType,
281                 restrictionsOnWwan,
282                 restrictionsOnWlan,
283                 signalStrength,
284                 signalQuality,
285                 signalNoise,
286                 iwlanSignalStrength,
287                 updateReason,
288                 callType,
289                 imsCallQuality);
290     }
291 
292 
procQualifiedNetworksForHandoverTime(QualifiedNetworksInfo info, int slotId)293     private void procQualifiedNetworksForHandoverTime(QualifiedNetworksInfo info, int slotId) {
294         if (info.getNetCapability() != NetworkCapabilities.NET_CAPABILITY_IMS) {
295             return;
296         }
297 
298         HandoverTimeStateMachine handoverTimeStateMachine = mHandoverTimeMap.get(slotId);
299         if (handoverTimeStateMachine == null) {
300             handoverTimeStateMachine =
301                     new HandoverTimeStateMachine(info.getNetCapability(), slotId, mHandler);
302             mHandoverTimeMap.put(slotId, handoverTimeStateMachine);
303         }
304 
305         handoverTimeStateMachine.sendQualifiedRatChanged(info);
306     }
307 
procDataConnectionChangedForHandoverTime( int netCapability, int slotId, DataConnectionChangedInfo info)308     private void procDataConnectionChangedForHandoverTime(
309             int netCapability, int slotId, DataConnectionChangedInfo info) {
310         if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
311             return;
312         }
313 
314         HandoverTimeStateMachine handoverTimeStateMachine = mHandoverTimeMap.get(slotId);
315         if (handoverTimeStateMachine == null) {
316             handoverTimeStateMachine =
317                     new HandoverTimeStateMachine(netCapability, slotId, mHandler);
318             mHandoverTimeMap.put(slotId, handoverTimeStateMachine);
319         }
320 
321         handoverTimeStateMachine.sendDataStateChanged(info);
322     }
323 
procDataConnectionChangedForHandoverPingPong(int netCapability, int slotId, DataConnectionChangedInfo info, int carrierId)324     private void procDataConnectionChangedForHandoverPingPong(int netCapability, int slotId,
325             DataConnectionChangedInfo info, int carrierId) {
326         if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
327             return;
328         }
329 
330         PingPongTime pingPongTime = mPingPongTime.get(slotId);
331         if (pingPongTime == null) {
332             pingPongTime = new PingPongTime();
333             mPingPongTime.put(slotId, pingPongTime);
334         }
335 
336         boolean bActiveState;
337         switch (info.getState()) {
338             case DataConnectionStatusTracker.STATE_INACTIVE:
339             case DataConnectionStatusTracker.STATE_CONNECTING:
340                 bActiveState = false;
341                 break;
342             case DataConnectionStatusTracker.STATE_CONNECTED:
343             case DataConnectionStatusTracker.STATE_HANDOVER:
344             default:
345                 bActiveState = true;
346                 break;
347         }
348         switch (info.getEvent()) {
349             case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_CONNECTED:
350                 pingPongTime.mSuccessTime = QnsUtils.getSystemElapsedRealTime();
351                 pingPongTime.mHandoverCount = 0;
352                 break;
353             case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_HANDOVER_STARTED:
354                 pingPongTime.mStartTime = QnsUtils.getSystemElapsedRealTime();
355                 break;
356             case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_HANDOVER_SUCCESS:
357                 pingPongTime.mHandoverCount++;
358                 pingPongTime.mSuccessTime = QnsUtils.getSystemElapsedRealTime();
359                 break;
360         }
361 
362         if (pingPongTime.mStartTime != 0L && pingPongTime.mSuccessTime != 0L) {
363             long pingPongTimeLimit = AtomsQnsHandoverPingPongInfo.PING_PONG_TIME_IN_MILLIS;
364             long elapsed =
365                     (pingPongTime.mSuccessTime > pingPongTime.mStartTime)
366                             ? (pingPongTime.mSuccessTime - pingPongTime.mStartTime)
367                             : (pingPongTime.mStartTime - pingPongTime.mSuccessTime);
368             if (pingPongTime.mHandoverCount > 0) {
369                 log("HandoverPingPong elapsed:" + elapsed
370                         + " ping-pong count:" + (pingPongTime.mHandoverCount / 2));
371             }
372             if (elapsed > pingPongTimeLimit || !bActiveState) {
373                 if (pingPongTime.mHandoverCount > 1) {
374                     int pingpongCount = pingPongTime.mHandoverCount / 2;
375                     writeQnsHandoverPingPong(slotId, pingpongCount, carrierId);
376                 }
377                 pingPongTime.mHandoverCount = 0;
378                 pingPongTime.mStartTime = 0L;
379                 pingPongTime.mSuccessTime = 0L;
380                 procDataConnectionChangedForHandoverPingPong(
381                         netCapability, slotId, info, carrierId);
382             }
383         }
384         if (!bActiveState) {
385             pingPongTime.mHandoverCount = 0;
386             pingPongTime.mStartTime = 0L;
387             pingPongTime.mSuccessTime = 0L;
388         }
389     }
390 
procRestrictionsForFallback(int netCapability, int slotId, List<Integer> wlanRestrictions, List<Integer> wwanRestrictions, int carrierId)391     private void procRestrictionsForFallback(int netCapability, int slotId,
392             List<Integer> wlanRestrictions, List<Integer> wwanRestrictions, int carrierId) {
393         if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS
394                 || wlanRestrictions == null
395                 || wwanRestrictions == null) {
396             return;
397         }
398 
399         boolean bRestrictionOnWlanByRtpThresholdBreached =
400                 wlanRestrictions.contains(RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY);
401         boolean bRestrictionOnWwanByRtpThresholdBreached =
402                 wwanRestrictions.contains(RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY);
403         boolean bRestrictionOnWlanByImsRegistrationFailed =
404                 wlanRestrictions.contains(
405                         RestrictManager.RESTRICT_TYPE_FALLBACK_TO_WWAN_IMS_REGI_FAIL);
406         boolean bRestrictionOnWlanByWifiBackhaulProblem =
407                 wlanRestrictions.contains(
408                         RestrictManager.RESTRICT_TYPE_FALLBACK_TO_WWAN_RTT_BACKHAUL_FAIL);
409 
410         // all false will not write atom because this atom is used for count metric.
411         if (bRestrictionOnWlanByRtpThresholdBreached
412                 || bRestrictionOnWwanByRtpThresholdBreached
413                 || bRestrictionOnWlanByImsRegistrationFailed
414                 || bRestrictionOnWlanByWifiBackhaulProblem) {
415             writeQnsFallbackRestrictionChangedInfo(
416                     bRestrictionOnWlanByRtpThresholdBreached,
417                     bRestrictionOnWwanByRtpThresholdBreached,
418                     bRestrictionOnWlanByImsRegistrationFailed,
419                     bRestrictionOnWlanByWifiBackhaulProblem,
420                     carrierId,
421                     slotId);
422         }
423     }
424 
procDataConnectionChangedForRatMismatch( int netCapability, int slotId, DataConnectionChangedInfo info, int carrierId)425     private void procDataConnectionChangedForRatMismatch(
426             int netCapability, int slotId, DataConnectionChangedInfo info, int carrierId) {
427 
428         RatMismatchTime mismatchTime = mRatMismatchTime.get(slotId);
429         if (mismatchTime == null) {
430             mismatchTime = new RatMismatchTime();
431             mRatMismatchTime.put(slotId, mismatchTime);
432         }
433 
434         switch (info.getEvent()) {
435             case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_HANDOVER_STARTED:
436                 if (mismatchTime.mCount == 0) {
437                     mismatchTime.mStartTime = QnsUtils.getSystemElapsedRealTime();
438                 }
439                 break;
440             case DataConnectionStatusTracker.EVENT_DATA_CONNECTION_HANDOVER_FAILED:
441                 mismatchTime.mCount++;
442                 break;
443             default:
444                 if (mismatchTime.mCount > 0) {
445                     long duration = QnsUtils.getSystemElapsedRealTime() - mismatchTime.mStartTime;
446                     int count = mismatchTime.mCount;
447 
448                     writeQnsRatPreferenceMismatchInfo(
449                             netCapability, count, (int) duration, carrierId, slotId);
450                     mismatchTime.mCount = 0;
451                     mismatchTime.mStartTime = 0L;
452                 }
453                 break;
454         }
455     }
456 
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)457     private void writeQualifiedRatListChangedInfo(
458             int netCapability,
459             int slotId,
460             int firstQualifiedRat,
461             int secondQualifiedRat,
462             int currentTransportType,
463             boolean wfcEnabled,
464             int wfcMode,
465             int cellularNetworkType,
466             int iwlanNetworkType,
467             int restrictionsOnWwan,
468             int restrictionsOnWlan,
469             int signalStrength,
470             int signalQuality,
471             int signalNoise,
472             int iwlanSignalStrength,
473             int updateReason,
474             int imsCallType,
475             int imsCallQuality) {
476         AtomsQualifiedRatListChangedInfo atoms =
477                 new AtomsQualifiedRatListChangedInfo(
478                         netCapability,
479                         firstQualifiedRat,
480                         secondQualifiedRat,
481                         currentTransportType,
482                         wfcEnabled,
483                         wfcMode,
484                         cellularNetworkType,
485                         iwlanNetworkType,
486                         restrictionsOnWwan,
487                         restrictionsOnWlan,
488                         signalStrength,
489                         signalQuality,
490                         signalNoise,
491                         iwlanSignalStrength,
492                         updateReason,
493                         imsCallType,
494                         imsCallQuality,
495                         slotId);
496         mStats.write(atoms);
497     }
498 
499 
writeQnsHandoverTimeMillisInfo(long handoverTime, int slotIndex)500     private void writeQnsHandoverTimeMillisInfo(long handoverTime, int slotIndex) {
501         AtomsQnsHandoverTimeMillisInfo atoms =
502                 new AtomsQnsHandoverTimeMillisInfo((int) handoverTime, slotIndex);
503         mStats.append(atoms);
504     }
505 
writeQnsHandoverPingPong(int slotId, int pingPongCount, int carrierId)506     private void writeQnsHandoverPingPong(int slotId, int pingPongCount, int carrierId) {
507         AtomsQnsHandoverPingPongInfo atoms =
508                 new AtomsQnsHandoverPingPongInfo(pingPongCount, carrierId, slotId);
509         mStats.append(atoms);
510     }
511 
writeQnsFallbackRestrictionChangedInfo( boolean bRestrictionOnWlanByRtpThresholdBreached, boolean bRestrictionOnWwanByRtpThresholdBreached, boolean bRestrictionOnWlanByImsRegistrationFailed, boolean bRestrictionOnWlanByWifiBackhaulProblem, int carrierId, int slotId)512     private void writeQnsFallbackRestrictionChangedInfo(
513             boolean bRestrictionOnWlanByRtpThresholdBreached,
514             boolean bRestrictionOnWwanByRtpThresholdBreached,
515             boolean bRestrictionOnWlanByImsRegistrationFailed,
516             boolean bRestrictionOnWlanByWifiBackhaulProblem,
517             int carrierId,
518             int slotId) {
519         AtomsQnsFallbackRestrictionChangedInfo atom =
520                 new AtomsQnsFallbackRestrictionChangedInfo(
521                         bRestrictionOnWlanByRtpThresholdBreached,
522                         bRestrictionOnWwanByRtpThresholdBreached,
523                         bRestrictionOnWlanByImsRegistrationFailed,
524                         bRestrictionOnWlanByWifiBackhaulProblem,
525                         carrierId,
526                         slotId);
527         mStats.write(atom);
528     }
529 
writeQnsRatPreferenceMismatchInfo(int netCapability, int handoverFailCount, int durationMismatch, int carrierId, int slotId)530     private void writeQnsRatPreferenceMismatchInfo(int netCapability, int handoverFailCount,
531             int durationMismatch, int carrierId, int slotId) {
532         AtomsQnsRatPreferenceMismatchInfo atoms = new AtomsQnsRatPreferenceMismatchInfo(
533                 netCapability, handoverFailCount, durationMismatch, carrierId, slotId);
534         mStats.append(atoms);
535     }
536 
537     class HandoverTimeStateMachine extends StateMachine {
538 
539         private static final int EVENT_DATA_STATE_CHANGED = 0;
540         private static final int EVENT_QUALIFIED_RAT_CHANGED = 1;
541 
542         private final IdleState mIdleState;
543         private final ConnectedState mConnectedState;
544         private final HandoverRequestedState mHandoverRequestedState;
545         private final HandoverInProgressState mHandoverInProgressState;
546 
547         private final int mNetCapability;
548         private final int mSlotId;
549         int mDataTransportType;
550         long mHandoverRequestedTime;
551 
HandoverTimeStateMachine(int netCapability, int slotId, Handler handler)552         HandoverTimeStateMachine(int netCapability, int slotId, Handler handler) {
553             super(mLogTag + "_" + HandoverTimeStateMachine.class.getSimpleName() + "_" + slotId
554                     + "_" + QnsUtils.getNameOfNetCapability(netCapability), handler);
555 
556             mIdleState = new IdleState();
557             mConnectedState = new ConnectedState();
558             mHandoverRequestedState = new HandoverRequestedState();
559             mHandoverInProgressState = new HandoverInProgressState();
560 
561             mNetCapability = netCapability;
562             mSlotId = slotId;
563             mDataTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
564             mHandoverRequestedTime = 0L;
565 
566             addState(mIdleState);
567             addState(mConnectedState);
568             addState(mHandoverRequestedState);
569             addState(mHandoverInProgressState);
570             setInitialState(mIdleState);
571             start();
572         }
573 
sendDataStateChanged(DataConnectionChangedInfo info)574         public void sendDataStateChanged(DataConnectionChangedInfo info) {
575             sendMessage(EVENT_DATA_STATE_CHANGED, info);
576         }
577 
sendQualifiedRatChanged(QualifiedNetworksInfo info)578         public void sendQualifiedRatChanged(QualifiedNetworksInfo info) {
579             sendMessage(EVENT_QUALIFIED_RAT_CHANGED, info);
580         }
581 
582         private final class IdleState extends State {
583             @Override
enter()584             public void enter() {
585                 log("IdleState");
586                 mDataTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
587                 mHandoverRequestedTime = 0L;
588             }
589 
590             @Override
processMessage(Message msg)591             public boolean processMessage(Message msg) {
592                 log("IdleState processMessage=" + msg.what);
593                 switch (msg.what) {
594                     case EVENT_DATA_STATE_CHANGED:
595                         DataConnectionChangedInfo dataInfo = (DataConnectionChangedInfo) msg.obj;
596                         switch (dataInfo.getState()) {
597                             case DataConnectionStatusTracker.STATE_CONNECTED:
598                                 mDataTransportType = dataInfo.getTransportType();
599                                 transitionTo(mConnectedState);
600                                 return HANDLED;
601                             case DataConnectionStatusTracker.STATE_HANDOVER:
602                                 mDataTransportType = dataInfo.getTransportType();
603                                 transitionTo(mConnectedState);
604                                 break;
605                         }
606                         break;
607                     case EVENT_QUALIFIED_RAT_CHANGED:
608                         break;
609                 }
610                 return super.processMessage(msg);
611             }
612 
613             @Override
exit()614             public void exit() {
615                 super.exit();
616             }
617         }
618 
619         private final class ConnectedState extends State {
620             @Override
enter()621             public void enter() {
622                 log("ConnectedState");
623                 mHandoverRequestedTime = 0L;
624             }
625 
626             @Override
processMessage(Message msg)627             public boolean processMessage(Message msg) {
628                 log("ConnectedState processMessage=" + msg.what);
629                 switch (msg.what) {
630                     case EVENT_DATA_STATE_CHANGED:
631                         DataConnectionChangedInfo dataInfo = (DataConnectionChangedInfo) msg.obj;
632                         switch (dataInfo.getState()) {
633                             case DataConnectionStatusTracker.STATE_INACTIVE:
634                             case DataConnectionStatusTracker.STATE_CONNECTING:
635                                 transitionTo(mIdleState);
636                                 break;
637                             case DataConnectionStatusTracker.STATE_CONNECTED:
638                             case DataConnectionStatusTracker.STATE_HANDOVER:
639                                 mDataTransportType = dataInfo.getTransportType();
640                                 return HANDLED;
641                         }
642                         break;
643                     case EVENT_QUALIFIED_RAT_CHANGED:
644                         QualifiedNetworksInfo qualifiedInfo = (QualifiedNetworksInfo) msg.obj;
645                         // handover trigger
646                         if (mNetCapability == qualifiedInfo.getNetCapability()
647                                 && qualifiedInfo.getAccessNetworkTypes().stream().anyMatch(
648                                         accessNetwork -> QnsUtils.getTransportTypeFromAccessNetwork(
649                                                 accessNetwork) != mDataTransportType)) {
650                             mHandoverRequestedTime = QnsUtils.getSystemElapsedRealTime();
651                             transitionTo(mHandoverRequestedState);
652                             return HANDLED;
653                         }
654                         break;
655                 }
656 
657                 return super.processMessage(msg);
658             }
659 
660             @Override
exit()661             public void exit() {
662                 super.exit();
663             }
664         }
665 
666         private final class HandoverRequestedState extends State {
667             @Override
enter()668             public void enter() {
669                 log("HandoverRequestedState");
670             }
671 
672             @Override
processMessage(Message msg)673             public boolean processMessage(Message msg) {
674                 log("HandoverRequestedState processMessage=" + msg.what);
675                 switch (msg.what) {
676                     case EVENT_DATA_STATE_CHANGED:
677                         DataConnectionChangedInfo dataInfo = (DataConnectionChangedInfo) msg.obj;
678                         switch (dataInfo.getState()) {
679                             case DataConnectionStatusTracker.STATE_INACTIVE:
680                             case DataConnectionStatusTracker.STATE_CONNECTING:
681                                 transitionTo(mIdleState);
682                                 break;
683                             case DataConnectionStatusTracker.STATE_CONNECTED:
684                                 if (dataInfo.getTransportType() != mDataTransportType) {
685                                     // back to connected state, already reached to target transport.
686                                     mDataTransportType = dataInfo.getTransportType();
687                                     transitionTo(mConnectedState);
688                                 }
689                                 break;
690                             case DataConnectionStatusTracker.STATE_HANDOVER:
691                                 if (dataInfo.getTransportType() != mDataTransportType) {
692                                     // back to connected state, already reached to target transport.
693                                     mDataTransportType = dataInfo.getTransportType();
694                                     transitionTo(mConnectedState);
695                                 }
696                                 transitionTo(mHandoverInProgressState);
697                                 break;
698                         }
699                         break;
700                     case EVENT_QUALIFIED_RAT_CHANGED:
701                         QualifiedNetworksInfo qualifiedInfo = (QualifiedNetworksInfo) msg.obj;
702                         if (mNetCapability != qualifiedInfo.getNetCapability()) {
703                             break;
704                         }
705                         if (qualifiedInfo.getAccessNetworkTypes().stream().noneMatch(
706                                 accessNetwork -> QnsUtils.getTransportTypeFromAccessNetwork(
707                                         accessNetwork) != mDataTransportType)) {
708                             // back to connected state. no handover target transport.
709                             transitionTo(mConnectedState);
710                             return HANDLED;
711                         }
712                         break;
713                 }
714                 return super.processMessage(msg);
715             }
716 
717             @Override
exit()718             public void exit() {
719                 super.exit();
720             }
721         }
722 
723         private final class HandoverInProgressState extends State {
724             @Override
enter()725             public void enter() {
726                 log("HandoverInProgressState");
727             }
728 
729             @Override
processMessage(Message msg)730             public boolean processMessage(Message msg) {
731                 log("HandoverInProgressState processMessage=" + msg.what);
732                 switch (msg.what) {
733                     case EVENT_DATA_STATE_CHANGED:
734                         DataConnectionChangedInfo dataInfo = (DataConnectionChangedInfo) msg.obj;
735                         switch (dataInfo.getState()) {
736                             case DataConnectionStatusTracker.STATE_INACTIVE:
737                             case DataConnectionStatusTracker.STATE_CONNECTING:
738                                 transitionTo(mIdleState);
739                                 break;
740                             case DataConnectionStatusTracker.STATE_CONNECTED:
741                                 if (dataInfo.getTransportType() != mDataTransportType) {
742                                     if (mHandoverRequestedTime == 0L) {
743                                         break;
744                                     }
745                                     // handover done.
746                                     long handoverTime = QnsUtils.getSystemElapsedRealTime()
747                                             - mHandoverRequestedTime;
748                                     writeQnsHandoverTimeMillisInfo(handoverTime, mSlotId);
749                                     mDataTransportType = dataInfo.getTransportType();
750                                     mHandoverRequestedTime = 0L;
751                                     transitionTo(mConnectedState);
752                                 } else {
753                                     // handover didn't have done yet.
754                                     transitionTo(mHandoverRequestedState);
755                                 }
756                                 break;
757                             case DataConnectionStatusTracker.STATE_HANDOVER:
758                                 if (dataInfo.getTransportType() != mDataTransportType) {
759                                     // back to connected state, already reached to target transport.
760                                     mDataTransportType = dataInfo.getTransportType();
761                                     transitionTo(mConnectedState);
762                                 }
763                                 break;
764                         }
765                         break;
766                     case EVENT_QUALIFIED_RAT_CHANGED:
767                         QualifiedNetworksInfo qualifiedInfo = (QualifiedNetworksInfo) msg.obj;
768                         if (mNetCapability == qualifiedInfo.getNetCapability()
769                                 && qualifiedInfo.getAccessNetworkTypes().stream().noneMatch(
770                                         accessNetwork -> QnsUtils.getTransportTypeFromAccessNetwork(
771                                                 accessNetwork) != mDataTransportType)) {
772                             // back to connected state. no handover request
773                             transitionTo(mConnectedState);
774                             return HANDLED;
775                         }
776                         break;
777                 }
778                 return super.processMessage(msg);
779             }
780 
781             @Override
exit()782             public void exit() {
783                 super.exit();
784             }
785         }
786     }
787 
788     private static class PingPongTime {
789         int mHandoverCount = 0;
790         long mStartTime = 0L;
791         long mSuccessTime = 0L;
792     }
793 
794     private static class RatMismatchTime {
795         int mCount = 0;
796         long mStartTime = 0L;
797     }
798 
799     private static class RtpCallDrop {
800         boolean mRtpThresholdBreached;
801         int mRestrictionsOnOtherTransportType;
802     }
803 
804 
procCallTypeChangedForImsCallDrop( int netCapability, int slotId, int oldCallType, int newCallType, RestrictManager restrictManager, int transportTypeOfCall)805     private void procCallTypeChangedForImsCallDrop(
806             int netCapability,
807             int slotId,
808             int oldCallType,
809             int newCallType,
810             RestrictManager restrictManager,
811             int transportTypeOfCall) {
812         if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
813             return;
814         }
815 
816         RtpCallDrop rtpCallDrop = mRtpCallDrop.get(slotId);
817         if (rtpCallDrop == null) {
818             rtpCallDrop = new RtpCallDrop();
819             mRtpCallDrop.put(slotId, rtpCallDrop);
820         }
821 
822         // call ended
823         if (newCallType == QnsConstants.CALL_TYPE_IDLE
824                 && oldCallType != QnsConstants.CALL_TYPE_IDLE) {
825             rtpCallDrop.mRtpThresholdBreached =
826                     restrictManager.hasRestrictionType(
827                             transportTypeOfCall, RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY);
828             int otherTransportType =
829                     transportTypeOfCall == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
830                             ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN
831                             : AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
832             rtpCallDrop.mRestrictionsOnOtherTransportType =
833                     getRestrictionsBitmask(otherTransportType, restrictManager);
834         } else {
835             rtpCallDrop.mRtpThresholdBreached = false;
836             rtpCallDrop.mRestrictionsOnOtherTransportType = 0;
837         }
838     }
839 
procCallDroppedForImsCallDrop( int netCapability, int slotId, RestrictManager restrictManager, QualityMonitor cellularQualityMonitor, QualityMonitor wifiQualityMonitor, int transportTypeOfCall, int cellularAccessNetworkType)840     private void procCallDroppedForImsCallDrop(
841             int netCapability,
842             int slotId,
843             RestrictManager restrictManager,
844             QualityMonitor cellularQualityMonitor,
845             QualityMonitor wifiQualityMonitor,
846             int transportTypeOfCall,
847             int cellularAccessNetworkType) {
848         if (netCapability != NetworkCapabilities.NET_CAPABILITY_IMS) {
849             return;
850         }
851 
852         RtpCallDrop rtpCallDrop = mRtpCallDrop.get(slotId);
853         if (rtpCallDrop == null) {
854             rtpCallDrop = new RtpCallDrop();
855             mRtpCallDrop.put(slotId, rtpCallDrop);
856         }
857 
858         if (!rtpCallDrop.mRtpThresholdBreached
859                 || rtpCallDrop.mRestrictionsOnOtherTransportType == 0) {
860             rtpCallDrop.mRtpThresholdBreached = restrictManager.hasRestrictionType(
861                             transportTypeOfCall, RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY);
862             int otherTransportType =
863                     transportTypeOfCall == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
864                             ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN
865                             : AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
866             rtpCallDrop.mRestrictionsOnOtherTransportType =
867                     getRestrictionsBitmask(otherTransportType, restrictManager);
868         }
869 
870         int signalStrength = getSignalStrength(cellularQualityMonitor, cellularAccessNetworkType);
871         int signalQuality = getSignalQuality(cellularQualityMonitor, cellularAccessNetworkType);
872         int signalNoise = getSignalNoise(cellularQualityMonitor, cellularAccessNetworkType);
873         int iwlanSignalStrength = getSignalStrength(wifiQualityMonitor, AccessNetworkType.IWLAN);
874 
875         writeQnsImsCallDropStats(
876                 transportTypeOfCall,
877                 rtpCallDrop.mRtpThresholdBreached,
878                 rtpCallDrop.mRestrictionsOnOtherTransportType,
879                 signalStrength,
880                 signalQuality,
881                 signalNoise,
882                 iwlanSignalStrength,
883                 cellularAccessNetworkType,
884                 slotId);
885     }
886 
writeQnsImsCallDropStats( int transportTypeCallDropped, boolean rtpThresholdBreached, int restrictionsOnOtherTransportType, int signalStrength, int signalQuality, int signalNoise, int iwlanSignalStrength, int cellularNetworkType, int slotId)887     private void writeQnsImsCallDropStats(
888             int transportTypeCallDropped,
889             boolean rtpThresholdBreached,
890             int restrictionsOnOtherTransportType,
891             int signalStrength,
892             int signalQuality,
893             int signalNoise,
894             int iwlanSignalStrength,
895             int cellularNetworkType,
896             int slotId) {
897         AtomsQnsImsCallDropStats atoms =
898                 new AtomsQnsImsCallDropStats(
899                         transportTypeCallDropped,
900                         rtpThresholdBreached,
901                         restrictionsOnOtherTransportType,
902                         signalStrength,
903                         signalQuality,
904                         signalNoise,
905                         iwlanSignalStrength,
906                         slotId,
907                         cellularNetworkType);
908         mStats.write(atoms);
909     }
910 
getQualifiedAccessNetwork(QualifiedNetworksInfo info, int index)911     private int getQualifiedAccessNetwork(QualifiedNetworksInfo info, int index) {
912         List<Integer> types = info.getAccessNetworkTypes();
913         if (types == null || index >= types.size()) {
914             return QnsProtoEnums.EMPTY;
915         }
916         return types.get(index);
917     }
918 
getWfcEnabled(int coverage, boolean wfcEnabled, boolean wfcRoamingEnabled)919     private boolean getWfcEnabled(int coverage, boolean wfcEnabled, boolean wfcRoamingEnabled) {
920         return coverage == QnsConstants.COVERAGE_HOME ? wfcEnabled : wfcRoamingEnabled;
921     }
922 
getWfcMode(int coverage, int wfcMode, int wfcRoamingMode)923     private int getWfcMode(int coverage, int wfcMode, int wfcRoamingMode) {
924         return coverage == QnsConstants.COVERAGE_HOME ? wfcMode : wfcRoamingMode;
925     }
926 
getIwlanNetworkType(boolean iwlanAvailable, boolean isCrossWfc)927     private int getIwlanNetworkType(boolean iwlanAvailable, boolean isCrossWfc) {
928         if (!iwlanAvailable) {
929             return QnsProtoEnums.IWLAN_NETWORK_TYPE_NONE;
930         } else if (isCrossWfc) {
931             return QnsProtoEnums.IWLAN_NETWORK_TYPE_CST;
932         }
933         return QnsProtoEnums.IWLAN_NETWORK_TYPE_WIFI;
934     }
935 
936     static final HashMap<Integer, Integer> sAtomRestrictionsMap;
937 
938     static {
939         sAtomRestrictionsMap = new HashMap<>();
sAtomRestrictionsMap.put( RestrictManager.RESTRICT_TYPE_GUARDING, QnsProtoEnums.RESTRICT_TYPE_GUARDING)940         sAtomRestrictionsMap.put(
941                 RestrictManager.RESTRICT_TYPE_GUARDING, QnsProtoEnums.RESTRICT_TYPE_GUARDING);
sAtomRestrictionsMap.put( RestrictManager.RESTRICT_TYPE_THROTTLING, QnsProtoEnums.RESTRICT_TYPE_THROTTLING)942         sAtomRestrictionsMap.put(
943                 RestrictManager.RESTRICT_TYPE_THROTTLING, QnsProtoEnums.RESTRICT_TYPE_THROTTLING);
sAtomRestrictionsMap.put( RestrictManager.RESTRICT_TYPE_HO_NOT_ALLOWED, QnsProtoEnums.RESTRICT_TYPE_HO_NOT_ALLOWED)944         sAtomRestrictionsMap.put(
945                 RestrictManager.RESTRICT_TYPE_HO_NOT_ALLOWED,
946                 QnsProtoEnums.RESTRICT_TYPE_HO_NOT_ALLOWED);
sAtomRestrictionsMap.put( RestrictManager.RESTRICT_TYPE_NON_PREFERRED_TRANSPORT, QnsProtoEnums.RESTRICT_TYPE_NON_PREFERRED_TRANSPORT)947         sAtomRestrictionsMap.put(
948                 RestrictManager.RESTRICT_TYPE_NON_PREFERRED_TRANSPORT,
949                 QnsProtoEnums.RESTRICT_TYPE_NON_PREFERRED_TRANSPORT);
sAtomRestrictionsMap.put( RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY, QnsProtoEnums.RESTRICT_TYPE_RTP_LOW_QUALITY)950         sAtomRestrictionsMap.put(
951                 RestrictManager.RESTRICT_TYPE_RTP_LOW_QUALITY,
952                 QnsProtoEnums.RESTRICT_TYPE_RTP_LOW_QUALITY);
sAtomRestrictionsMap.put( RestrictManager.RESTRICT_TYPE_RESTRICT_IWLAN_IN_CALL, QnsProtoEnums.RESTRICT_TYPE_RESTRICT_IWLAN_IN_CALL)953         sAtomRestrictionsMap.put(
954                 RestrictManager.RESTRICT_TYPE_RESTRICT_IWLAN_IN_CALL,
955                 QnsProtoEnums.RESTRICT_TYPE_RESTRICT_IWLAN_IN_CALL);
sAtomRestrictionsMap.put( RestrictManager.RESTRICT_TYPE_RESTRICT_IWLAN_CS_CALL, QnsProtoEnums.RESTRICT_TYPE_RESTRICT_IWLAN_CS_CALL)956         sAtomRestrictionsMap.put(
957                 RestrictManager.RESTRICT_TYPE_RESTRICT_IWLAN_CS_CALL,
958                 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)959         sAtomRestrictionsMap.put(
960                 RestrictManager.RESTRICT_TYPE_FALLBACK_TO_WWAN_IMS_REGI_FAIL,
961                 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)962         sAtomRestrictionsMap.put(
963                 RestrictManager.RESTRICT_TYPE_FALLBACK_ON_DATA_CONNECTION_FAIL,
964                 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)965         sAtomRestrictionsMap.put(
966                 RestrictManager.RESTRICT_TYPE_FALLBACK_TO_WWAN_RTT_BACKHAUL_FAIL,
967                 QnsProtoEnums.RESTRICT_TYPE_FALLBACK_TO_WWAN_RTT_BACKHAUL_FAIL);
968     }
969 
getRestrictionsBitmask(int transportType, RestrictManager restrictManager)970     private int getRestrictionsBitmask(int transportType, RestrictManager restrictManager) {
971         int restrictions = QnsProtoEnums.RESTRICT_TYPE_NONE;
972         for (int restrictionType : sAtomRestrictionsMap.keySet()) {
973             if (restrictManager.hasRestrictionType(transportType, restrictionType)) {
974                 restrictions |= sAtomRestrictionsMap.get(restrictionType);
975             }
976         }
977         return restrictions;
978     }
979 
getSignalStrength(QualityMonitor qm, int accessNetworkType)980     private int getSignalStrength(QualityMonitor qm, int accessNetworkType) {
981         switch (accessNetworkType) {
982             case AccessNetworkType.GERAN:
983             case AccessNetworkType.IWLAN:
984                 return qm.getCurrentQuality(
985                         accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI);
986             case AccessNetworkType.UTRAN:
987                 return qm.getCurrentQuality(
988                         accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP);
989             case AccessNetworkType.EUTRAN:
990                 return qm.getCurrentQuality(
991                         accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP);
992             case AccessNetworkType.NGRAN:
993                 return qm.getCurrentQuality(
994                         accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP);
995         }
996         return 0;
997     }
998 
getSignalQuality(QualityMonitor qm, int accessNetworkType)999     private int getSignalQuality(QualityMonitor qm, int accessNetworkType) {
1000         switch (accessNetworkType) {
1001             case AccessNetworkType.EUTRAN:
1002                 return qm.getCurrentQuality(
1003                         accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ);
1004             case AccessNetworkType.NGRAN:
1005                 return qm.getCurrentQuality(
1006                         accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ);
1007         }
1008         return 0;
1009     }
1010 
getSignalNoise(QualityMonitor qm, int accessNetworkType)1011     private int getSignalNoise(QualityMonitor qm, int accessNetworkType) {
1012         switch (accessNetworkType) {
1013             case AccessNetworkType.EUTRAN:
1014                 return qm.getCurrentQuality(
1015                         accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR);
1016             case AccessNetworkType.NGRAN:
1017                 return qm.getCurrentQuality(
1018                         accessNetworkType, SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR);
1019         }
1020         return 0;
1021     }
1022 
log(String s)1023     protected void log(String s) {
1024         Log.d(mLogTag, s);
1025     }
1026 }
1027