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

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: Sync 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
mmenke 2014/11/06 16:08:26 Maybe have a file-level comment along the lines of
mef 2014/11/06 22:51:44 Done.
22 namespace cronet {
23 namespace {
24
25 // A delegate of CronetURLRequestAdapter that delivers callbacks to the Java
26 // layer. Always called on the Network Thread.
mmenke 2014/11/06 16:08:26 Maybe "Created on a Java thread, but always called
mef 2014/11/06 22:51:45 Done.
27 class JniCronetURLRequestAdapterDelegate
28 : public CronetURLRequestAdapter::CronetURLRequestAdapterDelegate {
29 public:
30 JniCronetURLRequestAdapterDelegate(JNIEnv* env, jobject owner) {
31 owner_.Reset(env, owner);
32 }
33
mmenke 2014/11/06 16:08:26 // CronetURLRequestAdapter::CronetURLRequestAdapte
mef 2014/11/06 22:51:45 Done.
34 void OnRedirect(const GURL& new_location, int http_status_code) override {
35 JNIEnv* env = base::android::AttachCurrentThread();
36 cronet::Java_CronetUrlRequest_onRedirect(
37 env,
38 owner_.obj(),
39 ConvertUTF8ToJavaString(env, new_location.spec()).Release(),
mmenke 2014/11/06 16:11:01 Again, think this is a leak - shouldn't be releasi
mef 2014/11/06 17:07:46 Good point, I think you are right, I'll change the
mef 2014/11/06 22:51:45 Done.
40 http_status_code);
41 }
42
43 void OnResponseStarted(int http_status_code) override {
44 JNIEnv* env = base::android::AttachCurrentThread();
45 cronet::Java_CronetUrlRequest_onResponseStarted(env,
46 owner_.obj(),
47 http_status_code);
48 }
49
50 void OnBytesRead(unsigned char* bytes_buffer,
51 int bytes_read) override {
52 JNIEnv* env = base::android::AttachCurrentThread();
53 base::android::ScopedJavaLocalRef<jobject> java_buffer(
54 env, env->NewDirectByteBuffer(bytes_buffer, bytes_read));
55 cronet::Java_CronetUrlRequest_onDataReceived(
56 env, owner_.obj(), java_buffer.obj());
57 }
58
59 void OnRequestFinished() override {
60 JNIEnv* env = base::android::AttachCurrentThread();
61 cronet::Java_CronetUrlRequest_onComplete(env, owner_.obj());
62 }
63
64 void OnError(int net_error) override {
65 JNIEnv* env = base::android::AttachCurrentThread();
66 cronet::Java_CronetUrlRequest_onError(
67 env,
68 owner_.obj(),
69 net_error,
70 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).Release());
71 }
72
73 private:
74 ~JniCronetURLRequestAdapterDelegate() override {
75 }
76
77 // Java object that owns the CronetURLRequestContextAdapter, which owns this
78 // delegate.
79 base::android::ScopedJavaGlobalRef<jobject> owner_;
mmenke 2014/11/06 16:08:26 include base/android/scoped_java_ref.h
mef 2014/11/06 22:51:45 Done, it was already there.
80
81 DISALLOW_COPY_AND_ASSIGN(JniCronetURLRequestAdapterDelegate);
82 };
83
84 } // namespace
85
86 // Explicitly register static JNI functions.
87 bool CronetUrlRequestRegisterJni(JNIEnv* jenv) {
88 return RegisterNativesImpl(jenv);
89 }
90
91 static jlong CreateRequestAdapter(JNIEnv* jenv,
92 jobject jurl_request,
93 jlong jurl_request_context_adapter,
94 jstring jurl_string,
95 jint jpriority) {
96 CronetURLRequestContextAdapter* context_adapter =
97 reinterpret_cast<CronetURLRequestContextAdapter*>(
98 jurl_request_context_adapter);
99 DCHECK(context_adapter);
100
101 GURL url(base::android::ConvertJavaStringToUTF8(jenv, jurl_string));
102
103 VLOG(1) << "New chromium network request_adapter: "
104 << url.possibly_invalid_spec();
105
106 scoped_ptr<CronetURLRequestAdapter::CronetURLRequestAdapterDelegate> delegate(
107 new JniCronetURLRequestAdapterDelegate(jenv, jurl_request));
108
109 CronetURLRequestAdapter* adapter = new CronetURLRequestAdapter(
110 context_adapter,
111 delegate.Pass(),
112 url,
113 static_cast<net::RequestPriority>(jpriority));
114
115 return reinterpret_cast<jlong>(adapter);
116 }
117
118 static jboolean AddHeader(JNIEnv* jenv,
119 jobject jurl_request,
120 jlong jurl_request_adapter,
121 jstring jname,
122 jstring jvalue) {
123 DCHECK(jurl_request_adapter);
124 CronetURLRequestAdapter* request_adapter =
125 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
126 DCHECK(!request_adapter->IsOnNetworkThread());
127 std::string name(base::android::ConvertJavaStringToUTF8(jenv, jname));
128 std::string value(base::android::ConvertJavaStringToUTF8(jenv, jvalue));
129 if (!net::HttpUtil::IsValidHeaderName(name) ||
130 !net::HttpUtil::IsValidHeaderValue(value)) {
131 return JNI_FALSE;
132 }
133 request_adapter->AddRequestHeader(name, value);
134 return JNI_TRUE;
135 }
136
137 static jboolean SetHttpMethod(JNIEnv* jenv,
138 jobject jurl_request,
139 jlong jurl_request_adapter,
140 jstring jmethod) {
141 DCHECK(jurl_request_adapter);
142 CronetURLRequestAdapter* request_adapter =
143 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
144 DCHECK(!request_adapter->IsOnNetworkThread());
145 std::string method(base::android::ConvertJavaStringToUTF8(jenv, jmethod));
146 // Http method is a token, just as header name.
147 if (!net::HttpUtil::IsValidHeaderName(method))
148 return JNI_FALSE;
149 request_adapter->set_method(method);
150 return JNI_TRUE;
151 }
152
153 static void Start(JNIEnv* jenv,
154 jobject jurl_request,
155 jlong jurl_request_adapter) {
156 DCHECK(jurl_request_adapter);
157 CronetURLRequestAdapter* request_adapter =
158 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
159 DCHECK(!request_adapter->IsOnNetworkThread());
160 request_adapter->Start();
mmenke 2014/11/06 16:08:26 optional: Think it would be cleaner to post tasks
mef 2014/11/06 17:07:46 Sounds reasonable, I'll try that.
mef 2014/11/06 22:51:45 Done.
161 }
162
163 static void DestroyRequestAdapter(JNIEnv* jenv,
164 jobject jurl_request,
165 jlong jurl_request_adapter) {
166 DCHECK(jurl_request_adapter);
167 CronetURLRequestAdapter* request_adapter =
168 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
169 DCHECK(!request_adapter->IsOnNetworkThread());
170 request_adapter->Destroy();
171 }
172
173 static void ReceiveData(JNIEnv* jenv,
174 jobject jcaller,
175 jlong jurl_request_adapter) {
176 DCHECK(jurl_request_adapter);
177 CronetURLRequestAdapter* request_adapter =
178 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
179 DCHECK(!request_adapter->IsOnNetworkThread());
180 request_adapter->ReadData();
181 }
182
183 static void FollowDeferredRedirect(JNIEnv* jenv,
184 jobject jcaller,
185 jlong jurl_request_adapter) {
186 DCHECK(jurl_request_adapter);
187 CronetURLRequestAdapter* request_adapter =
188 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
189 DCHECK(!request_adapter->IsOnNetworkThread());
190 request_adapter->FollowDeferredRedirect();
191 }
192
193 static void PopulateResponseHeaders(JNIEnv* jenv,
194 jobject jurl_request,
195 jlong jurl_request_adapter,
196 jobject jheaders_map) {
197 DCHECK(jurl_request_adapter);
198 CronetURLRequestAdapter* request_adapter =
199 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
200 DCHECK(request_adapter->IsOnNetworkThread());
201
202 net::HttpResponseHeaders* headers = request_adapter->GetResponseHeaders();
203 if (headers == nullptr)
204 return;
205
206 void* iter = nullptr;
207 std::string header_name;
208 std::string header_value;
209 while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
210 ScopedJavaLocalRef<jstring> name =
211 ConvertUTF8ToJavaString(jenv, header_name);
212 ScopedJavaLocalRef<jstring> value =
213 ConvertUTF8ToJavaString(jenv, header_value);
214 Java_CronetUrlRequest_onAppendResponseHeader(
215 jenv, jurl_request, jheaders_map, name.Release(), value.Release());
mmenke 2014/11/06 16:08:26 I think this is a leak: When we call into Java, I
mef 2014/11/06 22:51:45 Done.
216 }
217
218 // Some implementations (notably HttpURLConnection) include a mapping for the
219 // null key; in HTTP's case, this maps to the HTTP status line.
220 ScopedJavaLocalRef<jstring> status_line =
221 ConvertUTF8ToJavaString(jenv, headers->GetStatusLine());
222 Java_CronetUrlRequest_onAppendResponseHeader(
223 jenv, jurl_request, jheaders_map, nullptr, status_line.Release());
mmenke 2014/11/06 16:08:26 Again, Release() -> obj()... Actually, I think we
mef 2014/11/06 22:51:45 Done.
224 }
225
226 static jstring GetNegotiatedProtocol(JNIEnv* jenv,
227 jobject jurl_request,
228 jlong jurl_request_adapter) {
229 DCHECK(jurl_request_adapter);
230 CronetURLRequestAdapter* request_adapter =
231 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
232 DCHECK(request_adapter->IsOnNetworkThread());
233 std::string negotiated_protocol = request_adapter->GetNegotiatedProtocol();
mmenke 2014/11/06 17:31:28 This is an unnecessary string copy. Can just inli
mef 2014/11/06 22:51:45 Done.
234 return ConvertUTF8ToJavaString(jenv, negotiated_protocol).Release();
235 }
236
237 static jboolean GetWasCached(JNIEnv* jenv,
238 jobject jurl_request,
239 jlong jurl_request_adapter) {
240 DCHECK(jurl_request_adapter);
241 CronetURLRequestAdapter* request_adapter =
242 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
243 DCHECK(request_adapter->IsOnNetworkThread());
244 return request_adapter->GetWasCached() ? JNI_TRUE : JNI_FALSE;
245 }
246
247 static jlong GetTotalReceivedBytes(JNIEnv* jenv,
248 jobject jurl_request,
249 jlong jurl_request_adapter) {
250 DCHECK(jurl_request_adapter);
251 CronetURLRequestAdapter* request_adapter =
252 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
253 DCHECK(request_adapter->IsOnNetworkThread());
254 return request_adapter->GetTotalReceivedBytes();
255 }
256
257 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698