1 // Copyright 2021 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.google.android.downloader;
16 
17 import com.google.common.util.concurrent.ListenableFuture;
18 
19 /**
20  * Interface representing a request to a URL. Intended for use with a {@link UrlEngine}.
21  *
22  * <p>Note: Unless explicitly noted, instances of this object are designed to be thread-safe,
23  * meaning that methods can be called from any thread. It is however not advisable to use instances
24  * of this object as a lock, as internal logic may synchronize on the request instance. Also,
25  * methods should not be called from the Android main/UI thread, as some I/O may occur.
26  */
27 public interface UrlRequest {
28   /** Builder interface for constructing URL requests. */
29   interface Builder {
30     /** Adds an individual HTTP header for this request. */
addHeader(String key, String value)31     default Builder addHeader(String key, String value) {
32       return this;
33     }
34 
35     /** Builds the URL request. */
build()36     UrlRequest build();
37   }
38 
39   /**
40    * Executes this request by connecting to the URL represented by this request. Returns
41    * immediately, with the {@link UrlResponse} becoming available asynchronously as a {@link
42    * ListenableFuture}. May only be called once; multiple calls result in undefined behavior.
43    *
44    * <p>If the request fails due to I/O errors or due to an error response from the server (e.g.
45    * http status codes in the 400s or 500s), then the future will resolve with either an {@link
46    * RequestException} or an {@link java.io.IOException}. Any other type of exception (e.g. {@link
47    * IllegalStateException}) indicates an unexpected error occurred, and such errors should likely
48    * be reported at a severe level and possibly even crash the app.
49    *
50    * <p>To cancel an executed requested, call {@link ListenableFuture#cancel} on the future returned
51    * by this method. Cancellation is opportunistic and best-effort; calling will not guarantee that
52    * no more network activity will occur, as it is not possible to immediately stop a thread that is
53    * transferring bytes from the network. Cancellation may fail internally; observe the resolution
54    * of the future to capture such failures.
55    *
56    * <p>Note that although this method returns its result asynchronously and doesn't block on the
57    * request, the operation may still involve performing some I/O (e.g. verifying the existence of a
58    * file). Do not call this on the UI thread!
59    */
send()60   ListenableFuture<UrlResponse> send();
61 }
62