Bug 1929335 - part1 : add new probe to record all types of media element error. r=media-playback-reviewers,aosmond

Differential Revision: https://phabricator.services.mozilla.com/D228733
This commit is contained in:
alwu
2024-11-14 06:18:44 +00:00
parent c611934dda
commit 787c8399d1
3 changed files with 74 additions and 9 deletions

View File

@@ -98,6 +98,7 @@
#include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/glean/GleanMetrics.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "nsAttrValueInlines.h"
#include "nsContentPolicyUtils.h"
@@ -1993,7 +1994,7 @@ class HTMLMediaElement::ErrorSink {
MOZ_ASSERT(mOwner);
}
void SetError(uint16_t aErrorCode, const nsACString& aErrorDetails) {
void SetError(uint16_t aErrorCode, const Maybe<MediaResult>& aResult) {
// Since we have multiple paths calling into DecodeError, e.g.
// MediaKeys::Terminated and EMEH264Decoder::Error. We should take the 1st
// one only in order not to fire multiple 'error' events.
@@ -2006,7 +2007,9 @@ class HTMLMediaElement::ErrorSink {
return;
}
mError = new MediaError(mOwner, aErrorCode, aErrorDetails);
ReportErrorProbe(aErrorCode, aResult);
mError = new MediaError(mOwner, aErrorCode,
aResult ? aResult->Message() : nsCString());
mOwner->DispatchAsyncEvent(u"error"_ns);
if (mOwner->ReadyState() == HAVE_NOTHING &&
aErrorCode == MEDIA_ERR_ABORTED) {
@@ -2036,6 +2039,35 @@ class HTMLMediaElement::ErrorSink {
aErrorCode == MEDIA_ERR_SRC_NOT_SUPPORTED);
}
void ReportErrorProbe(uint16_t aErrorCode,
const Maybe<MediaResult>& aResult) {
MOZ_ASSERT(IsValidErrorCode(aErrorCode));
auto getErrorType = [&]() {
if (aErrorCode == MEDIA_ERR_ABORTED) {
return "AbortError"_ns;
}
if (aErrorCode == MEDIA_ERR_NETWORK) {
return "NetworkError"_ns;
}
if (aErrorCode == MEDIA_ERR_DECODE) {
return "DecodeErr"_ns;
}
return "SrcNotSupportedErr"_ns;
};
glean::media::ErrorExtra extraData;
extraData.errorType = Some(getErrorType());
if (aResult) {
extraData.errorName = Some(aResult->ErrorName());
}
nsAutoString keySystem;
if (mOwner->mMediaKeys) {
mOwner->mMediaKeys->GetKeySystem(keySystem);
extraData.keySystem = Some(NS_ConvertUTF16toUTF8(keySystem));
}
glean::media::error.Record(Some(extraData));
}
// Media elememt's life cycle would be longer than error sink, so we use the
// raw pointer and this class would only be referenced by media element.
HTMLMediaElement* mOwner;
@@ -2518,9 +2550,12 @@ void HTMLMediaElement::NoSupportedMediaSourceError(
// Code. In case we're loading a 3rd party resource we should not leak this
// and pass a Generic Error Message
mErrorSink->SetError(MEDIA_ERR_SRC_NOT_SUPPORTED,
"Failed to open media"_ns);
Some(MediaResult{NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR,
"Failed to open media"_ns}));
} else {
mErrorSink->SetError(MEDIA_ERR_SRC_NOT_SUPPORTED, aErrorDetails);
mErrorSink->SetError(
MEDIA_ERR_SRC_NOT_SUPPORTED,
Some(MediaResult{NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR, aErrorDetails}));
}
RemoveMediaTracks();
@@ -5690,9 +5725,10 @@ void HTMLMediaElement::DecodeError(const MediaResult& aError) {
} else if (mReadyState == HAVE_NOTHING) {
NoSupportedMediaSourceError(aError.Description());
} else if (IsCORSSameOrigin()) {
Error(MEDIA_ERR_DECODE, aError.Description());
Error(MEDIA_ERR_DECODE, Some(aError));
} else {
Error(MEDIA_ERR_DECODE, "Failed to decode media"_ns);
Error(MEDIA_ERR_DECODE, Some(MediaResult{NS_ERROR_DOM_MEDIA_DECODE_ERR,
"Failed to decode media"}));
}
}
@@ -5708,8 +5744,8 @@ bool HTMLMediaElement::HasError() const { return GetError(); }
void HTMLMediaElement::LoadAborted() { Error(MEDIA_ERR_ABORTED); }
void HTMLMediaElement::Error(uint16_t aErrorCode,
const nsACString& aErrorDetails) {
mErrorSink->SetError(aErrorCode, aErrorDetails);
const Maybe<MediaResult>& aResult) {
mErrorSink->SetError(aErrorCode, aResult);
ChangeDelayLoadStatus(false);
UpdateAudioChannelPlayingState();
}