1 // Copyright 2016 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 package android.net.http; 5 6 import static android.net.http.ConnectionMigrationOptions.MIGRATION_OPTION_ENABLED; 7 import static android.net.http.ConnectionMigrationOptions.MIGRATION_OPTION_UNSPECIFIED; 8 import static android.net.http.DnsOptions.DNS_OPTION_ENABLED; 9 import static android.net.http.DnsOptions.DNS_OPTION_UNSPECIFIED; 10 11 import android.content.Context; 12 13 import androidx.annotation.VisibleForTesting; 14 15 import java.io.IOException; 16 import java.net.Proxy; 17 import java.net.URL; 18 import java.net.URLConnection; 19 import java.time.Instant; 20 import java.util.Set; 21 import java.util.concurrent.Executor; 22 23 /** 24 * {@link HttpEngine} that exposes experimental features. 25 * 26 * <p>{@hide since this class exposes experimental features that should be hidden.} 27 * 28 * @deprecated scheduled for deletion, don't use in new code. 29 */ 30 @Deprecated 31 public abstract class ExperimentalHttpEngine extends HttpEngine { 32 /** 33 * The value of a connection metric is unknown. 34 */ 35 public static final int CONNECTION_METRIC_UNKNOWN = -1; 36 37 /** 38 * The estimate of the effective connection type is unknown. 39 * 40 * @see #getEffectiveConnectionType 41 */ 42 public static final int EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0; 43 44 /** 45 * The device is offline. 46 * 47 * @see #getEffectiveConnectionType 48 */ 49 public static final int EFFECTIVE_CONNECTION_TYPE_OFFLINE = 1; 50 51 /** 52 * The estimate of the effective connection type is slow 2G. 53 * 54 * @see #getEffectiveConnectionType 55 */ 56 public static final int EFFECTIVE_CONNECTION_TYPE_SLOW_2G = 2; 57 58 /** 59 * The estimate of the effective connection type is 2G. 60 * 61 * @see #getEffectiveConnectionType 62 */ 63 public static final int EFFECTIVE_CONNECTION_TYPE_2G = 3; 64 65 /** 66 * The estimate of the effective connection type is 3G. 67 * 68 * @see #getEffectiveConnectionType 69 */ 70 public static final int EFFECTIVE_CONNECTION_TYPE_3G = 4; 71 72 /** 73 * The estimate of the effective connection type is 4G. 74 * 75 * @see #getEffectiveConnectionType 76 */ 77 public static final int EFFECTIVE_CONNECTION_TYPE_4G = 5; 78 79 /** The value to be used to undo any previous network binding. */ 80 public static final long UNBIND_NETWORK_HANDLE = -1; 81 82 /** 83 * A version of {@link HttpEngine.Builder} that exposes experimental features. Instances of 84 * this class are not meant for general use, but instead only to access experimental features. 85 * Experimental features may be deprecated in the future. Use at your own risk. 86 */ 87 public static class Builder extends HttpEngine.Builder { 88 /** 89 * Constructs a {@link Builder} object that facilitates creating a {@link HttpEngine}. The 90 * default configuration enables HTTP/2 and disables QUIC, SDCH and the HTTP cache. 91 * 92 * @param context Android {@link Context}, which is used by the Builder to retrieve the 93 * application context. A reference to only the application context will be kept, so as 94 * to avoid extending the lifetime of {@code context} unnecessarily. 95 */ Builder(Context context)96 public Builder(Context context) { 97 super(context); 98 } 99 100 /** 101 * Constructs {@link Builder} with a given delegate that provides the actual implementation 102 * of the {@code Builder} methods. This constructor is used only by the internal 103 * implementation. 104 * 105 * @param builderDelegate delegate that provides the actual implementation. 106 * <p>{@hide} 107 */ Builder(IHttpEngineBuilder builderDelegate)108 public Builder(IHttpEngineBuilder builderDelegate) { 109 super(builderDelegate); 110 } 111 112 /** 113 * Sets experimental options to be used. 114 * 115 * @param options JSON formatted experimental options. 116 * @return the builder to facilitate chaining. 117 */ setExperimentalOptions(String options)118 public Builder setExperimentalOptions(String options) { 119 mBuilderDelegate.setExperimentalOptions(options); 120 return this; 121 } 122 123 /** 124 * Enables the network quality estimator, which collects and reports 125 * measurements of round trip time (RTT) and downstream throughput at 126 * various layers of the network stack. After enabling the estimator, 127 * listeners of RTT and throughput can be added with 128 * {@link #addRttListener} and {@link #addThroughputListener} and 129 * removed with {@link #removeRttListener} and 130 * {@link #removeThroughputListener}. The estimator uses memory and CPU 131 * only when enabled. 132 * @param value {@code true} to enable network quality estimator, 133 * {@code false} to disable. 134 * @return the builder to facilitate chaining. 135 */ enableNetworkQualityEstimator(boolean value)136 public Builder enableNetworkQualityEstimator(boolean value) { 137 mBuilderDelegate.enableNetworkQualityEstimator(value); 138 return this; 139 } 140 141 /** 142 * Sets the thread priority of the internal thread. 143 * 144 * @param priority the thread priority of the internal thread. 145 * A Linux priority level, from -20 for highest scheduling 146 * priority to 19 for lowest scheduling priority. For more 147 * information on values, see 148 * {@link android.os.Process#setThreadPriority(int, int)} and 149 * {@link android.os.Process#THREAD_PRIORITY_DEFAULT 150 * THREAD_PRIORITY_*} values. 151 * @return the builder to facilitate chaining. 152 */ setThreadPriority(int priority)153 public Builder setThreadPriority(int priority) { 154 mBuilderDelegate.setThreadPriority(priority); 155 return this; 156 } 157 158 /** 159 * Returns delegate, only for testing. 160 * 161 * @hide 162 */ 163 @VisibleForTesting getBuilderDelegate()164 public IHttpEngineBuilder getBuilderDelegate() { 165 return mBuilderDelegate; 166 } 167 168 // To support method chaining, override superclass methods to return an 169 // instance of this class instead of the parent. 170 171 @Override setUserAgent(String userAgent)172 public Builder setUserAgent(String userAgent) { 173 super.setUserAgent(userAgent); 174 return this; 175 } 176 177 @Override setStoragePath(String value)178 public Builder setStoragePath(String value) { 179 super.setStoragePath(value); 180 return this; 181 } 182 183 @Override setEnableQuic(boolean value)184 public Builder setEnableQuic(boolean value) { 185 super.setEnableQuic(value); 186 return this; 187 } 188 189 @Override setEnableHttp2(boolean value)190 public Builder setEnableHttp2(boolean value) { 191 super.setEnableHttp2(value); 192 return this; 193 } 194 195 @Override 196 @QuicOptions.Experimental setQuicOptions(QuicOptions options)197 public Builder setQuicOptions(QuicOptions options) { 198 super.setQuicOptions(options); 199 return this; 200 } 201 202 @Override 203 @DnsOptions.Experimental setDnsOptions(DnsOptions options)204 public Builder setDnsOptions(DnsOptions options) { 205 super.setDnsOptions(options); 206 return this; 207 } 208 209 @Override 210 @ConnectionMigrationOptions.Experimental setConnectionMigrationOptions(ConnectionMigrationOptions options)211 public Builder setConnectionMigrationOptions(ConnectionMigrationOptions options) { 212 super.setConnectionMigrationOptions(options); 213 return this; 214 } 215 216 @Override setEnableHttpCache(int cacheMode, long maxSize)217 public Builder setEnableHttpCache(int cacheMode, long maxSize) { 218 super.setEnableHttpCache(cacheMode, maxSize); 219 return this; 220 } 221 222 @Override addQuicHint(String host, int port, int alternatePort)223 public Builder addQuicHint(String host, int port, int alternatePort) { 224 super.addQuicHint(host, port, alternatePort); 225 return this; 226 } 227 228 @Override addPublicKeyPins(String hostName, Set<byte[]> pinsSha256, boolean includeSubdomains, Instant expirationInstant)229 public Builder addPublicKeyPins(String hostName, Set<byte[]> pinsSha256, 230 boolean includeSubdomains, Instant expirationInstant) { 231 super.addPublicKeyPins(hostName, pinsSha256, includeSubdomains, expirationInstant); 232 return this; 233 } 234 235 @Override setEnablePublicKeyPinningBypassForLocalTrustAnchors(boolean value)236 public Builder setEnablePublicKeyPinningBypassForLocalTrustAnchors(boolean value) { 237 super.setEnablePublicKeyPinningBypassForLocalTrustAnchors(value); 238 return this; 239 } 240 241 @Override build()242 public ExperimentalHttpEngine build() { 243 return mBuilderDelegate.build(); 244 } 245 } 246 247 @Override newBidirectionalStreamBuilder( String url, Executor executor, BidirectionalStream.Callback callback)248 public abstract ExperimentalBidirectionalStream.Builder newBidirectionalStreamBuilder( 249 String url, Executor executor, BidirectionalStream.Callback callback); 250 251 @Override newUrlRequestBuilder( String url, Executor executor, UrlRequest.Callback callback)252 public abstract ExperimentalUrlRequest.Builder newUrlRequestBuilder( 253 String url, Executor executor, UrlRequest.Callback callback); 254 255 /** 256 * Starts NetLog logging to a specified directory with a bounded size. The NetLog will contain 257 * events emitted by all live CronetEngines. The NetLog is useful for debugging. 258 * Once logging has stopped {@link #stopNetLog}, the data will be written 259 * to netlog.json in {@code dirPath}. If logging is interrupted, you can 260 * stitch the files found in .inprogress subdirectory manually using: 261 * https://chromium.googlesource.com/chromium/src/+/main/net/tools/stitch_net_log_files.py. 262 * The log can be viewed using a Chrome browser navigated to chrome://net-internals/#import. 263 * @param dirPath the directory where the netlog.json file will be created. dirPath must 264 * already exist. NetLog files must not exist in the directory. If actively 265 * logging, this method is ignored. 266 * @param logAll {@code true} to include basic events, user cookies, 267 * credentials and all transferred bytes in the log. This option presents a 268 * privacy risk, since it exposes the user's credentials, and should only be 269 * used with the user's consent and in situations where the log won't be public. 270 * {@code false} to just include basic events. 271 * @param maxSize the maximum total disk space in bytes that should be used by NetLog. Actual 272 * disk space usage may exceed this limit slightly. 273 */ startNetLogToDisk(String dirPath, boolean logAll, int maxSize)274 public void startNetLogToDisk(String dirPath, boolean logAll, int maxSize) {} 275 276 /** 277 * Returns an estimate of the effective connection type computed by the network quality 278 * estimator. Call {@link Builder#enableNetworkQualityEstimator} to begin computing this 279 * value. 280 * 281 * @return the estimated connection type. The returned value is one of 282 * {@link #EFFECTIVE_CONNECTION_TYPE_UNKNOWN EFFECTIVE_CONNECTION_TYPE_* }. 283 */ getEffectiveConnectionType()284 public int getEffectiveConnectionType() { 285 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; 286 } 287 288 /** 289 * Configures the network quality estimator for testing. This must be called 290 * before round trip time and throughput listeners are added, and after the 291 * network quality estimator has been enabled. 292 * @param useLocalHostRequests include requests to localhost in estimates. 293 * @param useSmallerResponses include small responses in throughput estimates. 294 * @param disableOfflineCheck when set to true, disables the device offline checks when 295 * computing the effective connection type or when writing the prefs. 296 */ configureNetworkQualityEstimatorForTesting(boolean useLocalHostRequests, boolean useSmallerResponses, boolean disableOfflineCheck)297 public void configureNetworkQualityEstimatorForTesting(boolean useLocalHostRequests, 298 boolean useSmallerResponses, boolean disableOfflineCheck) {} 299 300 /** 301 * Registers a listener that gets called whenever the network quality 302 * estimator witnesses a sample round trip time. This must be called 303 * after {@link Builder#enableNetworkQualityEstimator}, and with throw an 304 * exception otherwise. Round trip times may be recorded at various layers 305 * of the network stack, including TCP, QUIC, and at the URL request layer. 306 * The listener is called on the {@link java.util.concurrent.Executor} that 307 * is passed to {@link Builder#enableNetworkQualityEstimator}. 308 * @param listener the listener of round trip times. 309 */ addRttListener(NetworkQualityRttListener listener)310 public void addRttListener(NetworkQualityRttListener listener) {} 311 312 /** 313 * Removes a listener of round trip times if previously registered with 314 * {@link #addRttListener}. This should be called after a 315 * {@link NetworkQualityRttListener} is added in order to stop receiving 316 * observations. 317 * @param listener the listener of round trip times. 318 */ removeRttListener(NetworkQualityRttListener listener)319 public void removeRttListener(NetworkQualityRttListener listener) {} 320 321 /** 322 * Registers a listener that gets called whenever the network quality 323 * estimator witnesses a sample throughput measurement. This must be called 324 * after {@link Builder#enableNetworkQualityEstimator}. Throughput observations 325 * are computed by measuring bytes read over the active network interface 326 * at times when at least one URL response is being received. The listener 327 * is called on the {@link java.util.concurrent.Executor} that is passed to 328 * {@link Builder#enableNetworkQualityEstimator}. 329 * @param listener the listener of throughput. 330 */ addThroughputListener(NetworkQualityThroughputListener listener)331 public void addThroughputListener(NetworkQualityThroughputListener listener) {} 332 333 /** 334 * Removes a listener of throughput. This should be called after a 335 * {@link NetworkQualityThroughputListener} is added with 336 * {@link #addThroughputListener} in order to stop receiving observations. 337 * @param listener the listener of throughput. 338 */ removeThroughputListener(NetworkQualityThroughputListener listener)339 public void removeThroughputListener(NetworkQualityThroughputListener listener) {} 340 341 /** 342 * Establishes a new connection to the resource specified by the {@link URL} {@code url} 343 * using the given proxy. 344 * <p> 345 * <b>Note:</b> this {@link java.net.HttpURLConnection} implementation is subject to certain 346 * limitations, see {@link #createUrlStreamHandlerFactory} for details. 347 * 348 * @param url URL of resource to connect to. 349 * @param proxy proxy to use when establishing connection. 350 * @return an {@link java.net.HttpURLConnection} instance implemented by this HttpEngine. 351 * @throws IOException if an error occurs while opening the connection. 352 */ 353 // TODO(pauljensen): Expose once implemented, http://crbug.com/418111 openConnection(URL url, Proxy proxy)354 public URLConnection openConnection(URL url, Proxy proxy) throws IOException { 355 return url.openConnection(proxy); 356 } 357 358 /** 359 * Registers a listener that gets called after the end of each request with the request info. 360 * 361 * <p>The listener is called on an {@link java.util.concurrent.Executor} provided by the 362 * listener. 363 * 364 * @param listener the listener for finished requests. 365 */ addRequestFinishedListener(RequestFinishedInfo.Listener listener)366 public void addRequestFinishedListener(RequestFinishedInfo.Listener listener) {} 367 368 /** 369 * Removes a finished request listener. 370 * 371 * @param listener the listener to remove. 372 */ removeRequestFinishedListener(RequestFinishedInfo.Listener listener)373 public void removeRequestFinishedListener(RequestFinishedInfo.Listener listener) {} 374 375 /** 376 * Returns the HTTP RTT estimate (in milliseconds) computed by the network 377 * quality estimator. Set to {@link #CONNECTION_METRIC_UNKNOWN} if the value 378 * is unavailable. This must be called after 379 * {@link Builder#enableNetworkQualityEstimator}, and will throw an 380 * exception otherwise. 381 * @return Estimate of the HTTP RTT in milliseconds. 382 */ getHttpRttMs()383 public int getHttpRttMs() { 384 return CONNECTION_METRIC_UNKNOWN; 385 } 386 387 /** 388 * Returns the transport RTT estimate (in milliseconds) computed by the 389 * network quality estimator. Set to {@link #CONNECTION_METRIC_UNKNOWN} if 390 * the value is unavailable. This must be called after 391 * {@link Builder#enableNetworkQualityEstimator}, and will throw an 392 * exception otherwise. 393 * @return Estimate of the transport RTT in milliseconds. 394 */ getTransportRttMs()395 public int getTransportRttMs() { 396 return CONNECTION_METRIC_UNKNOWN; 397 } 398 399 /** 400 * Returns the downstream throughput estimate (in kilobits per second) 401 * computed by the network quality estimator. Set to 402 * {@link #CONNECTION_METRIC_UNKNOWN} if the value is 403 * unavailable. This must be called after 404 * {@link Builder#enableNetworkQualityEstimator}, and will 405 * throw an exception otherwise. 406 * @return Estimate of the downstream throughput in kilobits per second. 407 */ getDownstreamThroughputKbps()408 public int getDownstreamThroughputKbps() { 409 return CONNECTION_METRIC_UNKNOWN; 410 } 411 } 412