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