Skip to content

Commit

Permalink
Add GetScrollOffset function to PPB_View
Browse files Browse the repository at this point in the history
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
  • Loading branch information
raymes@chromium.org committed Jun 19, 2014
1 parent ff75703 commit 5015a07
Show file tree
Hide file tree
Showing 15 changed files with 178 additions and 17 deletions.
1 change: 1 addition & 0 deletions chrome/test/ppapi/ppapi_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
5 changes: 5 additions & 0 deletions content/renderer/pepper/pepper_plugin_instance_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
26 changes: 22 additions & 4 deletions ppapi/api/ppb_view.idl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

label Chrome {
M18 = 1.0,
M28 = 1.1
M28 = 1.1,
[channel=dev] M37 = 1.2
};

/**
Expand Down Expand Up @@ -88,7 +89,7 @@ interface PPB_View {
* and IsPageVisible() (whether the page is visible to the user).
*
* @param resource A <code>PP_Resource</code> corresponding to a
* <code>PPB_View</code> resource.
* <code>PPB_View</code> resource.
*
* @return <code>PP_TRUE</code> if the instance might be visible to the
* user, <code>PP_FALSE</code> if it is definitely not visible.
Expand All @@ -108,7 +109,7 @@ interface PPB_View {
* not visible.
*
* @param resource A <code>PP_Resource</code> corresponding to a
* <code>PPB_View</code> resource.
* <code>PPB_View</code> resource.
*
* @return <code>PP_TRUE</code> if the instance is plausibly visible to the
* user, <code>PP_FALSE</code> if it is definitely not visible.
Expand Down Expand Up @@ -151,7 +152,7 @@ interface PPB_View {
* the visual distraction when this happens.
*
* @param resource A <code>PP_Resource</code> corresponding to a
* <code>PPB_View</code> resource.
* <code>PPB_View</code> resource.
*
* @param clip Output argument receiving the clip rect on success.
*
Expand Down Expand Up @@ -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);
};

34 changes: 30 additions & 4 deletions ppapi/c/ppb_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_
Expand All @@ -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

/**
Expand All @@ -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>
Expand Down Expand Up @@ -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);
Expand All @@ -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;
/**
* @}
*/
Expand Down
48 changes: 41 additions & 7 deletions ppapi/cpp/view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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>()) {
Expand All @@ -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>()) {
Expand All @@ -51,15 +61,20 @@ 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()));
return false;
}

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>()) {
Expand All @@ -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);
Expand All @@ -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
7 changes: 7 additions & 0 deletions ppapi/cpp/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions ppapi/proxy/ppapi_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 10 additions & 1 deletion ppapi/shared_impl/ppb_view_shared.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
2 changes: 2 additions & 0 deletions ppapi/shared_impl/ppb_view_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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_;
Expand Down
27 changes: 27 additions & 0 deletions ppapi/tests/test_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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();
}
1 change: 1 addition & 0 deletions ppapi/tests/test_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class TestView : public TestCase {
std::string TestPageHideShow();
std::string TestSizeChange();
std::string TestClipChange();
std::string TestScrollOffsetChange();

pp::View last_view_;

Expand Down
1 change: 1 addition & 0 deletions ppapi/thunk/interfaces_ppb_public_stable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions ppapi/thunk/ppb_view_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 5015a07

Please sign in to comment.