• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.captiveportal;
18 
19 import static android.net.metrics.ValidationProbeEvent.PROBE_HTTP;
20 import static android.net.metrics.ValidationProbeEvent.PROBE_HTTPS;
21 
22 import androidx.annotation.IntDef;
23 import androidx.annotation.NonNull;
24 import androidx.annotation.Nullable;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 /**
29  * Result of calling isCaptivePortal().
30  * @hide
31  */
32 public class CaptivePortalProbeResult {
33     public static final int SUCCESS_CODE = 204;
34     public static final int FAILED_CODE = 599;
35     public static final int PORTAL_CODE = 302;
36     // Set partial connectivity http response code to -1 to prevent conflict with the other http
37     // response codes. Besides the default http response code of probe result is set as 599 in
38     // NetworkMonitor#sendParallelHttpProbes(), so response code will be set as -1 only when
39     // NetworkMonitor detects partial connectivity.
40     /**
41      * @hide
42      */
43     public static final int PARTIAL_CODE = -1;
44 
45     // DNS response with private IP on the probe URL suggests that the network, especially Wi-Fi
46     // network is not connected to the Internet. This code represents the result of a single probe,
47     // for correct logging of the probe results. The result of the whole evaluation would typically
48     // be FAILED if one of the probes returns this status.
49     // This logic is only used if the config_force_dns_probe_private_ip_no_internet flag is set.
50     public static final int DNS_PRIVATE_IP_RESPONSE_CODE = -2;
51     // The private IP logic only applies to the HTTP probe.
52     public static final CaptivePortalProbeResult PRIVATE_IP =
53             new CaptivePortalProbeResult(DNS_PRIVATE_IP_RESPONSE_CODE, 1 << PROBE_HTTP);
54     // Partial connectivity should be concluded from both HTTP and HTTPS probes.
55     @NonNull
56     public static final CaptivePortalProbeResult PARTIAL = new CaptivePortalProbeResult(
57             PARTIAL_CODE, 1 << PROBE_HTTP | 1 << PROBE_HTTPS);
58     // Probe type that is used for unspecified probe result.
59     public static final int PROBE_UNKNOWN = 0;
60 
61     final int mHttpResponseCode;  // HTTP response code returned from Internet probe.
62     @Nullable
63     public final String redirectUrl;      // Redirect destination returned from Internet probe.
64     @Nullable
65     public final String detectUrl;        // URL where a 204 response code indicates
66                                           // captive portal has been appeased.
67     @Nullable
68     public final CaptivePortalProbeSpec probeSpec;
69 
70     // Indicate what kind of probe this is. This is a bitmask constructed by
71     // bitwise-or-ing(i.e. {@code |}) the {@code ValidationProbeEvent.PROBE_HTTP} or
72     // {@code ValidationProbeEvent.PROBE_HTTPS} values. Set it as {@code PROBE_UNKNOWN} if the probe
73     // type is unspecified.
74     @ProbeType
75     public final int probeType;
76 
77     @IntDef(value = {
78         PROBE_UNKNOWN,
79         1 << PROBE_HTTP,
80         1 << PROBE_HTTPS,
81     })
82     @Retention(RetentionPolicy.SOURCE)
83     public @interface ProbeType {
84     }
85 
CaptivePortalProbeResult(int httpResponseCode, @ProbeType int probeType)86     public CaptivePortalProbeResult(int httpResponseCode, @ProbeType int probeType) {
87         this(httpResponseCode, null, null, null, probeType);
88     }
89 
CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl, @Nullable String detectUrl, @ProbeType int probeType)90     public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
91             @Nullable String detectUrl, @ProbeType int probeType) {
92         this(httpResponseCode, redirectUrl, detectUrl, null, probeType);
93     }
94 
CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl, @Nullable String detectUrl, @Nullable CaptivePortalProbeSpec probeSpec, @ProbeType int probeType)95     public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
96             @Nullable String detectUrl, @Nullable CaptivePortalProbeSpec probeSpec,
97             @ProbeType int probeType) {
98         mHttpResponseCode = httpResponseCode;
99         this.redirectUrl = redirectUrl;
100         this.detectUrl = detectUrl;
101         this.probeSpec = probeSpec;
102         this.probeType = probeType;
103     }
104 
isSuccessful()105     public boolean isSuccessful() {
106         return isSuccessCode(mHttpResponseCode);
107     }
108 
isPortal()109     public boolean isPortal() {
110         return isPortalCode(mHttpResponseCode);
111     }
112 
isSuccessCode(int responseCode)113     private static boolean isSuccessCode(int responseCode) {
114         return responseCode == SUCCESS_CODE;
115     }
116 
117     /**
118      * @return Whether the specified HTTP return code indicates a captive portal.
119      */
isPortalCode(int responseCode)120     public static boolean isPortalCode(int responseCode) {
121         return !isSuccessCode(responseCode) && (responseCode >= 200) && (responseCode <= 399);
122     }
123 
isFailed()124     public boolean isFailed() {
125         return !isSuccessful() && !isPortal();
126     }
127 
isPartialConnectivity()128     public boolean isPartialConnectivity() {
129         return mHttpResponseCode == PARTIAL_CODE;
130     }
131 
isDnsPrivateIpResponse()132     public boolean isDnsPrivateIpResponse() {
133         return mHttpResponseCode == DNS_PRIVATE_IP_RESPONSE_CODE;
134     }
135 
136     /**
137      *  Make a failed {@code this} for either HTTPS or HTTP determined by {@param isHttps}.
138      *  @param probeType probe type of the result.
139      *  @return a failed {@link CaptivePortalProbeResult}
140      */
failed(@robeType int probeType)141     public static CaptivePortalProbeResult failed(@ProbeType int probeType) {
142         return new CaptivePortalProbeResult(FAILED_CODE, probeType);
143     }
144 
145     /**
146      *  Make a success {@code this} for either HTTPS or HTTP determined by {@param isHttps}.
147      *  @param probeType probe type of the result.
148      *  @return a success {@link CaptivePortalProbeResult}
149      */
success(@robeType int probeType)150     public static CaptivePortalProbeResult success(@ProbeType int probeType) {
151         return new CaptivePortalProbeResult(SUCCESS_CODE, probeType);
152     }
153 
154     /**
155      * As {@code this} is the result of calling isCaptivePortal(), the result may be determined from
156      * one or more probes depending on the configuration of detection probes. Return if HTTPS probe
157      * is one of the probes that concludes it.
158      */
isConcludedFromHttps()159     public boolean isConcludedFromHttps() {
160         return (probeType & (1 << PROBE_HTTPS)) != 0;
161     }
162 
163     /**
164      * As {@code this} is the result of calling isCaptivePortal(), the result may be determined from
165      * one or more probes depending on the configuration of detection probes. Return if HTTP probe
166      * is one of the probes that concludes it.
167      */
isConcludedFromHttp()168     public boolean isConcludedFromHttp() {
169         return (probeType & (1 << PROBE_HTTP)) != 0;
170     }
171 }
172