OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/android/view_android.h" | 5 #include "ui/android/view_android.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
10 #include "cc/layers/layer.h" | 10 #include "cc/layers/layer.h" |
11 #include "jni/ViewAndroidDelegate_jni.h" | 11 #include "jni/ViewAndroidDelegate_jni.h" |
12 #include "jni/ViewRoot_jni.h" | |
13 #include "ui/android/view_client.h" | |
14 #include "ui/android/window_android.h" | 12 #include "ui/android/window_android.h" |
15 #include "ui/display/display.h" | 13 #include "ui/display/display.h" |
16 #include "ui/display/screen.h" | 14 #include "ui/display/screen.h" |
17 | 15 |
18 namespace ui { | 16 namespace ui { |
19 | 17 |
20 using base::android::JavaParamRef; | |
21 using base::android::JavaRef; | 18 using base::android::JavaRef; |
22 using base::android::ScopedJavaLocalRef; | 19 using base::android::ScopedJavaLocalRef; |
23 | 20 |
24 ViewAndroid::ScopedAnchorView::ScopedAnchorView( | 21 ViewAndroid::ScopedAnchorView::ScopedAnchorView( |
25 JNIEnv* env, | 22 JNIEnv* env, |
26 const JavaRef<jobject>& jview, | 23 const JavaRef<jobject>& jview, |
27 const JavaRef<jobject>& jdelegate) | 24 const JavaRef<jobject>& jdelegate) |
28 : view_(env, jview.obj()), delegate_(env, jdelegate.obj()) { | 25 : view_(env, jview.obj()), delegate_(env, jdelegate.obj()) { |
29 // If there's a view, then we need a delegate to remove it. | 26 // If there's a view, then we need a delegate to remove it. |
30 DCHECK(!jdelegate.is_null() || jview.is_null()); | 27 DCHECK(!jdelegate.is_null() || jview.is_null()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 view_.reset(); | 61 view_.reset(); |
65 delegate_.reset(); | 62 delegate_.reset(); |
66 } | 63 } |
67 | 64 |
68 const base::android::ScopedJavaLocalRef<jobject> | 65 const base::android::ScopedJavaLocalRef<jobject> |
69 ViewAndroid::ScopedAnchorView::view() const { | 66 ViewAndroid::ScopedAnchorView::view() const { |
70 JNIEnv* env = base::android::AttachCurrentThread(); | 67 JNIEnv* env = base::android::AttachCurrentThread(); |
71 return view_.get(env); | 68 return view_.get(env); |
72 } | 69 } |
73 | 70 |
74 ViewAndroid::ViewAndroid(ViewClient* client) : parent_(nullptr), | 71 ViewAndroid::ViewAndroid(const JavaRef<jobject>& delegate) |
75 client_(client), | 72 : parent_(nullptr) |
76 physical_width_pix_(0), | 73 , delegate_(base::android::AttachCurrentThread(), |
77 physical_height_pix_(0) {} | 74 delegate.obj()) {} |
78 ViewAndroid::ViewAndroid() : ViewAndroid(nullptr) {} | 75 |
| 76 ViewAndroid::ViewAndroid() : parent_(nullptr) {} |
79 | 77 |
80 ViewAndroid::~ViewAndroid() { | 78 ViewAndroid::~ViewAndroid() { |
81 RemoveFromParent(); | 79 RemoveFromParent(); |
82 | 80 |
83 for (auto& child : children_) { | 81 for (std::list<ViewAndroid*>::iterator it = children_.begin(); |
84 DCHECK_EQ(child->parent_, this); | 82 it != children_.end(); it++) { |
85 child->parent_ = nullptr; | 83 DCHECK_EQ((*it)->parent_, this); |
| 84 (*it)->parent_ = nullptr; |
86 } | 85 } |
87 | |
88 JNIEnv* env = base::android::AttachCurrentThread(); | |
89 const ScopedJavaLocalRef<jobject> view_root = view_root_.get(env); | |
90 if (!view_root.is_null()) | |
91 Java_ViewRoot_onDestroyNativeView(env, view_root); | |
92 } | 86 } |
93 | 87 |
94 void ViewAndroid::SetDelegate(const JavaRef<jobject>& delegate) { | 88 void ViewAndroid::SetDelegate(const JavaRef<jobject>& delegate) { |
95 // A ViewAndroid may have its own delegate or otherwise will | |
96 // use the next available parent's delegate. | |
97 JNIEnv* env = base::android::AttachCurrentThread(); | 89 JNIEnv* env = base::android::AttachCurrentThread(); |
98 delegate_ = JavaObjectWeakGlobalRef(env, delegate); | 90 delegate_ = JavaObjectWeakGlobalRef(env, delegate); |
99 } | 91 } |
100 | 92 |
101 void ViewAndroid::AddChild(ViewAndroid* child) { | 93 void ViewAndroid::AddChild(ViewAndroid* child) { |
102 DCHECK(child); | 94 DCHECK(child); |
103 DCHECK(std::find(children_.begin(), children_.end(), child) == | 95 DCHECK(std::find(children_.begin(), children_.end(), child) == |
104 children_.end()); | 96 children_.end()); |
105 DCHECK(!HasViewRootInTreeHierarchy() || | |
106 !child->HasViewRootInSubtree()); | |
107 | 97 |
108 children_.push_back(child); | 98 children_.push_back(child); |
109 if (child->parent_) | 99 if (child->parent_) |
110 child->RemoveFromParent(); | 100 child->RemoveFromParent(); |
111 child->parent_ = this; | 101 child->parent_ = this; |
112 if (physical_width_pix_ || physical_height_pix_) { | |
113 child->OnPhysicalBackingSizeChanged(physical_width_pix_, | |
114 physical_height_pix_); | |
115 } | |
116 } | 102 } |
117 | 103 |
118 void ViewAndroid::RemoveFromParent() { | 104 void ViewAndroid::RemoveFromParent() { |
119 if (parent_) | 105 if (parent_) |
120 parent_->RemoveChild(this); | 106 parent_->RemoveChild(this); |
121 } | 107 } |
122 | 108 |
123 ViewAndroid::ScopedAnchorView ViewAndroid::AcquireAnchorView() { | 109 ViewAndroid::ScopedAnchorView ViewAndroid::AcquireAnchorView() { |
124 ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); | 110 ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); |
125 if (delegate.is_null()) | 111 if (delegate.is_null()) |
(...skipping 29 matching lines...) Expand all Loading... |
155 std::find(children_.begin(), children_.end(), child); | 141 std::find(children_.begin(), children_.end(), child); |
156 DCHECK(it != children_.end()); | 142 DCHECK(it != children_.end()); |
157 children_.erase(it); | 143 children_.erase(it); |
158 child->parent_ = nullptr; | 144 child->parent_ = nullptr; |
159 } | 145 } |
160 | 146 |
161 WindowAndroid* ViewAndroid::GetWindowAndroid() const { | 147 WindowAndroid* ViewAndroid::GetWindowAndroid() const { |
162 return parent_ ? parent_->GetWindowAndroid() : nullptr; | 148 return parent_ ? parent_->GetWindowAndroid() : nullptr; |
163 } | 149 } |
164 | 150 |
165 ScopedJavaLocalRef<jobject> ViewAndroid::CreateViewRoot() { | |
166 JNIEnv* env = base::android::AttachCurrentThread(); | |
167 return Java_ViewRoot_create(env, reinterpret_cast<intptr_t>(this)); | |
168 } | |
169 | |
170 bool ViewAndroid::HasViewRoot() { | |
171 return !view_root_.is_uninitialized(); | |
172 } | |
173 | |
174 const ScopedJavaLocalRef<jobject> ViewAndroid::GetViewAndroidDelegate() | 151 const ScopedJavaLocalRef<jobject> ViewAndroid::GetViewAndroidDelegate() |
175 const { | 152 const { |
176 JNIEnv* env = base::android::AttachCurrentThread(); | 153 JNIEnv* env = base::android::AttachCurrentThread(); |
177 const ScopedJavaLocalRef<jobject> delegate = delegate_.get(env); | 154 const ScopedJavaLocalRef<jobject> delegate = delegate_.get(env); |
178 if (!delegate.is_null()) | 155 if (!delegate.is_null()) |
179 return delegate; | 156 return delegate; |
180 | 157 |
181 return parent_ ? parent_->GetViewAndroidDelegate() : delegate; | 158 return parent_ ? parent_->GetViewAndroidDelegate() : delegate; |
182 } | 159 } |
183 | 160 |
184 cc::Layer* ViewAndroid::GetLayer() const { | 161 cc::Layer* ViewAndroid::GetLayer() const { |
185 return layer_.get(); | 162 return layer_.get(); |
186 } | 163 } |
187 | 164 |
188 void ViewAndroid::SetLayer(scoped_refptr<cc::Layer> layer) { | 165 void ViewAndroid::SetLayer(scoped_refptr<cc::Layer> layer) { |
189 layer_ = layer; | 166 layer_ = layer; |
190 UpdateLayerBounds(); | |
191 } | |
192 | |
193 ScopedJavaLocalRef<jobject> ViewAndroid::GetViewRoot() { | |
194 JNIEnv* env = base::android::AttachCurrentThread(); | |
195 const ScopedJavaLocalRef<jobject> view_root = view_root_.get(env); | |
196 if (!view_root.is_null()) | |
197 return view_root; | |
198 | |
199 DCHECK(!HasViewRootInTreeHierarchy()); | |
200 view_root_ = JavaObjectWeakGlobalRef(env, CreateViewRoot()); | |
201 return view_root_.get(env); | |
202 } | |
203 | |
204 bool ViewAndroid::HasViewRootInTreeHierarchy() { | |
205 ViewAndroid* view = parent_; | |
206 while (view) { | |
207 if (view->HasViewRoot()) | |
208 return true; | |
209 view = view->parent_; | |
210 } | |
211 return HasViewRootInSubtree(); | |
212 } | |
213 | |
214 bool ViewAndroid::HasViewRootInSubtree() { | |
215 if (HasViewRoot()) | |
216 return true; | |
217 for (auto& child : children_) { | |
218 if (child->HasViewRootInSubtree()) | |
219 return true; | |
220 } | |
221 return false; | |
222 } | 167 } |
223 | 168 |
224 bool ViewAndroid::StartDragAndDrop(const JavaRef<jstring>& jtext, | 169 bool ViewAndroid::StartDragAndDrop(const JavaRef<jstring>& jtext, |
225 const JavaRef<jobject>& jimage) { | 170 const JavaRef<jobject>& jimage) { |
226 ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); | 171 ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); |
227 if (delegate.is_null()) | 172 if (delegate.is_null()) |
228 return false; | 173 return false; |
229 JNIEnv* env = base::android::AttachCurrentThread(); | 174 JNIEnv* env = base::android::AttachCurrentThread(); |
230 return Java_ViewAndroidDelegate_startDragAndDrop(env, delegate, jtext, | 175 return Java_ViewAndroidDelegate_startDragAndDrop(env, delegate, jtext, |
231 jimage); | 176 jimage); |
232 } | 177 } |
233 | 178 |
234 gfx::Size ViewAndroid::GetPhysicalBackingSize() { | |
235 return gfx::Size(physical_width_pix_, physical_height_pix_); | |
236 } | |
237 | |
238 void ViewAndroid::UpdateLayerBounds() { | |
239 if (layer_) | |
240 layer_->SetBounds(GetPhysicalBackingSize()); | |
241 } | |
242 | |
243 void ViewAndroid::OnPhysicalBackingSizeChanged(int width, int height) { | |
244 if (width == physical_width_pix_ && height == physical_height_pix_) | |
245 return; | |
246 | |
247 physical_width_pix_ = width; | |
248 physical_height_pix_ = height; | |
249 UpdateLayerBounds(); | |
250 | |
251 if (client_) | |
252 client_->OnPhysicalBackingSizeChanged(width, height); | |
253 | |
254 for (auto& child : children_) | |
255 child->OnPhysicalBackingSizeChanged(width, height); | |
256 } | |
257 | |
258 // static | |
259 void OnPhysicalBackingSizeChanged(JNIEnv* env, | |
260 const JavaParamRef<jclass>& jcaller, | |
261 jlong native_view, | |
262 int width, | |
263 int height) { | |
264 ViewAndroid* view_android = reinterpret_cast<ViewAndroid*>(native_view); | |
265 view_android->OnPhysicalBackingSizeChanged(width, height); | |
266 } | |
267 | |
268 bool RegisterViewRoot(JNIEnv* env) { | |
269 return RegisterNativesImpl(env); | |
270 } | |
271 | |
272 } // namespace ui | 179 } // namespace ui |
OLD | NEW |