1 // Copyright 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.
5 #include "content/browser/android/content_view_core_impl.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h"
10 #include "base/android/scoped_java_ref.h"
11 #include "base/command_line.h"
12 #include "base/logging.h"
13 #include "base/metrics/histogram.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/values.h"
16 #include "cc/layers/layer.h"
17 #include "cc/layers/solid_color_layer.h"
18 #include "cc/output/begin_frame_args.h"
19 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
20 #include "content/browser/android/gesture_event_type.h"
21 #include "content/browser/android/interstitial_page_delegate_android.h"
22 #include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
23 #include "content/browser/android/load_url_params.h"
24 #include "content/browser/android/popup_touch_handle_drawable.h"
25 #include "content/browser/frame_host/interstitial_page_impl.h"
26 #include "content/browser/geolocation/geolocation_service_context.h"
27 #include "content/browser/media/media_web_contents_observer.h"
28 #include "content/browser/renderer_host/compositor_impl_android.h"
29 #include "content/browser/renderer_host/input/motion_event_android.h"
30 #include "content/browser/renderer_host/input/web_input_event_builders_android.h"
31 #include "content/browser/renderer_host/input/web_input_event_util.h"
32 #include "content/browser/renderer_host/render_view_host_impl.h"
33 #include "content/browser/renderer_host/render_widget_host_impl.h"
34 #include "content/browser/renderer_host/render_widget_host_view_android.h"
35 #include "content/browser/web_contents/web_contents_view_android.h"
36 #include "content/common/frame_messages.h"
37 #include "content/common/input/web_input_event_traits.h"
38 #include "content/common/input_messages.h"
39 #include "content/common/view_messages.h"
40 #include "content/public/browser/android/compositor.h"
41 #include "content/public/browser/browser_context.h"
42 #include "content/public/browser/browser_thread.h"
43 #include "content/public/browser/favicon_status.h"
44 #include "content/public/browser/render_frame_host.h"
45 #include "content/public/browser/screen_orientation_dispatcher_host.h"
46 #include "content/public/browser/ssl_host_state_delegate.h"
47 #include "content/public/browser/web_contents.h"
48 #include "content/public/common/content_client.h"
49 #include "content/public/common/content_switches.h"
50 #include "content/public/common/menu_item.h"
51 #include "content/public/common/user_agent.h"
52 #include "jni/ContentViewCore_jni.h"
53 #include "third_party/WebKit/public/web/WebInputEvent.h"
54 #include "ui/android/view_android.h"
55 #include "ui/android/window_android.h"
56 #include "ui/gfx/android/java_bitmap.h"
57 #include "ui/gfx/geometry/point_conversions.h"
58 #include "ui/gfx/geometry/size_conversions.h"
59 #include "ui/gfx/geometry/size_f.h"
61 using base::android::AttachCurrentThread
;
62 using base::android::ConvertJavaStringToUTF16
;
63 using base::android::ConvertJavaStringToUTF8
;
64 using base::android::ConvertUTF16ToJavaString
;
65 using base::android::ConvertUTF8ToJavaString
;
66 using base::android::ScopedJavaLocalRef
;
67 using blink::WebGestureEvent
;
68 using blink::WebInputEvent
;
70 // Describes the type and enabled state of a select popup item.
73 // A Java counterpart will be generated for this enum.
74 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.browser.input
76 // Popup item is of type group
77 POPUP_ITEM_TYPE_GROUP
,
79 // Popup item is disabled
80 POPUP_ITEM_TYPE_DISABLED
,
82 // Popup item is enabled
83 POPUP_ITEM_TYPE_ENABLED
,
92 const void* kContentViewUserDataKey
= &kContentViewUserDataKey
;
94 int GetRenderProcessIdFromRenderViewHost(RenderViewHost
* host
) {
96 RenderProcessHost
* render_process
= host
->GetProcess();
97 DCHECK(render_process
);
98 if (render_process
->HasConnection())
99 return render_process
->GetHandle();
104 ScopedJavaLocalRef
<jobject
> CreateJavaRect(
106 const gfx::Rect
& rect
) {
107 return ScopedJavaLocalRef
<jobject
>(
108 Java_ContentViewCore_createRect(env
,
109 static_cast<int>(rect
.x()),
110 static_cast<int>(rect
.y()),
111 static_cast<int>(rect
.right()),
112 static_cast<int>(rect
.bottom())));
115 int ToGestureEventType(WebInputEvent::Type type
) {
117 case WebInputEvent::GestureScrollBegin
:
118 return GESTURE_EVENT_TYPE_SCROLL_START
;
119 case WebInputEvent::GestureScrollEnd
:
120 return GESTURE_EVENT_TYPE_SCROLL_END
;
121 case WebInputEvent::GestureScrollUpdate
:
122 return GESTURE_EVENT_TYPE_SCROLL_BY
;
123 case WebInputEvent::GestureFlingStart
:
124 return GESTURE_EVENT_TYPE_FLING_START
;
125 case WebInputEvent::GestureFlingCancel
:
126 return GESTURE_EVENT_TYPE_FLING_CANCEL
;
127 case WebInputEvent::GestureShowPress
:
128 return GESTURE_EVENT_TYPE_SHOW_PRESS
;
129 case WebInputEvent::GestureTap
:
130 return GESTURE_EVENT_TYPE_SINGLE_TAP_CONFIRMED
;
131 case WebInputEvent::GestureTapUnconfirmed
:
132 return GESTURE_EVENT_TYPE_SINGLE_TAP_UNCONFIRMED
;
133 case WebInputEvent::GestureTapDown
:
134 return GESTURE_EVENT_TYPE_TAP_DOWN
;
135 case WebInputEvent::GestureTapCancel
:
136 return GESTURE_EVENT_TYPE_TAP_CANCEL
;
137 case WebInputEvent::GestureDoubleTap
:
138 return GESTURE_EVENT_TYPE_DOUBLE_TAP
;
139 case WebInputEvent::GestureLongPress
:
140 return GESTURE_EVENT_TYPE_LONG_PRESS
;
141 case WebInputEvent::GestureLongTap
:
142 return GESTURE_EVENT_TYPE_LONG_TAP
;
143 case WebInputEvent::GesturePinchBegin
:
144 return GESTURE_EVENT_TYPE_PINCH_BEGIN
;
145 case WebInputEvent::GesturePinchEnd
:
146 return GESTURE_EVENT_TYPE_PINCH_END
;
147 case WebInputEvent::GesturePinchUpdate
:
148 return GESTURE_EVENT_TYPE_PINCH_BY
;
149 case WebInputEvent::GestureTwoFingerTap
:
151 NOTREACHED() << "Invalid source gesture type: "
152 << WebInputEventTraits::GetName(type
);
159 // Enables a callback when the underlying WebContents is destroyed, to enable
160 // nulling the back-pointer.
161 class ContentViewCoreImpl::ContentViewUserData
162 : public base::SupportsUserData::Data
{
164 explicit ContentViewUserData(ContentViewCoreImpl
* content_view_core
)
165 : content_view_core_(content_view_core
) {
168 ~ContentViewUserData() override
{
169 // TODO(joth): When chrome has finished removing the TabContents class (see
170 // crbug.com/107201) consider inverting relationship, so ContentViewCore
171 // would own WebContents. That effectively implies making the WebContents
172 // destructor private on Android.
173 delete content_view_core_
;
176 ContentViewCoreImpl
* get() const { return content_view_core_
; }
179 // Not using scoped_ptr as ContentViewCoreImpl destructor is private.
180 ContentViewCoreImpl
* content_view_core_
;
182 DISALLOW_IMPLICIT_CONSTRUCTORS(ContentViewUserData
);
186 ContentViewCoreImpl
* ContentViewCoreImpl::FromWebContents(
187 content::WebContents
* web_contents
) {
188 ContentViewCoreImpl::ContentViewUserData
* data
=
189 static_cast<ContentViewCoreImpl::ContentViewUserData
*>(
190 web_contents
->GetUserData(kContentViewUserDataKey
));
191 return data
? data
->get() : NULL
;
195 ContentViewCore
* ContentViewCore::FromWebContents(
196 content::WebContents
* web_contents
) {
197 return ContentViewCoreImpl::FromWebContents(web_contents
);
201 ContentViewCore
* ContentViewCore::GetNativeContentViewCore(JNIEnv
* env
,
203 return reinterpret_cast<ContentViewCore
*>(
204 Java_ContentViewCore_getNativeContentViewCore(env
, obj
));
207 ContentViewCoreImpl::ContentViewCoreImpl(
210 WebContents
* web_contents
,
211 jobject view_android_delegate
,
212 ui::WindowAndroid
* window_android
,
213 jobject java_bridge_retained_object_set
)
214 : WebContentsObserver(web_contents
),
216 web_contents_(static_cast<WebContentsImpl
*>(web_contents
)),
217 root_layer_(cc::SolidColorLayer::Create(Compositor::LayerSettings())),
219 view_android_(new ui::ViewAndroid(view_android_delegate
, window_android
)),
220 dpi_scale_(ui::GetScaleFactorForNativeView(view_android_
.get())),
221 window_android_(window_android
),
222 device_orientation_(0),
223 accessibility_enabled_(false) {
224 CHECK(web_contents
) <<
225 "A ContentViewCoreImpl should be created with a valid WebContents.";
226 DCHECK(window_android_
);
228 root_layer_
->SetBackgroundColor(GetBackgroundColor(env
, obj
));
229 gfx::Size
physical_size(
230 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, obj
),
231 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, obj
));
232 root_layer_
->SetBounds(physical_size
);
233 root_layer_
->SetIsDrawable(true);
235 // Currently, the only use case we have for overriding a user agent involves
236 // spoofing a desktop Linux user agent for "Request desktop site".
237 // Automatically set it for all WebContents so that it is available when a
238 // NavigationEntry requires the user agent to be overridden.
239 const char kLinuxInfoStr
[] = "X11; Linux x86_64";
240 std::string product
= content::GetContentClient()->GetProduct();
241 std::string spoofed_ua
=
242 BuildUserAgentFromOSAndProduct(kLinuxInfoStr
, product
);
243 web_contents
->SetUserAgentOverride(spoofed_ua
);
245 java_bridge_dispatcher_host_
=
246 new GinJavaBridgeDispatcherHost(web_contents
,
247 java_bridge_retained_object_set
);
252 ContentViewCoreImpl::~ContentViewCoreImpl() {
253 root_layer_
->RemoveFromParent();
255 JNIEnv
* env
= base::android::AttachCurrentThread();
256 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
258 if (!j_obj
.is_null()) {
259 Java_ContentViewCore_onNativeContentViewCoreDestroyed(
260 env
, j_obj
.obj(), reinterpret_cast<intptr_t>(this));
264 base::android::ScopedJavaLocalRef
<jobject
>
265 ContentViewCoreImpl::GetWebContentsAndroid(JNIEnv
* env
, jobject obj
) {
266 return web_contents_
->GetJavaWebContents();
269 base::android::ScopedJavaLocalRef
<jobject
>
270 ContentViewCoreImpl::GetJavaWindowAndroid(JNIEnv
* env
, jobject obj
) {
271 if (!window_android_
)
272 return ScopedJavaLocalRef
<jobject
>();
273 return window_android_
->GetJavaObject();
276 void ContentViewCoreImpl::OnJavaContentViewCoreDestroyed(JNIEnv
* env
,
278 DCHECK(env
->IsSameObject(java_ref_
.get(env
).obj(), obj
));
280 // Java peer has gone, ContentViewCore is not functional and waits to
281 // be destroyed with WebContents.
282 // We need to reset WebContentsViewAndroid's reference, otherwise, there
283 // could have call in when swapping the WebContents,
284 // see http://crbug.com/383939 .
285 DCHECK(web_contents_
);
286 static_cast<WebContentsViewAndroid
*>(
287 static_cast<WebContentsImpl
*>(web_contents_
)->GetView())->
288 SetContentViewCore(NULL
);
291 void ContentViewCoreImpl::InitWebContents() {
292 DCHECK(web_contents_
);
293 static_cast<WebContentsViewAndroid
*>(
294 static_cast<WebContentsImpl
*>(web_contents_
)->GetView())->
295 SetContentViewCore(this);
296 DCHECK(!web_contents_
->GetUserData(kContentViewUserDataKey
));
297 web_contents_
->SetUserData(kContentViewUserDataKey
,
298 new ContentViewUserData(this));
301 void ContentViewCoreImpl::RenderViewReady() {
302 JNIEnv
* env
= AttachCurrentThread();
303 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
305 Java_ContentViewCore_onRenderProcessChange(env
, obj
.obj());
307 if (device_orientation_
!= 0)
308 SendOrientationChangeEventInternal();
311 void ContentViewCoreImpl::RenderViewHostChanged(RenderViewHost
* old_host
,
312 RenderViewHost
* new_host
) {
315 old_pid
= GetRenderProcessIdFromRenderViewHost(old_host
);
317 RenderWidgetHostViewAndroid
* view
=
318 static_cast<RenderWidgetHostViewAndroid
*>(old_host
->GetView());
320 view
->SetContentViewCore(NULL
);
322 view
= static_cast<RenderWidgetHostViewAndroid
*>(new_host
->GetView());
324 view
->SetContentViewCore(this);
326 int new_pid
= GetRenderProcessIdFromRenderViewHost(
327 web_contents_
->GetRenderViewHost());
328 if (new_pid
!= old_pid
) {
329 // Notify the Java side that the renderer process changed.
330 JNIEnv
* env
= AttachCurrentThread();
331 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
332 if (!obj
.is_null()) {
333 Java_ContentViewCore_onRenderProcessChange(env
, obj
.obj());
337 SetFocusInternal(HasFocus());
338 SetAccessibilityEnabledInternal(accessibility_enabled_
);
341 RenderWidgetHostViewAndroid
*
342 ContentViewCoreImpl::GetRenderWidgetHostViewAndroid() const {
343 RenderWidgetHostView
* rwhv
= NULL
;
345 rwhv
= web_contents_
->GetRenderWidgetHostView();
346 if (web_contents_
->ShowingInterstitialPage()) {
347 rwhv
= web_contents_
->GetInterstitialPage()
349 ->GetRenderViewHost()
353 return static_cast<RenderWidgetHostViewAndroid
*>(rwhv
);
356 ScopedJavaLocalRef
<jobject
> ContentViewCoreImpl::GetJavaObject() {
357 JNIEnv
* env
= AttachCurrentThread();
358 return java_ref_
.get(env
);
361 jint
ContentViewCoreImpl::GetBackgroundColor(JNIEnv
* env
, jobject obj
) {
362 RenderWidgetHostViewAndroid
* rwhva
= GetRenderWidgetHostViewAndroid();
364 return SK_ColorWHITE
;
365 return rwhva
->GetCachedBackgroundColor();
368 void ContentViewCoreImpl::PauseOrResumeGeolocation(bool should_pause
) {
370 web_contents_
->GetGeolocationServiceContext()->PauseUpdates();
372 web_contents_
->GetGeolocationServiceContext()->ResumeUpdates();
375 // All positions and sizes are in CSS pixels.
376 // Note that viewport_width/height is a best effort based.
377 // ContentViewCore has the actual information about the physical viewport size.
378 void ContentViewCoreImpl::UpdateFrameInfo(
379 const gfx::Vector2dF
& scroll_offset
,
380 float page_scale_factor
,
381 const gfx::Vector2dF
& page_scale_factor_limits
,
382 const gfx::SizeF
& content_size
,
383 const gfx::SizeF
& viewport_size
,
384 const gfx::Vector2dF
& controls_offset
,
385 const gfx::Vector2dF
& content_offset
,
386 bool is_mobile_optimized_hint
) {
387 JNIEnv
* env
= AttachCurrentThread();
388 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
392 window_android_
->set_content_offset(
393 gfx::ScaleVector2d(content_offset
, dpi_scale_
));
395 page_scale_
= page_scale_factor
;
397 Java_ContentViewCore_updateFrameInfo(
402 page_scale_factor_limits
.x(),
403 page_scale_factor_limits
.y(),
404 content_size
.width(),
405 content_size
.height(),
406 viewport_size
.width(),
407 viewport_size
.height(),
410 is_mobile_optimized_hint
);
413 void ContentViewCoreImpl::SetTitle(const base::string16
& title
) {
414 JNIEnv
* env
= AttachCurrentThread();
415 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
418 ScopedJavaLocalRef
<jstring
> jtitle
=
419 ConvertUTF8ToJavaString(env
, base::UTF16ToUTF8(title
));
420 Java_ContentViewCore_setTitle(env
, obj
.obj(), jtitle
.obj());
423 void ContentViewCoreImpl::OnBackgroundColorChanged(SkColor color
) {
424 root_layer_
->SetBackgroundColor(color
);
426 JNIEnv
* env
= AttachCurrentThread();
427 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
430 Java_ContentViewCore_onBackgroundColorChanged(env
, obj
.obj(), color
);
433 void ContentViewCoreImpl::ShowSelectPopupMenu(
434 RenderFrameHost
* frame
,
435 const gfx::Rect
& bounds
,
436 const std::vector
<MenuItem
>& items
,
439 JNIEnv
* env
= AttachCurrentThread();
440 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
444 ScopedJavaLocalRef
<jobject
> bounds_rect(CreateJavaRect(env
, bounds
));
446 // For multi-select list popups we find the list of previous selections by
447 // iterating through the items. But for single selection popups we take the
448 // given |selected_item| as is.
449 ScopedJavaLocalRef
<jintArray
> selected_array
;
451 scoped_ptr
<jint
[]> native_selected_array(new jint
[items
.size()]);
452 size_t selected_count
= 0;
453 for (size_t i
= 0; i
< items
.size(); ++i
) {
454 if (items
[i
].checked
)
455 native_selected_array
[selected_count
++] = i
;
458 selected_array
= ScopedJavaLocalRef
<jintArray
>(
459 env
, env
->NewIntArray(selected_count
));
460 env
->SetIntArrayRegion(selected_array
.obj(), 0, selected_count
,
461 native_selected_array
.get());
463 selected_array
= ScopedJavaLocalRef
<jintArray
>(env
, env
->NewIntArray(1));
464 jint value
= selected_item
;
465 env
->SetIntArrayRegion(selected_array
.obj(), 0, 1, &value
);
468 ScopedJavaLocalRef
<jintArray
> enabled_array(env
,
469 env
->NewIntArray(items
.size()));
470 std::vector
<base::string16
> labels
;
471 labels
.reserve(items
.size());
472 for (size_t i
= 0; i
< items
.size(); ++i
) {
473 labels
.push_back(items
[i
].label
);
475 (items
[i
].type
== MenuItem::GROUP
? POPUP_ITEM_TYPE_GROUP
:
476 (items
[i
].enabled
? POPUP_ITEM_TYPE_ENABLED
:
477 POPUP_ITEM_TYPE_DISABLED
));
478 env
->SetIntArrayRegion(enabled_array
.obj(), i
, 1, &enabled
);
480 ScopedJavaLocalRef
<jobjectArray
> items_array(
481 base::android::ToJavaArrayOfStrings(env
, labels
));
482 Java_ContentViewCore_showSelectPopup(env
,
484 reinterpret_cast<intptr_t>(frame
),
489 selected_array
.obj());
492 void ContentViewCoreImpl::HideSelectPopupMenu() {
493 JNIEnv
* env
= AttachCurrentThread();
494 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
495 if (!j_obj
.is_null())
496 Java_ContentViewCore_hideSelectPopup(env
, j_obj
.obj());
499 void ContentViewCoreImpl::OnGestureEventAck(const blink::WebGestureEvent
& event
,
500 InputEventAckState ack_result
) {
501 JNIEnv
* env
= AttachCurrentThread();
502 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
506 switch (event
.type
) {
507 case WebInputEvent::GestureFlingStart
:
508 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
) {
509 // The view expects the fling velocity in pixels/s.
510 Java_ContentViewCore_onFlingStartEventConsumed(env
, j_obj
.obj(),
511 event
.data
.flingStart
.velocityX
* dpi_scale(),
512 event
.data
.flingStart
.velocityY
* dpi_scale());
514 // If a scroll ends with a fling, a SCROLL_END event is never sent.
515 // However, if that fling went unconsumed, we still need to let the
516 // listeners know that scrolling has ended.
517 Java_ContentViewCore_onScrollEndEventAck(env
, j_obj
.obj());
520 if (ack_result
== INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS
) {
521 // The view expects the fling velocity in pixels/s.
522 Java_ContentViewCore_onFlingStartEventHadNoConsumer(env
, j_obj
.obj(),
523 event
.data
.flingStart
.velocityX
* dpi_scale(),
524 event
.data
.flingStart
.velocityY
* dpi_scale());
527 case WebInputEvent::GestureFlingCancel
:
528 Java_ContentViewCore_onFlingCancelEventAck(env
, j_obj
.obj());
530 case WebInputEvent::GestureScrollBegin
:
531 Java_ContentViewCore_onScrollBeginEventAck(env
, j_obj
.obj());
533 case WebInputEvent::GestureScrollUpdate
:
534 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
)
535 Java_ContentViewCore_onScrollUpdateGestureConsumed(env
, j_obj
.obj());
537 case WebInputEvent::GestureScrollEnd
:
538 Java_ContentViewCore_onScrollEndEventAck(env
, j_obj
.obj());
540 case WebInputEvent::GesturePinchBegin
:
541 Java_ContentViewCore_onPinchBeginEventAck(env
, j_obj
.obj());
543 case WebInputEvent::GesturePinchEnd
:
544 Java_ContentViewCore_onPinchEndEventAck(env
, j_obj
.obj());
546 case WebInputEvent::GestureTap
:
547 Java_ContentViewCore_onSingleTapEventAck(
550 ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
,
551 event
.x
* dpi_scale(),
552 event
.y
* dpi_scale());
559 bool ContentViewCoreImpl::FilterInputEvent(const blink::WebInputEvent
& event
) {
560 if (event
.type
!= WebInputEvent::GestureTap
&&
561 event
.type
!= WebInputEvent::GestureDoubleTap
&&
562 event
.type
!= WebInputEvent::GestureLongTap
&&
563 event
.type
!= WebInputEvent::GestureLongPress
)
566 JNIEnv
* env
= AttachCurrentThread();
567 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
571 const blink::WebGestureEvent
& gesture
=
572 static_cast<const blink::WebGestureEvent
&>(event
);
573 int gesture_type
= ToGestureEventType(event
.type
);
574 return Java_ContentViewCore_filterTapOrPressEvent(env
,
577 gesture
.x
* dpi_scale(),
578 gesture
.y
* dpi_scale());
580 // TODO(jdduke): Also report double-tap UMA, crbug/347568.
583 bool ContentViewCoreImpl::HasFocus() {
584 JNIEnv
* env
= AttachCurrentThread();
585 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
588 return Java_ContentViewCore_hasFocus(env
, obj
.obj());
591 void ContentViewCoreImpl::RequestDisallowInterceptTouchEvent() {
592 JNIEnv
* env
= AttachCurrentThread();
593 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
595 Java_ContentViewCore_requestDisallowInterceptTouchEvent(env
, obj
.obj());
598 void ContentViewCoreImpl::OnSelectionChanged(const std::string
& text
) {
599 JNIEnv
* env
= AttachCurrentThread();
600 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
603 ScopedJavaLocalRef
<jstring
> jtext
= ConvertUTF8ToJavaString(env
, text
);
604 Java_ContentViewCore_onSelectionChanged(env
, obj
.obj(), jtext
.obj());
607 void ContentViewCoreImpl::OnSelectionEvent(ui::SelectionEventType event
,
608 const gfx::PointF
& selection_anchor
,
609 const gfx::RectF
& selection_rect
) {
610 JNIEnv
* env
= AttachCurrentThread();
611 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
615 gfx::PointF selection_anchor_pix
=
616 gfx::ScalePoint(selection_anchor
, dpi_scale());
617 gfx::RectF selection_rect_pix
= gfx::ScaleRect(selection_rect
, dpi_scale());
618 Java_ContentViewCore_onSelectionEvent(
619 env
, j_obj
.obj(), event
, selection_anchor_pix
.x(),
620 selection_anchor_pix
.y(), selection_rect_pix
.x(), selection_rect_pix
.y(),
621 selection_rect_pix
.right(), selection_rect_pix
.bottom());
624 scoped_ptr
<ui::TouchHandleDrawable
>
625 ContentViewCoreImpl::CreatePopupTouchHandleDrawable() {
626 JNIEnv
* env
= AttachCurrentThread();
627 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
630 return scoped_ptr
<ui::TouchHandleDrawable
>();
632 return scoped_ptr
<ui::TouchHandleDrawable
>(new PopupTouchHandleDrawable(
633 Java_ContentViewCore_createPopupTouchHandleDrawable(env
, obj
.obj()),
637 void ContentViewCoreImpl::ShowPastePopup(int x_dip
, int y_dip
) {
638 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
642 view
->OnShowingPastePopup(gfx::PointF(x_dip
, y_dip
));
644 JNIEnv
* env
= AttachCurrentThread();
645 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
648 Java_ContentViewCore_showPastePopupWithFeedback(
649 env
, obj
.obj(), static_cast<jint
>(x_dip
* dpi_scale()),
650 static_cast<jint
>(y_dip
* dpi_scale()));
653 void ContentViewCoreImpl::GetScaledContentBitmap(
655 SkColorType preferred_color_type
,
656 const gfx::Rect
& src_subrect
,
657 ReadbackRequestCallback
& result_callback
) {
658 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
659 if (!view
|| preferred_color_type
== kUnknown_SkColorType
) {
660 result_callback
.Run(SkBitmap(), READBACK_FAILED
);
664 view
->GetScaledContentBitmap(scale
, preferred_color_type
, src_subrect
,
668 void ContentViewCoreImpl::StartContentIntent(const GURL
& content_url
) {
669 JNIEnv
* env
= AttachCurrentThread();
670 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
673 ScopedJavaLocalRef
<jstring
> jcontent_url
=
674 ConvertUTF8ToJavaString(env
, content_url
.spec());
675 Java_ContentViewCore_startContentIntent(env
,
680 void ContentViewCoreImpl::ShowDisambiguationPopup(
681 const gfx::Rect
& rect_pixels
,
682 const SkBitmap
& zoomed_bitmap
) {
683 JNIEnv
* env
= AttachCurrentThread();
685 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
689 ScopedJavaLocalRef
<jobject
> rect_object(CreateJavaRect(env
, rect_pixels
));
691 ScopedJavaLocalRef
<jobject
> java_bitmap
=
692 gfx::ConvertToJavaBitmap(&zoomed_bitmap
);
693 DCHECK(!java_bitmap
.is_null());
695 Java_ContentViewCore_showDisambiguationPopup(env
,
701 ScopedJavaLocalRef
<jobject
>
702 ContentViewCoreImpl::CreateMotionEventSynthesizer() {
703 JNIEnv
* env
= AttachCurrentThread();
705 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
707 return ScopedJavaLocalRef
<jobject
>();
708 return Java_ContentViewCore_createMotionEventSynthesizer(env
, obj
.obj());
711 bool ContentViewCoreImpl::ShouldBlockMediaRequest(const GURL
& url
) {
712 JNIEnv
* env
= AttachCurrentThread();
714 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
717 ScopedJavaLocalRef
<jstring
> j_url
= ConvertUTF8ToJavaString(env
, url
.spec());
718 return Java_ContentViewCore_shouldBlockMediaRequest(env
, obj
.obj(),
722 void ContentViewCoreImpl::DidStopFlinging() {
723 JNIEnv
* env
= AttachCurrentThread();
725 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
727 Java_ContentViewCore_onNativeFlingStopped(env
, obj
.obj());
730 ScopedJavaLocalRef
<jobject
> ContentViewCoreImpl::GetContext() const {
731 JNIEnv
* env
= AttachCurrentThread();
733 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
735 return ScopedJavaLocalRef
<jobject
>();
737 return Java_ContentViewCore_getContext(env
, obj
.obj());
740 gfx::Size
ContentViewCoreImpl::GetViewSize() const {
741 gfx::Size size
= GetViewportSizeDip();
742 if (DoTopControlsShrinkBlinkSize())
743 size
.Enlarge(0, -GetTopControlsHeightDip());
747 gfx::Size
ContentViewCoreImpl::GetPhysicalBackingSize() const {
748 JNIEnv
* env
= AttachCurrentThread();
749 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
753 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, j_obj
.obj()),
754 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, j_obj
.obj()));
757 gfx::Size
ContentViewCoreImpl::GetViewportSizePix() const {
758 JNIEnv
* env
= AttachCurrentThread();
759 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
763 Java_ContentViewCore_getViewportWidthPix(env
, j_obj
.obj()),
764 Java_ContentViewCore_getViewportHeightPix(env
, j_obj
.obj()));
767 int ContentViewCoreImpl::GetTopControlsHeightPix() const {
768 JNIEnv
* env
= AttachCurrentThread();
769 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
772 return Java_ContentViewCore_getTopControlsHeightPix(env
, j_obj
.obj());
775 gfx::Size
ContentViewCoreImpl::GetViewportSizeDip() const {
776 return gfx::ToCeiledSize(
777 gfx::ScaleSize(GetViewportSizePix(), 1.0f
/ dpi_scale()));
780 bool ContentViewCoreImpl::DoTopControlsShrinkBlinkSize() const {
781 JNIEnv
* env
= AttachCurrentThread();
782 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
785 return Java_ContentViewCore_doTopControlsShrinkBlinkSize(env
, j_obj
.obj());
788 float ContentViewCoreImpl::GetTopControlsHeightDip() const {
789 return GetTopControlsHeightPix() / dpi_scale();
792 void ContentViewCoreImpl::AttachLayer(scoped_refptr
<cc::Layer
> layer
) {
793 root_layer_
->InsertChild(layer
, 0);
794 root_layer_
->SetIsDrawable(false);
797 void ContentViewCoreImpl::RemoveLayer(scoped_refptr
<cc::Layer
> layer
) {
798 layer
->RemoveFromParent();
800 if (!root_layer_
->children().size())
801 root_layer_
->SetIsDrawable(true);
804 void ContentViewCoreImpl::MoveRangeSelectionExtent(const gfx::PointF
& extent
) {
808 web_contents_
->MoveRangeSelectionExtent(gfx::ToRoundedPoint(extent
));
811 void ContentViewCoreImpl::SelectBetweenCoordinates(const gfx::PointF
& base
,
812 const gfx::PointF
& extent
) {
816 gfx::Point base_point
= gfx::ToRoundedPoint(base
);
817 gfx::Point extent_point
= gfx::ToRoundedPoint(extent
);
818 if (base_point
== extent_point
)
821 web_contents_
->SelectRange(base_point
, extent_point
);
824 ui::ViewAndroid
* ContentViewCoreImpl::GetViewAndroid() const {
825 return view_android_
.get();
828 ui::WindowAndroid
* ContentViewCoreImpl::GetWindowAndroid() const {
829 return window_android_
;
832 const scoped_refptr
<cc::Layer
>& ContentViewCoreImpl::GetLayer() const {
836 // ----------------------------------------------------------------------------
837 // Methods called from Java via JNI
838 // ----------------------------------------------------------------------------
840 void ContentViewCoreImpl::SelectPopupMenuItems(JNIEnv
* env
,
842 jlong selectPopupSourceFrame
,
844 RenderFrameHostImpl
* rfhi
=
845 reinterpret_cast<RenderFrameHostImpl
*>(selectPopupSourceFrame
);
847 if (indices
== NULL
) {
848 rfhi
->DidCancelPopupMenu();
852 int selected_count
= env
->GetArrayLength(indices
);
853 std::vector
<int> selected_indices
;
854 jint
* indices_ptr
= env
->GetIntArrayElements(indices
, NULL
);
855 for (int i
= 0; i
< selected_count
; ++i
)
856 selected_indices
.push_back(indices_ptr
[i
]);
857 env
->ReleaseIntArrayElements(indices
, indices_ptr
, JNI_ABORT
);
858 rfhi
->DidSelectPopupMenuItems(selected_indices
);
861 WebContents
* ContentViewCoreImpl::GetWebContents() const {
862 return web_contents_
;
865 void ContentViewCoreImpl::SetFocus(JNIEnv
* env
, jobject obj
, jboolean focused
) {
866 SetFocusInternal(focused
);
869 void ContentViewCoreImpl::SetFocusInternal(bool focused
) {
870 if (!GetRenderWidgetHostViewAndroid())
874 GetRenderWidgetHostViewAndroid()->Focus();
876 GetRenderWidgetHostViewAndroid()->Blur();
879 void ContentViewCoreImpl::SendOrientationChangeEvent(JNIEnv
* env
,
882 if (device_orientation_
!= orientation
) {
883 device_orientation_
= orientation
;
884 SendOrientationChangeEventInternal();
888 jboolean
ContentViewCoreImpl::OnTouchEvent(JNIEnv
* env
,
890 jobject motion_event
,
902 jfloat touch_major_0
,
903 jfloat touch_major_1
,
904 jfloat touch_minor_0
,
905 jfloat touch_minor_1
,
906 jfloat orientation_0
,
907 jfloat orientation_1
,
910 jint android_tool_type_0
,
911 jint android_tool_type_1
,
912 jint android_button_state
,
913 jint android_meta_state
,
914 jboolean is_touch_handle_event
) {
915 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
916 // Avoid synthesizing a touch event if it cannot be forwarded.
920 MotionEventAndroid::Pointer
pointer0(pointer_id_0
,
926 android_tool_type_0
);
927 MotionEventAndroid::Pointer
pointer1(pointer_id_1
,
933 android_tool_type_1
);
934 MotionEventAndroid
event(1.f
/ dpi_scale(),
942 android_button_state
,
949 return is_touch_handle_event
? rwhv
->OnTouchHandleEvent(event
)
950 : rwhv
->OnTouchEvent(event
);
953 float ContentViewCoreImpl::GetDpiScale() const {
957 jboolean
ContentViewCoreImpl::SendMouseMoveEvent(JNIEnv
* env
,
962 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
966 blink::WebMouseEvent event
= WebMouseEventBuilder::Build(
967 WebInputEvent::MouseMove
,
968 blink::WebMouseEvent::ButtonNone
,
969 time_ms
/ 1000.0, x
/ dpi_scale(), y
/ dpi_scale(), 0, 1);
971 rwhv
->SendMouseEvent(event
);
975 jboolean
ContentViewCoreImpl::SendMouseWheelEvent(JNIEnv
* env
,
982 jfloat pixels_per_tick
) {
983 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
987 if (!ticks_x
&& !ticks_y
)
990 blink::WebMouseWheelEvent event
= WebMouseWheelEventBuilder::Build(
991 ticks_x
, ticks_y
, pixels_per_tick
/ dpi_scale(), time_ms
/ 1000.0,
992 x
/ dpi_scale(), y
/ dpi_scale());
994 rwhv
->SendMouseWheelEvent(event
);
998 WebGestureEvent
ContentViewCoreImpl::MakeGestureEvent(
999 WebInputEvent::Type type
, int64 time_ms
, float x
, float y
) const {
1000 return WebGestureEventBuilder::Build(
1001 type
, time_ms
/ 1000.0, x
/ dpi_scale(), y
/ dpi_scale());
1004 void ContentViewCoreImpl::SendGestureEvent(
1005 const blink::WebGestureEvent
& event
) {
1006 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1008 rwhv
->SendGestureEvent(event
);
1011 void ContentViewCoreImpl::ScrollBegin(JNIEnv
* env
,
1018 jboolean target_viewport
) {
1019 WebGestureEvent event
= MakeGestureEvent(
1020 WebInputEvent::GestureScrollBegin
, time_ms
, x
, y
);
1021 event
.data
.scrollBegin
.deltaXHint
= hintx
/ dpi_scale();
1022 event
.data
.scrollBegin
.deltaYHint
= hinty
/ dpi_scale();
1023 event
.data
.scrollBegin
.targetViewport
= target_viewport
;
1025 SendGestureEvent(event
);
1028 void ContentViewCoreImpl::ScrollEnd(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1029 WebGestureEvent event
= MakeGestureEvent(
1030 WebInputEvent::GestureScrollEnd
, time_ms
, 0, 0);
1031 SendGestureEvent(event
);
1034 void ContentViewCoreImpl::ScrollBy(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1035 jfloat x
, jfloat y
, jfloat dx
, jfloat dy
) {
1036 WebGestureEvent event
= MakeGestureEvent(
1037 WebInputEvent::GestureScrollUpdate
, time_ms
, x
, y
);
1038 event
.data
.scrollUpdate
.deltaX
= -dx
/ dpi_scale();
1039 event
.data
.scrollUpdate
.deltaY
= -dy
/ dpi_scale();
1041 SendGestureEvent(event
);
1044 void ContentViewCoreImpl::FlingStart(JNIEnv
* env
,
1051 jboolean target_viewport
) {
1052 WebGestureEvent event
= MakeGestureEvent(
1053 WebInputEvent::GestureFlingStart
, time_ms
, x
, y
);
1054 event
.data
.flingStart
.velocityX
= vx
/ dpi_scale();
1055 event
.data
.flingStart
.velocityY
= vy
/ dpi_scale();
1056 event
.data
.flingStart
.targetViewport
= target_viewport
;
1058 SendGestureEvent(event
);
1061 void ContentViewCoreImpl::FlingCancel(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1062 WebGestureEvent event
= MakeGestureEvent(
1063 WebInputEvent::GestureFlingCancel
, time_ms
, 0, 0);
1064 event
.data
.flingCancel
.preventBoosting
= true;
1066 SendGestureEvent(event
);
1069 void ContentViewCoreImpl::SingleTap(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1070 jfloat x
, jfloat y
) {
1071 // Tap gestures should always be preceded by a TapDown, ensuring consistency
1072 // with the touch-based gesture detection pipeline.
1073 WebGestureEvent tap_down_event
= MakeGestureEvent(
1074 WebInputEvent::GestureTapDown
, time_ms
, x
, y
);
1075 tap_down_event
.data
.tap
.tapCount
= 1;
1076 SendGestureEvent(tap_down_event
);
1078 WebGestureEvent tap_event
= MakeGestureEvent(
1079 WebInputEvent::GestureTap
, time_ms
, x
, y
);
1080 tap_event
.data
.tap
.tapCount
= 1;
1081 SendGestureEvent(tap_event
);
1084 void ContentViewCoreImpl::DoubleTap(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1085 jfloat x
, jfloat y
) {
1086 WebGestureEvent event
= MakeGestureEvent(
1087 WebInputEvent::GestureDoubleTap
, time_ms
, x
, y
);
1088 // Set the tap count to 1 even for DoubleTap, in order to be consistent with
1089 // double tap behavior on a mobile viewport. See crbug.com/234986 for context.
1090 event
.data
.tap
.tapCount
= 1;
1092 SendGestureEvent(event
);
1095 void ContentViewCoreImpl::LongPress(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1096 jfloat x
, jfloat y
) {
1097 WebGestureEvent event
= MakeGestureEvent(
1098 WebInputEvent::GestureLongPress
, time_ms
, x
, y
);
1100 SendGestureEvent(event
);
1103 void ContentViewCoreImpl::PinchBegin(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1104 jfloat x
, jfloat y
) {
1105 WebGestureEvent event
= MakeGestureEvent(
1106 WebInputEvent::GesturePinchBegin
, time_ms
, x
, y
);
1107 SendGestureEvent(event
);
1110 void ContentViewCoreImpl::PinchEnd(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1111 WebGestureEvent event
= MakeGestureEvent(
1112 WebInputEvent::GesturePinchEnd
, time_ms
, 0, 0);
1113 SendGestureEvent(event
);
1116 void ContentViewCoreImpl::PinchBy(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1117 jfloat anchor_x
, jfloat anchor_y
,
1119 WebGestureEvent event
= MakeGestureEvent(
1120 WebInputEvent::GesturePinchUpdate
, time_ms
, anchor_x
, anchor_y
);
1121 event
.data
.pinchUpdate
.scale
= delta
;
1123 SendGestureEvent(event
);
1126 void ContentViewCoreImpl::SelectBetweenCoordinates(JNIEnv
* env
, jobject obj
,
1127 jfloat x1
, jfloat y1
,
1128 jfloat x2
, jfloat y2
) {
1129 SelectBetweenCoordinates(gfx::PointF(x1
/ dpi_scale(), y1
/ dpi_scale()),
1130 gfx::PointF(x2
/ dpi_scale(), y2
/ dpi_scale()));
1133 void ContentViewCoreImpl::MoveCaret(JNIEnv
* env
, jobject obj
,
1134 jfloat x
, jfloat y
) {
1135 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1137 rwhv
->MoveCaret(gfx::Point(x
/ dpi_scale_
, y
/ dpi_scale_
));
1140 void ContentViewCoreImpl::DismissTextHandles(JNIEnv
* env
, jobject obj
) {
1141 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1143 rwhv
->DismissTextHandles();
1146 void ContentViewCoreImpl::SetTextHandlesTemporarilyHidden(JNIEnv
* env
,
1149 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1151 rwhv
->SetTextHandlesTemporarilyHidden(hidden
);
1154 void ContentViewCoreImpl::ResetGestureDetection(JNIEnv
* env
, jobject obj
) {
1155 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1157 rwhv
->ResetGestureDetection();
1160 void ContentViewCoreImpl::SetDoubleTapSupportEnabled(JNIEnv
* env
,
1163 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1165 rwhv
->SetDoubleTapSupportEnabled(enabled
);
1168 void ContentViewCoreImpl::SetMultiTouchZoomSupportEnabled(JNIEnv
* env
,
1171 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1173 rwhv
->SetMultiTouchZoomSupportEnabled(enabled
);
1176 void ContentViewCoreImpl::SetAllowJavascriptInterfacesInspection(
1180 java_bridge_dispatcher_host_
->SetAllowObjectContentsInspection(allow
);
1183 void ContentViewCoreImpl::AddJavascriptInterface(
1188 jclass safe_annotation_clazz
) {
1189 ScopedJavaLocalRef
<jobject
> scoped_object(env
, object
);
1190 ScopedJavaLocalRef
<jclass
> scoped_clazz(env
, safe_annotation_clazz
);
1191 java_bridge_dispatcher_host_
->AddNamedObject(
1192 ConvertJavaStringToUTF8(env
, name
), scoped_object
, scoped_clazz
);
1195 void ContentViewCoreImpl::RemoveJavascriptInterface(JNIEnv
* env
,
1198 java_bridge_dispatcher_host_
->RemoveNamedObject(
1199 ConvertJavaStringToUTF8(env
, name
));
1202 void ContentViewCoreImpl::WasResized(JNIEnv
* env
, jobject obj
) {
1203 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
1204 gfx::Size
physical_size(
1205 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, obj
),
1206 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, obj
));
1207 root_layer_
->SetBounds(physical_size
);
1210 RenderWidgetHostImpl
* host
= RenderWidgetHostImpl::From(
1211 view
->GetRenderWidgetHost());
1212 host
->SendScreenRects();
1217 long ContentViewCoreImpl::GetNativeImeAdapter(JNIEnv
* env
, jobject obj
) {
1218 RenderWidgetHostViewAndroid
* rwhva
= GetRenderWidgetHostViewAndroid();
1221 return rwhva
->GetNativeImeAdapter();
1224 void ContentViewCoreImpl::ForceUpdateImeAdapter(long native_ime_adapter
) {
1225 JNIEnv
* env
= AttachCurrentThread();
1226 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1229 Java_ContentViewCore_forceUpdateImeAdapter(env
, obj
.obj(),
1230 native_ime_adapter
);
1233 void ContentViewCoreImpl::UpdateImeAdapter(long native_ime_adapter
,
1234 int text_input_type
,
1235 int text_input_flags
,
1236 const std::string
& text
,
1237 int selection_start
,
1239 int composition_start
,
1240 int composition_end
,
1241 bool show_ime_if_needed
,
1242 bool is_non_ime_change
) {
1243 JNIEnv
* env
= AttachCurrentThread();
1244 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1248 ScopedJavaLocalRef
<jstring
> jstring_text
= ConvertUTF8ToJavaString(env
, text
);
1249 Java_ContentViewCore_updateImeAdapter(env
,
1263 void ContentViewCoreImpl::SetAccessibilityEnabled(JNIEnv
* env
, jobject obj
,
1265 SetAccessibilityEnabledInternal(enabled
);
1268 void ContentViewCoreImpl::SetTextTrackSettings(JNIEnv
* env
,
1270 jboolean textTracksEnabled
,
1271 jstring textTrackBackgroundColor
,
1272 jstring textTrackFontFamily
,
1273 jstring textTrackFontStyle
,
1274 jstring textTrackFontVariant
,
1275 jstring textTrackTextColor
,
1276 jstring textTrackTextShadow
,
1277 jstring textTrackTextSize
) {
1278 FrameMsg_TextTrackSettings_Params params
;
1279 params
.text_tracks_enabled
= textTracksEnabled
;
1280 params
.text_track_background_color
= ConvertJavaStringToUTF8(
1281 env
, textTrackBackgroundColor
);
1282 params
.text_track_font_family
= ConvertJavaStringToUTF8(
1283 env
, textTrackFontFamily
);
1284 params
.text_track_font_style
= ConvertJavaStringToUTF8(
1285 env
, textTrackFontStyle
);
1286 params
.text_track_font_variant
= ConvertJavaStringToUTF8(
1287 env
, textTrackFontVariant
);
1288 params
.text_track_text_color
= ConvertJavaStringToUTF8(
1289 env
, textTrackTextColor
);
1290 params
.text_track_text_shadow
= ConvertJavaStringToUTF8(
1291 env
, textTrackTextShadow
);
1292 params
.text_track_text_size
= ConvertJavaStringToUTF8(
1293 env
, textTrackTextSize
);
1294 web_contents_
->GetMainFrame()->SetTextTrackSettings(params
);
1297 bool ContentViewCoreImpl::IsFullscreenRequiredForOrientationLock() const {
1298 JNIEnv
* env
= AttachCurrentThread();
1299 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1302 return Java_ContentViewCore_isFullscreenRequiredForOrientationLock(env
,
1306 void ContentViewCoreImpl::SetAccessibilityEnabledInternal(bool enabled
) {
1307 accessibility_enabled_
= enabled
;
1308 BrowserAccessibilityStateImpl
* accessibility_state
=
1309 BrowserAccessibilityStateImpl::GetInstance();
1311 // This enables accessibility globally unless it was explicitly disallowed
1312 // by a command-line flag.
1313 accessibility_state
->OnScreenReaderDetected();
1314 // If it was actually enabled globally, enable it for this RenderWidget now.
1315 if (accessibility_state
->IsAccessibleBrowser() && web_contents_
)
1316 web_contents_
->AddAccessibilityMode(AccessibilityModeComplete
);
1318 accessibility_state
->ResetAccessibilityMode();
1319 if (web_contents_
) {
1320 web_contents_
->SetAccessibilityMode(
1321 accessibility_state
->accessibility_mode());
1326 void ContentViewCoreImpl::SendOrientationChangeEventInternal() {
1327 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1329 rwhv
->UpdateScreenInfo(GetViewAndroid());
1331 static_cast<WebContentsImpl
*>(web_contents())->
1332 screen_orientation_dispatcher_host()->OnOrientationChange();
1335 void ContentViewCoreImpl::ExtractSmartClipData(JNIEnv
* env
,
1342 static_cast<int>(x
/ dpi_scale()),
1343 static_cast<int>(y
/ dpi_scale()),
1344 static_cast<int>((width
> 0 && width
< dpi_scale()) ?
1345 1 : (int)(width
/ dpi_scale())),
1346 static_cast<int>((height
> 0 && height
< dpi_scale()) ?
1347 1 : (int)(height
/ dpi_scale())));
1348 GetWebContents()->Send(new ViewMsg_ExtractSmartClipData(
1349 GetWebContents()->GetRoutingID(), rect
));
1352 jint
ContentViewCoreImpl::GetCurrentRenderProcessId(JNIEnv
* env
, jobject obj
) {
1353 return GetRenderProcessIdFromRenderViewHost(
1354 web_contents_
->GetRenderViewHost());
1357 void ContentViewCoreImpl::SetBackgroundOpaque(JNIEnv
* env
, jobject jobj
,
1359 if (GetRenderWidgetHostViewAndroid()) {
1361 GetRenderWidgetHostViewAndroid()->SetBackgroundColorToDefault();
1363 GetRenderWidgetHostViewAndroid()->SetBackgroundColor(SK_ColorTRANSPARENT
);
1367 void ContentViewCoreImpl::RequestTextSurroundingSelection(
1369 const base::Callback
<
1370 void(const base::string16
& content
, int start_offset
, int end_offset
)>&
1372 DCHECK(!callback
.is_null());
1373 RenderFrameHost
* focused_frame
= web_contents_
->GetFocusedFrame();
1376 if (GetRenderWidgetHostViewAndroid()) {
1377 GetRenderWidgetHostViewAndroid()->SetTextSurroundingSelectionCallback(
1379 focused_frame
->Send(new FrameMsg_TextSurroundingSelectionRequest(
1380 focused_frame
->GetRoutingID(), max_length
));
1384 void ContentViewCoreImpl::OnShowUnhandledTapUIIfNeeded(int x_dip
, int y_dip
) {
1385 JNIEnv
* env
= AttachCurrentThread();
1386 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1389 Java_ContentViewCore_onShowUnhandledTapUIIfNeeded(
1390 env
, obj
.obj(), static_cast<jint
>(x_dip
* dpi_scale()),
1391 static_cast<jint
>(y_dip
* dpi_scale()));
1394 float ContentViewCoreImpl::GetScaleFactor() const {
1395 return page_scale_
* dpi_scale_
;
1398 void ContentViewCoreImpl::OnSmartClipDataExtracted(
1399 const base::string16
& text
,
1400 const base::string16
& html
,
1401 const gfx::Rect
& clip_rect
) {
1402 JNIEnv
* env
= AttachCurrentThread();
1403 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1406 ScopedJavaLocalRef
<jstring
> jtext
= ConvertUTF16ToJavaString(env
, text
);
1407 ScopedJavaLocalRef
<jstring
> jhtml
= ConvertUTF16ToJavaString(env
, html
);
1408 ScopedJavaLocalRef
<jobject
> clip_rect_object(CreateJavaRect(env
, clip_rect
));
1409 Java_ContentViewCore_onSmartClipDataExtracted(
1410 env
, obj
.obj(), jtext
.obj(), jhtml
.obj(), clip_rect_object
.obj());
1413 void ContentViewCoreImpl::WebContentsDestroyed() {
1414 WebContentsViewAndroid
* wcva
= static_cast<WebContentsViewAndroid
*>(
1415 static_cast<WebContentsImpl
*>(web_contents())->GetView());
1417 wcva
->SetContentViewCore(NULL
);
1420 bool ContentViewCoreImpl::PullStart() {
1421 JNIEnv
* env
= AttachCurrentThread();
1422 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1424 return Java_ContentViewCore_onOverscrollRefreshStart(env
, obj
.obj());
1428 void ContentViewCoreImpl::PullUpdate(float delta
) {
1429 JNIEnv
* env
= AttachCurrentThread();
1430 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1432 Java_ContentViewCore_onOverscrollRefreshUpdate(env
, obj
.obj(), delta
);
1435 void ContentViewCoreImpl::PullRelease(bool allow_refresh
) {
1436 JNIEnv
* env
= AttachCurrentThread();
1437 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1438 if (!obj
.is_null()) {
1439 Java_ContentViewCore_onOverscrollRefreshRelease(env
, obj
.obj(),
1444 void ContentViewCoreImpl::PullReset() {
1445 JNIEnv
* env
= AttachCurrentThread();
1446 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1448 Java_ContentViewCore_onOverscrollRefreshReset(env
, obj
.obj());
1451 // This is called for each ContentView.
1452 jlong
Init(JNIEnv
* env
,
1454 jobject web_contents
,
1455 jobject view_android_delegate
,
1456 jlong window_android
,
1457 jobject retained_objects_set
) {
1458 ContentViewCoreImpl
* view
= new ContentViewCoreImpl(
1459 env
, obj
, WebContents::FromJavaWebContents(web_contents
),
1460 view_android_delegate
,
1461 reinterpret_cast<ui::WindowAndroid
*>(window_android
),
1462 retained_objects_set
);
1463 return reinterpret_cast<intptr_t>(view
);
1466 static jobject
FromWebContentsAndroid(
1469 jobject jweb_contents
) {
1470 WebContents
* web_contents
= WebContents::FromJavaWebContents(jweb_contents
);
1474 ContentViewCore
* view
= ContentViewCore::FromWebContents(web_contents
);
1478 return view
->GetJavaObject().Release();
1481 bool RegisterContentViewCore(JNIEnv
* env
) {
1482 return RegisterNativesImpl(env
);
1485 } // namespace content