Bug 1564422 - Change `outputLatency` and `getOutputTimestamp` when `resistFingerPrinting` is enabled. r=tjr

When Firefox is configured to resist fingerprinting, the latency figure returned
is the most commonly found on a particular OS.

For Android, I got data from [0], roughly copy/pasted the table into a file and
did:

```
cat file | cut -d $'\t' -f4 | grep "^[[:digit:]]" | cut -d ' ' -f 1 | sort -h
| uniq -c | sort -h
```

which indicated that 40ms was a good number for round trip latency (input to
output). Since this is for output latency only and the audio path
is roughly symmetrical in terms of duration, we report 20ms.

For OSX, 512 is always used with the default hardware in Firefox, with this
patch, it's always 512 regardless of the setup.

On Linux/Pulse, we use 25ms [1] always, and this is adjusted by PulseAudio. This
makes it always return 25ms.

On Windows, there is a wide variety of configurations, but it's common to be in
the ballpark of 80ms output (this is very empirical, by testing a bunch of
hardware over the years).

For other OSes, we use 2048 frames (adjusted to the sample-rate).

[0]: https://superpowered.com/latency
[1]: https://searchfox.org/mozilla-central/source/media/libcubeb/src/cubeb_pulse.c#725

Differential Revision: https://phabricator.services.mozilla.com/D37723

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Paul Adenot 2019-07-12 11:27:25 +00:00
Родитель 553f80fde6
Коммит 6d8671ebb8
1 изменённых файлов: 21 добавлений и 4 удалений

Просмотреть файл

@ -524,7 +524,25 @@ AudioListener* AudioContext::Listener() {
return mListener;
}
double AudioContext::OutputLatency() { return Graph()->AudioOutputLatency(); }
double AudioContext::OutputLatency() {
// When reduceFingerprinting is enabled, return a latency figure that is
// fixed, but plausible for the platform.
double latency_s = 0.0;
if (nsRFPService::IsResistFingerprintingEnabled()) {
#ifdef XP_MACOSX
latency_s = 512. / mSampleRate;
#elif MOZ_WIDGET_ANDROID
latency_s = 0.020;
#elif XP_WIN
latency_s = 0.04;
#else // Catchall for other OSes, including Linux.
latency_s = 0.025;
#endif
} else {
return Graph()->AudioOutputLatency();
}
return latency_s;
}
void AudioContext::GetOutputTimestamp(AudioTimestamp& aTimeStamp) {
if (!Destination()) {
@ -534,13 +552,13 @@ void AudioContext::GetOutputTimestamp(AudioTimestamp& aTimeStamp) {
}
// The currentTime currently being output is the currentTime minus the audio
// output latency.
// output latency. The resolution of CurrentTime() is already reduced.
aTimeStamp.mContextTime.Construct(
std::max(0.0, CurrentTime() - OutputLatency()));
nsPIDOMWindowInner* parent = GetParentObject();
Performance* perf = parent ? parent->GetPerformance() : nullptr;
if (perf) {
// Convert to milliseconds.
// perf->Now() already has reduced resolution here, no need to do it again.
aTimeStamp.mPerformanceTime.Construct(
std::max(0., perf->Now() - (OutputLatency() * 1000.)));
} else {
@ -555,7 +573,6 @@ Worklet* AudioContext::GetAudioWorklet(ErrorResult& aRv) {
return mWorklet;
}
bool AudioContext::IsRunning() const {
return mAudioContextState == AudioContextState::Running;
}