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.NonNull;
21 import android.annotation.SystemApi;
22 import android.os.Bundle;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.util.Objects;
29 
30 /**
31  * The status of a connection to a hotspot network after the client called
32  * {@link SharedConnectivityManager#connectHotspotNetwork}.
33  *
34  * @hide
35  */
36 @SystemApi
37 public final class HotspotNetworkConnectionStatus implements Parcelable {
38 
39     /**
40      * Connection status is unknown.
41      */
42     public static final int CONNECTION_STATUS_UNKNOWN = 0;
43 
44     /**
45      * The connection is being initiated.
46      */
47     public static final int CONNECTION_STATUS_ENABLING_HOTSPOT = 1;
48 
49     /**
50      * Device providing the hotspot failed to initiate it.
51      */
52     public static final int CONNECTION_STATUS_UNKNOWN_ERROR = 2;
53 
54     /**
55      * Failed to provision tethering.
56      */
57     public static final int CONNECTION_STATUS_PROVISIONING_FAILED = 3;
58 
59     /**
60      * Timeout while trying to provision tethering.
61      */
62     public static final int CONNECTION_STATUS_TETHERING_TIMEOUT = 4;
63 
64     /**
65      * Device doesn't support tethering.
66      */
67     public static final int CONNECTION_STATUS_TETHERING_UNSUPPORTED = 5;
68 
69     /**
70      * Device has no cell data.
71      */
72     public static final int CONNECTION_STATUS_NO_CELL_DATA = 6;
73 
74     /**
75      * Device failed to enable hotspot
76      */
77     public static final int CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED = 7;
78 
79     /**
80      * Timeout while trying to enable hotspot
81      */
82     public static final int CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT = 8;
83 
84     /**
85      * Failed to connect to hotspot
86      */
87     public static final int CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED = 9;
88 
89     /**
90      * @hide
91      */
92     @Retention(RetentionPolicy.SOURCE)
93     @IntDef({
94             CONNECTION_STATUS_UNKNOWN,
95             CONNECTION_STATUS_ENABLING_HOTSPOT,
96             CONNECTION_STATUS_UNKNOWN_ERROR,
97             CONNECTION_STATUS_PROVISIONING_FAILED,
98             CONNECTION_STATUS_TETHERING_TIMEOUT,
99             CONNECTION_STATUS_TETHERING_UNSUPPORTED,
100             CONNECTION_STATUS_NO_CELL_DATA,
101             CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED,
102             CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT,
103             CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED,
104     })
105     public @interface ConnectionStatus {
106     }
107 
108     @ConnectionStatus
109     private final int mStatus;
110     private final HotspotNetwork mHotspotNetwork;
111     private final Bundle mExtras;
112 
113     /**
114      * Builder class for {@link HotspotNetworkConnectionStatus}.
115      */
116     public static final class Builder {
117         @ConnectionStatus
118         private int mStatus;
119         private HotspotNetwork mHotspotNetwork;
120         private Bundle mExtras = Bundle.EMPTY;
121 
122         /**
123          * Sets the status of the connection
124          *
125          * @return Returns the Builder object.
126          */
127         @NonNull
setStatus(@onnectionStatus int status)128         public Builder setStatus(@ConnectionStatus int status) {
129             mStatus = status;
130             return this;
131         }
132 
133         /**
134          * Sets the {@link HotspotNetwork} object of the connection.
135          *
136          * @return Returns the Builder object.
137          */
138         @NonNull
setHotspotNetwork(@onNull HotspotNetwork hotspotNetwork)139         public Builder setHotspotNetwork(@NonNull HotspotNetwork hotspotNetwork) {
140             mHotspotNetwork = hotspotNetwork;
141             return this;
142         }
143 
144         /**
145          * Sets the extras bundle
146          *
147          * @return Returns the Builder object.
148          */
149         @NonNull
setExtras(@onNull Bundle extras)150         public Builder setExtras(@NonNull Bundle extras) {
151             mExtras = extras;
152             return this;
153         }
154 
155         /**
156          * Builds the {@link HotspotNetworkConnectionStatus} object.
157          *
158          * @return Returns the built {@link HotspotNetworkConnectionStatus} object.
159          */
160         @NonNull
build()161         public HotspotNetworkConnectionStatus build() {
162             return new HotspotNetworkConnectionStatus(mStatus, mHotspotNetwork, mExtras);
163         }
164     }
165 
validate(@onnectionStatus int status)166     private static void validate(@ConnectionStatus int status) {
167         if (status != CONNECTION_STATUS_UNKNOWN
168                 && status != CONNECTION_STATUS_ENABLING_HOTSPOT
169                 && status != CONNECTION_STATUS_UNKNOWN_ERROR
170                 && status != CONNECTION_STATUS_PROVISIONING_FAILED
171                 && status != CONNECTION_STATUS_TETHERING_TIMEOUT
172                 && status != CONNECTION_STATUS_TETHERING_UNSUPPORTED
173                 && status != CONNECTION_STATUS_NO_CELL_DATA
174                 && status != CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED
175                 && status != CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT
176                 && status != CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED) {
177             throw new IllegalArgumentException("Illegal connection status");
178         }
179     }
180 
HotspotNetworkConnectionStatus(@onnectionStatus int status, HotspotNetwork hotspotNetwork, @NonNull Bundle extras)181     private HotspotNetworkConnectionStatus(@ConnectionStatus int status,
182             HotspotNetwork hotspotNetwork, @NonNull Bundle extras) {
183         validate(status);
184         mStatus = status;
185         mHotspotNetwork = hotspotNetwork;
186         mExtras = extras;
187     }
188 
189     /**
190      * Gets the status of the connection
191      *
192      * @return Returns true for enabled, false otherwise.
193      */
194     @ConnectionStatus
getStatus()195     public int getStatus() {
196         return mStatus;
197     }
198 
199     /**
200      * Gets the {@link HotspotNetwork} object of the connection.
201      *
202      * @return Returns a HotspotNetwork object.
203      */
204     @NonNull
getHotspotNetwork()205     public HotspotNetwork getHotspotNetwork() {
206         return mHotspotNetwork;
207     }
208 
209     /**
210      * Gets the extras Bundle.
211      *
212      * @return Returns a Bundle object.
213      */
214     @NonNull
getExtras()215     public Bundle getExtras() {
216         return mExtras;
217     }
218 
219     @Override
equals(Object obj)220     public boolean equals(Object obj) {
221         if (!(obj instanceof HotspotNetworkConnectionStatus)) return false;
222         HotspotNetworkConnectionStatus other = (HotspotNetworkConnectionStatus) obj;
223         return mStatus == other.getStatus()
224                 && Objects.equals(mHotspotNetwork, other.getHotspotNetwork());
225     }
226 
227     @Override
hashCode()228     public int hashCode() {
229         return Objects.hash(mStatus, mHotspotNetwork);
230     }
231 
232     @Override
describeContents()233     public int describeContents() {
234         return 0;
235     }
236 
237     @Override
writeToParcel(@onNull Parcel dest, int flags)238     public void writeToParcel(@NonNull Parcel dest, int flags) {
239         dest.writeInt(mStatus);
240         mHotspotNetwork.writeToParcel(dest, flags);
241         dest.writeBundle(mExtras);
242     }
243 
244     /**
245      * Creates a {@link HotspotNetworkConnectionStatus} object from a parcel.
246      *
247      * @hide
248      */
249     @NonNull
readFromParcel(@onNull Parcel in)250     public static HotspotNetworkConnectionStatus readFromParcel(@NonNull Parcel in) {
251         return new HotspotNetworkConnectionStatus(in.readInt(),
252                 HotspotNetwork.readFromParcel(in), in.readBundle());
253     }
254 
255     @NonNull
256     public static final Creator<HotspotNetworkConnectionStatus> CREATOR = new Creator<>() {
257         @Override
258         public HotspotNetworkConnectionStatus createFromParcel(Parcel in) {
259             return readFromParcel(in);
260         }
261 
262         @Override
263         public HotspotNetworkConnectionStatus[] newArray(int size) {
264             return new HotspotNetworkConnectionStatus[size];
265         }
266     };
267 
268     @Override
toString()269     public String toString() {
270         return new StringBuilder("HotspotNetworkConnectionStatus[")
271                 .append("status=").append(mStatus)
272                 .append("hotspot network=").append(mHotspotNetwork.toString())
273                 .append("extras=").append(mExtras.toString())
274                 .append("]").toString();
275     }
276 }
277