--- a/dom/media/DecoderDoctorDiagnostics.cpp
+++ b/dom/media/DecoderDoctorDiagnostics.cpp
@@ -63,16 +63,17 @@ private:
nsIAtom* aPropertyName,
void* aPropertyValue,
void* aData);
static const uint32_t sAnalysisPeriod_ms = 1000;
void EnsureTimerIsStarted();
void ReportAnalysis(dom::DecoderDoctorNotificationType aNotificationType,
+ bool aIsSolved,
const char* aReportStringId,
const nsAString& aFormats);
void SynthesizeAnalysis();
// Raw pointer to an nsIDocument.
// Must be non-null during construction.
// Nulled when we want to stop watching, because either:
@@ -234,23 +235,28 @@ DecoderDoctorDocumentWatcher::EnsureTime
mTimer = nullptr;
}
}
}
static void
DispatchNotification(nsISupports* aSubject,
dom::DecoderDoctorNotificationType aNotificationType,
+ bool aIsSolved,
+ const char* aReportStringId,
const nsAString& aFormats)
{
if (!aSubject) {
return;
}
dom::DecoderDoctorNotification data;
data.mType = aNotificationType;
+ data.mIsSolved = aIsSolved;
+ data.mDecoderDoctorReportId.Assign(
+ NS_ConvertUTF8toUTF16(aReportStringId));
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
@@ -262,37 +268,41 @@ DispatchNotification(nsISupports* aSubje
if (obs) {
obs->NotifyObservers(aSubject, "decoder-doctor-notification", json.get());
}
}
void
DecoderDoctorDocumentWatcher::ReportAnalysis(
dom::DecoderDoctorNotificationType aNotificationType,
+ bool aIsSolved,
const char* aReportStringId,
const nsAString& aParams)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mDocument) {
return;
}
- // 'params' will only be forwarded for non-empty strings.
- const char16_t* params[1] = { aParams.Data() };
- DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::ReportAnalysis() ReportToConsole - aMsg='%s' params[0]='%s'",
- this, mDocument, aReportStringId,
- aParams.IsEmpty() ? "<no params>" : NS_ConvertUTF16toUTF8(params[0]).get());
- nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- NS_LITERAL_CSTRING("Media"),
- mDocument,
- nsContentUtils::eDOM_PROPERTIES,
- aReportStringId,
- aParams.IsEmpty() ? nullptr : params,
- aParams.IsEmpty() ? 0 : 1);
+ // Report non-solved issues to console.
+ if (!aIsSolved) {
+ // 'params' will only be forwarded for non-empty strings.
+ const char16_t* params[1] = { aParams.Data() };
+ DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::ReportAnalysis() ReportToConsole - aMsg='%s' params[0]='%s'",
+ this, mDocument, aReportStringId,
+ aParams.IsEmpty() ? "<no params>" : NS_ConvertUTF16toUTF8(params[0]).get());
+ nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
+ NS_LITERAL_CSTRING("Media"),
+ mDocument,
+ nsContentUtils::eDOM_PROPERTIES,
+ aReportStringId,
+ aParams.IsEmpty() ? nullptr : params,
+ aParams.IsEmpty() ? 0 : 1);
+ }
// "media.decoder-doctor.notifications-allowed" controls which notifications
// may be dispatched to the front-end. It either contains:
// - '*' -> Allow everything.
// - Comma-separater list of ids -> Allow if aReportStringId (from
// dom.properties) is one of them.
// - Nothing (missing or empty) -> Disable everything.
nsAdoptingCString filter =
@@ -310,17 +320,18 @@ DecoderDoctorDocumentWatcher::ReportAnal
allowed = true;
break;
}
// Skip comma. End of line will be caught in for 'while' clause.
start = end + 1;
}
if (allowed) {
DispatchNotification(
- mDocument->GetInnerWindow(), aNotificationType, aParams);
+ mDocument->GetInnerWindow(),
+ aNotificationType, aIsSolved, aReportStringId, aParams);
}
}
enum SilverlightPresence {
eNoSilverlight,
eSilverlightDisabled,
eSilverlightEnabled
};
@@ -422,18 +433,19 @@ DecoderDoctorDocumentWatcher::Synthesize
// Look at Key System issues first, as they take precedence over format checks.
if (!unsupportedKeySystems.IsEmpty() && supportedKeySystems.IsEmpty()) {
// No supported key systems!
switch (lastKeySystemIssue) {
case DecoderDoctorDiagnostics::eWidevineWithNoWMF:
if (CheckSilverlight() != eSilverlightEnabled) {
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unsupported key systems: %s, widevine without WMF nor Silverlight",
this, mDocument, NS_ConvertUTF16toUTF8(unsupportedKeySystems).get());
- ReportAnalysis(dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
- "MediaWidevineNoWMFNoSilverlight", NS_LITERAL_STRING(""));
+ ReportAnalysis(
+ dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
+ false, "MediaWidevineNoWMFNoSilverlight", unsupportedKeySystems);
return;
}
break;
default:
break;
}
}
@@ -443,42 +455,42 @@ DecoderDoctorDocumentWatcher::Synthesize
if (playableFormats.IsEmpty()) {
// No requested formats can be played. See if we can help the user, by
// going through expected decoders from most to least desirable.
#if defined(XP_WIN)
if (!formatsRequiringWMF.IsEmpty()) {
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because WMF was not found",
this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
ReportAnalysis(dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
- "MediaWMFNeeded", formatsRequiringWMF);
+ false, "MediaWMFNeeded", formatsRequiringWMF);
return;
}
#endif
#if defined(MOZ_FFMPEG)
if (!formatsRequiringFFMpeg.IsEmpty()) {
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because platform decoder was not found",
this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringFFMpeg).get());
ReportAnalysis(dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
"MediaPlatformDecoderNotFound", formatsRequiringFFMpeg);
return;
}
#endif
DD_WARN("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - Cannot play media, unplayable formats: %s",
this, mDocument, NS_ConvertUTF16toUTF8(unplayableFormats).get());
ReportAnalysis(dom::DecoderDoctorNotificationType::Cannot_play,
- "MediaCannotPlayNoDecoders", unplayableFormats);
+ false, "MediaCannotPlayNoDecoders", unplayableFormats);
return;
}
DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - Can play media, but no decoders for some requested formats: %s",
this, mDocument, NS_ConvertUTF16toUTF8(unplayableFormats).get());
if (Preferences::GetBool("media.decoder-doctor.verbose", false)) {
ReportAnalysis(
dom::DecoderDoctorNotificationType::Can_play_but_some_missing_decoders,
- "MediaNoDecoders", unplayableFormats);
+ false, "MediaNoDecoders", unplayableFormats);
}
return;
}
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - Can play media, decoders available for all requested formats",
this, mDocument);
}
void