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/frame_host/navigation_controller_impl.h"
27 #include "content/browser/frame_host/navigation_entry_impl.h"
28 #include "content/browser/frame_host/render_frame_host_impl.h"
29 #include "content/browser/geolocation/geolocation_dispatcher_host.h"
30 #include "content/browser/media/media_web_contents_observer.h"
31 #include "content/browser/renderer_host/compositor_impl_android.h"
32 #include "content/browser/renderer_host/input/motion_event_android.h"
33 #include "content/browser/renderer_host/input/web_input_event_builders_android.h"
34 #include "content/browser/renderer_host/input/web_input_event_util.h"
35 #include "content/browser/renderer_host/render_view_host_impl.h"
36 #include "content/browser/renderer_host/render_widget_host_impl.h"
37 #include "content/browser/renderer_host/render_widget_host_view_android.h"
38 #include "content/browser/screen_orientation/screen_orientation_dispatcher_host.h"
39 #include "content/browser/transition_request_manager.h"
40 #include "content/browser/web_contents/web_contents_view_android.h"
41 #include "content/common/frame_messages.h"
42 #include "content/common/input/web_input_event_traits.h"
43 #include "content/common/input_messages.h"
44 #include "content/common/view_messages.h"
45 #include "content/public/browser/browser_context.h"
46 #include "content/public/browser/browser_thread.h"
47 #include "content/public/browser/favicon_status.h"
48 #include "content/public/browser/render_frame_host.h"
49 #include "content/public/browser/ssl_host_state_delegate.h"
50 #include "content/public/browser/web_contents.h"
51 #include "content/public/common/content_client.h"
52 #include "content/public/common/content_switches.h"
53 #include "content/public/common/menu_item.h"
54 #include "content/public/common/page_transition_types.h"
55 #include "content/public/common/user_agent.h"
56 #include "jni/ContentViewCore_jni.h"
57 #include "third_party/WebKit/public/web/WebInputEvent.h"
58 #include "ui/base/android/view_android.h"
59 #include "ui/base/android/window_android.h"
60 #include "ui/gfx/android/java_bitmap.h"
61 #include "ui/gfx/screen.h"
62 #include "ui/gfx/size_conversions.h"
63 #include "ui/gfx/size_f.h"
65 using base::android::AttachCurrentThread
;
66 using base::android::ConvertJavaStringToUTF16
;
67 using base::android::ConvertJavaStringToUTF8
;
68 using base::android::ConvertUTF16ToJavaString
;
69 using base::android::ConvertUTF8ToJavaString
;
70 using base::android::ScopedJavaLocalRef
;
71 using blink::WebGestureEvent
;
72 using blink::WebInputEvent
;
74 // Describes the type and enabled state of a select popup item.
78 #define DEFINE_POPUP_ITEM_TYPE(name, value) POPUP_ITEM_TYPE_##name = value,
79 #include "content/browser/android/popup_item_type_list.h"
80 #undef DEFINE_POPUP_ITEM_TYPE
89 const void* kContentViewUserDataKey
= &kContentViewUserDataKey
;
91 int GetRenderProcessIdFromRenderViewHost(RenderViewHost
* host
) {
93 RenderProcessHost
* render_process
= host
->GetProcess();
94 DCHECK(render_process
);
95 if (render_process
->HasConnection())
96 return render_process
->GetHandle();
101 ScopedJavaLocalRef
<jobject
> CreateJavaRect(
103 const gfx::Rect
& rect
) {
104 return ScopedJavaLocalRef
<jobject
>(
105 Java_ContentViewCore_createRect(env
,
106 static_cast<int>(rect
.x()),
107 static_cast<int>(rect
.y()),
108 static_cast<int>(rect
.right()),
109 static_cast<int>(rect
.bottom())));
112 int ToGestureEventType(WebInputEvent::Type type
) {
114 case WebInputEvent::GestureScrollBegin
:
116 case WebInputEvent::GestureScrollEnd
:
118 case WebInputEvent::GestureScrollUpdate
:
120 case WebInputEvent::GestureFlingStart
:
122 case WebInputEvent::GestureFlingCancel
:
124 case WebInputEvent::GestureShowPress
:
126 case WebInputEvent::GestureTap
:
127 return SINGLE_TAP_CONFIRMED
;
128 case WebInputEvent::GestureTapUnconfirmed
:
129 return SINGLE_TAP_UNCONFIRMED
;
130 case WebInputEvent::GestureTapDown
:
132 case WebInputEvent::GestureTapCancel
:
134 case WebInputEvent::GestureDoubleTap
:
136 case WebInputEvent::GestureLongPress
:
138 case WebInputEvent::GestureLongTap
:
140 case WebInputEvent::GesturePinchBegin
:
142 case WebInputEvent::GesturePinchEnd
:
144 case WebInputEvent::GesturePinchUpdate
:
146 case WebInputEvent::GestureTwoFingerTap
:
147 case WebInputEvent::GestureScrollUpdateWithoutPropagation
:
149 NOTREACHED() << "Invalid source gesture type: "
150 << WebInputEventTraits::GetName(type
);
155 float GetPrimaryDisplayDeviceScaleFactor() {
156 const gfx::Display
& display
=
157 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
158 return display
.device_scale_factor();
163 // Enables a callback when the underlying WebContents is destroyed, to enable
164 // nulling the back-pointer.
165 class ContentViewCoreImpl::ContentViewUserData
166 : public base::SupportsUserData::Data
{
168 explicit ContentViewUserData(ContentViewCoreImpl
* content_view_core
)
169 : content_view_core_(content_view_core
) {
172 virtual ~ContentViewUserData() {
173 // TODO(joth): When chrome has finished removing the TabContents class (see
174 // crbug.com/107201) consider inverting relationship, so ContentViewCore
175 // would own WebContents. That effectively implies making the WebContents
176 // destructor private on Android.
177 delete content_view_core_
;
180 ContentViewCoreImpl
* get() const { return content_view_core_
; }
183 // Not using scoped_ptr as ContentViewCoreImpl destructor is private.
184 ContentViewCoreImpl
* content_view_core_
;
186 DISALLOW_IMPLICIT_CONSTRUCTORS(ContentViewUserData
);
190 ContentViewCoreImpl
* ContentViewCoreImpl::FromWebContents(
191 content::WebContents
* web_contents
) {
192 ContentViewCoreImpl::ContentViewUserData
* data
=
193 reinterpret_cast<ContentViewCoreImpl::ContentViewUserData
*>(
194 web_contents
->GetUserData(kContentViewUserDataKey
));
195 return data
? data
->get() : NULL
;
199 ContentViewCore
* ContentViewCore::FromWebContents(
200 content::WebContents
* web_contents
) {
201 return ContentViewCoreImpl::FromWebContents(web_contents
);
205 ContentViewCore
* ContentViewCore::GetNativeContentViewCore(JNIEnv
* env
,
207 return reinterpret_cast<ContentViewCore
*>(
208 Java_ContentViewCore_getNativeContentViewCore(env
, obj
));
211 ContentViewCoreImpl::ContentViewCoreImpl(
214 WebContents
* web_contents
,
215 ui::ViewAndroid
* view_android
,
216 ui::WindowAndroid
* window_android
,
217 jobject java_bridge_retained_object_set
)
218 : WebContentsObserver(web_contents
),
220 web_contents_(static_cast<WebContentsImpl
*>(web_contents
)),
221 root_layer_(cc::SolidColorLayer::Create()),
222 dpi_scale_(GetPrimaryDisplayDeviceScaleFactor()),
223 view_android_(view_android
),
224 window_android_(window_android
),
225 device_orientation_(0),
226 accessibility_enabled_(false) {
227 CHECK(web_contents
) <<
228 "A ContentViewCoreImpl should be created with a valid WebContents.";
229 DCHECK(view_android_
);
230 DCHECK(window_android_
);
232 root_layer_
->SetBackgroundColor(GetBackgroundColor(env
, obj
));
233 gfx::Size
physical_size(
234 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, obj
),
235 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, obj
));
236 root_layer_
->SetBounds(physical_size
);
237 root_layer_
->SetIsDrawable(true);
239 // Currently, the only use case we have for overriding a user agent involves
240 // spoofing a desktop Linux user agent for "Request desktop site".
241 // Automatically set it for all WebContents so that it is available when a
242 // NavigationEntry requires the user agent to be overridden.
243 const char kLinuxInfoStr
[] = "X11; Linux x86_64";
244 std::string product
= content::GetContentClient()->GetProduct();
245 std::string spoofed_ua
=
246 BuildUserAgentFromOSAndProduct(kLinuxInfoStr
, product
);
247 web_contents
->SetUserAgentOverride(spoofed_ua
);
249 java_bridge_dispatcher_host_
.reset(
250 new GinJavaBridgeDispatcherHost(web_contents
,
251 java_bridge_retained_object_set
));
256 ContentViewCoreImpl::~ContentViewCoreImpl() {
257 JNIEnv
* env
= base::android::AttachCurrentThread();
258 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
260 if (!j_obj
.is_null()) {
261 Java_ContentViewCore_onNativeContentViewCoreDestroyed(
262 env
, j_obj
.obj(), reinterpret_cast<intptr_t>(this));
266 base::android::ScopedJavaLocalRef
<jobject
>
267 ContentViewCoreImpl::GetWebContentsAndroid(JNIEnv
* env
, jobject obj
) {
268 return web_contents_
->GetJavaWebContents();
271 void ContentViewCoreImpl::OnJavaContentViewCoreDestroyed(JNIEnv
* env
,
273 DCHECK(env
->IsSameObject(java_ref_
.get(env
).obj(), obj
));
275 // Java peer has gone, ContentViewCore is not functional and waits to
276 // be destroyed with WebContents.
277 // We need to reset WebContentsViewAndroid's reference, otherwise, there
278 // could have call in when swapping the WebContents,
279 // see http://crbug.com/383939 .
280 DCHECK(web_contents_
);
281 static_cast<WebContentsViewAndroid
*>(
282 static_cast<WebContentsImpl
*>(web_contents_
)->GetView())->
283 SetContentViewCore(NULL
);
286 void ContentViewCoreImpl::InitWebContents() {
287 DCHECK(web_contents_
);
288 static_cast<WebContentsViewAndroid
*>(
289 static_cast<WebContentsImpl
*>(web_contents_
)->GetView())->
290 SetContentViewCore(this);
291 DCHECK(!web_contents_
->GetUserData(kContentViewUserDataKey
));
292 web_contents_
->SetUserData(kContentViewUserDataKey
,
293 new ContentViewUserData(this));
296 void ContentViewCoreImpl::RenderViewReady() {
297 JNIEnv
* env
= AttachCurrentThread();
298 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
300 Java_ContentViewCore_onRenderProcessChange(env
, obj
.obj());
302 if (device_orientation_
!= 0)
303 SendOrientationChangeEventInternal();
306 void ContentViewCoreImpl::RenderViewHostChanged(RenderViewHost
* old_host
,
307 RenderViewHost
* new_host
) {
310 old_pid
= GetRenderProcessIdFromRenderViewHost(old_host
);
312 RenderWidgetHostViewAndroid
* view
=
313 static_cast<RenderWidgetHostViewAndroid
*>(old_host
->GetView());
315 view
->SetContentViewCore(NULL
);
317 view
= static_cast<RenderWidgetHostViewAndroid
*>(new_host
->GetView());
319 view
->SetContentViewCore(this);
321 int new_pid
= GetRenderProcessIdFromRenderViewHost(
322 web_contents_
->GetRenderViewHost());
323 if (new_pid
!= old_pid
) {
324 // Notify the Java side that the renderer process changed.
325 JNIEnv
* env
= AttachCurrentThread();
326 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
327 if (!obj
.is_null()) {
328 Java_ContentViewCore_onRenderProcessChange(env
, obj
.obj());
332 SetFocusInternal(HasFocus());
333 SetAccessibilityEnabledInternal(accessibility_enabled_
);
336 RenderWidgetHostViewAndroid
*
337 ContentViewCoreImpl::GetRenderWidgetHostViewAndroid() {
338 RenderWidgetHostView
* rwhv
= NULL
;
340 rwhv
= web_contents_
->GetRenderWidgetHostView();
341 if (web_contents_
->ShowingInterstitialPage()) {
342 rwhv
= static_cast<InterstitialPageImpl
*>(
343 web_contents_
->GetInterstitialPage())->
344 GetRenderViewHost()->GetView();
347 return static_cast<RenderWidgetHostViewAndroid
*>(rwhv
);
350 ScopedJavaLocalRef
<jobject
> ContentViewCoreImpl::GetJavaObject() {
351 JNIEnv
* env
= AttachCurrentThread();
352 return java_ref_
.get(env
);
355 jint
ContentViewCoreImpl::GetBackgroundColor(JNIEnv
* env
, jobject obj
) {
356 RenderWidgetHostViewAndroid
* rwhva
= GetRenderWidgetHostViewAndroid();
358 return SK_ColorWHITE
;
359 return rwhva
->GetCachedBackgroundColor();
362 void ContentViewCoreImpl::PauseVideo() {
363 RenderViewHostImpl
* rvhi
= static_cast<RenderViewHostImpl
*>(
364 web_contents_
->GetRenderViewHost());
366 rvhi
->media_web_contents_observer()->PauseVideo();
369 void ContentViewCoreImpl::PauseOrResumeGeolocation(bool should_pause
) {
370 web_contents_
->geolocation_dispatcher_host()->PauseOrResume(should_pause
);
373 // All positions and sizes are in CSS pixels.
374 // Note that viewport_width/height is a best effort based.
375 // ContentViewCore has the actual information about the physical viewport size.
376 void ContentViewCoreImpl::UpdateFrameInfo(
377 const gfx::Vector2dF
& scroll_offset
,
378 float page_scale_factor
,
379 const gfx::Vector2dF
& page_scale_factor_limits
,
380 const gfx::SizeF
& content_size
,
381 const gfx::SizeF
& viewport_size
,
382 const gfx::Vector2dF
& controls_offset
,
383 const gfx::Vector2dF
& content_offset
) {
384 JNIEnv
* env
= AttachCurrentThread();
385 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
389 window_android_
->set_content_offset(
390 gfx::ScaleVector2d(content_offset
, dpi_scale_
));
392 Java_ContentViewCore_updateFrameInfo(
397 page_scale_factor_limits
.x(),
398 page_scale_factor_limits
.y(),
399 content_size
.width(),
400 content_size
.height(),
401 viewport_size
.width(),
402 viewport_size
.height(),
407 void ContentViewCoreImpl::SetTitle(const base::string16
& title
) {
408 JNIEnv
* env
= AttachCurrentThread();
409 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
412 ScopedJavaLocalRef
<jstring
> jtitle
=
413 ConvertUTF8ToJavaString(env
, base::UTF16ToUTF8(title
));
414 Java_ContentViewCore_setTitle(env
, obj
.obj(), jtitle
.obj());
417 void ContentViewCoreImpl::OnBackgroundColorChanged(SkColor color
) {
418 root_layer_
->SetBackgroundColor(color
);
420 JNIEnv
* env
= AttachCurrentThread();
421 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
424 Java_ContentViewCore_onBackgroundColorChanged(env
, obj
.obj(), color
);
427 void ContentViewCoreImpl::ShowSelectPopupMenu(
428 RenderFrameHost
* frame
,
429 const gfx::Rect
& bounds
,
430 const std::vector
<MenuItem
>& items
,
433 JNIEnv
* env
= AttachCurrentThread();
434 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
438 ScopedJavaLocalRef
<jobject
> bounds_rect(CreateJavaRect(env
, bounds
));
440 // For multi-select list popups we find the list of previous selections by
441 // iterating through the items. But for single selection popups we take the
442 // given |selected_item| as is.
443 ScopedJavaLocalRef
<jintArray
> selected_array
;
445 scoped_ptr
<jint
[]> native_selected_array(new jint
[items
.size()]);
446 size_t selected_count
= 0;
447 for (size_t i
= 0; i
< items
.size(); ++i
) {
448 if (items
[i
].checked
)
449 native_selected_array
[selected_count
++] = i
;
452 selected_array
= ScopedJavaLocalRef
<jintArray
>(
453 env
, env
->NewIntArray(selected_count
));
454 env
->SetIntArrayRegion(selected_array
.obj(), 0, selected_count
,
455 native_selected_array
.get());
457 selected_array
= ScopedJavaLocalRef
<jintArray
>(env
, env
->NewIntArray(1));
458 jint value
= selected_item
;
459 env
->SetIntArrayRegion(selected_array
.obj(), 0, 1, &value
);
462 ScopedJavaLocalRef
<jintArray
> enabled_array(env
,
463 env
->NewIntArray(items
.size()));
464 std::vector
<base::string16
> labels
;
465 labels
.reserve(items
.size());
466 for (size_t i
= 0; i
< items
.size(); ++i
) {
467 labels
.push_back(items
[i
].label
);
469 (items
[i
].type
== MenuItem::GROUP
? POPUP_ITEM_TYPE_GROUP
:
470 (items
[i
].enabled
? POPUP_ITEM_TYPE_ENABLED
:
471 POPUP_ITEM_TYPE_DISABLED
));
472 env
->SetIntArrayRegion(enabled_array
.obj(), i
, 1, &enabled
);
474 ScopedJavaLocalRef
<jobjectArray
> items_array(
475 base::android::ToJavaArrayOfStrings(env
, labels
));
476 Java_ContentViewCore_showSelectPopup(env
,
478 reinterpret_cast<intptr_t>(frame
),
483 selected_array
.obj());
486 void ContentViewCoreImpl::HideSelectPopupMenu() {
487 JNIEnv
* env
= AttachCurrentThread();
488 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
489 if (!j_obj
.is_null())
490 Java_ContentViewCore_hideSelectPopup(env
, j_obj
.obj());
493 void ContentViewCoreImpl::OnGestureEventAck(const blink::WebGestureEvent
& event
,
494 InputEventAckState ack_result
) {
495 JNIEnv
* env
= AttachCurrentThread();
496 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
500 switch (event
.type
) {
501 case WebInputEvent::GestureFlingStart
:
502 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
) {
503 // The view expects the fling velocity in pixels/s.
504 Java_ContentViewCore_onFlingStartEventConsumed(env
, j_obj
.obj(),
505 event
.data
.flingStart
.velocityX
* dpi_scale(),
506 event
.data
.flingStart
.velocityY
* dpi_scale());
508 // If a scroll ends with a fling, a SCROLL_END event is never sent.
509 // However, if that fling went unconsumed, we still need to let the
510 // listeners know that scrolling has ended.
511 Java_ContentViewCore_onScrollEndEventAck(env
, j_obj
.obj());
514 if (ack_result
== INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS
) {
515 // The view expects the fling velocity in pixels/s.
516 Java_ContentViewCore_onFlingStartEventHadNoConsumer(env
, j_obj
.obj(),
517 event
.data
.flingStart
.velocityX
* dpi_scale(),
518 event
.data
.flingStart
.velocityY
* dpi_scale());
521 case WebInputEvent::GestureFlingCancel
:
522 Java_ContentViewCore_onFlingCancelEventAck(env
, j_obj
.obj());
524 case WebInputEvent::GestureScrollBegin
:
525 Java_ContentViewCore_onScrollBeginEventAck(env
, j_obj
.obj());
527 case WebInputEvent::GestureScrollUpdate
:
528 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
)
529 Java_ContentViewCore_onScrollUpdateGestureConsumed(env
, j_obj
.obj());
531 case WebInputEvent::GestureScrollEnd
:
532 Java_ContentViewCore_onScrollEndEventAck(env
, j_obj
.obj());
534 case WebInputEvent::GesturePinchBegin
:
535 Java_ContentViewCore_onPinchBeginEventAck(env
, j_obj
.obj());
537 case WebInputEvent::GesturePinchEnd
:
538 Java_ContentViewCore_onPinchEndEventAck(env
, j_obj
.obj());
540 case WebInputEvent::GestureTap
:
541 Java_ContentViewCore_onSingleTapEventAck(
544 ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
,
545 event
.x
* dpi_scale(),
546 event
.y
* dpi_scale());
553 bool ContentViewCoreImpl::FilterInputEvent(const blink::WebInputEvent
& event
) {
554 if (event
.type
!= WebInputEvent::GestureTap
&&
555 event
.type
!= WebInputEvent::GestureDoubleTap
&&
556 event
.type
!= WebInputEvent::GestureLongTap
&&
557 event
.type
!= WebInputEvent::GestureLongPress
)
560 JNIEnv
* env
= AttachCurrentThread();
561 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
565 const blink::WebGestureEvent
& gesture
=
566 static_cast<const blink::WebGestureEvent
&>(event
);
567 int gesture_type
= ToGestureEventType(event
.type
);
568 return Java_ContentViewCore_filterTapOrPressEvent(env
,
571 gesture
.x
* dpi_scale(),
572 gesture
.y
* dpi_scale());
574 // TODO(jdduke): Also report double-tap UMA, crbug/347568.
577 bool ContentViewCoreImpl::HasFocus() {
578 JNIEnv
* env
= AttachCurrentThread();
579 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
582 return Java_ContentViewCore_hasFocus(env
, obj
.obj());
585 void ContentViewCoreImpl::OnSelectionChanged(const std::string
& text
) {
586 JNIEnv
* env
= AttachCurrentThread();
587 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
590 ScopedJavaLocalRef
<jstring
> jtext
= ConvertUTF8ToJavaString(env
, text
);
591 Java_ContentViewCore_onSelectionChanged(env
, obj
.obj(), jtext
.obj());
594 void ContentViewCoreImpl::OnSelectionEvent(SelectionEventType event
,
595 const gfx::PointF
& position
) {
596 JNIEnv
* env
= AttachCurrentThread();
597 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
600 Java_ContentViewCore_onSelectionEvent(
601 env
, j_obj
.obj(), event
, position
.x(), position
.y());
604 scoped_ptr
<TouchHandleDrawable
>
605 ContentViewCoreImpl::CreatePopupTouchHandleDrawable() {
606 JNIEnv
* env
= AttachCurrentThread();
607 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
610 return scoped_ptr
<TouchHandleDrawable
>();
612 return scoped_ptr
<TouchHandleDrawable
>(new PopupTouchHandleDrawable(
613 Java_ContentViewCore_createPopupTouchHandleDrawable(env
, obj
.obj()),
617 void ContentViewCoreImpl::ShowPastePopup(int x_dip
, int y_dip
) {
618 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
622 view
->OnShowingPastePopup(gfx::PointF(x_dip
, y_dip
));
624 JNIEnv
* env
= AttachCurrentThread();
625 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
628 Java_ContentViewCore_showPastePopupWithFeedback(env
, obj
.obj(),
629 static_cast<jint
>(x_dip
),
630 static_cast<jint
>(y_dip
));
633 void ContentViewCoreImpl::GetScaledContentBitmap(
635 SkColorType color_type
,
636 gfx::Rect src_subrect
,
637 const base::Callback
<void(bool, const SkBitmap
&)>& result_callback
) {
638 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
640 result_callback
.Run(false, SkBitmap());
644 view
->GetScaledContentBitmap(scale
, color_type
, src_subrect
,
648 void ContentViewCoreImpl::StartContentIntent(const GURL
& content_url
) {
649 JNIEnv
* env
= AttachCurrentThread();
650 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
653 ScopedJavaLocalRef
<jstring
> jcontent_url
=
654 ConvertUTF8ToJavaString(env
, content_url
.spec());
655 Java_ContentViewCore_startContentIntent(env
,
660 void ContentViewCoreImpl::ShowDisambiguationPopup(
661 const gfx::Rect
& target_rect
,
662 const SkBitmap
& zoomed_bitmap
) {
663 JNIEnv
* env
= AttachCurrentThread();
665 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
669 ScopedJavaLocalRef
<jobject
> rect_object(CreateJavaRect(env
, target_rect
));
671 ScopedJavaLocalRef
<jobject
> java_bitmap
=
672 gfx::ConvertToJavaBitmap(&zoomed_bitmap
);
673 DCHECK(!java_bitmap
.is_null());
675 Java_ContentViewCore_showDisambiguationPopup(env
,
681 ScopedJavaLocalRef
<jobject
> ContentViewCoreImpl::CreateTouchEventSynthesizer() {
682 JNIEnv
* env
= AttachCurrentThread();
684 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
686 return ScopedJavaLocalRef
<jobject
>();
687 return Java_ContentViewCore_createTouchEventSynthesizer(env
, obj
.obj());
690 ScopedJavaLocalRef
<jobject
> ContentViewCoreImpl::GetContentVideoViewClient() {
691 JNIEnv
* env
= AttachCurrentThread();
693 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
695 return ScopedJavaLocalRef
<jobject
>();
697 return Java_ContentViewCore_getContentVideoViewClient(env
, obj
.obj());
700 ScopedJavaLocalRef
<jobject
> ContentViewCoreImpl::GetContext() {
701 JNIEnv
* env
= AttachCurrentThread();
703 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
705 return ScopedJavaLocalRef
<jobject
>();
707 return Java_ContentViewCore_getContext(env
, obj
.obj());
710 bool ContentViewCoreImpl::ShouldBlockMediaRequest(const GURL
& url
) {
711 JNIEnv
* env
= AttachCurrentThread();
713 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
716 ScopedJavaLocalRef
<jstring
> j_url
= ConvertUTF8ToJavaString(env
, url
.spec());
717 return Java_ContentViewCore_shouldBlockMediaRequest(env
, obj
.obj(),
721 void ContentViewCoreImpl::DidStopFlinging() {
722 JNIEnv
* env
= AttachCurrentThread();
724 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
726 Java_ContentViewCore_onNativeFlingStopped(env
, obj
.obj());
729 gfx::Size
ContentViewCoreImpl::GetViewSize() const {
730 gfx::Size size
= GetViewportSizeDip();
731 size
.Enlarge(0, -GetTopControlsLayoutHeightDip());
735 gfx::Size
ContentViewCoreImpl::GetPhysicalBackingSize() const {
736 JNIEnv
* env
= AttachCurrentThread();
737 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
741 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, j_obj
.obj()),
742 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, j_obj
.obj()));
745 gfx::Size
ContentViewCoreImpl::GetViewportSizePix() const {
746 JNIEnv
* env
= AttachCurrentThread();
747 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
751 Java_ContentViewCore_getViewportWidthPix(env
, j_obj
.obj()),
752 Java_ContentViewCore_getViewportHeightPix(env
, j_obj
.obj()));
755 int ContentViewCoreImpl::GetTopControlsLayoutHeightPix() const {
756 JNIEnv
* env
= AttachCurrentThread();
757 ScopedJavaLocalRef
<jobject
> j_obj
= java_ref_
.get(env
);
760 return Java_ContentViewCore_getTopControlsLayoutHeightPix(env
, j_obj
.obj());
763 gfx::Size
ContentViewCoreImpl::GetViewportSizeDip() const {
764 return gfx::ToCeiledSize(
765 gfx::ScaleSize(GetViewportSizePix(), 1.0f
/ dpi_scale()));
768 float ContentViewCoreImpl::GetTopControlsLayoutHeightDip() const {
769 return GetTopControlsLayoutHeightPix() / dpi_scale();
772 void ContentViewCoreImpl::AttachLayer(scoped_refptr
<cc::Layer
> layer
) {
773 root_layer_
->InsertChild(layer
, 0);
774 root_layer_
->SetIsDrawable(false);
777 void ContentViewCoreImpl::RemoveLayer(scoped_refptr
<cc::Layer
> layer
) {
778 layer
->RemoveFromParent();
780 if (!root_layer_
->children().size())
781 root_layer_
->SetIsDrawable(true);
784 void ContentViewCoreImpl::SelectBetweenCoordinates(const gfx::PointF
& start
,
785 const gfx::PointF
& end
) {
789 gfx::Point start_point
= gfx::Point(start
.x(), start
.y());
790 gfx::Point end_point
= gfx::Point(end
.x(), end
.y());
791 if (start_point
== end_point
)
794 web_contents_
->SelectRange(start_point
, end_point
);
797 void ContentViewCoreImpl::LoadUrl(
798 NavigationController::LoadURLParams
& params
) {
799 GetWebContents()->GetController().LoadURLWithParams(params
);
802 ui::ViewAndroid
* ContentViewCoreImpl::GetViewAndroid() const {
803 return view_android_
;
806 ui::WindowAndroid
* ContentViewCoreImpl::GetWindowAndroid() const {
807 return window_android_
;
810 scoped_refptr
<cc::Layer
> ContentViewCoreImpl::GetLayer() const {
811 return root_layer_
.get();
814 // ----------------------------------------------------------------------------
815 // Methods called from Java via JNI
816 // ----------------------------------------------------------------------------
818 void ContentViewCoreImpl::SelectPopupMenuItems(JNIEnv
* env
,
820 jlong selectPopupSourceFrame
,
822 RenderFrameHostImpl
* rfhi
=
823 reinterpret_cast<RenderFrameHostImpl
*>(selectPopupSourceFrame
);
825 if (indices
== NULL
) {
826 rfhi
->DidCancelPopupMenu();
830 int selected_count
= env
->GetArrayLength(indices
);
831 std::vector
<int> selected_indices
;
832 jint
* indices_ptr
= env
->GetIntArrayElements(indices
, NULL
);
833 for (int i
= 0; i
< selected_count
; ++i
)
834 selected_indices
.push_back(indices_ptr
[i
]);
835 env
->ReleaseIntArrayElements(indices
, indices_ptr
, JNI_ABORT
);
836 rfhi
->DidSelectPopupMenuItems(selected_indices
);
839 void ContentViewCoreImpl::LoadUrl(
840 JNIEnv
* env
, jobject obj
,
843 jint transition_type
,
844 jstring j_referrer_url
,
845 jint referrer_policy
,
846 jint ua_override_option
,
847 jstring extra_headers
,
848 jbyteArray post_data
,
849 jstring base_url_for_data_url
,
850 jstring virtual_url_for_data_url
,
851 jboolean can_load_local_resources
,
852 jboolean is_renderer_initiated
) {
854 NavigationController::LoadURLParams
params(
855 GURL(ConvertJavaStringToUTF8(env
, url
)));
857 params
.load_type
= static_cast<NavigationController::LoadURLType
>(
859 params
.transition_type
= PageTransitionFromInt(transition_type
);
860 params
.override_user_agent
=
861 static_cast<NavigationController::UserAgentOverrideOption
>(
865 params
.extra_headers
= ConvertJavaStringToUTF8(env
, extra_headers
);
868 std::vector
<uint8
> http_body_vector
;
869 base::android::JavaByteArrayToByteVector(env
, post_data
, &http_body_vector
);
870 params
.browser_initiated_post_data
=
871 base::RefCountedBytes::TakeVector(&http_body_vector
);
874 if (base_url_for_data_url
) {
875 params
.base_url_for_data_url
=
876 GURL(ConvertJavaStringToUTF8(env
, base_url_for_data_url
));
879 if (virtual_url_for_data_url
) {
880 params
.virtual_url_for_data_url
=
881 GURL(ConvertJavaStringToUTF8(env
, virtual_url_for_data_url
));
884 params
.can_load_local_resources
= can_load_local_resources
;
885 if (j_referrer_url
) {
886 params
.referrer
= content::Referrer(
887 GURL(ConvertJavaStringToUTF8(env
, j_referrer_url
)),
888 static_cast<blink::WebReferrerPolicy
>(referrer_policy
));
891 params
.is_renderer_initiated
= is_renderer_initiated
;
896 WebContents
* ContentViewCoreImpl::GetWebContents() const {
897 return web_contents_
;
900 void ContentViewCoreImpl::SetFocus(JNIEnv
* env
, jobject obj
, jboolean focused
) {
901 SetFocusInternal(focused
);
904 void ContentViewCoreImpl::SetFocusInternal(bool focused
) {
905 if (!GetRenderWidgetHostViewAndroid())
909 GetRenderWidgetHostViewAndroid()->Focus();
911 GetRenderWidgetHostViewAndroid()->Blur();
914 void ContentViewCoreImpl::SendOrientationChangeEvent(JNIEnv
* env
,
917 if (device_orientation_
!= orientation
) {
918 device_orientation_
= orientation
;
919 SendOrientationChangeEventInternal();
923 jboolean
ContentViewCoreImpl::OnTouchEvent(JNIEnv
* env
,
925 jobject motion_event
,
937 jfloat touch_major_0
,
938 jfloat touch_major_1
,
941 jint android_tool_type_0
,
942 jint android_tool_type_1
,
943 jint android_button_state
,
944 jboolean is_touch_handle_event
) {
945 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
946 // Avoid synthesizing a touch event if it cannot be forwarded.
950 MotionEventAndroid
event(1.f
/ dpi_scale(),
970 android_button_state
);
972 return is_touch_handle_event
? rwhv
->OnTouchHandleEvent(event
)
973 : rwhv
->OnTouchEvent(event
);
976 float ContentViewCoreImpl::GetDpiScale() const {
980 jboolean
ContentViewCoreImpl::SendMouseMoveEvent(JNIEnv
* env
,
985 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
989 blink::WebMouseEvent event
= WebMouseEventBuilder::Build(
990 WebInputEvent::MouseMove
,
991 blink::WebMouseEvent::ButtonNone
,
992 time_ms
/ 1000.0, x
/ dpi_scale(), y
/ dpi_scale(), 0, 1);
994 rwhv
->SendMouseEvent(event
);
998 jboolean
ContentViewCoreImpl::SendMouseWheelEvent(JNIEnv
* env
,
1003 jfloat vertical_axis
) {
1004 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1008 WebMouseWheelEventBuilder::Direction direction
;
1009 if (vertical_axis
> 0) {
1010 direction
= WebMouseWheelEventBuilder::DIRECTION_UP
;
1011 } else if (vertical_axis
< 0) {
1012 direction
= WebMouseWheelEventBuilder::DIRECTION_DOWN
;
1016 blink::WebMouseWheelEvent event
= WebMouseWheelEventBuilder::Build(
1017 direction
, time_ms
/ 1000.0, x
/ dpi_scale(), y
/ dpi_scale());
1019 rwhv
->SendMouseWheelEvent(event
);
1023 WebGestureEvent
ContentViewCoreImpl::MakeGestureEvent(
1024 WebInputEvent::Type type
, int64 time_ms
, float x
, float y
) const {
1025 return WebGestureEventBuilder::Build(
1026 type
, time_ms
/ 1000.0, x
/ dpi_scale(), y
/ dpi_scale());
1029 void ContentViewCoreImpl::SendGestureEvent(
1030 const blink::WebGestureEvent
& event
) {
1031 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1033 rwhv
->SendGestureEvent(event
);
1036 void ContentViewCoreImpl::ScrollBegin(JNIEnv
* env
,
1043 WebGestureEvent event
= MakeGestureEvent(
1044 WebInputEvent::GestureScrollBegin
, time_ms
, x
, y
);
1045 event
.data
.scrollBegin
.deltaXHint
= hintx
/ dpi_scale();
1046 event
.data
.scrollBegin
.deltaYHint
= hinty
/ dpi_scale();
1048 SendGestureEvent(event
);
1051 void ContentViewCoreImpl::ScrollEnd(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1052 WebGestureEvent event
= MakeGestureEvent(
1053 WebInputEvent::GestureScrollEnd
, time_ms
, 0, 0);
1054 SendGestureEvent(event
);
1057 void ContentViewCoreImpl::ScrollBy(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1058 jfloat x
, jfloat y
, jfloat dx
, jfloat dy
) {
1059 WebGestureEvent event
= MakeGestureEvent(
1060 WebInputEvent::GestureScrollUpdate
, time_ms
, x
, y
);
1061 event
.data
.scrollUpdate
.deltaX
= -dx
/ dpi_scale();
1062 event
.data
.scrollUpdate
.deltaY
= -dy
/ dpi_scale();
1064 SendGestureEvent(event
);
1067 void ContentViewCoreImpl::FlingStart(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1068 jfloat x
, jfloat y
, jfloat vx
, jfloat vy
) {
1069 WebGestureEvent event
= MakeGestureEvent(
1070 WebInputEvent::GestureFlingStart
, time_ms
, x
, y
);
1071 event
.data
.flingStart
.velocityX
= vx
/ dpi_scale();
1072 event
.data
.flingStart
.velocityY
= vy
/ dpi_scale();
1074 SendGestureEvent(event
);
1077 void ContentViewCoreImpl::FlingCancel(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1078 WebGestureEvent event
= MakeGestureEvent(
1079 WebInputEvent::GestureFlingCancel
, time_ms
, 0, 0);
1080 SendGestureEvent(event
);
1083 void ContentViewCoreImpl::SingleTap(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1084 jfloat x
, jfloat y
) {
1085 WebGestureEvent event
= MakeGestureEvent(
1086 WebInputEvent::GestureTap
, time_ms
, x
, y
);
1087 event
.data
.tap
.tapCount
= 1;
1089 SendGestureEvent(event
);
1092 void ContentViewCoreImpl::DoubleTap(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1093 jfloat x
, jfloat y
) {
1094 WebGestureEvent event
= MakeGestureEvent(
1095 WebInputEvent::GestureDoubleTap
, time_ms
, x
, y
);
1096 // Set the tap count to 1 even for DoubleTap, in order to be consistent with
1097 // double tap behavior on a mobile viewport. See crbug.com/234986 for context.
1098 event
.data
.tap
.tapCount
= 1;
1100 SendGestureEvent(event
);
1103 void ContentViewCoreImpl::LongPress(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1104 jfloat x
, jfloat y
) {
1105 WebGestureEvent event
= MakeGestureEvent(
1106 WebInputEvent::GestureLongPress
, time_ms
, x
, y
);
1108 SendGestureEvent(event
);
1111 void ContentViewCoreImpl::PinchBegin(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1112 jfloat x
, jfloat y
) {
1113 WebGestureEvent event
= MakeGestureEvent(
1114 WebInputEvent::GesturePinchBegin
, time_ms
, x
, y
);
1115 SendGestureEvent(event
);
1118 void ContentViewCoreImpl::PinchEnd(JNIEnv
* env
, jobject obj
, jlong time_ms
) {
1119 WebGestureEvent event
= MakeGestureEvent(
1120 WebInputEvent::GesturePinchEnd
, time_ms
, 0, 0);
1121 SendGestureEvent(event
);
1124 void ContentViewCoreImpl::PinchBy(JNIEnv
* env
, jobject obj
, jlong time_ms
,
1125 jfloat anchor_x
, jfloat anchor_y
,
1127 WebGestureEvent event
= MakeGestureEvent(
1128 WebInputEvent::GesturePinchUpdate
, time_ms
, anchor_x
, anchor_y
);
1129 event
.data
.pinchUpdate
.scale
= delta
;
1131 SendGestureEvent(event
);
1134 void ContentViewCoreImpl::SelectBetweenCoordinates(JNIEnv
* env
, jobject obj
,
1135 jfloat x1
, jfloat y1
,
1136 jfloat x2
, jfloat y2
) {
1137 SelectBetweenCoordinates(gfx::PointF(x1
/ dpi_scale(), y1
/ dpi_scale()),
1138 gfx::PointF(x2
/ dpi_scale(), y2
/ dpi_scale()));
1141 void ContentViewCoreImpl::MoveCaret(JNIEnv
* env
, jobject obj
,
1142 jfloat x
, jfloat y
) {
1143 if (GetRenderWidgetHostViewAndroid()) {
1144 GetRenderWidgetHostViewAndroid()->MoveCaret(
1145 gfx::Point(x
/ dpi_scale_
, y
/ dpi_scale_
));
1149 void ContentViewCoreImpl::HideTextHandles(JNIEnv
* env
, jobject obj
) {
1150 if (GetRenderWidgetHostViewAndroid())
1151 GetRenderWidgetHostViewAndroid()->HideTextHandles();
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::ClearHistory(JNIEnv
* env
, jobject obj
) {
1177 // TODO(creis): Do callers of this need to know if it fails?
1178 if (web_contents_
->GetController().CanPruneAllButLastCommitted())
1179 web_contents_
->GetController().PruneAllButLastCommitted();
1182 void ContentViewCoreImpl::SetAllowJavascriptInterfacesInspection(
1186 java_bridge_dispatcher_host_
->SetAllowObjectContentsInspection(allow
);
1189 void ContentViewCoreImpl::AddJavascriptInterface(
1194 jclass safe_annotation_clazz
) {
1195 ScopedJavaLocalRef
<jobject
> scoped_object(env
, object
);
1196 ScopedJavaLocalRef
<jclass
> scoped_clazz(env
, safe_annotation_clazz
);
1197 java_bridge_dispatcher_host_
->AddNamedObject(
1198 ConvertJavaStringToUTF8(env
, name
), scoped_object
, scoped_clazz
);
1201 void ContentViewCoreImpl::RemoveJavascriptInterface(JNIEnv
* env
,
1204 java_bridge_dispatcher_host_
->RemoveNamedObject(
1205 ConvertJavaStringToUTF8(env
, name
));
1208 void ContentViewCoreImpl::WasResized(JNIEnv
* env
, jobject obj
) {
1209 RenderWidgetHostViewAndroid
* view
= GetRenderWidgetHostViewAndroid();
1210 gfx::Size
physical_size(
1211 Java_ContentViewCore_getPhysicalBackingWidthPix(env
, obj
),
1212 Java_ContentViewCore_getPhysicalBackingHeightPix(env
, obj
));
1213 root_layer_
->SetBounds(physical_size
);
1216 RenderWidgetHostImpl
* host
= RenderWidgetHostImpl::From(
1217 view
->GetRenderWidgetHost());
1218 host
->SendScreenRects();
1225 static void AddNavigationEntryToHistory(JNIEnv
* env
, jobject obj
,
1227 NavigationEntry
* entry
,
1229 // Get the details of the current entry
1230 ScopedJavaLocalRef
<jstring
> j_url(
1231 ConvertUTF8ToJavaString(env
, entry
->GetURL().spec()));
1232 ScopedJavaLocalRef
<jstring
> j_virtual_url(
1233 ConvertUTF8ToJavaString(env
, entry
->GetVirtualURL().spec()));
1234 ScopedJavaLocalRef
<jstring
> j_original_url(
1235 ConvertUTF8ToJavaString(env
, entry
->GetOriginalRequestURL().spec()));
1236 ScopedJavaLocalRef
<jstring
> j_title(
1237 ConvertUTF16ToJavaString(env
, entry
->GetTitle()));
1238 ScopedJavaLocalRef
<jobject
> j_bitmap
;
1239 const FaviconStatus
& status
= entry
->GetFavicon();
1240 if (status
.valid
&& status
.image
.ToSkBitmap()->getSize() > 0)
1241 j_bitmap
= gfx::ConvertToJavaBitmap(status
.image
.ToSkBitmap());
1243 // Add the item to the list
1244 Java_ContentViewCore_addToNavigationHistory(
1245 env
, obj
, history
, index
, j_url
.obj(), j_virtual_url
.obj(),
1246 j_original_url
.obj(), j_title
.obj(), j_bitmap
.obj());
1251 int ContentViewCoreImpl::GetNavigationHistory(JNIEnv
* env
,
1254 // Iterate through navigation entries to populate the list
1255 const NavigationController
& controller
= web_contents_
->GetController();
1256 int count
= controller
.GetEntryCount();
1257 for (int i
= 0; i
< count
; ++i
) {
1258 AddNavigationEntryToHistory(
1259 env
, obj
, history
, controller
.GetEntryAtIndex(i
), i
);
1262 return controller
.GetCurrentEntryIndex();
1265 void ContentViewCoreImpl::GetDirectedNavigationHistory(JNIEnv
* env
,
1268 jboolean is_forward
,
1270 // Iterate through navigation entries to populate the list
1271 const NavigationController
& controller
= web_contents_
->GetController();
1272 int count
= controller
.GetEntryCount();
1274 int increment_value
= is_forward
? 1 : -1;
1275 for (int i
= controller
.GetCurrentEntryIndex() + increment_value
;
1276 i
>= 0 && i
< count
;
1277 i
+= increment_value
) {
1278 if (num_added
>= max_entries
)
1281 AddNavigationEntryToHistory(
1282 env
, obj
, history
, controller
.GetEntryAtIndex(i
), i
);
1287 ScopedJavaLocalRef
<jstring
>
1288 ContentViewCoreImpl::GetOriginalUrlForActiveNavigationEntry(JNIEnv
* env
,
1290 NavigationEntry
* entry
= web_contents_
->GetController().GetVisibleEntry();
1292 return ScopedJavaLocalRef
<jstring
>(env
, NULL
);
1293 return ConvertUTF8ToJavaString(env
, entry
->GetOriginalRequestURL().spec());
1296 long ContentViewCoreImpl::GetNativeImeAdapter(JNIEnv
* env
, jobject obj
) {
1297 RenderWidgetHostViewAndroid
* rwhva
= GetRenderWidgetHostViewAndroid();
1300 return rwhva
->GetNativeImeAdapter();
1303 // TODO(sgurun) add support for posting a frame whose name is known (only
1304 // main frame is supported at this time, see crbug.com/389721)
1305 // TODO(sgurun) add support for passing message ports
1306 void ContentViewCoreImpl::PostMessageToFrame(JNIEnv
* env
, jobject obj
,
1307 jstring frame_name
, jstring message
, jstring source_origin
,
1308 jstring target_origin
) {
1310 RenderViewHost
* host
= web_contents_
->GetRenderViewHost();
1313 ViewMsg_PostMessage_Params params
;
1314 params
.source_origin
= ConvertJavaStringToUTF16(env
, source_origin
);
1315 params
.target_origin
= ConvertJavaStringToUTF16(env
, target_origin
);
1316 params
.data
= ConvertJavaStringToUTF16(env
, message
);
1317 params
.is_data_raw_string
= true;
1318 params
.source_routing_id
= MSG_ROUTING_NONE
;
1319 host
->Send(new ViewMsg_PostMessageEvent(host
->GetRoutingID(), params
));
1323 bool ContentViewCoreImpl::GetUseDesktopUserAgent(
1324 JNIEnv
* env
, jobject obj
) {
1325 NavigationEntry
* entry
= web_contents_
->GetController().GetVisibleEntry();
1326 return entry
&& entry
->GetIsOverridingUserAgent();
1329 void ContentViewCoreImpl::UpdateImeAdapter(long native_ime_adapter
,
1330 int text_input_type
,
1331 int text_input_flags
,
1332 const std::string
& text
,
1333 int selection_start
,
1335 int composition_start
,
1336 int composition_end
,
1337 bool show_ime_if_needed
,
1338 bool is_non_ime_change
) {
1339 JNIEnv
* env
= AttachCurrentThread();
1340 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1344 ScopedJavaLocalRef
<jstring
> jstring_text
= ConvertUTF8ToJavaString(env
, text
);
1345 Java_ContentViewCore_updateImeAdapter(env
,
1359 void ContentViewCoreImpl::ClearSslPreferences(JNIEnv
* env
, jobject obj
) {
1360 content::SSLHostStateDelegate
* delegate
=
1363 GetBrowserContext()->
1364 GetSSLHostStateDelegate();
1369 void ContentViewCoreImpl::SetUseDesktopUserAgent(
1373 jboolean reload_on_state_change
) {
1374 if (GetUseDesktopUserAgent(env
, obj
) == enabled
)
1377 // Make sure the navigation entry actually exists.
1378 NavigationEntry
* entry
= web_contents_
->GetController().GetVisibleEntry();
1382 // Set the flag in the NavigationEntry.
1383 entry
->SetIsOverridingUserAgent(enabled
);
1385 // Send the override to the renderer.
1386 if (reload_on_state_change
) {
1387 // Reloading the page will send the override down as part of the
1388 // navigation IPC message.
1389 NavigationControllerImpl
& controller
=
1390 static_cast<NavigationControllerImpl
&>(web_contents_
->GetController());
1391 controller
.ReloadOriginalRequestURL(false);
1395 void ContentViewCoreImpl::SetAccessibilityEnabled(JNIEnv
* env
, jobject obj
,
1397 SetAccessibilityEnabledInternal(enabled
);
1400 bool ContentViewCoreImpl::IsFullscreenRequiredForOrientationLock() const {
1401 JNIEnv
* env
= AttachCurrentThread();
1402 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1405 return Java_ContentViewCore_isFullscreenRequiredForOrientationLock(env
,
1409 void ContentViewCoreImpl::SetAccessibilityEnabledInternal(bool enabled
) {
1410 accessibility_enabled_
= enabled
;
1411 BrowserAccessibilityStateImpl
* accessibility_state
=
1412 BrowserAccessibilityStateImpl::GetInstance();
1414 // This enables accessibility globally unless it was explicitly disallowed
1415 // by a command-line flag.
1416 accessibility_state
->OnScreenReaderDetected();
1417 // If it was actually enabled globally, enable it for this RenderWidget now.
1418 if (accessibility_state
->IsAccessibleBrowser() && web_contents_
)
1419 web_contents_
->AddAccessibilityMode(AccessibilityModeComplete
);
1421 accessibility_state
->ResetAccessibilityMode();
1422 if (web_contents_
) {
1423 web_contents_
->SetAccessibilityMode(
1424 accessibility_state
->accessibility_mode());
1429 void ContentViewCoreImpl::SendOrientationChangeEventInternal() {
1430 RenderWidgetHostViewAndroid
* rwhv
= GetRenderWidgetHostViewAndroid();
1432 rwhv
->UpdateScreenInfo(GetViewAndroid());
1434 static_cast<WebContentsImpl
*>(web_contents())->
1435 screen_orientation_dispatcher_host()->OnOrientationChange();
1438 void ContentViewCoreImpl::ExtractSmartClipData(JNIEnv
* env
,
1445 static_cast<int>(x
/ dpi_scale()),
1446 static_cast<int>(y
/ dpi_scale()),
1447 static_cast<int>((width
> 0 && width
< dpi_scale()) ?
1448 1 : (int)(width
/ dpi_scale())),
1449 static_cast<int>((height
> 0 && height
< dpi_scale()) ?
1450 1 : (int)(height
/ dpi_scale())));
1451 GetWebContents()->Send(new ViewMsg_ExtractSmartClipData(
1452 GetWebContents()->GetRoutingID(), rect
));
1455 jint
ContentViewCoreImpl::GetCurrentRenderProcessId(JNIEnv
* env
, jobject obj
) {
1456 return GetRenderProcessIdFromRenderViewHost(
1457 web_contents_
->GetRenderViewHost());
1460 void ContentViewCoreImpl::SetBackgroundOpaque(JNIEnv
* env
, jobject jobj
,
1462 if (GetRenderWidgetHostViewAndroid())
1463 GetRenderWidgetHostViewAndroid()->SetBackgroundOpaque(opaque
);
1466 void ContentViewCoreImpl::RequestTextSurroundingSelection(
1468 const base::Callback
<
1469 void(const base::string16
& content
, int start_offset
, int end_offset
)>&
1471 DCHECK(!callback
.is_null());
1472 RenderFrameHost
* focused_frame
= web_contents_
->GetFocusedFrame();
1475 if (GetRenderWidgetHostViewAndroid()) {
1476 GetRenderWidgetHostViewAndroid()->SetTextSurroundingSelectionCallback(
1478 focused_frame
->Send(new FrameMsg_TextSurroundingSelectionRequest(
1479 focused_frame
->GetRoutingID(), max_length
));
1483 void ContentViewCoreImpl::OnSmartClipDataExtracted(
1484 const base::string16
& text
,
1485 const base::string16
& html
,
1486 const gfx::Rect
& clip_rect
) {
1487 JNIEnv
* env
= AttachCurrentThread();
1488 ScopedJavaLocalRef
<jobject
> obj
= java_ref_
.get(env
);
1491 ScopedJavaLocalRef
<jstring
> jtext
= ConvertUTF16ToJavaString(env
, text
);
1492 ScopedJavaLocalRef
<jstring
> jhtml
= ConvertUTF16ToJavaString(env
, html
);
1493 ScopedJavaLocalRef
<jobject
> clip_rect_object(CreateJavaRect(env
, clip_rect
));
1494 Java_ContentViewCore_onSmartClipDataExtracted(
1495 env
, obj
.obj(), jtext
.obj(), jhtml
.obj(), clip_rect_object
.obj());
1498 void ContentViewCoreImpl::WebContentsDestroyed() {
1499 WebContentsViewAndroid
* wcva
= static_cast<WebContentsViewAndroid
*>(
1500 static_cast<WebContentsImpl
*>(web_contents())->GetView());
1502 wcva
->SetContentViewCore(NULL
);
1505 // This is called for each ContentView.
1506 jlong
Init(JNIEnv
* env
,
1508 jlong native_web_contents
,
1510 jlong window_android
,
1511 jobject retained_objects_set
) {
1512 ContentViewCoreImpl
* view
= new ContentViewCoreImpl(
1514 reinterpret_cast<WebContents
*>(native_web_contents
),
1515 reinterpret_cast<ui::ViewAndroid
*>(view_android
),
1516 reinterpret_cast<ui::WindowAndroid
*>(window_android
),
1517 retained_objects_set
);
1518 return reinterpret_cast<intptr_t>(view
);
1521 bool RegisterContentViewCore(JNIEnv
* env
) {
1522 return RegisterNativesImpl(env
);
1525 } // namespace content