| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/android/content_view_delegate.h" |
| 6 |
| 7 #include "base/android/jni_helper.h" |
| 8 #include "base/android/jni_string.h" |
| 9 #include "base/hash_tables.h" |
| 10 #include "base/memory/linked_ptr.h" |
| 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/synchronization/lock.h" |
| 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "content/public/browser/render_view_host.h" |
| 15 #include "content/public/browser/web_contents.h" |
| 16 #include "content/public/browser/web_contents_observer.h" |
| 17 |
| 18 #include "jni/content_view_delegate_jni.h" |
| 19 |
| 20 using namespace base::android; |
| 21 using content::BrowserThread; |
| 22 using content::RenderViewHost; |
| 23 using content::WebContents; |
| 24 |
| 25 #if defined(COMPILER_GCC) |
| 26 namespace BASE_HASH_NAMESPACE { |
| 27 |
| 28 template<> |
| 29 struct hash<content::WebContents*> { |
| 30 size_t operator()(content::WebContents* value) const { |
| 31 return hash<void*>()(static_cast<void*>(value)); |
| 32 } |
| 33 }; |
| 34 |
| 35 template<> |
| 36 struct hash<content::RenderViewHost*> { |
| 37 size_t operator()(content::RenderViewHost* value) const { |
| 38 return hash<void*>()(static_cast<void*>(value)); |
| 39 } |
| 40 }; |
| 41 |
| 42 } // namespace BASE_HASH_NAMESPACE |
| 43 #endif |
| 44 |
| 45 namespace { |
| 46 |
| 47 typedef linked_ptr<JavaObjectWeakGlobalRef> LinkedJavaWeakRef; |
| 48 typedef base::hash_map<RenderViewHost*, WebContents*> |
| 49 RenderViewHostToWebContentsMapType; |
| 50 typedef std::map<WebContents*, LinkedJavaWeakRef> |
| 51 WebContentsToWeakClientMapType; |
| 52 |
| 53 base::Lock g_map_lock; |
| 54 RenderViewHostToWebContentsMapType g_rvh_to_web_contents_map; |
| 55 WebContentsToWeakClientMapType g_web_contents_to_weak_client_map; |
| 56 |
| 57 } // namespace |
| 58 |
| 59 // WebContentsObserver -------------------------------------------------------- |
| 60 |
| 61 class ContentViewDelegate::WebContentsObserver |
| 62 : public content::WebContentsObserver { |
| 63 public: |
| 64 WebContentsObserver(JNIEnv* env, jobject jobject, WebContents* web_contents); |
| 65 |
| 66 virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; |
| 67 virtual void RenderViewForInterstitialPageCreated( |
| 68 RenderViewHost* render_view_host) OVERRIDE; |
| 69 virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE; |
| 70 virtual void WebContentsDestroyed(WebContents* web_contents); |
| 71 }; |
| 72 |
| 73 ContentViewDelegate::WebContentsObserver::WebContentsObserver( |
| 74 JNIEnv* env, jobject jobject, WebContents* web_contents) |
| 75 : content::WebContentsObserver(web_contents) { |
| 76 DCHECK(web_contents); |
| 77 DCHECK(jobject); |
| 78 LinkedJavaWeakRef linked_weak_ref = LinkedJavaWeakRef( |
| 79 new JavaObjectWeakGlobalRef(env, jobject)); |
| 80 base::AutoLock lock(g_map_lock); |
| 81 g_web_contents_to_weak_client_map[web_contents] = linked_weak_ref; |
| 82 } |
| 83 |
| 84 void ContentViewDelegate::WebContentsObserver::RenderViewCreated( |
| 85 RenderViewHost* rvh) { |
| 86 DCHECK(rvh); |
| 87 DCHECK(web_contents()); |
| 88 base::AutoLock lock(g_map_lock); |
| 89 g_rvh_to_web_contents_map[rvh] = web_contents(); |
| 90 } |
| 91 |
| 92 void |
| 93 ContentViewDelegate::WebContentsObserver::RenderViewForInterstitialPageCreated( |
| 94 RenderViewHost* rvh) { |
| 95 RenderViewCreated(rvh); |
| 96 } |
| 97 |
| 98 void ContentViewDelegate::WebContentsObserver::RenderViewDeleted( |
| 99 RenderViewHost* rvh) { |
| 100 DCHECK(rvh); |
| 101 base::AutoLock lock(g_map_lock); |
| 102 g_rvh_to_web_contents_map.erase(rvh); |
| 103 } |
| 104 |
| 105 void ContentViewDelegate::WebContentsObserver::WebContentsDestroyed( |
| 106 WebContents* web_contents) { |
| 107 scoped_ptr<ContentViewDelegate> content_view_delegate = |
| 108 ContentViewDelegate::ForWebContents(web_contents); |
| 109 if (content_view_delegate.get()) |
| 110 content_view_delegate->OnWebContentsDestroyed(); |
| 111 { |
| 112 base::AutoLock lock(g_map_lock); |
| 113 g_web_contents_to_weak_client_map.erase(web_contents); |
| 114 } |
| 115 delete this; |
| 116 } |
| 117 |
| 118 // ContentViewDelegate -------------------------------------------------------- |
| 119 |
| 120 // JNI Methods ---------------------------------------------------------------- |
| 121 |
| 122 void Init(JNIEnv* env, jobject obj, |
| 123 jint native_web_contents) { |
| 124 WebContents* web_contents = |
| 125 reinterpret_cast<WebContents*>(native_web_contents); |
| 126 // The observer's lifespan is tied to that of the WebContents. |
| 127 new ContentViewDelegate::WebContentsObserver(env, obj, web_contents); |
| 128 } |
| 129 |
| 130 bool ContentViewDelegate::RegisterContentViewDelegate(JNIEnv* env) { |
| 131 return RegisterNativesImpl(env); |
| 132 } |
| 133 |
| 134 // Static methods ------------------------------------------------------------- |
| 135 |
| 136 scoped_ptr<ContentViewDelegate> |
| 137 ContentViewDelegate::ForRenderViewHost(RenderViewHost* rvh) { |
| 138 DCHECK(rvh); |
| 139 WebContents* web_contents = NULL; |
| 140 { |
| 141 base::AutoLock lock(g_map_lock); |
| 142 RenderViewHostToWebContentsMapType::iterator web_contents_iterator = |
| 143 g_rvh_to_web_contents_map.find(rvh); |
| 144 if (web_contents_iterator != g_rvh_to_web_contents_map.end()) |
| 145 web_contents = web_contents_iterator->second; |
| 146 } |
| 147 if (web_contents == NULL) |
| 148 return scoped_ptr<ContentViewDelegate>(); |
| 149 return ForWebContents(web_contents).Pass(); |
| 150 } |
| 151 |
| 152 scoped_ptr<ContentViewDelegate> |
| 153 ContentViewDelegate::ForWebContents(WebContents* web_contents) { |
| 154 DCHECK(web_contents); |
| 155 base::AutoLock lock(g_map_lock); |
| 156 WebContentsToWeakClientMapType::iterator weak_client_iterator = |
| 157 g_web_contents_to_weak_client_map.find(web_contents); |
| 158 if (weak_client_iterator == g_web_contents_to_weak_client_map.end()) |
| 159 return scoped_ptr<ContentViewDelegate>(); |
| 160 |
| 161 JNIEnv* env = AttachCurrentThread(); |
| 162 ScopedJavaLocalRef<jobject> java_client = |
| 163 weak_client_iterator->second->get(env); |
| 164 if (!java_client.obj()) |
| 165 return scoped_ptr<ContentViewDelegate>(); |
| 166 |
| 167 return scoped_ptr<ContentViewDelegate>(); |
| 168 // return scoped_ptr<ContentViewDelegate>( |
| 169 // new ContentViewDelegate(env, jobject)); |
| 170 } |
| 171 |
| 172 // regular methods ------------------------------------------------------------ |
| 173 |
| 174 ContentViewDelegate::ContentViewDelegate(JNIEnv* env, jobject obj) { |
| 175 java_object_.Reset(env, obj); |
| 176 } |
| 177 |
| 178 ContentViewDelegate::~ContentViewDelegate() { |
| 179 } |
| 180 |
| 181 void ContentViewDelegate::OnWebContentsDestroyed() { |
| 182 JNIEnv* env = AttachCurrentThread(); |
| 183 Java_ContentViewDelegate_onWebContentsDestroyed(env, java_object_.obj()); |
| 184 } |
| 185 |
| 186 bool ContentViewDelegate::ShouldIgnoreNavigation( |
| 187 RenderViewHost* source, |
| 188 const GURL& validated_url, |
| 189 const content::Referrer& referrer, |
| 190 bool is_content_initiated) { |
| 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 192 JNIEnv* env = AttachCurrentThread(); |
| 193 ScopedJavaLocalRef<jstring> jstring_url = |
| 194 ConvertUTF8ToJavaString(env, validated_url.spec()); |
| 195 bool ret = Java_ContentViewDelegate_shouldOverrideUrlLoading( |
| 196 env, java_object_.obj(), jstring_url.obj()); |
| 197 return ret; |
| 198 } |
| 199 |
| 200 bool ContentViewDelegate::ShouldInterceptRequest( |
| 201 const net::URLRequest* request) { |
| 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 203 return false; |
| 204 } |
| OLD | NEW |