Make timestamps on gestures match incoming events

In the gesture library, we use MSC_TIMESTAMP from the touch controller
to adjust the timestamp from the browser, allowing more accurate
timestamp deltas.  However, some skew can occur between the two clock
sources, causing issues in the browser.

This CL adjusts the timestamps after the gestures are produced to more
closely match the original timestamp for events.

BUG=chromium:983375
TEST=manual testing and check against regression test suite

Change-Id: Iae48d1ce8c9d3b1bfd1e6bad2c808c21689ca6df
Reviewed-on: https://chromium-review.googlesource.com/1718995
Tested-by: Sean O'Brien <seobrien@chromium.org>
Commit-Ready: Sean O'Brien <seobrien@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Sean O'Brien <seobrien@chromium.org>
Reviewed-by: Harry Cutts <hcutts@chromium.org>
diff --git a/include/timestamp_filter_interpreter.h b/include/timestamp_filter_interpreter.h
index f9df057..d0f0111 100644
--- a/include/timestamp_filter_interpreter.h
+++ b/include/timestamp_filter_interpreter.h
@@ -63,6 +63,8 @@
   // hwstate->timestamp.
   void ChangeTimestampUsingFake(HardwareState* hwstate);
 
+  void ConsumeGesture(const Gesture& gs);
+
   stime_t prev_msc_timestamp_;
 
   // Difference between msc_timestamp and timestamp as of last timestamp reset.
@@ -74,6 +76,11 @@
   DoubleProperty fake_timestamp_delta_;
   // Maximum we let fake_timestamp_ diverge from hwstate->timestamp
   stime_t fake_timestamp_max_divergence_;
+
+  // The difference between the original timestamp and the timestamp after
+  // adjustment by this interpreter. When contact begins this will be zero, but
+  // the two clocks may get out of sync by a small amount as time goes on
+  stime_t skew_;
 };
 
 }  // namespace gestures
diff --git a/src/timestamp_filter_interpreter.cc b/src/timestamp_filter_interpreter.cc
index d1159bd..c3286c7 100644
--- a/src/timestamp_filter_interpreter.cc
+++ b/src/timestamp_filter_interpreter.cc
@@ -18,7 +18,8 @@
       msc_timestamp_offset_(-1.0),
       fake_timestamp_(-1.0),
       fake_timestamp_delta_(prop_reg, "Fake Timestamp Delta", 0.0),
-      fake_timestamp_max_divergence_(0.1) {
+      fake_timestamp_max_divergence_(0.1),
+      skew_(0.0) {
   InitName();
 }
 
@@ -40,7 +41,11 @@
     msc_timestamp_offset_ = hwstate->timestamp - hwstate->msc_timestamp;
   }
   prev_msc_timestamp_ = hwstate->msc_timestamp;
-  hwstate->timestamp = hwstate->msc_timestamp + msc_timestamp_offset_;
+
+  stime_t new_timestamp = hwstate->msc_timestamp + msc_timestamp_offset_;
+  skew_ = new_timestamp - hwstate->timestamp;
+  hwstate->timestamp = new_timestamp;
+
   hwstate->msc_timestamp = 0.0;
 }
 
@@ -50,7 +55,17 @@
   if (fabs(fake_timestamp_ - hwstate->timestamp) >
       fake_timestamp_max_divergence_)
     fake_timestamp_ = hwstate->timestamp;
+
+  skew_ = fake_timestamp_ - hwstate->timestamp;
   hwstate->timestamp = fake_timestamp_;
 }
 
+void TimestampFilterInterpreter::ConsumeGesture(const Gesture& gs) {
+  // Adjust gesture timestamp by latest skew to match browser clock
+  Gesture copy = gs;
+  copy.start_time -= skew_;
+  copy.end_time -= skew_;
+  ProduceGesture(copy);
+}
+
 }  // namespace gestures