Bug 1425462 Address another Animation ReducetimePRecision call: Animation::GetCurrentTime draft
authorTom Ritter <tom@mozilla.com>
Sun, 21 Jan 2018 10:37:19 -0600
changeset 724413 7159092cda97399274ed46d1a4bd83e0c333a150
parent 724412 04a96016086fd744fbd71faf802c81cf933bebe3
child 724414 c7b4f997d5a5d6f722420a9bad08378c411c1142
push id96741
push userbmo:tom@mozilla.com
push dateWed, 24 Jan 2018 22:45:52 +0000
bugs1425462, 1430975
milestone59.0a1
Bug 1425462 Address another Animation ReducetimePRecision call: Animation::GetCurrentTime Right now (might change later) I don't think we should fuzz (only round) the reporting of an animaitons current time. The current time may be the animation hold time, which is when the animation was paused. If we jittered that, we would have to jitter it to the exact same value each time, since it'd be constant. The current time may also be the current time of the animation, as you'd expect, in which case it is alculated as the timeline's time minus the animation start time x the playback rate. In general, CSS Animations are... 'interesting' and as Bug 1430975 illustrates, timer rounding/fuzzing may not make sense in a lot of its places. I suspect by the time I complete this, I will have re-validated Bug 1430975. https://drafts.csswg.org/web-animations/#current-time MozReview-Commit-ID: KqrtVWpJ00X
dom/animation/Animation.cpp
dom/animation/AnimationEffectReadOnly.cpp
dom/animation/AnimationTimeline.h
dom/animation/AnimationUtils.h
toolkit/components/resistfingerprinting/nsRFPService.cpp
toolkit/components/resistfingerprinting/nsRFPService.h
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -556,29 +556,29 @@ Animation::Reverse(ErrorResult& aRv)
 //
 // JS wrappers for Animation interface:
 //
 // ---------------------------------------------------------------------------
 
 Nullable<double>
 Animation::GetStartTimeAsDouble() const
 {
-  return AnimationUtils::TimeDurationToDouble(mStartTime, 0);
+  return AnimationUtils::TimeDurationToDouble(mStartTime, 0, true);
 }
 
 void
 Animation::SetStartTimeAsDouble(const Nullable<double>& aStartTime)
 {
   return SetStartTime(AnimationUtils::DoubleToTimeDuration(aStartTime));
 }
 
 Nullable<double>
 Animation::GetCurrentTimeAsDouble() const
 {
-  return AnimationUtils::TimeDurationToDouble(GetCurrentTime(), 0);
+  return AnimationUtils::TimeDurationToDouble(GetCurrentTime(), 0, false);
 }
 
 void
 Animation::SetCurrentTimeAsDouble(const Nullable<double>& aCurrentTime,
                                         ErrorResult& aRv)
 {
   if (aCurrentTime.IsNull()) {
     if (!GetCurrentTime().IsNull()) {
--- a/dom/animation/AnimationEffectReadOnly.cpp
+++ b/dom/animation/AnimationEffectReadOnly.cpp
@@ -288,17 +288,17 @@ GetComputedTimingDictionary(const Comput
   aRetVal.mIterationStart = aComputedTiming.mIterationStart;
   aRetVal.mDuration.SetAsUnrestrictedDouble() =
     aComputedTiming.mDuration.ToMilliseconds();
   aRetVal.mDirection = aTiming.Direction();
 
   // ComputedTimingProperties
   aRetVal.mActiveDuration = aComputedTiming.mActiveDuration.ToMilliseconds();
   aRetVal.mEndTime = aComputedTiming.mEndTime.ToMilliseconds();
-  aRetVal.mLocalTime = AnimationUtils::TimeDurationToDouble(aLocalTime, 0);
+  aRetVal.mLocalTime = AnimationUtils::TimeDurationToDouble(aLocalTime, 0, true);
   aRetVal.mProgress = aComputedTiming.mProgress;
 
   if (!aRetVal.mProgress.IsNull()) {
     // Convert the returned currentIteration into Infinity if we set
     // (uint64_t) aComputedTiming.mCurrentIteration to UINT64_MAX
     double iteration = aComputedTiming.mCurrentIteration == UINT64_MAX
                        ? PositiveInfinity<double>()
                        : static_cast<double>(aComputedTiming.mCurrentIteration);
--- a/dom/animation/AnimationTimeline.h
+++ b/dom/animation/AnimationTimeline.h
@@ -53,17 +53,17 @@ public:
 
   // AnimationTimeline methods
   virtual Nullable<TimeDuration> GetCurrentTime() const = 0;
   virtual double GetCurrentTimeOrigin() const = 0;
 
   // Wrapper functions for AnimationTimeline DOM methods when called from
   // script.
   Nullable<double> GetCurrentTimeAsDouble() const {
-    return AnimationUtils::TimeDurationToDouble(GetCurrentTime(), GetCurrentTimeOrigin());
+    return AnimationUtils::TimeDurationToDouble(GetCurrentTime(), GetCurrentTimeOrigin(), true);
   }
 
   /**
    * Returns true if the times returned by GetCurrentTime() are convertible
    * to and from wallclock-based TimeStamp (e.g. from TimeStamp::Now()) values
    * using ToTimelineTime() and ToTimeStamp().
    *
    * Typically this is true, but it will be false in the case when this
--- a/dom/animation/AnimationUtils.h
+++ b/dom/animation/AnimationUtils.h
@@ -22,23 +22,23 @@ namespace mozilla {
 
 class ComputedTimingFunction;
 class EffectSet;
 
 class AnimationUtils
 {
 public:
   static dom::Nullable<double>
-  TimeDurationToDouble(const dom::Nullable<TimeDuration>& aTime, const double aTimeOrigin)
+  TimeDurationToDouble(const dom::Nullable<TimeDuration>& aTime, const double aTimeOrigin, bool canJitter)
   {
     dom::Nullable<double> result;
 
     if (!aTime.IsNull()) {
       result.SetValue(
-        nsRFPService::ReduceTimePrecisionAsMSecs(aTime.Value().ToMilliseconds(), aTimeOrigin)
+        nsRFPService::ReduceTimePrecisionAsMSecs(aTime.Value().ToMilliseconds(), aTimeOrigin, canJitter)
       );
     }
 
     return result;
   }
 
   static dom::Nullable<TimeDuration>
   DoubleToTimeDuration(const dom::Nullable<double>& aTime)
--- a/toolkit/components/resistfingerprinting/nsRFPService.cpp
+++ b/toolkit/components/resistfingerprinting/nsRFPService.cpp
@@ -163,17 +163,17 @@ nsRFPService::IsTimerPrecisionReductionE
     for (int i = 0; i < frames; ++i) { \
       MOZ_LOG(gResistFingerprintingLog, LogLevel::Debug, ("  %s\n", strs[i])); \
     } \
   } \
   free(strs);
 
 /* static */
 double
-nsRFPService::ReduceTimePrecisionAsMSecs(double aTime, double timeOrigin /* = 0 */)
+nsRFPService::ReduceTimePrecisionAsMSecs(double aTime, double timeOrigin /* = 0 */, bool canJitter /* = true */)
 {
 #if defined(DEBUG)
   INIT_STACKTRACE();
   MOZ_LOG(gResistFingerprintingLog, LogLevel::Debug,
     ("Parent: %d Timestamp: %f Caller: %s", XRE_IsParentProcess(), (aTime + timeOrigin), CALLER()));
   PRINT_STACKTRACE();
 #endif
 
@@ -183,32 +183,32 @@ nsRFPService::ReduceTimePrecisionAsMSecs
   const double resolutionMSec = TimerResolution() / 1000.0;
   double clamped = floor(aTime / resolutionMSec) * resolutionMSec;
 #if defined(DEBUG)
   MOZ_LOG(gResistFingerprintingLog, LogLevel::Verbose,
     ("Given: %.*f, Rounding with %.*f, Intermediate: %.*f, Got: %.*f",
       DBL_DIG-1, aTime, DBL_DIG-1, resolutionMSec, DBL_DIG-1, floor(aTime / resolutionMSec), DBL_DIG-1, clamped));
 #endif
 
-  if (sJitterUSec != 0) {
+  if (canJitter && sJitterUSec != 0) {
     // Generate a random value for jitter
     double r1;
     const double jitterResolutionMSec = sJitterUSec / 1000.0;
     if(NS_FAILED(RandomDouble(&r1))) { return clamped; }
 
     // Add or Subtract up to the jitter value
     clamped += r1 * 2 * jitterResolutionMSec - jitterResolutionMSec;
   }
 
   return clamped;
 }
 
 /* static */
 double
-nsRFPService::ReduceTimePrecisionAsUSecs(double aTime, double timeOrigin /* = 0 */)
+nsRFPService::ReduceTimePrecisionAsUSecs(double aTime, double timeOrigin /* = 0 */, bool canJitter /* = true */)
 {
 #if defined(DEBUG)
   INIT_STACKTRACE();
   MOZ_LOG(gResistFingerprintingLog, LogLevel::Debug,
     ("Parent: %d Timestamp: %f Caller: %s", XRE_IsParentProcess(), (aTime + timeOrigin), CALLER()));
   PRINT_STACKTRACE();
 #endif
 
@@ -219,17 +219,17 @@ nsRFPService::ReduceTimePrecisionAsUSecs
   double clamped = floor(aTime / resolutionUSec) * resolutionUSec;
 #if defined(DEBUG)
   double tmp_sResolutionUSec = resolutionUSec;
   MOZ_LOG(gResistFingerprintingLog, LogLevel::Verbose,
     ("Given: %.*f, Rounding with %.*f, Intermediate: %.*f, Got: %.*f",
       DBL_DIG-1, aTime, DBL_DIG-1, tmp_sResolutionUSec, DBL_DIG-1, floor(aTime / tmp_sResolutionUSec), DBL_DIG-1, clamped));
 #endif
 
-  if (sJitterUSec != 0) {
+  if (canJitter && sJitterUSec != 0) {
     // Generate a random value for jitter
     double r1;
     if(NS_FAILED(RandomDouble(&r1))) { return clamped; }
 
     // Add or Subtract up to the jitter value
     clamped += r1 * 2 * sJitterUSec - sJitterUSec;
   }
 
@@ -240,17 +240,17 @@ nsRFPService::ReduceTimePrecisionAsUSecs
 uint32_t
 nsRFPService::CalculateTargetVideoResolution(uint32_t aVideoQuality)
 {
   return aVideoQuality * NSToIntCeil(aVideoQuality * 16 / 9.0);
 }
 
 /* static */
 double
-nsRFPService::ReduceTimePrecisionAsSecs(double aTime, double timeOrigin /* = 0 */)
+nsRFPService::ReduceTimePrecisionAsSecs(double aTime, double timeOrigin /* = 0 */, bool canJitter /* = true */)
 {
 #if defined(DEBUG)
   INIT_STACKTRACE();
   MOZ_LOG(gResistFingerprintingLog, LogLevel::Debug,
     ("Parent: %d Timestamp: %f Caller: %s", XRE_IsParentProcess(), (aTime + timeOrigin), CALLER()));
   PRINT_STACKTRACE();
 #endif
 
@@ -274,17 +274,17 @@ nsRFPService::ReduceTimePrecisionAsSecs(
     clamped = floor(aTime / resolutionSec) * resolutionSec;
 #if defined(DEBUG)
     MOZ_LOG(gResistFingerprintingLog, LogLevel::Verbose,
       ("Given: %.*f, Rounding with %.*f, Intermediate: %.*f, Got: %.*f",
         DBL_DIG-1, aTime, DBL_DIG-1, resolutionSec, DBL_DIG-1, floor(aTime / resolutionSec), DBL_DIG-1, clamped));
 #endif
   }
 
-  if (sJitterUSec != 0) {
+  if (canJitter && sJitterUSec != 0) {
     // Generate a random value for jitter
     double r1;
     const double jitterResolutionSec = sJitterUSec / 1000000.0;
     if(NS_FAILED(RandomDouble(&r1))) { return clamped; }
     // Add or Subtract up to the jitter value
     clamped += r1 * 2 * jitterResolutionSec - jitterResolutionSec;
   }
 
--- a/toolkit/components/resistfingerprinting/nsRFPService.h
+++ b/toolkit/components/resistfingerprinting/nsRFPService.h
@@ -156,19 +156,19 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   static nsRFPService* GetOrCreate();
   static bool IsResistFingerprintingEnabled();
   static bool IsTimerPrecisionReductionEnabled();
 
   // The following Reduce methods can be called off main thread.
-  static double ReduceTimePrecisionAsMSecs(double aTime, double timeOrigin = 0);
-  static double ReduceTimePrecisionAsUSecs(double aTime, double timeOrigin = 0);
-  static double ReduceTimePrecisionAsSecs(double aTime, double timeOrigin = 0);
+  static double ReduceTimePrecisionAsMSecs(double aTime, double timeOrigin = 0, bool canJitter = true);
+  static double ReduceTimePrecisionAsUSecs(double aTime, double timeOrigin = 0, bool canJitter = true);
+  static double ReduceTimePrecisionAsSecs(double aTime, double timeOrigin = 0, bool canJitter = true);
 
   // This method calculates the video resolution (i.e. height x width) based
   // on the video quality (480p, 720p, etc).
   static uint32_t CalculateTargetVideoResolution(uint32_t aVideoQuality);
 
   // Methods for getting spoofed media statistics and the return value will
   // depend on the video resolution.
   static uint32_t GetSpoofedTotalFrames(double aTime);