| Index: chrome/browser/android/content_view_delegate.cc
|
| diff --git a/chrome/browser/android/content_view_delegate.cc b/chrome/browser/android/content_view_delegate.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fa6067609689e5b1583c29a24c30fad81db7ac74
|
| --- /dev/null
|
| +++ b/chrome/browser/android/content_view_delegate.cc
|
| @@ -0,0 +1,204 @@
|
| +// 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 "chrome/browser/android/content_view_delegate.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/web_contents.h"
|
| +#include "content/public/browser/web_contents_observer.h"
|
| +
|
| +#include "jni/content_view_delegate_jni.h"
|
| +
|
| +using namespace base::android;
|
| +using content::BrowserThread;
|
| +using content::RenderViewHost;
|
| +using content::WebContents;
|
| +
|
| +#if defined(COMPILER_GCC)
|
| +namespace BASE_HASH_NAMESPACE {
|
| +
|
| +template<>
|
| +struct hash<content::WebContents*> {
|
| + size_t operator()(content::WebContents* value) const {
|
| + return hash<void*>()(static_cast<void*>(value));
|
| + }
|
| +};
|
| +
|
| +template<>
|
| +struct hash<content::RenderViewHost*> {
|
| + size_t operator()(content::RenderViewHost* value) const {
|
| + return hash<void*>()(static_cast<void*>(value));
|
| + }
|
| +};
|
| +
|
| +} // namespace BASE_HASH_NAMESPACE
|
| +#endif
|
| +
|
| +namespace {
|
| +
|
| +typedef linked_ptr<JavaObjectWeakGlobalRef> LinkedJavaWeakRef;
|
| +typedef base::hash_map<RenderViewHost*, WebContents*>
|
| + RenderViewHostToWebContentsMapType;
|
| +typedef std::map<WebContents*, LinkedJavaWeakRef>
|
| + WebContentsToWeakClientMapType;
|
| +
|
| +base::Lock g_map_lock;
|
| +RenderViewHostToWebContentsMapType g_rvh_to_web_contents_map;
|
| +WebContentsToWeakClientMapType g_web_contents_to_weak_client_map;
|
| +
|
| +} // namespace
|
| +
|
| +// WebContentsObserver --------------------------------------------------------
|
| +
|
| +class ContentViewDelegate::WebContentsObserver
|
| + : public content::WebContentsObserver {
|
| + public:
|
| + WebContentsObserver(JNIEnv* env, jobject jobject, 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);
|
| +};
|
| +
|
| +ContentViewDelegate::WebContentsObserver::WebContentsObserver(
|
| + JNIEnv* env, jobject jobject, WebContents* web_contents)
|
| + : content::WebContentsObserver(web_contents) {
|
| + DCHECK(web_contents);
|
| + DCHECK(jobject);
|
| + LinkedJavaWeakRef linked_weak_ref = LinkedJavaWeakRef(
|
| + new JavaObjectWeakGlobalRef(env, jobject));
|
| + base::AutoLock lock(g_map_lock);
|
| + g_web_contents_to_weak_client_map[web_contents] = linked_weak_ref;
|
| +}
|
| +
|
| +void ContentViewDelegate::WebContentsObserver::RenderViewCreated(
|
| + RenderViewHost* rvh) {
|
| + DCHECK(rvh);
|
| + DCHECK(web_contents());
|
| + base::AutoLock lock(g_map_lock);
|
| + g_rvh_to_web_contents_map[rvh] = web_contents();
|
| +}
|
| +
|
| +void
|
| +ContentViewDelegate::WebContentsObserver::RenderViewForInterstitialPageCreated(
|
| + RenderViewHost* rvh) {
|
| + RenderViewCreated(rvh);
|
| +}
|
| +
|
| +void ContentViewDelegate::WebContentsObserver::RenderViewDeleted(
|
| + RenderViewHost* rvh) {
|
| + DCHECK(rvh);
|
| + base::AutoLock lock(g_map_lock);
|
| + g_rvh_to_web_contents_map.erase(rvh);
|
| +}
|
| +
|
| +void ContentViewDelegate::WebContentsObserver::WebContentsDestroyed(
|
| + WebContents* web_contents) {
|
| + scoped_ptr<ContentViewDelegate> content_view_delegate =
|
| + ContentViewDelegate::ForWebContents(web_contents);
|
| + if (content_view_delegate.get())
|
| + content_view_delegate->OnWebContentsDestroyed();
|
| + {
|
| + base::AutoLock lock(g_map_lock);
|
| + g_web_contents_to_weak_client_map.erase(web_contents);
|
| + }
|
| + delete this;
|
| +}
|
| +
|
| +// ContentViewDelegate --------------------------------------------------------
|
| +
|
| +// JNI Methods ----------------------------------------------------------------
|
| +
|
| +void Init(JNIEnv* env, jobject obj,
|
| + 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 ContentViewDelegate::WebContentsObserver(env, obj, web_contents);
|
| +}
|
| +
|
| +bool ContentViewDelegate::RegisterContentViewDelegate(JNIEnv* env) {
|
| + return RegisterNativesImpl(env);
|
| +}
|
| +
|
| +// Static methods -------------------------------------------------------------
|
| +
|
| +scoped_ptr<ContentViewDelegate>
|
| +ContentViewDelegate::ForRenderViewHost(RenderViewHost* rvh) {
|
| + DCHECK(rvh);
|
| + WebContents* web_contents = NULL;
|
| + {
|
| + base::AutoLock lock(g_map_lock);
|
| + RenderViewHostToWebContentsMapType::iterator web_contents_iterator =
|
| + g_rvh_to_web_contents_map.find(rvh);
|
| + if (web_contents_iterator != g_rvh_to_web_contents_map.end())
|
| + web_contents = web_contents_iterator->second;
|
| + }
|
| + if (web_contents == NULL)
|
| + return scoped_ptr<ContentViewDelegate>();
|
| + return ForWebContents(web_contents).Pass();
|
| +}
|
| +
|
| +scoped_ptr<ContentViewDelegate>
|
| +ContentViewDelegate::ForWebContents(WebContents* web_contents) {
|
| + DCHECK(web_contents);
|
| + base::AutoLock lock(g_map_lock);
|
| + WebContentsToWeakClientMapType::iterator weak_client_iterator =
|
| + g_web_contents_to_weak_client_map.find(web_contents);
|
| + if (weak_client_iterator == g_web_contents_to_weak_client_map.end())
|
| + return scoped_ptr<ContentViewDelegate>();
|
| +
|
| + JNIEnv* env = AttachCurrentThread();
|
| + ScopedJavaLocalRef<jobject> java_client =
|
| + weak_client_iterator->second->get(env);
|
| + if (!java_client.obj())
|
| + return scoped_ptr<ContentViewDelegate>();
|
| +
|
| + return scoped_ptr<ContentViewDelegate>();
|
| +// return scoped_ptr<ContentViewDelegate>(
|
| +// new ContentViewDelegate(env, jobject));
|
| +}
|
| +
|
| +// regular methods ------------------------------------------------------------
|
| +
|
| +ContentViewDelegate::ContentViewDelegate(JNIEnv* env, jobject obj) {
|
| + java_object_.Reset(env, obj);
|
| +}
|
| +
|
| +ContentViewDelegate::~ContentViewDelegate() {
|
| +}
|
| +
|
| +void ContentViewDelegate::OnWebContentsDestroyed() {
|
| + JNIEnv* env = AttachCurrentThread();
|
| + Java_ContentViewDelegate_onWebContentsDestroyed(env, java_object_.obj());
|
| +}
|
| +
|
| +bool ContentViewDelegate::ShouldIgnoreNavigation(
|
| + RenderViewHost* source,
|
| + const GURL& validated_url,
|
| + const content::Referrer& referrer,
|
| + bool is_content_initiated) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + JNIEnv* env = AttachCurrentThread();
|
| + ScopedJavaLocalRef<jstring> jstring_url =
|
| + ConvertUTF8ToJavaString(env, validated_url.spec());
|
| + bool ret = Java_ContentViewDelegate_shouldOverrideUrlLoading(
|
| + env, java_object_.obj(), jstring_url.obj());
|
| + return ret;
|
| +}
|
| +
|
| +bool ContentViewDelegate::ShouldInterceptRequest(
|
| + const net::URLRequest* request) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return false;
|
| +}
|
|
|