Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: components/cronet/android/cronet_url_request.cc

Issue 586143002: Initial implementation of Cronet Async API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments, add more shutdown tests. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/cronet/android/cronet_url_request.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/scoped_java_ref.h"
10 #include "base/logging.h"
11 #include "base/macros.h"
12 #include "components/cronet/android/cronet_url_request_adapter.h"
13 #include "components/cronet/android/cronet_url_request_context_adapter.h"
14 #include "jni/CronetUrlRequest_jni.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/request_priority.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/http/http_util.h"
19
20 using base::android::ConvertUTF8ToJavaString;
21
22 namespace cronet {
23 namespace {
24
25 net::RequestPriority ConvertRequestPriority(jint request_priority) {
26 switch (request_priority) {
27 case CRONET_REQUEST_PRIORITY_IDLE:
28 return net::IDLE;
29 case CRONET_REQUEST_PRIORITY_LOWEST:
30 return net::LOWEST;
31 case CRONET_REQUEST_PRIORITY_LOW:
32 return net::LOW;
33 case CRONET_REQUEST_PRIORITY_MEDIUM:
34 return net::MEDIUM;
35 case CRONET_REQUEST_PRIORITY_HIGHEST:
36 return net::HIGHEST;
37 default:
38 return net::LOWEST;
39 }
40 }
41
42 // A delegate of CronetURLRequestAdapter that delivers callbacks to the Java
43 // layer. Always called on Network Thread.
44 class JniCronetURLRequestAdapterDelegate
45 : public CronetURLRequestAdapter::CronetURLRequestAdapterDelegate {
46 public:
47 JniCronetURLRequestAdapterDelegate(JNIEnv* jenv, jobject jowner) {
48 owner_.Reset(jenv, jowner);
mmenke 2014/10/31 19:16:22 Can put owner_(jowner) in the initialized list ins
mef 2014/10/31 20:39:14 Hmm, I get weird build errors. How do I express th
mmenke 2014/10/31 21:03:24 Oops...doesn't work. Only works with other Scoped
49 }
50
51 void OnRedirect(const GURL& new_location, int http_status_code) override {
52 JNIEnv* jenv = base::android::AttachCurrentThread();
53 cronet::Java_CronetUrlRequest_onRedirect(
54 jenv,
55 owner_.obj(),
56 ConvertUTF8ToJavaString(jenv, new_location.spec()).Release(),
57 http_status_code);
58 }
59
60 void OnResponseStarted(int http_status_code) override {
61 JNIEnv* jenv = base::android::AttachCurrentThread();
62 cronet::Java_CronetUrlRequest_onResponseStarted(jenv, owner_.obj(),
63 http_status_code);
64 }
65
66 void OnBytesRead(unsigned char* bytes_buffer,
67 int bytes_read) override {
68 JNIEnv* jenv = base::android::AttachCurrentThread();
69 base::android::ScopedJavaLocalRef<jobject> java_buffer(
70 jenv, jenv->NewDirectByteBuffer(bytes_buffer, bytes_read));
71 cronet::Java_CronetUrlRequest_onDataReceived(
72 jenv, owner_.obj(), java_buffer.obj());
73 }
74
75 void OnRequestFinished() override {
76 JNIEnv* jenv = base::android::AttachCurrentThread();
77 cronet::Java_CronetUrlRequest_onComplete(jenv, owner_.obj());
78 }
79
80 void OnError(int error) override {
mmenke 2014/10/31 19:16:22 Suggest calling this net_error (And in CronetURLRe
mef 2014/10/31 20:39:14 Done.
81 JNIEnv* jenv = base::android::AttachCurrentThread();
82 cronet::Java_CronetUrlRequest_onError(
83 jenv,
84 owner_.obj(),
85 error,
86 ConvertUTF8ToJavaString(jenv, net::ErrorToString(error)).Release());
87 }
88
89 protected:
90 virtual ~JniCronetURLRequestAdapterDelegate() {
mmenke 2014/10/31 19:16:22 -virtual +override
mef 2014/10/31 20:39:14 Done.
91 }
92
93 private:
94 base::android::ScopedJavaGlobalRef<jobject> owner_;
mmenke 2014/10/31 19:16:22 Should this be jowner_? I'm not sure, myself.
mef 2014/10/31 20:39:14 My understanding is that jxyz naming applies to pa
95
96 DISALLOW_COPY_AND_ASSIGN(JniCronetURLRequestAdapterDelegate);
97 };
98
99 } // namespace
100
101 // Explicitly register static JNI functions.
102 bool CronetUrlRequestRegisterJni(JNIEnv* jenv) {
103 return RegisterNativesImpl(jenv);
104 }
105
106 static jlong CreateRequestAdapter(JNIEnv* jenv,
107 jobject jurl_request,
108 jlong jurl_request_context_adapter,
109 jstring jurl_string,
110 jint jpriority) {
111 CronetURLRequestContextAdapter* context_adapter =
112 reinterpret_cast<CronetURLRequestContextAdapter*>(
113 jurl_request_context_adapter);
114 DCHECK(context_adapter);
115
116 GURL url(base::android::ConvertJavaStringToUTF8(jenv, jurl_string));
117
118 VLOG(1) << "New chromium network request_adapter: "
119 << url.possibly_invalid_spec();
120
121 CronetURLRequestAdapter* adapter = new CronetURLRequestAdapter(
122 context_adapter,
123 new JniCronetURLRequestAdapterDelegate(jenv, jurl_request),
124 url,
125 ConvertRequestPriority(jpriority));
126
127 return reinterpret_cast<jlong>(adapter);
128 }
129
130 static jboolean AddHeader(JNIEnv* jenv,
131 jobject jurl_request,
132 jlong jurl_request_adapter,
133 jstring jname,
134 jstring jvalue) {
135 if (!jurl_request_adapter)
136 return JNI_FALSE;
137 CronetURLRequestAdapter* request_adapter =
138 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
139 std::string name(base::android::ConvertJavaStringToUTF8(jenv, jname));
140 std::string value(base::android::ConvertJavaStringToUTF8(jenv, jvalue));
141 DCHECK(!request_adapter->IsOnNetworkThread());
142 if (!net::HttpUtil::IsValidHeaderName(name) ||
143 !net::HttpUtil::IsValidHeaderValue(value)) {
144 return JNI_FALSE;
145 }
146 request_adapter->AddRequestHeader(name, value);
147 return JNI_TRUE;
148 }
149
150 static jboolean SetHttpMethod(JNIEnv* jenv,
151 jobject jurl_request,
152 jlong jurl_request_adapter,
153 jstring jmethod) {
mmenke 2014/10/31 19:16:22 Fix indent
mef 2014/10/31 20:39:14 Done.
154 if (!jurl_request_adapter)
155 return JNI_FALSE;
156 CronetURLRequestAdapter* request_adapter =
157 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
158 std::string method(base::android::ConvertJavaStringToUTF8(jenv, jmethod));
159 DCHECK(!request_adapter->IsOnNetworkThread());
160 // Http Method is a token, just as Header name.
mmenke 2014/10/31 19:16:22 nit: Method -> method.
mef 2014/10/31 20:39:14 Done.
161 if (!net::HttpUtil::IsValidHeaderName(method))
162 return JNI_FALSE;
163 request_adapter->SetMethod(method);
164 return JNI_TRUE;
165 }
166
167 static void Start(JNIEnv* jenv,
168 jobject jurl_request,
169 jlong jurl_request_adapter) {
170 if (!jurl_request_adapter)
171 return;
172 CronetURLRequestAdapter* request_adapter =
173 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
174 DCHECK(!request_adapter->IsOnNetworkThread());
175 request_adapter->Start();
176 }
177
178 static void DestroyRequestAdapter(JNIEnv* jenv,
179 jobject jurl_request,
180 jlong jurl_request_adapter) {
181 if (!jurl_request_adapter)
182 return;
183 CronetURLRequestAdapter* request_adapter =
184 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
185 DCHECK(!request_adapter->IsOnNetworkThread());
186 request_adapter->Destroy();
187 }
188
189 static void ReceiveData(JNIEnv* jenv,
190 jobject jcaller,
191 jlong jurl_request_adapter) {
192 if (!jurl_request_adapter)
193 return;
194 CronetURLRequestAdapter* request_adapter =
195 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
196 DCHECK(!request_adapter->IsOnNetworkThread());
197 request_adapter->ReadData();
198 }
199
200 static void FollowDeferredRedirect(JNIEnv* jenv,
201 jobject jcaller,
202 jlong jurl_request_adapter) {
203 if (!jurl_request_adapter)
204 return;
205 CronetURLRequestAdapter* request_adapter =
206 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
207 DCHECK(!request_adapter->IsOnNetworkThread());
208 request_adapter->FollowDeferredRedirect();
209 }
210
211 static void PopulateResponseHeaders(JNIEnv* jenv,
212 jobject jurl_request,
213 jlong jurl_request_adapter,
214 jobject jheaders_map) {
215 if (!jurl_request_adapter)
216 return;
217 CronetURLRequestAdapter* request_adapter =
218 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
219 DCHECK(request_adapter);
220 DCHECK(request_adapter->IsOnNetworkThread());
221
222 net::HttpResponseHeaders* headers = request_adapter->GetResponseHeaders();
223 if (headers == nullptr)
224 return;
225
226 void* iter = nullptr;
227 std::string header_name;
228 std::string header_value;
229 while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
230 ScopedJavaLocalRef<jstring> name =
231 ConvertUTF8ToJavaString(jenv, header_name);
232 ScopedJavaLocalRef<jstring> value =
233 ConvertUTF8ToJavaString(jenv, header_value);
234 Java_CronetUrlRequest_onAppendResponseHeader(
235 jenv, jurl_request, jheaders_map, name.Release(), value.Release());
236 }
237
238 // Some implementations (notably HttpURLConnection) include a mapping for the
239 // null key; in HTTP's case, this maps to the HTTP status line.
240 ScopedJavaLocalRef<jstring> status_line =
241 ConvertUTF8ToJavaString(jenv, headers->GetStatusLine());
242 Java_CronetUrlRequest_onAppendResponseHeader(
243 jenv, jurl_request, jheaders_map, nullptr, status_line.Release());
244 }
245
246 static jstring GetNegotiatedProtocol(JNIEnv* jenv,
247 jobject jurl_request,
248 jlong jurl_request_adapter) {
249 if (!jurl_request_adapter)
250 return ConvertUTF8ToJavaString(jenv, std::string()).Release();
251 CronetURLRequestAdapter* request_adapter =
252 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
253 DCHECK(request_adapter->IsOnNetworkThread());
254 std::string negotiated_protocol = request_adapter->GetNegotiatedProtocol();
255 return ConvertUTF8ToJavaString(jenv, negotiated_protocol).Release();
256 }
257
258 static jboolean GetWasCached(JNIEnv* jenv,
259 jobject jurl_request,
260 jlong jurl_request_adapter) {
261 if (!jurl_request_adapter)
262 return JNI_FALSE;
263 CronetURLRequestAdapter* request_adapter =
264 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
265 DCHECK(request_adapter->IsOnNetworkThread());
266 return request_adapter->GetWasCached() ? JNI_TRUE : JNI_FALSE;
267 }
268
269 static jlong GetTotalReceivedBytes(JNIEnv* jenv,
270 jobject jurl_request,
271 jlong jurl_request_adapter) {
272 if (!jurl_request_adapter)
273 return 0;
274 CronetURLRequestAdapter* request_adapter =
275 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
276 DCHECK(request_adapter->IsOnNetworkThread());
277 return request_adapter->GetTotalReceivedBytes();
278 }
279
280 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698