• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.annotation.ElapsedRealtimeLong;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.os.SystemClock;
23 import android.telephony.Annotation.ApnType;
24 import android.telephony.Annotation.NetworkType;
25 import android.telephony.PreciseDataConnectionState;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 import com.android.internal.telephony.Phone;
29 import com.android.internal.telephony.PhoneFactory;
30 import com.android.internal.telephony.TelephonyStatsLog;
31 import com.android.internal.telephony.nano.PersistAtomsProto.DataNetworkValidation;
32 
33 /**
34  * DataNetworkValidationStats logs the atoms for response after a validation request from the
35  * DataNetwork in framework.
36  */
37 public class DataNetworkValidationStats {
38 
39     private static final String TAG = DataNetworkValidationStats.class.getSimpleName();
40 
41     @NonNull
42     private final Phone mPhone;
43 
44     @NonNull
45     private final PersistAtomsStorage mAtomsStorage =
46             PhoneFactory.getMetricsCollector().getAtomsStorage();
47 
48     @Nullable
49     private DataNetworkValidation mDataNetworkValidation;
50 
51     @ElapsedRealtimeLong
52     private long mRequestedTimeInMillis;
53 
54     /** constructor */
DataNetworkValidationStats(@onNull Phone phone)55     public DataNetworkValidationStats(@NonNull Phone phone) {
56         mPhone = phone;
57     }
58 
59 
60     /**
61      * Create a new ongoing atom when NetworkValidation requested.
62      *
63      * Create a data network validation proto for a new atom record and write the start time to
64      * calculate the elapsed time required.
65      *
66      * @param apnTypeBitMask APN type bitmask of DataNetwork.
67      */
onRequestNetworkValidation(@pnType int apnTypeBitMask)68     public void onRequestNetworkValidation(@ApnType int apnTypeBitMask) {
69         if (mDataNetworkValidation == null) {
70             mDataNetworkValidation = getDefaultProto(apnTypeBitMask);
71             mRequestedTimeInMillis = getTimeMillis();
72         }
73     }
74 
75     /** Mark the Handover Attempt field as true if validation was requested */
onHandoverAttempted()76     public void onHandoverAttempted() {
77         if (mDataNetworkValidation != null) {
78             mDataNetworkValidation.handoverAttempted = true;
79         }
80     }
81 
82     /**
83      * Called when data network is disconnected.
84      *
85      * Since network validation is based on the data network, validation must also end when the data
86      * network is disconnected. At this time, validation has not been completed, save an atom as
87      * unspecified. and clear.
88      *
89      * @param networkType Current Network Type of the Data Network.
90      */
onDataNetworkDisconnected(@etworkType int networkType)91     public void onDataNetworkDisconnected(@NetworkType int networkType) {
92         // Nothing to do, if never requested validation
93         if (mDataNetworkValidation == null) {
94             return;
95         }
96 
97         // Set data for and atom.
98         calcElapsedTime();
99         mDataNetworkValidation.networkType = networkType;
100         mDataNetworkValidation.signalStrength = mPhone.getSignalStrength().getLevel();
101         mDataNetworkValidation.validationResult = TelephonyStatsLog
102                 .DATA_NETWORK_VALIDATION__VALIDATION_RESULT__VALIDATION_RESULT_UNSPECIFIED;
103 
104         // Store.
105         mAtomsStorage.addDataNetworkValidation(mDataNetworkValidation);
106 
107         // clear all values.
108         clear();
109     }
110 
111     /**
112      * Store an atom by updated state.
113      *
114      * Called when the validation status is updated, and saves the atom when a failure or success
115      * result is received.
116      *
117      * @param status Data Network Validation Status.
118      * @param networkType Current Network Type of the Data Network.
119      */
onUpdateNetworkValidationState( @reciseDataConnectionState.NetworkValidationStatus int status, @NetworkType int networkType)120     public void onUpdateNetworkValidationState(
121             @PreciseDataConnectionState.NetworkValidationStatus int status,
122             @NetworkType int networkType) {
123         // Nothing to do, if never requested validation
124         if (mDataNetworkValidation == null) {
125             return;
126         }
127 
128         switch (status) {
129             // Immediately after requesting validation, these messages may occur. In this case,
130             // ignore it and wait for the next update.
131             case PreciseDataConnectionState.NETWORK_VALIDATION_NOT_REQUESTED: // fall-through
132             case PreciseDataConnectionState.NETWORK_VALIDATION_IN_PROGRESS:
133                 return;
134             // If status is unsupported, NetworkValidation should not be requested initially. logs
135             // this for abnormal tracking.
136             case PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED:
137                 mDataNetworkValidation.validationResult = TelephonyStatsLog
138                     .DATA_NETWORK_VALIDATION__VALIDATION_RESULT__VALIDATION_RESULT_NOT_SUPPORTED;
139                 break;
140             // Success or failure corresponds to the result, store an atom.
141             case PreciseDataConnectionState.NETWORK_VALIDATION_SUCCESS:
142             case PreciseDataConnectionState.NETWORK_VALIDATION_FAILURE:
143                 mDataNetworkValidation.validationResult = status;
144                 break;
145         }
146 
147         // Set data for and atom.
148         calcElapsedTime();
149         mDataNetworkValidation.networkType = networkType;
150         mDataNetworkValidation.signalStrength = mPhone.getSignalStrength().getLevel();
151 
152         // Store.
153         mAtomsStorage.addDataNetworkValidation(mDataNetworkValidation);
154 
155         // clear all values.
156         clear();
157     }
158 
159     /**
160      * Calculate the current time required based on when network validation is requested.
161      */
calcElapsedTime()162     private void calcElapsedTime() {
163         if (mDataNetworkValidation != null && mRequestedTimeInMillis != 0) {
164             mDataNetworkValidation.elapsedTimeInMillis = getTimeMillis() - mRequestedTimeInMillis;
165         }
166     }
167 
168     /**
169      * Returns current time in millis from boot.
170      */
171     @VisibleForTesting
172     @ElapsedRealtimeLong
getTimeMillis()173     protected long getTimeMillis() {
174         return SystemClock.elapsedRealtime();
175     }
176 
177     /**
178      * Clear all values.
179      */
clear()180     private void clear() {
181         mDataNetworkValidation = null;
182         mRequestedTimeInMillis = 0;
183     }
184 
185 
186     /** Creates a DataNetworkValidation proto with default values. */
187     @NonNull
getDefaultProto(@pnType int apnTypeBitmask)188     private DataNetworkValidation getDefaultProto(@ApnType int apnTypeBitmask) {
189         DataNetworkValidation proto = new DataNetworkValidation();
190         proto.networkType =
191                 TelephonyStatsLog.DATA_NETWORK_VALIDATION__NETWORK_TYPE__NETWORK_TYPE_UNKNOWN;
192         proto.apnTypeBitmask = apnTypeBitmask;
193         proto.signalStrength =
194                 TelephonyStatsLog
195                         .DATA_NETWORK_VALIDATION__SIGNAL_STRENGTH__SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
196         proto.validationResult =
197                 TelephonyStatsLog
198                         .DATA_NETWORK_VALIDATION__VALIDATION_RESULT__VALIDATION_RESULT_UNSPECIFIED;
199         proto.elapsedTimeInMillis = 0;
200         proto.handoverAttempted = false;
201         proto.networkValidationCount = 1;
202         return proto;
203     }
204 }
205 
206