• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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.data;
18 
19 import android.annotation.CurrentTimeMillisLong;
20 import android.annotation.ElapsedRealtimeLong;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.net.NetworkAgent;
24 import android.net.NetworkCapabilities;
25 import android.os.SystemClock;
26 import android.telephony.AccessNetworkConstants;
27 import android.telephony.AccessNetworkConstants.AccessNetworkType;
28 import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
29 import android.telephony.AccessNetworkConstants.TransportType;
30 import android.telephony.Annotation.DataActivityType;
31 import android.telephony.Annotation.NetCapability;
32 import android.telephony.Annotation.NetworkType;
33 import android.telephony.Annotation.ValidationStatus;
34 import android.telephony.TelephonyManager;
35 import android.telephony.data.ApnSetting;
36 import android.telephony.data.ApnSetting.ApnType;
37 import android.telephony.data.DataCallResponse;
38 import android.telephony.data.DataCallResponse.LinkStatus;
39 import android.telephony.data.DataProfile;
40 import android.telephony.ims.feature.ImsFeature;
41 import android.util.ArrayMap;
42 
43 import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
44 import com.android.telephony.Rlog;
45 
46 import java.text.SimpleDateFormat;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collection;
50 import java.util.Collections;
51 import java.util.Comparator;
52 import java.util.List;
53 import java.util.Locale;
54 import java.util.Map;
55 import java.util.Set;
56 import java.util.stream.Collectors;
57 
58 /**
59  * This class contains all the utility methods used by telephony data stack.
60  */
61 public class DataUtils {
62     /** The time format for converting time to readable string. */
63     private static final SimpleDateFormat TIME_FORMAT =
64             new SimpleDateFormat("HH:mm:ss.SSS", Locale.US);
65     private static final String TAG = "DataUtils";
66 
67     /**
68      * Get the network capability from the string.
69      *
70      * @param capabilityString The capability in string format
71      * @return The network capability. -1 if not found.
72      */
getNetworkCapabilityFromString( @onNull String capabilityString)73     public static @NetCapability int getNetworkCapabilityFromString(
74             @NonNull String capabilityString) {
75         switch (capabilityString.toUpperCase(Locale.ROOT)) {
76             case "MMS": return NetworkCapabilities.NET_CAPABILITY_MMS;
77             case "SUPL": return NetworkCapabilities.NET_CAPABILITY_SUPL;
78             case "DUN": return NetworkCapabilities.NET_CAPABILITY_DUN;
79             case "FOTA": return NetworkCapabilities.NET_CAPABILITY_FOTA;
80             case "IMS": return NetworkCapabilities.NET_CAPABILITY_IMS;
81             case "CBS": return NetworkCapabilities.NET_CAPABILITY_CBS;
82             case "XCAP": return NetworkCapabilities.NET_CAPABILITY_XCAP;
83             case "EIMS": return NetworkCapabilities.NET_CAPABILITY_EIMS;
84             case "INTERNET": return NetworkCapabilities.NET_CAPABILITY_INTERNET;
85             case "MCX": return NetworkCapabilities.NET_CAPABILITY_MCX;
86             case "VSIM": return NetworkCapabilities.NET_CAPABILITY_VSIM;
87             case "BIP" : return NetworkCapabilities.NET_CAPABILITY_BIP;
88             case "ENTERPRISE": return NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
89             case "PRIORITIZE_BANDWIDTH":
90                 return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
91             case "PRIORITIZE_LATENCY":
92                 return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
93             default:
94                 return -1;
95         }
96     }
97 
98     /**
99      * Get Set of network capabilities from string joined by {@code |}, space is ignored.
100      * If input string contains unknown capability or malformatted(e.g. empty string), -1 is
101      * included in the returned set.
102      *
103      * @param capabilitiesString capability strings joined by {@code |}
104      * @return Set of capabilities
105      */
getNetworkCapabilitiesFromString( @onNull String capabilitiesString)106     public static @NetCapability Set<Integer> getNetworkCapabilitiesFromString(
107             @NonNull String capabilitiesString) {
108         // e.g. "IMS|" is not allowed
109         if (!capabilitiesString.matches("(\\s*[a-zA-Z]+\\s*)(\\|\\s*[a-zA-Z]+\\s*)*")) {
110             return Collections.singleton(-1);
111         }
112         return Arrays.stream(capabilitiesString.split("\\s*\\|\\s*"))
113                 .map(String::trim)
114                 .map(DataUtils::getNetworkCapabilityFromString)
115                 .collect(Collectors.toSet());
116     }
117 
118     /**
119      * Convert a network capability to string.
120      *
121      * This is for debugging and logging purposes only.
122      *
123      * @param netCap Network capability.
124      * @return Network capability in string format.
125      */
networkCapabilityToString(@etCapability int netCap)126     public static @NonNull String networkCapabilityToString(@NetCapability int netCap) {
127         switch (netCap) {
128             case NetworkCapabilities.NET_CAPABILITY_MMS:                  return "MMS";
129             case NetworkCapabilities.NET_CAPABILITY_SUPL:                 return "SUPL";
130             case NetworkCapabilities.NET_CAPABILITY_DUN:                  return "DUN";
131             case NetworkCapabilities.NET_CAPABILITY_FOTA:                 return "FOTA";
132             case NetworkCapabilities.NET_CAPABILITY_IMS:                  return "IMS";
133             case NetworkCapabilities.NET_CAPABILITY_CBS:                  return "CBS";
134             case NetworkCapabilities.NET_CAPABILITY_WIFI_P2P:             return "WIFI_P2P";
135             case NetworkCapabilities.NET_CAPABILITY_IA:                   return "IA";
136             case NetworkCapabilities.NET_CAPABILITY_RCS:                  return "RCS";
137             case NetworkCapabilities.NET_CAPABILITY_XCAP:                 return "XCAP";
138             case NetworkCapabilities.NET_CAPABILITY_EIMS:                 return "EIMS";
139             case NetworkCapabilities.NET_CAPABILITY_NOT_METERED:          return "NOT_METERED";
140             case NetworkCapabilities.NET_CAPABILITY_INTERNET:             return "INTERNET";
141             case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED:       return "NOT_RESTRICTED";
142             case NetworkCapabilities.NET_CAPABILITY_TRUSTED:              return "TRUSTED";
143             case NetworkCapabilities.NET_CAPABILITY_NOT_VPN:              return "NOT_VPN";
144             case NetworkCapabilities.NET_CAPABILITY_VALIDATED:            return "VALIDATED";
145             case NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL:       return "CAPTIVE_PORTAL";
146             case NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING:          return "NOT_ROAMING";
147             case NetworkCapabilities.NET_CAPABILITY_FOREGROUND:           return "FOREGROUND";
148             case NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED:        return "NOT_CONGESTED";
149             case NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED:        return "NOT_SUSPENDED";
150             case NetworkCapabilities.NET_CAPABILITY_OEM_PAID:             return "OEM_PAID";
151             case NetworkCapabilities.NET_CAPABILITY_MCX:                  return "MCX";
152             case NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY:
153                 return "PARTIAL_CONNECTIVITY";
154             case NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED:
155                 return "TEMPORARILY_NOT_METERED";
156             case NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE:          return "OEM_PRIVATE";
157             case NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL:     return "VEHICLE_INTERNAL";
158             case NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED:      return "NOT_VCN_MANAGED";
159             case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:           return "ENTERPRISE";
160             case NetworkCapabilities.NET_CAPABILITY_VSIM:                 return "VSIM";
161             case NetworkCapabilities.NET_CAPABILITY_BIP:                  return "BIP";
162             case NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT:            return "HEAD_UNIT";
163             case NetworkCapabilities.NET_CAPABILITY_MMTEL:                return "MMTEL";
164             case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY:
165                 return "PRIORITIZE_LATENCY";
166             case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH:
167                 return "PRIORITIZE_BANDWIDTH";
168             default:
169                 loge("Unknown network capability(" + netCap + ")");
170                 return "Unknown(" + netCap + ")";
171         }
172     }
173 
174     /**
175      * Convert network capabilities to string.
176      *
177      * This is for debugging and logging purposes only.
178      *
179      * @param netCaps Network capabilities.
180      * @return Network capabilities in string format.
181      */
networkCapabilitiesToString( @etCapability @ullable Collection<Integer> netCaps)182     public static @NonNull String networkCapabilitiesToString(
183             @NetCapability @Nullable Collection<Integer> netCaps) {
184         if (netCaps == null || netCaps.isEmpty()) return "";
185         return "[" + netCaps.stream()
186                 .map(DataUtils::networkCapabilityToString)
187                 .collect(Collectors.joining("|")) + "]";
188     }
189 
190     /**
191      * Convert network capabilities to string.
192      *
193      * This is for debugging and logging purposes only.
194      *
195      * @param netCaps Network capabilities.
196      * @return Network capabilities in string format.
197      */
networkCapabilitiesToString(@etCapability int[] netCaps)198     public static @NonNull String networkCapabilitiesToString(@NetCapability int[] netCaps) {
199         if (netCaps == null) return "";
200         return "[" + Arrays.stream(netCaps)
201                 .mapToObj(DataUtils::networkCapabilityToString)
202                 .collect(Collectors.joining("|")) + "]";
203     }
204 
205     /**
206      * Convert the validation status to string.
207      *
208      * @param status The validation status.
209      * @return The validation status in string format.
210      */
validationStatusToString(@alidationStatus int status)211     public static @NonNull String validationStatusToString(@ValidationStatus int status) {
212         switch (status) {
213             case NetworkAgent.VALIDATION_STATUS_VALID: return "VALID";
214             case NetworkAgent.VALIDATION_STATUS_NOT_VALID: return "INVALID";
215             default:
216                 loge("Unknown validation status(" + status + ")");
217                 return "UNKNOWN(" + status + ")";
218         }
219     }
220 
221     /**
222      * Convert network capability into APN type.
223      *
224      * @param networkCapability Network capability.
225      * @return APN type.
226      */
networkCapabilityToApnType(@etCapability int networkCapability)227     public static @ApnType int networkCapabilityToApnType(@NetCapability int networkCapability) {
228         switch (networkCapability) {
229             case NetworkCapabilities.NET_CAPABILITY_MMS:
230                 return ApnSetting.TYPE_MMS;
231             case NetworkCapabilities.NET_CAPABILITY_SUPL:
232                 return ApnSetting.TYPE_SUPL;
233             case NetworkCapabilities.NET_CAPABILITY_DUN:
234                 return ApnSetting.TYPE_DUN;
235             case NetworkCapabilities.NET_CAPABILITY_FOTA:
236                 return ApnSetting.TYPE_FOTA;
237             case NetworkCapabilities.NET_CAPABILITY_IMS:
238                 return ApnSetting.TYPE_IMS;
239             case NetworkCapabilities.NET_CAPABILITY_CBS:
240                 return ApnSetting.TYPE_CBS;
241             case NetworkCapabilities.NET_CAPABILITY_XCAP:
242                 return ApnSetting.TYPE_XCAP;
243             case NetworkCapabilities.NET_CAPABILITY_EIMS:
244                 return ApnSetting.TYPE_EMERGENCY;
245             case NetworkCapabilities.NET_CAPABILITY_INTERNET:
246                 return ApnSetting.TYPE_DEFAULT;
247             case NetworkCapabilities.NET_CAPABILITY_MCX:
248                 return ApnSetting.TYPE_MCX;
249             case NetworkCapabilities.NET_CAPABILITY_IA:
250                 return ApnSetting.TYPE_IA;
251             case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:
252                 return ApnSetting.TYPE_ENTERPRISE;
253             case NetworkCapabilities.NET_CAPABILITY_VSIM:
254                 return ApnSetting.TYPE_VSIM;
255             case NetworkCapabilities.NET_CAPABILITY_BIP:
256                 return ApnSetting.TYPE_BIP;
257             default:
258                 return ApnSetting.TYPE_NONE;
259         }
260     }
261 
262     /**
263      * Convert APN type to capability.
264      *
265      * @param apnType APN type.
266      * @return Network capability.
267      */
apnTypeToNetworkCapability(@pnType int apnType)268     public static @NetCapability int apnTypeToNetworkCapability(@ApnType int apnType) {
269         switch (apnType) {
270             case ApnSetting.TYPE_MMS:
271                 return NetworkCapabilities.NET_CAPABILITY_MMS;
272             case ApnSetting.TYPE_SUPL:
273                 return NetworkCapabilities.NET_CAPABILITY_SUPL;
274             case ApnSetting.TYPE_DUN:
275                 return NetworkCapabilities.NET_CAPABILITY_DUN;
276             case ApnSetting.TYPE_FOTA:
277                 return NetworkCapabilities.NET_CAPABILITY_FOTA;
278             case ApnSetting.TYPE_IMS:
279                 return NetworkCapabilities.NET_CAPABILITY_IMS;
280             case ApnSetting.TYPE_CBS:
281                 return NetworkCapabilities.NET_CAPABILITY_CBS;
282             case ApnSetting.TYPE_XCAP:
283                 return NetworkCapabilities.NET_CAPABILITY_XCAP;
284             case ApnSetting.TYPE_EMERGENCY:
285                 return NetworkCapabilities.NET_CAPABILITY_EIMS;
286             case ApnSetting.TYPE_DEFAULT:
287                 return NetworkCapabilities.NET_CAPABILITY_INTERNET;
288             case ApnSetting.TYPE_MCX:
289                 return NetworkCapabilities.NET_CAPABILITY_MCX;
290             case ApnSetting.TYPE_IA:
291                 return NetworkCapabilities.NET_CAPABILITY_IA;
292             case ApnSetting.TYPE_BIP:
293                 return NetworkCapabilities.NET_CAPABILITY_BIP;
294             case ApnSetting.TYPE_VSIM:
295                 return NetworkCapabilities.NET_CAPABILITY_VSIM;
296             case ApnSetting.TYPE_ENTERPRISE:
297                 return NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
298             default:
299                 return -1;
300         }
301     }
302 
303     /**
304      * Convert network type to access network type.
305      *
306      * @param networkType The network type.
307      * @return The access network type.
308      */
networkTypeToAccessNetworkType( @etworkType int networkType)309     public static @RadioAccessNetworkType int networkTypeToAccessNetworkType(
310             @NetworkType int networkType) {
311         switch (networkType) {
312             case TelephonyManager.NETWORK_TYPE_GPRS:
313             case TelephonyManager.NETWORK_TYPE_EDGE:
314             case TelephonyManager.NETWORK_TYPE_GSM:
315                 return AccessNetworkType.GERAN;
316             case TelephonyManager.NETWORK_TYPE_UMTS:
317             case TelephonyManager.NETWORK_TYPE_HSDPA:
318             case TelephonyManager.NETWORK_TYPE_HSPAP:
319             case TelephonyManager.NETWORK_TYPE_HSUPA:
320             case TelephonyManager.NETWORK_TYPE_HSPA:
321             case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
322                 return AccessNetworkType.UTRAN;
323             case TelephonyManager.NETWORK_TYPE_CDMA:
324             case TelephonyManager.NETWORK_TYPE_EVDO_0:
325             case TelephonyManager.NETWORK_TYPE_EVDO_A:
326             case TelephonyManager.NETWORK_TYPE_EVDO_B:
327             case TelephonyManager.NETWORK_TYPE_1xRTT:
328             case TelephonyManager.NETWORK_TYPE_EHRPD:
329                 return AccessNetworkType.CDMA2000;
330             case TelephonyManager.NETWORK_TYPE_LTE:
331             case TelephonyManager.NETWORK_TYPE_LTE_CA:
332                 return AccessNetworkType.EUTRAN;
333             case TelephonyManager.NETWORK_TYPE_IWLAN:
334                 return AccessNetworkType.IWLAN;
335             case TelephonyManager.NETWORK_TYPE_NR:
336                 return AccessNetworkType.NGRAN;
337             default:
338                 return AccessNetworkType.UNKNOWN;
339         }
340     }
341 
342     /**
343      * Convert the elapsed time to the current time with readable time format.
344      *
345      * @param elapsedTime The elapsed time retrieved from {@link SystemClock#elapsedRealtime()}.
346      * @return The string format time.
347      */
elapsedTimeToString(@lapsedRealtimeLong long elapsedTime)348     public static @NonNull String elapsedTimeToString(@ElapsedRealtimeLong long elapsedTime) {
349         return (elapsedTime != 0) ? systemTimeToString(System.currentTimeMillis()
350                 - SystemClock.elapsedRealtime() + elapsedTime) : "never";
351     }
352 
353     /**
354      * Convert the system time to the human readable format.
355      *
356      * @param systemTime The system time retrieved from {@link System#currentTimeMillis()}.
357      * @return The string format time.
358      */
systemTimeToString(@urrentTimeMillisLong long systemTime)359     public static @NonNull String systemTimeToString(@CurrentTimeMillisLong long systemTime) {
360         return (systemTime != 0) ? TIME_FORMAT.format(systemTime) : "never";
361     }
362 
363     /**
364      * Convert the IMS feature to string.
365      *
366      * @param imsFeature IMS feature.
367      * @return IMS feature in string format.
368      */
imsFeatureToString(@msFeature.FeatureType int imsFeature)369     public static @NonNull String imsFeatureToString(@ImsFeature.FeatureType int imsFeature) {
370         switch (imsFeature) {
371             case ImsFeature.FEATURE_MMTEL: return "MMTEL";
372             case ImsFeature.FEATURE_RCS: return "RCS";
373             default:
374                 loge("Unknown IMS feature(" + imsFeature + ")");
375                 return "Unknown(" + imsFeature + ")";
376         }
377     }
378 
379     /**
380      * Get the highest priority supported network capability from the specified data profile.
381      *
382      * @param dataConfigManager The data config that contains network priority information.
383      * @param dataProfile The data profile
384      * @return The highest priority network capability. -1 if cannot find one.
385      */
getHighestPriorityNetworkCapabilityFromDataProfile( @onNull DataConfigManager dataConfigManager, @NonNull DataProfile dataProfile)386     public static @NetCapability int getHighestPriorityNetworkCapabilityFromDataProfile(
387             @NonNull DataConfigManager dataConfigManager, @NonNull DataProfile dataProfile) {
388         if (dataProfile.getApnSetting() == null
389                 || dataProfile.getApnSetting().getApnTypes().isEmpty()) return -1;
390         return dataProfile.getApnSetting().getApnTypes().stream()
391                 .map(DataUtils::apnTypeToNetworkCapability)
392                 .sorted(Comparator.comparing(dataConfigManager::getNetworkCapabilityPriority)
393                         .reversed())
394                 .collect(Collectors.toList())
395                 .get(0);
396     }
397 
398     /**
399      * Group the network requests into several list that contains the same network capabilities.
400      *
401      * @param networkRequestList The provided network requests.
402      * @return The network requests after grouping.
403      */
getGroupedNetworkRequestList( @onNull NetworkRequestList networkRequestList)404     public static @NonNull List<NetworkRequestList> getGroupedNetworkRequestList(
405             @NonNull NetworkRequestList networkRequestList) {
406         // Key is the capabilities set.
407         Map<Set<Integer>, NetworkRequestList> requestsMap = new ArrayMap<>();
408         for (TelephonyNetworkRequest networkRequest : networkRequestList) {
409             requestsMap.computeIfAbsent(Arrays.stream(networkRequest.getCapabilities())
410                             .boxed().collect(Collectors.toSet()),
411                     v -> new NetworkRequestList()).add(networkRequest);
412         }
413         List<NetworkRequestList> requests = new ArrayList<>();
414         // Create separate groups for enterprise requests with different enterprise IDs.
415         for (NetworkRequestList requestList : requestsMap.values()) {
416             List<TelephonyNetworkRequest> enterpriseRequests = requestList.stream()
417                     .filter(request ->
418                             request.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE))
419                     .collect(Collectors.toList());
420             if (enterpriseRequests.isEmpty()) {
421                 requests.add(requestList);
422                 continue;
423             }
424             // Key is the enterprise ID
425             Map<Integer, NetworkRequestList> enterpriseRequestsMap = new ArrayMap<>();
426             for (TelephonyNetworkRequest request : enterpriseRequests) {
427                 enterpriseRequestsMap.computeIfAbsent(request.getCapabilityDifferentiator(),
428                         v -> new NetworkRequestList()).add(request);
429             }
430             requests.addAll(enterpriseRequestsMap.values());
431         }
432         // Sort the requests so the network request list with higher priority will be at the front.
433         return requests.stream()
434                 .sorted((list1, list2) -> Integer.compare(
435                         list2.get(0).getPriority(), list1.get(0).getPriority()))
436                 .collect(Collectors.toList());
437     }
438 
439     /**
440      * Get the target transport from source transport. This is only used for handover between
441      * IWLAN and cellular scenario.
442      *
443      * @param sourceTransport The source transport.
444      * @return The target transport.
445      */
getTargetTransport(@ransportType int sourceTransport)446     public static @TransportType int getTargetTransport(@TransportType int sourceTransport) {
447         return sourceTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
448                 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
449                 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
450     }
451 
452     /**
453      * Get the source transport from target transport. This is only used for handover between
454      * IWLAN and cellular scenario.
455      *
456      * @param targetTransport The target transport.
457      * @return The source transport.
458      */
getSourceTransport(@ransportType int targetTransport)459     public static @TransportType int getSourceTransport(@TransportType int targetTransport) {
460         return targetTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
461                 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
462                 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
463     }
464 
465     /**
466      * Convert link status to string.
467      *
468      * @param linkStatus The link status.
469      * @return The link status in string format.
470      */
linkStatusToString(@inkStatus int linkStatus)471     public static @NonNull String linkStatusToString(@LinkStatus int linkStatus) {
472         switch (linkStatus) {
473             case DataCallResponse.LINK_STATUS_UNKNOWN: return "UNKNOWN";
474             case DataCallResponse.LINK_STATUS_INACTIVE: return "INACTIVE";
475             case DataCallResponse.LINK_STATUS_ACTIVE: return "ACTIVE";
476             case DataCallResponse.LINK_STATUS_DORMANT: return "DORMANT";
477             default:
478                 loge("Unknown link status(" + linkStatus + ")");
479                 return "UNKNOWN(" + linkStatus + ")";
480         }
481     }
482 
483     /**
484      * Check if access network type is valid.
485      *
486      * @param accessNetworkType The access network type to check.
487      * @return {@code true} if the access network type is valid.
488      */
isValidAccessNetwork(@adioAccessNetworkType int accessNetworkType)489     public static boolean isValidAccessNetwork(@RadioAccessNetworkType int accessNetworkType) {
490         switch (accessNetworkType) {
491             case AccessNetworkType.GERAN:
492             case AccessNetworkType.UTRAN:
493             case AccessNetworkType.EUTRAN:
494             case AccessNetworkType.CDMA2000:
495             case AccessNetworkType.IWLAN:
496             case AccessNetworkType.NGRAN:
497                 return true;
498             default:
499                 return false;
500         }
501     }
502 
503     /**
504      * Convert data activity to string.
505      *
506      * @param dataActivity The data activity.
507      * @return The data activity in string format.
508      */
dataActivityToString(@ataActivityType int dataActivity)509     public static @NonNull String dataActivityToString(@DataActivityType int dataActivity) {
510         switch (dataActivity) {
511             case TelephonyManager.DATA_ACTIVITY_NONE: return "NONE";
512             case TelephonyManager.DATA_ACTIVITY_IN: return "IN";
513             case TelephonyManager.DATA_ACTIVITY_OUT: return "OUT";
514             case TelephonyManager.DATA_ACTIVITY_INOUT: return "INOUT";
515             case TelephonyManager.DATA_ACTIVITY_DORMANT: return "DORMANT";
516             default:
517                 loge("Unknown data activity(" + dataActivity + ")");
518                 return "UNKNOWN(" + dataActivity + ")";
519         }
520     }
521 
loge(String msg)522     private static void loge(String msg) {
523         Rlog.e(TAG, msg);
524     }
525 }
526