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

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: More tests, more comments, more cancel. Created 6 years, 2 months 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);
49 }
50
51 void OnRedirect(CronetURLRequestAdapter* request_adapter,
52 const GURL& new_location) override {
53 JNIEnv* jenv = base::android::AttachCurrentThread();
54 cronet::Java_CronetUrlRequest_onRedirect(
55 jenv,
56 owner_.obj(),
57 ConvertUTF8ToJavaString(jenv, new_location.spec()).Release());
58 }
59
60 void OnResponseStarted(CronetURLRequestAdapter* request_adapter) override {
61 JNIEnv* jenv = base::android::AttachCurrentThread();
62 cronet::Java_CronetUrlRequest_onResponseStarted(jenv, owner_.obj());
63 }
64
65 void OnBytesRead(CronetURLRequestAdapter* request_adapter,
66 int bytes_read) override {
67 JNIEnv* jenv = base::android::AttachCurrentThread();
68 base::android::ScopedJavaLocalRef<jobject> java_buffer(
69 jenv, jenv->NewDirectByteBuffer(request_adapter->Data(), bytes_read));
mmenke 2014/10/23 16:26:00 I think it makes more sense to pass in data, in ad
mef 2014/10/24 03:31:42 Done.
70 cronet::Java_CronetUrlRequest_onDataReceived(
71 jenv, owner_.obj(), java_buffer.obj());
72 }
73
74 void OnRequestCanceled(CronetURLRequestAdapter* request_adapter) override {
xunjieli 2014/10/22 21:02:16 unused request_adapter.
mef 2014/10/24 03:31:42 Done.
75 JNIEnv* jenv = base::android::AttachCurrentThread();
76 cronet::Java_CronetUrlRequest_onCanceled(jenv, owner_.obj());
77 }
78
79 void OnRequestFinished(CronetURLRequestAdapter* request_adapter) override {
xunjieli 2014/10/22 21:02:16 unused request_adapter
mef 2014/10/24 03:31:42 Done.
80 JNIEnv* jenv = base::android::AttachCurrentThread();
81 cronet::Java_CronetUrlRequest_onComplete(jenv, owner_.obj());
82 }
83
84 void OnError(CronetURLRequestAdapter* request_adapter, int error) override {
xunjieli 2014/10/22 21:02:16 unused request_adapter.
mef 2014/10/24 03:31:42 Done.
85 JNIEnv* jenv = base::android::AttachCurrentThread();
86 cronet::Java_CronetUrlRequest_onError(
87 jenv,
88 owner_.obj(),
89 error,
90 ConvertUTF8ToJavaString(jenv, net::ErrorToString(error)).Release());
91 }
92
93 protected:
94 virtual ~JniCronetURLRequestAdapterDelegate() {
95 }
96
97 private:
98 base::android::ScopedJavaGlobalRef<jobject> owner_;
99
100 DISALLOW_COPY_AND_ASSIGN(JniCronetURLRequestAdapterDelegate);
101 };
102
103 } // namespace
104
105 // Explicitly register static JNI functions.
106 bool CronetUrlRequestRegisterJni(JNIEnv* jenv) {
107 return RegisterNativesImpl(jenv);
108 }
109
110 static jlong CreateRequestAdapter(JNIEnv* jenv,
111 jobject jurl_request,
112 jlong jurl_request_context_adapter,
113 jstring jurl_string,
114 jint jpriority) {
115 CronetURLRequestContextAdapter* context_adapter =
116 reinterpret_cast<CronetURLRequestContextAdapter*>(
117 jurl_request_context_adapter);
118 DCHECK(context_adapter != nullptr);
119
120 GURL url(base::android::ConvertJavaStringToUTF8(jenv, jurl_string));
121
122 VLOG(1) << "New chromium network request_adapter: "
123 << url.possibly_invalid_spec();
124
125 CronetURLRequestAdapter* adapter = new CronetURLRequestAdapter(
126 context_adapter,
127 new JniCronetURLRequestAdapterDelegate(jenv, jurl_request),
128 url,
129 ConvertRequestPriority(jpriority));
mmenke 2014/10/23 16:26:00 I think the ownership story here is a little weird
mef 2014/10/24 03:31:42 Acknowledged.
130
131 return reinterpret_cast<jlong>(adapter);
132 }
133
134 static jboolean AddHeader(JNIEnv* jenv,
135 jobject jurl_request,
136 jlong jurl_request_adapter,
137 jstring jname,
138 jstring jvalue) {
139 CronetURLRequestAdapter* request_adapter =
140 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
141 std::string name(base::android::ConvertJavaStringToUTF8(jenv, jname));
142 std::string value(base::android::ConvertJavaStringToUTF8(jenv, jvalue));
143 DCHECK(request_adapter);
144 DCHECK(!request_adapter->IsOnNetworkThread());
145 if (!net::HttpUtil::IsValidHeaderName(name) ||
146 !net::HttpUtil::IsValidHeaderValue(value)) {
147 return false;
148 }
149 request_adapter->AddRequestHeader(name, value);
150 return true;
151 }
152
153 static void SetHttpMethod(JNIEnv* jenv,
154 jobject jurl_request,
155 jlong jurl_request_adapter,
156 jstring jmethod) {
157 CronetURLRequestAdapter* request_adapter =
158 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
159 std::string method(base::android::ConvertJavaStringToUTF8(jenv, jmethod));
160 DCHECK(request_adapter);
161 DCHECK(!request_adapter->IsOnNetworkThread());
162 request_adapter->SetMethod(method);
163 }
164
165 static void Start(JNIEnv* jenv,
166 jobject jurl_request,
167 jlong jurl_request_adapter) {
168 CronetURLRequestAdapter* request_adapter =
169 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
170 DCHECK(request_adapter);
171 DCHECK(!request_adapter->IsOnNetworkThread());
172 request_adapter->Start();
173 }
174
175 static void DestroyRequestAdapter(JNIEnv* jenv,
176 jobject jurl_request,
177 jlong jurl_request_adapter) {
178 CronetURLRequestAdapter* request_adapter =
179 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
180 DCHECK(request_adapter);
181 DCHECK(!request_adapter->IsOnNetworkThread());
182 request_adapter->Destroy();
183 }
184
185 static void Cancel(JNIEnv* jenv,
186 jobject jurl_request,
187 jlong jurl_request_adapter) {
188 CronetURLRequestAdapter* request_adapter =
189 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
190 DCHECK(request_adapter);
191 DCHECK(!request_adapter->IsOnNetworkThread());
192 request_adapter->Cancel();
193 }
194
195 static void ReceiveData(JNIEnv* jenv,
196 jobject jcaller,
197 jlong jurl_request_adapter) {
198 CronetURLRequestAdapter* request_adapter =
199 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
200 DCHECK(request_adapter);
201 DCHECK(!request_adapter->IsOnNetworkThread());
202 request_adapter->ReadData();
203 }
204
205 static void FollowDeferredRedirect(JNIEnv* jenv,
206 jobject jcaller,
207 jlong jurl_request_adapter) {
208 CronetURLRequestAdapter* request_adapter =
209 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
210 DCHECK(request_adapter);
211 DCHECK(!request_adapter->IsOnNetworkThread());
212 request_adapter->FollowDeferredRedirect();
213 }
214
215 static jint GetHttpStatusCode(JNIEnv* jenv,
216 jobject jurl_request,
217 jlong jurl_request_adapter) {
218 CronetURLRequestAdapter* request_adapter =
219 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
220 DCHECK(request_adapter);
221 DCHECK(request_adapter->IsOnNetworkThread());
222 return request_adapter->http_status_code();
223 }
224
225 static void PopulateResponseHeaders(JNIEnv* jenv,
226 jobject jurl_request,
227 jlong jurl_request_adapter,
228 jobject jheaders_map) {
229 CronetURLRequestAdapter* request_adapter =
230 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
231 DCHECK(request_adapter);
232 DCHECK(request_adapter->IsOnNetworkThread());
233
234 net::HttpResponseHeaders* headers = request_adapter->GetResponseHeaders();
235 if (headers == nullptr)
236 return;
237
238 void* iter = nullptr;
239 std::string header_name;
240 std::string header_value;
241 while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
242 ScopedJavaLocalRef<jstring> name =
243 ConvertUTF8ToJavaString(jenv, header_name);
244 ScopedJavaLocalRef<jstring> value =
245 ConvertUTF8ToJavaString(jenv, header_value);
246 Java_CronetUrlRequest_onAppendResponseHeader(
247 jenv, jurl_request, jheaders_map, name.Release(), value.Release());
248 }
249
250 // Some implementations (notably HttpURLConnection) include a mapping for the
251 // null key; in HTTP's case, this maps to the HTTP status line.
252 ScopedJavaLocalRef<jstring> status_line =
253 ConvertUTF8ToJavaString(jenv, headers->GetStatusLine());
254 Java_CronetUrlRequest_onAppendResponseHeader(
255 jenv, jurl_request, jheaders_map, nullptr, status_line.Release());
256 }
257
258 static jstring GetNegotiatedProtocol(JNIEnv* jenv,
259 jobject jurl_request,
260 jlong jurl_request_adapter) {
261 CronetURLRequestAdapter* request_adapter =
262 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
263 DCHECK(request_adapter);
264 DCHECK(request_adapter->IsOnNetworkThread());
265 std::string negotiated_protocol = request_adapter->GetNegotiatedProtocol();
266 return ConvertUTF8ToJavaString(jenv, negotiated_protocol.c_str()).Release();
mmenke 2014/10/23 16:26:00 I don't think c_str() is really needed here.
mef 2014/10/24 03:31:42 Done.
267 }
268
269 static jboolean GetWasCached(JNIEnv* jenv,
270 jobject jurl_request,
271 jlong jurl_request_adapter) {
272 CronetURLRequestAdapter* request_adapter =
273 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
274 DCHECK(request_adapter);
275 DCHECK(request_adapter->IsOnNetworkThread());
276 return request_adapter->GetWasCached() ? JNI_TRUE : JNI_FALSE;
277 }
278
279 static jlong GetTotalReceivedBytes(JNIEnv* jenv,
280 jobject jurl_request,
281 jlong jurl_request_adapter) {
282 CronetURLRequestAdapter* request_adapter =
283 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
284 DCHECK(request_adapter);
285 DCHECK(request_adapter->IsOnNetworkThread());
286 return request_adapter->GetTotalReceivedBytes();
287 }
288
289 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698