static void DispatchNotification(nsISupports* aSubject, const NotificationAndReportStringId& aNotification, bool aIsSolved, const nsAString& aFormats) { if (!aSubject) { return; } dom::DecoderDoctorNotification data; data.mType = aNotification.mNotificationType; data.mIsSolved = aIsSolved; data.mDecoderDoctorReportId.Assign( NS_ConvertUTF8toUTF16(aNotification.mReportStringId)); 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 DecoderDoctorDiagnostics::StoreMediaKeySystemAccess(nsIDocument* aDocument, const nsAString& aKeySystem, bool aIsSupported, const char* aCallSite) { MOZ_ASSERT(NS_IsMainThread()); // Make sure we only store once. MOZ_ASSERT(mDiagnosticsType == eUnsaved); mDiagnosticsType = eMediaKeySystemAccessRequest; if (NS_WARN_IF(!aDocument)) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreMediaKeySystemAccess(nsIDocument* aDocument=nullptr, keysystem='%s', supported=%d, call site '%s')", this, NS_ConvertUTF16toUTF8(aKeySystem).get(), aIsSupported, aCallSite); return; } if (NS_WARN_IF(aKeySystem.IsEmpty())) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreMediaKeySystemAccess(nsIDocument* aDocument=%p, keysystem=<empty>, supported=%d, call site '%s')", this, aDocument, aIsSupported, aCallSite); return; } RefPtr<DecoderDoctorDocumentWatcher> watcher = DecoderDoctorDocumentWatcher::RetrieveOrCreate(aDocument); if (NS_WARN_IF(!watcher)) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreMediaKeySystemAccess(nsIDocument* aDocument=%p, keysystem='%s', supported=%d, call site '%s') - Could not create document watcher", this, aDocument, NS_ConvertUTF16toUTF8(aKeySystem).get(), aIsSupported, aCallSite); return; } mKeySystem = aKeySystem; mIsKeySystemSupported = aIsSupported; // StoreMediaKeySystemAccess should only be called once, after all data is // available, so it is safe to std::move() from this object. watcher->AddDiagnostics(std::move(*this), aCallSite); // Even though it's moved-from, the type should stay set // (Only used to ensure that we do store only once.) MOZ_ASSERT(mDiagnosticsType == eMediaKeySystemAccessRequest); }
void DecoderDoctorDiagnostics::StoreFormatDiagnostics(nsIDocument* aDocument, const nsAString& aFormat, bool aCanPlay, const char* aCallSite) { MOZ_ASSERT(NS_IsMainThread()); // Make sure we only store once. MOZ_ASSERT(mDiagnosticsType == eUnsaved); mDiagnosticsType = eFormatSupportCheck; if (NS_WARN_IF(!aDocument)) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreFormatDiagnostics(nsIDocument* aDocument=nullptr, format='%s', can-play=%d, call site '%s')", this, NS_ConvertUTF16toUTF8(aFormat).get(), aCanPlay, aCallSite); return; } if (NS_WARN_IF(aFormat.IsEmpty())) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreFormatDiagnostics(nsIDocument* aDocument=%p, format=<empty>, can-play=%d, call site '%s')", this, aDocument, aCanPlay, aCallSite); return; } RefPtr<DecoderDoctorDocumentWatcher> watcher = DecoderDoctorDocumentWatcher::RetrieveOrCreate(aDocument); if (NS_WARN_IF(!watcher)) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreFormatDiagnostics(nsIDocument* aDocument=%p, format='%s', can-play=%d, call site '%s') - Could not create document watcher", this, aDocument, NS_ConvertUTF16toUTF8(aFormat).get(), aCanPlay, aCallSite); return; } mFormat = aFormat; mCanPlay = aCanPlay; // StoreDiagnostics should only be called once, after all data is available, // so it is safe to std::move() from this object. watcher->AddDiagnostics(std::move(*this), aCallSite); // Even though it's moved-from, the type should stay set // (Only used to ensure that we do store only once.) MOZ_ASSERT(mDiagnosticsType == eFormatSupportCheck); }
void DecoderDoctorDiagnostics::StoreDecodeWarning(nsIDocument* aDocument, const MediaResult& aWarning, const nsString& aMediaSrc, const char* aCallSite) { MOZ_ASSERT(NS_IsMainThread()); // Make sure we only store once. MOZ_ASSERT(mDiagnosticsType == eUnsaved); mDiagnosticsType = eDecodeWarning; if (NS_WARN_IF(!aDocument)) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreDecodeWarning(" "nsIDocument* aDocument=nullptr, aWarning=%s," " aMediaSrc=<provided>, call site '%s')", this, aWarning.Description().get(), aCallSite); return; } RefPtr<DecoderDoctorDocumentWatcher> watcher = DecoderDoctorDocumentWatcher::RetrieveOrCreate(aDocument); if (NS_WARN_IF(!watcher)) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreDecodeWarning(" "nsIDocument* aDocument=%p, aWarning='%s', aMediaSrc=<provided>," " call site '%s') - Could not create document watcher", this, aDocument, aWarning.Description().get(), aCallSite); return; } mDecodeIssue = aWarning; mDecodeIssueMediaSrc = aMediaSrc; // StoreDecodeWarning should only be called once, after all data is // available, so it is safe to std::move() from this object. watcher->AddDiagnostics(std::move(*this), aCallSite); // Even though it's moved-from, the type should stay set // (Only used to ensure that we do store only once.) MOZ_ASSERT(mDiagnosticsType == eDecodeWarning); }
void DecoderDoctorDiagnostics::StoreEvent(nsIDocument* aDocument, const DecoderDoctorEvent& aEvent, const char* aCallSite) { MOZ_ASSERT(NS_IsMainThread()); // Make sure we only store once. MOZ_ASSERT(mDiagnosticsType == eUnsaved); mDiagnosticsType = eEvent; mEvent = aEvent; if (NS_WARN_IF(!aDocument)) { DD_WARN("DecoderDoctorDiagnostics[%p]::StoreEvent(nsIDocument* aDocument=nullptr, aEvent=%s, call site '%s')", this, GetDescription().get(), aCallSite); return; } // Don't keep events for later processing, just handle them now. #ifdef MOZ_PULSEAUDIO switch (aEvent.mDomain) { case DecoderDoctorEvent::eAudioSinkStartup: if (aEvent.mResult == NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR) { DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::AddDiagnostics() - unable to initialize PulseAudio", this, aDocument); ReportAnalysis(aDocument, sCannotInitializePulseAudio, false, NS_LITERAL_STRING("*")); } else if (aEvent.mResult == NS_OK) { DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::AddDiagnostics() - now able to initialize PulseAudio", this, aDocument); ReportAnalysis(aDocument, sCannotInitializePulseAudio, true, NS_LITERAL_STRING("*")); } break; } #endif // MOZ_PULSEAUDIO }