Commit 33963436 authored by dominikg@chromium.org's avatar dominikg@chromium.org

Synthetic pinch gesture take scale factor as parameter.

Instead of a zoom direction and the number of pixels to be covered by the pinch
gesture, the gesture now takes a scale factor as parameter. From that, it
computes how to perform the gesture: the ratio of the final span and the initial
span equals the scale factor (modulo touch slop). The spans must not fall below
a certain threshold, provided by the gesture target (GetMinScalingSpanInDips).

Update the JS interface (chrome.gpuBenchmarking.pinchBy) to reflect the changes.
For (temporary) backwards compatibility, add another method to the interface to
tell Telemetry whether or not the browser supports the new interface. This is to
avoid crashes when Telemetry is run with the current stable version. Will be
removed once the stable version supports the new interface.

Update tough_pinch_zoom_cases page set to make sure all pinch gestures start
within the web content (tested on N4 and N10).

Update synthetic gesture controller unit tests to use the new parameter.

BUG=309484

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272359 0039d316-1c4b-4281-b951-d872f2087c98
parent f694b67c
...@@ -36,7 +36,8 @@ namespace { ...@@ -36,7 +36,8 @@ namespace {
const int kFlushInputRateInMs = 16; const int kFlushInputRateInMs = 16;
const int kPointerAssumedStoppedTimeMs = 43; const int kPointerAssumedStoppedTimeMs = 43;
const int kTouchSlopInDips = 7; const float kTouchSlopInDips = 7.0f;
const float kMinScalingSpanInDips = 27.5f;
class MockSyntheticGesture : public SyntheticGesture { class MockSyntheticGesture : public SyntheticGesture {
public: public:
...@@ -97,10 +98,14 @@ class MockSyntheticGestureTarget : public SyntheticGestureTarget { ...@@ -97,10 +98,14 @@ class MockSyntheticGestureTarget : public SyntheticGestureTarget {
pointer_assumed_stopped_time_ms_ = time_ms; pointer_assumed_stopped_time_ms_ = time_ms;
} }
virtual int GetTouchSlopInDips() const OVERRIDE { virtual float GetTouchSlopInDips() const OVERRIDE {
return kTouchSlopInDips; return kTouchSlopInDips;
} }
virtual float GetMinScalingSpanInDips() const OVERRIDE {
return kMinScalingSpanInDips;
}
bool flush_requested() const { return flush_requested_; } bool flush_requested() const { return flush_requested_; }
void ClearFlushRequest() { flush_requested_ = false; } void ClearFlushRequest() { flush_requested_ = false; }
...@@ -191,7 +196,7 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget { ...@@ -191,7 +196,7 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget {
}; };
MockSyntheticPinchTouchTarget() MockSyntheticPinchTouchTarget()
: total_num_pixels_covered_(0), : initial_pointer_distance_(0),
last_pointer_distance_(0), last_pointer_distance_(0),
zoom_direction_(ZOOM_DIRECTION_UNKNOWN), zoom_direction_(ZOOM_DIRECTION_UNKNOWN),
started_(false) {} started_(false) {}
...@@ -209,6 +214,8 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget { ...@@ -209,6 +214,8 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget {
start_0_ = gfx::PointF(touch_event.touches[0].position); start_0_ = gfx::PointF(touch_event.touches[0].position);
start_1_ = gfx::PointF(touch_event.touches[1].position); start_1_ = gfx::PointF(touch_event.touches[1].position);
last_pointer_distance_ = (start_0_ - start_1_).Length(); last_pointer_distance_ = (start_0_ - start_1_).Length();
initial_pointer_distance_ = last_pointer_distance_;
EXPECT_GE(initial_pointer_distance_, GetMinScalingSpanInDips());
started_ = true; started_ = true;
} else { } else {
...@@ -218,8 +225,6 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget { ...@@ -218,8 +225,6 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget {
gfx::PointF current_0 = gfx::PointF(touch_event.touches[0].position); gfx::PointF current_0 = gfx::PointF(touch_event.touches[0].position);
gfx::PointF current_1 = gfx::PointF(touch_event.touches[1].position); gfx::PointF current_1 = gfx::PointF(touch_event.touches[1].position);
total_num_pixels_covered_ =
(current_0 - start_0_).Length() + (current_1 - start_1_).Length();
float pointer_distance = (current_0 - current_1).Length(); float pointer_distance = (current_0 - current_1).Length();
if (last_pointer_distance_ != pointer_distance) { if (last_pointer_distance_ != pointer_distance) {
...@@ -236,9 +241,24 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget { ...@@ -236,9 +241,24 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget {
} }
} }
float total_num_pixels_covered() const { return total_num_pixels_covered_; }
ZoomDirection zoom_direction() const { return zoom_direction_; } ZoomDirection zoom_direction() const { return zoom_direction_; }
float ComputeScaleFactor() const {
switch (zoom_direction_) {
case ZOOM_IN:
return last_pointer_distance_ /
(initial_pointer_distance_ + 2 * GetTouchSlopInDips());
case ZOOM_OUT:
return last_pointer_distance_ /
(initial_pointer_distance_ - 2 * GetTouchSlopInDips());
case ZOOM_DIRECTION_UNKNOWN:
return 1.0f;
default:
NOTREACHED();
return 0.0f;
}
}
private: private:
ZoomDirection ComputeZoomDirection(float last_pointer_distance, ZoomDirection ComputeZoomDirection(float last_pointer_distance,
float current_pointer_distance) { float current_pointer_distance) {
...@@ -247,7 +267,7 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget { ...@@ -247,7 +267,7 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget {
: ZOOM_OUT; : ZOOM_OUT;
} }
float total_num_pixels_covered_; float initial_pointer_distance_;
float last_pointer_distance_; float last_pointer_distance_;
ZoomDirection zoom_direction_; ZoomDirection zoom_direction_;
gfx::PointF start_0_; gfx::PointF start_0_;
...@@ -883,8 +903,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) { ...@@ -883,8 +903,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) {
SyntheticPinchGestureParams params; SyntheticPinchGestureParams params;
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
params.zoom_in = true; params.scale_factor = 2.3f;
params.total_num_pixels_covered = 345;
params.anchor.SetPoint(54, 89); params.anchor.SetPoint(54, 89);
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params)); scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
...@@ -897,8 +916,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) { ...@@ -897,8 +916,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) {
EXPECT_EQ(0, num_failure_); EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pinch_target->zoom_direction(), EXPECT_EQ(pinch_target->zoom_direction(),
MockSyntheticPinchTouchTarget::ZOOM_IN); MockSyntheticPinchTouchTarget::ZOOM_IN);
EXPECT_EQ(params.total_num_pixels_covered + 2 * target_->GetTouchSlopInDips(), EXPECT_FLOAT_EQ(params.scale_factor, pinch_target->ComputeScaleFactor());
pinch_target->total_num_pixels_covered());
} }
TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) { TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
...@@ -906,8 +924,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) { ...@@ -906,8 +924,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
SyntheticPinchGestureParams params; SyntheticPinchGestureParams params;
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
params.zoom_in = false; params.scale_factor = 0.4f;
params.total_num_pixels_covered = 456;
params.anchor.SetPoint(-12, 93); params.anchor.SetPoint(-12, 93);
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params)); scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
...@@ -920,17 +937,15 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) { ...@@ -920,17 +937,15 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
EXPECT_EQ(0, num_failure_); EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pinch_target->zoom_direction(), EXPECT_EQ(pinch_target->zoom_direction(),
MockSyntheticPinchTouchTarget::ZOOM_OUT); MockSyntheticPinchTouchTarget::ZOOM_OUT);
EXPECT_EQ(params.total_num_pixels_covered + 2 * target_->GetTouchSlopInDips(), EXPECT_FLOAT_EQ(params.scale_factor, pinch_target->ComputeScaleFactor());
pinch_target->total_num_pixels_covered());
} }
TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZeroPixelsCovered) { TEST_F(SyntheticGestureControllerTest, PinchGestureTouchNoScaling) {
CreateControllerAndTarget<MockSyntheticPinchTouchTarget>(); CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
SyntheticPinchGestureParams params; SyntheticPinchGestureParams params;
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
params.zoom_in = true; params.scale_factor = 1.0f;
params.total_num_pixels_covered = 0;
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params)); scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>()); QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
...@@ -942,7 +957,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZeroPixelsCovered) { ...@@ -942,7 +957,7 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZeroPixelsCovered) {
EXPECT_EQ(0, num_failure_); EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pinch_target->zoom_direction(), EXPECT_EQ(pinch_target->zoom_direction(),
MockSyntheticPinchTouchTarget::ZOOM_DIRECTION_UNKNOWN); MockSyntheticPinchTouchTarget::ZOOM_DIRECTION_UNKNOWN);
EXPECT_EQ(0, pinch_target->total_num_pixels_covered()); EXPECT_EQ(params.scale_factor, pinch_target->ComputeScaleFactor());
} }
TEST_F(SyntheticGestureControllerTest, TapGestureTouch) { TEST_F(SyntheticGestureControllerTest, TapGestureTouch) {
......
...@@ -42,7 +42,11 @@ class CONTENT_EXPORT SyntheticGestureTarget { ...@@ -42,7 +42,11 @@ class CONTENT_EXPORT SyntheticGestureTarget {
// Returns the maximum number of DIPs a touch pointer can move without being // Returns the maximum number of DIPs a touch pointer can move without being
// considered moving by the platform. // considered moving by the platform.
virtual int GetTouchSlopInDips() const = 0; virtual float GetTouchSlopInDips() const = 0;
// Returns the minimum number of DIPs two touch pointers have to be apart
// to perform a pinch-zoom.
virtual float GetMinScalingSpanInDips() const = 0;
}; };
} // namespace content } // namespace content
......
...@@ -92,10 +92,17 @@ SyntheticGestureTargetAndroid::GetDefaultSyntheticGestureSourceType() const { ...@@ -92,10 +92,17 @@ SyntheticGestureTargetAndroid::GetDefaultSyntheticGestureSourceType() const {
return SyntheticGestureParams::TOUCH_INPUT; return SyntheticGestureParams::TOUCH_INPUT;
} }
int SyntheticGestureTargetAndroid::GetTouchSlopInDips() const { float SyntheticGestureTargetAndroid::GetTouchSlopInDips() const {
float device_scale_factor = float device_scale_factor =
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor(); gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor();
return gfx::ViewConfiguration::GetTouchSlopInPixels() / device_scale_factor; return gfx::ViewConfiguration::GetTouchSlopInPixels() / device_scale_factor;
} }
float SyntheticGestureTargetAndroid::GetMinScalingSpanInDips() const {
float device_scale_factor =
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor();
return
gfx::ViewConfiguration::GetMinScalingSpanInPixels() / device_scale_factor;
}
} // namespace content } // namespace content
...@@ -37,7 +37,9 @@ class SyntheticGestureTargetAndroid : public SyntheticGestureTargetBase { ...@@ -37,7 +37,9 @@ class SyntheticGestureTargetAndroid : public SyntheticGestureTargetBase {
virtual SyntheticGestureParams::GestureSourceType virtual SyntheticGestureParams::GestureSourceType
GetDefaultSyntheticGestureSourceType() const OVERRIDE; GetDefaultSyntheticGestureSourceType() const OVERRIDE;
virtual int GetTouchSlopInDips() const OVERRIDE; virtual float GetTouchSlopInDips() const OVERRIDE;
virtual float GetMinScalingSpanInDips() const OVERRIDE;
private: private:
// Enum values below need to be kept in sync with TouchEventSynthesizer.java // Enum values below need to be kept in sync with TouchEventSynthesizer.java
......
...@@ -132,12 +132,16 @@ SyntheticGestureTargetAura::GetDefaultSyntheticGestureSourceType() const { ...@@ -132,12 +132,16 @@ SyntheticGestureTargetAura::GetDefaultSyntheticGestureSourceType() const {
return SyntheticGestureParams::TOUCH_INPUT; return SyntheticGestureParams::TOUCH_INPUT;
} }
int SyntheticGestureTargetAura::GetTouchSlopInDips() const { float SyntheticGestureTargetAura::GetTouchSlopInDips() const {
// - 1 because Aura considers a pointer to be moving if it has moved at least // - 1 because Aura considers a pointer to be moving if it has moved at least
// 'max_touch_move_in_pixels_for_click' pixels. // 'max_touch_move_in_pixels_for_click' pixels.
return ui::GestureConfiguration::max_touch_move_in_pixels_for_click() - 1; return ui::GestureConfiguration::max_touch_move_in_pixels_for_click() - 1;
} }
float SyntheticGestureTargetAura::GetMinScalingSpanInDips() const {
return ui::GestureConfiguration::min_distance_for_pinch_scroll_in_pixels();
}
aura::Window* SyntheticGestureTargetAura::GetWindow() const { aura::Window* SyntheticGestureTargetAura::GetWindow() const {
aura::Window* window = render_widget_host()->GetView()->GetNativeView(); aura::Window* window = render_widget_host()->GetView()->GetNativeView();
DCHECK(window); DCHECK(window);
......
...@@ -40,7 +40,9 @@ class SyntheticGestureTargetAura : public SyntheticGestureTargetBase { ...@@ -40,7 +40,9 @@ class SyntheticGestureTargetAura : public SyntheticGestureTargetBase {
virtual SyntheticGestureParams::GestureSourceType virtual SyntheticGestureParams::GestureSourceType
GetDefaultSyntheticGestureSourceType() const OVERRIDE; GetDefaultSyntheticGestureSourceType() const OVERRIDE;
virtual int GetTouchSlopInDips() const OVERRIDE; virtual float GetTouchSlopInDips() const OVERRIDE;
virtual float GetMinScalingSpanInDips() const OVERRIDE;
private: private:
aura::Window* GetWindow() const; aura::Window* GetWindow() const;
......
...@@ -28,7 +28,7 @@ const int kPointerAssumedStoppedTimeMs = 100; ...@@ -28,7 +28,7 @@ const int kPointerAssumedStoppedTimeMs = 100;
// SyntheticGestureTargetBase passes input events straight on to the renderer // SyntheticGestureTargetBase passes input events straight on to the renderer
// without going through a gesture recognition framework. There is thus no touch // without going through a gesture recognition framework. There is thus no touch
// slop. // slop.
const int kTouchSlopInDips = 0; const float kTouchSlopInDips = 0.0f;
} // namespace } // namespace
...@@ -117,10 +117,17 @@ base::TimeDelta SyntheticGestureTargetBase::PointerAssumedStoppedTime() ...@@ -117,10 +117,17 @@ base::TimeDelta SyntheticGestureTargetBase::PointerAssumedStoppedTime()
return base::TimeDelta::FromMilliseconds(kPointerAssumedStoppedTimeMs); return base::TimeDelta::FromMilliseconds(kPointerAssumedStoppedTimeMs);
} }
int SyntheticGestureTargetBase::GetTouchSlopInDips() const { float SyntheticGestureTargetBase::GetTouchSlopInDips() const {
return kTouchSlopInDips; return kTouchSlopInDips;
} }
float SyntheticGestureTargetBase::GetMinScalingSpanInDips() const {
// The minimum scaling distance is only relevant for touch gestures and the
// base target doesn't support touch.
NOTREACHED();
return 0.0f;
}
bool SyntheticGestureTargetBase::PointIsWithinContents(int x, int y) const { bool SyntheticGestureTargetBase::PointIsWithinContents(int x, int y) const {
gfx::Rect bounds = host_->GetView()->GetViewBounds(); gfx::Rect bounds = host_->GetView()->GetViewBounds();
bounds -= bounds.OffsetFromOrigin(); // Translate the bounds to (0,0). bounds -= bounds.OffsetFromOrigin(); // Translate the bounds to (0,0).
......
...@@ -50,7 +50,9 @@ class SyntheticGestureTargetBase : public SyntheticGestureTarget { ...@@ -50,7 +50,9 @@ class SyntheticGestureTargetBase : public SyntheticGestureTarget {
virtual base::TimeDelta PointerAssumedStoppedTime() const OVERRIDE; virtual base::TimeDelta PointerAssumedStoppedTime() const OVERRIDE;
virtual int GetTouchSlopInDips() const OVERRIDE; virtual float GetTouchSlopInDips() const OVERRIDE;
virtual float GetMinScalingSpanInDips() const OVERRIDE;
protected: protected:
RenderWidgetHostImpl* render_widget_host() const { return host_; } RenderWidgetHostImpl* render_widget_host() const { return host_; }
......
...@@ -16,9 +16,10 @@ SyntheticPinchGesture::SyntheticPinchGesture( ...@@ -16,9 +16,10 @@ SyntheticPinchGesture::SyntheticPinchGesture(
: params_(params), : params_(params),
start_y_0_(0.0f), start_y_0_(0.0f),
start_y_1_(0.0f), start_y_1_(0.0f),
max_pointer_delta_0_(0.0f),
gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT), gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT),
state_(SETUP) { state_(SETUP) {
DCHECK_GE(params_.total_num_pixels_covered, 0); DCHECK_GT(params_.scale_factor, 0.0f);
} }
SyntheticPinchGesture::~SyntheticPinchGesture() {} SyntheticPinchGesture::~SyntheticPinchGesture() {}
...@@ -49,7 +50,7 @@ void SyntheticPinchGesture::ForwardTouchInputEvents( ...@@ -49,7 +50,7 @@ void SyntheticPinchGesture::ForwardTouchInputEvents(
switch (state_) { switch (state_) {
case STARTED: case STARTED:
// Check for an early finish. // Check for an early finish.
if (params_.total_num_pixels_covered == 0) { if (params_.scale_factor == 1.0f) {
state_ = DONE; state_ = DONE;
break; break;
} }
...@@ -87,13 +88,8 @@ void SyntheticPinchGesture::MoveTouchPoints(SyntheticGestureTarget* target, ...@@ -87,13 +88,8 @@ void SyntheticPinchGesture::MoveTouchPoints(SyntheticGestureTarget* target,
float current_y_0 = start_y_0_ + delta; float current_y_0 = start_y_0_ + delta;
float current_y_1 = start_y_1_ - delta; float current_y_1 = start_y_1_ - delta;
// The current pointer positions are stored as float but the pointer touch_event_.MovePoint(0, params_.anchor.x(), current_y_0);
// coordinates of the input event are integers. Floor both positions so that touch_event_.MovePoint(1, params_.anchor.x(), current_y_1);
// in case of an odd distance one of the pointers (the one whose position goes
// down) moves one pixel further than the other. The explicit flooring is only
// needed for negative values.
touch_event_.MovePoint(0, params_.anchor.x(), floor(current_y_0));
touch_event_.MovePoint(1, params_.anchor.x(), floor(current_y_1));
ForwardTouchEvent(target, timestamp); ForwardTouchEvent(target, timestamp);
} }
...@@ -112,24 +108,30 @@ void SyntheticPinchGesture::ForwardTouchEvent( ...@@ -112,24 +108,30 @@ void SyntheticPinchGesture::ForwardTouchEvent(
void SyntheticPinchGesture::SetupCoordinatesAndStopTime( void SyntheticPinchGesture::SetupCoordinatesAndStopTime(
SyntheticGestureTarget* target) { SyntheticGestureTarget* target) {
const int kTouchSlopInDips = target->GetTouchSlopInDips(); // To achieve the specified scaling factor, the ratio of the final to the
params_.total_num_pixels_covered += 2 * kTouchSlopInDips; // initial span (distance between the pointers) has to be equal to the scaling
float inner_distance_to_anchor = 2 * kTouchSlopInDips; // factor. Since we're moving both pointers at the same speed, each pointer's
float outer_distance_to_anchor = // distance to the anchor is half the span.
inner_distance_to_anchor + params_.total_num_pixels_covered / 2.0f; float initial_distance_to_anchor, final_distance_to_anchor;
if (params_.scale_factor > 1.0f) { // zooming in
// Move pointers away from each other to zoom in initial_distance_to_anchor = target->GetMinScalingSpanInDips() / 2.0f;
// or towards each other to zoom out. final_distance_to_anchor =
if (params_.zoom_in) { (initial_distance_to_anchor + target->GetTouchSlopInDips()) *
start_y_0_ = params_.anchor.y() - inner_distance_to_anchor; params_.scale_factor;
start_y_1_ = params_.anchor.y() + inner_distance_to_anchor; } else { // zooming out
} else { final_distance_to_anchor = target->GetMinScalingSpanInDips() / 2.0f;
start_y_0_ = params_.anchor.y() - outer_distance_to_anchor; initial_distance_to_anchor =
start_y_1_ = params_.anchor.y() + outer_distance_to_anchor; (final_distance_to_anchor / params_.scale_factor) +
target->GetTouchSlopInDips();
} }
start_y_0_ = params_.anchor.y() - initial_distance_to_anchor;
start_y_1_ = params_.anchor.y() + initial_distance_to_anchor;
max_pointer_delta_0_ = initial_distance_to_anchor - final_distance_to_anchor;
int64 total_duration_in_us = static_cast<int64>( int64 total_duration_in_us = static_cast<int64>(
1e6 * (static_cast<double>(params_.total_num_pixels_covered) / 1e6 * (static_cast<double>(std::abs(2 * max_pointer_delta_0_)) /
params_.relative_pointer_speed_in_pixels_s)); params_.relative_pointer_speed_in_pixels_s));
DCHECK_GT(total_duration_in_us, 0); DCHECK_GT(total_duration_in_us, 0);
stop_time_ = stop_time_ =
...@@ -138,18 +140,16 @@ void SyntheticPinchGesture::SetupCoordinatesAndStopTime( ...@@ -138,18 +140,16 @@ void SyntheticPinchGesture::SetupCoordinatesAndStopTime(
float SyntheticPinchGesture::GetDeltaForPointer0AtTime( float SyntheticPinchGesture::GetDeltaForPointer0AtTime(
const base::TimeTicks& timestamp) const { const base::TimeTicks& timestamp) const {
float total_abs_delta;
// Make sure the final delta is correct. Using the computation below can lead // Make sure the final delta is correct. Using the computation below can lead
// to issues with floating point precision. // to issues with floating point precision.
if (HasReachedTarget(timestamp)) if (HasReachedTarget(timestamp))
total_abs_delta = params_.total_num_pixels_covered; return max_pointer_delta_0_;
else
total_abs_delta = params_.relative_pointer_speed_in_pixels_s *
(timestamp - start_time_).InSecondsF();
float total_abs_delta = params_.relative_pointer_speed_in_pixels_s *
(timestamp - start_time_).InSecondsF();
float abs_delta_pointer_0 = total_abs_delta / 2.0f; float abs_delta_pointer_0 = total_abs_delta / 2.0f;
return params_.zoom_in ? -abs_delta_pointer_0 : abs_delta_pointer_0; return (params_.scale_factor > 1.0f) ? -abs_delta_pointer_0
: abs_delta_pointer_0;
} }
base::TimeTicks SyntheticPinchGesture::ClampTimestamp( base::TimeTicks SyntheticPinchGesture::ClampTimestamp(
......
...@@ -53,6 +53,7 @@ class CONTENT_EXPORT SyntheticPinchGesture : public SyntheticGesture { ...@@ -53,6 +53,7 @@ class CONTENT_EXPORT SyntheticPinchGesture : public SyntheticGesture {
SyntheticPinchGestureParams params_; SyntheticPinchGestureParams params_;
float start_y_0_; float start_y_0_;
float start_y_1_; float start_y_1_;
float max_pointer_delta_0_;
SyntheticGestureParams::GestureSourceType gesture_source_type_; SyntheticGestureParams::GestureSourceType gesture_source_type_;
GestureState state_; GestureState state_;
SyntheticWebTouchEvent touch_event_; SyntheticWebTouchEvent touch_event_;
......
...@@ -51,8 +51,7 @@ class InputParamTraitsTest : public testing::Test { ...@@ -51,8 +51,7 @@ class InputParamTraitsTest : public testing::Test {
static void Compare(const SyntheticPinchGestureParams* a, static void Compare(const SyntheticPinchGestureParams* a,
const SyntheticPinchGestureParams* b) { const SyntheticPinchGestureParams* b) {
EXPECT_EQ(a->gesture_source_type, b->gesture_source_type); EXPECT_EQ(a->gesture_source_type, b->gesture_source_type);
EXPECT_EQ(a->zoom_in, b->zoom_in); EXPECT_EQ(a->scale_factor, b->scale_factor);
EXPECT_EQ(a->total_num_pixels_covered, b->total_num_pixels_covered);
EXPECT_EQ(a->anchor, b->anchor); EXPECT_EQ(a->anchor, b->anchor);
EXPECT_EQ(a->relative_pointer_speed_in_pixels_s, EXPECT_EQ(a->relative_pointer_speed_in_pixels_s,
b->relative_pointer_speed_in_pixels_s); b->relative_pointer_speed_in_pixels_s);
...@@ -209,8 +208,7 @@ TEST_F(InputParamTraitsTest, SyntheticPinchGestureParams) { ...@@ -209,8 +208,7 @@ TEST_F(InputParamTraitsTest, SyntheticPinchGestureParams) {
scoped_ptr<SyntheticPinchGestureParams> gesture_params( scoped_ptr<SyntheticPinchGestureParams> gesture_params(
new SyntheticPinchGestureParams); new SyntheticPinchGestureParams);
gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
gesture_params->zoom_in = true; gesture_params->scale_factor = 2.3f;
gesture_params->total_num_pixels_covered = 123;
gesture_params->anchor.SetPoint(234, 345); gesture_params->anchor.SetPoint(234, 345);
gesture_params->relative_pointer_speed_in_pixels_s = 456; gesture_params->relative_pointer_speed_in_pixels_s = 456;
ASSERT_EQ(SyntheticGestureParams::PINCH_GESTURE, ASSERT_EQ(SyntheticGestureParams::PINCH_GESTURE,
......
...@@ -9,15 +9,13 @@ ...@@ -9,15 +9,13 @@
namespace content { namespace content {
SyntheticPinchGestureParams::SyntheticPinchGestureParams() SyntheticPinchGestureParams::SyntheticPinchGestureParams()
: zoom_in(true), : scale_factor(1.0f),
total_num_pixels_covered(100),
relative_pointer_speed_in_pixels_s(500) {} relative_pointer_speed_in_pixels_s(500) {}
SyntheticPinchGestureParams::SyntheticPinchGestureParams( SyntheticPinchGestureParams::SyntheticPinchGestureParams(
const SyntheticPinchGestureParams& other) const SyntheticPinchGestureParams& other)
: SyntheticGestureParams(other), : SyntheticGestureParams(other),
zoom_in(other.zoom_in), scale_factor(other.scale_factor),
total_num_pixels_covered(other.total_num_pixels_covered),
anchor(other.anchor), anchor(other.anchor),
relative_pointer_speed_in_pixels_s( relative_pointer_speed_in_pixels_s(
other.relative_pointer_speed_in_pixels_s) {} other.relative_pointer_speed_in_pixels_s) {}
......
...@@ -21,8 +21,7 @@ struct CONTENT_EXPORT SyntheticPinchGestureParams ...@@ -21,8 +21,7 @@ struct CONTENT_EXPORT SyntheticPinchGestureParams
virtual GestureType GetGestureType() const OVERRIDE; virtual GestureType GetGestureType() const OVERRIDE;
bool zoom_in; float scale_factor;
int total_num_pixels_covered;
gfx::Point anchor; gfx::Point anchor;
int relative_pointer_speed_in_pixels_s; int relative_pointer_speed_in_pixels_s;
......
...@@ -84,8 +84,7 @@ IPC_STRUCT_TRAITS_END() ...@@ -84,8 +84,7 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::SyntheticPinchGestureParams) IPC_STRUCT_TRAITS_BEGIN(content::SyntheticPinchGestureParams)
IPC_STRUCT_TRAITS_PARENT(content::SyntheticGestureParams) IPC_STRUCT_TRAITS_PARENT(content::SyntheticGestureParams)
IPC_STRUCT_TRAITS_MEMBER(zoom_in) IPC_STRUCT_TRAITS_MEMBER(scale_factor)
IPC_STRUCT_TRAITS_MEMBER(total_num_pixels_covered)
IPC_STRUCT_TRAITS_MEMBER(anchor) IPC_STRUCT_TRAITS_MEMBER(anchor)
IPC_STRUCT_TRAITS_MEMBER(relative_pointer_speed_in_pixels_s) IPC_STRUCT_TRAITS_MEMBER(relative_pointer_speed_in_pixels_s)
IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_END()
......
...@@ -286,15 +286,17 @@ class GpuBenchmarkingWrapper : public v8::Extension { ...@@ -286,15 +286,17 @@ class GpuBenchmarkingWrapper : public v8::Extension {
" speed_in_pixels_s," " speed_in_pixels_s,"
" opt_start_x, opt_start_y);" " opt_start_x, opt_start_y);"
"};" "};"
// TODO(dominikg): Remove once JS interface changes have rolled into
// stable.
"chrome.gpuBenchmarking.newPinchInterface = true;"
"chrome.gpuBenchmarking.pinchBy = " "chrome.gpuBenchmarking.pinchBy = "
" function(zoom_in, pixels_to_cover, anchor_x, anchor_y," " function(scale_factor, anchor_x, anchor_y,"
" opt_callback, opt_relative_pointer_speed_in_pixels_s) {" " opt_callback, opt_relative_pointer_speed_in_pixels_s) {"
" callback = opt_callback || function() { };" " callback = opt_callback || function() { };"
" relative_pointer_speed_in_pixels_s =" " relative_pointer_speed_in_pixels_s ="
" opt_relative_pointer_speed_in_pixels_s || 800;" " opt_relative_pointer_speed_in_pixels_s || 800;"
" native function BeginPinch();" " native function BeginPinch();"
" return BeginPinch(zoom_in, pixels_to_cover," " return BeginPinch(scale_factor, anchor_x, anchor_y, callback,"
" anchor_x, anchor_y, callback,"
" relative_pointer_speed_in_pixels_s);" " relative_pointer_speed_in_pixels_s);"
"};" "};"
"chrome.gpuBenchmarking.tap = " "chrome.gpuBenchmarking.tap = "
...@@ -640,13 +642,12 @@ class GpuBenchmarkingWrapper : public v8::Extension { ...@@ -640,13 +642,12 @@ class GpuBenchmarkingWrapper : public v8::Extension {
return; return;
int arglen = args.Length(); int arglen = args.Length();
if (arglen < 6 || if (arglen < 5 ||
!args[0]->IsBoolean() || !args[0]->IsNumber() ||
!args[1]->IsNumber() || !args[1]->IsNumber() ||
!args[2]->IsNumber() || !args[2]->IsNumber() ||
!args[3]->IsNumber() || !args[3]->IsFunction() ||
!args[4]->IsFunction() || !args[4]->IsNumber()) {
!args[5]->IsNumber()) {
args.GetReturnValue().Set(false); args.GetReturnValue().Set(false);
return; return;
} }
...@@ -657,17 +658,15 @@ class GpuBenchmarkingWrapper : public v8::Extension { ...@@ -657,17 +658,15 @@ class GpuBenchmarkingWrapper : public v8::Extension {
// Convert coordinates from CSS pixels to density independent pixels (DIPs). // Convert coordinates from CSS pixels to density independent pixels (DIPs).
float page_scale_factor = context.web_view()->pageScaleFactor(); float page_scale_factor = context.web_view()->pageScaleFactor();
gesture_params->zoom_in = args[0]->BooleanValue(); gesture_params->scale_factor = args[0]->NumberValue();
gesture_params->total_num_pixels_covered =
args[1]->IntegerValue() * page_scale_factor;
gesture_params->anchor.SetPoint( gesture_params->anchor.SetPoint(
args[2]->IntegerValue() * page_scale_factor, args[1]->IntegerValue() * page_scale_factor,
args[3]->IntegerValue() * page_scale_factor); args[2]->IntegerValue() * page_scale_factor);
gesture_params->relative_pointer_speed_in_pixels_s = gesture_params->relative_pointer_speed_in_pixels_s =
args[5]->IntegerValue(); args[4]->IntegerValue();
v8::Local<v8::Function> callback_local = v8::Local<v8::Function> callback_local =
v8::Local<v8::Function>::Cast(args[4]); v8::Local<v8::Function>::Cast(args[3]);
scoped_refptr<CallbackAndContext> callback_and_context = scoped_refptr<CallbackAndContext> callback_and_context =
new CallbackAndContext(args.GetIsolate(), new CallbackAndContext(args.GetIsolate(),
......
...@@ -78,7 +78,7 @@ class GoogleCalendarPage(ToughPinchZoomCasesPage): ...@@ -78,7 +78,7 @@ class GoogleCalendarPage(ToughPinchZoomCasesPage):
action_runner.RunAction(PinchAction( action_runner.RunAction(PinchAction(
{ {
'left_anchor_percentage': 0.1, 'left_anchor_percentage': 0.1,
'top_anchor_percentage': 0.1 'top_anchor_percentage': 0.3
})) }))
...@@ -118,7 +118,7 @@ class GooglePlusPage(ToughPinchZoomCasesPage): ...@@ -118,7 +118,7 @@ class GooglePlusPage(ToughPinchZoomCasesPage):
{ {
'element_function': ''' 'element_function': '''
function(callback) { function(callback) {
callback(document.getElementsByClassName("Ct")[0]) callback(document.getElementById("110031535020051778989-tab-bar"))
}''' }'''
})) }))
...@@ -245,6 +245,26 @@ class YahooGamePage(ToughPinchZoomCasesPage): ...@@ -245,6 +245,26 @@ class YahooGamePage(ToughPinchZoomCasesPage):
action_runner.NavigateToPage(self) action_runner.NavigateToPage(self)
action_runner.RunAction(WaitAction({'seconds':2})) action_runner.RunAction(WaitAction({'seconds':2}))
class YahooAnswersPage(ToughPinchZoomCasesPage):
""" Why: #1 Alexa reference """
def __init__(self, page_set):
super(YahooAnswersPage, self).__init__(
url='http://answers.yahoo.com',
page_set=page_set)
def RunSmoothness(self, action_runner):
action_runner.RunAction(PinchAction(
{
'element_function': '''
function(callback) {
callback(document.getElementById("ya-content-apps"))
}'''
}))
class ToughPinchZoomCasesPageSet(page_set_module.PageSet): class ToughPinchZoomCasesPageSet(page_set_module.PageSet):
""" Set of pages that are tricky to pinch-zoom """ """ Set of pages that are tricky to pinch-zoom """
...@@ -288,8 +308,7 @@ class ToughPinchZoomCasesPageSet(page_set_module.PageSet): ...@@ -288,8 +308,7 @@ class ToughPinchZoomCasesPageSet(page_set_module.PageSet):
# Why: #1 Alexa recreation # Why: #1 Alexa recreation
self.AddPage(ToughPinchZoomCasesPage('http://booking.com', self)) self.AddPage(ToughPinchZoomCasesPage('http://booking.com', self))
# Why: #1 Alexa reference self.AddPage(YahooAnswersPage(self))
self.AddPage(ToughPinchZoomCasesPage('http://answers.yahoo.com', self))
# Why: #1 Alexa sports # Why: #1 Alexa sports
self.AddPage(ToughPinchZoomCasesPage('http://sports.yahoo.com/', self)) self.AddPage(ToughPinchZoomCasesPage('http://sports.yahoo.com/', self))
...@@ -15,15 +15,13 @@ ...@@ -15,15 +15,13 @@
this.element_ = opt_options.element; this.element_ = opt_options.element;
this.left_anchor_percentage_ = opt_options.left_anchor_percentage; this.left_anchor_percentage_ = opt_options.left_anchor_percentage;
this.top_anchor_percentage_ = opt_options.top_anchor_percentage; this.top_anchor_percentage_ = opt_options.top_anchor_percentage;
this.zoom_in_ = opt_options.zoom_in; this.scale_factor_ = opt_options.scale_factor;
this.pixels_to_cover_ = opt_options.pixels_to_cover;
this.speed_ = opt_options.speed; this.speed_ = opt_options.speed;
} else { } else {
this.element_ = document.body; this.element_ = document.body;
this.left_anchor_percentage_ = 0.5; this.left_anchor_percentage_ = 0.5;
this.top_anchor_percentage_ = 0.5; this.top_anchor_percentage_ = 0.5;
this.zoom_in_ = true; this.scale_factor_ = 2.0;
this.pixels_to_cover_ = 4000;
this.speed_ = 800; this.speed_ = 800;
} }
} }
...@@ -59,8 +57,7 @@ ...@@ -59,8 +57,7 @@
rect.left + rect.width * this.options_.left_anchor_percentage_; rect.left + rect.width * this.options_.left_anchor_percentage_;
var anchor_top = var anchor_top =
rect.top + rect.height * this.options_.top_anchor_percentage_; rect.top + rect.height * this.options_.top_anchor_percentage_;
chrome.gpuBenchmarking.pinchBy(this.options_.zoom_in_, chrome.gpuBenchmarking.pinchBy(this.options_.scale_factor_,
this.options_.pixels_to_cover_,
anchor_left, anchor_top, anchor_left, anchor_top,
this.onGestureComplete_.bind(this), this.onGestureComplete_.bind(this),
this.options_.speed_); this.options_.speed_);
......
...@@ -21,6 +21,12 @@ class PinchAction(GestureAction): ...@@ -21,6 +21,12 @@ class PinchAction(GestureAction):
raise page_action.PageActionNotSupported( raise page_action.PageActionNotSupported(
'Synthetic pinch not supported for this browser') 'Synthetic pinch not supported for this browser')
# TODO(dominikg): Remove once JS interface changes have rolled into stable.
if not tab.EvaluateJavaScript('chrome.gpuBenchmarking.newPinchInterface'):
raise page_action.PageActionNotSupported(
'This version of the browser doesn\'t support the new JS interface '
'for pinch gestures.')
if (GestureAction.GetGestureSourceTypeFromOptions(tab) == if (GestureAction.GetGestureSourceTypeFromOptions(tab) ==
'chrome.gpuBenchmarking.MOUSE_INPUT'): 'chrome.gpuBenchmarking.MOUSE_INPUT'):
raise page_action.PageActionNotSupported( raise page_action.PageActionNotSupported(
...@@ -36,11 +42,17 @@ class PinchAction(GestureAction): ...@@ -36,11 +42,17 @@ class PinchAction(GestureAction):
window.__pinchAction = new __PinchAction(%s);""" window.__pinchAction = new __PinchAction(%s);"""
% done_callback) % done_callback)
@staticmethod
def _GetDefaultScaleFactorForPage(tab):
current_scale_factor = tab.EvaluateJavaScript(
'window.outerWidth / window.innerWidth')
return 3.0 / current_scale_factor
def RunGesture(self, tab): def RunGesture(self, tab):
left_anchor_percentage = getattr(self, 'left_anchor_percentage', 0.5) left_anchor_percentage = getattr(self, 'left_anchor_percentage', 0.5)
top_anchor_percentage = getattr(self, 'top_anchor_percentage', 0.5) top_anchor_percentage = getattr(self, 'top_anchor_percentage', 0.5)
zoom_in = getattr(self, 'zoom_in', True) scale_factor = getattr(self, 'scale_factor',
pixels_to_cover = getattr(self, 'pixels_to_cover', 500) PinchAction._GetDefaultScaleFactorForPage(tab))
speed = getattr(self, 'speed', 800) speed = getattr(self, 'speed', 800)
if hasattr(self, 'element_function'): if hasattr(self, 'element_function'):
...@@ -49,14 +61,12 @@ class PinchAction(GestureAction): ...@@ -49,14 +61,12 @@ class PinchAction(GestureAction):
{ element: element, { element: element,
left_anchor_percentage: %s, left_anchor_percentage: %s,
top_anchor_percentage: %s, top_anchor_percentage: %s,
zoom_in: %s, scale_factor: %s,
pixels_to_cover: %s,
speed: %s }) speed: %s })
});""" % (self.element_function, });""" % (self.element_function,
left_anchor_percentage, left_anchor_percentage,
top_anchor_percentage, top_anchor_percentage,
'true' if zoom_in else 'false', scale_factor,
pixels_to_cover,
speed)) speed))
else: else:
tab.ExecuteJavaScript(""" tab.ExecuteJavaScript("""
...@@ -64,13 +74,11 @@ class PinchAction(GestureAction): ...@@ -64,13 +74,11 @@ class PinchAction(GestureAction):
{ element: document.body, { element: document.body,
left_anchor_percentage: %s, left_anchor_percentage: %s,
top_anchor_percentage: %s, top_anchor_percentage: %s,
zoom_in: %s, scale_factor: %s,
pixels_to_cover: %s,
speed: %s });""" speed: %s });"""
% (left_anchor_percentage, % (left_anchor_percentage,
top_anchor_percentage, top_anchor_percentage,
'true' if zoom_in else 'false', scale_factor,
pixels_to_cover,
speed)) speed))
tab.WaitForJavaScriptExpression('window.__pinchActionDone', 60) tab.WaitForJavaScriptExpression('window.__pinchActionDone', 60)
......
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