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 android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.IntRange; 22 import android.annotation.NonNull; 23 import android.annotation.SystemApi; 24 import android.net.wifi.flags.Flags; 25 import android.net.wifi.sharedconnectivity.service.SharedConnectivityService; 26 import android.os.Bundle; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 import java.util.Objects; 33 34 /** 35 * A data class representing a device providing connectivity. 36 * This class is used in IPC calls between the implementer of {@link SharedConnectivityService} and 37 * the consumers of {@link com.android.wifitrackerlib}. 38 * 39 * @hide 40 */ 41 @SystemApi 42 public final class NetworkProviderInfo implements Parcelable { 43 44 /** 45 * Device type providing connectivity is unknown. 46 */ 47 public static final int DEVICE_TYPE_UNKNOWN = 0; 48 49 /** 50 * Device providing connectivity is a mobile phone. 51 */ 52 public static final int DEVICE_TYPE_PHONE = 1; 53 54 /** 55 * Device providing connectivity is a tablet. 56 */ 57 public static final int DEVICE_TYPE_TABLET = 2; 58 59 /** 60 * Device providing connectivity is a laptop. 61 */ 62 public static final int DEVICE_TYPE_LAPTOP = 3; 63 64 /** 65 * Device providing connectivity is a watch. 66 */ 67 public static final int DEVICE_TYPE_WATCH = 4; 68 69 /** 70 * Device providing connectivity is a watch. 71 */ 72 public static final int DEVICE_TYPE_AUTO = 5; 73 74 /** 75 * @hide 76 */ 77 @Retention(RetentionPolicy.SOURCE) 78 @IntDef({ 79 DEVICE_TYPE_UNKNOWN, 80 DEVICE_TYPE_PHONE, 81 DEVICE_TYPE_TABLET, 82 DEVICE_TYPE_LAPTOP, 83 DEVICE_TYPE_WATCH, 84 DEVICE_TYPE_AUTO 85 }) 86 public @interface DeviceType { 87 } 88 89 @DeviceType 90 private final int mDeviceType; 91 private final String mDeviceName; 92 private final String mModelName; 93 private final int mBatteryPercentage; 94 private final boolean mIsBatteryCharging; 95 private final int mConnectionStrength; 96 private final Bundle mExtras; 97 98 /** 99 * Builder class for {@link NetworkProviderInfo}. 100 */ 101 public static final class Builder { 102 private int mDeviceType; 103 private String mDeviceName; 104 private String mModelName; 105 private int mBatteryPercentage; 106 private boolean mIsBatteryCharging; 107 private int mConnectionStrength; 108 private Bundle mExtras = Bundle.EMPTY; 109 Builder(@onNull String deviceName, @NonNull String modelName)110 public Builder(@NonNull String deviceName, @NonNull String modelName) { 111 Objects.requireNonNull(deviceName); 112 Objects.requireNonNull(modelName); 113 mDeviceName = deviceName; 114 mModelName = modelName; 115 } 116 117 /** 118 * Sets the device type that provides connectivity. 119 * 120 * @param deviceType Device type as represented by IntDef {@link DeviceType}. 121 * @return Returns the Builder object. 122 */ 123 @NonNull setDeviceType(@eviceType int deviceType)124 public Builder setDeviceType(@DeviceType int deviceType) { 125 mDeviceType = deviceType; 126 return this; 127 } 128 129 /** 130 * Sets the device name of the remote device. 131 * 132 * @param deviceName The user configurable device name. 133 * @return Returns the Builder object. 134 */ 135 @NonNull setDeviceName(@onNull String deviceName)136 public Builder setDeviceName(@NonNull String deviceName) { 137 Objects.requireNonNull(deviceName); 138 mDeviceName = deviceName; 139 return this; 140 } 141 142 /** 143 * Sets the model name of the remote device. 144 * 145 * @param modelName The OEM configured name for the device model. 146 * @return Returns the Builder object. 147 */ 148 @NonNull setModelName(@onNull String modelName)149 public Builder setModelName(@NonNull String modelName) { 150 Objects.requireNonNull(modelName); 151 mModelName = modelName; 152 return this; 153 } 154 155 /** 156 * Sets the battery charge percentage of the remote device. 157 * 158 * @param batteryPercentage The battery charge percentage in the range 0 to 100. 159 * @return Returns the Builder object. 160 */ 161 @NonNull setBatteryPercentage(@ntRangefrom = 0, to = 100) int batteryPercentage)162 public Builder setBatteryPercentage(@IntRange(from = 0, to = 100) int batteryPercentage) { 163 mBatteryPercentage = batteryPercentage; 164 return this; 165 } 166 167 /** 168 * Sets if the battery of the remote device is charging. 169 * 170 * @param isBatteryCharging True if battery is charging. 171 * @return Returns the Builder object. 172 */ 173 @NonNull 174 @FlaggedApi(Flags.FLAG_NETWORK_PROVIDER_BATTERY_CHARGING_STATUS) setBatteryCharging(boolean isBatteryCharging)175 public Builder setBatteryCharging(boolean isBatteryCharging) { 176 mIsBatteryCharging = isBatteryCharging; 177 return this; 178 } 179 180 /** 181 * Sets the displayed connection strength of the remote device to the internet. 182 * 183 * @param connectionStrength Connection strength in range 0 to 4. 184 * @return Returns the Builder object. 185 */ 186 @NonNull setConnectionStrength(@ntRangefrom = 0, to = 4) int connectionStrength)187 public Builder setConnectionStrength(@IntRange(from = 0, to = 4) int connectionStrength) { 188 mConnectionStrength = connectionStrength; 189 return this; 190 } 191 192 /** 193 * Sets the extras bundle 194 * 195 * @return Returns the Builder object. 196 */ 197 @NonNull setExtras(@onNull Bundle extras)198 public Builder setExtras(@NonNull Bundle extras) { 199 Objects.requireNonNull(extras); 200 mExtras = extras; 201 return this; 202 } 203 204 /** 205 * Builds the {@link NetworkProviderInfo} object. 206 * 207 * @return Returns the built {@link NetworkProviderInfo} object. 208 */ 209 @NonNull build()210 public NetworkProviderInfo build() { 211 return new NetworkProviderInfo(mDeviceType, mDeviceName, mModelName, mBatteryPercentage, 212 mIsBatteryCharging, mConnectionStrength, mExtras); 213 } 214 } 215 validate(@eviceType int deviceType, String deviceName, String modelName, int batteryPercentage, int connectionStrength)216 private static void validate(@DeviceType int deviceType, String deviceName, String modelName, 217 int batteryPercentage, int connectionStrength) { 218 if (deviceType != DEVICE_TYPE_UNKNOWN && deviceType != DEVICE_TYPE_PHONE 219 && deviceType != DEVICE_TYPE_TABLET && deviceType != DEVICE_TYPE_LAPTOP 220 && deviceType != DEVICE_TYPE_WATCH && deviceType != DEVICE_TYPE_AUTO) { 221 throw new IllegalArgumentException("Illegal device type"); 222 } 223 if (batteryPercentage < 0 || batteryPercentage > 100) { 224 throw new IllegalArgumentException("BatteryPercentage must be in range 0-100"); 225 } 226 if (connectionStrength < 0 || connectionStrength > 4) { 227 throw new IllegalArgumentException("ConnectionStrength must be in range 0-4"); 228 } 229 } 230 NetworkProviderInfo(@eviceType int deviceType, @NonNull String deviceName, @NonNull String modelName, int batteryPercentage, boolean isBatteryCharging, int connectionStrength, @NonNull Bundle extras)231 private NetworkProviderInfo(@DeviceType int deviceType, @NonNull String deviceName, 232 @NonNull String modelName, int batteryPercentage, boolean isBatteryCharging, 233 int connectionStrength, @NonNull Bundle extras) { 234 validate(deviceType, deviceName, modelName, batteryPercentage, connectionStrength); 235 mDeviceType = deviceType; 236 mDeviceName = deviceName; 237 mModelName = modelName; 238 mBatteryPercentage = batteryPercentage; 239 mIsBatteryCharging = isBatteryCharging; 240 mConnectionStrength = connectionStrength; 241 mExtras = extras; 242 } 243 244 /** 245 * Gets the device type that provides connectivity. 246 * 247 * @return Returns the device type as represented by IntDef {@link DeviceType}. 248 */ 249 @DeviceType getDeviceType()250 public int getDeviceType() { 251 return mDeviceType; 252 } 253 254 /** 255 * Gets the device name of the remote device. 256 * 257 * @return Returns the user configurable device name. 258 */ 259 @NonNull getDeviceName()260 public String getDeviceName() { 261 return mDeviceName; 262 } 263 264 /** 265 * Gets the model name of the remote device. 266 * 267 * @return Returns the OEM configured name for the device model. 268 */ 269 @NonNull getModelName()270 public String getModelName() { 271 return mModelName; 272 } 273 274 /** 275 * Gets the battery charge percentage of the remote device. 276 * 277 * @return Returns the battery charge percentage in the range 0 to 100. 278 */ 279 @IntRange(from = 0, to = 100) getBatteryPercentage()280 public int getBatteryPercentage() { 281 return mBatteryPercentage; 282 } 283 284 /** 285 * Gets the charging state of the battery on the remote device. 286 * 287 * @return Returns true if the battery of the remote device is charging. 288 */ 289 @FlaggedApi(Flags.FLAG_NETWORK_PROVIDER_BATTERY_CHARGING_STATUS) isBatteryCharging()290 public boolean isBatteryCharging() { 291 return mIsBatteryCharging; 292 } 293 294 /** 295 * Gets the displayed connection strength of the remote device to the internet. 296 * 297 * @return Returns the connection strength in range 0 to 4. 298 */ 299 @IntRange(from = 0, to = 4) getConnectionStrength()300 public int getConnectionStrength() { 301 return mConnectionStrength; 302 } 303 304 /** 305 * Gets the extras Bundle. 306 * 307 * @return Returns a Bundle object. 308 */ 309 @NonNull getExtras()310 public Bundle getExtras() { 311 return mExtras; 312 } 313 314 @Override equals(Object obj)315 public boolean equals(Object obj) { 316 if (!(obj instanceof NetworkProviderInfo)) return false; 317 NetworkProviderInfo other = (NetworkProviderInfo) obj; 318 return mDeviceType == other.getDeviceType() 319 && Objects.equals(mDeviceName, other.mDeviceName) 320 && Objects.equals(mModelName, other.mModelName) 321 && mBatteryPercentage == other.mBatteryPercentage 322 && mIsBatteryCharging == other.mIsBatteryCharging 323 && mConnectionStrength == other.mConnectionStrength; 324 } 325 326 @Override hashCode()327 public int hashCode() { 328 return Objects.hash(mDeviceType, mDeviceName, mModelName, mBatteryPercentage, 329 mIsBatteryCharging, mConnectionStrength); 330 } 331 332 @Override writeToParcel(@onNull Parcel dest, int flags)333 public void writeToParcel(@NonNull Parcel dest, int flags) { 334 dest.writeInt(mDeviceType); 335 dest.writeString(mDeviceName); 336 dest.writeString(mModelName); 337 dest.writeInt(mBatteryPercentage); 338 dest.writeBoolean(mIsBatteryCharging); 339 dest.writeInt(mConnectionStrength); 340 dest.writeBundle(mExtras); 341 } 342 343 @Override describeContents()344 public int describeContents() { 345 return 0; 346 } 347 348 /** 349 * Creates a {@link NetworkProviderInfo} object from a parcel. 350 * 351 * @hide 352 */ 353 @NonNull readFromParcel(@onNull Parcel in)354 public static NetworkProviderInfo readFromParcel(@NonNull Parcel in) { 355 return new NetworkProviderInfo(in.readInt(), in.readString(), in.readString(), in.readInt(), 356 in.readBoolean(), in.readInt(), in.readBundle()); 357 } 358 359 @NonNull 360 public static final Creator<NetworkProviderInfo> CREATOR = new Creator<NetworkProviderInfo>() { 361 @Override 362 public NetworkProviderInfo createFromParcel(Parcel in) { 363 return readFromParcel(in); 364 } 365 366 @Override 367 public NetworkProviderInfo[] newArray(int size) { 368 return new NetworkProviderInfo[size]; 369 } 370 }; 371 372 @Override toString()373 public String toString() { 374 return new StringBuilder("NetworkProviderInfo[") 375 .append("deviceType=").append(mDeviceType) 376 .append(", deviceName=").append(mDeviceName) 377 .append(", modelName=").append(mModelName) 378 .append(", batteryPercentage=").append(mBatteryPercentage) 379 .append(", isBatteryCharging=").append(mIsBatteryCharging) 380 .append(", connectionStrength=").append(mConnectionStrength) 381 .append(", extras=").append(mExtras.toString()) 382 .append("]").toString(); 383 } 384 } 385