Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / android_webview / native / aw_contents_io_thread_client_impl.cc
index 6e24d9a..8bdbf77 100644 (file)
@@ -7,20 +7,24 @@
 #include <map>
 #include <utility>
 
-#include "android_webview/native/intercepted_request_data_impl.h"
-#include "base/android/jni_helper.h"
+#include "android_webview/common/devtools_instrumentation.h"
+#include "android_webview/native/aw_web_resource_response_impl.h"
+#include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
+#include "base/android/jni_weak_ref.h"
 #include "base/lazy_instance.h"
 #include "base/memory/linked_ptr.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/synchronization/lock.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/resource_request_info.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "jni/AwContentsIoThreadClient_jni.h"
+#include "net/http/http_request_headers.h"
 #include "net/url_request/url_request.h"
 #include "url/gurl.h"
 
@@ -28,12 +32,16 @@ using base::android::AttachCurrentThread;
 using base::android::ConvertUTF8ToJavaString;
 using base::android::JavaRef;
 using base::android::ScopedJavaLocalRef;
+using base::android::ToJavaArrayOfStrings;
 using base::LazyInstance;
 using content::BrowserThread;
-using content::RenderViewHost;
+using content::RenderFrameHost;
+using content::ResourceType;
 using content::WebContents;
 using std::map;
 using std::pair;
+using std::string;
+using std::vector;
 
 namespace android_webview {
 
@@ -49,56 +57,56 @@ struct IoThreadClientData {
 IoThreadClientData::IoThreadClientData() : pending_association(false) {}
 
 typedef map<pair<int, int>, IoThreadClientData>
-    RenderViewHostToIoThreadClientType;
+    RenderFrameHostToIoThreadClientType;
 
-static pair<int, int> GetRenderViewHostIdPair(RenderViewHost* rvh) {
-  return pair<int, int>(rvh->GetProcess()->GetID(), rvh->GetRoutingID());
+static pair<int, int> GetRenderFrameHostIdPair(RenderFrameHost* rfh) {
+  return pair<int, int>(rfh->GetProcess()->GetID(), rfh->GetRoutingID());
 }
 
-// RvhToIoThreadClientMap -----------------------------------------------------
-class RvhToIoThreadClientMap {
+// RfhToIoThreadClientMap -----------------------------------------------------
+class RfhToIoThreadClientMap {
  public:
-  static RvhToIoThreadClientMap* GetInstance();
-  void Set(pair<int, int> rvh_id, const IoThreadClientData& client);
-  bool Get(pair<int, int> rvh_id, IoThreadClientData* client);
-  void Erase(pair<int, int> rvh_id);
+  static RfhToIoThreadClientMap* GetInstance();
+  void Set(pair<int, int> rfh_id, const IoThreadClientData& client);
+  bool Get(pair<int, int> rfh_id, IoThreadClientData* client);
+  void Erase(pair<int, int> rfh_id);
 
  private:
-  static LazyInstance<RvhToIoThreadClientMap> g_instance_;
+  static LazyInstance<RfhToIoThreadClientMap> g_instance_;
   base::Lock map_lock_;
-  RenderViewHostToIoThreadClientType rvh_to_io_thread_client_;
+  RenderFrameHostToIoThreadClientType rfh_to_io_thread_client_;
 };
 
 // static
-LazyInstance<RvhToIoThreadClientMap> RvhToIoThreadClientMap::g_instance_ =
+LazyInstance<RfhToIoThreadClientMap> RfhToIoThreadClientMap::g_instance_ =
     LAZY_INSTANCE_INITIALIZER;
 
 // static
-RvhToIoThreadClientMap* RvhToIoThreadClientMap::GetInstance() {
+RfhToIoThreadClientMap* RfhToIoThreadClientMap::GetInstance() {
   return g_instance_.Pointer();
 }
 
-void RvhToIoThreadClientMap::Set(pair<int, int> rvh_id,
+void RfhToIoThreadClientMap::Set(pair<int, int> rfh_id,
                                  const IoThreadClientData& client) {
   base::AutoLock lock(map_lock_);
-  rvh_to_io_thread_client_[rvh_id] = client;
+  rfh_to_io_thread_client_[rfh_id] = client;
 }
 
-bool RvhToIoThreadClientMap::Get(
-    pair<int, int> rvh_id, IoThreadClientData* client) {
+bool RfhToIoThreadClientMap::Get(
+    pair<int, int> rfh_id, IoThreadClientData* client) {
   base::AutoLock lock(map_lock_);
-  RenderViewHostToIoThreadClientType::iterator iterator =
-      rvh_to_io_thread_client_.find(rvh_id);
-  if (iterator == rvh_to_io_thread_client_.end())
+  RenderFrameHostToIoThreadClientType::iterator iterator =
+      rfh_to_io_thread_client_.find(rfh_id);
+  if (iterator == rfh_to_io_thread_client_.end())
     return false;
 
   *client = iterator->second;
   return true;
 }
 
-void RvhToIoThreadClientMap::Erase(pair<int, int> rvh_id) {
+void RfhToIoThreadClientMap::Erase(pair<int, int> rfh_id) {
   base::AutoLock lock(map_lock_);
-  rvh_to_io_thread_client_.erase(rvh_id);
+  rfh_to_io_thread_client_.erase(rfh_id);
 }
 
 // ClientMapEntryUpdater ------------------------------------------------------
@@ -108,9 +116,9 @@ class ClientMapEntryUpdater : public content::WebContentsObserver {
   ClientMapEntryUpdater(JNIEnv* env, WebContents* web_contents,
                         jobject jdelegate);
 
-  virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE;
-  virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) OVERRIDE;
+  virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
  private:
   JavaObjectWeakGlobalRef jdelegate_;
@@ -124,23 +132,23 @@ ClientMapEntryUpdater::ClientMapEntryUpdater(JNIEnv* env,
   DCHECK(web_contents);
   DCHECK(jdelegate);
 
-  if (web_contents->GetRenderViewHost())
-    RenderViewCreated(web_contents->GetRenderViewHost());
+  if (web_contents->GetMainFrame())
+    RenderFrameCreated(web_contents->GetMainFrame());
 }
 
-void ClientMapEntryUpdater::RenderViewCreated(RenderViewHost* rvh) {
+void ClientMapEntryUpdater::RenderFrameCreated(RenderFrameHost* rfh) {
   IoThreadClientData client_data;
   client_data.io_thread_client = jdelegate_;
   client_data.pending_association = false;
-  RvhToIoThreadClientMap::GetInstance()->Set(
-      GetRenderViewHostIdPair(rvh), client_data);
+  RfhToIoThreadClientMap::GetInstance()->Set(
+      GetRenderFrameHostIdPair(rfh), client_data);
 }
 
-void ClientMapEntryUpdater::RenderViewDeleted(RenderViewHost* rvh) {
-  RvhToIoThreadClientMap::GetInstance()->Erase(GetRenderViewHostIdPair(rvh));
+void ClientMapEntryUpdater::RenderFrameDeleted(RenderFrameHost* rfh) {
+  RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh));
 }
 
-void ClientMapEntryUpdater::WebContentsDestroyed(WebContents* web_contents) {
+void ClientMapEntryUpdater::WebContentsDestroyed() {
   delete this;
 }
 
@@ -150,10 +158,10 @@ void ClientMapEntryUpdater::WebContentsDestroyed(WebContents* web_contents) {
 
 // static
 scoped_ptr<AwContentsIoThreadClient>
-AwContentsIoThreadClient::FromID(int render_process_id, int render_view_id) {
-  pair<int, int> rvh_id(render_process_id, render_view_id);
+AwContentsIoThreadClient::FromID(int render_process_id, int render_frame_id) {
+  pair<int, int> rfh_id(render_process_id, render_frame_id);
   IoThreadClientData client_data;
-  if (!RvhToIoThreadClientMap::GetInstance()->Get(rvh_id, &client_data))
+  if (!RfhToIoThreadClientMap::GetInstance()->Get(rfh_id, &client_data))
     return scoped_ptr<AwContentsIoThreadClient>();
 
   JNIEnv* env = AttachCurrentThread();
@@ -165,12 +173,28 @@ AwContentsIoThreadClient::FromID(int render_process_id, int render_view_id) {
 }
 
 // static
+void AwContentsIoThreadClient::SubFrameCreated(int render_process_id,
+                                               int parent_render_frame_id,
+                                               int child_render_frame_id) {
+  pair<int, int> parent_rfh_id(render_process_id, parent_render_frame_id);
+  pair<int, int> child_rfh_id(render_process_id, child_render_frame_id);
+  IoThreadClientData client_data;
+  if (!RfhToIoThreadClientMap::GetInstance()->Get(parent_rfh_id,
+                                                  &client_data)) {
+    NOTREACHED();
+    return;
+  }
+
+  RfhToIoThreadClientMap::GetInstance()->Set(child_rfh_id, client_data);
+}
+
+// static
 void AwContentsIoThreadClientImpl::RegisterPendingContents(
     WebContents* web_contents) {
   IoThreadClientData client_data;
   client_data.pending_association = true;
-  RvhToIoThreadClientMap::GetInstance()->Set(
-      GetRenderViewHostIdPair(web_contents->GetRenderViewHost()), client_data);
+  RfhToIoThreadClientMap::GetInstance()->Set(
+      GetRenderFrameHostIdPair(web_contents->GetMainFrame()), client_data);
 }
 
 // static
@@ -209,28 +233,57 @@ AwContentsIoThreadClientImpl::GetCacheMode() const {
           env, java_object_.obj()));
 }
 
-scoped_ptr<InterceptedRequestData>
+scoped_ptr<AwWebResourceResponse>
 AwContentsIoThreadClientImpl::ShouldInterceptRequest(
     const GURL& location,
     const net::URLRequest* request) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (java_object_.is_null())
-    return scoped_ptr<InterceptedRequestData>();
+    return scoped_ptr<AwWebResourceResponse>();
   const content::ResourceRequestInfo* info =
       content::ResourceRequestInfo::ForRequest(request);
   bool is_main_frame = info &&
-      info->GetResourceType() == ResourceType::MAIN_FRAME;
+      info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME;
+  bool has_user_gesture = info && info->HasUserGesture();
+
+  vector<string> headers_names;
+  vector<string> headers_values;
+  {
+    net::HttpRequestHeaders headers;
+    if (!request->GetFullRequestHeaders(&headers))
+      headers = request->extra_request_headers();
+    net::HttpRequestHeaders::Iterator headers_iterator(headers);
+    while (headers_iterator.GetNext()) {
+      headers_names.push_back(headers_iterator.name());
+      headers_values.push_back(headers_iterator.value());
+    }
+  }
 
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jstring> jstring_url =
       ConvertUTF8ToJavaString(env, location.spec());
+  ScopedJavaLocalRef<jstring> jstring_method =
+      ConvertUTF8ToJavaString(env, request->method());
+  ScopedJavaLocalRef<jobjectArray> jstringArray_headers_names =
+      ToJavaArrayOfStrings(env, headers_names);
+  ScopedJavaLocalRef<jobjectArray> jstringArray_headers_values =
+      ToJavaArrayOfStrings(env, headers_values);
+  devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
+      "shouldInterceptRequest");
   ScopedJavaLocalRef<jobject> ret =
       Java_AwContentsIoThreadClient_shouldInterceptRequest(
-          env, java_object_.obj(), jstring_url.obj(), is_main_frame);
+          env,
+          java_object_.obj(),
+          jstring_url.obj(),
+          is_main_frame,
+          has_user_gesture,
+          jstring_method.obj(),
+          jstringArray_headers_names.obj(),
+          jstringArray_headers_values.obj());
   if (ret.is_null())
-    return scoped_ptr<InterceptedRequestData>();
-  return scoped_ptr<InterceptedRequestData>(
-      new InterceptedRequestDataImpl(ret));
+    return scoped_ptr<AwWebResourceResponse>();
+  return scoped_ptr<AwWebResourceResponse>(
+      new AwWebResourceResponseImpl(ret));
 }
 
 bool AwContentsIoThreadClientImpl::ShouldBlockContentUrls() const {
@@ -253,6 +306,16 @@ bool AwContentsIoThreadClientImpl::ShouldBlockFileUrls() const {
       env, java_object_.obj());
 }
 
+bool AwContentsIoThreadClientImpl::ShouldAcceptThirdPartyCookies() const {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  if (java_object_.is_null())
+    return false;
+
+  JNIEnv* env = AttachCurrentThread();
+  return Java_AwContentsIoThreadClient_shouldAcceptThirdPartyCookies(
+      env, java_object_.obj());
+}
+
 bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (java_object_.is_null())
@@ -265,9 +328,9 @@ bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const {
 
 void AwContentsIoThreadClientImpl::NewDownload(
     const GURL& url,
-    const std::string& user_agent,
-    const std::string& content_disposition,
-    const std::string& mime_type,
+    const string& user_agent,
+    const string& content_disposition,
+    const string& mime_type,
     int64 content_length) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (java_object_.is_null())
@@ -293,9 +356,9 @@ void AwContentsIoThreadClientImpl::NewDownload(
       content_length);
 }
 
-void AwContentsIoThreadClientImpl::NewLoginRequest(const std::string& realm,
-                                                   const std::string& account,
-                                                   const std::string& args) {
+void AwContentsIoThreadClientImpl::NewLoginRequest(const string& realm,
+                                                   const string& account,
+                                                   const string& args) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (java_object_.is_null())
     return;