• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 org.chromium.net.impl;
5 
6 import android.annotation.SuppressLint;
7 import android.os.Build;
8 
9 import org.chromium.net.BidirectionalStream;
10 import org.chromium.net.CronetEngine;
11 import org.chromium.net.ExperimentalBidirectionalStream;
12 
13 import java.util.AbstractMap;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Map;
17 import java.util.concurrent.Executor;
18 
19 /** Implementation of {@link ExperimentalBidirectionalStream.Builder}. */
20 public class BidirectionalStreamBuilderImpl extends ExperimentalBidirectionalStream.Builder {
21     // All fields are temporary storage of ExperimentalBidirectionalStream configuration to be
22     // copied to CronetBidirectionalStream.
23 
24     // CronetEngine to create the stream.
25     private final CronetEngineBase mCronetEngine;
26     // URL to request.
27     private final String mUrl;
28     // Callback to receive progress callbacks.
29     private final BidirectionalStream.Callback mCallback;
30     // Executor on which callbacks will be invoked.
31     private final Executor mExecutor;
32     // List of request headers, stored as header field name and value pairs.
33     private final ArrayList<Map.Entry<String, String>> mRequestHeaders = new ArrayList<>();
34 
35     // HTTP method for the request. Default to POST.
36     private String mHttpMethod = "POST";
37     // Priority of the stream. Default is medium.
38     @CronetEngineBase.StreamPriority private int mPriority = STREAM_PRIORITY_MEDIUM;
39 
40     private boolean mDelayRequestHeadersUntilFirstFlush;
41 
42     // Request reporting annotations.
43     private Collection<Object> mRequestAnnotations;
44 
45     private boolean mTrafficStatsTagSet;
46     private int mTrafficStatsTag;
47     private boolean mTrafficStatsUidSet;
48     private int mTrafficStatsUid;
49     private long mNetworkHandle = CronetEngineBase.DEFAULT_NETWORK_HANDLE;
50 
51     /**
52      * Creates a builder for {@link BidirectionalStream} objects. All callbacks for
53      * generated {@code BidirectionalStream} objects will be invoked on
54      * {@code executor}. {@code executor} must not run tasks on the
55      * current thread, otherwise the networking operations may block and exceptions
56      * may be thrown at shutdown time.
57      *
58      * @param url the URL for the generated stream
59      * @param callback the {@link BidirectionalStream.Callback} object that gets invoked upon
60      * different events
61      *     occuring
62      * @param executor the {@link Executor} on which {@code callback} methods will be invoked
63      * @param cronetEngine the {@link CronetEngine} used to create the stream
64      */
BidirectionalStreamBuilderImpl( String url, BidirectionalStream.Callback callback, Executor executor, CronetEngineBase cronetEngine)65     BidirectionalStreamBuilderImpl(
66             String url,
67             BidirectionalStream.Callback callback,
68             Executor executor,
69             CronetEngineBase cronetEngine) {
70         super();
71         if (url == null) {
72             throw new NullPointerException("URL is required.");
73         }
74         if (callback == null) {
75             throw new NullPointerException("Callback is required.");
76         }
77         if (executor == null) {
78             throw new NullPointerException("Executor is required.");
79         }
80         if (cronetEngine == null) {
81             throw new NullPointerException("CronetEngine is required.");
82         }
83         mUrl = url;
84         mCallback = callback;
85         mExecutor = executor;
86         mCronetEngine = cronetEngine;
87     }
88 
89     @Override
setHttpMethod(String method)90     public BidirectionalStreamBuilderImpl setHttpMethod(String method) {
91         if (method == null) {
92             throw new NullPointerException("Method is required.");
93         }
94         mHttpMethod = method;
95         return this;
96     }
97 
98     @Override
addHeader(String header, String value)99     public BidirectionalStreamBuilderImpl addHeader(String header, String value) {
100         if (header == null) {
101             throw new NullPointerException("Invalid header name.");
102         }
103         if (value == null) {
104             throw new NullPointerException("Invalid header value.");
105         }
106         mRequestHeaders.add(new AbstractMap.SimpleImmutableEntry<>(header, value));
107         return this;
108     }
109 
110     @Override
setPriority( @ronetEngineBase.StreamPriority int priority)111     public BidirectionalStreamBuilderImpl setPriority(
112             @CronetEngineBase.StreamPriority int priority) {
113         mPriority = priority;
114         return this;
115     }
116 
117     @Override
delayRequestHeadersUntilFirstFlush( boolean delayRequestHeadersUntilFirstFlush)118     public BidirectionalStreamBuilderImpl delayRequestHeadersUntilFirstFlush(
119             boolean delayRequestHeadersUntilFirstFlush) {
120         mDelayRequestHeadersUntilFirstFlush = delayRequestHeadersUntilFirstFlush;
121         return this;
122     }
123 
124     @Override
addRequestAnnotation(Object annotation)125     public ExperimentalBidirectionalStream.Builder addRequestAnnotation(Object annotation) {
126         if (annotation == null) {
127             throw new NullPointerException("Invalid metrics annotation.");
128         }
129         if (mRequestAnnotations == null) {
130             mRequestAnnotations = new ArrayList<Object>();
131         }
132         mRequestAnnotations.add(annotation);
133         return this;
134     }
135 
136     @Override
setTrafficStatsTag(int tag)137     public ExperimentalBidirectionalStream.Builder setTrafficStatsTag(int tag) {
138         mTrafficStatsTagSet = true;
139         mTrafficStatsTag = tag;
140         return this;
141     }
142 
143     @Override
setTrafficStatsUid(int uid)144     public ExperimentalBidirectionalStream.Builder setTrafficStatsUid(int uid) {
145         mTrafficStatsUidSet = true;
146         mTrafficStatsUid = uid;
147         return this;
148     }
149 
150     @Override
bindToNetwork(long networkHandle)151     public ExperimentalBidirectionalStream.Builder bindToNetwork(long networkHandle) {
152         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
153             throw new UnsupportedOperationException(
154                     "The multi-network API is available starting from Android Marshmallow");
155         }
156         mNetworkHandle = networkHandle;
157         return this;
158     }
159 
160     @Override
161     @SuppressLint("WrongConstant") // TODO(jbudorick): Remove this after rolling to the N SDK.
build()162     public ExperimentalBidirectionalStream build() {
163         return mCronetEngine.createBidirectionalStream(
164                 mUrl,
165                 mCallback,
166                 mExecutor,
167                 mHttpMethod,
168                 mRequestHeaders,
169                 mPriority,
170                 mDelayRequestHeadersUntilFirstFlush,
171                 mRequestAnnotations,
172                 mTrafficStatsTagSet,
173                 mTrafficStatsTag,
174                 mTrafficStatsUidSet,
175                 mTrafficStatsUid,
176                 mNetworkHandle);
177     }
178 }
179