1 /* 2 * Copyright (C) 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 package android.net.vcn; 17 18 import static com.android.internal.annotations.VisibleForTesting.Visibility; 19 import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER; 20 import static com.android.server.vcn.util.PersistableBundleUtils.STRING_SERIALIZER; 21 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.SuppressLint; 25 import android.net.NetworkCapabilities; 26 import android.os.PersistableBundle; 27 import android.util.ArraySet; 28 29 import com.android.internal.annotations.VisibleForTesting; 30 import com.android.internal.util.IndentingPrintWriter; 31 import com.android.server.vcn.util.PersistableBundleUtils; 32 33 import java.util.ArrayList; 34 import java.util.Collections; 35 import java.util.Objects; 36 import java.util.Set; 37 38 /** 39 * This class represents a configuration for a network template class of underlying Carrier WiFi 40 * networks. 41 * 42 * <p>See {@link VcnUnderlyingNetworkTemplate} 43 */ 44 public final class VcnWifiUnderlyingNetworkTemplate extends VcnUnderlyingNetworkTemplate { 45 private static final String SSIDS_KEY = "mSsids"; 46 @Nullable private final Set<String> mSsids; 47 VcnWifiUnderlyingNetworkTemplate( int meteredMatchCriteria, int minEntryUpstreamBandwidthKbps, int minExitUpstreamBandwidthKbps, int minEntryDownstreamBandwidthKbps, int minExitDownstreamBandwidthKbps, Set<String> ssids)48 private VcnWifiUnderlyingNetworkTemplate( 49 int meteredMatchCriteria, 50 int minEntryUpstreamBandwidthKbps, 51 int minExitUpstreamBandwidthKbps, 52 int minEntryDownstreamBandwidthKbps, 53 int minExitDownstreamBandwidthKbps, 54 Set<String> ssids) { 55 super( 56 NETWORK_PRIORITY_TYPE_WIFI, 57 meteredMatchCriteria, 58 minEntryUpstreamBandwidthKbps, 59 minExitUpstreamBandwidthKbps, 60 minEntryDownstreamBandwidthKbps, 61 minExitDownstreamBandwidthKbps); 62 mSsids = new ArraySet<>(ssids); 63 64 validate(); 65 } 66 67 /** @hide */ 68 @Override validate()69 protected void validate() { 70 super.validate(); 71 validateSsids(mSsids); 72 } 73 validateSsids(Set<String> ssids)74 private static void validateSsids(Set<String> ssids) { 75 Objects.requireNonNull(ssids, "ssids is null"); 76 77 for (String ssid : ssids) { 78 Objects.requireNonNull(ssid, "found null value ssid"); 79 } 80 } 81 82 /** @hide */ 83 @NonNull 84 @VisibleForTesting(visibility = Visibility.PROTECTED) fromPersistableBundle( @onNull PersistableBundle in)85 public static VcnWifiUnderlyingNetworkTemplate fromPersistableBundle( 86 @NonNull PersistableBundle in) { 87 Objects.requireNonNull(in, "PersistableBundle is null"); 88 89 final int meteredMatchCriteria = in.getInt(METERED_MATCH_KEY); 90 91 final int minEntryUpstreamBandwidthKbps = 92 in.getInt(MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); 93 final int minExitUpstreamBandwidthKbps = 94 in.getInt(MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); 95 final int minEntryDownstreamBandwidthKbps = 96 in.getInt(MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); 97 final int minExitDownstreamBandwidthKbps = 98 in.getInt(MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); 99 100 final PersistableBundle ssidsBundle = in.getPersistableBundle(SSIDS_KEY); 101 Objects.requireNonNull(ssidsBundle, "ssidsBundle is null"); 102 final Set<String> ssids = 103 new ArraySet<String>( 104 PersistableBundleUtils.toList(ssidsBundle, STRING_DESERIALIZER)); 105 return new VcnWifiUnderlyingNetworkTemplate( 106 meteredMatchCriteria, 107 minEntryUpstreamBandwidthKbps, 108 minExitUpstreamBandwidthKbps, 109 minEntryDownstreamBandwidthKbps, 110 minExitDownstreamBandwidthKbps, 111 ssids); 112 } 113 114 /** @hide */ 115 @Override 116 @NonNull 117 @VisibleForTesting(visibility = Visibility.PROTECTED) toPersistableBundle()118 public PersistableBundle toPersistableBundle() { 119 final PersistableBundle result = super.toPersistableBundle(); 120 121 final PersistableBundle ssidsBundle = 122 PersistableBundleUtils.fromList(new ArrayList<>(mSsids), STRING_SERIALIZER); 123 result.putPersistableBundle(SSIDS_KEY, ssidsBundle); 124 125 return result; 126 } 127 128 @Override hashCode()129 public int hashCode() { 130 return Objects.hash(super.hashCode(), mSsids); 131 } 132 133 @Override equals(@ullable Object other)134 public boolean equals(@Nullable Object other) { 135 if (!super.equals(other)) { 136 return false; 137 } 138 139 if (!(other instanceof VcnWifiUnderlyingNetworkTemplate)) { 140 return false; 141 } 142 143 final VcnWifiUnderlyingNetworkTemplate rhs = (VcnWifiUnderlyingNetworkTemplate) other; 144 return mSsids.equals(rhs.mSsids); 145 } 146 147 /** @hide */ 148 @Override dumpTransportSpecificFields(IndentingPrintWriter pw)149 void dumpTransportSpecificFields(IndentingPrintWriter pw) { 150 if (!mSsids.isEmpty()) { 151 pw.println("mSsids: " + mSsids); 152 } 153 } 154 155 /** 156 * Retrieve the matching SSIDs, or an empty set if any SSID is acceptable. 157 * 158 * @see Builder#setSsids(Set) 159 */ 160 @NonNull getSsids()161 public Set<String> getSsids() { 162 return Collections.unmodifiableSet(mSsids); 163 } 164 165 /** This class is used to incrementally build VcnWifiUnderlyingNetworkTemplate objects. */ 166 public static final class Builder { 167 private int mMeteredMatchCriteria = MATCH_ANY; 168 @NonNull private final Set<String> mSsids = new ArraySet<>(); 169 170 private int mMinEntryUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; 171 private int mMinExitUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; 172 private int mMinEntryDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; 173 private int mMinExitDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; 174 175 /** Construct a Builder object. */ Builder()176 public Builder() {} 177 178 /** 179 * Set the matching criteria for metered networks. 180 * 181 * <p>A template where setMetered(MATCH_REQUIRED) will only match metered networks (one 182 * without NET_CAPABILITY_NOT_METERED). A template where setMetered(MATCH_FORBIDDEN) will 183 * only match a network that is not metered (one with NET_CAPABILITY_NOT_METERED). 184 * 185 * @param matchCriteria the matching criteria for metered networks. Defaults to {@link 186 * #MATCH_ANY}. 187 * @see NetworkCapabilities#NET_CAPABILITY_NOT_METERED 188 */ 189 // The matching getter is defined in the super class. Please see {@link 190 // VcnUnderlyingNetworkTemplate#getMetered()} 191 @SuppressLint("MissingGetterMatchingBuilder") 192 @NonNull setMetered(@atchCriteria int matchCriteria)193 public Builder setMetered(@MatchCriteria int matchCriteria) { 194 validateMatchCriteria(matchCriteria, "setMetered"); 195 196 mMeteredMatchCriteria = matchCriteria; 197 return this; 198 } 199 200 /** 201 * Set the SSIDs with which a network can match this priority rule. 202 * 203 * @param ssids the matching SSIDs. Network with one of the matching SSIDs can match this 204 * priority rule. If the set is empty, any SSID will match. The default is an empty set. 205 */ 206 @NonNull setSsids(@onNull Set<String> ssids)207 public Builder setSsids(@NonNull Set<String> ssids) { 208 validateSsids(ssids); 209 210 mSsids.clear(); 211 mSsids.addAll(ssids); 212 return this; 213 } 214 215 /** 216 * Set the minimum upstream bandwidths that this template will match. 217 * 218 * <p>This template will not match a network that does not provide at least the bandwidth 219 * passed as the entry bandwidth, except in the case that the network is selected as the VCN 220 * Gateway Connection's underlying network, where it will continue to match until the 221 * bandwidth drops under the exit bandwidth. 222 * 223 * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the 224 * invalid case where a network fulfills the entry criteria, but at the same time fails the 225 * exit criteria. 226 * 227 * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in 228 * {@link NetworkCapabilities}. The provided estimates will be used without modification. 229 * 230 * @param minEntryUpstreamBandwidthKbps the minimum accepted upstream bandwidth for networks 231 * that ARE NOT the already-selected underlying network, or {@code 0} to disable this 232 * requirement. Disabled by default. 233 * @param minExitUpstreamBandwidthKbps the minimum accepted upstream bandwidth for a network 234 * that IS the already-selected underlying network, or {@code 0} to disable this 235 * requirement. Disabled by default. 236 * @return this {@link Builder} instance, for chaining 237 */ 238 @NonNull 239 // The getter for the two integers are separated, and in the superclass. Please see {@link 240 // VcnUnderlyingNetworkTemplate#getMinEntryUpstreamBandwidthKbps()} and {@link 241 // VcnUnderlyingNetworkTemplate#getMinExitUpstreamBandwidthKbps()} 242 @SuppressLint("MissingGetterMatchingBuilder") setMinUpstreamBandwidthKbps( int minEntryUpstreamBandwidthKbps, int minExitUpstreamBandwidthKbps)243 public Builder setMinUpstreamBandwidthKbps( 244 int minEntryUpstreamBandwidthKbps, int minExitUpstreamBandwidthKbps) { 245 validateMinBandwidthKbps(minEntryUpstreamBandwidthKbps, minExitUpstreamBandwidthKbps); 246 247 mMinEntryUpstreamBandwidthKbps = minEntryUpstreamBandwidthKbps; 248 mMinExitUpstreamBandwidthKbps = minExitUpstreamBandwidthKbps; 249 250 return this; 251 } 252 253 /** 254 * Set the minimum upstream bandwidths that this template will match. 255 * 256 * <p>This template will not match a network that does not provide at least the bandwidth 257 * passed as the entry bandwidth, except in the case that the network is selected as the VCN 258 * Gateway Connection's underlying network, where it will continue to match until the 259 * bandwidth drops under the exit bandwidth. 260 * 261 * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the 262 * invalid case where a network fulfills the entry criteria, but at the same time fails the 263 * exit criteria. 264 * 265 * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in 266 * {@link NetworkCapabilities}. The provided estimates will be used without modification. 267 * 268 * @param minEntryDownstreamBandwidthKbps the minimum accepted downstream bandwidth for 269 * networks that ARE NOT the already-selected underlying network, or {@code 0} to 270 * disable this requirement. Disabled by default. 271 * @param minExitDownstreamBandwidthKbps the minimum accepted downstream bandwidth for a 272 * network that IS the already-selected underlying network, or {@code 0} to disable this 273 * requirement. Disabled by default. 274 * @return this {@link Builder} instance, for chaining 275 */ 276 @NonNull 277 // The getter for the two integers are separated, and in the superclass. Please see {@link 278 // VcnUnderlyingNetworkTemplate#getMinEntryDownstreamBandwidthKbps()} and {@link 279 // VcnUnderlyingNetworkTemplate#getMinExitDownstreamBandwidthKbps()} 280 @SuppressLint("MissingGetterMatchingBuilder") setMinDownstreamBandwidthKbps( int minEntryDownstreamBandwidthKbps, int minExitDownstreamBandwidthKbps)281 public Builder setMinDownstreamBandwidthKbps( 282 int minEntryDownstreamBandwidthKbps, int minExitDownstreamBandwidthKbps) { 283 validateMinBandwidthKbps( 284 minEntryDownstreamBandwidthKbps, minExitDownstreamBandwidthKbps); 285 286 mMinEntryDownstreamBandwidthKbps = minEntryDownstreamBandwidthKbps; 287 mMinExitDownstreamBandwidthKbps = minExitDownstreamBandwidthKbps; 288 289 return this; 290 } 291 292 /** Build the VcnWifiUnderlyingNetworkTemplate. */ 293 @NonNull build()294 public VcnWifiUnderlyingNetworkTemplate build() { 295 return new VcnWifiUnderlyingNetworkTemplate( 296 mMeteredMatchCriteria, 297 mMinEntryUpstreamBandwidthKbps, 298 mMinExitUpstreamBandwidthKbps, 299 mMinEntryDownstreamBandwidthKbps, 300 mMinExitDownstreamBandwidthKbps, 301 mSsids); 302 } 303 } 304 } 305