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.auto.value.AutoValue;
18 import com.google.common.annotations.VisibleForTesting;
19 import com.google.common.collect.ImmutableMultimap;
20 import java.net.URI;
21 import javax.annotation.Nullable;
22 
23 /**
24  * Buildable value class used to construct and represent an individual download request. Instances
25  * are created via {@link Builder}, which in turn can be obtained via {@link
26  * Downloader2#newRequestBuilder}. Requests are executed via {@link Downloader2#execute}.
27  */
28 @AutoValue
29 public abstract class DownloadRequest {
uri()30   public abstract URI uri();
31 
headers()32   public abstract ImmutableMultimap<String, String> headers();
33 
downloadConstraints()34   public abstract DownloadConstraints downloadConstraints();
35 
oAuthTokenProvider()36   public abstract @Nullable OAuthTokenProvider oAuthTokenProvider();
37 
destination()38   public abstract DownloadDestination destination();
39 
40   @VisibleForTesting // Package-private outside of testing use
newBuilder()41   public static Builder newBuilder() {
42     return new AutoValue_DownloadRequest.Builder();
43   }
44 
45   /** Builder facility for constructing instances of an {@link DownloadRequest}. */
46   @AutoValue.Builder
47   public abstract static class Builder {
48     /** Sets the {@link DownloadDestination} that the download result should be sent to. */
setDestination(DownloadDestination destination)49     public abstract Builder setDestination(DownloadDestination destination);
50 
51     /**
52      * Sets the {@link URI} to download from. The URI scheme returned by {@link URI#getScheme} must
53      * be supported by one of the {@link com.google.android.libraries.net.urlengine.UrlEngine}
54      * instances attached to the downloader.
55      */
setUri(URI uri)56     public abstract Builder setUri(URI uri);
57 
58     /**
59      * Sets the URL to download from. This must be a valid URL string per RFC 2396; invalid strings
60      * will result in an {@link IllegalArgumentException} to be thrown from this method.
61      *
62      * <p>Internally this has the same effect as calling {@code setUri(URI.create(string))}, and
63      * exists here as a convenience method.
64      */
setUrl(String url)65     public Builder setUrl(String url) {
66       return setUri(URI.create(url));
67     }
68 
headersBuilder()69     abstract ImmutableMultimap.Builder<String, String> headersBuilder();
70 
71     /**
72      * Adds a request header to be sent as part of this request. Request headers are only used in
73      * {@link com.google.android.libraries.net.urlengine.UrlEngine} instances where they make sense
74      * (e.g. headers are attached to HTTP requests but ignored for Data URIs).
75      */
addHeader(String key, String value)76     public Builder addHeader(String key, String value) {
77       headersBuilder().put(key, value);
78       return this;
79     }
80 
81     /**
82      * Specifies the {@link com.google.android.libraries.net.downloader2.DownloadConstraints} for
83      * this request.
84      *
85      * <p>Note that the checking the download constraints for a request only occurs right before the
86      * request is executed, including cases where the request is retried due to a network error.
87      *
88      * <p>The ability to detect changes in connectivity depends on the underlying implementation of
89      * the {@link com.google.android.libraries.net.urlengine.UrlEngine} that processes this request.
90      * Some network stacks may be able to switch network types without interrupting the connection
91      * (e.g. seamless hand-off between WiFI and Cellular). The downloader relies on an interrupted
92      * connection to detect network changes, so in those cases the download may silently continue on
93      * the changed network.
94      *
95      * <p>The default value is {@link
96      * com.google.android.libraries.net.downloader2.DownloadConstraints#NETWORK_CONNECTED}.
97      */
setDownloadConstraints(DownloadConstraints downloadConstraints)98     public abstract Builder setDownloadConstraints(DownloadConstraints downloadConstraints);
99 
100     /**
101      * Sets an optional {@link OAuthTokenProvider} on the request. When set, the downloader will
102      * consult the OAuthTokenProvider on this request and use it to attach "Authorization" headers
103      * to outgoing HTTP requests.
104      */
setOAuthTokenProvider( @ullable OAuthTokenProvider oAuthTokenProvider)105     public abstract Builder setOAuthTokenProvider(
106         @Nullable OAuthTokenProvider oAuthTokenProvider);
107 
build()108     public abstract DownloadRequest build();
109   }
110 }
111