OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "android_webview/native/aw_contents_io_thread_client_impl.h" | 5 #include "android_webview/native/aw_contents_io_thread_client_impl.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <memory> | 8 #include <memory> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
| 11 #include "android_webview/browser/net/aw_web_resource_request.h" |
11 #include "android_webview/common/devtools_instrumentation.h" | 12 #include "android_webview/common/devtools_instrumentation.h" |
12 #include "android_webview/native/aw_contents_background_thread_client.h" | 13 #include "android_webview/native/aw_contents_background_thread_client.h" |
13 #include "android_webview/native/aw_web_resource_response_impl.h" | 14 #include "android_webview/native/aw_web_resource_response_impl.h" |
14 #include "base/android/jni_array.h" | 15 #include "base/android/jni_array.h" |
15 #include "base/android/jni_string.h" | 16 #include "base/android/jni_string.h" |
16 #include "base/android/jni_weak_ref.h" | 17 #include "base/android/jni_weak_ref.h" |
17 #include "base/lazy_instance.h" | 18 #include "base/lazy_instance.h" |
18 #include "base/synchronization/lock.h" | 19 #include "base/synchronization/lock.h" |
19 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
20 #include "content/public/browser/render_frame_host.h" | 21 #include "content/public/browser/render_frame_host.h" |
21 #include "content/public/browser/render_process_host.h" | 22 #include "content/public/browser/render_process_host.h" |
22 #include "content/public/browser/render_view_host.h" | 23 #include "content/public/browser/render_view_host.h" |
23 #include "content/public/browser/resource_request_info.h" | 24 #include "content/public/browser/resource_request_info.h" |
24 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
25 #include "content/public/browser/web_contents_observer.h" | 26 #include "content/public/browser/web_contents_observer.h" |
26 #include "jni/AwContentsIoThreadClient_jni.h" | 27 #include "jni/AwContentsIoThreadClient_jni.h" |
27 #include "net/base/net_errors.h" | |
28 #include "net/http/http_request_headers.h" | |
29 #include "net/http/http_response_headers.h" | |
30 #include "net/url_request/url_request.h" | 28 #include "net/url_request/url_request.h" |
31 #include "url/gurl.h" | |
32 | 29 |
33 using base::android::AttachCurrentThread; | 30 using base::android::AttachCurrentThread; |
34 using base::android::ConvertUTF8ToJavaString; | 31 using base::android::ConvertUTF8ToJavaString; |
35 using base::android::JavaRef; | 32 using base::android::JavaRef; |
36 using base::android::ScopedJavaLocalRef; | 33 using base::android::ScopedJavaLocalRef; |
37 using base::android::ToJavaArrayOfStrings; | 34 using base::android::ToJavaArrayOfStrings; |
38 using base::LazyInstance; | 35 using base::LazyInstance; |
39 using content::BrowserThread; | 36 using content::BrowserThread; |
40 using content::RenderFrameHost; | 37 using content::RenderFrameHost; |
41 using content::ResourceType; | 38 using content::ResourceType; |
42 using content::WebContents; | 39 using content::WebContents; |
43 using std::map; | 40 using std::map; |
44 using std::pair; | 41 using std::pair; |
45 using std::string; | 42 using std::string; |
46 using std::vector; | |
47 | 43 |
48 namespace android_webview { | 44 namespace android_webview { |
49 | 45 |
50 namespace { | 46 namespace { |
51 | 47 |
52 struct IoThreadClientData { | 48 struct IoThreadClientData { |
53 bool pending_association; | 49 bool pending_association; |
54 JavaObjectWeakGlobalRef io_thread_client; | 50 JavaObjectWeakGlobalRef io_thread_client; |
55 | 51 |
56 IoThreadClientData(); | 52 IoThreadClientData(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 } | 147 } |
152 | 148 |
153 void ClientMapEntryUpdater::RenderFrameDeleted(RenderFrameHost* rfh) { | 149 void ClientMapEntryUpdater::RenderFrameDeleted(RenderFrameHost* rfh) { |
154 RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh)); | 150 RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh)); |
155 } | 151 } |
156 | 152 |
157 void ClientMapEntryUpdater::WebContentsDestroyed() { | 153 void ClientMapEntryUpdater::WebContentsDestroyed() { |
158 delete this; | 154 delete this; |
159 } | 155 } |
160 | 156 |
161 struct WebResourceRequest { | |
162 std::string url; | |
163 std::string method; | |
164 bool is_main_frame; | |
165 bool has_user_gesture; | |
166 vector<string> header_names; | |
167 vector<string> header_values; | |
168 | |
169 ScopedJavaLocalRef<jstring> jstring_url; | |
170 ScopedJavaLocalRef<jstring> jstring_method; | |
171 ScopedJavaLocalRef<jobjectArray> jstringArray_header_names; | |
172 ScopedJavaLocalRef<jobjectArray> jstringArray_header_values; | |
173 | |
174 WebResourceRequest(const net::URLRequest* request) | |
175 : url(request->url().spec()), | |
176 method(request->method()) { | |
177 const content::ResourceRequestInfo* info = | |
178 content::ResourceRequestInfo::ForRequest(request); | |
179 is_main_frame = | |
180 info && info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME; | |
181 has_user_gesture = info && info->HasUserGesture(); | |
182 | |
183 net::HttpRequestHeaders headers; | |
184 if (!request->GetFullRequestHeaders(&headers)) | |
185 headers = request->extra_request_headers(); | |
186 net::HttpRequestHeaders::Iterator headers_iterator(headers); | |
187 while (headers_iterator.GetNext()) { | |
188 header_names.push_back(headers_iterator.name()); | |
189 header_values.push_back(headers_iterator.value()); | |
190 } | |
191 } | |
192 | |
193 WebResourceRequest(JNIEnv* env, const net::URLRequest* request) | |
194 : WebResourceRequest(request) { | |
195 ConvertToJava(env); | |
196 } | |
197 | |
198 void ConvertToJava(JNIEnv* env) { | |
199 jstring_url = ConvertUTF8ToJavaString(env, url); | |
200 jstring_method = ConvertUTF8ToJavaString(env, method); | |
201 jstringArray_header_names = ToJavaArrayOfStrings(env, header_names); | |
202 jstringArray_header_values = ToJavaArrayOfStrings(env, header_values); | |
203 } | |
204 }; | |
205 | |
206 } // namespace | 157 } // namespace |
207 | 158 |
208 // AwContentsIoThreadClientImpl ----------------------------------------------- | 159 // AwContentsIoThreadClientImpl ----------------------------------------------- |
209 | 160 |
210 // static | 161 // static |
211 std::unique_ptr<AwContentsIoThreadClient> AwContentsIoThreadClient::FromID( | 162 std::unique_ptr<AwContentsIoThreadClient> AwContentsIoThreadClient::FromID( |
212 int render_process_id, | 163 int render_process_id, |
213 int render_frame_id) { | 164 int render_frame_id) { |
214 pair<int, int> rfh_id(render_process_id, render_frame_id); | 165 pair<int, int> rfh_id(render_process_id, render_frame_id); |
215 IoThreadClientData client_data; | 166 IoThreadClientData client_data; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 | 257 |
307 JNIEnv* env = AttachCurrentThread(); | 258 JNIEnv* env = AttachCurrentThread(); |
308 return static_cast<AwContentsIoThreadClient::CacheMode>( | 259 return static_cast<AwContentsIoThreadClient::CacheMode>( |
309 Java_AwContentsIoThreadClient_getCacheMode(env, java_object_)); | 260 Java_AwContentsIoThreadClient_getCacheMode(env, java_object_)); |
310 } | 261 } |
311 | 262 |
312 | 263 |
313 namespace { | 264 namespace { |
314 | 265 |
315 std::unique_ptr<AwWebResourceResponse> RunShouldInterceptRequest( | 266 std::unique_ptr<AwWebResourceResponse> RunShouldInterceptRequest( |
316 WebResourceRequest web_request, | 267 const AwWebResourceRequest& request, |
317 JavaObjectWeakGlobalRef ref) { | 268 JavaObjectWeakGlobalRef ref) { |
318 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 269 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
319 JNIEnv* env = AttachCurrentThread(); | 270 JNIEnv* env = AttachCurrentThread(); |
320 base::android::ScopedJavaLocalRef<jobject> obj = ref.get(env); | 271 base::android::ScopedJavaLocalRef<jobject> obj = ref.get(env); |
321 if (obj.is_null()) | 272 if (obj.is_null()) |
322 return nullptr; | 273 return nullptr; |
323 | 274 |
324 web_request.ConvertToJava(env); | 275 AwWebResourceRequest::AwJavaWebResourceRequest java_web_resource_request; |
| 276 AwWebResourceRequest::ConvertToJava(env, request, &java_web_resource_request); |
325 | 277 |
326 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback( | 278 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback( |
327 "shouldInterceptRequest"); | 279 "shouldInterceptRequest"); |
328 ScopedJavaLocalRef<jobject> ret = | 280 ScopedJavaLocalRef<jobject> ret = |
329 AwContentsBackgroundThreadClient::shouldInterceptRequest( | 281 AwContentsBackgroundThreadClient::shouldInterceptRequest( |
330 env, obj, web_request.jstring_url, web_request.is_main_frame, | 282 env, obj, java_web_resource_request.jurl, request.is_main_frame, |
331 web_request.has_user_gesture, web_request.jstring_method, | 283 request.has_user_gesture, java_web_resource_request.jmethod, |
332 web_request.jstringArray_header_names, | 284 java_web_resource_request.jheader_names, |
333 web_request.jstringArray_header_values); | 285 java_web_resource_request.jheader_values); |
334 return std::unique_ptr<AwWebResourceResponse>( | 286 return std::unique_ptr<AwWebResourceResponse>( |
335 ret.is_null() ? nullptr : new AwWebResourceResponseImpl(ret)); | 287 ret.is_null() ? nullptr : new AwWebResourceResponseImpl(ret)); |
336 } | 288 } |
337 | 289 |
338 std::unique_ptr<AwWebResourceResponse> ReturnNull() { | 290 std::unique_ptr<AwWebResourceResponse> ReturnNull() { |
339 return std::unique_ptr<AwWebResourceResponse>(); | 291 return std::unique_ptr<AwWebResourceResponse>(); |
340 } | 292 } |
341 | 293 |
342 } // namespace | 294 } // namespace |
343 | 295 |
344 void AwContentsIoThreadClientImpl::ShouldInterceptRequestAsync( | 296 void AwContentsIoThreadClientImpl::ShouldInterceptRequestAsync( |
345 const net::URLRequest* request, | 297 const net::URLRequest* request, |
346 const ShouldInterceptRequestResultCallback callback) { | 298 const ShouldInterceptRequestResultCallback callback) { |
347 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 299 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
348 base::Callback<std::unique_ptr<AwWebResourceResponse>()> get_response = | 300 base::Callback<std::unique_ptr<AwWebResourceResponse>()> get_response = |
349 base::Bind(&ReturnNull); | 301 base::Bind(&ReturnNull); |
350 JNIEnv* env = AttachCurrentThread(); | 302 JNIEnv* env = AttachCurrentThread(); |
351 if (bg_thread_client_object_.is_null() && !java_object_.is_null()) { | 303 if (bg_thread_client_object_.is_null() && !java_object_.is_null()) { |
352 bg_thread_client_object_.Reset( | 304 bg_thread_client_object_.Reset( |
353 Java_AwContentsIoThreadClient_getBackgroundThreadClient(env, | 305 Java_AwContentsIoThreadClient_getBackgroundThreadClient(env, |
354 java_object_)); | 306 java_object_)); |
355 } | 307 } |
356 if (!bg_thread_client_object_.is_null()) { | 308 if (!bg_thread_client_object_.is_null()) { |
357 get_response = base::Bind( | 309 get_response = base::Bind( |
358 &RunShouldInterceptRequest, WebResourceRequest(request), | 310 &RunShouldInterceptRequest, AwWebResourceRequest(*request), |
359 JavaObjectWeakGlobalRef(env, bg_thread_client_object_.obj())); | 311 JavaObjectWeakGlobalRef(env, bg_thread_client_object_.obj())); |
360 } | 312 } |
361 BrowserThread::PostTaskAndReplyWithResult(BrowserThread::FILE, FROM_HERE, | 313 BrowserThread::PostTaskAndReplyWithResult(BrowserThread::FILE, FROM_HERE, |
362 get_response, callback); | 314 get_response, callback); |
363 } | 315 } |
364 | 316 |
365 bool AwContentsIoThreadClientImpl::ShouldBlockContentUrls() const { | 317 bool AwContentsIoThreadClientImpl::ShouldBlockContentUrls() const { |
366 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 318 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
367 if (java_object_.is_null()) | 319 if (java_object_.is_null()) |
368 return false; | 320 return false; |
(...skipping 25 matching lines...) Expand all Loading... |
394 bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const { | 346 bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const { |
395 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 347 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
396 if (java_object_.is_null()) | 348 if (java_object_.is_null()) |
397 return false; | 349 return false; |
398 | 350 |
399 JNIEnv* env = AttachCurrentThread(); | 351 JNIEnv* env = AttachCurrentThread(); |
400 return Java_AwContentsIoThreadClient_shouldBlockNetworkLoads(env, | 352 return Java_AwContentsIoThreadClient_shouldBlockNetworkLoads(env, |
401 java_object_); | 353 java_object_); |
402 } | 354 } |
403 | 355 |
404 void AwContentsIoThreadClientImpl::OnReceivedError( | |
405 const net::URLRequest* request) { | |
406 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
407 if (java_object_.is_null()) | |
408 return; | |
409 | |
410 JNIEnv* env = AttachCurrentThread(); | |
411 WebResourceRequest web_request(env, request); | |
412 | |
413 int error_code = request->status().error(); | |
414 ScopedJavaLocalRef<jstring> jstring_description = ConvertUTF8ToJavaString( | |
415 env, net::ErrorToString(request->status().error())); | |
416 | |
417 Java_AwContentsIoThreadClient_onReceivedError( | |
418 env, java_object_, web_request.jstring_url, web_request.is_main_frame, | |
419 web_request.has_user_gesture, web_request.jstring_method, | |
420 web_request.jstringArray_header_names, | |
421 web_request.jstringArray_header_values, error_code, jstring_description); | |
422 } | |
423 | |
424 void AwContentsIoThreadClientImpl::OnReceivedHttpError( | |
425 const net::URLRequest* request, | |
426 const net::HttpResponseHeaders* response_headers) { | |
427 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
428 if (java_object_.is_null()) | |
429 return; | |
430 | |
431 JNIEnv* env = AttachCurrentThread(); | |
432 WebResourceRequest web_request(env, request); | |
433 | |
434 vector<string> response_header_names; | |
435 vector<string> response_header_values; | |
436 { | |
437 size_t headers_iterator = 0; | |
438 string header_name, header_value; | |
439 while (response_headers->EnumerateHeaderLines( | |
440 &headers_iterator, &header_name, &header_value)) { | |
441 response_header_names.push_back(header_name); | |
442 response_header_values.push_back(header_value); | |
443 } | |
444 } | |
445 | |
446 string mime_type, encoding; | |
447 response_headers->GetMimeTypeAndCharset(&mime_type, &encoding); | |
448 ScopedJavaLocalRef<jstring> jstring_mime_type = | |
449 ConvertUTF8ToJavaString(env, mime_type); | |
450 ScopedJavaLocalRef<jstring> jstring_encoding = | |
451 ConvertUTF8ToJavaString(env, encoding); | |
452 int status_code = response_headers->response_code(); | |
453 ScopedJavaLocalRef<jstring> jstring_reason = | |
454 ConvertUTF8ToJavaString(env, response_headers->GetStatusText()); | |
455 ScopedJavaLocalRef<jobjectArray> jstringArray_response_header_names = | |
456 ToJavaArrayOfStrings(env, response_header_names); | |
457 ScopedJavaLocalRef<jobjectArray> jstringArray_response_header_values = | |
458 ToJavaArrayOfStrings(env, response_header_values); | |
459 | |
460 Java_AwContentsIoThreadClient_onReceivedHttpError( | |
461 env, java_object_, web_request.jstring_url, web_request.is_main_frame, | |
462 web_request.has_user_gesture, web_request.jstring_method, | |
463 web_request.jstringArray_header_names, | |
464 web_request.jstringArray_header_values, jstring_mime_type, | |
465 jstring_encoding, status_code, jstring_reason, | |
466 jstringArray_response_header_names, jstringArray_response_header_values); | |
467 } | |
468 | |
469 } // namespace android_webview | 356 } // namespace android_webview |
OLD | NEW |