| 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 |