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" | |
12 #include "android_webview/common/devtools_instrumentation.h" | 11 #include "android_webview/common/devtools_instrumentation.h" |
13 #include "android_webview/native/aw_contents_background_thread_client.h" | 12 #include "android_webview/native/aw_contents_background_thread_client.h" |
14 #include "android_webview/native/aw_web_resource_response_impl.h" | 13 #include "android_webview/native/aw_web_resource_response_impl.h" |
15 #include "base/android/jni_array.h" | 14 #include "base/android/jni_array.h" |
16 #include "base/android/jni_string.h" | 15 #include "base/android/jni_string.h" |
17 #include "base/android/jni_weak_ref.h" | 16 #include "base/android/jni_weak_ref.h" |
18 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
19 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
20 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
21 #include "content/public/browser/render_frame_host.h" | 20 #include "content/public/browser/render_frame_host.h" |
22 #include "content/public/browser/render_process_host.h" | 21 #include "content/public/browser/render_process_host.h" |
23 #include "content/public/browser/render_view_host.h" | 22 #include "content/public/browser/render_view_host.h" |
24 #include "content/public/browser/resource_request_info.h" | 23 #include "content/public/browser/resource_request_info.h" |
25 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
26 #include "content/public/browser/web_contents_observer.h" | 25 #include "content/public/browser/web_contents_observer.h" |
27 #include "jni/AwContentsIoThreadClient_jni.h" | 26 #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" |
28 #include "net/url_request/url_request.h" | 30 #include "net/url_request/url_request.h" |
| 31 #include "url/gurl.h" |
29 | 32 |
30 using base::android::AttachCurrentThread; | 33 using base::android::AttachCurrentThread; |
31 using base::android::ConvertUTF8ToJavaString; | 34 using base::android::ConvertUTF8ToJavaString; |
32 using base::android::JavaRef; | 35 using base::android::JavaRef; |
33 using base::android::ScopedJavaLocalRef; | 36 using base::android::ScopedJavaLocalRef; |
34 using base::android::ToJavaArrayOfStrings; | 37 using base::android::ToJavaArrayOfStrings; |
35 using base::LazyInstance; | 38 using base::LazyInstance; |
36 using content::BrowserThread; | 39 using content::BrowserThread; |
37 using content::RenderFrameHost; | 40 using content::RenderFrameHost; |
38 using content::ResourceType; | 41 using content::ResourceType; |
39 using content::WebContents; | 42 using content::WebContents; |
40 using std::map; | 43 using std::map; |
41 using std::pair; | 44 using std::pair; |
42 using std::string; | 45 using std::string; |
| 46 using std::vector; |
43 | 47 |
44 namespace android_webview { | 48 namespace android_webview { |
45 | 49 |
46 namespace { | 50 namespace { |
47 | 51 |
48 struct IoThreadClientData { | 52 struct IoThreadClientData { |
49 bool pending_association; | 53 bool pending_association; |
50 JavaObjectWeakGlobalRef io_thread_client; | 54 JavaObjectWeakGlobalRef io_thread_client; |
51 | 55 |
52 IoThreadClientData(); | 56 IoThreadClientData(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 } | 151 } |
148 | 152 |
149 void ClientMapEntryUpdater::RenderFrameDeleted(RenderFrameHost* rfh) { | 153 void ClientMapEntryUpdater::RenderFrameDeleted(RenderFrameHost* rfh) { |
150 RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh)); | 154 RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh)); |
151 } | 155 } |
152 | 156 |
153 void ClientMapEntryUpdater::WebContentsDestroyed() { | 157 void ClientMapEntryUpdater::WebContentsDestroyed() { |
154 delete this; | 158 delete this; |
155 } | 159 } |
156 | 160 |
| 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 |
157 } // namespace | 206 } // namespace |
158 | 207 |
159 // AwContentsIoThreadClientImpl ----------------------------------------------- | 208 // AwContentsIoThreadClientImpl ----------------------------------------------- |
160 | 209 |
161 // static | 210 // static |
162 std::unique_ptr<AwContentsIoThreadClient> AwContentsIoThreadClient::FromID( | 211 std::unique_ptr<AwContentsIoThreadClient> AwContentsIoThreadClient::FromID( |
163 int render_process_id, | 212 int render_process_id, |
164 int render_frame_id) { | 213 int render_frame_id) { |
165 pair<int, int> rfh_id(render_process_id, render_frame_id); | 214 pair<int, int> rfh_id(render_process_id, render_frame_id); |
166 IoThreadClientData client_data; | 215 IoThreadClientData client_data; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 | 306 |
258 JNIEnv* env = AttachCurrentThread(); | 307 JNIEnv* env = AttachCurrentThread(); |
259 return static_cast<AwContentsIoThreadClient::CacheMode>( | 308 return static_cast<AwContentsIoThreadClient::CacheMode>( |
260 Java_AwContentsIoThreadClient_getCacheMode(env, java_object_)); | 309 Java_AwContentsIoThreadClient_getCacheMode(env, java_object_)); |
261 } | 310 } |
262 | 311 |
263 | 312 |
264 namespace { | 313 namespace { |
265 | 314 |
266 std::unique_ptr<AwWebResourceResponse> RunShouldInterceptRequest( | 315 std::unique_ptr<AwWebResourceResponse> RunShouldInterceptRequest( |
267 const AwWebResourceRequest& request, | 316 WebResourceRequest web_request, |
268 JavaObjectWeakGlobalRef ref) { | 317 JavaObjectWeakGlobalRef ref) { |
269 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 318 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
270 JNIEnv* env = AttachCurrentThread(); | 319 JNIEnv* env = AttachCurrentThread(); |
271 base::android::ScopedJavaLocalRef<jobject> obj = ref.get(env); | 320 base::android::ScopedJavaLocalRef<jobject> obj = ref.get(env); |
272 if (obj.is_null()) | 321 if (obj.is_null()) |
273 return nullptr; | 322 return nullptr; |
274 | 323 |
275 AwWebResourceRequest::AwJavaWebResourceRequest java_web_resource_request; | 324 web_request.ConvertToJava(env); |
276 AwWebResourceRequest::ConvertToJava(env, request, &java_web_resource_request); | |
277 | 325 |
278 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback( | 326 devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback( |
279 "shouldInterceptRequest"); | 327 "shouldInterceptRequest"); |
280 ScopedJavaLocalRef<jobject> ret = | 328 ScopedJavaLocalRef<jobject> ret = |
281 AwContentsBackgroundThreadClient::shouldInterceptRequest( | 329 AwContentsBackgroundThreadClient::shouldInterceptRequest( |
282 env, obj, java_web_resource_request.jurl, request.is_main_frame, | 330 env, obj, web_request.jstring_url, web_request.is_main_frame, |
283 request.has_user_gesture, java_web_resource_request.jmethod, | 331 web_request.has_user_gesture, web_request.jstring_method, |
284 java_web_resource_request.jheader_names, | 332 web_request.jstringArray_header_names, |
285 java_web_resource_request.jheader_values); | 333 web_request.jstringArray_header_values); |
286 return std::unique_ptr<AwWebResourceResponse>( | 334 return std::unique_ptr<AwWebResourceResponse>( |
287 ret.is_null() ? nullptr : new AwWebResourceResponseImpl(ret)); | 335 ret.is_null() ? nullptr : new AwWebResourceResponseImpl(ret)); |
288 } | 336 } |
289 | 337 |
290 std::unique_ptr<AwWebResourceResponse> ReturnNull() { | 338 std::unique_ptr<AwWebResourceResponse> ReturnNull() { |
291 return std::unique_ptr<AwWebResourceResponse>(); | 339 return std::unique_ptr<AwWebResourceResponse>(); |
292 } | 340 } |
293 | 341 |
294 } // namespace | 342 } // namespace |
295 | 343 |
296 void AwContentsIoThreadClientImpl::ShouldInterceptRequestAsync( | 344 void AwContentsIoThreadClientImpl::ShouldInterceptRequestAsync( |
297 const net::URLRequest* request, | 345 const net::URLRequest* request, |
298 const ShouldInterceptRequestResultCallback callback) { | 346 const ShouldInterceptRequestResultCallback callback) { |
299 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 347 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
300 base::Callback<std::unique_ptr<AwWebResourceResponse>()> get_response = | 348 base::Callback<std::unique_ptr<AwWebResourceResponse>()> get_response = |
301 base::Bind(&ReturnNull); | 349 base::Bind(&ReturnNull); |
302 JNIEnv* env = AttachCurrentThread(); | 350 JNIEnv* env = AttachCurrentThread(); |
303 if (bg_thread_client_object_.is_null() && !java_object_.is_null()) { | 351 if (bg_thread_client_object_.is_null() && !java_object_.is_null()) { |
304 bg_thread_client_object_.Reset( | 352 bg_thread_client_object_.Reset( |
305 Java_AwContentsIoThreadClient_getBackgroundThreadClient(env, | 353 Java_AwContentsIoThreadClient_getBackgroundThreadClient(env, |
306 java_object_)); | 354 java_object_)); |
307 } | 355 } |
308 if (!bg_thread_client_object_.is_null()) { | 356 if (!bg_thread_client_object_.is_null()) { |
309 get_response = base::Bind( | 357 get_response = base::Bind( |
310 &RunShouldInterceptRequest, AwWebResourceRequest(*request), | 358 &RunShouldInterceptRequest, WebResourceRequest(request), |
311 JavaObjectWeakGlobalRef(env, bg_thread_client_object_.obj())); | 359 JavaObjectWeakGlobalRef(env, bg_thread_client_object_.obj())); |
312 } | 360 } |
313 BrowserThread::PostTaskAndReplyWithResult(BrowserThread::FILE, FROM_HERE, | 361 BrowserThread::PostTaskAndReplyWithResult(BrowserThread::FILE, FROM_HERE, |
314 get_response, callback); | 362 get_response, callback); |
315 } | 363 } |
316 | 364 |
317 bool AwContentsIoThreadClientImpl::ShouldBlockContentUrls() const { | 365 bool AwContentsIoThreadClientImpl::ShouldBlockContentUrls() const { |
318 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 366 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
319 if (java_object_.is_null()) | 367 if (java_object_.is_null()) |
320 return false; | 368 return false; |
(...skipping 25 matching lines...) Expand all Loading... |
346 bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const { | 394 bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const { |
347 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 395 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
348 if (java_object_.is_null()) | 396 if (java_object_.is_null()) |
349 return false; | 397 return false; |
350 | 398 |
351 JNIEnv* env = AttachCurrentThread(); | 399 JNIEnv* env = AttachCurrentThread(); |
352 return Java_AwContentsIoThreadClient_shouldBlockNetworkLoads(env, | 400 return Java_AwContentsIoThreadClient_shouldBlockNetworkLoads(env, |
353 java_object_); | 401 java_object_); |
354 } | 402 } |
355 | 403 |
| 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 |
356 } // namespace android_webview | 469 } // namespace android_webview |
OLD | NEW |