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

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: UPPERCASE enum names. 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.
mmenke 2014/11/03 20:21:16 nit: on -> on the
mef 2014/11/03 21:23:37 Done.
44 class JniCronetURLRequestAdapterDelegate
45 : public CronetURLRequestAdapter::CronetURLRequestAdapterDelegate {
46 public:
47 JniCronetURLRequestAdapterDelegate(JNIEnv* jenv, jobject jowner) {
mmenke 2014/11/03 20:21:16 I don't believe this should actually be j prefixed
mef 2014/11/03 21:23:37 Done.
48 owner_.Reset(jenv, jowner);
49 }
50
51 void OnRedirect(const GURL& new_location, int http_status_code) override {
52 JNIEnv* jenv = base::android::AttachCurrentThread();
mmenke 2014/11/03 20:21:16 env is the name pretty much always used for JNIEnv
mef 2014/11/03 21:23:37 Done.
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);
mmenke 2014/11/03 20:21:16 Fix indent
mef 2014/11/03 21:23:37 Done.
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 net_error) override {
81 JNIEnv* jenv = base::android::AttachCurrentThread();
82 cronet::Java_CronetUrlRequest_onError(
83 jenv,
84 owner_.obj(),
85 net_error,
86 ConvertUTF8ToJavaString(jenv, net::ErrorToString(net_error)).Release());
87 }
88
89 protected:
mmenke 2014/11/03 20:21:16 Since nothing subclasses this class, this method s
mef 2014/11/03 21:23:37 Done.
90 ~JniCronetURLRequestAdapterDelegate() override {
91 }
92
93 private:
94 base::android::ScopedJavaGlobalRef<jobject> owner_;
mmenke 2014/11/03 20:21:16 This isn't quite accurately named (And again, I th
mef 2014/11/03 21:23:37 Done.
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,
mmenke 2014/11/03 20:21:16 These, too, always use env. Looking over existing
xunjieli 2014/11/03 20:27:49 I still feel that using j prefix will potentially
mef 2014/11/03 21:23:38 I don't have strong preference, but I guess 'comin
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 scoped_ptr<CronetURLRequestAdapter::CronetURLRequestAdapterDelegate> delegate(
122 new JniCronetURLRequestAdapterDelegate(jenv, jurl_request));
123
124 CronetURLRequestAdapter* adapter = new CronetURLRequestAdapter(
125 context_adapter,
126 delegate.Pass(),
127 url,
128 ConvertRequestPriority(jpriority));
129
130 return reinterpret_cast<jlong>(adapter);
131 }
132
133 static jboolean AddHeader(JNIEnv* jenv,
134 jobject jurl_request,
135 jlong jurl_request_adapter,
136 jstring jname,
137 jstring jvalue) {
138 if (!jurl_request_adapter)
mmenke 2014/11/03 20:21:16 This can't happen. Fine to DCHECK on it.
mef 2014/11/03 21:23:37 Done.
139 return JNI_FALSE;
140 CronetURLRequestAdapter* request_adapter =
141 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
142 std::string name(base::android::ConvertJavaStringToUTF8(jenv, jname));
143 std::string value(base::android::ConvertJavaStringToUTF8(jenv, jvalue));
144 DCHECK(!request_adapter->IsOnNetworkThread());
mmenke 2014/11/03 20:21:16 DCHECKs on input state should generally go first.
mef 2014/11/03 21:23:37 Done.
145 if (!net::HttpUtil::IsValidHeaderName(name) ||
146 !net::HttpUtil::IsValidHeaderValue(value)) {
147 return JNI_FALSE;
148 }
149 request_adapter->AddRequestHeader(name, value);
150 return JNI_TRUE;
151 }
152
153 static jboolean SetHttpMethod(JNIEnv* jenv,
154 jobject jurl_request,
155 jlong jurl_request_adapter,
156 jstring jmethod) {
157 if (!jurl_request_adapter)
158 return JNI_FALSE;
mmenke 2014/11/03 20:21:16 This can't happen. Fine to DCHECK on it. This go
mef 2014/11/03 21:23:38 Done.
159 CronetURLRequestAdapter* request_adapter =
160 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
161 std::string method(base::android::ConvertJavaStringToUTF8(jenv, jmethod));
162 DCHECK(!request_adapter->IsOnNetworkThread());
mmenke 2014/11/03 20:21:16 DCHECKs should go first, when they can. Goes for
mef 2014/11/03 21:23:38 Done.
163 // Http method is a token, just as header name.
164 if (!net::HttpUtil::IsValidHeaderName(method))
165 return JNI_FALSE;
166 request_adapter->set_method(method);
167 return JNI_TRUE;
168 }
169
170 static void Start(JNIEnv* jenv,
171 jobject jurl_request,
172 jlong jurl_request_adapter) {
173 if (!jurl_request_adapter)
174 return;
175 CronetURLRequestAdapter* request_adapter =
176 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
177 DCHECK(!request_adapter->IsOnNetworkThread());
178 request_adapter->Start();
179 }
180
181 static void DestroyRequestAdapter(JNIEnv* jenv,
182 jobject jurl_request,
183 jlong jurl_request_adapter) {
184 if (!jurl_request_adapter)
185 return;
186 CronetURLRequestAdapter* request_adapter =
187 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
188 DCHECK(!request_adapter->IsOnNetworkThread());
189 request_adapter->Destroy();
190 }
191
192 static void ReceiveData(JNIEnv* jenv,
193 jobject jcaller,
194 jlong jurl_request_adapter) {
195 if (!jurl_request_adapter)
196 return;
197 CronetURLRequestAdapter* request_adapter =
198 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
199 DCHECK(!request_adapter->IsOnNetworkThread());
200 request_adapter->ReadData();
201 }
202
203 static void FollowDeferredRedirect(JNIEnv* jenv,
204 jobject jcaller,
205 jlong jurl_request_adapter) {
206 if (!jurl_request_adapter)
207 return;
208 CronetURLRequestAdapter* request_adapter =
209 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
210 DCHECK(!request_adapter->IsOnNetworkThread());
211 request_adapter->FollowDeferredRedirect();
212 }
213
214 static void PopulateResponseHeaders(JNIEnv* jenv,
215 jobject jurl_request,
216 jlong jurl_request_adapter,
217 jobject jheaders_map) {
218 if (!jurl_request_adapter)
219 return;
220 CronetURLRequestAdapter* request_adapter =
221 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
222 DCHECK(request_adapter);
223 DCHECK(request_adapter->IsOnNetworkThread());
224
225 net::HttpResponseHeaders* headers = request_adapter->GetResponseHeaders();
226 if (headers == nullptr)
227 return;
228
229 void* iter = nullptr;
230 std::string header_name;
231 std::string header_value;
232 while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
233 ScopedJavaLocalRef<jstring> name =
234 ConvertUTF8ToJavaString(jenv, header_name);
235 ScopedJavaLocalRef<jstring> value =
236 ConvertUTF8ToJavaString(jenv, header_value);
237 Java_CronetUrlRequest_onAppendResponseHeader(
238 jenv, jurl_request, jheaders_map, name.Release(), value.Release());
239 }
240
241 // Some implementations (notably HttpURLConnection) include a mapping for the
242 // null key; in HTTP's case, this maps to the HTTP status line.
243 ScopedJavaLocalRef<jstring> status_line =
244 ConvertUTF8ToJavaString(jenv, headers->GetStatusLine());
245 Java_CronetUrlRequest_onAppendResponseHeader(
246 jenv, jurl_request, jheaders_map, nullptr, status_line.Release());
247 }
248
249 static jstring GetNegotiatedProtocol(JNIEnv* jenv,
250 jobject jurl_request,
251 jlong jurl_request_adapter) {
252 if (!jurl_request_adapter)
253 return ConvertUTF8ToJavaString(jenv, std::string()).Release();
254 CronetURLRequestAdapter* request_adapter =
255 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
256 DCHECK(request_adapter->IsOnNetworkThread());
257 std::string negotiated_protocol = request_adapter->GetNegotiatedProtocol();
258 return ConvertUTF8ToJavaString(jenv, negotiated_protocol).Release();
259 }
260
261 static jboolean GetWasCached(JNIEnv* jenv,
262 jobject jurl_request,
263 jlong jurl_request_adapter) {
264 if (!jurl_request_adapter)
265 return JNI_FALSE;
266 CronetURLRequestAdapter* request_adapter =
267 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
268 DCHECK(request_adapter->IsOnNetworkThread());
269 return request_adapter->GetWasCached() ? JNI_TRUE : JNI_FALSE;
270 }
271
272 static jlong GetTotalReceivedBytes(JNIEnv* jenv,
273 jobject jurl_request,
274 jlong jurl_request_adapter) {
275 if (!jurl_request_adapter)
276 return 0;
277 CronetURLRequestAdapter* request_adapter =
278 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
279 DCHECK(request_adapter->IsOnNetworkThread());
280 return request_adapter->GetTotalReceivedBytes();
281 }
282
283 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698