Commit 5015a072 authored by raymes@chromium.org's avatar raymes@chromium.org

Add GetScrollOffset function to PPB_View

This adds a function to PPB_View which allows plugins to know the scroll offset
of the page when they are in view. This is useful for OOP PDF which uses the
scroll offset of the window it is contained in to determine the document's
scroll location. A web page can send scroll location via postMessage but
this is slow. Sending the offset directly via view messages is much faster
and seems reasonable.

We don't send the scroll offset in the cases where the plugin is off screen
to avoid any more additional IPC traffic than what currently exists.

BUG=303491

Review URL: https://codereview.chromium.org/329033003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278236 0039d316-1c4b-4281-b951-d872f2087c98
parent ff757030
......@@ -1167,6 +1167,7 @@ IN_PROC_BROWSER_TEST_F(PPAPITest, InputEvent_AcceptTouchEvent) {
RunTestViaHTTP( \
LIST_TEST(View_SizeChange) \
LIST_TEST(View_ClipChange) \
LIST_TEST(View_ScrollOffsetChange) \
)
IN_PROC_BROWSER_TEST_F(PPAPITest, View) {
......
......@@ -1237,6 +1237,11 @@ void PepperPluginInstanceImpl::ViewChanged(
view_data_.css_scale =
container_->pageZoomFactor() * container_->pageScaleFactor();
gfx::Size scroll_offset =
container_->element().document().frame()->scrollOffset();
view_data_.scroll_offset = PP_MakePoint(scroll_offset.width(),
scroll_offset.height());
if (desired_fullscreen_state_ || view_data_.is_fullscreen) {
WebElement element = container_->element();
WebDocument document = element.document();
......
......@@ -12,7 +12,8 @@
label Chrome {
M18 = 1.0,
M28 = 1.1
M28 = 1.1,
[channel=dev] M37 = 1.2
};
/**
......@@ -193,5 +194,22 @@ interface PPB_View {
*/
[version=1.1]
float_t GetCSSScale([in] PP_Resource resource);
/**
* GetScrollOffset returns the scroll offset of the window containing the
* plugin.
*
* @param[in] resource A <code>PP_Resource</code> corresponding to a
* <code>PPB_View</code> resource.
*
* @param[out] offset A <code>PP_Point</code> which will be set to the value
* of the scroll offset in CSS pixels.
*
* @return Returns <code>PP_TRUE</code> if the resource was valid and the
* offset was filled in, <code>PP_FALSE</code> if not.
*/
[version=1.2]
PP_Bool GetScrollOffset([in] PP_Resource resource,
[out] PP_Point offset);
};
......@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
/* From ppb_view.idl modified Fri Mar 29 11:55:32 2013. */
/* From ppb_view.idl modified Tue Jun 17 10:27:32 2014. */
#ifndef PPAPI_C_PPB_VIEW_H_
#define PPAPI_C_PPB_VIEW_H_
......@@ -18,6 +18,7 @@
#define PPB_VIEW_INTERFACE_1_0 "PPB_View;1.0"
#define PPB_VIEW_INTERFACE_1_1 "PPB_View;1.1"
#define PPB_VIEW_INTERFACE_1_2 "PPB_View;1.2" /* dev */
#define PPB_VIEW_INTERFACE PPB_VIEW_INTERFACE_1_1
/**
......@@ -36,7 +37,7 @@
* You will receive new view information using
* <code>PPP_Instance.DidChangeView</code>.
*/
struct PPB_View_1_1 {
struct PPB_View_1_2 { /* dev */
/**
* IsView() determines if the given resource is a valid
* <code>PPB_View</code> resource. Note that <code>PPB_ViewChanged</code>
......@@ -197,10 +198,22 @@ struct PPB_View_1_1 {
* DIPs per CSS pixel. If the resource is invalid, the value will be 0.0.
*/
float (*GetCSSScale)(PP_Resource resource);
/**
* GetScrollOffset returns the scroll offset of the window containing the
* plugin.
*
* @param[in] resource A <code>PP_Resource</code> corresponding to a
* <code>PPB_View</code> resource.
*
* @param[out] offset A <code>PP_Point</code> which will be set to the value
* of the scroll offset in CSS pixels.
*
* @return Returns <code>PP_TRUE</code> if the resource was valid and the
* offset was filled in, <code>PP_FALSE</code> if not.
*/
PP_Bool (*GetScrollOffset)(PP_Resource resource, struct PP_Point* offset);
};
typedef struct PPB_View_1_1 PPB_View;
struct PPB_View_1_0 {
PP_Bool (*IsView)(PP_Resource resource);
PP_Bool (*GetRect)(PP_Resource resource, struct PP_Rect* rect);
......@@ -209,6 +222,19 @@ struct PPB_View_1_0 {
PP_Bool (*IsPageVisible)(PP_Resource resource);
PP_Bool (*GetClipRect)(PP_Resource resource, struct PP_Rect* clip);
};
struct PPB_View_1_1 {
PP_Bool (*IsView)(PP_Resource resource);
PP_Bool (*GetRect)(PP_Resource resource, struct PP_Rect* rect);
PP_Bool (*IsFullscreen)(PP_Resource resource);
PP_Bool (*IsVisible)(PP_Resource resource);
PP_Bool (*IsPageVisible)(PP_Resource resource);
PP_Bool (*GetClipRect)(PP_Resource resource, struct PP_Rect* clip);
float (*GetDeviceScale)(PP_Resource resource);
float (*GetCSSScale)(PP_Resource resource);
};
typedef struct PPB_View_1_1 PPB_View;
/**
* @}
*/
......
......@@ -19,6 +19,10 @@ template <> const char* interface_name<PPB_View_1_1>() {
return PPB_VIEW_INTERFACE_1_1;
}
template <> const char* interface_name<PPB_View_1_2>() {
return PPB_VIEW_INTERFACE_1_2;
}
} // namespace
View::View() : Resource() {
......@@ -29,7 +33,10 @@ View::View(PP_Resource view_resource) : Resource(view_resource) {
Rect View::GetRect() const {
PP_Rect out;
if (has_interface<PPB_View_1_1>()) {
if (has_interface<PPB_View_1_2>()) {
if (PP_ToBool(get_interface<PPB_View_1_2>()->GetRect(pp_resource(), &out)))
return Rect(out);
} else if (has_interface<PPB_View_1_1>()) {
if (PP_ToBool(get_interface<PPB_View_1_1>()->GetRect(pp_resource(), &out)))
return Rect(out);
} else if (has_interface<PPB_View_1_0>()) {
......@@ -40,7 +47,10 @@ Rect View::GetRect() const {
}
bool View::IsFullscreen() const {
if (has_interface<PPB_View_1_1>()) {
if (has_interface<PPB_View_1_2>()) {
return PP_ToBool(get_interface<PPB_View_1_2>()->IsFullscreen(
pp_resource()));
} else if (has_interface<PPB_View_1_1>()) {
return PP_ToBool(get_interface<PPB_View_1_1>()->IsFullscreen(
pp_resource()));
} else if (has_interface<PPB_View_1_0>()) {
......@@ -51,7 +61,9 @@ bool View::IsFullscreen() const {
}
bool View::IsVisible() const {
if (has_interface<PPB_View_1_1>())
if (has_interface<PPB_View_1_2>())
return PP_ToBool(get_interface<PPB_View_1_2>()->IsVisible(pp_resource()));
else if (has_interface<PPB_View_1_1>())
return PP_ToBool(get_interface<PPB_View_1_1>()->IsVisible(pp_resource()));
else if (has_interface<PPB_View_1_0>())
return PP_ToBool(get_interface<PPB_View_1_0>()->IsVisible(pp_resource()));
......@@ -59,7 +71,10 @@ bool View::IsVisible() const {
}
bool View::IsPageVisible() const {
if (has_interface<PPB_View_1_1>()) {
if (has_interface<PPB_View_1_2>()) {
return PP_ToBool(get_interface<PPB_View_1_2>()->IsPageVisible(
pp_resource()));
} else if (has_interface<PPB_View_1_1>()) {
return PP_ToBool(get_interface<PPB_View_1_1>()->IsPageVisible(
pp_resource()));
} else if (has_interface<PPB_View_1_0>()) {
......@@ -71,7 +86,11 @@ bool View::IsPageVisible() const {
Rect View::GetClipRect() const {
PP_Rect out;
if (has_interface<PPB_View_1_1>()) {
if (has_interface<PPB_View_1_2>()) {
if (PP_ToBool(get_interface<PPB_View_1_2>()->GetClipRect(pp_resource(),
&out)))
return Rect(out);
} else if (has_interface<PPB_View_1_1>()) {
if (PP_ToBool(get_interface<PPB_View_1_1>()->GetClipRect(pp_resource(),
&out)))
return Rect(out);
......@@ -84,15 +103,30 @@ Rect View::GetClipRect() const {
}
float View::GetDeviceScale() const {
if (has_interface<PPB_View_1_1>())
if (has_interface<PPB_View_1_2>())
return get_interface<PPB_View_1_2>()->GetDeviceScale(pp_resource());
else if (has_interface<PPB_View_1_1>())
return get_interface<PPB_View_1_1>()->GetDeviceScale(pp_resource());
return 1.0f;
}
float View::GetCSSScale() const {
if (has_interface<PPB_View_1_1>())
if (has_interface<PPB_View_1_2>())
return get_interface<PPB_View_1_2>()->GetCSSScale(pp_resource());
else if (has_interface<PPB_View_1_1>())
return get_interface<PPB_View_1_1>()->GetCSSScale(pp_resource());
return 1.0f;
}
Point View::GetScrollOffset() const {
PP_Point out;
if (has_interface<PPB_View_1_2>()) {
if (PP_ToBool(get_interface<PPB_View_1_2>()->GetScrollOffset(pp_resource(),
&out))) {
return Point(out);
}
}
return Point();
}
} // namespace pp
......@@ -138,6 +138,13 @@ class View : public Resource {
/// @return A <code>float</code> value representing the number of DIPs per CSS
/// pixel.
float GetCSSScale() const;
/// GetScrollOffset returns the scroll offset of the window containing the
/// plugin.
///
/// @return A <code>Point</code> which is set to the value of the scroll
/// offset in CSS pixels.
Point GetScrollOffset() const;
};
} // namespace pp
......
......@@ -1919,6 +1919,8 @@ static int32_t Pnacl_M36_PPB_VideoDecoder_Reset(PP_Resource video_decoder, struc
/* Not generating wrapper methods for PPB_View_1_1 */
/* Not generating wrapper methods for PPB_View_1_2 */
/* Begin wrapper methods for PPB_WebSocket_1_0 */
static PP_Resource Pnacl_M18_PPB_WebSocket_Create(PP_Instance instance) {
......@@ -4800,6 +4802,8 @@ static const struct PPB_VideoDecoder_0_1 Pnacl_Wrappers_PPB_VideoDecoder_0_1 = {
/* Not generating wrapper interface for PPB_View_1_1 */
/* Not generating wrapper interface for PPB_View_1_2 */
static const struct PPB_WebSocket_1_0 Pnacl_Wrappers_PPB_WebSocket_1_0 = {
.Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M18_PPB_WebSocket_Create,
.IsWebSocket = (PP_Bool (*)(PP_Resource resource))&Pnacl_M18_PPB_WebSocket_IsWebSocket,
......
......@@ -312,6 +312,7 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::ViewData)
IPC_STRUCT_TRAITS_MEMBER(clip_rect)
IPC_STRUCT_TRAITS_MEMBER(device_scale)
IPC_STRUCT_TRAITS_MEMBER(css_scale)
IPC_STRUCT_TRAITS_MEMBER(scroll_offset)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(PP_TouchPoint)
......
......@@ -35,7 +35,9 @@ bool ViewData::Equals(const ViewData& other) const {
clip_rect.point.y == other.clip_rect.point.y &&
clip_rect.size.width == other.clip_rect.size.width &&
clip_rect.size.height == other.clip_rect.size.height &&
device_scale == other.device_scale && css_scale == other.css_scale;
device_scale == other.device_scale && css_scale == other.css_scale &&
scroll_offset.x == other.scroll_offset.x &&
scroll_offset.y == other.scroll_offset.y;
}
PPB_View_Shared::PPB_View_Shared(ResourceObjectType type,
......@@ -79,4 +81,11 @@ float PPB_View_Shared::GetDeviceScale() const { return data_.device_scale; }
float PPB_View_Shared::GetCSSScale() const { return data_.css_scale; }
PP_Bool PPB_View_Shared::GetScrollOffset(PP_Point* scroll_offset) const {
if (!scroll_offset)
return PP_FALSE;
*scroll_offset = data_.scroll_offset;
return PP_TRUE;
}
} // namespace ppapi
......@@ -27,6 +27,7 @@ struct PPAPI_SHARED_EXPORT ViewData {
PP_Rect clip_rect;
float device_scale;
float css_scale;
PP_Point scroll_offset;
};
class PPAPI_SHARED_EXPORT PPB_View_Shared : public Resource,
......@@ -49,6 +50,7 @@ class PPAPI_SHARED_EXPORT PPB_View_Shared : public Resource,
virtual PP_Bool GetClipRect(PP_Rect* clip) const OVERRIDE;
virtual float GetDeviceScale() const OVERRIDE;
virtual float GetCSSScale() const OVERRIDE;
virtual PP_Bool GetScrollOffset(PP_Point* scroll_offset) const OVERRIDE;
private:
ViewData data_;
......
......@@ -46,6 +46,7 @@ void TestView::RunTests(const std::string& filter) {
RUN_TEST(PageHideShow, filter);
RUN_TEST(SizeChange, filter);
RUN_TEST(ClipChange, filter);
RUN_TEST(ScrollOffsetChange, filter);
}
bool TestView::WaitUntilViewChanged() {
......@@ -199,3 +200,29 @@ std::string TestView::TestClipChange() {
ASSERT_TRUE(last_view_.GetClipRect() == desired_clip);
PASS();
}
std::string TestView::TestScrollOffsetChange() {
instance_->EvalScript("document.body.style.width = '5000px';"
"document.body.style.height = '5000px';");
instance_->EvalScript("window.scrollTo(5, 1);");
PP_Time begin_time = pp::Module::Get()->core()->GetTime();
while (WaitUntilViewChanged() &&
last_view_.GetScrollOffset() != pp::Point(5, 1) &&
pp::Module::Get()->core()->GetTime() - begin_time <
kViewChangeTimeoutSec) {
}
ASSERT_EQ(pp::Point(5, 1), last_view_.GetScrollOffset());
instance_->EvalScript("window.scrollTo(0, 0);");
begin_time = pp::Module::Get()->core()->GetTime();
while (WaitUntilViewChanged() &&
last_view_.GetScrollOffset() != pp::Point(0, 0) &&
pp::Module::Get()->core()->GetTime() - begin_time <
kViewChangeTimeoutSec) {
}
ASSERT_EQ(pp::Point(0, 0), last_view_.GetScrollOffset());
PASS();
}
......@@ -35,6 +35,7 @@ class TestView : public TestCase {
std::string TestPageHideShow();
std::string TestSizeChange();
std::string TestClipChange();
std::string TestScrollOffsetChange();
pp::View last_view_;
......
......@@ -99,6 +99,7 @@ PROXIED_IFACE(PPB_WEBSOCKET_INTERFACE_1_0, PPB_WebSocket_1_0)
// Note: PPB_Var and PPB_VarArrayBuffer are special and registered manually.
PROXIED_IFACE(PPB_VIEW_INTERFACE_1_0, PPB_View_1_0)
PROXIED_IFACE(PPB_VIEW_INTERFACE_1_1, PPB_View_1_1)
PROXIED_IFACE(PPB_VIEW_INTERFACE_1_2, PPB_View_1_2)
// This has no corresponding _Proxy object since it does no IPC.
PROXIED_IFACE(PPB_AUDIO_CONFIG_INTERFACE_1_0, PPB_AudioConfig_1_0)
......
......@@ -27,6 +27,7 @@ class PPAPI_THUNK_EXPORT PPB_View_API {
virtual PP_Bool GetClipRect(PP_Rect* clip) const = 0;
virtual float GetDeviceScale() const = 0;
virtual float GetCSSScale() const = 0;
virtual PP_Bool GetScrollOffset(PP_Point* offset) const = 0;
};
} // namespace thunk
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// From ppb_view.idl modified Tue Aug 20 08:13:36 2013.
// From ppb_view.idl modified Wed Jun 11 15:42:26 2014.
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_view.h"
......@@ -78,6 +78,14 @@ float GetCSSScale(PP_Resource resource) {
return enter.object()->GetCSSScale();
}
PP_Bool GetScrollOffset(PP_Resource resource, struct PP_Point* offset) {
VLOG(4) << "PPB_View::GetScrollOffset()";
EnterResource<PPB_View_API> enter(resource, true);
if (enter.failed())
return PP_FALSE;
return enter.object()->GetScrollOffset(offset);
}
const PPB_View_1_0 g_ppb_view_thunk_1_0 = {
&IsView,
&GetRect,
......@@ -98,6 +106,18 @@ const PPB_View_1_1 g_ppb_view_thunk_1_1 = {
&GetCSSScale
};
const PPB_View_1_2 g_ppb_view_thunk_1_2 = {
&IsView,
&GetRect,
&IsFullscreen,
&IsVisible,
&IsPageVisible,
&GetClipRect,
&GetDeviceScale,
&GetCSSScale,
&GetScrollOffset
};
} // namespace
PPAPI_THUNK_EXPORT const PPB_View_1_0* GetPPB_View_1_0_Thunk() {
......@@ -108,5 +128,9 @@ PPAPI_THUNK_EXPORT const PPB_View_1_1* GetPPB_View_1_1_Thunk() {
return &g_ppb_view_thunk_1_1;
}
PPAPI_THUNK_EXPORT const PPB_View_1_2* GetPPB_View_1_2_Thunk() {
return &g_ppb_view_thunk_1_2;
}
} // namespace thunk
} // namespace ppapi
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment