• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.networkstack.metrics;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.net.util.NetworkStackUtils;
22 import android.net.wifi.WifiInfo;
23 
24 import com.android.internal.util.HexDump;
25 import com.android.server.connectivity.nano.CellularData;
26 import com.android.server.connectivity.nano.DataStallEventProto;
27 import com.android.server.connectivity.nano.DnsEvent;
28 import com.android.server.connectivity.nano.WifiData;
29 
30 import com.google.protobuf.nano.MessageNano;
31 
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.Objects;
36 
37 /**
38  * Class to record the stats of detection level information for data stall.
39  *
40  * @hide
41  */
42 public final class DataStallDetectionStats {
43     private static final int UNKNOWN_SIGNAL_STRENGTH = -1;
44     @NonNull
45     final byte[] mCellularInfo;
46     @NonNull
47     final byte[] mWifiInfo;
48     @NonNull
49     final byte[] mDns;
50     final int mEvaluationType;
51     final int mNetworkType;
52 
DataStallDetectionStats(@ullable byte[] cell, @Nullable byte[] wifi, @NonNull int[] returnCode, @NonNull long[] dnsTime, int evalType, int netType)53     public DataStallDetectionStats(@Nullable byte[] cell, @Nullable byte[] wifi,
54                 @NonNull int[] returnCode, @NonNull long[] dnsTime, int evalType, int netType) {
55         mCellularInfo = emptyCellDataIfNull(cell);
56         mWifiInfo = emptyWifiInfoIfNull(wifi);
57 
58         DnsEvent dns = new DnsEvent();
59         dns.dnsReturnCode = returnCode;
60         dns.dnsTime = dnsTime;
61         mDns = MessageNano.toByteArray(dns);
62         mEvaluationType = evalType;
63         mNetworkType = netType;
64     }
65 
emptyCellDataIfNull(@ullable byte[] cell)66     private byte[] emptyCellDataIfNull(@Nullable byte[] cell) {
67         if (cell != null) return cell;
68 
69         CellularData data  = new CellularData();
70         data.ratType = DataStallEventProto.RADIO_TECHNOLOGY_UNKNOWN;
71         data.networkMccmnc = "";
72         data.simMccmnc = "";
73         data.signalStrength = UNKNOWN_SIGNAL_STRENGTH;
74         return MessageNano.toByteArray(data);
75     }
76 
emptyWifiInfoIfNull(@ullable byte[] wifi)77     private byte[] emptyWifiInfoIfNull(@Nullable byte[] wifi) {
78         if (wifi != null) return wifi;
79 
80         WifiData data = new WifiData();
81         data.wifiBand = DataStallEventProto.AP_BAND_UNKNOWN;
82         data.signalStrength = UNKNOWN_SIGNAL_STRENGTH;
83         return MessageNano.toByteArray(data);
84     }
85 
86     @Override
toString()87     public String toString() {
88         StringBuilder sb = new StringBuilder();
89         sb.append("type: ").append(mNetworkType)
90           .append(", evaluation type: ")
91           .append(mEvaluationType)
92           .append(", wifi info: ")
93           .append(HexDump.toHexString(mWifiInfo))
94           .append(", cell info: ")
95           .append(HexDump.toHexString(mCellularInfo))
96           .append(", dns: ")
97           .append(HexDump.toHexString(mDns));
98         return sb.toString();
99     }
100 
101     @Override
equals(@ullable final Object o)102     public boolean equals(@Nullable final Object o) {
103         if (!(o instanceof DataStallDetectionStats)) return false;
104         final DataStallDetectionStats other = (DataStallDetectionStats) o;
105         return (mNetworkType == other.mNetworkType)
106             && (mEvaluationType == other.mEvaluationType)
107             && Arrays.equals(mWifiInfo, other.mWifiInfo)
108             && Arrays.equals(mCellularInfo, other.mCellularInfo)
109             && Arrays.equals(mDns, other.mDns);
110     }
111 
112     @Override
hashCode()113     public int hashCode() {
114         return Objects.hash(mNetworkType, mEvaluationType, mWifiInfo, mCellularInfo, mDns);
115     }
116 
117     /**
118      * Utility to create an instance of {@Link DataStallDetectionStats}
119      *
120      * @hide
121      */
122     public static class Builder {
123         @Nullable
124         private byte[] mCellularInfo;
125         @Nullable
126         private byte[] mWifiInfo;
127         @NonNull
128         private final List<Integer> mDnsReturnCode = new ArrayList<Integer>();
129         @NonNull
130         private final List<Long> mDnsTimeStamp = new ArrayList<Long>();
131         private int mEvaluationType;
132         private int mNetworkType;
133 
134         /**
135          * Add a dns event into Builder.
136          *
137          * @param code the return code of the dns event.
138          * @param timeMs the elapsedRealtime in ms that the the dns event was received from netd.
139          * @return {@code this} {@link Builder} instance.
140          */
addDnsEvent(int code, long timeMs)141         public Builder addDnsEvent(int code, long timeMs) {
142             mDnsReturnCode.add(code);
143             mDnsTimeStamp.add(timeMs);
144             return this;
145         }
146 
147         /**
148          * Set the dns evaluation type into Builder.
149          *
150          * @param type the return code of the dns event.
151          * @return {@code this} {@link Builder} instance.
152          */
setEvaluationType(int type)153         public Builder setEvaluationType(int type) {
154             mEvaluationType = type;
155             return this;
156         }
157 
158         /**
159          * Set the network type into Builder.
160          *
161          * @param type the network type of the logged network.
162          * @return {@code this} {@link Builder} instance.
163          */
setNetworkType(int type)164         public Builder setNetworkType(int type) {
165             mNetworkType = type;
166             return this;
167         }
168 
169         /**
170          * Set the wifi data into Builder.
171          *
172          * @param info a {@link WifiInfo} of the connected wifi network.
173          * @return {@code this} {@link Builder} instance.
174          */
setWiFiData(@ullable final WifiInfo info)175         public Builder setWiFiData(@Nullable final WifiInfo info) {
176             WifiData data = new WifiData();
177             data.wifiBand = getWifiBand(info);
178             data.signalStrength = (info != null) ? info.getRssi() : UNKNOWN_SIGNAL_STRENGTH;
179             mWifiInfo = MessageNano.toByteArray(data);
180             return this;
181         }
182 
getWifiBand(@ullable final WifiInfo info)183         private static int getWifiBand(@Nullable final WifiInfo info) {
184             if (info == null) return DataStallEventProto.AP_BAND_UNKNOWN;
185 
186             int freq = info.getFrequency();
187             // Refer to ScanResult.is5GHz() and ScanResult.is24GHz().
188             if (freq > 4900 && freq < 5900) {
189                 return DataStallEventProto.AP_BAND_5GHZ;
190             } else if (freq > 2400 && freq < 2500) {
191                 return DataStallEventProto.AP_BAND_2GHZ;
192             } else {
193                 return DataStallEventProto.AP_BAND_UNKNOWN;
194             }
195         }
196 
197         /**
198          * Set the cellular data into Builder.
199          *
200          * @param radioType the radio technology of the logged cellular network.
201          * @param roaming a boolean indicates if logged cellular network is roaming or not.
202          * @param networkMccmnc the mccmnc of the camped network.
203          * @param simMccmnc the mccmnc of the sim.
204          * @return {@code this} {@link Builder} instance.
205          */
setCellData(int radioType, boolean roaming, @NonNull String networkMccmnc, @NonNull String simMccmnc, int ss)206         public Builder setCellData(int radioType, boolean roaming,
207                 @NonNull String networkMccmnc, @NonNull String simMccmnc, int ss) {
208             CellularData data  = new CellularData();
209             data.ratType = radioType;
210             data.isRoaming = roaming;
211             data.networkMccmnc = networkMccmnc;
212             data.simMccmnc = simMccmnc;
213             data.signalStrength = ss;
214             mCellularInfo = MessageNano.toByteArray(data);
215             return this;
216         }
217 
218         /**
219          * Create a new {@Link DataStallDetectionStats}.
220          */
build()221         public DataStallDetectionStats build() {
222             return new DataStallDetectionStats(mCellularInfo, mWifiInfo,
223                     NetworkStackUtils.convertToIntArray(mDnsReturnCode),
224                     NetworkStackUtils.convertToLongArray(mDnsTimeStamp),
225                     mEvaluationType, mNetworkType);
226         }
227     }
228 }
229