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 mHttpResponseCode == SUCCESS_CODE; 107 } 108 isPortal()109 public boolean isPortal() { 110 return !isSuccessful() && (mHttpResponseCode >= 200) && (mHttpResponseCode <= 399); 111 } 112 isFailed()113 public boolean isFailed() { 114 return !isSuccessful() && !isPortal(); 115 } 116 isPartialConnectivity()117 public boolean isPartialConnectivity() { 118 return mHttpResponseCode == PARTIAL_CODE; 119 } 120 isDnsPrivateIpResponse()121 public boolean isDnsPrivateIpResponse() { 122 return mHttpResponseCode == DNS_PRIVATE_IP_RESPONSE_CODE; 123 } 124 125 /** 126 * Make a failed {@code this} for either HTTPS or HTTP determined by {@param isHttps}. 127 * @param probeType probe type of the result. 128 * @return a failed {@link CaptivePortalProbeResult} 129 */ failed(@robeType int probeType)130 public static CaptivePortalProbeResult failed(@ProbeType int probeType) { 131 return new CaptivePortalProbeResult(FAILED_CODE, probeType); 132 } 133 134 /** 135 * Make a success {@code this} for either HTTPS or HTTP determined by {@param isHttps}. 136 * @param probeType probe type of the result. 137 * @return a success {@link CaptivePortalProbeResult} 138 */ success(@robeType int probeType)139 public static CaptivePortalProbeResult success(@ProbeType int probeType) { 140 return new CaptivePortalProbeResult(SUCCESS_CODE, probeType); 141 } 142 143 /** 144 * As {@code this} is the result of calling isCaptivePortal(), the result may be determined from 145 * one or more probes depending on the configuration of detection probes. Return if HTTPS probe 146 * is one of the probes that concludes it. 147 */ isConcludedFromHttps()148 public boolean isConcludedFromHttps() { 149 return (probeType & (1 << PROBE_HTTPS)) != 0; 150 } 151 152 /** 153 * As {@code this} is the result of calling isCaptivePortal(), the result may be determined from 154 * one or more probes depending on the configuration of detection probes. Return if HTTP probe 155 * is one of the probes that concludes it. 156 */ isConcludedFromHttp()157 public boolean isConcludedFromHttp() { 158 return (probeType & (1 << PROBE_HTTP)) != 0; 159 } 160 } 161