1 /* 2 * Copyright (C) 2023 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 android.net.wifi.sharedconnectivity.app; 18 19 import static android.net.wifi.WifiAnnotations.SecurityType; 20 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.SystemApi; 25 import android.net.wifi.sharedconnectivity.service.SharedConnectivityService; 26 import android.os.Bundle; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 import android.util.ArraySet; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 import java.util.Objects; 34 import java.util.Set; 35 36 /** 37 * A data class representing a hotspot network. 38 * This class is used in IPC calls between the implementer of {@link SharedConnectivityService} and 39 * the consumers of {@link com.android.wifitrackerlib}. 40 * 41 * @hide 42 */ 43 @SystemApi 44 public final class HotspotNetwork implements Parcelable { 45 /** 46 * Remote device is connected to the internet via an unknown connection. 47 */ 48 public static final int NETWORK_TYPE_UNKNOWN = 0; 49 50 /** 51 * Remote device is connected to the internet via a cellular connection. 52 */ 53 public static final int NETWORK_TYPE_CELLULAR = 1; 54 55 /** 56 * Remote device is connected to the internet via a Wi-Fi connection. 57 */ 58 public static final int NETWORK_TYPE_WIFI = 2; 59 60 /** 61 * Remote device is connected to the internet via an ethernet connection. 62 */ 63 public static final int NETWORK_TYPE_ETHERNET = 3; 64 65 /** 66 * @hide 67 */ 68 @Retention(RetentionPolicy.SOURCE) 69 @IntDef({ 70 NETWORK_TYPE_UNKNOWN, 71 NETWORK_TYPE_CELLULAR, 72 NETWORK_TYPE_WIFI, 73 NETWORK_TYPE_ETHERNET 74 }) 75 public @interface NetworkType { 76 } 77 78 private final long mDeviceId; 79 private final NetworkProviderInfo mNetworkProviderInfo; 80 @NetworkType 81 private final int mNetworkType; 82 private final String mNetworkName; 83 @Nullable 84 private final String mHotspotSsid; 85 @Nullable 86 private final String mHotspotBssid; 87 @Nullable 88 @SecurityType 89 private final ArraySet<Integer> mHotspotSecurityTypes; 90 private final Bundle mExtras; 91 92 /** 93 * Builder class for {@link HotspotNetwork}. 94 */ 95 public static final class Builder { 96 private long mDeviceId = -1; 97 private NetworkProviderInfo mNetworkProviderInfo; 98 @NetworkType 99 private int mNetworkType; 100 private String mNetworkName; 101 @Nullable 102 private String mHotspotSsid; 103 @Nullable 104 private String mHotspotBssid; 105 @Nullable 106 @SecurityType 107 private final ArraySet<Integer> mHotspotSecurityTypes = new ArraySet<>(); 108 private Bundle mExtras = Bundle.EMPTY; 109 110 /** 111 * Set the remote device ID. 112 * 113 * @param deviceId Locally unique ID for this Hotspot network. 114 * @return Returns the Builder object. 115 */ 116 @NonNull setDeviceId(long deviceId)117 public Builder setDeviceId(long deviceId) { 118 mDeviceId = deviceId; 119 return this; 120 } 121 122 /** 123 * Sets information about the device providing connectivity. 124 * 125 * @param networkProviderInfo The device information object. 126 * @return Returns the Builder object. 127 */ 128 @NonNull setNetworkProviderInfo(@onNull NetworkProviderInfo networkProviderInfo)129 public Builder setNetworkProviderInfo(@NonNull NetworkProviderInfo networkProviderInfo) { 130 mNetworkProviderInfo = networkProviderInfo; 131 return this; 132 } 133 134 /** 135 * Sets the network type that the remote device is connected to. 136 * 137 * @param networkType Network type as represented by IntDef {@link NetworkType}. 138 * @return Returns the Builder object. 139 */ 140 @NonNull setHostNetworkType(@etworkType int networkType)141 public Builder setHostNetworkType(@NetworkType int networkType) { 142 mNetworkType = networkType; 143 return this; 144 } 145 146 /** 147 * Sets the display name of the network the remote device is connected to. 148 * 149 * @param networkName Network display name. (e.g. "Google Fi", "Hotel WiFi", "Ethernet") 150 * @return Returns the Builder object. 151 */ 152 @NonNull setNetworkName(@onNull String networkName)153 public Builder setNetworkName(@NonNull String networkName) { 154 mNetworkName = networkName; 155 return this; 156 } 157 158 /** 159 * Sets the hotspot SSID being broadcast by the remote device, or null if hotspot is off. 160 * 161 * @param hotspotSsid The SSID of the hotspot. Surrounded by double quotes if UTF-8. 162 * @return Returns the Builder object. 163 */ 164 @NonNull setHotspotSsid(@onNull String hotspotSsid)165 public Builder setHotspotSsid(@NonNull String hotspotSsid) { 166 mHotspotSsid = hotspotSsid; 167 return this; 168 } 169 170 /** 171 * Sets the hotspot BSSID being broadcast by the remote device, or null if hotspot is off. 172 * 173 * @param hotspotBssid The BSSID of the hotspot. 174 * @return Returns the Builder object. 175 */ 176 @NonNull setHotspotBssid(@onNull String hotspotBssid)177 public Builder setHotspotBssid(@NonNull String hotspotBssid) { 178 mHotspotBssid = hotspotBssid; 179 return this; 180 } 181 182 /** 183 * Adds a security type supported by the hotspot created by the remote device. 184 * 185 * @param hotspotSecurityType A security type supported by the hotspot. 186 * @return Returns the Builder object. 187 */ 188 @NonNull addHotspotSecurityType(@ecurityType int hotspotSecurityType)189 public Builder addHotspotSecurityType(@SecurityType int hotspotSecurityType) { 190 mHotspotSecurityTypes.add(hotspotSecurityType); 191 return this; 192 } 193 194 /** 195 * Sets the extras bundle 196 * 197 * @return Returns the Builder object. 198 */ 199 @NonNull setExtras(@onNull Bundle extras)200 public Builder setExtras(@NonNull Bundle extras) { 201 mExtras = extras; 202 return this; 203 } 204 205 /** 206 * Builds the {@link HotspotNetwork} object. 207 * 208 * @return Returns the built {@link HotspotNetwork} object. 209 */ 210 @NonNull build()211 public HotspotNetwork build() { 212 return new HotspotNetwork( 213 mDeviceId, 214 mNetworkProviderInfo, 215 mNetworkType, 216 mNetworkName, 217 mHotspotSsid, 218 mHotspotBssid, 219 mHotspotSecurityTypes, 220 mExtras); 221 } 222 } 223 validate(long deviceId, @NetworkType int networkType, String networkName, NetworkProviderInfo networkProviderInfo)224 private static void validate(long deviceId, @NetworkType int networkType, String networkName, 225 NetworkProviderInfo networkProviderInfo) { 226 if (deviceId < 0) { 227 throw new IllegalArgumentException("DeviceId must be set"); 228 } 229 if (Objects.isNull(networkProviderInfo)) { 230 throw new IllegalArgumentException("NetworkProviderInfo must be set"); 231 } 232 if (networkType != NETWORK_TYPE_CELLULAR && networkType != NETWORK_TYPE_WIFI 233 && networkType != NETWORK_TYPE_ETHERNET && networkType != NETWORK_TYPE_UNKNOWN) { 234 throw new IllegalArgumentException("Illegal network type"); 235 } 236 if (Objects.isNull(networkName)) { 237 throw new IllegalArgumentException("NetworkName must be set"); 238 } 239 } 240 HotspotNetwork( long deviceId, NetworkProviderInfo networkProviderInfo, @NetworkType int networkType, @NonNull String networkName, @Nullable String hotspotSsid, @Nullable String hotspotBssid, @Nullable @SecurityType ArraySet<Integer> hotspotSecurityTypes, @NonNull Bundle extras)241 private HotspotNetwork( 242 long deviceId, 243 NetworkProviderInfo networkProviderInfo, 244 @NetworkType int networkType, 245 @NonNull String networkName, 246 @Nullable String hotspotSsid, 247 @Nullable String hotspotBssid, 248 @Nullable @SecurityType ArraySet<Integer> hotspotSecurityTypes, 249 @NonNull Bundle extras) { 250 validate(deviceId, 251 networkType, 252 networkName, 253 networkProviderInfo); 254 mDeviceId = deviceId; 255 mNetworkProviderInfo = networkProviderInfo; 256 mNetworkType = networkType; 257 mNetworkName = networkName; 258 mHotspotSsid = hotspotSsid; 259 mHotspotBssid = hotspotBssid; 260 mHotspotSecurityTypes = new ArraySet<>(hotspotSecurityTypes); 261 mExtras = extras; 262 } 263 264 /** 265 * Gets the remote device ID. 266 * 267 * @return Returns the locally unique ID for this Hotspot network. 268 */ getDeviceId()269 public long getDeviceId() { 270 return mDeviceId; 271 } 272 273 /** 274 * Gets information about the device providing connectivity. 275 * 276 * @return Returns the information of the device providing the Hotspot network. 277 */ 278 @NonNull getNetworkProviderInfo()279 public NetworkProviderInfo getNetworkProviderInfo() { 280 return mNetworkProviderInfo; 281 } 282 283 /** 284 * Gets the network type that the remote device is connected to. 285 * 286 * @return Returns the network type as represented by IntDef {@link NetworkType}. 287 */ 288 @NetworkType getHostNetworkType()289 public int getHostNetworkType() { 290 return mNetworkType; 291 } 292 293 /** 294 * Gets the display name of the network the remote device is connected to. 295 * 296 * @return Returns the network display name. (e.g. "Google Fi", "Hotel WiFi", "Ethernet") 297 */ 298 @NonNull getNetworkName()299 public String getNetworkName() { 300 return mNetworkName; 301 } 302 303 /** 304 * Gets the hotspot SSID being broadcast by the remote device, or null if hotspot is off. 305 * 306 * @return Returns the SSID of the hotspot. Surrounded by double quotes if UTF-8. 307 */ 308 @Nullable getHotspotSsid()309 public String getHotspotSsid() { 310 return mHotspotSsid; 311 } 312 313 /** 314 * Gets the hotspot BSSID being broadcast by the remote device, or null if hotspot is off. 315 * 316 * @return Returns the BSSID of the hotspot. 317 */ 318 @Nullable getHotspotBssid()319 public String getHotspotBssid() { 320 return mHotspotBssid; 321 } 322 323 /** 324 * Gets the hotspot security types supported by the remote device. 325 * 326 * @return Returns a set of the security types supported by the hotspot. 327 */ 328 @NonNull 329 @SecurityType getHotspotSecurityTypes()330 public Set<Integer> getHotspotSecurityTypes() { 331 return mHotspotSecurityTypes; 332 } 333 334 /** 335 * Gets the extras Bundle. 336 * 337 * @return Returns a Bundle object. 338 */ 339 @NonNull getExtras()340 public Bundle getExtras() { 341 return mExtras; 342 } 343 344 @Override equals(Object obj)345 public boolean equals(Object obj) { 346 if (!(obj instanceof HotspotNetwork)) return false; 347 HotspotNetwork other = (HotspotNetwork) obj; 348 return mDeviceId == other.getDeviceId() 349 && Objects.equals(mNetworkProviderInfo, other.getNetworkProviderInfo()) 350 && mNetworkType == other.getHostNetworkType() 351 && Objects.equals(mNetworkName, other.getNetworkName()) 352 && Objects.equals(mHotspotSsid, other.getHotspotSsid()) 353 && Objects.equals(mHotspotBssid, other.getHotspotBssid()) 354 && Objects.equals(mHotspotSecurityTypes, other.getHotspotSecurityTypes()); 355 } 356 357 @Override hashCode()358 public int hashCode() { 359 return Objects.hash(mDeviceId, mNetworkProviderInfo, mNetworkName, mHotspotSsid, 360 mHotspotBssid, mHotspotSecurityTypes); 361 } 362 363 @Override describeContents()364 public int describeContents() { 365 return 0; 366 } 367 368 @Override writeToParcel(@onNull Parcel dest, int flags)369 public void writeToParcel(@NonNull Parcel dest, int flags) { 370 dest.writeLong(mDeviceId); 371 mNetworkProviderInfo.writeToParcel(dest, flags); 372 dest.writeInt(mNetworkType); 373 dest.writeString(mNetworkName); 374 dest.writeString(mHotspotSsid); 375 dest.writeString(mHotspotBssid); 376 dest.writeArraySet(mHotspotSecurityTypes); 377 dest.writeBundle(mExtras); 378 } 379 380 /** 381 * Creates a {@link HotspotNetwork} object from a parcel. 382 * 383 * @hide 384 */ 385 @NonNull readFromParcel(@onNull Parcel in)386 public static HotspotNetwork readFromParcel(@NonNull Parcel in) { 387 return new HotspotNetwork(in.readLong(), NetworkProviderInfo.readFromParcel(in), 388 in.readInt(), in.readString(), in.readString(), in.readString(), 389 (ArraySet<Integer>) in.readArraySet(null), in.readBundle()); 390 } 391 392 @NonNull 393 public static final Creator<HotspotNetwork> CREATOR = new Creator<>() { 394 @Override 395 public HotspotNetwork createFromParcel(Parcel in) { 396 return readFromParcel(in); 397 } 398 399 @Override 400 public HotspotNetwork[] newArray(int size) { 401 return new HotspotNetwork[size]; 402 } 403 }; 404 405 @Override toString()406 public String toString() { 407 return new StringBuilder("HotspotNetwork[") 408 .append("deviceId=").append(mDeviceId) 409 .append(", networkType=").append(mNetworkType) 410 .append(", networkProviderInfo=").append(mNetworkProviderInfo.toString()) 411 .append(", networkName=").append(mNetworkName) 412 .append(", hotspotSsid=").append(mHotspotSsid) 413 .append(", hotspotBssid=").append(mHotspotBssid) 414 .append(", hotspotSecurityTypes=").append(mHotspotSecurityTypes.toString()) 415 .append(", extras=").append(mExtras.toString()) 416 .append("]").toString(); 417 } 418 } 419