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.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.annotation.TestApi; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import java.util.Objects; 27 28 /** 29 * Metadata sent by captive portals, see https://www.ietf.org/id/draft-ietf-capport-api-03.txt. 30 * @hide 31 */ 32 @SystemApi 33 @TestApi 34 public final class CaptivePortalData implements Parcelable { 35 private final long mRefreshTimeMillis; 36 @Nullable 37 private final Uri mUserPortalUrl; 38 @Nullable 39 private final Uri mVenueInfoUrl; 40 private final boolean mIsSessionExtendable; 41 private final long mByteLimit; 42 private final long mExpiryTimeMillis; 43 private final boolean mCaptive; 44 CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl, boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive)45 private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl, 46 boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive) { 47 mRefreshTimeMillis = refreshTimeMillis; 48 mUserPortalUrl = userPortalUrl; 49 mVenueInfoUrl = venueInfoUrl; 50 mIsSessionExtendable = isSessionExtendable; 51 mByteLimit = byteLimit; 52 mExpiryTimeMillis = expiryTimeMillis; 53 mCaptive = captive; 54 } 55 CaptivePortalData(Parcel p)56 private CaptivePortalData(Parcel p) { 57 this(p.readLong(), p.readParcelable(null), p.readParcelable(null), p.readBoolean(), 58 p.readLong(), p.readLong(), p.readBoolean()); 59 } 60 61 @Override describeContents()62 public int describeContents() { 63 return 0; 64 } 65 66 @Override writeToParcel(@onNull Parcel dest, int flags)67 public void writeToParcel(@NonNull Parcel dest, int flags) { 68 dest.writeLong(mRefreshTimeMillis); 69 dest.writeParcelable(mUserPortalUrl, 0); 70 dest.writeParcelable(mVenueInfoUrl, 0); 71 dest.writeBoolean(mIsSessionExtendable); 72 dest.writeLong(mByteLimit); 73 dest.writeLong(mExpiryTimeMillis); 74 dest.writeBoolean(mCaptive); 75 } 76 77 /** 78 * A builder to create new {@link CaptivePortalData}. 79 */ 80 public static class Builder { 81 private long mRefreshTime; 82 private Uri mUserPortalUrl; 83 private Uri mVenueInfoUrl; 84 private boolean mIsSessionExtendable; 85 private long mBytesRemaining = -1; 86 private long mExpiryTime = -1; 87 private boolean mCaptive; 88 89 /** 90 * Create an empty builder. 91 */ Builder()92 public Builder() {} 93 94 /** 95 * Create a builder copying all data from existing {@link CaptivePortalData}. 96 */ Builder(@ullable CaptivePortalData data)97 public Builder(@Nullable CaptivePortalData data) { 98 if (data == null) return; 99 setRefreshTime(data.mRefreshTimeMillis) 100 .setUserPortalUrl(data.mUserPortalUrl) 101 .setVenueInfoUrl(data.mVenueInfoUrl) 102 .setSessionExtendable(data.mIsSessionExtendable) 103 .setBytesRemaining(data.mByteLimit) 104 .setExpiryTime(data.mExpiryTimeMillis) 105 .setCaptive(data.mCaptive); 106 } 107 108 /** 109 * Set the time at which data was last refreshed, as per {@link System#currentTimeMillis()}. 110 */ 111 @NonNull setRefreshTime(long refreshTime)112 public Builder setRefreshTime(long refreshTime) { 113 mRefreshTime = refreshTime; 114 return this; 115 } 116 117 /** 118 * Set the URL to be used for users to login to the portal, if captive. 119 */ 120 @NonNull setUserPortalUrl(@ullable Uri userPortalUrl)121 public Builder setUserPortalUrl(@Nullable Uri userPortalUrl) { 122 mUserPortalUrl = userPortalUrl; 123 return this; 124 } 125 126 /** 127 * Set the URL that can be used by users to view information about the network venue. 128 */ 129 @NonNull setVenueInfoUrl(@ullable Uri venueInfoUrl)130 public Builder setVenueInfoUrl(@Nullable Uri venueInfoUrl) { 131 mVenueInfoUrl = venueInfoUrl; 132 return this; 133 } 134 135 /** 136 * Set whether the portal supports extending a user session on the portal URL page. 137 */ 138 @NonNull setSessionExtendable(boolean sessionExtendable)139 public Builder setSessionExtendable(boolean sessionExtendable) { 140 mIsSessionExtendable = sessionExtendable; 141 return this; 142 } 143 144 /** 145 * Set the number of bytes remaining on the network before the portal closes. 146 */ 147 @NonNull setBytesRemaining(long bytesRemaining)148 public Builder setBytesRemaining(long bytesRemaining) { 149 mBytesRemaining = bytesRemaining; 150 return this; 151 } 152 153 /** 154 * Set the time at the session will expire, as per {@link System#currentTimeMillis()}. 155 */ 156 @NonNull setExpiryTime(long expiryTime)157 public Builder setExpiryTime(long expiryTime) { 158 mExpiryTime = expiryTime; 159 return this; 160 } 161 162 /** 163 * Set whether the network is captive (portal closed). 164 */ 165 @NonNull setCaptive(boolean captive)166 public Builder setCaptive(boolean captive) { 167 mCaptive = captive; 168 return this; 169 } 170 171 /** 172 * Create a new {@link CaptivePortalData}. 173 */ 174 @NonNull build()175 public CaptivePortalData build() { 176 return new CaptivePortalData(mRefreshTime, mUserPortalUrl, mVenueInfoUrl, 177 mIsSessionExtendable, mBytesRemaining, mExpiryTime, mCaptive); 178 } 179 } 180 181 /** 182 * Get the time at which data was last refreshed, as per {@link System#currentTimeMillis()}. 183 */ getRefreshTimeMillis()184 public long getRefreshTimeMillis() { 185 return mRefreshTimeMillis; 186 } 187 188 /** 189 * Get the URL to be used for users to login to the portal, or extend their session if 190 * {@link #isSessionExtendable()} is true. 191 */ 192 @Nullable getUserPortalUrl()193 public Uri getUserPortalUrl() { 194 return mUserPortalUrl; 195 } 196 197 /** 198 * Get the URL that can be used by users to view information about the network venue. 199 */ 200 @Nullable getVenueInfoUrl()201 public Uri getVenueInfoUrl() { 202 return mVenueInfoUrl; 203 } 204 205 /** 206 * Indicates whether the user portal URL can be used to extend sessions, when the user is logged 207 * in and the session has a time or byte limit. 208 */ isSessionExtendable()209 public boolean isSessionExtendable() { 210 return mIsSessionExtendable; 211 } 212 213 /** 214 * Get the remaining bytes on the captive portal session, at the time {@link CaptivePortalData} 215 * was refreshed. This may be different from the limit currently enforced by the portal. 216 * @return The byte limit, or -1 if not set. 217 */ getByteLimit()218 public long getByteLimit() { 219 return mByteLimit; 220 } 221 222 /** 223 * Get the time at the session will expire, as per {@link System#currentTimeMillis()}. 224 * @return The expiry time, or -1 if unset. 225 */ getExpiryTimeMillis()226 public long getExpiryTimeMillis() { 227 return mExpiryTimeMillis; 228 } 229 230 /** 231 * Get whether the network is captive (portal closed). 232 */ isCaptive()233 public boolean isCaptive() { 234 return mCaptive; 235 } 236 237 @NonNull 238 public static final Creator<CaptivePortalData> CREATOR = new Creator<CaptivePortalData>() { 239 @Override 240 public CaptivePortalData createFromParcel(Parcel source) { 241 return new CaptivePortalData(source); 242 } 243 244 @Override 245 public CaptivePortalData[] newArray(int size) { 246 return new CaptivePortalData[size]; 247 } 248 }; 249 250 @Override hashCode()251 public int hashCode() { 252 return Objects.hash(mRefreshTimeMillis, mUserPortalUrl, mVenueInfoUrl, 253 mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive); 254 } 255 256 @Override equals(Object obj)257 public boolean equals(Object obj) { 258 if (!(obj instanceof CaptivePortalData)) return false; 259 final CaptivePortalData other = (CaptivePortalData) obj; 260 return mRefreshTimeMillis == other.mRefreshTimeMillis 261 && Objects.equals(mUserPortalUrl, other.mUserPortalUrl) 262 && Objects.equals(mVenueInfoUrl, other.mVenueInfoUrl) 263 && mIsSessionExtendable == other.mIsSessionExtendable 264 && mByteLimit == other.mByteLimit 265 && mExpiryTimeMillis == other.mExpiryTimeMillis 266 && mCaptive == other.mCaptive; 267 } 268 269 @Override toString()270 public String toString() { 271 return "CaptivePortalData {" 272 + "refreshTime: " + mRefreshTimeMillis 273 + ", userPortalUrl: " + mUserPortalUrl 274 + ", venueInfoUrl: " + mVenueInfoUrl 275 + ", isSessionExtendable: " + mIsSessionExtendable 276 + ", byteLimit: " + mByteLimit 277 + ", expiryTime: " + mExpiryTimeMillis 278 + ", captive: " + mCaptive 279 + "}"; 280 } 281 } 282