1 /*
2  * Copyright (C) 2020 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.internal.telephony.metrics;
18 
19 import android.telephony.Annotation.NetworkType;
20 import android.telephony.ServiceState;
21 import android.telephony.TelephonyManager;
22 
23 import com.android.internal.telephony.Phone;
24 import com.android.internal.telephony.PhoneConstants;
25 import com.android.internal.telephony.ServiceStateTracker;
26 import com.android.internal.telephony.SubscriptionController;
27 import com.android.internal.telephony.TelephonyStatsLog;
28 import com.android.internal.telephony.dataconnection.DcTracker;
29 
30 /** Generates metrics related to data stall recovery events per phone ID for the pushed atom. */
31 public class DataStallRecoveryStats {
32     /**
33      * Create and push new atom when there is a data stall recovery event
34      *
35      * @param recoveryAction Data stall recovery action
36      * @param phone
37      */
onDataStallEvent( @cTracker.RecoveryAction int recoveryAction, Phone phone, boolean isRecovered, int durationMillis)38     public static void onDataStallEvent(
39             @DcTracker.RecoveryAction int recoveryAction,
40             Phone phone,
41             boolean isRecovered,
42             int durationMillis) {
43         if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
44             phone = phone.getDefaultPhone();
45         }
46 
47         int carrierId = phone.getCarrierId();
48         int rat = getRat(phone);
49         int band =
50                 (rat == TelephonyManager.NETWORK_TYPE_IWLAN) ? 0 : ServiceStateStats.getBand(phone);
51         // the number returned here matches the SignalStrength enum we have
52         int signalStrength = phone.getSignalStrength().getLevel();
53         boolean isOpportunistic = getIsOpportunistic(phone);
54         boolean isMultiSim = SimSlotState.getCurrentState().numActiveSims > 1;
55 
56         TelephonyStatsLog.write(
57                 TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED,
58                 carrierId,
59                 rat,
60                 signalStrength,
61                 recoveryAction,
62                 isOpportunistic,
63                 isMultiSim,
64                 band,
65                 isRecovered,
66                 durationMillis);
67     }
68 
69     /** Returns the RAT used for data (including IWLAN). */
getRat(Phone phone)70     private static @NetworkType int getRat(Phone phone) {
71         ServiceStateTracker serviceStateTracker = phone.getServiceStateTracker();
72         ServiceState serviceState =
73                 serviceStateTracker != null ? serviceStateTracker.getServiceState() : null;
74         return serviceState != null
75                 ? serviceState.getDataNetworkType()
76                 : TelephonyManager.NETWORK_TYPE_UNKNOWN;
77     }
78 
getIsOpportunistic(Phone phone)79     private static boolean getIsOpportunistic(Phone phone) {
80         SubscriptionController subController = SubscriptionController.getInstance();
81         return subController != null ? subController.isOpportunistic(phone.getSubId()) : false;
82     }
83 }
84