Bug 1248507 - p7. Notify decoder-doctor-notification listeners - r=jya,bz

If the Decoder Doctor analysis needs to report something, a notification
is sent to listeners of "decoder-doctor-notification", with data identifying
the type of notification along with the media format(s) that could not be
decoded.

In this patch, there are only two notification types: "cannot-play", or
"can-play-but-some-missing-decoders" (if pref "media.decoderdoctor.verbose" is
true).

In a future bug, the Firefox front-end will handle this notification and then
optionally display a user notification.

Note: "can-play-but-some-missing-decoders" should be useful to help implement
the front-end side (as sites like YouTube will probably have some formats we
don't handle); it may be removed later on if it has no further use.

MozReview-Commit-ID: GL3JRqLxzxL
This commit is contained in:
Gerald Squelart 2016-04-19 17:36:19 +10:00
Родитель d04e284211
Коммит 5f8533edb0
1 изменённых файлов: 43 добавлений и 5 удалений

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

@ -6,9 +6,11 @@
#include "DecoderDoctorDiagnostics.h"
#include "mozilla/dom/DecoderDoctorNotificationBinding.h"
#include "mozilla/Logging.h"
#include "nsGkAtoms.h"
#include "nsIDocument.h"
#include "nsIObserverService.h"
#include "nsITimer.h"
#include "nsIWeakReference.h"
@ -63,7 +65,8 @@ private:
static const uint32_t sAnalysisPeriod_ms = 1000;
void EnsureTimerIsStarted();
void ReportAnalysis(const char* aReportStringId,
void ReportAnalysis(dom::DecoderDoctorNotificationType aNotificationType,
const char* aReportStringId,
const nsAString& aFormats);
void SynthesizeAnalysis();
@ -235,9 +238,39 @@ DecoderDoctorDocumentWatcher::EnsureTimerIsStarted()
}
}
static void
DispatchNotification(nsISupports* aSubject,
dom::DecoderDoctorNotificationType aNotificationType,
const nsAString& aFormats)
{
if (!aSubject) {
return;
}
dom::DecoderDoctorNotification data;
data.mType = aNotificationType;
if (!aFormats.IsEmpty()) {
data.mFormats.Construct(aFormats);
}
nsAutoString json;
data.ToJSON(json);
if (json.IsEmpty()) {
DD_WARN("DecoderDoctorDiagnostics/DispatchEvent() - Could not create json for dispatch");
// No point in dispatching this notification without data, the front-end
// wouldn't know what to display.
return;
}
DD_DEBUG("DecoderDoctorDiagnostics/DispatchEvent() %s", NS_ConvertUTF16toUTF8(json).get());
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs) {
obs->NotifyObservers(aSubject, "decoder-doctor-notification", json.get());
}
}
void
DecoderDoctorDocumentWatcher::ReportAnalysis(const char* aReportStringId,
const nsAString& aFormats)
DecoderDoctorDocumentWatcher::ReportAnalysis(
dom::DecoderDoctorNotificationType aNotificationType,
const char* aReportStringId,
const nsAString& aFormats)
{
MOZ_ASSERT(NS_IsMainThread());
@ -256,6 +289,8 @@ DecoderDoctorDocumentWatcher::ReportAnalysis(const char* aReportStringId,
aReportStringId,
params,
ArrayLength(params));
DispatchNotification(mDocument->GetInnerWindow(), aNotificationType, aFormats);
}
void
@ -278,12 +313,15 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
if (!canPlay) {
DD_WARN("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Cannot play media, formats: %s",
this, mDocument, NS_ConvertUTF16toUTF8(formats).get());
ReportAnalysis("MediaCannotPlayNoDecoders", formats);
ReportAnalysis(dom::DecoderDoctorNotificationType::Cannot_play,
"MediaCannotPlayNoDecoders", formats);
} else if (!formats.IsEmpty()) {
DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Can play media, but no decoders for some requested formats: %s",
this, mDocument, NS_ConvertUTF16toUTF8(formats).get());
if (Preferences::GetBool("media.decoderdoctor.verbose", false)) {
ReportAnalysis("MediaNoDecoders", formats);
ReportAnalysis(
dom::DecoderDoctorNotificationType::Can_play_but_some_missing_decoders,
"MediaNoDecoders", formats);
}
} else {
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Can play media, decoders available for all requested formats",