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: Address Helen's comments, add CronetUrlRequestContextTest. 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);
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 {
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() {
91 }
92
93 private:
94 base::android::ScopedJavaGlobalRef<jobject> owner_;
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 void SetHttpMethod(JNIEnv* jenv,
151 jobject jurl_request,
152 jlong jurl_request_adapter,
153 jstring jmethod) {
154 if (!jurl_request_adapter)
155 return;
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 request_adapter->SetMethod(method);
161 }
162
163 static void Start(JNIEnv* jenv,
164 jobject jurl_request,
165 jlong jurl_request_adapter) {
166 if (!jurl_request_adapter)
167 return;
168 CronetURLRequestAdapter* request_adapter =
169 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
170 DCHECK(!request_adapter->IsOnNetworkThread());
171 request_adapter->Start();
172 }
173
174 static void DestroyRequestAdapter(JNIEnv* jenv,
175 jobject jurl_request,
176 jlong jurl_request_adapter) {
177 if (!jurl_request_adapter)
178 return;
179 CronetURLRequestAdapter* request_adapter =
180 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
181 DCHECK(!request_adapter->IsOnNetworkThread());
182 request_adapter->Destroy();
183 }
184
185 static void ReceiveData(JNIEnv* jenv,
186 jobject jcaller,
187 jlong jurl_request_adapter) {
188 if (!jurl_request_adapter)
189 return;
190 CronetURLRequestAdapter* request_adapter =
191 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
192 DCHECK(!request_adapter->IsOnNetworkThread());
193 request_adapter->ReadData();
194 }
195
196 static void FollowDeferredRedirect(JNIEnv* jenv,
197 jobject jcaller,
198 jlong jurl_request_adapter) {
199 if (!jurl_request_adapter)
200 return;
201 CronetURLRequestAdapter* request_adapter =
202 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
203 DCHECK(!request_adapter->IsOnNetworkThread());
204 request_adapter->FollowDeferredRedirect();
205 }
206
207 static void PopulateResponseHeaders(JNIEnv* jenv,
208 jobject jurl_request,
209 jlong jurl_request_adapter,
210 jobject jheaders_map) {
211 if (!jurl_request_adapter)
212 return;
213 CronetURLRequestAdapter* request_adapter =
214 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
215 DCHECK(request_adapter);
216 DCHECK(request_adapter->IsOnNetworkThread());
217
218 net::HttpResponseHeaders* headers = request_adapter->GetResponseHeaders();
219 if (headers == nullptr)
220 return;
221
222 void* iter = nullptr;
223 std::string header_name;
224 std::string header_value;
225 while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
226 ScopedJavaLocalRef<jstring> name =
227 ConvertUTF8ToJavaString(jenv, header_name);
228 ScopedJavaLocalRef<jstring> value =
229 ConvertUTF8ToJavaString(jenv, header_value);
230 Java_CronetUrlRequest_onAppendResponseHeader(
231 jenv, jurl_request, jheaders_map, name.Release(), value.Release());
232 }
233
234 // Some implementations (notably HttpURLConnection) include a mapping for the
235 // null key; in HTTP's case, this maps to the HTTP status line.
236 ScopedJavaLocalRef<jstring> status_line =
237 ConvertUTF8ToJavaString(jenv, headers->GetStatusLine());
238 Java_CronetUrlRequest_onAppendResponseHeader(
239 jenv, jurl_request, jheaders_map, nullptr, status_line.Release());
240 }
241
242 static jstring GetNegotiatedProtocol(JNIEnv* jenv,
243 jobject jurl_request,
244 jlong jurl_request_adapter) {
245 if (!jurl_request_adapter)
246 return ConvertUTF8ToJavaString(jenv, std::string()).Release();
247 CronetURLRequestAdapter* request_adapter =
248 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
249 DCHECK(request_adapter->IsOnNetworkThread());
250 std::string negotiated_protocol = request_adapter->GetNegotiatedProtocol();
251 return ConvertUTF8ToJavaString(jenv, negotiated_protocol).Release();
252 }
253
254 static jboolean GetWasCached(JNIEnv* jenv,
255 jobject jurl_request,
256 jlong jurl_request_adapter) {
257 if (!jurl_request_adapter)
258 return JNI_FALSE;
259 CronetURLRequestAdapter* request_adapter =
260 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
261 DCHECK(request_adapter->IsOnNetworkThread());
262 return request_adapter->GetWasCached() ? JNI_TRUE : JNI_FALSE;
263 }
264
265 static jlong GetTotalReceivedBytes(JNIEnv* jenv,
266 jobject jurl_request,
267 jlong jurl_request_adapter) {
268 if (!jurl_request_adapter)
269 return 0;
270 CronetURLRequestAdapter* request_adapter =
271 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
272 DCHECK(request_adapter->IsOnNetworkThread());
273 return request_adapter->GetTotalReceivedBytes();
274 }
275
276 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698