| Index: ui/android/view_android.cc
|
| diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc
|
| index 41a8c346bf21e9328e54d9af032f614280e6b214..e8be76b47a1bf472a4f61f446d7f5286f56bcca4 100644
|
| --- a/ui/android/view_android.cc
|
| +++ b/ui/android/view_android.cc
|
| @@ -8,19 +8,65 @@
|
|
|
| #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(
|
| + const JavaRef<jobject>& jview,
|
| + const JavaRef<jobject>& jdelegate)
|
| + : view_(jview), delegate_(jdelegate) {
|
| + // If there's a view, then we need a delegate to remove it.
|
| + DCHECK(!jdelegate.is_null() || jview.is_null());
|
| +}
|
| +
|
| +ViewAndroid::ScopedAnchorView::ScopedAnchorView()
|
| + : ScopedAnchorView(nullptr, nullptr) { }
|
| +
|
| +ViewAndroid::ScopedAnchorView::ScopedAnchorView(ScopedAnchorView&& other) {
|
| + JNIEnv* env = base::android::AttachCurrentThread();
|
| + view_.Reset(env, other.view_.Release());
|
| + delegate_.Reset(env, other.delegate_.Release());
|
| +}
|
| +
|
| +ViewAndroid::ScopedAnchorView&
|
| +ViewAndroid::ScopedAnchorView::operator=(ScopedAnchorView&& other) {
|
| + JNIEnv* env = base::android::AttachCurrentThread();
|
| + if (this != &other) {
|
| + view_.Reset(env, other.view_.Release());
|
| + delegate_.Reset(env, other.delegate_.Release());
|
| + }
|
| + return *this;
|
| +}
|
| +
|
| +ViewAndroid::ScopedAnchorView::~ScopedAnchorView() {
|
| + JNIEnv* env = base::android::AttachCurrentThread();
|
| + if (!view_.is_null())
|
| + Java_ViewAndroidDelegate_removeView(env, delegate_.obj(), view_.obj());
|
| + view_.Reset();
|
| +}
|
| +
|
| +void ViewAndroid::ScopedAnchorView::Reset() {
|
| + view_.Reset();
|
| + delegate_.Reset();
|
| +}
|
| +
|
| ViewAndroid::ViewAndroid(const JavaRef<jobject>& delegate,
|
| WindowAndroid* root_window)
|
| - : parent_(nullptr), window_(root_window), delegate_(delegate) {}
|
| + : parent_(nullptr)
|
| + , window_(root_window)
|
| + , delegate_(delegate) {}
|
|
|
| ViewAndroid::ViewAndroid() : parent_(nullptr), window_(nullptr) {}
|
|
|
| +bool ViewAndroid::RegisterViewAndroid(JNIEnv* env) {
|
| + return RegisterNativesImpl(env);
|
| +}
|
| +
|
| ViewAndroid::~ViewAndroid() {
|
| if (parent_)
|
| parent_->RemoveChild(this);
|
| @@ -55,6 +101,52 @@ void ViewAndroid::RemoveChild(ViewAndroid* child) {
|
| child->parent_ = nullptr;
|
| }
|
|
|
| +
|
| +ViewAndroid::ScopedAnchorView ViewAndroid::AcquireAnchorView() {
|
| + ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
|
| + if (delegate.is_null())
|
| + return ViewAndroid::ScopedAnchorView();
|
| +
|
| + JNIEnv* env = base::android::AttachCurrentThread();
|
| + return ViewAndroid::ScopedAnchorView(
|
| + Java_ViewAndroidDelegate_acquireView(env, delegate.obj()),
|
| + delegate);
|
| +}
|
| +
|
| +void ViewAndroid::SetAnchorRect(const JavaRef<jobject>& anchor,
|
| + const gfx::RectF& bounds) {
|
| + if (bounds.IsEmpty()) return;
|
| +
|
| + ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
|
| + if (delegate.is_null())
|
| + return;
|
| +
|
| + JNIEnv* env = base::android::AttachCurrentThread();
|
| + 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);
|
| +}
|
| +
|
| +const JavaRef<jobject>& ViewAndroid::GetViewAndroidDelegate() const {
|
| + if (!delegate_.is_null())
|
| + return delegate_;
|
| +
|
| + return parent_ ? parent_->GetViewAndroidDelegate() : delegate_;
|
| +}
|
| +
|
| WindowAndroid* ViewAndroid::GetWindowAndroid() const {
|
| if (window_)
|
| return window_;
|
| @@ -67,14 +159,6 @@ void ViewAndroid::SetWindowAndroid(WindowAndroid* root_window) {
|
| DCHECK(parent_ == nullptr) << "Children shouldn't have a root window";
|
| }
|
|
|
| -const JavaRef<jobject>& ViewAndroid::GetViewAndroidDelegate()
|
| - const {
|
| - if (!delegate_.is_null())
|
| - return delegate_;
|
| -
|
| - return parent_ ? parent_->GetViewAndroidDelegate() : delegate_;
|
| -}
|
| -
|
| cc::Layer* ViewAndroid::GetLayer() const {
|
| return layer_.get();
|
| }
|
| @@ -85,11 +169,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)
|
| - return;
|
| -
|
| - window_android->StartDragAndDrop(GetViewAndroidDelegate(), jtext, jimage);
|
| + ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate());
|
| + if (delegate.is_null())
|
| + return;
|
| + JNIEnv* env = base::android::AttachCurrentThread();
|
| + Java_ViewAndroidDelegate_startDragAndDrop(env,
|
| + delegate.obj(),
|
| + jtext.obj(),
|
| + jimage.obj());
|
| }
|
|
|
| } // namespace ui
|
|
|