• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
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  * Metadata sent by captive portals, see https://www.ietf.org/id/draft-ietf-capport-api-03.txt.
32  * @hide
33  */
34 @SystemApi
35 public final class CaptivePortalData implements Parcelable {
36     private final long mRefreshTimeMillis;
37     @Nullable
38     private final Uri mUserPortalUrl;
39     @Nullable
40     private final Uri mVenueInfoUrl;
41     private final boolean mIsSessionExtendable;
42     private final long mByteLimit;
43     private final long mExpiryTimeMillis;
44     private final boolean mCaptive;
45     private final String mVenueFriendlyName;
46     private final int mVenueInfoUrlSource;
47     private final int mUserPortalUrlSource;
48 
49     /** @hide */
50     @Retention(RetentionPolicy.SOURCE)
51     @IntDef(prefix = {"CAPTIVE_PORTAL_DATA_SOURCE_"}, value = {
52             CAPTIVE_PORTAL_DATA_SOURCE_OTHER,
53             CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT})
54     public @interface CaptivePortalDataSource {}
55 
56     /**
57      * Source of information: Other (default)
58      */
59     public static final int CAPTIVE_PORTAL_DATA_SOURCE_OTHER = 0;
60 
61     /**
62      * Source of information: Wi-Fi Passpoint
63      */
64     public static final int CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT = 1;
65 
CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl, boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive, CharSequence venueFriendlyName, int venueInfoUrlSource, int userPortalUrlSource)66     private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl,
67             boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive,
68             CharSequence venueFriendlyName, int venueInfoUrlSource, int userPortalUrlSource) {
69         mRefreshTimeMillis = refreshTimeMillis;
70         mUserPortalUrl = userPortalUrl;
71         mVenueInfoUrl = venueInfoUrl;
72         mIsSessionExtendable = isSessionExtendable;
73         mByteLimit = byteLimit;
74         mExpiryTimeMillis = expiryTimeMillis;
75         mCaptive = captive;
76         mVenueFriendlyName = venueFriendlyName == null ? null : venueFriendlyName.toString();
77         mVenueInfoUrlSource = venueInfoUrlSource;
78         mUserPortalUrlSource = userPortalUrlSource;
79     }
80 
CaptivePortalData(Parcel p)81     private CaptivePortalData(Parcel p) {
82         this(p.readLong(), p.readParcelable(null), p.readParcelable(null), p.readBoolean(),
83                 p.readLong(), p.readLong(), p.readBoolean(), p.readString(), p.readInt(),
84                 p.readInt());
85     }
86 
87     @Override
describeContents()88     public int describeContents() {
89         return 0;
90     }
91 
92     @Override
writeToParcel(@onNull Parcel dest, int flags)93     public void writeToParcel(@NonNull Parcel dest, int flags) {
94         dest.writeLong(mRefreshTimeMillis);
95         dest.writeParcelable(mUserPortalUrl, 0);
96         dest.writeParcelable(mVenueInfoUrl, 0);
97         dest.writeBoolean(mIsSessionExtendable);
98         dest.writeLong(mByteLimit);
99         dest.writeLong(mExpiryTimeMillis);
100         dest.writeBoolean(mCaptive);
101         dest.writeString(mVenueFriendlyName);
102         dest.writeInt(mVenueInfoUrlSource);
103         dest.writeInt(mUserPortalUrlSource);
104     }
105 
106     /**
107      * A builder to create new {@link CaptivePortalData}.
108      */
109     public static class Builder {
110         private long mRefreshTime;
111         private Uri mUserPortalUrl;
112         private Uri mVenueInfoUrl;
113         private boolean mIsSessionExtendable;
114         private long mBytesRemaining = -1;
115         private long mExpiryTime = -1;
116         private boolean mCaptive;
117         private CharSequence mVenueFriendlyName;
118         private @CaptivePortalDataSource int mVenueInfoUrlSource = CAPTIVE_PORTAL_DATA_SOURCE_OTHER;
119         private @CaptivePortalDataSource int mUserPortalUrlSource =
120                 CAPTIVE_PORTAL_DATA_SOURCE_OTHER;
121 
122         /**
123          * Create an empty builder.
124          */
Builder()125         public Builder() {}
126 
127         /**
128          * Create a builder copying all data from existing {@link CaptivePortalData}.
129          */
Builder(@ullable CaptivePortalData data)130         public Builder(@Nullable CaptivePortalData data) {
131             if (data == null) return;
132             setRefreshTime(data.mRefreshTimeMillis)
133                     .setUserPortalUrl(data.mUserPortalUrl, data.mUserPortalUrlSource)
134                     .setVenueInfoUrl(data.mVenueInfoUrl, data.mVenueInfoUrlSource)
135                     .setSessionExtendable(data.mIsSessionExtendable)
136                     .setBytesRemaining(data.mByteLimit)
137                     .setExpiryTime(data.mExpiryTimeMillis)
138                     .setCaptive(data.mCaptive)
139                     .setVenueFriendlyName(data.mVenueFriendlyName);
140         }
141 
142         /**
143          * Set the time at which data was last refreshed, as per {@link System#currentTimeMillis()}.
144          */
145         @NonNull
setRefreshTime(long refreshTime)146         public Builder setRefreshTime(long refreshTime) {
147             mRefreshTime = refreshTime;
148             return this;
149         }
150 
151         /**
152          * Set the URL to be used for users to login to the portal, if captive.
153          */
154         @NonNull
setUserPortalUrl(@ullable Uri userPortalUrl)155         public Builder setUserPortalUrl(@Nullable Uri userPortalUrl) {
156             return setUserPortalUrl(userPortalUrl, CAPTIVE_PORTAL_DATA_SOURCE_OTHER);
157         }
158 
159         /**
160          * Set the URL to be used for users to login to the portal, if captive, and the source of
161          * the data, see {@link CaptivePortalDataSource}
162          */
163         @NonNull
setUserPortalUrl(@ullable Uri userPortalUrl, @CaptivePortalDataSource int source)164         public Builder setUserPortalUrl(@Nullable Uri userPortalUrl,
165                 @CaptivePortalDataSource int source) {
166             mUserPortalUrl = userPortalUrl;
167             mUserPortalUrlSource = source;
168             return this;
169         }
170 
171         /**
172          * Set the URL that can be used by users to view information about the network venue.
173          */
174         @NonNull
setVenueInfoUrl(@ullable Uri venueInfoUrl)175         public Builder setVenueInfoUrl(@Nullable Uri venueInfoUrl) {
176             return setVenueInfoUrl(venueInfoUrl, CAPTIVE_PORTAL_DATA_SOURCE_OTHER);
177         }
178 
179         /**
180          * Set the URL that can be used by users to view information about the network venue, and
181          * the source of the data, see {@link CaptivePortalDataSource}
182          */
183         @NonNull
setVenueInfoUrl(@ullable Uri venueInfoUrl, @CaptivePortalDataSource int source)184         public Builder setVenueInfoUrl(@Nullable Uri venueInfoUrl,
185                 @CaptivePortalDataSource int source) {
186             mVenueInfoUrl = venueInfoUrl;
187             mVenueInfoUrlSource = source;
188             return this;
189         }
190 
191         /**
192          * Set whether the portal supports extending a user session on the portal URL page.
193          */
194         @NonNull
setSessionExtendable(boolean sessionExtendable)195         public Builder setSessionExtendable(boolean sessionExtendable) {
196             mIsSessionExtendable = sessionExtendable;
197             return this;
198         }
199 
200         /**
201          * Set the number of bytes remaining on the network before the portal closes.
202          */
203         @NonNull
setBytesRemaining(long bytesRemaining)204         public Builder setBytesRemaining(long bytesRemaining) {
205             mBytesRemaining = bytesRemaining;
206             return this;
207         }
208 
209         /**
210          * Set the time at the session will expire, as per {@link System#currentTimeMillis()}.
211          */
212         @NonNull
setExpiryTime(long expiryTime)213         public Builder setExpiryTime(long expiryTime) {
214             mExpiryTime = expiryTime;
215             return this;
216         }
217 
218         /**
219          * Set whether the network is captive (portal closed).
220          */
221         @NonNull
setCaptive(boolean captive)222         public Builder setCaptive(boolean captive) {
223             mCaptive = captive;
224             return this;
225         }
226 
227         /**
228          * Set the venue friendly name.
229          */
230         @NonNull
setVenueFriendlyName(@ullable CharSequence venueFriendlyName)231         public Builder setVenueFriendlyName(@Nullable CharSequence venueFriendlyName) {
232             mVenueFriendlyName = venueFriendlyName;
233             return this;
234         }
235 
236         /**
237          * Create a new {@link CaptivePortalData}.
238          */
239         @NonNull
build()240         public CaptivePortalData build() {
241             return new CaptivePortalData(mRefreshTime, mUserPortalUrl, mVenueInfoUrl,
242                     mIsSessionExtendable, mBytesRemaining, mExpiryTime, mCaptive,
243                     mVenueFriendlyName, mVenueInfoUrlSource,
244                     mUserPortalUrlSource);
245         }
246     }
247 
248     /**
249      * Get the time at which data was last refreshed, as per {@link System#currentTimeMillis()}.
250      */
getRefreshTimeMillis()251     public long getRefreshTimeMillis() {
252         return mRefreshTimeMillis;
253     }
254 
255     /**
256      * Get the URL to be used for users to login to the portal, or extend their session if
257      * {@link #isSessionExtendable()} is true.
258      */
259     @Nullable
getUserPortalUrl()260     public Uri getUserPortalUrl() {
261         return mUserPortalUrl;
262     }
263 
264     /**
265      * Get the URL that can be used by users to view information about the network venue.
266      */
267     @Nullable
getVenueInfoUrl()268     public Uri getVenueInfoUrl() {
269         return mVenueInfoUrl;
270     }
271 
272     /**
273      * Indicates whether the user portal URL can be used to extend sessions, when the user is logged
274      * in and the session has a time or byte limit.
275      */
isSessionExtendable()276     public boolean isSessionExtendable() {
277         return mIsSessionExtendable;
278     }
279 
280     /**
281      * Get the remaining bytes on the captive portal session, at the time {@link CaptivePortalData}
282      * was refreshed. This may be different from the limit currently enforced by the portal.
283      * @return The byte limit, or -1 if not set.
284      */
getByteLimit()285     public long getByteLimit() {
286         return mByteLimit;
287     }
288 
289     /**
290      * Get the time at the session will expire, as per {@link System#currentTimeMillis()}.
291      * @return The expiry time, or -1 if unset.
292      */
getExpiryTimeMillis()293     public long getExpiryTimeMillis() {
294         return mExpiryTimeMillis;
295     }
296 
297     /**
298      * Get whether the network is captive (portal closed).
299      */
isCaptive()300     public boolean isCaptive() {
301         return mCaptive;
302     }
303 
304     /**
305      * Get the information source of the Venue URL
306      * @return The source that the Venue URL was obtained from
307      */
getVenueInfoUrlSource()308     public @CaptivePortalDataSource int getVenueInfoUrlSource() {
309         return mVenueInfoUrlSource;
310     }
311 
312     /**
313      * Get the information source of the user portal URL
314      * @return The source that the user portal URL was obtained from
315      */
getUserPortalUrlSource()316     public @CaptivePortalDataSource int getUserPortalUrlSource() {
317         return mUserPortalUrlSource;
318     }
319 
320     /**
321      * Get the venue friendly name
322      */
323     @Nullable
getVenueFriendlyName()324     public CharSequence getVenueFriendlyName() {
325         return mVenueFriendlyName;
326     }
327 
328     @NonNull
329     public static final Creator<CaptivePortalData> CREATOR = new Creator<CaptivePortalData>() {
330         @Override
331         public CaptivePortalData createFromParcel(Parcel source) {
332             return new CaptivePortalData(source);
333         }
334 
335         @Override
336         public CaptivePortalData[] newArray(int size) {
337             return new CaptivePortalData[size];
338         }
339     };
340 
341     @Override
hashCode()342     public int hashCode() {
343         return Objects.hash(mRefreshTimeMillis, mUserPortalUrl, mVenueInfoUrl,
344                 mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive, mVenueFriendlyName,
345                 mVenueInfoUrlSource, mUserPortalUrlSource);
346     }
347 
348     @Override
equals(@ullable Object obj)349     public boolean equals(@Nullable Object obj) {
350         if (!(obj instanceof CaptivePortalData)) return false;
351         final CaptivePortalData other = (CaptivePortalData) obj;
352         return mRefreshTimeMillis == other.mRefreshTimeMillis
353                 && Objects.equals(mUserPortalUrl, other.mUserPortalUrl)
354                 && Objects.equals(mVenueInfoUrl, other.mVenueInfoUrl)
355                 && mIsSessionExtendable == other.mIsSessionExtendable
356                 && mByteLimit == other.mByteLimit
357                 && mExpiryTimeMillis == other.mExpiryTimeMillis
358                 && mCaptive == other.mCaptive
359                 && Objects.equals(mVenueFriendlyName, other.mVenueFriendlyName)
360                 && mVenueInfoUrlSource == other.mVenueInfoUrlSource
361                 && mUserPortalUrlSource == other.mUserPortalUrlSource;
362     }
363 
364     @Override
toString()365     public String toString() {
366         return "CaptivePortalData {"
367                 + "refreshTime: " + mRefreshTimeMillis
368                 + ", userPortalUrl: " + mUserPortalUrl
369                 + ", venueInfoUrl: " + mVenueInfoUrl
370                 + ", isSessionExtendable: " + mIsSessionExtendable
371                 + ", byteLimit: " + mByteLimit
372                 + ", expiryTime: " + mExpiryTimeMillis
373                 + ", captive: " + mCaptive
374                 + ", venueFriendlyName: " + mVenueFriendlyName
375                 + ", venueInfoUrlSource: " + mVenueInfoUrlSource
376                 + ", userPortalUrlSource: " + mUserPortalUrlSource
377                 + "}";
378     }
379 }
380