Chromium Code Reviews| Index: ui/android/view_android.cc |
| diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc |
| index b1ea3608998b81ce71032739ac0ee9da3c88367f..42c359f7cd7a1f25582f6e679a03fb4ae75b621a 100644 |
| --- a/ui/android/view_android.cc |
| +++ b/ui/android/view_android.cc |
| @@ -8,15 +8,68 @@ |
| #include "base/android/jni_android.h" |
| #include "cc/layers/layer.h" |
| +#include "jni/ViewAndroidDelegate_jni.h" |
| #include "ui/android/window_android.h" |
| - |
| +#include "ui/base/layout.h" |
| namespace ui { |
| using base::android::JavaRef; |
| +ViewAndroid::ScopedAnchorView::ScopedAnchorView( |
| + JNIEnv* env, |
| + const JavaRef<jobject>& jview, |
| + const JavaRef<jobject>& jdelegate) |
| + : view_(env, jview.obj()), delegate_(env, jdelegate.obj()) { |
| + // If there's a view, then we need a delegate to remove it. |
| + DCHECK(!jdelegate.is_null() || jview.is_null()); |
| +} |
| + |
| +ViewAndroid::ScopedAnchorView::ScopedAnchorView() { } |
| + |
| +ViewAndroid::ScopedAnchorView::ScopedAnchorView(ScopedAnchorView&& other) { |
| + view_ = other.view_; |
| + other.view_.reset(); |
| + delegate_ = other.delegate_; |
| + other.delegate_.reset(); |
| +} |
| + |
| +ViewAndroid::ScopedAnchorView& |
| +ViewAndroid::ScopedAnchorView::operator=(ScopedAnchorView&& other) { |
| + if (this != &other) { |
| + view_ = other.view_; |
| + other.view_.reset(); |
| + delegate_ = other.delegate_; |
| + other.delegate_.reset(); |
| + } |
| + return *this; |
| +} |
| + |
| +ViewAndroid::ScopedAnchorView::~ScopedAnchorView() { |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + if (!view_.is_empty()) { |
| + Java_ViewAndroidDelegate_removeView(env, |
| + delegate_.get(env).obj(), |
|
boliu
2016/07/29 20:05:15
null check delegate_
Jinsuk Kim
2016/08/01 02:02:47
view_ != null && delegate_ == null is DCHECK'd in
|
| + view_.get(env).obj()); |
| + } |
| + view_.reset(); |
| +} |
| + |
| +void ViewAndroid::ScopedAnchorView::Reset() { |
| + view_.reset(); |
| + delegate_.reset(); |
| +} |
| + |
| +const base::android::ScopedJavaLocalRef<jobject> |
| +ViewAndroid::ScopedAnchorView::view() const { |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + return view_.get(env); |
| +} |
| + |
| ViewAndroid::ViewAndroid(const JavaRef<jobject>& delegate) |
| - : parent_(nullptr), delegate_(delegate) {} |
| + : parent_(nullptr) |
| + , delegate_(base::android::AttachCurrentThread(), |
| + delegate.obj()) {} |
| ViewAndroid::ViewAndroid() : parent_(nullptr) {} |
| @@ -30,6 +83,10 @@ ViewAndroid::~ViewAndroid() { |
| } |
| } |
| +bool ViewAndroid::RegisterViewAndroid(JNIEnv* env) { |
| + return RegisterNativesImpl(env); |
| +} |
| + |
| void ViewAndroid::AddChild(ViewAndroid* child) { |
| DCHECK(child); |
| DCHECK(std::find(children_.begin(), children_.end(), child) == |
| @@ -46,6 +103,47 @@ void ViewAndroid::RemoveFromParent() { |
| parent_->RemoveChild(this); |
| } |
| +ViewAndroid::ScopedAnchorView ViewAndroid::AcquireAnchorView() { |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + ScopedJavaLocalRef<jobject> delegate(delegate_.get(env)); |
| + if (delegate.is_null()) |
| + return parent_ ? parent_->AcquireAnchorView() |
| + : ViewAndroid::ScopedAnchorView(); |
| + |
| + return ViewAndroid::ScopedAnchorView( |
| + env, |
| + Java_ViewAndroidDelegate_acquireView(env, delegate.obj()), |
| + delegate); |
| +} |
| + |
| +void ViewAndroid::SetAnchorRect(const JavaRef<jobject>& anchor, |
| + const gfx::RectF& bounds) { |
| + if (bounds.IsEmpty()) |
| + return; |
| + |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + ScopedJavaLocalRef<jobject> delegate(delegate_.get(env)); |
| + if (delegate.is_null()) |
| + return; |
| + |
| + float scale = GetScaleFactorForNativeView(this); |
| + int left_margin = std::round(bounds.x() * scale); |
| + // TODO(jinsukkim): Move content_offset() to ViewAndroid, since it's |
| + // specific to a given web contents/render widget. |
| + float content_offset_y_pix = GetWindowAndroid()->content_offset().y(); |
| + int top_margin = std::round(content_offset_y_pix + bounds.y() * scale); |
| + Java_ViewAndroidDelegate_setViewPosition(env, |
| + delegate.obj(), |
| + anchor.obj(), |
| + bounds.x(), |
| + bounds.y(), |
| + bounds.width(), |
| + bounds.height(), |
| + scale, |
| + left_margin, |
| + top_margin); |
| +} |
| + |
| void ViewAndroid::RemoveChild(ViewAndroid* child) { |
| DCHECK(child); |
| DCHECK_EQ(child->parent_, this); |
| @@ -61,12 +159,13 @@ WindowAndroid* ViewAndroid::GetWindowAndroid() const { |
| return parent_ ? parent_->GetWindowAndroid() : nullptr; |
| } |
| -const JavaRef<jobject>& ViewAndroid::GetViewAndroidDelegate() |
| - const { |
| - if (!delegate_.is_null()) |
| - return delegate_; |
| +const JavaRef<jobject>& ViewAndroid::GetViewAndroidDelegate() const { |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + const ScopedJavaLocalRef<jobject>& delegate = delegate_.get(env); |
|
boliu
2016/07/29 20:05:15
ditto
sgurun-gerrit only
2016/07/29 23:44:06
and also what clang caught:
/include -fno-except
Jinsuk Kim
2016/08/01 02:02:47
Fixed
Jinsuk Kim
2016/08/01 02:02:47
Done.
|
| + if (!delegate.is_null()) |
| + return delegate; |
| - return parent_ ? parent_->GetViewAndroidDelegate() : delegate_; |
| + return parent_ ? parent_->GetViewAndroidDelegate() : delegate; |
| } |
| cc::Layer* ViewAndroid::GetLayer() const { |
| @@ -79,11 +178,14 @@ void ViewAndroid::SetLayer(scoped_refptr<cc::Layer> layer) { |
| void ViewAndroid::StartDragAndDrop(const JavaRef<jstring>& jtext, |
| const JavaRef<jobject>& jimage) { |
| - WindowAndroid* window_android = GetWindowAndroid(); |
| - if (!window_android) |
| + ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); |
| + if (delegate.is_null()) |
| return; |
| - |
| - window_android->StartDragAndDrop(GetViewAndroidDelegate(), jtext, jimage); |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + Java_ViewAndroidDelegate_startDragAndDrop(env, |
| + delegate.obj(), |
| + jtext.obj(), |
| + jimage.obj()); |
| } |
| } // namespace ui |