зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1691578 - part6 : add test cases to test reporting decode error. r=bryce,webidl,emilio
Differential Revision: https://phabricator.services.mozilla.com/D104570
This commit is contained in:
Родитель
edf054e11a
Коммит
5c51ce0bba
|
@ -9,6 +9,9 @@
|
|||
#endif
|
||||
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "AudioDeviceInfo.h"
|
||||
#include "AudioStreamTrack.h"
|
||||
#include "AutoplayPolicy.h"
|
||||
|
@ -2087,6 +2090,44 @@ void HTMLMediaElement::SetFormatDiagnosticsReportForMimeType(
|
|||
__func__);
|
||||
}
|
||||
|
||||
void HTMLMediaElement::SetDecodeError(const nsAString& aError,
|
||||
ErrorResult& aRv) {
|
||||
// The reason we use this map-ish structure is because we can't use
|
||||
// `CR.NS_ERROR.*` directly in test. In order to use them in test, we have to
|
||||
// add them into `xpc.msg`. As we won't use `CR.NS_ERROR.*` in the production
|
||||
// code, adding them to `xpc.msg` seems an overdesign and adding maintenance
|
||||
// effort (exposing them in CR also needs to add a description, which is
|
||||
// useless because we won't show them to users)
|
||||
static struct {
|
||||
const char* mName;
|
||||
nsresult mResult;
|
||||
} kSupportedErrorList[] = {
|
||||
{"NS_ERROR_DOM_MEDIA_ABORT_ERR", NS_ERROR_DOM_MEDIA_ABORT_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR",
|
||||
NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR",
|
||||
NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_DECODE_ERR", NS_ERROR_DOM_MEDIA_DECODE_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_FATAL_ERR", NS_ERROR_DOM_MEDIA_FATAL_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_METADATA_ERR", NS_ERROR_DOM_MEDIA_METADATA_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_OVERFLOW_ERR", NS_ERROR_DOM_MEDIA_OVERFLOW_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_MEDIASINK_ERR", NS_ERROR_DOM_MEDIA_MEDIASINK_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_DEMUXER_ERR", NS_ERROR_DOM_MEDIA_DEMUXER_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_CDM_ERR", NS_ERROR_DOM_MEDIA_CDM_ERR},
|
||||
{"NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR",
|
||||
NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR}
|
||||
};
|
||||
for (auto& error : kSupportedErrorList) {
|
||||
if (strcmp(error.mName, NS_ConvertUTF16toUTF8(aError).get()) == 0) {
|
||||
DecoderDoctorDiagnostics diagnostics;
|
||||
diagnostics.StoreDecodeError(OwnerDoc(), error.mResult, u""_ns, __func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
already_AddRefed<layers::Image> HTMLMediaElement::GetCurrentImage() {
|
||||
MarkAsTainted();
|
||||
|
||||
|
|
|
@ -658,6 +658,7 @@ class HTMLMediaElement : public nsGenericHTMLElement,
|
|||
// Test methods for decoder doctor.
|
||||
void SetFormatDiagnosticsReportForMimeType(const nsAString& aMimeType,
|
||||
DecoderDoctorReportType aType);
|
||||
void SetDecodeError(const nsAString& aError, ErrorResult& aRv);
|
||||
|
||||
// Synchronously, return the next video frame and mark the element unable to
|
||||
// participate in decode suspending.
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
* Error should be reported after calling `DecoderDoctorDiagnostics::StoreXXX`
|
||||
* methods.
|
||||
* - StoreFormatDiagnostics() [for checking if type is supported]
|
||||
* - StoreDecodeError() [when decode error occurs]
|
||||
*/
|
||||
|
||||
// Only types being listed here would be allowed to display on a
|
||||
// notification banner. Otherwise, the error would only be showed on the
|
||||
// web console.
|
||||
var gAllowedNotificationTypes =
|
||||
"MediaWMFNeeded,MediaFFMpegNotFound,MediaUnsupportedLibavcodec,";
|
||||
"MediaWMFNeeded,MediaFFMpegNotFound,MediaUnsupportedLibavcodec,MediaDecodeError";
|
||||
|
||||
// Used to check if the mime type in the notification is equal to what we set
|
||||
// before. This mime type doesn't reflect the real world siutation, i.e. not
|
||||
|
@ -81,6 +82,54 @@ add_task(async function testNoDecoder() {
|
|||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
const gErrorList = [
|
||||
"NS_ERROR_DOM_MEDIA_ABORT_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_DECODE_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_FATAL_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_METADATA_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_OVERFLOW_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_MEDIASINK_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_DEMUXER_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_CDM_ERR",
|
||||
"NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR",
|
||||
];
|
||||
|
||||
add_task(async function testDecodeError() {
|
||||
const type = "decode-error";
|
||||
const decoderDoctorReportId = "mediadecodeerror";
|
||||
for (let error of gErrorList) {
|
||||
const tab = await createTab("about:blank");
|
||||
info(`first to try if the error is not allowed to be reported`);
|
||||
// No error is allowed to be reported in the notification banner.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["media.decoder-doctor.decode-errors-allowed", ""]],
|
||||
});
|
||||
await setDecodeError(tab, {
|
||||
type,
|
||||
decoderDoctorReportId,
|
||||
error,
|
||||
shouldReportNotification: false,
|
||||
});
|
||||
|
||||
// If the notification type is `MediaDecodeError` and the error type is
|
||||
// listed in the pref, then the error would be reported to the
|
||||
// notification banner.
|
||||
info(`Then to try if the error is allowed to be reported`);
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["media.decoder-doctor.decode-errors-allowed", error]],
|
||||
});
|
||||
await setDecodeError(tab, {
|
||||
type,
|
||||
decoderDoctorReportId,
|
||||
error,
|
||||
shouldReportNotification: true,
|
||||
});
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Following are helper functions
|
||||
*/
|
||||
|
@ -126,6 +175,27 @@ async function createTab(url) {
|
|||
});
|
||||
},
|
||||
};
|
||||
content._waitForReport = (params, shouldReportNotification) => {
|
||||
const reportToConsolePromise = new Promise(r => {
|
||||
content.document.addEventListener(
|
||||
"mozreportmediaerror",
|
||||
_ => {
|
||||
r();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
const reportToNotificationBannerPromise = shouldReportNotification
|
||||
? content._obs.waitFor(params)
|
||||
: Promise.resolve();
|
||||
info(
|
||||
`waitForConsole=true, waitForNotificationBanner=${shouldReportNotification}`
|
||||
);
|
||||
return Promise.all([
|
||||
reportToConsolePromise,
|
||||
reportToNotificationBannerPromise,
|
||||
]);
|
||||
};
|
||||
});
|
||||
return tab;
|
||||
}
|
||||
|
@ -143,26 +213,22 @@ async function setFormatDiagnosticsReportForMimeType(tab, params) {
|
|||
params.formats,
|
||||
params.decoderDoctorReportId
|
||||
);
|
||||
const reportToConsolePromise = new Promise(r => {
|
||||
content.document.addEventListener(
|
||||
"mozreportmediaerror",
|
||||
_ => {
|
||||
r();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
const reportToNotificationBannerPromise = shouldReportNotification
|
||||
? content._obs.waitFor(params)
|
||||
: Promise.resolve();
|
||||
info(
|
||||
`waitForConsole=true, waitForNotificationBanner=${shouldReportNotification}`
|
||||
);
|
||||
await Promise.all([
|
||||
reportToConsolePromise,
|
||||
reportToNotificationBannerPromise,
|
||||
]);
|
||||
await content._waitForReport(params, shouldReportNotification);
|
||||
}
|
||||
);
|
||||
ok(true, `finished check for ${params.decoderDoctorReportId}`);
|
||||
}
|
||||
|
||||
async function setDecodeError(tab, params) {
|
||||
info(`start check for ${params.error}`);
|
||||
await SpecialPowers.spawn(
|
||||
tab.linkedBrowser,
|
||||
[params],
|
||||
async (params, shouldReportNotification) => {
|
||||
const video = content.document.createElement("video");
|
||||
SpecialPowers.wrap(video).setDecodeError(params.error);
|
||||
await content._waitForReport(params, params.shouldReportNotification);
|
||||
}
|
||||
);
|
||||
ok(true, `finished check for ${params.error}`);
|
||||
}
|
||||
|
|
|
@ -240,6 +240,9 @@ partial interface HTMLMediaElement {
|
|||
// These APIs are used for decoder doctor tests.
|
||||
[ChromeOnly]
|
||||
void setFormatDiagnosticsReportForMimeType(DOMString mimeType, DecoderDoctorReportType error);
|
||||
|
||||
[Throws, ChromeOnly]
|
||||
void setDecodeError(DOMString error);
|
||||
};
|
||||
|
||||
/* Audio Output Devices API */
|
||||
|
|
Загрузка…
Ссылка в новой задаче