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
--- 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);