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.net.module.util; 18 19 import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; 20 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 21 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 22 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; 23 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; 24 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; 25 import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; 26 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; 27 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 28 import static android.net.NetworkCapabilities.NET_CAPABILITY_MCX; 29 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; 30 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMTEL; 31 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; 32 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; 33 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 34 import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; 35 import static android.net.NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL; 36 import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM; 37 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; 38 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; 39 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; 40 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 41 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 42 import static android.net.NetworkCapabilities.TRANSPORT_SATELLITE; 43 import static android.net.NetworkCapabilities.TRANSPORT_USB; 44 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 45 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 46 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; 47 48 import static com.android.net.module.util.BitUtils.packBits; 49 import static com.android.net.module.util.BitUtils.unpackBits; 50 51 import android.annotation.NonNull; 52 import android.net.NetworkCapabilities; 53 54 import com.android.internal.annotations.VisibleForTesting; 55 56 /** 57 * Utilities to examine {@link android.net.NetworkCapabilities}. 58 * @hide 59 */ 60 public final class NetworkCapabilitiesUtils { 61 // Transports considered to classify networks in UI, in order of which transport should be 62 // surfaced when there are multiple transports. Transports not in this list do not have 63 // an ordering preference (in practice they will have a deterministic order based on the 64 // transport int itself). 65 private static final int[] DISPLAY_TRANSPORT_PRIORITIES = new int[] { 66 // Users think of their VPNs as VPNs, not as any of the underlying nets 67 TRANSPORT_VPN, 68 // If the network has cell, prefer showing that because it's usually metered. 69 TRANSPORT_CELLULAR, 70 // If the network has WiFi aware, prefer showing that as it's a more specific use case. 71 // Ethernet can masquerade as other transports, where the device uses ethernet to connect to 72 // a box providing cell or wifi. Today this is represented by only the masqueraded type for 73 // backward compatibility, but these networks should morally have Ethernet & the masqueraded 74 // type. Because of this, prefer other transports instead of Ethernet. 75 TRANSPORT_WIFI_AWARE, 76 TRANSPORT_BLUETOOTH, 77 TRANSPORT_WIFI, 78 TRANSPORT_ETHERNET, 79 TRANSPORT_USB, 80 TRANSPORT_SATELLITE 81 // Notably, TRANSPORT_TEST is not in this list as any network that has TRANSPORT_TEST and 82 // one of the above transports should be counted as that transport, to keep tests as 83 // realistic as possible. 84 }; 85 86 /** 87 * Capabilities that suggest that a network is restricted. 88 * See {@code NetworkCapabilities#maybeMarkCapabilitiesRestricted}, 89 * and {@code FORCE_RESTRICTED_CAPABILITIES}. 90 */ 91 @VisibleForTesting 92 public static final long RESTRICTED_CAPABILITIES = 93 (1L << NET_CAPABILITY_BIP) | 94 (1L << NET_CAPABILITY_CBS) | 95 (1L << NET_CAPABILITY_DUN) | 96 (1L << NET_CAPABILITY_EIMS) | 97 (1L << NET_CAPABILITY_ENTERPRISE) | 98 (1L << NET_CAPABILITY_FOTA) | 99 (1L << NET_CAPABILITY_IA) | 100 (1L << NET_CAPABILITY_IMS) | 101 (1L << NET_CAPABILITY_MCX) | 102 (1L << NET_CAPABILITY_RCS) | 103 (1L << NET_CAPABILITY_VEHICLE_INTERNAL) | 104 (1L << NET_CAPABILITY_VSIM) | 105 (1L << NET_CAPABILITY_XCAP) | 106 (1L << NET_CAPABILITY_MMTEL); 107 108 /** 109 * Capabilities that force network to be restricted. 110 * See {@code NetworkCapabilities#maybeMarkCapabilitiesRestricted}. 111 */ 112 private static final long FORCE_RESTRICTED_CAPABILITIES = 113 (1L << NET_CAPABILITY_ENTERPRISE) | 114 (1L << NET_CAPABILITY_OEM_PAID) | 115 (1L << NET_CAPABILITY_OEM_PRIVATE); 116 117 /** 118 * Capabilities that suggest that a network is unrestricted. 119 * See {@code NetworkCapabilities#maybeMarkCapabilitiesRestricted}. 120 */ 121 @VisibleForTesting 122 public static final long UNRESTRICTED_CAPABILITIES = 123 (1L << NET_CAPABILITY_INTERNET) | 124 (1L << NET_CAPABILITY_MMS) | 125 (1L << NET_CAPABILITY_SUPL) | 126 (1L << NET_CAPABILITY_WIFI_P2P); 127 128 /** 129 * Get a transport that can be used to classify a network when displaying its info to users. 130 * 131 * While networks can have multiple transports, users generally think of them as "wifi", 132 * "mobile data", "vpn" and expect them to be classified as such in UI such as settings. 133 * @param transports Non-empty array of transports on a network 134 * @return A single transport 135 * @throws IllegalArgumentException The array is empty 136 */ getDisplayTransport(@onNull int[] transports)137 public static int getDisplayTransport(@NonNull int[] transports) { 138 for (int transport : DISPLAY_TRANSPORT_PRIORITIES) { 139 if (CollectionUtils.contains(transports, transport)) { 140 return transport; 141 } 142 } 143 144 if (transports.length < 1) { 145 // All NetworkCapabilities representing a network have at least one transport, so an 146 // empty transport array would be created by the caller instead of extracted from 147 // NetworkCapabilities. 148 throw new IllegalArgumentException("No transport in the provided array"); 149 } 150 return transports[0]; 151 } 152 153 154 /** 155 * Infers that all the capabilities it provides are typically provided by restricted networks 156 * or not. 157 * 158 * @param nc the {@link NetworkCapabilities} to infer the restricted capabilities. 159 * 160 * @return {@code true} if the network should be restricted. 161 */ inferRestrictedCapability(NetworkCapabilities nc)162 public static boolean inferRestrictedCapability(NetworkCapabilities nc) { 163 return inferRestrictedCapability(packBits(nc.getCapabilities())); 164 } 165 166 /** 167 * Infers that all the capabilities it provides are typically provided by restricted networks 168 * or not. 169 * 170 * @param capabilities see {@link NetworkCapabilities#getCapabilities()} 171 * 172 * @return {@code true} if the network should be restricted. 173 */ inferRestrictedCapability(long capabilities)174 public static boolean inferRestrictedCapability(long capabilities) { 175 // Check if we have any capability that forces the network to be restricted. 176 if ((capabilities & FORCE_RESTRICTED_CAPABILITIES) != 0) { 177 return true; 178 } 179 180 // Verify there aren't any unrestricted capabilities. If there are we say 181 // the whole thing is unrestricted unless it is forced to be restricted. 182 if ((capabilities & UNRESTRICTED_CAPABILITIES) != 0) { 183 return false; 184 } 185 186 // Must have at least some restricted capabilities. 187 if ((capabilities & RESTRICTED_CAPABILITIES) != 0) { 188 return true; 189 } 190 return false; 191 } 192 193 } 194