Chromium Code Reviews| Index: content/browser/android/content_view_core_impl.cc |
| diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc |
| index 273fd5f8c66772f9f2ca36f2fc7e8144457081e2..61b86e261da0197f268eca0766cbef9a6cba232d 100644 |
| --- a/content/browser/android/content_view_core_impl.cc |
| +++ b/content/browser/android/content_view_core_impl.cc |
| @@ -65,24 +65,63 @@ enum PopupItemType { |
| POPUP_ITEM_TYPE_ENABLED |
| }; |
| +namespace content { |
| + |
| namespace { |
| jfieldID g_native_content_view; |
| + |
| +const void* kContentViewUserDataKey = &kContentViewUserDataKey; |
| } // namespace |
| -namespace content { |
| +// Enables a callback when the underlying WebContents is destroyed, to enable |
| +// nulling the back-pointer. |
| +class ContentViewCoreImpl::ContentViewUserData |
| + : public base::SupportsUserData::Data { |
| + public: |
| + ContentViewUserData(ContentViewCoreImpl* content_view_core) |
|
Jay Civelli
2012/10/15 17:11:49
explicit
joth
2012/10/15 20:11:35
Done.
|
| + : content_view_core_(content_view_core) { |
| + } |
| + |
| + virtual ~ContentViewUserData() { |
| + // TODO(joth): When chrome has finished removing the TabContents class (see |
| + // crbug.com/107201) consider inverting relationship, so ContentViewCore |
| + // would own WebContents. The effectively requires making the WebContents |
|
joth
2012/10/13 17:53:30
=> That effectively implies
joth
2012/10/15 20:11:35
Done.
|
| + // destructor private on Android. |
| + delete content_view_core_; |
| + } |
| + |
| + ContentViewCoreImpl* get() { return content_view_core_; } |
|
Jay Civelli
2012/10/15 17:11:49
const
joth
2012/10/15 20:11:35
Done.
|
| + |
| + private: |
| + ContentViewCoreImpl* content_view_core_; |
|
joth
2012/10/13 17:53:30
// Not using scoped_ptr as ContentViewCoreImpl des
joth
2012/10/15 20:11:35
Done.
|
| +}; |
|
Jay Civelli
2012/10/15 17:11:49
DISALLOW_...
joth
2012/10/15 20:11:35
Done.
|
| struct ContentViewCoreImpl::JavaObject { |
| ScopedJavaGlobalRef<jclass> rect_clazz; |
| jmethodID rect_constructor; |
| }; |
| +// static |
| +ContentViewCoreImpl* ContentViewCoreImpl::FromWebContents( |
| + content::WebContents* web_contents) { |
| + ContentViewCoreImpl::ContentViewUserData* data = |
| + reinterpret_cast<ContentViewCoreImpl::ContentViewUserData*>( |
| + web_contents->GetUserData(kContentViewUserDataKey)); |
| + return data ? data->get() : NULL; |
| +} |
| + |
| +// static |
| +ContentViewCore* ContentViewCore::FromWebContents( |
| + content::WebContents* web_contents) { |
| + return ContentViewCoreImpl::FromWebContents(web_contents); |
| +} |
| + |
| ContentViewCore* ContentViewCore::GetNativeContentViewCore(JNIEnv* env, |
| jobject obj) { |
| return reinterpret_cast<ContentViewCore*>( |
| env->GetIntField(obj, g_native_content_view)); |
| } |
| - |
| ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, |
| bool hardware_accelerated, |
| WebContents* web_contents, |
| @@ -119,31 +158,42 @@ ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, |
| webkit_glue::BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product); |
| web_contents->SetUserAgentOverride(spoofed_ua); |
| - InitWebContents(web_contents); |
| + InitWebContents(); |
| } |
| ContentViewCoreImpl::~ContentViewCoreImpl() { |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); |
| + java_ref_.reset(); |
| + if (!j_obj.is_null()) { |
| + Java_ContentViewCore_onNativeContentViewCoreDestroyed( |
| + env, j_obj.obj(), reinterpret_cast<jint>(this)); |
| + } |
| // Make sure nobody calls back into this object while we are tearing things |
| // down. |
| notification_registrar_.RemoveAll(); |
| delete java_object_; |
| java_object_ = NULL; |
| - java_ref_.reset(); |
| } |
| -void ContentViewCoreImpl::Destroy(JNIEnv* env, jobject obj) { |
| - delete this; |
| +void ContentViewCoreImpl::OnJavaContentViewCoreDestroyed(JNIEnv* env, |
| + jobject obj) { |
| + DCHECK(env->IsSameObject(java_ref_.get(env).obj(), obj)); |
| + java_ref_.reset(); |
| } |
| -void ContentViewCoreImpl::InitWebContents(WebContents* web_contents) { |
| - web_contents_ = static_cast<WebContentsImpl*>(web_contents); |
| +void ContentViewCoreImpl::InitWebContents() { |
| + DCHECK(web_contents_); |
| notification_registrar_.Add(this, |
| NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
| Source<NavigationController>(&web_contents_->GetController())); |
| static_cast<WebContentsViewAndroid*>(web_contents_->GetView())-> |
| SetContentViewCore(this); |
| + DCHECK(!web_contents_->GetUserData(kContentViewUserDataKey)); |
| + web_contents_->SetUserData(kContentViewUserDataKey, |
| + new ContentViewUserData(this)); |
| } |
| void ContentViewCoreImpl::Observe(int type, |