Chromium Code Reviews| Index: android_webview/native/aw_contents_io_thread_delegate.cc |
| diff --git a/android_webview/native/aw_contents_io_thread_delegate.cc b/android_webview/native/aw_contents_io_thread_delegate.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..22b2ce044a4ad764f406a6df8a92be689994390b |
| --- /dev/null |
| +++ b/android_webview/native/aw_contents_io_thread_delegate.cc |
| @@ -0,0 +1,181 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "android_webview/native/aw_contents_io_thread_delegate.h" |
| + |
| +#include <map> |
| +#include <utility> |
| + |
| +#include "android_webview/native/intercepted_request_data.h" |
| +#include "base/android/jni_helper.h" |
| +#include "base/android/jni_string.h" |
| +#include "base/hash_tables.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_view_host.h" |
| +#include "content/public/browser/render_process_host.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "content/public/browser/web_contents_observer.h" |
| +#include "net/url_request/url_request.h" |
| + |
| +#include "jni/AwWebContentsIoThreadDelegate_jni.h" |
| + |
| +using namespace base::android; |
| +using content::BrowserThread; |
| +using content::RenderViewHost; |
| +using content::WebContents; |
| +using std::map; |
| +using std::pair; |
| + |
| +namespace { |
| + |
| +typedef map<pair<int, int>, JavaObjectWeakGlobalRef> |
| + RenderViewHostToWeakDelegateMapType; |
| + |
| +base::Lock g_map_lock; |
| +RenderViewHostToWeakDelegateMapType g_rvh_to_weak_delegate_map; |
|
joth
2012/09/11 02:06:50
these still need to be lazy instance-ified.
mkosiba (inactive)
2012/09/13 01:48:26
Done.
|
| + |
| +static pair<int, int> GetRenderViewHostIdPair(RenderViewHost* rvh) { |
| + return pair<int, int>(rvh->GetProcess()->GetID(), rvh->GetRoutingID()); |
| +} |
| + |
| +} // namespace |
| + |
| +// JavaDelegateMapMaintainer -------------------------------------------------- |
| + |
| +class JavaDelegateMapMaintainer : public content::WebContentsObserver { |
| + public: |
| + JavaDelegateMapMaintainer(JNIEnv* env, jobject jdelegate, |
| + WebContents* web_contents); |
| + |
| + virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; |
| + virtual void RenderViewForInterstitialPageCreated( |
| + RenderViewHost* render_view_host) OVERRIDE; |
| + virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE; |
| + virtual void WebContentsDestroyed(WebContents* web_contents); |
| + |
| + private: |
| + JavaObjectWeakGlobalRef jdelegate_; |
| +}; |
| + |
| +JavaDelegateMapMaintainer::JavaDelegateMapMaintainer( |
| + JNIEnv* env, jobject jdelegate, WebContents* web_contents) |
| + : content::WebContentsObserver(web_contents), |
| + jdelegate_(env, jdelegate) { |
|
joth
2012/09/11 02:06:50
I think we can remove jdelegate_ member, and then
mkosiba (inactive)
2012/09/13 01:48:26
changed the code to not do this anymore, but in th
|
| + DCHECK(web_contents); |
| + DCHECK(jdelegate); |
| + |
| + if (web_contents->GetRenderViewHost()) { |
| + pair<int, int> rvh_id = GetRenderViewHostIdPair( |
| + web_contents->GetRenderViewHost()); |
| + base::AutoLock lock(g_map_lock); |
| + g_rvh_to_weak_delegate_map[rvh_id] = jdelegate_; |
|
joth
2012/09/11 02:06:50
not sure why I didn't suggest this before, but rat
mkosiba (inactive)
2012/09/13 01:48:26
IMHO the lock-based approach is simpler to read.
|
| + } |
| +} |
| + |
| +void JavaDelegateMapMaintainer::RenderViewCreated(RenderViewHost* rvh) { |
| + pair<int, int> rvh_id = GetRenderViewHostIdPair(rvh); |
| + base::AutoLock lock(g_map_lock); |
| + g_rvh_to_weak_delegate_map[rvh_id] = jdelegate_; |
| +} |
| + |
| +void JavaDelegateMapMaintainer::RenderViewForInterstitialPageCreated( |
| + RenderViewHost* rvh) { |
| + RenderViewCreated(rvh); |
| +} |
| + |
| +void JavaDelegateMapMaintainer::RenderViewDeleted(RenderViewHost* rvh) { |
| + pair<int, int> rvh_id = GetRenderViewHostIdPair(rvh); |
| + base::AutoLock lock(g_map_lock); |
| + g_rvh_to_weak_delegate_map.erase(rvh_id); |
| +} |
| + |
| +void JavaDelegateMapMaintainer::WebContentsDestroyed( |
| + WebContents* web_contents) { |
| + |
| + if (web_contents->GetRenderViewHost()) |
| + RenderViewDeleted(web_contents->GetRenderViewHost()); |
| + |
| + JNIEnv* env = AttachCurrentThread(); |
| + ScopedJavaLocalRef<jobject> java_delegate = jdelegate_.get(env); |
| + if (java_delegate.obj()) { |
| + AwWebContentsIoThreadDelegate io_thread_delegate(java_delegate); |
| + io_thread_delegate.OnWebContentsDestroyed(); |
|
joth
2012/09/11 02:06:50
note this is calling the "IO" thread delegate on t
mkosiba (inactive)
2012/09/13 01:48:26
method removed
|
| + } |
| + |
| + delete this; |
| +} |
| + |
| +// AwWebContentsIoThreadDelegate ---------------------------------------------- |
| + |
| +// JNI Methods ---------------------------------------------------------------- |
| + |
| +void Init(JNIEnv* env, jobject jdelegate, |
| + jint native_web_contents) { |
| + WebContents* web_contents = |
| + reinterpret_cast<WebContents*>(native_web_contents); |
| + // The observer's lifespan is tied to that of the WebContents. |
| + new JavaDelegateMapMaintainer(env, jdelegate, web_contents); |
| +} |
| + |
| +bool AwWebContentsIoThreadDelegate::RegisterAwWebContentsIoThreadDelegate( |
| + JNIEnv* env) { |
| + return RegisterNativesImpl(env); |
| +} |
| + |
| +// Static methods ------------------------------------------------------------- |
| + |
| +scoped_ptr<AwWebContentsIoThreadDelegate> |
| +AwWebContentsIoThreadDelegate::FromID(int render_process_id, |
| + int render_view_id) { |
| + pair<int, int> rvh_id(render_process_id, render_view_id); |
| + base::AutoLock lock(g_map_lock); |
| + RenderViewHostToWeakDelegateMapType::iterator weak_delegate_iterator = |
| + g_rvh_to_weak_delegate_map.find(rvh_id); |
| + if (weak_delegate_iterator == g_rvh_to_weak_delegate_map.end()) |
| + return scoped_ptr<AwWebContentsIoThreadDelegate>(); |
| + |
| + JNIEnv* env = AttachCurrentThread(); |
| + ScopedJavaLocalRef<jobject> java_delegate = |
| + weak_delegate_iterator->second.get(env); |
| + if (java_delegate.is_null()) |
| + return scoped_ptr<AwWebContentsIoThreadDelegate>(); |
| + |
| + return scoped_ptr<AwWebContentsIoThreadDelegate>( |
| + new AwWebContentsIoThreadDelegate(java_delegate)); |
|
joth
2012/09/11 02:06:50
return make_scoped_ptr(new Foo);
mkosiba (inactive)
2012/09/13 01:48:26
Done.
|
| +} |
| + |
| +// regular methods ------------------------------------------------------------ |
| + |
| +AwWebContentsIoThreadDelegate::AwWebContentsIoThreadDelegate( |
| + const JavaRef<jobject>& obj) |
| + : java_object_(obj) { |
| +} |
| + |
| +AwWebContentsIoThreadDelegate::~AwWebContentsIoThreadDelegate() { |
| +} |
| + |
| +void AwWebContentsIoThreadDelegate::OnWebContentsDestroyed() { |
| + JNIEnv* env = AttachCurrentThread(); |
| + Java_AwWebContentsIoThreadDelegate_onWebContentsDestroyed( |
| + env, java_object_.obj()); |
| +} |
| + |
| +scoped_ptr<InterceptedRequestData> |
| +AwWebContentsIoThreadDelegate::ShouldInterceptRequest( |
| + const net::URLRequest* request) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + JNIEnv* env = AttachCurrentThread(); |
| + ScopedJavaLocalRef<jstring> jstring_url = |
| + ConvertUTF8ToJavaString(env, request->url().spec()); |
| + ScopedJavaLocalRef<jobject> ret = |
| + Java_AwWebContentsIoThreadDelegate_shouldInterceptRequest( |
| + env, java_object_.obj(), jstring_url.obj()); |
| + if (ret.is_null()) |
| + return scoped_ptr<InterceptedRequestData>(); |
| + return scoped_ptr<InterceptedRequestData>( |
| + new InterceptedRequestData(ret)); |
| +} |