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/frame_host/interstitial_page_impl.h"
25 #include "content/browser/geolocation/geolocation_service_context.h"
26 #include "content/browser/media/media_web_contents_observer.h"
27 #include "content/browser/renderer_host/compositor_impl_android.h"
28 #include "content/browser/renderer_host/input/motion_event_android.h"
29 #include "content/browser/renderer_host/input/web_input_event_builders_android.h"
30 #include "content/browser/renderer_host/input/web_input_event_util.h"
31 #include "content/browser/renderer_host/render_view_host_impl.h"
32 #include "content/browser/renderer_host/render_widget_host_impl.h"
33 #include "content/browser/renderer_host/render_widget_host_view_android.h"
34 #include "content/browser/web_contents/web_contents_view_android.h"
35 #include "content/common/frame_messages.h"
36 #include "content/common/input/web_input_event_traits.h"
37 #include "content/common/input_messages.h"
38 #include "content/common/view_messages.h"
39 #include "content/public/browser/android/compositor.h"
40 #include "content/public/browser/browser_context.h"
41 #include "content/public/browser/browser_thread.h"
42 #include "content/public/browser/favicon_status.h"
43 #include "content/public/browser/render_frame_host.h"
44 #include "content/public/browser/screen_orientation_dispatcher_host.h"
45 #include "content/public/browser/ssl_host_state_delegate.h"
46 #include "content/public/browser/web_contents.h"
47 #include "content/public/common/content_client.h"
48 #include "content/public/common/content_switches.h"
49 #include "content/public/common/menu_item.h"
50 #include "content/public/common/user_agent.h"
51 #include "jni/ContentViewCore_jni.h"
52 #include "third_party/WebKit/public/web/WebInputEvent.h"
53 #include "ui/android/view_android.h"
54 #include "ui/android/window_android.h"
55 #include "ui/gfx/android/java_bitmap.h"
56 #include "ui/gfx/geometry/point_conversions.h"
57 #include "ui/gfx/geometry/size_conversions.h"
58 #include "ui/gfx/geometry/size_f.h"
60 using base::android::AttachCurrentThread
;
61 using base::android::ConvertJavaStringToUTF16
;
62 using base::android::ConvertJavaStringToUTF8
;
63 using base::android::ConvertUTF16ToJavaString
;
64 using base::android::ConvertUTF8ToJavaString
;
65 using base::android::ScopedJavaLocalRef
;
66 using blink::WebGestureEvent
;
67 using blink::WebInputEvent
;
69 // Describes the type and enabled state of a select popup item.
72 // A Java counterpart will be generated for this enum.
73 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.browser.input
75 // Popup item is of type group
76 POPUP_ITEM_TYPE_GROUP
,
78 // Popup item is disabled
79 POPUP_ITEM_TYPE_DISABLED
,
81 // Popup item is enabled
82 POPUP_ITEM_TYPE_ENABLED
,
91 const void* kContentViewUserDataKey
= &kContentViewUserDataKey
;
93 int GetRenderProcessIdFromRenderViewHost(RenderViewHost
* host
) {
95 RenderProcessHost
* render_process
= host
->GetProcess();
96 DCHECK(render_process
);
97 if (render_process
->HasConnection())
98 return render_process
->GetHandle();
103 ScopedJavaLocalRef
<jobject
> CreateJavaRect(
105 const gfx::Rect
& rect
) {
106 return ScopedJavaLocalRef
<jobject
>(
107 Java_ContentViewCore_createRect(env
,
108 static_cast<int>(rect
.x()),
109 static_cast<int>(rect
.y()),
110 static_cast<int>(rect
.right()),
111 static_cast<int>(rect
.bottom())));
114 int ToGestureEventType(WebInputEvent::Type type
) {
116 case WebInputEvent::GestureScrollBegin
:
117 return GESTURE_EVENT_TYPE_SCROLL_START
;
118 case WebInputEvent::GestureScrollEnd
:
119 return GESTURE_EVENT_TYPE_SCROLL_END
;
120 case WebInputEvent::GestureScrollUpdate
:
121 return GESTURE_EVENT_TYPE_SCROLL_BY
;
122 case WebInputEvent::GestureFlingStart
:
123 return GESTURE_EVENT_TYPE_FLING_START
;
124 case WebInputEvent::GestureFlingCancel
:
125 return GESTURE_EVENT_TYPE_FLING_CANCEL
;
126 case WebInputEvent::GestureShowPress
:
127 return GESTURE_EVENT_TYPE_SHOW_PRESS
;
128 case WebInputEvent::GestureTap
:
129 return GESTURE_EVENT_TYPE_SINGLE_TAP_CONFIRMED
;
130 case WebInputEvent::GestureTapUnconfirmed
:
131 return GESTURE_EVENT_TYPE_SINGLE_TAP_UNCONFIRMED
;
132 case WebInputEvent::GestureTapDown
:
133 return GESTURE_EVENT_TYPE_TAP_DOWN
;
134 case WebInputEvent::GestureTapCancel
:
135 return GESTURE_EVENT_TYPE_TAP_CANCEL
;
136 case WebInputEvent::GestureDoubleTap
:
137 return GESTURE_EVENT_TYPE_DOUBLE_TAP
;
138 case WebInputEvent::GestureLongPress
:
139 return GESTURE_EVENT_TYPE_LONG_PRESS
;
140 case WebInputEvent::GestureLongTap
:
141 return GESTURE_EVENT_TYPE_LONG_TAP
;
142 case WebInputEvent::GesturePinchBegin
:
143 return GESTURE_EVENT_TYPE_PINCH_BEGIN
;
144 case WebInputEvent::GesturePinchEnd
:
145 return GESTURE_EVENT_TYPE_PINCH_END
;
146 case WebInputEvent::GesturePinchUpdate
:
147 return GESTURE_EVENT_TYPE_PINCH_BY
;
148 case WebInputEvent::GestureTwoFingerTap
:
150 NOTREACHED() << "Invalid source gesture type: "
151 << WebInputEventTraits::GetName(type
);
158 // Enables a callback when the underlying WebContents is destroyed, to enable
159 // nulling the back-pointer.
160 class ContentViewCoreImpl::ContentViewUserData
161 : public base::SupportsUserData::Data
{
163 explicit ContentViewUserData(ContentViewCoreImpl
* content_view_core
)
164 : content_view_core_(content_view_core
) {
167 ~ContentViewUserData() override
{
168 // TODO(joth): When chrome has finished removing the TabContents class (see
169 // crbug.com/107201) consider inverting relationship, so ContentViewCore
170 // would own WebContents. That effectively implies making the WebContents
171 // destructor private on Android.
172 delete content_view_core_
;
175 ContentViewCoreImpl
* get() const { return content_view_core_
; }
178 // Not using scoped_ptr as ContentViewCoreImpl destructor is private.
179 ContentViewCoreImpl
* content_view_core_
;
181 DISALLOW_IMPLICIT_CONSTRUCTORS(ContentViewUserData
);
185 ContentViewCoreImpl
* ContentViewCoreImpl::FromWebContents(
186 content::WebContents
* web_contents
) {
187 ContentViewCoreImpl::ContentViewUserData
* data
=
188 static_cast<ContentViewCoreImpl::ContentViewUserData
*>(
189 web_contents
->GetUserData(kContentViewUserDataKey
));
190 return data
? data
->get() : NULL
;
194 ContentViewCore
* ContentViewCore::FromWebContents(
195 content::WebContents
* web_contents
) {
196 return ContentViewCoreImpl::FromWebContents(web_contents
);
200 ContentViewCore
* ContentViewCore::GetNativeContentViewCore(JNIEnv
* env
,
202 return reinterpret_cast<ContentViewCore
*>(
203 Java_ContentViewCore_getNativeContentViewCore(env
, obj
));
206 ContentViewCoreImpl::ContentViewCoreImpl(
209 WebContents
* web_contents
,
210 jobject view_android_delegate
,
211 ui::WindowAndroid
* window_android
,
212 jobject java_bridge_retained_object_set
)
213 : WebContentsObserver(web_contents
),
215 web_contents_(static_cast<WebContentsImpl
*>(web_contents
)),
216 root_layer_(cc::SolidColorLayer::Create(Compositor::LayerSettings())),
218 view_android_(new ui::ViewAndroid(view_android_delegate
, window_android
)),
219 dpi_scale_(ui::GetScaleFactorForNativeView(view_android_
.get())),
220 window_android_(window_android
),
221 device_orientation_(0),
222 accessibility_enabled_(false) {
223 CHECK(web_contents
) <<
224 "A ContentViewCoreImpl should be created with a valid WebContents.";
225 DCHECK(window_android_
);
227 root_layer_
->SetBackgroundColor(GetBackgroundColor(env
, obj
));
228 gfx::Size
physical_size(
229 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, obj
),
230 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, obj
));
231 root_layer_
->SetBounds(physical_size
);
232 root_layer_
->SetIsDrawable(true);
234 // Currently, the only use case we have for overriding a user agent involves
235 // spoofing a desktop Linux user agent for "Request desktop site".
236 // Automatically set it for all WebContents so that it is available when a
237 // NavigationEntry requires the user agent to be overridden.
238 const char kLinuxInfoStr
[] = "X11; Linux x86_64";
239 std::string product
= content::GetContentClient()->GetProduct();
240 std::string spoofed_ua
=
241 BuildUserAgentFromOSAndProduct(kLinuxInfoStr
, product
);
242 web_contents
->SetUserAgentOverride(spoofed_ua
);
244 java_bridge_dispatcher_host_
=
245 new GinJavaBridgeDispatcherHost(web_contents
,
246 java_bridge_retained_object_set
);
251 ContentViewCoreImpl::~ContentViewCoreImpl() {
252 root_layer_
->RemoveFromParent();
254 JNIEnv
* env
= base::android::AttachCurrentThread();
255 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
257 if (!j_obj
.is_null()) {
258 Java_ContentViewCore_onNativeContentViewCoreDestroyed(
259 env
, j_obj
.obj(), reinterpret_cast<intptr_t>(this));
263 base::android::ScopedJavaLocalRef
<jobject
>
264 ContentViewCoreImpl::GetWebContentsAndroid(JNIEnv
* env
, jobject obj
) {
265 return web_contents_
->GetJavaWebContents();
268 base::android::ScopedJavaLocalRef
<jobject
>
269 ContentViewCoreImpl::GetJavaWindowAndroid(JNIEnv
* env
, jobject obj
) {
270 if (!window_android_
)
271 return ScopedJavaLocalRef
<jobject
>();
272 return window_android_
->GetJavaObject();
275 void ContentViewCoreImpl::OnJavaContentViewCoreDestroyed(JNIEnv
* env
,
277 DCHECK(env
->IsSameObject(java_ref_
.get(env
).obj(), obj
));
279 // Java peer has gone, ContentViewCore is not functional and waits to
280 // be destroyed with WebContents.
281 // We need to reset WebContentsViewAndroid's reference, otherwise, there
282 // could have call in when swapping the WebContents,
283 // see http://crbug.com/383939 .
284 DCHECK(web_contents_
);
285 static_cast<WebContentsViewAndroid
*>(
286 static_cast<WebContentsImpl
*>(web_contents_
)->GetView())->
287 SetContentViewCore(NULL
);
290 void ContentViewCoreImpl::InitWebContents() {
291 DCHECK(web_contents_
);
292 static_cast<WebContentsViewAndroid
*>(
293 static_cast<WebContentsImpl
*>(web_contents_
)->GetView())->
294 SetContentViewCore(this);
295 DCHECK(!web_contents_
->GetUserData(kContentViewUserDataKey
));
296 web_contents_
->SetUserData(kContentViewUserDataKey
,
297 new ContentViewUserData(this));
300 void ContentViewCoreImpl::RenderViewReady() {
301 JNIEnv
* env
= AttachCurrentThread();
302 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
304 Java_ContentViewCore_onRenderProcessChange(env
, obj
.obj());
306 if (device_orientation_
!= 0)
307 SendOrientationChangeEventInternal();
310 void ContentViewCoreImpl::RenderViewHostChanged(RenderViewHost
* old_host
,
311 RenderViewHost
* new_host
) {
314 old_pid
= GetRenderProcessIdFromRenderViewHost(old_host
);
316 RenderWidgetHostViewAndroid
* view
=
317 static_cast<RenderWidgetHostViewAndroid
*>(old_host
->GetView());
319 view
->SetContentViewCore(NULL
);
321 view
= static_cast<RenderWidgetHostViewAndroid
*>(new_host
->GetView());
323 view
->SetContentViewCore(this);
325 int new_pid
= GetRenderProcessIdFromRenderViewHost(
326 web_contents_
->GetRenderViewHost());
327 if (new_pid
!= old_pid
) {
328 // Notify the Java side that the renderer process changed.
329 JNIEnv
* env
= AttachCurrentThread();
330 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
331 if (!obj
.is_null()) {
332 Java_ContentViewCore_onRenderProcessChange(env
, obj
.obj());
336 SetFocusInternal(HasFocus());
337 SetAccessibilityEnabledInternal(accessibility_enabled_
);
340 RenderWidgetHostViewAndroid
*
341 ContentViewCoreImpl::GetRenderWidgetHostViewAndroid() const {
342 RenderWidgetHostView
* rwhv
= NULL
;
344 rwhv
= web_contents_
->GetRenderWidgetHostView();
345 if (web_contents_
->ShowingInterstitialPage()) {
346 rwhv
= web_contents_
->GetInterstitialPage()
348 ->GetRenderViewHost()
352 return static_cast<RenderWidgetHostViewAndroid
*>(rwhv
);
355 ScopedJavaLocalRef
<jobject
> ContentViewCoreImpl::GetJavaObject() {
356 JNIEnv
* env
= AttachCurrentThread();
357 return java_ref_
.get(env
);
360 jint
ContentViewCoreImpl::GetBackgroundColor(JNIEnv
* env
, jobject obj
) {
361 RenderWidgetHostViewAndroid
* rwhva
= GetRenderWidgetHostViewAndroid();
363 return SK_ColorWHITE
;
364 return rwhva
->GetCachedBackgroundColor();
367 void ContentViewCoreImpl::PauseOrResumeGeolocation(bool should_pause
) {
369 web_contents_
->GetGeolocationServiceContext()->PauseUpdates();
371 web_contents_
->GetGeolocationServiceContext()->ResumeUpdates();
374 // All positions and sizes are in CSS pixels.
375 // Note that viewport_width/height is a best effort based.
376 // ContentViewCore has the actual information about the physical viewport size.
377 void ContentViewCoreImpl::UpdateFrameInfo(
378 const gfx::Vector2dF
& scroll_offset
,
379 float page_scale_factor
,
380 const gfx::Vector2dF
& page_scale_factor_limits
,
381 const gfx::SizeF
& content_size
,
382 const gfx::SizeF
& viewport_size
,
383 const gfx::Vector2dF
& controls_offset
,
384 const gfx::Vector2dF
& content_offset
,
385 bool is_mobile_optimized_hint
) {
386 JNIEnv
* env
= AttachCurrentThread();
387 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
391 window_android_
->set_content_offset(
392 gfx::ScaleVector2d(content_offset
, dpi_scale_
));
394 page_scale_
= page_scale_factor
;
396 Java_ContentViewCore_updateFrameInfo(
401 page_scale_factor_limits
.x(),
402 page_scale_factor_limits
.y(),
403 content_size
.width(),
404 content_size
.height(),
405 viewport_size
.width(),
406 viewport_size
.height(),
409 is_mobile_optimized_hint
);
412 void ContentViewCoreImpl::SetTitle(const base::string16
& title
) {
413 JNIEnv
* env
= AttachCurrentThread();
414 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
417 ScopedJavaLocalRef
<jstring
> jtitle
=
418 ConvertUTF8ToJavaString(env
, base::UTF16ToUTF8(title
));
419 Java_ContentViewCore_setTitle(env
, obj
.obj(), jtitle
.obj());
422 void ContentViewCoreImpl::OnBackgroundColorChanged(SkColor color
) {
423 root_layer_
->SetBackgroundColor(color
);
425 JNIEnv
* env
= AttachCurrentThread();
426 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
429 Java_ContentViewCore_onBackgroundColorChanged(env
, obj
.obj(), color
);
432 void ContentViewCoreImpl::ShowSelectPopupMenu(
433 RenderFrameHost
* frame
,
434 const gfx::Rect
& bounds
,
435 const std::vector
<MenuItem
>& items
,
438 JNIEnv
* env
= AttachCurrentThread();
439 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
443 ScopedJavaLocalRef
<jobject
> bounds_rect(CreateJavaRect(env
, bounds
));
445 // For multi-select list popups we find the list of previous selections by
446 // iterating through the items. But for single selection popups we take the
447 // given |selected_item| as is.
448 ScopedJavaLocalRef
<jintArray
> selected_array
;
450 scoped_ptr
<jint
[]> native_selected_array(new jint
[items
.size()]);
451 size_t selected_count
= 0;
452 for (size_t i
= 0; i
< items
.size(); ++i
) {
453 if (items
[i
].checked
)
454 native_selected_array
[selected_count
++] = i
;
457 selected_array
= ScopedJavaLocalRef
<jintArray
>(
458 env
, env
->NewIntArray(selected_count
));
459 env
->SetIntArrayRegion(selected_array
.obj(), 0, selected_count
,
460 native_selected_array
.get());
462 selected_array
= ScopedJavaLocalRef
<jintArray
>(env
, env
->NewIntArray(1));
463 jint value
= selected_item
;
464 env
->SetIntArrayRegion(selected_array
.obj(), 0, 1, &value
);
467 ScopedJavaLocalRef
<jintArray
> enabled_array(env
,
468 env
->NewIntArray(items
.size()));
469 std::vector
<base::string16
> labels
;
470 labels
.reserve(items
.size());
471 for (size_t i
= 0; i
< items
.size(); ++i
) {
472 labels
.push_back(items
[i
].label
);
474 (items
[i
].type
== MenuItem::GROUP
? POPUP_ITEM_TYPE_GROUP
:
475 (items
[i
].enabled
? POPUP_ITEM_TYPE_ENABLED
:
476 POPUP_ITEM_TYPE_DISABLED
));
477 env
->SetIntArrayRegion(enabled_array
.obj(), i
, 1, &enabled
);
479 ScopedJavaLocalRef
<jobjectArray
> items_array(
480 base::android::ToJavaArrayOfStrings(env
, labels
));
481 Java_ContentViewCore_showSelectPopup(env
,
483 reinterpret_cast<intptr_t>(frame
),
488 selected_array
.obj());
491 void ContentViewCoreImpl::HideSelectPopupMenu() {
492 JNIEnv
* env
= AttachCurrentThread();
493 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
494 if (!j_obj
.is_null())
495 Java_ContentViewCore_hideSelectPopup(env
, j_obj
.obj());
498 void ContentViewCoreImpl::OnGestureEventAck(const blink::WebGestureEvent
& event
,
499 InputEventAckState ack_result
) {
500 JNIEnv
* env
= AttachCurrentThread();
501 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
505 switch (event
.type
) {
506 case WebInputEvent::GestureFlingStart
:
507 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
) {
508 // The view expects the fling velocity in pixels/s.
509 Java_ContentViewCore_onFlingStartEventConsumed(env
, j_obj
.obj(),
510 event
.data
.flingStart
.velocityX
* dpi_scale(),
511 event
.data
.flingStart
.velocityY
* dpi_scale());
513 // If a scroll ends with a fling, a SCROLL_END event is never sent.
514 // However, if that fling went unconsumed, we still need to let the
515 // listeners know that scrolling has ended.
516 Java_ContentViewCore_onScrollEndEventAck(env
, j_obj
.obj());
519 case WebInputEvent::GestureFlingCancel
:
520 Java_ContentViewCore_onFlingCancelEventAck(env
, j_obj
.obj());
522 case WebInputEvent::GestureScrollBegin
:
523 Java_ContentViewCore_onScrollBeginEventAck(env
, j_obj
.obj());
525 case WebInputEvent::GestureScrollUpdate
:
526 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
)
527 Java_ContentViewCore_onScrollUpdateGestureConsumed(env
, j_obj
.obj());
529 case WebInputEvent::GestureScrollEnd
:
530 Java_ContentViewCore_onScrollEndEventAck(env
, j_obj
.obj());
532 case WebInputEvent::GesturePinchBegin
:
533 Java_ContentViewCore_onPinchBeginEventAck(env
, j_obj
.obj());
535 case WebInputEvent::GesturePinchEnd
:
536 Java_ContentViewCore_onPinchEndEventAck(env
, j_obj
.obj());
538 case WebInputEvent::GestureTap
:
539 Java_ContentViewCore_onSingleTapEventAck(
542 ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
,
543 event
.x
* dpi_scale(),
544 event
.y
* dpi_scale());
551 bool ContentViewCoreImpl::FilterInputEvent(const blink::WebInputEvent
& event
) {
552 if (event
.type
!= WebInputEvent::GestureTap
&&
553 event
.type
!= WebInputEvent::GestureDoubleTap
&&
554 event
.type
!= WebInputEvent::GestureLongTap
&&
555 event
.type
!= WebInputEvent::GestureLongPress
)
558 JNIEnv
* env
= AttachCurrentThread();
559 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
563 const blink::WebGestureEvent
& gesture
=
564 static_cast<const blink::WebGestureEvent
&>(event
);
565 int gesture_type
= ToGestureEventType(event
.type
);
566 return Java_ContentViewCore_filterTapOrPressEvent(env
,
569 gesture
.x
* dpi_scale(),
570 gesture
.y
* dpi_scale());
572 // TODO(jdduke): Also report double-tap UMA, crbug/347568.
575 bool ContentViewCoreImpl::HasFocus() {
576 JNIEnv
* env
= AttachCurrentThread();
577 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
580 return Java_ContentViewCore_hasFocus(env
, obj
.obj());
583 void ContentViewCoreImpl::RequestDisallowInterceptTouchEvent() {
584 JNIEnv
* env
= AttachCurrentThread();
585 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
587 Java_ContentViewCore_requestDisallowInterceptTouchEvent(env
, obj
.obj());
590 void ContentViewCoreImpl::OnSelectionChanged(const std::string
& text
) {
591 JNIEnv
* env
= AttachCurrentThread();
592 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
595 ScopedJavaLocalRef
<jstring
> jtext
= ConvertUTF8ToJavaString(env
, text
);
596 Java_ContentViewCore_onSelectionChanged(env
, obj
.obj(), jtext
.obj());
599 void ContentViewCoreImpl::OnSelectionEvent(ui::SelectionEventType event
,
600 const gfx::PointF
& selection_anchor
,
601 const gfx::RectF
& selection_rect
) {
602 JNIEnv
* env
= AttachCurrentThread();
603 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
607 gfx::PointF selection_anchor_pix
=
608 gfx::ScalePoint(selection_anchor
, dpi_scale());
609 gfx::RectF selection_rect_pix
= gfx::ScaleRect(selection_rect
, dpi_scale());
610 Java_ContentViewCore_onSelectionEvent(
611 env
, j_obj
.obj(), event
, selection_anchor_pix
.x(),
612 selection_anchor_pix
.y(), selection_rect_pix
.x(), selection_rect_pix
.y(),
613 selection_rect_pix
.right(), selection_rect_pix
.bottom());
616 void ContentViewCoreImpl::ShowPastePopup(int x_dip
, int y_dip
) {
617 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
621 view
->OnShowingPastePopup(gfx::PointF(x_dip
, y_dip
));
623 JNIEnv
* env
= AttachCurrentThread();
624 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
627 Java_ContentViewCore_showPastePopupWithFeedback(
628 env
, obj
.obj(), static_cast<jint
>(x_dip
* dpi_scale()),
629 static_cast<jint
>(y_dip
* dpi_scale()));
632 void ContentViewCoreImpl::GetScaledContentBitmap(
634 SkColorType preferred_color_type
,
635 const gfx::Rect
& src_subrect
,
636 ReadbackRequestCallback
& result_callback
) {
637 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
638 if (!view
|| preferred_color_type
== kUnknown_SkColorType
) {
639 result_callback
.Run(SkBitmap(), READBACK_FAILED
);
643 view
->GetScaledContentBitmap(scale
, preferred_color_type
, src_subrect
,
647 void ContentViewCoreImpl::StartContentIntent(const GURL
& content_url
) {
648 JNIEnv
* env
= AttachCurrentThread();
649 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
652 ScopedJavaLocalRef
<jstring
> jcontent_url
=
653 ConvertUTF8ToJavaString(env
, content_url
.spec());
654 Java_ContentViewCore_startContentIntent(env
,
659 void ContentViewCoreImpl::ShowDisambiguationPopup(
660 const gfx::Rect
& rect_pixels
,
661 const SkBitmap
& zoomed_bitmap
) {
662 JNIEnv
* env
= AttachCurrentThread();
664 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
668 ScopedJavaLocalRef
<jobject
> rect_object(CreateJavaRect(env
, rect_pixels
));
670 ScopedJavaLocalRef
<jobject
> java_bitmap
=
671 gfx::ConvertToJavaBitmap(&zoomed_bitmap
);
672 DCHECK(!java_bitmap
.is_null());
674 Java_ContentViewCore_showDisambiguationPopup(env
,
680 ScopedJavaLocalRef
<jobject
>
681 ContentViewCoreImpl::CreateMotionEventSynthesizer() {
682 JNIEnv
* env
= AttachCurrentThread();
684 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
686 return ScopedJavaLocalRef
<jobject
>();
687 return Java_ContentViewCore_createMotionEventSynthesizer(env
, obj
.obj());
690 bool ContentViewCoreImpl::ShouldBlockMediaRequest(const GURL
& url
) {
691 JNIEnv
* env
= AttachCurrentThread();
693 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
696 ScopedJavaLocalRef
<jstring
> j_url
= ConvertUTF8ToJavaString(env
, url
.spec());
697 return Java_ContentViewCore_shouldBlockMediaRequest(env
, obj
.obj(),
701 void ContentViewCoreImpl::DidStopFlinging() {
702 JNIEnv
* env
= AttachCurrentThread();
704 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
706 Java_ContentViewCore_onNativeFlingStopped(env
, obj
.obj());
709 ScopedJavaLocalRef
<jobject
> ContentViewCoreImpl::GetContext() const {
710 JNIEnv
* env
= AttachCurrentThread();
712 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
714 return ScopedJavaLocalRef
<jobject
>();
716 return Java_ContentViewCore_getContext(env
, obj
.obj());
719 gfx::Size
ContentViewCoreImpl::GetViewSize() const {
720 gfx::Size size
= GetViewportSizeDip();
721 if (DoTopControlsShrinkBlinkSize())
722 size
.Enlarge(0, -GetTopControlsHeightDip());
726 gfx::Size
ContentViewCoreImpl::GetPhysicalBackingSize() const {
727 JNIEnv
* env
= AttachCurrentThread();
728 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
732 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, j_obj
.obj()),
733 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, j_obj
.obj()));
736 gfx::Size
ContentViewCoreImpl::GetViewportSizePix() const {
737 JNIEnv
* env
= AttachCurrentThread();
738 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
742 Java_ContentViewCore_getViewportWidthPix(env
, j_obj
.obj()),
743 Java_ContentViewCore_getViewportHeightPix(env
, j_obj
.obj()));
746 int ContentViewCoreImpl::GetTopControlsHeightPix() const {
747 JNIEnv
* env
= AttachCurrentThread();
748 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
751 return Java_ContentViewCore_getTopControlsHeightPix(env
, j_obj
.obj());
754 gfx::Size
ContentViewCoreImpl::GetViewportSizeDip() const {
755 return gfx::ToCeiledSize(
756 gfx::ScaleSize(GetViewportSizePix(), 1.0f
/ dpi_scale()));
759 bool ContentViewCoreImpl::DoTopControlsShrinkBlinkSize() const {
760 JNIEnv
* env
= AttachCurrentThread();
761 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
764 return Java_ContentViewCore_doTopControlsShrinkBlinkSize(env
, j_obj
.obj());
767 float ContentViewCoreImpl::GetTopControlsHeightDip() const {
768 return GetTopControlsHeightPix() / dpi_scale();
771 void ContentViewCoreImpl::AttachLayer(scoped_refptr
<cc::Layer
> layer
) {
772 root_layer_
->InsertChild(layer
, 0);
773 root_layer_
->SetIsDrawable(false);
776 void ContentViewCoreImpl::RemoveLayer(scoped_refptr
<cc::Layer
> layer
) {
777 layer
->RemoveFromParent();
779 if (!root_layer_
->children().size())
780 root_layer_
->SetIsDrawable(true);
783 void ContentViewCoreImpl::MoveRangeSelectionExtent(const gfx::PointF
& extent
) {
787 web_contents_
->MoveRangeSelectionExtent(gfx::ToRoundedPoint(extent
));
790 void ContentViewCoreImpl::SelectBetweenCoordinates(const gfx::PointF
& base
,
791 const gfx::PointF
& extent
) {
795 gfx::Point base_point
= gfx::ToRoundedPoint(base
);
796 gfx::Point extent_point
= gfx::ToRoundedPoint(extent
);
797 if (base_point
== extent_point
)
800 web_contents_
->SelectRange(base_point
, extent_point
);
803 ui::ViewAndroid
* ContentViewCoreImpl::GetViewAndroid() const {
804 return view_android_
.get();
807 ui::WindowAndroid
* ContentViewCoreImpl::GetWindowAndroid() const {
808 return window_android_
;
811 const scoped_refptr
<cc::Layer
>& ContentViewCoreImpl::GetLayer() const {
815 // ----------------------------------------------------------------------------
816 // Methods called from Java via JNI
817 // ----------------------------------------------------------------------------
819 void ContentViewCoreImpl::SelectPopupMenuItems(JNIEnv
* env
,
821 jlong selectPopupSourceFrame
,
823 RenderFrameHostImpl
* rfhi
=
824 reinterpret_cast<RenderFrameHostImpl
*>(selectPopupSourceFrame
);
826 if (indices
== NULL
) {
827 rfhi
->DidCancelPopupMenu();
831 int selected_count
= env
->GetArrayLength(indices
);
832 std::vector
<int> selected_indices
;
833 jint
* indices_ptr
= env
->GetIntArrayElements(indices
, NULL
);
834 for (int i
= 0; i
< selected_count
; ++i
)
835 selected_indices
.push_back(indices_ptr
[i
]);
836 env
->ReleaseIntArrayElements(indices
, indices_ptr
, JNI_ABORT
);
837 rfhi
->DidSelectPopupMenuItems(selected_indices
);
840 WebContents
* ContentViewCoreImpl::GetWebContents() const {
841 return web_contents_
;
844 void ContentViewCoreImpl::SetFocus(JNIEnv
* env
, jobject obj
, jboolean focused
) {
845 SetFocusInternal(focused
);
848 void ContentViewCoreImpl::SetFocusInternal(bool focused
) {
849 if (!GetRenderWidgetHostViewAndroid())
853 GetRenderWidgetHostViewAndroid()->Focus();
855 GetRenderWidgetHostViewAndroid()->Blur();
858 void ContentViewCoreImpl::SendOrientationChangeEvent(JNIEnv
* env
,
861 if (device_orientation_
!= orientation
) {
862 device_orientation_
= orientation
;
863 SendOrientationChangeEventInternal();
867 jboolean
ContentViewCoreImpl::OnTouchEvent(JNIEnv
* env
,
869 jobject motion_event
,
881 jfloat touch_major_0
,
882 jfloat touch_major_1
,
883 jfloat touch_minor_0
,
884 jfloat touch_minor_1
,
885 jfloat orientation_0
,
886 jfloat orientation_1
,
889 jint android_tool_type_0
,
890 jint android_tool_type_1
,
891 jint android_button_state
,
892 jint android_meta_state
,
893 jboolean is_touch_handle_event
) {
894 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
895 // Avoid synthesizing a touch event if it cannot be forwarded.
899 MotionEventAndroid::Pointer
pointer0(pointer_id_0
,
905 android_tool_type_0
);
906 MotionEventAndroid::Pointer
pointer1(pointer_id_1
,
912 android_tool_type_1
);
913 MotionEventAndroid
event(1.f
/ dpi_scale(),
921 android_button_state
,
928 return is_touch_handle_event
? rwhv
->OnTouchHandleEvent(event
)
929 : rwhv
->OnTouchEvent(event
);
932 float ContentViewCoreImpl::GetDpiScale() const {
936 jboolean
ContentViewCoreImpl::SendMouseMoveEvent(JNIEnv
* env
,
941 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
945 blink::WebMouseEvent event
= WebMouseEventBuilder::Build(
946 WebInputEvent::MouseMove
,
947 blink::WebMouseEvent::ButtonNone
,
948 time_ms
/ 1000.0, x
/ dpi_scale(), y
/ dpi_scale(), 0, 1);
950 rwhv
->SendMouseEvent(event
);
954 jboolean
ContentViewCoreImpl::SendMouseWheelEvent(JNIEnv
* env
,
961 jfloat pixels_per_tick
) {
962 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
966 if (!ticks_x
&& !ticks_y
)
969 blink::WebMouseWheelEvent event
= WebMouseWheelEventBuilder::Build(
970 ticks_x
, ticks_y
, pixels_per_tick
/ dpi_scale(), time_ms
/ 1000.0,
971 x
/ dpi_scale(), y
/ dpi_scale());
973 rwhv
->SendMouseWheelEvent(event
);
977 WebGestureEvent
ContentViewCoreImpl::MakeGestureEvent(
978 WebInputEvent::Type type
, int64 time_ms
, float x
, float y
) const {
979 return WebGestureEventBuilder::Build(
980 type
, time_ms
/ 1000.0, x
/ dpi_scale(), y
/ dpi_scale());
983 void ContentViewCoreImpl::SendGestureEvent(
984 const blink::WebGestureEvent
& event
) {
985 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
987 rwhv
->SendGestureEvent(event
);
990 void ContentViewCoreImpl::ScrollBegin(JNIEnv
* env
,
997 jboolean target_viewport
) {
998 WebGestureEvent event
= MakeGestureEvent(
999 WebInputEvent::GestureScrollBegin
, time_ms
, x
, y
);
1000 event
.data
.scrollBegin
.deltaXHint
= hintx
/ dpi_scale();
1001 event
.data
.scrollBegin
.deltaYHint
= hinty
/ dpi_scale();
1002 event
.data
.scrollBegin
.targetViewport
= target_viewport
;
1004 SendGestureEvent(event
);
1007 void ContentViewCoreImpl::ScrollEnd(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1008 WebGestureEvent event
= MakeGestureEvent(
1009 WebInputEvent::GestureScrollEnd
, time_ms
, 0, 0);
1010 SendGestureEvent(event
);
1013 void ContentViewCoreImpl::ScrollBy(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1014 jfloat x
, jfloat y
, jfloat dx
, jfloat dy
) {
1015 WebGestureEvent event
= MakeGestureEvent(
1016 WebInputEvent::GestureScrollUpdate
, time_ms
, x
, y
);
1017 event
.data
.scrollUpdate
.deltaX
= -dx
/ dpi_scale();
1018 event
.data
.scrollUpdate
.deltaY
= -dy
/ dpi_scale();
1020 SendGestureEvent(event
);
1023 void ContentViewCoreImpl::FlingStart(JNIEnv
* env
,
1030 jboolean target_viewport
) {
1031 WebGestureEvent event
= MakeGestureEvent(
1032 WebInputEvent::GestureFlingStart
, time_ms
, x
, y
);
1033 event
.data
.flingStart
.velocityX
= vx
/ dpi_scale();
1034 event
.data
.flingStart
.velocityY
= vy
/ dpi_scale();
1035 event
.data
.flingStart
.targetViewport
= target_viewport
;
1037 SendGestureEvent(event
);
1040 void ContentViewCoreImpl::FlingCancel(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1041 WebGestureEvent event
= MakeGestureEvent(
1042 WebInputEvent::GestureFlingCancel
, time_ms
, 0, 0);
1043 event
.data
.flingCancel
.preventBoosting
= true;
1045 SendGestureEvent(event
);
1048 void ContentViewCoreImpl::SingleTap(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1049 jfloat x
, jfloat y
) {
1050 // Tap gestures should always be preceded by a TapDown, ensuring consistency
1051 // with the touch-based gesture detection pipeline.
1052 WebGestureEvent tap_down_event
= MakeGestureEvent(
1053 WebInputEvent::GestureTapDown
, time_ms
, x
, y
);
1054 tap_down_event
.data
.tap
.tapCount
= 1;
1055 SendGestureEvent(tap_down_event
);
1057 WebGestureEvent tap_event
= MakeGestureEvent(
1058 WebInputEvent::GestureTap
, time_ms
, x
, y
);
1059 tap_event
.data
.tap
.tapCount
= 1;
1060 SendGestureEvent(tap_event
);
1063 void ContentViewCoreImpl::DoubleTap(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1064 jfloat x
, jfloat y
) {
1065 WebGestureEvent event
= MakeGestureEvent(
1066 WebInputEvent::GestureDoubleTap
, time_ms
, x
, y
);
1067 // Set the tap count to 1 even for DoubleTap, in order to be consistent with
1068 // double tap behavior on a mobile viewport. See crbug.com/234986 for context.
1069 event
.data
.tap
.tapCount
= 1;
1071 SendGestureEvent(event
);
1074 void ContentViewCoreImpl::LongPress(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1075 jfloat x
, jfloat y
) {
1076 WebGestureEvent event
= MakeGestureEvent(
1077 WebInputEvent::GestureLongPress
, time_ms
, x
, y
);
1079 SendGestureEvent(event
);
1082 void ContentViewCoreImpl::PinchBegin(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1083 jfloat x
, jfloat y
) {
1084 WebGestureEvent event
= MakeGestureEvent(
1085 WebInputEvent::GesturePinchBegin
, time_ms
, x
, y
);
1086 SendGestureEvent(event
);
1089 void ContentViewCoreImpl::PinchEnd(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1090 WebGestureEvent event
= MakeGestureEvent(
1091 WebInputEvent::GesturePinchEnd
, time_ms
, 0, 0);
1092 SendGestureEvent(event
);
1095 void ContentViewCoreImpl::PinchBy(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1096 jfloat anchor_x
, jfloat anchor_y
,
1098 WebGestureEvent event
= MakeGestureEvent(
1099 WebInputEvent::GesturePinchUpdate
, time_ms
, anchor_x
, anchor_y
);
1100 event
.data
.pinchUpdate
.scale
= delta
;
1102 SendGestureEvent(event
);
1105 void ContentViewCoreImpl::SelectBetweenCoordinates(JNIEnv
* env
, jobject obj
,
1106 jfloat x1
, jfloat y1
,
1107 jfloat x2
, jfloat y2
) {
1108 SelectBetweenCoordinates(gfx::PointF(x1
/ dpi_scale(), y1
/ dpi_scale()),
1109 gfx::PointF(x2
/ dpi_scale(), y2
/ dpi_scale()));
1112 void ContentViewCoreImpl::MoveCaret(JNIEnv
* env
, jobject obj
,
1113 jfloat x
, jfloat y
) {
1114 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1116 rwhv
->MoveCaret(gfx::Point(x
/ dpi_scale_
, y
/ dpi_scale_
));
1119 void ContentViewCoreImpl::DismissTextHandles(JNIEnv
* env
, jobject obj
) {
1120 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1122 rwhv
->DismissTextHandles();
1125 void ContentViewCoreImpl::SetTextHandlesTemporarilyHidden(JNIEnv
* env
,
1128 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1130 rwhv
->SetTextHandlesTemporarilyHidden(hidden
);
1133 void ContentViewCoreImpl::ResetGestureDetection(JNIEnv
* env
, jobject obj
) {
1134 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1136 rwhv
->ResetGestureDetection();
1139 void ContentViewCoreImpl::SetDoubleTapSupportEnabled(JNIEnv
* env
,
1142 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1144 rwhv
->SetDoubleTapSupportEnabled(enabled
);
1147 void ContentViewCoreImpl::SetMultiTouchZoomSupportEnabled(JNIEnv
* env
,
1150 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1152 rwhv
->SetMultiTouchZoomSupportEnabled(enabled
);
1155 void ContentViewCoreImpl::SetAllowJavascriptInterfacesInspection(
1159 java_bridge_dispatcher_host_
->SetAllowObjectContentsInspection(allow
);
1162 void ContentViewCoreImpl::AddJavascriptInterface(
1167 jclass safe_annotation_clazz
) {
1168 ScopedJavaLocalRef
<jobject
> scoped_object(env
, object
);
1169 ScopedJavaLocalRef
<jclass
> scoped_clazz(env
, safe_annotation_clazz
);
1170 java_bridge_dispatcher_host_
->AddNamedObject(
1171 ConvertJavaStringToUTF8(env
, name
), scoped_object
, scoped_clazz
);
1174 void ContentViewCoreImpl::RemoveJavascriptInterface(JNIEnv
* env
,
1177 java_bridge_dispatcher_host_
->RemoveNamedObject(
1178 ConvertJavaStringToUTF8(env
, name
));
1181 void ContentViewCoreImpl::WasResized(JNIEnv
* env
, jobject obj
) {
1182 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
1183 gfx::Size
physical_size(
1184 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, obj
),
1185 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, obj
));
1186 root_layer_
->SetBounds(physical_size
);
1189 RenderWidgetHostImpl
* host
= RenderWidgetHostImpl::From(
1190 view
->GetRenderWidgetHost());
1191 host
->SendScreenRects();
1196 long ContentViewCoreImpl::GetNativeImeAdapter(JNIEnv
* env
, jobject obj
) {
1197 RenderWidgetHostViewAndroid
* rwhva
= GetRenderWidgetHostViewAndroid();
1200 return rwhva
->GetNativeImeAdapter();
1203 void ContentViewCoreImpl::ForceUpdateImeAdapter(long native_ime_adapter
) {
1204 JNIEnv
* env
= AttachCurrentThread();
1205 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1208 Java_ContentViewCore_forceUpdateImeAdapter(env
, obj
.obj(),
1209 native_ime_adapter
);
1212 void ContentViewCoreImpl::UpdateImeAdapter(long native_ime_adapter
,
1213 int text_input_type
,
1214 int text_input_flags
,
1215 const std::string
& text
,
1216 int selection_start
,
1218 int composition_start
,
1219 int composition_end
,
1220 bool show_ime_if_needed
,
1221 bool is_non_ime_change
) {
1222 JNIEnv
* env
= AttachCurrentThread();
1223 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1227 ScopedJavaLocalRef
<jstring
> jstring_text
= ConvertUTF8ToJavaString(env
, text
);
1228 Java_ContentViewCore_updateImeAdapter(env
,
1242 void ContentViewCoreImpl::SetAccessibilityEnabled(JNIEnv
* env
, jobject obj
,
1244 SetAccessibilityEnabledInternal(enabled
);
1247 void ContentViewCoreImpl::SetTextTrackSettings(JNIEnv
* env
,
1249 jboolean textTracksEnabled
,
1250 jstring textTrackBackgroundColor
,
1251 jstring textTrackFontFamily
,
1252 jstring textTrackFontStyle
,
1253 jstring textTrackFontVariant
,
1254 jstring textTrackTextColor
,
1255 jstring textTrackTextShadow
,
1256 jstring textTrackTextSize
) {
1257 FrameMsg_TextTrackSettings_Params params
;
1258 params
.text_tracks_enabled
= textTracksEnabled
;
1259 params
.text_track_background_color
= ConvertJavaStringToUTF8(
1260 env
, textTrackBackgroundColor
);
1261 params
.text_track_font_family
= ConvertJavaStringToUTF8(
1262 env
, textTrackFontFamily
);
1263 params
.text_track_font_style
= ConvertJavaStringToUTF8(
1264 env
, textTrackFontStyle
);
1265 params
.text_track_font_variant
= ConvertJavaStringToUTF8(
1266 env
, textTrackFontVariant
);
1267 params
.text_track_text_color
= ConvertJavaStringToUTF8(
1268 env
, textTrackTextColor
);
1269 params
.text_track_text_shadow
= ConvertJavaStringToUTF8(
1270 env
, textTrackTextShadow
);
1271 params
.text_track_text_size
= ConvertJavaStringToUTF8(
1272 env
, textTrackTextSize
);
1273 web_contents_
->GetMainFrame()->SetTextTrackSettings(params
);
1276 bool ContentViewCoreImpl::IsFullscreenRequiredForOrientationLock() const {
1277 JNIEnv
* env
= AttachCurrentThread();
1278 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1281 return Java_ContentViewCore_isFullscreenRequiredForOrientationLock(env
,
1285 void ContentViewCoreImpl::SetAccessibilityEnabledInternal(bool enabled
) {
1286 accessibility_enabled_
= enabled
;
1287 BrowserAccessibilityStateImpl
* accessibility_state
=
1288 BrowserAccessibilityStateImpl::GetInstance();
1290 // This enables accessibility globally unless it was explicitly disallowed
1291 // by a command-line flag.
1292 accessibility_state
->OnScreenReaderDetected();
1293 // If it was actually enabled globally, enable it for this RenderWidget now.
1294 if (accessibility_state
->IsAccessibleBrowser() && web_contents_
)
1295 web_contents_
->AddAccessibilityMode(AccessibilityModeComplete
);
1297 accessibility_state
->ResetAccessibilityMode();
1298 if (web_contents_
) {
1299 web_contents_
->SetAccessibilityMode(
1300 accessibility_state
->accessibility_mode());
1305 void ContentViewCoreImpl::SendOrientationChangeEventInternal() {
1306 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1308 rwhv
->UpdateScreenInfo(GetViewAndroid());
1310 static_cast<WebContentsImpl
*>(web_contents())->
1311 screen_orientation_dispatcher_host()->OnOrientationChange();
1314 void ContentViewCoreImpl::ExtractSmartClipData(JNIEnv
* env
,
1321 static_cast<int>(x
/ dpi_scale()),
1322 static_cast<int>(y
/ dpi_scale()),
1323 static_cast<int>((width
> 0 && width
< dpi_scale()) ?
1324 1 : (int)(width
/ dpi_scale())),
1325 static_cast<int>((height
> 0 && height
< dpi_scale()) ?
1326 1 : (int)(height
/ dpi_scale())));
1327 GetWebContents()->Send(new ViewMsg_ExtractSmartClipData(
1328 GetWebContents()->GetRoutingID(), rect
));
1331 jint
ContentViewCoreImpl::GetCurrentRenderProcessId(JNIEnv
* env
, jobject obj
) {
1332 return GetRenderProcessIdFromRenderViewHost(
1333 web_contents_
->GetRenderViewHost());
1336 void ContentViewCoreImpl::SetBackgroundOpaque(JNIEnv
* env
, jobject jobj
,
1338 if (GetRenderWidgetHostViewAndroid()) {
1340 GetRenderWidgetHostViewAndroid()->SetBackgroundColorToDefault();
1342 GetRenderWidgetHostViewAndroid()->SetBackgroundColor(SK_ColorTRANSPARENT
);
1346 void ContentViewCoreImpl::RequestTextSurroundingSelection(
1348 const base::Callback
<
1349 void(const base::string16
& content
, int start_offset
, int end_offset
)>&
1351 DCHECK(!callback
.is_null());
1352 RenderFrameHost
* focused_frame
= web_contents_
->GetFocusedFrame();
1355 if (GetRenderWidgetHostViewAndroid()) {
1356 GetRenderWidgetHostViewAndroid()->SetTextSurroundingSelectionCallback(
1358 focused_frame
->Send(new FrameMsg_TextSurroundingSelectionRequest(
1359 focused_frame
->GetRoutingID(), max_length
));
1363 void ContentViewCoreImpl::OnShowUnhandledTapUIIfNeeded(int x_dip
, int y_dip
) {
1364 JNIEnv
* env
= AttachCurrentThread();
1365 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1368 Java_ContentViewCore_onShowUnhandledTapUIIfNeeded(
1369 env
, obj
.obj(), static_cast<jint
>(x_dip
* dpi_scale()),
1370 static_cast<jint
>(y_dip
* dpi_scale()));
1373 float ContentViewCoreImpl::GetScaleFactor() const {
1374 return page_scale_
* dpi_scale_
;
1377 void ContentViewCoreImpl::OnSmartClipDataExtracted(
1378 const base::string16
& text
,
1379 const base::string16
& html
,
1380 const gfx::Rect
& clip_rect
) {
1381 JNIEnv
* env
= AttachCurrentThread();
1382 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1385 ScopedJavaLocalRef
<jstring
> jtext
= ConvertUTF16ToJavaString(env
, text
);
1386 ScopedJavaLocalRef
<jstring
> jhtml
= ConvertUTF16ToJavaString(env
, html
);
1387 ScopedJavaLocalRef
<jobject
> clip_rect_object(CreateJavaRect(env
, clip_rect
));
1388 Java_ContentViewCore_onSmartClipDataExtracted(
1389 env
, obj
.obj(), jtext
.obj(), jhtml
.obj(), clip_rect_object
.obj());
1392 void ContentViewCoreImpl::WebContentsDestroyed() {
1393 WebContentsViewAndroid
* wcva
= static_cast<WebContentsViewAndroid
*>(
1394 static_cast<WebContentsImpl
*>(web_contents())->GetView());
1396 wcva
->SetContentViewCore(NULL
);
1399 bool ContentViewCoreImpl::PullStart() {
1400 JNIEnv
* env
= AttachCurrentThread();
1401 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1403 return Java_ContentViewCore_onOverscrollRefreshStart(env
, obj
.obj());
1407 void ContentViewCoreImpl::PullUpdate(float delta
) {
1408 JNIEnv
* env
= AttachCurrentThread();
1409 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1411 Java_ContentViewCore_onOverscrollRefreshUpdate(env
, obj
.obj(), delta
);
1414 void ContentViewCoreImpl::PullRelease(bool allow_refresh
) {
1415 JNIEnv
* env
= AttachCurrentThread();
1416 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1417 if (!obj
.is_null()) {
1418 Java_ContentViewCore_onOverscrollRefreshRelease(env
, obj
.obj(),
1423 void ContentViewCoreImpl::PullReset() {
1424 JNIEnv
* env
= AttachCurrentThread();
1425 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1427 Java_ContentViewCore_onOverscrollRefreshReset(env
, obj
.obj());
1430 // This is called for each ContentView.
1431 jlong
Init(JNIEnv
* env
,
1432 const JavaParamRef
<jobject
>& obj
,
1433 const JavaParamRef
<jobject
>& web_contents
,
1434 const JavaParamRef
<jobject
>& view_android_delegate
,
1435 jlong window_android
,
1436 const JavaParamRef
<jobject
>& retained_objects_set
) {
1437 ContentViewCoreImpl
* view
= new ContentViewCoreImpl(
1438 env
, obj
, WebContents::FromJavaWebContents(web_contents
),
1439 view_android_delegate
,
1440 reinterpret_cast<ui::WindowAndroid
*>(window_android
),
1441 retained_objects_set
);
1442 return reinterpret_cast<intptr_t>(view
);
1445 static ScopedJavaLocalRef
<jobject
> FromWebContentsAndroid(
1447 const JavaParamRef
<jclass
>& clazz
,
1448 const JavaParamRef
<jobject
>& jweb_contents
) {
1449 WebContents
* web_contents
= WebContents::FromJavaWebContents(jweb_contents
);
1451 return ScopedJavaLocalRef
<jobject
>();
1453 ContentViewCore
* view
= ContentViewCore::FromWebContents(web_contents
);
1455 return ScopedJavaLocalRef
<jobject
>();
1457 return view
->GetJavaObject();
1460 bool RegisterContentViewCore(JNIEnv
* env
) {
1461 return RegisterNativesImpl(env
);
1464 } // namespace content