summaryrefslogtreecommitdiff
path: root/dom
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2023-10-19 18:41:58 +0000
committerMoonchild <moonchild@palemoon.org>2023-10-19 18:41:58 +0000
commit4554cb9929edfe8a62d6352824f27bc9e9a9b89f (patch)
tree7cc254b4eaa5ae95381737a34133579f4e435ce9 /dom
parent8f62ed27ebf098888398de741c012b743e6f0ef1 (diff)
parentf2ec6ef34d9f38faed6b0b2f556390976353fef7 (diff)
downloaduxp-4554cb9929edfe8a62d6352824f27bc9e9a9b89f.tar.gz
Merge pull request 'Clean up the rest of EME' (#2348) from 2346-EME-cleanup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2348
Diffstat (limited to 'dom')
-rw-r--r--dom/base/Navigator.cpp141
-rw-r--r--dom/base/Navigator.h12
-rw-r--r--dom/base/nsDocument.cpp34
-rw-r--r--dom/base/nsDocument.h4
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp7
-rw-r--r--dom/html/HTMLMediaElement.cpp322
-rw-r--r--dom/html/HTMLMediaElement.h37
-rw-r--r--dom/media/AbstractMediaDecoder.h3
-rw-r--r--dom/media/MediaDecoder.cpp24
-rw-r--r--dom/media/MediaDecoder.h19
-rw-r--r--dom/media/MediaDecoderOwner.h8
-rw-r--r--dom/media/MediaDecoderReader.h7
-rw-r--r--dom/media/MediaDecoderReaderWrapper.h4
-rw-r--r--dom/media/MediaDecoderStateMachine.cpp119
-rw-r--r--dom/media/MediaDecoderStateMachine.h9
-rw-r--r--dom/media/MediaFormatReader.cpp70
-rw-r--r--dom/media/MediaFormatReader.h18
-rw-r--r--dom/media/MediaPrefs.h3
-rw-r--r--dom/media/eme/CDMCaps.cpp169
-rw-r--r--dom/media/eme/CDMCaps.h112
-rw-r--r--dom/media/eme/CDMProxy.h278
-rw-r--r--dom/media/eme/DecryptorProxyCallback.h54
-rw-r--r--dom/media/eme/DetailedPromise.cpp57
-rw-r--r--dom/media/eme/DetailedPromise.h57
-rw-r--r--dom/media/eme/EMEUtils.cpp86
-rw-r--r--dom/media/eme/EMEUtils.h104
-rw-r--r--dom/media/eme/MediaEncryptedEvent.cpp128
-rw-r--r--dom/media/eme/MediaEncryptedEvent.h66
-rw-r--r--dom/media/eme/MediaKeyError.cpp38
-rw-r--r--dom/media/eme/MediaKeyError.h37
-rw-r--r--dom/media/eme/MediaKeyMessageEvent.cpp122
-rw-r--r--dom/media/eme/MediaKeyMessageEvent.h66
-rw-r--r--dom/media/eme/MediaKeySession.cpp670
-rw-r--r--dom/media/eme/MediaKeySession.h136
-rw-r--r--dom/media/eme/MediaKeyStatusMap.cpp120
-rw-r--r--dom/media/eme/MediaKeyStatusMap.h96
-rw-r--r--dom/media/eme/MediaKeySystemAccess.cpp1041
-rw-r--r--dom/media/eme/MediaKeySystemAccess.h80
-rw-r--r--dom/media/eme/MediaKeySystemAccessManager.cpp339
-rw-r--r--dom/media/eme/MediaKeySystemAccessManager.h83
-rw-r--r--dom/media/eme/MediaKeys.cpp579
-rw-r--r--dom/media/eme/MediaKeys.h167
-rw-r--r--dom/media/eme/moz.build41
-rw-r--r--dom/media/fmp4/MP4Decoder.cpp3
-rw-r--r--dom/media/gmp/GMPCDMCallbackProxy.cpp250
-rw-r--r--dom/media/gmp/GMPCDMCallbackProxy.h71
-rw-r--r--dom/media/gmp/GMPCDMProxy.cpp798
-rw-r--r--dom/media/gmp/GMPCDMProxy.h265
-rw-r--r--dom/media/gmp/GMPChild.cpp9
-rw-r--r--dom/media/gmp/GMPDecryptorChild.cpp5
-rw-r--r--dom/media/gmp/GMPDecryptorParent.cpp13
-rw-r--r--dom/media/gmp/GMPDecryptorParent.h2
-rw-r--r--dom/media/gmp/GMPDecryptorProxy.h8
-rw-r--r--dom/media/gmp/GMPParent.cpp56
-rw-r--r--dom/media/gmp/PGMPDecryptor.ipdl2
-rw-r--r--dom/media/gmp/moz.build15
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineAdapter.cpp168
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineAdapter.h59
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp554
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineDecryptor.h132
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineFileIO.cpp97
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineFileIO.h46
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineUtils.cpp95
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineUtils.h73
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp400
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h80
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp126
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineVideoFrame.h50
-rw-r--r--dom/media/gmp/widevine-adapter/content_decryption_module.h1278
-rw-r--r--dom/media/gmp/widevine-adapter/content_decryption_module_export.h22
-rw-r--r--dom/media/gmp/widevine-adapter/content_decryption_module_ext.h64
-rw-r--r--dom/media/gmp/widevine-adapter/moz.build24
-rw-r--r--dom/media/gtest/MockMediaDecoderOwner.h4
-rw-r--r--dom/media/mediasource/TrackBuffersManager.cpp36
-rw-r--r--dom/media/moz.build3
-rw-r--r--dom/media/platforms/PDMFactory.cpp22
-rw-r--r--dom/media/platforms/PDMFactory.h14
-rw-r--r--dom/media/platforms/PlatformDecoderModule.h3
-rw-r--r--dom/media/platforms/agnostic/eme/EMEAudioDecoder.cpp43
-rw-r--r--dom/media/platforms/agnostic/eme/EMEAudioDecoder.h36
-rw-r--r--dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp306
-rw-r--r--dom/media/platforms/agnostic/eme/EMEDecoderModule.h51
-rw-r--r--dom/media/platforms/agnostic/eme/EMEVideoDecoder.cpp67
-rw-r--r--dom/media/platforms/agnostic/eme/EMEVideoDecoder.h44
-rw-r--r--dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp85
-rw-r--r--dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h57
-rw-r--r--dom/media/platforms/agnostic/eme/moz.build22
-rw-r--r--dom/media/platforms/moz.build3
-rw-r--r--dom/media/test/mochitest.ini35
-rw-r--r--dom/media/test/test_eme_canvas_blocked.html58
-rw-r--r--dom/media/test/test_eme_detach_media_keys.html63
-rw-r--r--dom/media/test/test_eme_initDataTypes.html133
-rw-r--r--dom/media/test/test_eme_missing_pssh.html92
-rw-r--r--dom/media/test/test_eme_non_mse_fails.html103
-rw-r--r--dom/media/test/test_eme_playback.html188
-rw-r--r--dom/media/test/test_eme_requestKeySystemAccess.html484
-rw-r--r--dom/media/test/test_eme_request_notifications.html88
-rw-r--r--dom/media/test/test_eme_session_callable_value.html35
-rw-r--r--dom/media/test/test_eme_setMediaKeys_before_attach_MediaSource.html41
-rw-r--r--dom/media/test/test_eme_stream_capture_blocked_case1.html52
-rw-r--r--dom/media/test/test_eme_stream_capture_blocked_case2.html55
-rw-r--r--dom/media/test/test_eme_stream_capture_blocked_case3.html54
-rw-r--r--dom/media/test/test_eme_waitingforkey.html117
-rwxr-xr-xdom/media/webaudio/AudioContext.cpp7
-rw-r--r--dom/webidl/HTMLMediaElement.webidl18
-rw-r--r--dom/webidl/MediaEncryptedEvent.webidl23
-rw-r--r--dom/webidl/MediaKeyError.webidl19
-rw-r--r--dom/webidl/MediaKeyMessageEvent.webidl30
-rw-r--r--dom/webidl/MediaKeySession.webidl47
-rw-r--r--dom/webidl/MediaKeyStatusMap.webidl30
-rw-r--r--dom/webidl/MediaKeySystemAccess.webidl41
-rw-r--r--dom/webidl/MediaKeys.webidl30
-rw-r--r--dom/webidl/MediaKeysRequestStatus.webidl23
-rw-r--r--dom/webidl/Navigator.webidl9
-rw-r--r--dom/webidl/WidevineCDMManifest.webidl15
-rw-r--r--dom/webidl/moz.build13
116 files changed, 4 insertions, 13027 deletions
diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
index 0bf9ccbf45..3a10427b0f 100644
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -91,11 +91,6 @@
#endif
#include "mozilla/dom/ContentChild.h"
-#ifdef MOZ_EME
-#include "mozilla/EMEUtils.h"
-#include "mozilla/DetailedPromise.h"
-#endif
-
namespace mozilla {
namespace dom {
@@ -198,9 +193,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerContainer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
-#ifdef MOZ_EME
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeySystemAccessManager)
-#endif
#ifdef MOZ_GAMEPAD
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepadServiceTest)
#endif
@@ -261,13 +253,6 @@ Navigator::Invalidate()
mServiceWorkerContainer = nullptr;
-#ifdef MOZ_EME
- if (mMediaKeySystemAccessManager) {
- mMediaKeySystemAccessManager->Shutdown();
- mMediaKeySystemAccessManager = nullptr;
- }
-#endif
-
#ifdef MOZ_GAMEPAD
if (mGamepadServiceTest) {
mGamepadServiceTest->Shutdown();
@@ -1504,131 +1489,5 @@ Navigator::GetUserAgent(nsPIDOMWindowInner* aWindow, nsIURI* aURI,
return siteSpecificUA->GetUserAgentForURIAndWindow(aURI, aWindow, aUserAgent);
}
-#ifdef MOZ_EME
-static nsCString
-ToCString(const nsString& aString)
-{
- nsCString str("'");
- str.Append(NS_ConvertUTF16toUTF8(aString));
- str.AppendLiteral("'");
- return str;
-}
-
-static nsCString
-ToCString(const MediaKeysRequirement aValue)
-{
- nsCString str("'");
- str.Append(nsDependentCString(MediaKeysRequirementValues::strings[static_cast<uint32_t>(aValue)].value));
- str.AppendLiteral("'");
- return str;
-}
-
-static nsCString
-ToCString(const MediaKeySystemMediaCapability& aValue)
-{
- nsCString str;
- str.AppendLiteral("{contentType=");
- str.Append(ToCString(aValue.mContentType));
- str.AppendLiteral(", robustness=");
- str.Append(ToCString(aValue.mRobustness));
- str.AppendLiteral("}");
- return str;
-}
-
-template<class Type>
-static nsCString
-ToCString(const Sequence<Type>& aSequence)
-{
- nsCString str;
- str.AppendLiteral("[");
- for (size_t i = 0; i < aSequence.Length(); i++) {
- if (i != 0) {
- str.AppendLiteral(",");
- }
- str.Append(ToCString(aSequence[i]));
- }
- str.AppendLiteral("]");
- return str;
-}
-
-template<class Type>
-static nsCString
-ToCString(const Optional<Sequence<Type>>& aOptional)
-{
- nsCString str;
- if (aOptional.WasPassed()) {
- str.Append(ToCString(aOptional.Value()));
- } else {
- str.AppendLiteral("[]");
- }
- return str;
-}
-
-static nsCString
-ToCString(const MediaKeySystemConfiguration& aConfig)
-{
- nsCString str;
- str.AppendLiteral("{label=");
- str.Append(ToCString(aConfig.mLabel));
-
- str.AppendLiteral(", initDataTypes=");
- str.Append(ToCString(aConfig.mInitDataTypes));
-
- str.AppendLiteral(", audioCapabilities=");
- str.Append(ToCString(aConfig.mAudioCapabilities));
-
- str.AppendLiteral(", videoCapabilities=");
- str.Append(ToCString(aConfig.mVideoCapabilities));
-
- str.AppendLiteral(", distinctiveIdentifier=");
- str.Append(ToCString(aConfig.mDistinctiveIdentifier));
-
- str.AppendLiteral(", persistentState=");
- str.Append(ToCString(aConfig.mPersistentState));
-
- str.AppendLiteral(", sessionTypes=");
- str.Append(ToCString(aConfig.mSessionTypes));
-
- str.AppendLiteral("}");
-
- return str;
-}
-
-static nsCString
-RequestKeySystemAccessLogString(const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs)
-{
- nsCString str;
- str.AppendPrintf("Navigator::RequestMediaKeySystemAccess(keySystem='%s' options=",
- NS_ConvertUTF16toUTF8(aKeySystem).get());
- str.Append(ToCString(aConfigs));
- str.AppendLiteral(")");
- return str;
-}
-
-already_AddRefed<Promise>
-Navigator::RequestMediaKeySystemAccess(const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs,
- ErrorResult& aRv)
-{
- EME_LOG("%s", RequestKeySystemAccessLogString(aKeySystem, aConfigs).get());
-
- nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
- RefPtr<DetailedPromise> promise =
- DetailedPromise::Create(go, aRv,
- NS_LITERAL_CSTRING("navigator.requestMediaKeySystemAccess"));
- if (aRv.Failed()) {
- return nullptr;
- }
-
- if (!mMediaKeySystemAccessManager) {
- mMediaKeySystemAccessManager = new MediaKeySystemAccessManager(mWindow);
- }
-
- mMediaKeySystemAccessManager->Request(promise, aKeySystem, aConfigs);
- return promise.forget();
-}
-#endif
-
} // namespace dom
} // namespace mozilla
diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h
index 175940e82d..a61ed10e49 100644
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -18,9 +18,6 @@
#include "nsString.h"
#include "nsTArray.h"
#include "nsWeakPtr.h"
-#ifdef MOZ_EME
-#include "mozilla/dom/MediaKeySystemAccessManager.h"
-#endif
class nsPluginArray;
class nsMimeTypeArray;
@@ -240,15 +237,6 @@ public:
// any, else null.
static already_AddRefed<nsPIDOMWindowInner> GetWindowFromGlobal(JSObject* aGlobal);
-#ifdef MOZ_EME
- already_AddRefed<Promise>
- RequestMediaKeySystemAccess(const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfig,
- ErrorResult& aRv);
-private:
- RefPtr<MediaKeySystemAccessManager> mMediaKeySystemAccessManager;
-#endif
-
private:
virtual ~Navigator();
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 20fbf72983..9b7a8c2721 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -4206,32 +4206,6 @@ nsDocument::SetScopeObject(nsIGlobalObject* aGlobal)
}
}
-#ifdef MOZ_EME
-static void
-CheckIfContainsEMEContent(nsISupports* aSupports, void* aContainsEME)
-{
- nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aSupports));
- if (domMediaElem) {
- nsCOMPtr<nsIContent> content(do_QueryInterface(domMediaElem));
- MOZ_ASSERT(content, "aSupports is not a content");
- HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(content.get());
- bool* contains = static_cast<bool*>(aContainsEME);
- if (mediaElem->GetMediaKeys()) {
- *contains = true;
- }
- }
-}
-
-bool
-nsDocument::ContainsEMEContent()
-{
- bool containsEME = false;
- EnumerateActivityObservers(CheckIfContainsEMEContent,
- static_cast<void*>(&containsEME));
- return containsEME;
-}
-#endif // MOZ_EME
-
static void
CheckIfContainsMSEContent(nsISupports* aSupports, void* aContainsMSE)
{
@@ -8036,14 +8010,6 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
}
#endif // MOZ_WEBRTC
-#ifdef MOZ_EME
- // Don't save presentations for documents containing EME content, so that
- // CDMs reliably shutdown upon user navigation.
- if (ContainsEMEContent()) {
- return false;
- }
-#endif
-
// Don't save presentations for documents containing MSE content, to
// reduce memory usage.
if (ContainsMSEContent()) {
diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h
index 923fb49ae9..767ab845ba 100644
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1104,10 +1104,6 @@ public:
js::ExpandoAndGeneration mExpandoAndGeneration;
-#ifdef MOZ_EME
- bool ContainsEMEContent();
-#endif
-
bool ContainsMSEContent();
protected:
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index 1e7eab82b2..d1a618744b 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -5012,13 +5012,6 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
return;
}
-#ifdef MOZ_EME
- if (video->ContainsRestrictedContent()) {
- aError.Throw(NS_ERROR_NOT_AVAILABLE);
- return;
- }
-#endif
-
uint16_t readyState;
if (NS_SUCCEEDED(video->GetReadyState(&readyState)) &&
readyState < nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA) {
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index 6774504a43..9b3b725c67 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -12,9 +12,6 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/AsyncEventDispatcher.h"
-#ifdef MOZ_EME
-#include "mozilla/dom/MediaEncryptedEvent.h"
-#endif
#include "base/basictypes.h"
#include "nsIDOMHTMLMediaElement.h"
@@ -877,9 +874,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTrackManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioTrackList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVideoTrackList)
-#ifdef MOZ_EME
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeys)
-#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectedVideoStreamTrack)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingPlayPromises)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -905,9 +899,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTextTrackManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioTrackList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVideoTrackList)
-#ifdef MOZ_EME
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaKeys)
-#endif
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectedVideoStreamTrack)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingPlayPromises)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@@ -1160,9 +1151,6 @@ void HTMLMediaElement::AbortExistingLoads()
mDownloadSuspendedByCache = false;
mMediaInfo = MediaInfo();
mIsEncrypted = false;
-#ifdef MOZ_EME
- mPendingEncryptedInitData.mInitDatas.Clear();
-#endif
mWaitingForKey = NOT_WAITING_FOR_KEY;
mSourcePointer = nullptr;
@@ -1851,20 +1839,6 @@ nsresult HTMLMediaElement::LoadResource()
// Set the media element's CORS mode only when loading a resource
mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
-#ifdef MOZ_EME
- bool isBlob = false;
- if (mMediaKeys &&
- Preferences::GetBool("media.eme.mse-only", true) &&
- // We only want mediaSource URLs, but they are BlobURL, so we have to
- // check the schema and abort if they are not MediaStream or real Blob.
- (NS_FAILED(mLoadingSrc->SchemeIs(BLOBURI_SCHEME, &isBlob)) ||
- !isBlob ||
- IsMediaStreamURI(mLoadingSrc) ||
- IsBlobURI(mLoadingSrc))) {
- return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
- }
-#endif
-
HTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
if (other && other->mDecoder) {
// Clone it.
@@ -2780,11 +2754,6 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
if (!window) {
return nullptr;
}
-#ifdef MOZ_EME
- if (ContainsRestrictedContent()) {
- return nullptr;
- }
-#endif
if (!mOutputStreams.IsEmpty() &&
aGraph != mOutputStreams[0].mStream->GetInputStream()->Graph()) {
@@ -3981,25 +3950,6 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
ms.mFinishWhenEnded);
}
-#ifdef MOZ_EME
- if (mMediaKeys) {
- if (mMediaKeys->GetCDMProxy()) {
- mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
- } else {
- // CDM must have crashed.
- ShutdownDecoder();
- return NS_ERROR_FAILURE;
- }
- }
-
- MediaEventSource<void>* waitingForKeyProducer = mDecoder->WaitingForKeyEvent();
- // Not every decoder will produce waitingForKey events, only add ones that can
- if (waitingForKeyProducer) {
- mWaitingForKeyListener = waitingForKeyProducer->Connect(
- AbstractThread::MainThread(), this, &HTMLMediaElement::CannotDecryptWaitingForKey);
- }
-#endif
-
if (mChannelLoader) {
mChannelLoader->Done();
mChannelLoader = nullptr;
@@ -4454,11 +4404,7 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
SetMediaInfo(*aInfo);
- mIsEncrypted = aInfo->IsEncrypted()
-#ifdef MOZ_EME
- || mPendingEncryptedInitData.IsEncrypted()
-#endif
- ;
+ mIsEncrypted = aInfo->IsEncrypted();
mTags = aTags.forget();
mLoadedDataFired = false;
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
@@ -4483,14 +4429,6 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
"Encrypted content not supported outside of MSE"));
return;
}
-
-#ifdef MOZ_EME
- // Dispatch a distinct 'encrypted' event for each initData we have.
- for (const auto& initData : mPendingEncryptedInitData.mInitDatas) {
- DispatchEncrypted(initData.mInitData, initData.mType);
- }
- mPendingEncryptedInitData.mInitDatas.Clear();
-#endif
}
mWatchManager.ManualNotify(&HTMLMediaElement::UpdateReadyStateInternal);
@@ -5424,29 +5362,12 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendE
UpdateSrcMediaStreamPlaying();
UpdateAudioChannelPlayingState();
if (aPauseElement) {
-#ifdef MOZ_EME
- // For EME content, we may force destruction of the CDM client (and CDM
- // instance if this is the last client for that CDM instance) and
- // the CDM's decoder. This ensures the CDM gets reliable and prompt
- // shutdown notifications, as it may have book-keeping it needs
- // to do on shutdown.
- if (mMediaKeys) {
- mMediaKeys->Shutdown();
- mMediaKeys = nullptr;
- if (mDecoder) {
- ShutdownDecoder();
- }
- }
-#endif
if (mDecoder) {
mDecoder->Pause();
mDecoder->Suspend();
}
mEventDeliveryPaused = aSuspendEvents;
} else {
-#ifdef MOZ_EME
- MOZ_ASSERT(!mMediaKeys);
-#endif
if (mDecoder) {
mDecoder->Resume();
if (!mPaused && !mDecoder->IsEnded()) {
@@ -5483,17 +5404,6 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
bool pauseElement = ShouldElementBePaused();
SuspendOrResumeElement(pauseElement, !IsActive());
-#ifdef MOZ_EME
- // If the owning document has become inactive we should shutdown the CDM.
- if (!OwnerDoc()->IsCurrentActiveDocument() && mMediaKeys) {
- mMediaKeys->Shutdown();
- mMediaKeys = nullptr;
- if (mDecoder) {
- ShutdownDecoder();
- }
- }
-#endif
-
AddRemoveSelfReference();
}
@@ -6254,236 +6164,6 @@ HTMLMediaElement::OnVisibilityChange(Visibility aNewVisibility)
}
-#ifdef MOZ_EME
-MediaKeys*
-HTMLMediaElement::GetMediaKeys() const
-{
- return mMediaKeys;
-}
-
-bool
-HTMLMediaElement::ContainsRestrictedContent()
-{
- return GetMediaKeys() != nullptr;
-}
-
-already_AddRefed<Promise>
-HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
- ErrorResult& aRv)
-{
- LOG(LogLevel::Debug, ("%p SetMediaKeys(%p) mMediaKeys=%p mDecoder=%p",
- this, aMediaKeys, mMediaKeys.get(), mDecoder.get()));
-
- if (MozAudioCaptured()) {
- aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return nullptr;
- }
-
- nsCOMPtr<nsIGlobalObject> global =
- do_QueryInterface(OwnerDoc()->GetInnerWindow());
- if (!global) {
- aRv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
- RefPtr<DetailedPromise> promise = DetailedPromise::Create(global, aRv,
- NS_LITERAL_CSTRING("HTMLMediaElement.setMediaKeys"));
- if (aRv.Failed()) {
- return nullptr;
- }
-
- // 1. If mediaKeys and the mediaKeys attribute are the same object,
- // return a resolved promise.
- if (mMediaKeys == aMediaKeys) {
- promise->MaybeResolveWithUndefined();
- return promise.forget();
- }
-
- // Note: Our attaching code is synchronous, so we can skip the following steps.
-
- // 2. If this object's attaching media keys value is true, return a
- // promise rejected with a new DOMException whose name is InvalidStateError.
- // 3. Let this object's attaching media keys value be true.
- // 4. Let promise be a new promise.
- // 5. Run the following steps in parallel:
-
- // 5.1 If mediaKeys is not null, CDM instance represented by mediaKeys is
- // already in use by another media element, and the user agent is unable
- // to use it with this element, let this object's attaching media keys
- // value be false and reject promise with a new DOMException whose name
- // is QuotaExceededError.
- if (aMediaKeys && aMediaKeys->IsBoundToMediaElement()) {
- promise->MaybeReject(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR,
- NS_LITERAL_CSTRING("MediaKeys object is already bound to another HTMLMediaElement"));
- return promise.forget();
- }
-
- // 5.2 If the mediaKeys attribute is not null, run the following steps:
- if (mMediaKeys) {
- // 5.2.1 If the user agent or CDM do not support removing the association,
- // let this object's attaching media keys value be false and reject promise
- // with a new DOMException whose name is NotSupportedError.
-
- // 5.2.2 If the association cannot currently be removed, let this object's
- // attaching media keys value be false and reject promise with a new
- // DOMException whose name is InvalidStateError.
- if (mDecoder) {
- // We don't support swapping out the MediaKeys once we've started to
- // setup the playback pipeline. Note this also means we don't need to worry
- // about handling disassociating the MediaKeys from the MediaDecoder.
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Can't change MediaKeys on HTMLMediaElement after load has started"));
- return promise.forget();
- }
-
- // 5.2.3 Stop using the CDM instance represented by the mediaKeys attribute
- // to decrypt media data and remove the association with the media element.
- mMediaKeys->Unbind();
- mMediaKeys = nullptr;
-
- // 5.2.4 If the preceding step failed, let this object's attaching media
- // keys value be false and reject promise with a new DOMException whose
- // name is the appropriate error name.
- }
-
- // 5.3. If mediaKeys is not null, run the following steps:
- if (aMediaKeys) {
- if (!aMediaKeys->GetCDMProxy()) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("CDM crashed before binding MediaKeys object to HTMLMediaElement"));
- return promise.forget();
- }
-
- // 5.3.1 Associate the CDM instance represented by mediaKeys with the
- // media element for decrypting media data.
- if (NS_FAILED(aMediaKeys->Bind(this))) {
- // 5.3.2 If the preceding step failed, run the following steps:
- // 5.3.2.1 Set the mediaKeys attribute to null.
- mMediaKeys = nullptr;
- // 5.3.2.2 Let this object's attaching media keys value be false.
- // 5.3.2.3 Reject promise with a new DOMException whose name is
- // the appropriate error name.
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Failed to bind MediaKeys object to HTMLMediaElement"));
- return promise.forget();
- }
- // 5.3.3 Queue a task to run the "Attempt to Resume Playback If Necessary"
- // algorithm on the media element.
- // Note: Setting the CDMProxy on the MediaDecoder will unblock playback.
- if (mDecoder) {
- mDecoder->SetCDMProxy(aMediaKeys->GetCDMProxy());
- }
- }
-
- // 5.4 Set the mediaKeys attribute to mediaKeys.
- mMediaKeys = aMediaKeys;
-
- // 5.5 Let this object's attaching media keys value be false.
-
- // 5.6 Resolve promise.
- promise->MaybeResolveWithUndefined();
-
- // 6. Return promise.
- return promise.forget();
-}
-
-EventHandlerNonNull*
-HTMLMediaElement::GetOnencrypted()
-{
- return EventTarget::GetEventHandler(nsGkAtoms::onencrypted, EmptyString());
-}
-
-void
-HTMLMediaElement::SetOnencrypted(EventHandlerNonNull* aCallback)
-{
- EventTarget::SetEventHandler(nsGkAtoms::onencrypted, EmptyString(), aCallback);
-}
-
-EventHandlerNonNull*
-HTMLMediaElement::GetOnwaitingforkey()
-{
- return EventTarget::GetEventHandler(nsGkAtoms::onwaitingforkey, EmptyString());
-}
-
-void
-HTMLMediaElement::SetOnwaitingforkey(EventHandlerNonNull* aCallback)
-{
- EventTarget::SetEventHandler(nsGkAtoms::onwaitingforkey, EmptyString(), aCallback);
-}
-
-void
-HTMLMediaElement::DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
- const nsAString& aInitDataType)
-{
- LOG(LogLevel::Debug,
- ("%p DispatchEncrypted initDataType='%s'",
- this, NS_ConvertUTF16toUTF8(aInitDataType).get()));
-
- if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
- // Ready state not HAVE_METADATA (yet), don't dispatch encrypted now.
- // Queueing for later dispatch in MetadataLoaded.
- mPendingEncryptedInitData.AddInitData(aInitDataType, aInitData);
- return;
- }
-
- RefPtr<MediaEncryptedEvent> event;
- if (IsCORSSameOrigin()) {
- event = MediaEncryptedEvent::Constructor(this, aInitDataType, aInitData);
- } else {
- event = MediaEncryptedEvent::Constructor(this);
- }
-
- RefPtr<AsyncEventDispatcher> asyncDispatcher =
- new AsyncEventDispatcher(this, event);
- asyncDispatcher->PostDOMEvent();
-}
-
-bool
-HTMLMediaElement::IsEventAttributeName(nsIAtom* aName)
-{
- return aName == nsGkAtoms::onencrypted ||
- nsGenericHTMLElement::IsEventAttributeName(aName);
-}
-
-already_AddRefed<nsIPrincipal>
-HTMLMediaElement::GetTopLevelPrincipal()
-{
- RefPtr<nsIPrincipal> principal;
- nsCOMPtr<nsPIDOMWindowInner> window = OwnerDoc()->GetInnerWindow();
- if (!window) {
- return nullptr;
- }
- // XXXkhuey better hope we always have an outer ...
- nsCOMPtr<nsPIDOMWindowOuter> top = window->GetOuterWindow()->GetTop();
- if (!top) {
- return nullptr;
- }
- nsIDocument* doc = top->GetExtantDoc();
- if (!doc) {
- return nullptr;
- }
- principal = doc->NodePrincipal();
- return principal.forget();
-}
-
-void
-HTMLMediaElement::CannotDecryptWaitingForKey()
-{
- LOG(LogLevel::Debug, ("%p, CannotDecryptWaitingForKey()", this));
-
- // http://w3c.github.io/encrypted-media/#wait-for-key
- // 7.3.4 Queue a "waitingforkey" Event
- // 1. Let the media element be the specified HTMLMediaElement object.
- // 2. If the media element's waiting for key value is true, abort these steps.
- if (mWaitingForKey == NOT_WAITING_FOR_KEY) {
- // 3. Set the media element's waiting for key value to true.
- // Note: algorithm continues in UpdateReadyStateInternal() when all decoded
- // data enqueued in the MDSM is consumed.
- mWaitingForKey = WAITING_FOR_KEY;
- UpdateReadyStateInternal();
- }
-}
-#endif //MOZ_EME
-
NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged(bool aCapture)
{
MOZ_ASSERT(mAudioChannelAgent);
diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h
index bda9924a6f..23799b574c 100644
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -18,9 +18,6 @@
#include "mozilla/dom/TextTrackManager.h"
#include "mozilla/WeakPtr.h"
#include "MediaDecoder.h"
-#ifdef MOZ_EME
-#include "mozilla/dom/MediaKeys.h"
-#endif
#include "mozilla/StateWatching.h"
#include "nsGkAtoms.h"
#include "PrincipalChangeObserver.h"
@@ -616,30 +613,6 @@ public:
// XPCOM MozPreservesPitch() is OK
-#ifdef MOZ_EME
- MediaKeys* GetMediaKeys() const;
-
- already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
- ErrorResult& aRv);
-
- mozilla::dom::EventHandlerNonNull* GetOnencrypted();
- void SetOnencrypted(mozilla::dom::EventHandlerNonNull* aCallback);
-
- mozilla::dom::EventHandlerNonNull* GetOnwaitingforkey();
- void SetOnwaitingforkey(mozilla::dom::EventHandlerNonNull* aCallback);
-
- void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
- const nsAString& aInitDataType) override;
-
- bool IsEventAttributeName(nsIAtom* aName) override;
-
- // Returns the principal of the "top level" document; the origin displayed
- // in the URL bar of the browser window.
- already_AddRefed<nsIPrincipal> GetTopLevelPrincipal();
-
- bool ContainsRestrictedContent();
-#endif // MOZ_EME
-
void CannotDecryptWaitingForKey();
bool MozAutoplayEnabled() const
@@ -1474,11 +1447,6 @@ protected:
// Timer used for updating progress events.
nsCOMPtr<nsITimer> mProgressTimer;
-#ifdef MOZ_EME
- // Encrypted Media Extension media keys.
- RefPtr<MediaKeys> mMediaKeys;
-#endif
-
// Stores the time at the start of the current 'played' range.
double mCurrentPlayRangeStart;
@@ -1632,11 +1600,6 @@ protected:
// Listens for waitingForKey events from the owned decoder.
MediaEventListener mWaitingForKeyListener;
-#ifdef MOZ_EME
- // Init Data that needs to be sent in 'encrypted' events in MetadataLoaded().
- EncryptionInfo mPendingEncryptedInitData;
-#endif
-
// True if the media's channel's download has been suspended.
Watchable<bool> mDownloadSuspendedByCache;
diff --git a/dom/media/AbstractMediaDecoder.h b/dom/media/AbstractMediaDecoder.h
index c6aa997553..108f7a57f7 100644
--- a/dom/media/AbstractMediaDecoder.h
+++ b/dom/media/AbstractMediaDecoder.h
@@ -32,9 +32,6 @@ class MediaResource;
class ReentrantMonitor;
class VideoFrameContainer;
class MediaDecoderOwner;
-#ifdef MOZ_EME
-class CDMProxy;
-#endif
typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags;
diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp
index 87454a4686..921ec6bfbf 100644
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -388,9 +388,6 @@ MediaDecoder::MediaDecoder(MediaDecoderOwner* aOwner)
, mLogicalPosition(0.0)
, mDuration(std::numeric_limits<double>::quiet_NaN())
, mResourceCallback(new ResourceCallback())
-#ifdef MOZ_EME
- , mCDMProxyPromise(mCDMProxyPromiseHolder.Ensure(__func__))
-#endif
, mIgnoreProgressData(false)
, mInfiniteStream(false)
, mOwner(aOwner)
@@ -475,10 +472,6 @@ MediaDecoder::Shutdown()
mResourceCallback->Disconnect();
-#ifdef MOZ_EME
- mCDMProxyPromiseHolder.RejectIfExists(true, __func__);
-#endif
-
DiscardOngoingSeekIfExists();
// This changes the decoder state to SHUTDOWN and does other things
@@ -1551,23 +1544,6 @@ MediaDecoder::CanPlayThrough()
return GetStatistics().CanPlayThrough();
}
-#ifdef MOZ_EME
-RefPtr<MediaDecoder::CDMProxyPromise>
-MediaDecoder::RequestCDMProxy() const
-{
- return mCDMProxyPromise;
-}
-
-void
-MediaDecoder::SetCDMProxy(CDMProxy* aProxy)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aProxy);
-
- mCDMProxyPromiseHolder.ResolveIfExists(aProxy, __func__);
-}
-#endif
-
bool
MediaDecoder::IsOpusEnabled()
{
diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h
index 95f211e1c5..d54ba30de5 100644
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -8,10 +8,6 @@
#include "mozilla/Atomics.h"
-#ifdef MOZ_EME
-#include "mozilla/CDMProxy.h"
-#endif
-
#include "mozilla/MozPromise.h"
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/StateMirroring.h"
@@ -437,16 +433,6 @@ private:
MediaDecoderOwner* GetOwner() const override;
-#ifdef MOZ_EME
- typedef MozPromise<RefPtr<CDMProxy>, bool /* aIgnored */, /* IsExclusive = */ true> CDMProxyPromise;
-
- // Resolved when a CDMProxy is available and the capabilities are known or
- // rejected when this decoder is about to shut down.
- RefPtr<CDMProxyPromise> RequestCDMProxy() const;
-
- void SetCDMProxy(CDMProxy* aProxy);
-#endif
-
static bool IsOggEnabled();
static bool IsOpusEnabled();
static bool IsWaveEnabled();
@@ -596,11 +582,6 @@ private:
RefPtr<ResourceCallback> mResourceCallback;
-#ifdef MOZ_EME
- MozPromiseHolder<CDMProxyPromise> mCDMProxyPromiseHolder;
- RefPtr<CDMProxyPromise> mCDMProxyPromise;
-#endif
-
protected:
// The promise resolving/rejection is queued as a "micro-task" which will be
// handled immediately after the current JS task and before any pending JS
diff --git a/dom/media/MediaDecoderOwner.h b/dom/media/MediaDecoderOwner.h
index 9be4be3d0b..50a29d0951 100644
--- a/dom/media/MediaDecoderOwner.h
+++ b/dom/media/MediaDecoderOwner.h
@@ -141,14 +141,6 @@ public:
// The decoder owner should call Shutdown() on the decoder and drop the
// reference to the decoder to prevent further calls into the decoder.
virtual void NotifyXPCOMShutdown() = 0;
-
-#ifdef MOZ_EME
- // Dispatches a "encrypted" event to the HTMLMediaElement, with the
- // provided init data. Actual dispatch may be delayed until HAVE_METADATA.
- // Main thread only.
- virtual void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
- const nsAString& aInitDataType) = 0;
-#endif
};
} // namespace mozilla
diff --git a/dom/media/MediaDecoderReader.h b/dom/media/MediaDecoderReader.h
index dd406ed90e..3a3e2ceb82 100644
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -24,9 +24,6 @@
namespace mozilla {
-#ifdef MOZ_EME
-class CDMProxy;
-#endif
class MediaDecoderReader;
struct WaitForDataRejectValue
@@ -188,10 +185,6 @@ public:
// when to call SetIdle().
virtual void SetIdle() {}
-#ifdef MOZ_EME
- virtual void SetCDMProxy(CDMProxy* aProxy) {}
-#endif
-
// Tell the reader that the data decoded are not for direct playback, so it
// can accept more files, in particular those which have more channels than
// available in the audio output.
diff --git a/dom/media/MediaDecoderReaderWrapper.h b/dom/media/MediaDecoderReaderWrapper.h
index a0f845538e..c85c93d44f 100644
--- a/dom/media/MediaDecoderReaderWrapper.h
+++ b/dom/media/MediaDecoderReaderWrapper.h
@@ -112,10 +112,6 @@ public:
return mReader->CanonicalBuffered();
}
-#ifdef MOZ_EME
- void SetCDMProxy(CDMProxy* aProxy) { mReader->SetCDMProxy(aProxy); }
-#endif
-
void SetVideoBlankDecode(bool aIsBlankDecode);
private:
diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp
index b84a76d624..dc82e89e34 100644
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -271,7 +271,6 @@ protected:
*
* Transition to other states when decoding metadata is done:
* SHUTDOWN if failing to decode metadata.
- * WAIT_FOR_CDM if the media is encrypted and CDM is not available.
* DECODING_FIRSTFRAME otherwise.
*/
class MediaDecoderStateMachine::DecodeMetadataState
@@ -342,60 +341,6 @@ private:
};
/**
- * Purpose: wait for the CDM to start decoding.
- *
- * Transition to other states when CDM is ready:
- * DECODING_FIRSTFRAME otherwise.
- */
-class MediaDecoderStateMachine::WaitForCDMState
- : public MediaDecoderStateMachine::StateObject
-{
-public:
- explicit WaitForCDMState(Master* aPtr) : StateObject(aPtr) {}
-
- void Enter()
- {
- MOZ_ASSERT(!mMaster->mVideoDecodeSuspended);
- }
-
- void Exit() override
- {
- // mPendingSeek is either moved in HandleCDMProxyReady() or should be
- // rejected here before transition to SHUTDOWN.
- mPendingSeek.RejectIfExists(__func__);
- }
-
- State GetState() const override
- {
- return DECODER_STATE_WAIT_FOR_CDM;
- }
-
- void HandleCDMProxyReady() override;
-
- RefPtr<MediaDecoder::SeekPromise> HandleSeek(SeekTarget aTarget) override
- {
- SLOG("Not Enough Data to seek at this stage, queuing seek");
- mPendingSeek.RejectIfExists(__func__);
- mPendingSeek.mTarget = aTarget;
- return mPendingSeek.mPromise.Ensure(__func__);
- }
-
- void HandleVideoSuspendTimeout() override
- {
- // Do nothing since no decoders are created yet.
- }
-
- void HandleResumeVideoDecoding() override
- {
- // We never suspend video decoding in this state.
- MOZ_ASSERT(false, "Shouldn't have suspended video decoding.");
- }
-
-private:
- SeekJob mPendingSeek;
-};
-
-/**
* Purpose: release decoder resources to save memory and hardware resources.
*
* Transition to:
@@ -1231,33 +1176,14 @@ DecodeMetadataState::OnMetadataRead(MetadataHolder* aMetadata)
mMaster->GetAmpleVideoFrames());
}
- // In general, we wait until we know the duration before notifying the decoder.
- // However, we notify unconditionally in this case without waiting for the start
- // time, since the caller might be waiting on metadataloaded to be fired before
- // feeding in the CDM, which we need to decode the first frame (and
- // thus get the metadata). We could fix this if we could compute the start
- // time by demuxing without necessaring decoding.
- bool waitingForCDM =
-#ifdef MOZ_EME
- mMaster->Info().IsEncrypted() && !mMaster->mCDMProxy;
-#else
- false;
-#endif
-
mMaster->mNotifyMetadataBeforeFirstFrame =
- mMaster->mDuration.Ref().isSome() || waitingForCDM;
+ mMaster->mDuration.Ref().isSome();
if (mMaster->mNotifyMetadataBeforeFirstFrame) {
mMaster->EnqueueLoadedMetadataEvent();
}
- if (waitingForCDM) {
- // Metadata parsing was successful but we're still waiting for CDM caps
- // to become available so that we can build the correct decryptor/decoder.
- SetState<WaitForCDMState>();
- } else {
- SetState<DecodingFirstFrameState>(SeekJob{});
- }
+ SetState<DecodingFirstFrameState>(SeekJob{});
}
void
@@ -1266,9 +1192,6 @@ DormantState::HandlePlayStateChanged(MediaDecoder::PlayState aPlayState)
{
if (aPlayState == MediaDecoder::PLAY_STATE_PLAYING) {
// Exit dormant when the user wants to play.
-#ifdef MOZ_EME
- MOZ_ASSERT(!Info().IsEncrypted() || mMaster->mCDMProxy);
-#endif
MOZ_ASSERT(mMaster->mSentFirstFrameLoadedEvent);
SetState<SeekingState>(Move(mPendingSeek), EventVisibility::Suppressed);
}
@@ -1276,13 +1199,6 @@ DormantState::HandlePlayStateChanged(MediaDecoder::PlayState aPlayState)
void
MediaDecoderStateMachine::
-WaitForCDMState::HandleCDMProxyReady()
-{
- SetState<DecodingFirstFrameState>(Move(mPendingSeek));
-}
-
-void
-MediaDecoderStateMachine::
DecodingFirstFrameState::Enter(SeekJob aPendingSeek)
{
// Handle pending seek.
@@ -1581,10 +1497,6 @@ ShutdownState::Enter()
// dispose of the timer.
master->mVideoDecodeSuspendTimer.Reset();
-#ifdef MOZ_EME
- master->mCDMProxyPromise.DisconnectIfExists();
-#endif
-
if (master->IsPlaying()) {
master->StopPlayback();
}
@@ -2137,13 +2049,6 @@ nsresult MediaDecoderStateMachine::Init(MediaDecoder* aDecoder)
mMediaSink = CreateMediaSink(mAudioCaptured);
-#ifdef MOZ_EME
- mCDMProxyPromise.Begin(aDecoder->RequestCDMProxy()->Then(
- OwnerThread(), __func__, this,
- &MediaDecoderStateMachine::OnCDMProxyReady,
- &MediaDecoderStateMachine::OnCDMProxyNotReady));
-#endif
-
nsresult rv = mReader->Init();
NS_ENSURE_SUCCESS(rv, rv);
@@ -2267,7 +2172,6 @@ MediaDecoderStateMachine::ToStateStr(State aState)
{
switch (aState) {
case DECODER_STATE_DECODING_METADATA: return "DECODING_METADATA";
- case DECODER_STATE_WAIT_FOR_CDM: return "WAIT_FOR_CDM";
case DECODER_STATE_DORMANT: return "DORMANT";
case DECODER_STATE_DECODING_FIRSTFRAME: return "DECODING_FIRSTFRAME";
case DECODER_STATE_DECODING: return "DECODING";
@@ -3118,25 +3022,6 @@ void MediaDecoderStateMachine::OnMediaSinkAudioError(nsresult aResult)
DecodeError(MediaResult(NS_ERROR_DOM_MEDIA_MEDIASINK_ERR, __func__));
}
-#ifdef MOZ_EME
-void
-MediaDecoderStateMachine::OnCDMProxyReady(RefPtr<CDMProxy> aProxy)
-{
- MOZ_ASSERT(OnTaskQueue());
- mCDMProxyPromise.Complete();
- mCDMProxy = aProxy;
- mReader->SetCDMProxy(aProxy);
- mStateObj->HandleCDMProxyReady();
-}
-
-void
-MediaDecoderStateMachine::OnCDMProxyNotReady()
-{
- MOZ_ASSERT(OnTaskQueue());
- mCDMProxyPromise.Complete();
-}
-#endif
-
void
MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
{
diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h
index 29da56e57d..ba9034e4fa 100644
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -155,7 +155,6 @@ public:
// Enumeration for the valid decoding states
enum State {
DECODER_STATE_DECODING_METADATA,
- DECODER_STATE_WAIT_FOR_CDM,
DECODER_STATE_DORMANT,
DECODER_STATE_DECODING_FIRSTFRAME,
DECODER_STATE_DECODING,
@@ -263,7 +262,6 @@ public:
private:
class StateObject;
class DecodeMetadataState;
- class WaitForCDMState;
class DormantState;
class DecodingFirstFrameState;
class DecodingState;
@@ -767,13 +765,6 @@ private:
// Playback will not start when audio is offloading.
bool mAudioOffloading;
-#ifdef MOZ_EME
- void OnCDMProxyReady(RefPtr<CDMProxy> aProxy);
- void OnCDMProxyNotReady();
- RefPtr<CDMProxy> mCDMProxy;
- MozPromiseRequestHolder<MediaDecoder::CDMProxyPromise> mCDMProxyPromise;
-#endif
-
private:
// The buffered range. Mirrored from the decoder thread.
Mirror<media::TimeIntervals> mBuffered;
diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp
index a658298e2d..17fa29c080 100644
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -3,10 +3,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef MOZ_EME
-#include "mozilla/CDMProxy.h"
-#endif
-
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/Preferences.h"
@@ -351,12 +347,7 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(TrackType aTrack)
if (!mOwner->mPlatform) {
mOwner->mPlatform = new PDMFactory();
if (mOwner->IsEncrypted()) {
-#ifdef MOZ_EME
- MOZ_ASSERT(mOwner->mCDMProxy);
- mOwner->mPlatform->SetCDMProxy(mOwner->mCDMProxy);
-#else
return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, "EME not supported");
-#endif
}
}
@@ -592,56 +583,6 @@ MediaFormatReader::InitInternal()
return NS_OK;
}
-#ifdef MOZ_EME
-class DispatchKeyNeededEvent : public Runnable {
-public:
- DispatchKeyNeededEvent(AbstractMediaDecoder* aDecoder,
- nsTArray<uint8_t>& aInitData,
- const nsString& aInitDataType)
- : mDecoder(aDecoder)
- , mInitData(aInitData)
- , mInitDataType(aInitDataType)
- {
- }
- NS_IMETHOD Run() override {
- // Note: Null check the owner, as the decoder could have been shutdown
- // since this event was dispatched.
- MediaDecoderOwner* owner = mDecoder->GetOwner();
- if (owner) {
- owner->DispatchEncrypted(mInitData, mInitDataType);
- }
- mDecoder = nullptr;
- return NS_OK;
- }
-private:
- RefPtr<AbstractMediaDecoder> mDecoder;
- nsTArray<uint8_t> mInitData;
- nsString mInitDataType;
-};
-
-void
-MediaFormatReader::SetCDMProxy(CDMProxy* aProxy)
-{
- RefPtr<CDMProxy> proxy = aProxy;
- RefPtr<MediaFormatReader> self = this;
- nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
- MOZ_ASSERT(self->OnTaskQueue());
- self->mCDMProxy = proxy;
- });
- OwnerThread()->Dispatch(r.forget());
-}
-#endif // MOZ_EME
-
-bool
-MediaFormatReader::IsWaitingOnCDMResource() {
- MOZ_ASSERT(OnTaskQueue());
-#ifdef MOZ_EME
- return IsEncrypted() && !mCDMProxy;
-#else
- return false;
-#endif
-}
-
RefPtr<MediaDecoderReader::MetadataPromise>
MediaFormatReader::AsyncReadMetadata()
{
@@ -677,9 +618,7 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
UniquePtr<MetadataTags> tags(MakeUnique<MetadataTags>());
RefPtr<PDMFactory> platform;
- if (!IsWaitingOnCDMResource()) {
- platform = new PDMFactory();
- }
+ platform = new PDMFactory();
// To decode, we need valid video and a place to put it.
bool videoActive = !!mDemuxer->GetNumberTracks(TrackInfo::kVideoTrack) &&
@@ -746,13 +685,6 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
UniquePtr<EncryptionInfo> crypto = mDemuxer->GetCrypto();
if (mDecoder && crypto && crypto->IsEncrypted()) {
-#ifdef MOZ_EME
- // Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
- for (uint32_t i = 0; i < crypto->mInitDatas.Length(); i++) {
- NS_DispatchToMainThread(
- new DispatchKeyNeededEvent(mDecoder, crypto->mInitDatas[i].mInitData, crypto->mInitDatas[i].mType));
- }
-#endif
mInfo.mCrypto = *crypto;
}
diff --git a/dom/media/MediaFormatReader.h b/dom/media/MediaFormatReader.h
index ccd43f0e6a..60ee022264 100644
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -19,10 +19,6 @@
namespace mozilla {
-#ifdef MOZ_EME
-class CDMProxy;
-#endif
-
class MediaFormatReader final : public MediaDecoderReader
{
typedef TrackInfo::TrackType TrackType;
@@ -92,10 +88,6 @@ public:
return mTrackDemuxersMayBlock;
}
-#ifdef MOZ_EME
- void SetCDMProxy(CDMProxy* aProxy) override;
-#endif
-
// Returns a string describing the state of the decoder data.
// Used for debugging purposes.
void GetMozDebugReaderData(nsAString& aString);
@@ -108,8 +100,6 @@ private:
bool HasVideo() const { return mVideo.mTrackDemuxer; }
bool HasAudio() const { return mAudio.mTrackDemuxer; }
- bool IsWaitingOnCDMResource();
-
bool InitDemuxer();
// Notify the demuxer that new data has been received.
// The next queued task calling GetBuffered() is guaranteed to have up to date
@@ -587,14 +577,6 @@ private:
RefPtr<VideoFrameContainer> mVideoFrameContainer;
layers::ImageContainer* GetImageContainer();
-#ifdef MOZ_EME
- RefPtr<CDMProxy> mCDMProxy;
-#endif
-
-#ifdef MOZ_GMP
- RefPtr<GMPCrashHelper> mCrashHelper;
-#endif
-
void SetBlankDecode(TrackType aTrack, bool aIsBlankDecode);
class DecoderFactory;
diff --git a/dom/media/MediaPrefs.h b/dom/media/MediaPrefs.h
index 675518ba62..40d0971d80 100644
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -102,9 +102,6 @@ private:
DECL_MEDIA_PREF("media.gmp.insecure.allow", GMPAllowInsecure, bool, false);
DECL_MEDIA_PREF("media.gmp.async-shutdown-timeout", GMPAsyncShutdownTimeout, uint32_t, GMP_DEFAULT_ASYNC_SHUTDOWN_TIMEOUT);
#endif
-#ifdef MOZ_EME
- DECL_MEDIA_PREF("media.eme.enabled", EMEEnabled, bool, false);
-#endif
DECL_MEDIA_PREF("media.use-blank-decoder", PDMUseBlankDecoder, bool, false);
DECL_MEDIA_PREF("media.gpu-process-decoder", PDMUseGPUDecoder, bool, false);
#ifdef MOZ_FFMPEG
diff --git a/dom/media/eme/CDMCaps.cpp b/dom/media/eme/CDMCaps.cpp
deleted file mode 100644
index a30fb59ac8..0000000000
--- a/dom/media/eme/CDMCaps.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/CDMCaps.h"
-#include "mozilla/EMEUtils.h"
-#include "nsThreadUtils.h"
-#include "SamplesWaitingForKey.h"
-
-namespace mozilla {
-
-CDMCaps::CDMCaps()
- : mMonitor("CDMCaps")
-{
-}
-
-CDMCaps::~CDMCaps()
-{
-}
-
-void
-CDMCaps::Lock()
-{
- mMonitor.Lock();
-}
-
-void
-CDMCaps::Unlock()
-{
- mMonitor.Unlock();
-}
-
-CDMCaps::AutoLock::AutoLock(CDMCaps& aInstance)
- : mData(aInstance)
-{
- mData.Lock();
-}
-
-CDMCaps::AutoLock::~AutoLock()
-{
- mData.Unlock();
-}
-
-// Keys with MediaKeyStatus::Usable, MediaKeyStatus::Output_downscaled,
-// or MediaKeyStatus::Output_restricted status can be used by the CDM
-// to decrypt or decrypt-and-decode samples.
-static bool
-IsUsableStatus(dom::MediaKeyStatus aStatus)
-{
- return aStatus == dom::MediaKeyStatus::Usable ||
- aStatus == dom::MediaKeyStatus::Output_restricted ||
- aStatus == dom::MediaKeyStatus::Output_downscaled;
-}
-
-bool
-CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId)
-{
- mData.mMonitor.AssertCurrentThreadOwns();
- for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
- if (keyStatus.mId == aKeyId) {
- return IsUsableStatus(keyStatus.mStatus);
- }
- }
- return false;
-}
-
-bool
-CDMCaps::AutoLock::SetKeyStatus(const CencKeyId& aKeyId,
- const nsString& aSessionId,
- const dom::Optional<dom::MediaKeyStatus>& aStatus)
-{
- mData.mMonitor.AssertCurrentThreadOwns();
-
- if (!aStatus.WasPassed()) {
- // Called from ForgetKeyStatus.
- // Return true if the element is found to notify key changes.
- return mData.mKeyStatuses.RemoveElement(KeyStatus(aKeyId,
- aSessionId,
- dom::MediaKeyStatus::Internal_error));
- }
-
- KeyStatus key(aKeyId, aSessionId, aStatus.Value());
- auto index = mData.mKeyStatuses.IndexOf(key);
- if (index != mData.mKeyStatuses.NoIndex) {
- if (mData.mKeyStatuses[index].mStatus == aStatus.Value()) {
- // No change.
- return false;
- }
- auto oldStatus = mData.mKeyStatuses[index].mStatus;
- mData.mKeyStatuses[index].mStatus = aStatus.Value();
- // The old key status was one for which we can decrypt media. We don't
- // need to do the "notify usable" step below, as it should be impossible
- // for us to have anything waiting on this key to become usable, since it
- // was already usable.
- if (IsUsableStatus(oldStatus)) {
- return true;
- }
- } else {
- mData.mKeyStatuses.AppendElement(key);
- }
-
- // Only call NotifyUsable() for a key when we are going from non-usable
- // to usable state.
- if (!IsUsableStatus(aStatus.Value())) {
- return true;
- }
-
- auto& waiters = mData.mWaitForKeys;
- size_t i = 0;
- while (i < waiters.Length()) {
- auto& w = waiters[i];
- if (w.mKeyId == aKeyId) {
- w.mListener->NotifyUsable(aKeyId);
- waiters.RemoveElementAt(i);
- } else {
- i++;
- }
- }
- return true;
-}
-
-void
-CDMCaps::AutoLock::NotifyWhenKeyIdUsable(const CencKeyId& aKey,
- SamplesWaitingForKey* aListener)
-{
- mData.mMonitor.AssertCurrentThreadOwns();
- MOZ_ASSERT(!IsKeyUsable(aKey));
- MOZ_ASSERT(aListener);
- mData.mWaitForKeys.AppendElement(WaitForKeys(aKey, aListener));
-}
-
-void
-CDMCaps::AutoLock::GetKeyStatusesForSession(const nsAString& aSessionId,
- nsTArray<KeyStatus>& aOutKeyStatuses)
-{
- for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
- if (keyStatus.mSessionId.Equals(aSessionId)) {
- aOutKeyStatuses.AppendElement(keyStatus);
- }
- }
-}
-
-void
-CDMCaps::AutoLock::GetSessionIdsForKeyId(const CencKeyId& aKeyId,
- nsTArray<nsCString>& aOutSessionIds)
-{
- for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
- if (keyStatus.mId == aKeyId) {
- aOutSessionIds.AppendElement(NS_ConvertUTF16toUTF8(keyStatus.mSessionId));
- }
- }
-}
-
-bool
-CDMCaps::AutoLock::RemoveKeysForSession(const nsString& aSessionId)
-{
- bool changed = false;
- nsTArray<KeyStatus> statuses;
- GetKeyStatusesForSession(aSessionId, statuses);
- for (const KeyStatus& status : statuses) {
- changed |= SetKeyStatus(status.mId,
- aSessionId,
- dom::Optional<dom::MediaKeyStatus>());
- }
- return changed;
-}
-
-} // namespace mozilla
diff --git a/dom/media/eme/CDMCaps.h b/dom/media/eme/CDMCaps.h
deleted file mode 100644
index cb4b5e2910..0000000000
--- a/dom/media/eme/CDMCaps.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CDMCaps_h_
-#define CDMCaps_h_
-
-#include "gmp-decryption.h"
-#include "nsIThread.h"
-#include "nsTArray.h"
-#include "nsString.h"
-#include "SamplesWaitingForKey.h"
-
-#include "mozilla/Monitor.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/dom/MediaKeyStatusMapBinding.h" // For MediaKeyStatus
-#include "mozilla/dom/BindingDeclarations.h" // For Optional
-
-namespace mozilla {
-
-// CDM capabilities; what keys a CDMProxy can use.
-// Must be locked to access state.
-class CDMCaps {
-public:
- CDMCaps();
- ~CDMCaps();
-
- struct KeyStatus {
- KeyStatus(const CencKeyId& aId,
- const nsString& aSessionId,
- dom::MediaKeyStatus aStatus)
- : mId(aId)
- , mSessionId(aSessionId)
- , mStatus(aStatus)
- {}
- KeyStatus(const KeyStatus& aOther)
- : mId(aOther.mId)
- , mSessionId(aOther.mSessionId)
- , mStatus(aOther.mStatus)
- {}
- bool operator==(const KeyStatus& aOther) const {
- return mId == aOther.mId &&
- mSessionId == aOther.mSessionId;
- };
-
- CencKeyId mId;
- nsString mSessionId;
- dom::MediaKeyStatus mStatus;
- };
-
- // Locks the CDMCaps. It must be locked to access its shared state.
- // Threadsafe when locked.
- class MOZ_STACK_CLASS AutoLock {
- public:
- explicit AutoLock(CDMCaps& aKeyCaps);
- ~AutoLock();
-
- bool IsKeyUsable(const CencKeyId& aKeyId);
-
- // Returns true if key status changed,
- // i.e. the key status changed from usable to expired.
- bool SetKeyStatus(const CencKeyId& aKeyId,
- const nsString& aSessionId,
- const dom::Optional<dom::MediaKeyStatus>& aStatus);
-
- void GetKeyStatusesForSession(const nsAString& aSessionId,
- nsTArray<KeyStatus>& aOutKeyStatuses);
-
- void GetSessionIdsForKeyId(const CencKeyId& aKeyId,
- nsTArray<nsCString>& aOutSessionIds);
-
- // Ensures all keys for a session are marked as 'unknown', i.e. removed.
- // Returns true if a key status was changed.
- bool RemoveKeysForSession(const nsString& aSessionId);
-
- // Notifies the SamplesWaitingForKey when key become usable.
- void NotifyWhenKeyIdUsable(const CencKeyId& aKey,
- SamplesWaitingForKey* aSamplesWaiting);
- private:
- // Not taking a strong ref, since this should be allocated on the stack.
- CDMCaps& mData;
- };
-
-private:
- void Lock();
- void Unlock();
-
- struct WaitForKeys {
- WaitForKeys(const CencKeyId& aKeyId,
- SamplesWaitingForKey* aListener)
- : mKeyId(aKeyId)
- , mListener(aListener)
- {}
- CencKeyId mKeyId;
- RefPtr<SamplesWaitingForKey> mListener;
- };
-
- Monitor mMonitor;
-
- nsTArray<KeyStatus> mKeyStatuses;
-
- nsTArray<WaitForKeys> mWaitForKeys;
-
- // It is not safe to copy this object.
- CDMCaps(const CDMCaps&) = delete;
- CDMCaps& operator=(const CDMCaps&) = delete;
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/eme/CDMProxy.h b/dom/media/eme/CDMProxy.h
deleted file mode 100644
index a9e783f506..0000000000
--- a/dom/media/eme/CDMProxy.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CDMProxy_h_
-#define CDMProxy_h_
-
-#include "mozilla/CDMCaps.h"
-#include "mozilla/MozPromise.h"
-
-#include "mozilla/dom/MediaKeyMessageEvent.h"
-#include "mozilla/dom/MediaKeys.h"
-
-#include "nsIThread.h"
-
-namespace mozilla {
-class MediaRawData;
-
-enum DecryptStatus {
- Ok = 0,
- GenericErr = 1,
- NoKeyErr = 2,
- AbortedErr = 3,
-};
-
-struct DecryptResult {
- DecryptResult(DecryptStatus aStatus, MediaRawData* aSample)
- : mStatus(aStatus)
- , mSample(aSample)
- {}
- DecryptStatus mStatus;
- RefPtr<MediaRawData> mSample;
-};
-
-class CDMKeyInfo {
-public:
- explicit CDMKeyInfo(const nsTArray<uint8_t>& aKeyId)
- : mKeyId(aKeyId)
- , mStatus()
- {}
-
- CDMKeyInfo(const nsTArray<uint8_t>& aKeyId,
- const dom::Optional<dom::MediaKeyStatus>& aStatus)
- : mKeyId(aKeyId)
- , mStatus(aStatus.Value())
- {}
-
- // The copy-ctor and copy-assignment operator for Optional<T> are declared as
- // delete, so override CDMKeyInfo copy-ctor for nsTArray operations.
- CDMKeyInfo(const CDMKeyInfo& aKeyInfo)
- {
- mKeyId = aKeyInfo.mKeyId;
- if (aKeyInfo.mStatus.WasPassed()) {
- mStatus.Construct(aKeyInfo.mStatus.Value());
- }
- }
-
- nsTArray<uint8_t> mKeyId;
- dom::Optional<dom::MediaKeyStatus> mStatus;
-};
-
-typedef int64_t UnixTime;
-
-// Proxies calls CDM, and proxies calls back.
-// Note: Promises are passed in via a PromiseId, so that the ID can be
-// passed via IPC to the CDM, which can then signal when to reject or
-// resolve the promise using its PromiseId.
-class CDMProxy {
-protected:
- typedef dom::PromiseId PromiseId;
- typedef dom::MediaKeySessionType MediaKeySessionType;
-public:
-
- NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
- NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
-
- typedef MozPromise<DecryptResult, DecryptResult, /* IsExclusive = */ true> DecryptPromise;
-
- // Main thread only.
- CDMProxy(dom::MediaKeys* aKeys,
- const nsAString& aKeySystem,
- bool aDistinctiveIdentifierRequired,
- bool aPersistentStateRequired)
- : mKeys(aKeys)
- , mKeySystem(aKeySystem)
- , mDistinctiveIdentifierRequired(aDistinctiveIdentifierRequired)
- , mPersistentStateRequired(aPersistentStateRequired)
- {}
-
- // Main thread only.
- // Loads the CDM corresponding to mKeySystem.
- // Calls MediaKeys::OnCDMCreated() when the CDM is created.
- virtual void Init(PromiseId aPromiseId,
- const nsAString& aOrigin,
- const nsAString& aTopLevelOrigin,
- const nsAString& aName,
- bool aInPrivateBrowsing) = 0;
-
- virtual void OnSetDecryptorId(uint32_t aId) {}
-
- // Main thread only.
- // Uses the CDM to create a key session.
- // Calls MediaKeys::OnSessionActivated() when session is created.
- // Assumes ownership of (Move()s) aInitData's contents.
- virtual void CreateSession(uint32_t aCreateSessionToken,
- MediaKeySessionType aSessionType,
- PromiseId aPromiseId,
- const nsAString& aInitDataType,
- nsTArray<uint8_t>& aInitData) = 0;
-
- // Main thread only.
- // Uses the CDM to load a presistent session stored on disk.
- // Calls MediaKeys::OnSessionActivated() when session is loaded.
- virtual void LoadSession(PromiseId aPromiseId,
- const nsAString& aSessionId) = 0;
-
- // Main thread only.
- // Sends a new certificate to the CDM.
- // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
- // processed the request.
- // Assumes ownership of (Move()s) aCert's contents.
- virtual void SetServerCertificate(PromiseId aPromiseId,
- nsTArray<uint8_t>& aCert) = 0;
-
- // Main thread only.
- // Sends an update to the CDM.
- // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
- // processed the request.
- // Assumes ownership of (Move()s) aResponse's contents.
- virtual void UpdateSession(const nsAString& aSessionId,
- PromiseId aPromiseId,
- nsTArray<uint8_t>& aResponse) = 0;
-
- // Main thread only.
- // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
- // processed the request.
- // If processing this operation results in the session actually closing,
- // we also call MediaKeySession::OnClosed(), which in turn calls
- // MediaKeys::OnSessionClosed().
- virtual void CloseSession(const nsAString& aSessionId,
- PromiseId aPromiseId) = 0;
-
- // Main thread only.
- // Removes all data for a persisent session.
- // Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
- // processed the request.
- virtual void RemoveSession(const nsAString& aSessionId,
- PromiseId aPromiseId) = 0;
-
- // Main thread only.
- virtual void Shutdown() = 0;
-
- // Main thread only.
- virtual void Terminated() = 0;
-
- // Threadsafe.
- virtual const nsCString& GetNodeId() const = 0;
-
- // Main thread only.
- virtual void OnSetSessionId(uint32_t aCreateSessionToken,
- const nsAString& aSessionId) = 0;
-
- // Main thread only.
- virtual void OnResolveLoadSessionPromise(uint32_t aPromiseId,
- bool aSuccess) = 0;
-
- // Main thread only.
- virtual void OnSessionMessage(const nsAString& aSessionId,
- dom::MediaKeyMessageType aMessageType,
- nsTArray<uint8_t>& aMessage) = 0;
-
- // Main thread only.
- virtual void OnExpirationChange(const nsAString& aSessionId,
- UnixTime aExpiryTime) = 0;
-
- // Main thread only.
- virtual void OnSessionClosed(const nsAString& aSessionId) = 0;
-
- // Main thread only.
- virtual void OnSessionError(const nsAString& aSessionId,
- nsresult aException,
- uint32_t aSystemCode,
- const nsAString& aMsg) = 0;
-
- // Main thread only.
- virtual void OnRejectPromise(uint32_t aPromiseId,
- nsresult aDOMException,
- const nsCString& aMsg) = 0;
-
- virtual RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) = 0;
-
- // Owner thread only.
- virtual void OnDecrypted(uint32_t aId,
- DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData) = 0;
-
- // Reject promise with DOMException corresponding to aExceptionCode.
- // Can be called from any thread.
- virtual void RejectPromise(PromiseId aId,
- nsresult aExceptionCode,
- const nsCString& aReason) = 0;
-
- // Resolves promise with "undefined".
- // Can be called from any thread.
- virtual void ResolvePromise(PromiseId aId) = 0;
-
- // Threadsafe.
- virtual const nsString& KeySystem() const = 0;
-
- virtual CDMCaps& Capabilites() = 0;
-
- // Main thread only.
- virtual void OnKeyStatusesChange(const nsAString& aSessionId) = 0;
-
- virtual void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
- nsTArray<nsCString>& aSessionIds) = 0;
-
-#ifdef DEBUG
- virtual bool IsOnOwnerThread() = 0;
-#endif
-
- virtual uint32_t GetDecryptorId() { return 0; }
-
-protected:
- virtual ~CDMProxy() {}
-
- // Helper to enforce that a raw pointer is only accessed on the main thread.
- template<class Type>
- class MainThreadOnlyRawPtr {
- public:
- explicit MainThreadOnlyRawPtr(Type* aPtr)
- : mPtr(aPtr)
- {
- MOZ_ASSERT(NS_IsMainThread());
- }
-
- bool IsNull() const {
- MOZ_ASSERT(NS_IsMainThread());
- return !mPtr;
- }
-
- void Clear() {
- MOZ_ASSERT(NS_IsMainThread());
- mPtr = nullptr;
- }
-
- Type* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN {
- MOZ_ASSERT(NS_IsMainThread());
- return mPtr;
- }
- private:
- Type* mPtr;
- };
-
- // Our reference back to the MediaKeys object.
- // WARNING: This is a non-owning reference that is cleared by MediaKeys
- // destructor. only use on main thread, and always nullcheck before using!
- MainThreadOnlyRawPtr<dom::MediaKeys> mKeys;
-
- const nsString mKeySystem;
-
- // Onwer specified thread. e.g. Gecko Media Plugin thread.
- // All interactions with the out-of-process EME plugin must come from this thread.
- RefPtr<nsIThread> mOwnerThread;
-
- nsCString mNodeId;
-
- CDMCaps mCapabilites;
-
- const bool mDistinctiveIdentifierRequired;
- const bool mPersistentStateRequired;
-};
-
-
-} // namespace mozilla
-
-#endif // CDMProxy_h_
diff --git a/dom/media/eme/DecryptorProxyCallback.h b/dom/media/eme/DecryptorProxyCallback.h
deleted file mode 100644
index c1fcb49a4f..0000000000
--- a/dom/media/eme/DecryptorProxyCallback.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef DecryptorProxyCallback_h_
-#define DecryptorProxyCallback_h_
-
-#include "mozilla/dom/MediaKeyStatusMapBinding.h" // For MediaKeyStatus
-#include "mozilla/dom/MediaKeyMessageEventBinding.h" // For MediaKeyMessageType
-#include "mozilla/CDMProxy.h"
-
-class DecryptorProxyCallback {
-public:
-
- virtual ~DecryptorProxyCallback() {}
-
- virtual void SetDecryptorId(uint32_t aId) = 0;
-
- virtual void SetSessionId(uint32_t aCreateSessionId,
- const nsCString& aSessionId) = 0;
-
- virtual void ResolveLoadSessionPromise(uint32_t aPromiseId,
- bool aSuccess) = 0;
-
- virtual void ResolvePromise(uint32_t aPromiseId) = 0;
-
- virtual void RejectPromise(uint32_t aPromiseId,
- nsresult aException,
- const nsCString& aSessionId) = 0;
-
- virtual void SessionMessage(const nsCString& aSessionId,
- mozilla::dom::MediaKeyMessageType aMessageType,
- const nsTArray<uint8_t>& aMessage) = 0;
-
- virtual void ExpirationChange(const nsCString& aSessionId,
- mozilla::UnixTime aExpiryTime) = 0;
-
- virtual void SessionClosed(const nsCString& aSessionId) = 0;
-
- virtual void SessionError(const nsCString& aSessionId,
- nsresult aException,
- uint32_t aSystemCode,
- const nsCString& aMessage) = 0;
-
- virtual void Decrypted(uint32_t aId,
- mozilla::DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData) = 0;
-
- virtual void BatchedKeyStatusChanged(const nsCString& aSessionId,
- const nsTArray<mozilla::CDMKeyInfo>& aKeyInfos) = 0;
-};
-
-#endif
diff --git a/dom/media/eme/DetailedPromise.cpp b/dom/media/eme/DetailedPromise.cpp
deleted file mode 100644
index 1aa83bef5d..0000000000
--- a/dom/media/eme/DetailedPromise.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DetailedPromise.h"
-#include "mozilla/dom/DOMException.h"
-#include "nsPrintfCString.h"
-
-namespace mozilla {
-namespace dom {
-
-DetailedPromise::DetailedPromise(nsIGlobalObject* aGlobal,
- const nsACString& aName)
- : Promise(aGlobal)
- , mName(aName)
- , mResponded(false)
- , mStartTime(TimeStamp::Now())
-{
-}
-
-DetailedPromise::~DetailedPromise()
-{
-}
-
-void
-DetailedPromise::MaybeReject(nsresult aArg, const nsACString& aReason)
-{
- nsPrintfCString msg("%s promise rejected 0x%x '%s'", mName.get(), aArg,
- PromiseFlatCString(aReason).get());
- EME_LOG(msg.get());
-
- LogToBrowserConsole(NS_ConvertUTF8toUTF16(msg));
-
- ErrorResult rv;
- rv.ThrowDOMException(aArg, aReason);
- Promise::MaybeReject(rv);
-}
-
-void
-DetailedPromise::MaybeReject(ErrorResult&, const nsACString& aReason)
-{
- NS_NOTREACHED("nsresult expected in MaybeReject()");
-}
-
-/* static */ already_AddRefed<DetailedPromise>
-DetailedPromise::Create(nsIGlobalObject* aGlobal,
- ErrorResult& aRv,
- const nsACString& aName)
-{
- RefPtr<DetailedPromise> promise = new DetailedPromise(aGlobal, aName);
- promise->CreateWrapper(nullptr, aRv);
- return aRv.Failed() ? nullptr : promise.forget();
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/DetailedPromise.h b/dom/media/eme/DetailedPromise.h
deleted file mode 100644
index f7f10aa403..0000000000
--- a/dom/media/eme/DetailedPromise.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __DetailedPromise_h__
-#define __DetailedPromise_h__
-
-#include "mozilla/dom/Promise.h"
-#include "EMEUtils.h"
-
-namespace mozilla {
-namespace dom {
-
-/*
- * This is pretty horrible; bug 1160445.
- * Extend Promise to add custom DOMException messages on rejection.
- * Get rid of this once we've ironed out EME errors in the wild.
- */
-class DetailedPromise : public Promise
-{
-public:
- static already_AddRefed<DetailedPromise>
- Create(nsIGlobalObject* aGlobal,
- ErrorResult& aRv,
- const nsACString& aName);
-
- template <typename T>
- void MaybeResolve(const T& aArg)
- {
- EME_LOG("%s promise resolved", mName.get());
- Promise::MaybeResolve<T>(aArg);
- }
-
- void MaybeReject(nsresult aArg) = delete;
- void MaybeReject(nsresult aArg, const nsACString& aReason);
-
- void MaybeReject(ErrorResult& aArg) = delete;
- void MaybeReject(ErrorResult&, const nsACString& aReason);
-
-private:
- explicit DetailedPromise(nsIGlobalObject* aGlobal,
- const nsACString& aName);
-
- virtual ~DetailedPromise();
-
- enum Status { Succeeded, Failed };
-
- nsCString mName;
- bool mResponded;
- TimeStamp mStartTime;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // __DetailedPromise_h__
diff --git a/dom/media/eme/EMEUtils.cpp b/dom/media/eme/EMEUtils.cpp
deleted file mode 100644
index 68ef52d83e..0000000000
--- a/dom/media/eme/EMEUtils.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/EMEUtils.h"
-
-#include "jsfriendapi.h" // for AutoCheckCannotGC
-#include "mozilla/dom/UnionTypes.h"
-
-namespace mozilla {
-
-LogModule* GetEMELog() {
- static LazyLogModule log("EME");
- return log;
-}
-
-LogModule* GetEMEVerboseLog() {
- static LazyLogModule log("EMEV");
- return log;
-}
-
-ArrayData
-GetArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aBufferOrView)
-{
- MOZ_ASSERT(aBufferOrView.IsArrayBuffer() || aBufferOrView.IsArrayBufferView());
- JS::AutoCheckCannotGC nogc;
- if (aBufferOrView.IsArrayBuffer()) {
- const dom::ArrayBuffer& buffer = aBufferOrView.GetAsArrayBuffer();
- buffer.ComputeLengthAndData();
- return ArrayData(buffer.Data(), buffer.Length());
- } else if (aBufferOrView.IsArrayBufferView()) {
- const dom::ArrayBufferView& bufferview = aBufferOrView.GetAsArrayBufferView();
- bufferview.ComputeLengthAndData();
- return ArrayData(bufferview.Data(), bufferview.Length());
- }
- return ArrayData(nullptr, 0);
-}
-
-void
-CopyArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aBufferOrView,
- nsTArray<uint8_t>& aOutData)
-{
- JS::AutoCheckCannotGC nogc;
- ArrayData data = GetArrayBufferViewOrArrayBufferData(aBufferOrView);
- aOutData.Clear();
- if (!data.IsValid()) {
- return;
- }
- aOutData.AppendElements(data.mData, data.mLength);
-}
-
-void CopyArrayBufferViewOrArrayBufferData(const dom::ArrayBuffer& aBuffer,
- nsTArray<uint8_t>& aOutData) {
- JS::AutoCheckCannotGC nogc;
- aBuffer.ComputeLengthAndData();
- aOutData.Clear();
- aOutData.AppendElements(aBuffer.Data(), aBuffer.Length());
-}
-
-bool
-IsClearkeyKeySystem(const nsAString& aKeySystem)
-{
- return !CompareUTF8toUTF16(kEMEKeySystemClearkey, aKeySystem);
-}
-
-bool
-IsWidevineKeySystem(const nsAString& aKeySystem)
-{
- return !CompareUTF8toUTF16(kEMEKeySystemWidevine, aKeySystem);
-}
-
-nsString
-KeySystemToGMPName(const nsAString& aKeySystem)
-{
- if (IsClearkeyKeySystem(aKeySystem)) {
- return NS_LITERAL_STRING("gmp-clearkey");
- }
- if (IsWidevineKeySystem(aKeySystem)) {
- return NS_LITERAL_STRING("gmp-widevinecdm");
- }
- MOZ_ASSERT(false, "We should only call this for known GMPs");
- return EmptyString();
-}
-
-} // namespace mozilla
diff --git a/dom/media/eme/EMEUtils.h b/dom/media/eme/EMEUtils.h
deleted file mode 100644
index aef1574829..0000000000
--- a/dom/media/eme/EMEUtils.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef EME_LOG_H_
-#define EME_LOG_H_
-
-#include "VideoUtils.h"
-#include "mozilla/Logging.h"
-#include "nsString.h"
-#include "nsTArray.h"
-#include "mozilla/dom/TypedArray.h"
-
-namespace mozilla {
-
-namespace dom {
-class ArrayBufferViewOrArrayBuffer;
-}
-
-#ifndef EME_LOG
- LogModule* GetEMELog();
- #define EME_LOG(...) MOZ_LOG(GetEMELog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
- #define EME_LOG_ENABLED() MOZ_LOG_TEST(GetEMELog(), mozilla::LogLevel::Debug)
-#endif
-
-#ifndef EME_VERBOSE_LOG
- LogModule* GetEMEVerboseLog();
- #define EME_VERBOSE_LOG(...) MOZ_LOG(GetEMEVerboseLog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
-#else
- #ifndef EME_LOG
- #define EME_LOG(...)
- #endif
-
- #ifndef EME_VERBOSE_LOG
- #define EME_VERBOSE_LOG(...)
- #endif
-#endif
-
-// Helper function to extract a copy of data coming in from JS in an
-// (ArrayBuffer or ArrayBufferView) IDL typed function argument.
-//
-// Only call this on a properly initialized ArrayBufferViewOrArrayBuffer.
-void
-CopyArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aBufferOrView,
- nsTArray<uint8_t>& aOutData);
-
-// Overload for ArrayBuffer
-void CopyArrayBufferViewOrArrayBufferData(const dom::ArrayBuffer& aBufferOrView,
- nsTArray<uint8_t>& aOutData);
-
-struct ArrayData {
- explicit ArrayData(const uint8_t* aData, size_t aLength)
- : mData(aData)
- , mLength(aLength)
- {
- }
- const uint8_t* mData;
- const size_t mLength;
- bool IsValid() const {
- return mData != nullptr && mLength != 0;
- }
- bool operator== (const nsTArray<uint8_t>& aOther) const {
- return mLength == aOther.Length() &&
- memcmp(mData, aOther.Elements(), mLength) == 0;
- }
-};
-
-// Helper function to extract data coming in from JS in an
-// (ArrayBuffer or ArrayBufferView) IDL typed function argument.
-//
-// Be *very* careful with this!
-//
-// Only use returned ArrayData inside the lifetime of the
-// ArrayBufferViewOrArrayBuffer; the ArrayData struct does not contain
-// a copy of the data!
-//
-// And do *not* call out to anything that could call into JavaScript,
-// while the ArrayData is live, as then all bets about the data not changing
-// are off! No calls into JS, no calls into JS-implemented WebIDL or XPIDL,
-// nothing. Beware!
-//
-// Only call this on a properly initialized ArrayBufferViewOrArrayBuffer.
-ArrayData
-GetArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aBufferOrView);
-
-nsString
-KeySystemToGMPName(const nsAString& aKeySystem);
-
-bool
-IsClearkeyKeySystem(const nsAString& aKeySystem);
-
-bool
-IsWidevineKeySystem(const nsAString& aKeySystem);
-
-enum CDMType {
- eClearKey = 0,
- eWidevine = 2,
- eUnknown = 3
-};
-
-} // namespace mozilla
-
-#endif // EME_LOG_H_
diff --git a/dom/media/eme/MediaEncryptedEvent.cpp b/dom/media/eme/MediaEncryptedEvent.cpp
deleted file mode 100644
index a9c83291e9..0000000000
--- a/dom/media/eme/MediaEncryptedEvent.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "MediaEncryptedEvent.h"
-#include "mozilla/dom/MediaEncryptedEventBinding.h"
-#include "nsContentUtils.h"
-#include "jsfriendapi.h"
-#include "nsINode.h"
-#include "mozilla/dom/MediaKeys.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(MediaEncryptedEvent)
-
-NS_IMPL_ADDREF_INHERITED(MediaEncryptedEvent, Event)
-NS_IMPL_RELEASE_INHERITED(MediaEncryptedEvent, Event)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaEncryptedEvent, Event)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MediaEncryptedEvent, Event)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mInitData)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaEncryptedEvent, Event)
- tmp->mInitData = nullptr;
- mozilla::DropJSObjects(this);
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaEncryptedEvent)
-NS_INTERFACE_MAP_END_INHERITING(Event)
-
-MediaEncryptedEvent::MediaEncryptedEvent(EventTarget* aOwner)
- : Event(aOwner, nullptr, nullptr)
-{
- mozilla::HoldJSObjects(this);
-}
-
-MediaEncryptedEvent::~MediaEncryptedEvent()
-{
- mInitData = nullptr;
- mozilla::DropJSObjects(this);
-}
-
-JSObject*
-MediaEncryptedEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return MediaEncryptedEventBinding::Wrap(aCx, this, aGivenProto);
-}
-
-already_AddRefed<MediaEncryptedEvent>
-MediaEncryptedEvent::Constructor(EventTarget* aOwner)
-{
- RefPtr<MediaEncryptedEvent> e = new MediaEncryptedEvent(aOwner);
- e->InitEvent(NS_LITERAL_STRING("encrypted"), false, false);
- e->SetTrusted(true);
- return e.forget();
-}
-
-already_AddRefed<MediaEncryptedEvent>
-MediaEncryptedEvent::Constructor(EventTarget* aOwner,
- const nsAString& aInitDataType,
- const nsTArray<uint8_t>& aInitData)
-{
- RefPtr<MediaEncryptedEvent> e = new MediaEncryptedEvent(aOwner);
- e->InitEvent(NS_LITERAL_STRING("encrypted"), false, false);
- e->mInitDataType = aInitDataType;
- e->mRawInitData = aInitData;
- e->SetTrusted(true);
- return e.forget();
-}
-
-already_AddRefed<MediaEncryptedEvent>
-MediaEncryptedEvent::Constructor(const GlobalObject& aGlobal,
- const nsAString& aType,
- const MediaKeyNeededEventInit& aEventInitDict,
- ErrorResult& aRv)
-{
- nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
- RefPtr<MediaEncryptedEvent> e = new MediaEncryptedEvent(owner);
- bool trusted = e->Init(owner);
- e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
- e->mInitDataType = aEventInitDict.mInitDataType;
- if (!aEventInitDict.mInitData.IsNull()) {
- const auto& a = aEventInitDict.mInitData.Value();
- nsTArray<uint8_t> initData;
- CopyArrayBufferViewOrArrayBufferData(a, initData);
- e->mInitData = ArrayBuffer::Create(aGlobal.Context(), initData.Length(),
- initData.Elements());
- if (!e->mInitData) {
- aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
- }
- e->SetTrusted(trusted);
- return e.forget();
-}
-
-void
-MediaEncryptedEvent::GetInitDataType(nsString& aRetVal) const
-{
- aRetVal = mInitDataType;
-}
-
-void
-MediaEncryptedEvent::GetInitData(JSContext* cx,
- JS::MutableHandle<JSObject*> aData,
- ErrorResult& aRv)
-{
- if (mRawInitData.Length()) {
- mInitData = ArrayBuffer::Create(cx,
- this,
- mRawInitData.Length(),
- mRawInitData.Elements());
- if (!mInitData) {
- aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
- mRawInitData.Clear();
- }
- aData.set(mInitData);
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/MediaEncryptedEvent.h b/dom/media/eme/MediaEncryptedEvent.h
deleted file mode 100644
index c2ac560612..0000000000
--- a/dom/media/eme/MediaEncryptedEvent.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_MediaKeyNeededEvent_h__
-#define mozilla_dom_MediaKeyNeededEvent_h__
-
-#include "mozilla/dom/MediaEncryptedEventBinding.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsWrapperCache.h"
-#include "nsCOMPtr.h"
-#include "mozilla/dom/Event.h"
-#include "mozilla/dom/TypedArray.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "js/TypeDecls.h"
-
-namespace mozilla {
-namespace dom {
-
-class MediaEncryptedEvent final : public Event
-{
-public:
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MediaEncryptedEvent, Event)
-protected:
- virtual ~MediaEncryptedEvent();
- explicit MediaEncryptedEvent(EventTarget* aOwner);
-
- nsString mInitDataType;
- JS::Heap<JSObject*> mInitData;
-
-public:
-
- JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- static already_AddRefed<MediaEncryptedEvent>
- Constructor(EventTarget* aOwner);
-
- static already_AddRefed<MediaEncryptedEvent>
- Constructor(EventTarget* aOwner,
- const nsAString& aInitDataType,
- const nsTArray<uint8_t>& aInitData);
-
- static already_AddRefed<MediaEncryptedEvent>
- Constructor(const GlobalObject& aGlobal,
- const nsAString& aType,
- const MediaKeyNeededEventInit& aEventInitDict,
- ErrorResult& aRv);
-
- void GetInitDataType(nsString& aRetVal) const;
-
- void GetInitData(JSContext* cx,
- JS::MutableHandle<JSObject*> aData,
- ErrorResult& aRv);
-private:
- nsTArray<uint8_t> mRawInitData;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_MediaKeyNeededEvent_h__
diff --git a/dom/media/eme/MediaKeyError.cpp b/dom/media/eme/MediaKeyError.cpp
deleted file mode 100644
index 95e544fe76..0000000000
--- a/dom/media/eme/MediaKeyError.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "MediaKeyError.h"
-#include "mozilla/dom/MediaKeyErrorBinding.h"
-#include "nsContentUtils.h"
-
-namespace mozilla {
-namespace dom {
-
-MediaKeyError::MediaKeyError(EventTarget* aOwner, uint32_t aSystemCode)
- : Event(aOwner, nullptr, nullptr)
- , mSystemCode(aSystemCode)
-{
- InitEvent(NS_LITERAL_STRING("error"), false, false);
-}
-
-MediaKeyError::~MediaKeyError()
-{
-}
-
-uint32_t
-MediaKeyError::SystemCode() const
-{
- return mSystemCode;
-}
-
-JSObject*
-MediaKeyError::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return MediaKeyErrorBinding::Wrap(aCx, this, aGivenProto);
-}
-
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/MediaKeyError.h b/dom/media/eme/MediaKeyError.h
deleted file mode 100644
index b1e7aad3ee..0000000000
--- a/dom/media/eme/MediaKeyError.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_MediaKeyError_h
-#define mozilla_dom_MediaKeyError_h
-
-#include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
-#include "nsWrapperCache.h"
-#include "mozilla/dom/Event.h"
-#include "js/TypeDecls.h"
-
-namespace mozilla {
-namespace dom {
-
-class MediaKeyError final : public Event
-{
-public:
- NS_FORWARD_TO_EVENT
-
- MediaKeyError(EventTarget* aOwner, uint32_t aSystemCode);
- ~MediaKeyError();
-
- JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- uint32_t SystemCode() const;
-
-private:
- uint32_t mSystemCode;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/eme/MediaKeyMessageEvent.cpp b/dom/media/eme/MediaKeyMessageEvent.cpp
deleted file mode 100644
index ee13f8d26f..0000000000
--- a/dom/media/eme/MediaKeyMessageEvent.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/MediaKeyMessageEvent.h"
-#include "mozilla/dom/MediaKeyMessageEventBinding.h"
-#include "js/GCAPI.h"
-#include "jsfriendapi.h"
-#include "mozilla/dom/Nullable.h"
-#include "mozilla/dom/PrimitiveConversions.h"
-#include "mozilla/HoldDropJSObjects.h"
-#include "mozilla/dom/TypedArray.h"
-#include "nsContentUtils.h"
-#include "mozilla/dom/MediaKeys.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(MediaKeyMessageEvent)
-
-NS_IMPL_ADDREF_INHERITED(MediaKeyMessageEvent, Event)
-NS_IMPL_RELEASE_INHERITED(MediaKeyMessageEvent, Event)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaKeyMessageEvent, Event)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MediaKeyMessageEvent, Event)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMessage)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaKeyMessageEvent, Event)
- tmp->mMessage = nullptr;
- mozilla::DropJSObjects(this);
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaKeyMessageEvent)
-NS_INTERFACE_MAP_END_INHERITING(Event)
-
-MediaKeyMessageEvent::MediaKeyMessageEvent(EventTarget* aOwner)
- : Event(aOwner, nullptr, nullptr)
-{
- mozilla::HoldJSObjects(this);
-}
-
-MediaKeyMessageEvent::~MediaKeyMessageEvent()
-{
- mMessage = nullptr;
- mozilla::DropJSObjects(this);
-}
-
-MediaKeyMessageEvent*
-MediaKeyMessageEvent::AsMediaKeyMessageEvent()
-{
- return this;
-}
-
-JSObject*
-MediaKeyMessageEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return MediaKeyMessageEventBinding::Wrap(aCx, this, aGivenProto);
-}
-
-already_AddRefed<MediaKeyMessageEvent>
-MediaKeyMessageEvent::Constructor(EventTarget* aOwner,
- MediaKeyMessageType aMessageType,
- const nsTArray<uint8_t>& aMessage)
-{
- RefPtr<MediaKeyMessageEvent> e = new MediaKeyMessageEvent(aOwner);
- e->InitEvent(NS_LITERAL_STRING("message"), false, false);
- e->mMessageType = aMessageType;
- e->mRawMessage = aMessage;
- e->SetTrusted(true);
- return e.forget();
-}
-
-already_AddRefed<MediaKeyMessageEvent>
-MediaKeyMessageEvent::Constructor(const GlobalObject& aGlobal,
- const nsAString& aType,
- const MediaKeyMessageEventInit& aEventInitDict,
- ErrorResult& aRv)
-{
- nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
- RefPtr<MediaKeyMessageEvent> e = new MediaKeyMessageEvent(owner);
- bool trusted = e->Init(owner);
- e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
- nsTArray<uint8_t> initData;
- CopyArrayBufferViewOrArrayBufferData(aEventInitDict.mMessage, initData);
- e->mMessage = ArrayBuffer::Create(aGlobal.Context(),
- initData.Length(),
- initData.Elements());
- if (!e->mMessage) {
- aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
- e->mMessageType = aEventInitDict.mMessageType;
- e->SetTrusted(trusted);
- e->SetComposed(aEventInitDict.mComposed);
- return e.forget();
-}
-
-void
-MediaKeyMessageEvent::GetMessage(JSContext* cx,
- JS::MutableHandle<JSObject*> aMessage,
- ErrorResult& aRv)
-{
- if (!mMessage) {
- mMessage = ArrayBuffer::Create(cx,
- this,
- mRawMessage.Length(),
- mRawMessage.Elements());
- if (!mMessage) {
- aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
- mRawMessage.Clear();
- }
- aMessage.set(mMessage);
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/MediaKeyMessageEvent.h b/dom/media/eme/MediaKeyMessageEvent.h
deleted file mode 100644
index 2ec50f4f07..0000000000
--- a/dom/media/eme/MediaKeyMessageEvent.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_MediaKeyMessageEvent_h__
-#define mozilla_dom_MediaKeyMessageEvent_h__
-
-#include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsWrapperCache.h"
-#include "nsCOMPtr.h"
-#include "mozilla/dom/Event.h"
-#include "mozilla/dom/TypedArray.h"
-#include "js/TypeDecls.h"
-#include "mozilla/dom/MediaKeyMessageEventBinding.h"
-
-namespace mozilla {
-namespace dom {
-
-struct MediaKeyMessageEventInit;
-
-class MediaKeyMessageEvent final : public Event
-{
-public:
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MediaKeyMessageEvent, Event)
-protected:
- virtual ~MediaKeyMessageEvent();
- explicit MediaKeyMessageEvent(EventTarget* aOwner);
-
- MediaKeyMessageType mMessageType;
- JS::Heap<JSObject*> mMessage;
-
-public:
- virtual MediaKeyMessageEvent* AsMediaKeyMessageEvent();
-
- JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- static already_AddRefed<MediaKeyMessageEvent>
- Constructor(EventTarget* aOwner,
- MediaKeyMessageType aMessageType,
- const nsTArray<uint8_t>& aMessage);
-
- static already_AddRefed<MediaKeyMessageEvent>
- Constructor(const GlobalObject& aGlobal,
- const nsAString& aType,
- const MediaKeyMessageEventInit& aEventInitDict,
- ErrorResult& aRv);
-
- MediaKeyMessageType MessageType() const { return mMessageType; }
-
- void GetMessage(JSContext* cx,
- JS::MutableHandle<JSObject*> aMessage,
- ErrorResult& aRv);
-
-private:
- nsTArray<uint8_t> mRawMessage;
-};
-
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_MediaKeyMessageEvent_h__
diff --git a/dom/media/eme/MediaKeySession.cpp b/dom/media/eme/MediaKeySession.cpp
deleted file mode 100644
index b5f3fe498b..0000000000
--- a/dom/media/eme/MediaKeySession.cpp
+++ /dev/null
@@ -1,670 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/HTMLMediaElement.h"
-#include "mozilla/dom/MediaKeySession.h"
-#include "mozilla/dom/MediaKeyError.h"
-#include "mozilla/dom/MediaKeyMessageEvent.h"
-#include "mozilla/dom/MediaEncryptedEvent.h"
-#include "mozilla/dom/MediaKeyStatusMap.h"
-#include "mozilla/dom/MediaKeySystemAccess.h"
-#include "mozilla/dom/KeyIdsInitDataBinding.h"
-#include "nsCycleCollectionParticipant.h"
-#include "mozilla/CDMProxy.h"
-#include "mozilla/AsyncEventDispatcher.h"
-#include "mozilla/Move.h"
-#include "nsContentUtils.h"
-#include "mozilla/EMEUtils.h"
-#include "GMPUtils.h"
-#include "nsPrintfCString.h"
-#include "psshparser/PsshParser.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaKeySession,
- DOMEventTargetHelper,
- mMediaKeyError,
- mKeys,
- mKeyStatusMap,
- mClosed)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaKeySession)
-NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
-
-NS_IMPL_ADDREF_INHERITED(MediaKeySession, DOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(MediaKeySession, DOMEventTargetHelper)
-
-// Count of number of instances. Used to give each instance a
-// unique token.
-static uint32_t sMediaKeySessionNum = 0;
-
-// Max length of keyId in EME "keyIds" or WebM init data format, as enforced
-// by web platform tests.
-static const uint32_t MAX_KEY_ID_LENGTH = 512;
-
-// Max length of CENC PSSH init data tolerated, as enforced by web
-// platform tests.
-static const uint32_t MAX_CENC_INIT_DATA_LENGTH = 64 * 1024;
-
-
-MediaKeySession::MediaKeySession(JSContext* aCx,
- nsPIDOMWindowInner* aParent,
- MediaKeys* aKeys,
- const nsAString& aKeySystem,
- MediaKeySessionType aSessionType,
- ErrorResult& aRv)
- : DOMEventTargetHelper(aParent)
- , mKeys(aKeys)
- , mKeySystem(aKeySystem)
- , mSessionType(aSessionType)
- , mToken(sMediaKeySessionNum++)
- , mIsClosed(false)
- , mUninitialized(true)
- , mKeyStatusMap(new MediaKeyStatusMap(aParent))
- , mExpiration(JS::GenericNaN())
-{
- EME_LOG("MediaKeySession[%p,''] ctor", this);
-
- MOZ_ASSERT(aParent);
- if (aRv.Failed()) {
- return;
- }
- mClosed = MakePromise(aRv, NS_LITERAL_CSTRING("MediaKeys.createSession"));
-}
-
-void MediaKeySession::SetSessionId(const nsAString& aSessionId)
-{
- EME_LOG("MediaKeySession[%p,'%s'] session Id set",
- this, NS_ConvertUTF16toUTF8(aSessionId).get());
-
- if (NS_WARN_IF(!mSessionId.IsEmpty())) {
- return;
- }
- mSessionId = aSessionId;
- mKeys->OnSessionIdReady(this);
-}
-
-MediaKeySession::~MediaKeySession()
-{
-}
-
-MediaKeyError*
-MediaKeySession::GetError() const
-{
- return mMediaKeyError;
-}
-
-void
-MediaKeySession::GetKeySystem(nsString& aOutKeySystem) const
-{
- aOutKeySystem.Assign(mKeySystem);
-}
-
-void
-MediaKeySession::GetSessionId(nsString& aSessionId) const
-{
- aSessionId = GetSessionId();
-}
-
-const nsString&
-MediaKeySession::GetSessionId() const
-{
- return mSessionId;
-}
-
-JSObject*
-MediaKeySession::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return MediaKeySessionBinding::Wrap(aCx, this, aGivenProto);
-}
-
-double
-MediaKeySession::Expiration() const
-{
- return mExpiration;
-}
-
-Promise*
-MediaKeySession::Closed() const
-{
- return mClosed;
-}
-
-void
-MediaKeySession::UpdateKeyStatusMap()
-{
- MOZ_ASSERT(!IsClosed());
- if (!mKeys->GetCDMProxy()) {
- return;
- }
-
- nsTArray<CDMCaps::KeyStatus> keyStatuses;
- {
- CDMCaps::AutoLock caps(mKeys->GetCDMProxy()->Capabilites());
- caps.GetKeyStatusesForSession(mSessionId, keyStatuses);
- }
-
- mKeyStatusMap->Update(keyStatuses);
-
- if (EME_LOG_ENABLED()) {
- nsAutoCString message(
- nsPrintfCString("MediaKeySession[%p,'%s'] key statuses change {",
- this, NS_ConvertUTF16toUTF8(mSessionId).get()));
- using IntegerType = typename std::underlying_type<MediaKeyStatus>::type;
- for (const CDMCaps::KeyStatus& status : keyStatuses) {
- message.Append(nsPrintfCString(" (%s,%s)", ToBase64(status.mId).get(),
- MediaKeyStatusValues::strings[static_cast<IntegerType>(status.mStatus)].value));
- }
- message.Append(" }");
- EME_LOG(message.get());
- }
-}
-
-MediaKeyStatusMap*
-MediaKeySession::KeyStatuses() const
-{
- return mKeyStatusMap;
-}
-
-// The user agent MUST thoroughly validate the Initialization Data before
-// passing it to the CDM. This includes verifying that the length and
-// values of fields are reasonable, verifying that values are within
-// reasonable limits, and stripping irrelevant, unsupported, or unknown
-// data or fields. It is RECOMMENDED that user agents pre-parse, sanitize,
-// and/or generate a fully sanitized version of the Initialization Data.
-// If the Initialization Data format specified by initDataType supports
-// multiple entries, the user agent SHOULD remove entries that are not
-// needed by the CDM. The user agent MUST NOT re-order entries within
-// the Initialization Data.
-static bool
-ValidateInitData(const nsTArray<uint8_t>& aInitData, const nsAString& aInitDataType)
-{
- if (aInitDataType.LowerCaseEqualsLiteral("webm")) {
- // WebM initData consists of a single keyId. Ensure it's of reasonable length.
- return aInitData.Length() <= MAX_KEY_ID_LENGTH;
- } else if (aInitDataType.LowerCaseEqualsLiteral("cenc")) {
- // Limit initData to less than 64KB.
- if (aInitData.Length() > MAX_CENC_INIT_DATA_LENGTH) {
- return false;
- }
- std::vector<std::vector<uint8_t>> keyIds;
- return ParseCENCInitData(aInitData.Elements(), aInitData.Length(), keyIds);
- } else if (aInitDataType.LowerCaseEqualsLiteral("keyids")) {
- if (aInitData.Length() > MAX_KEY_ID_LENGTH) {
- return false;
- }
- // Ensure that init data matches the expected JSON format.
- mozilla::dom::KeyIdsInitData keyIds;
- nsString json;
- nsDependentCSubstring raw(reinterpret_cast<const char*>(aInitData.Elements()), aInitData.Length());
- if (NS_FAILED(nsContentUtils::ConvertStringFromEncoding(NS_LITERAL_CSTRING("UTF-8"), raw, json))) {
- return false;
- }
- if (!keyIds.Init(json)) {
- return false;
- }
- if (keyIds.mKids.Length() == 0) {
- return false;
- }
- for (const auto& kid : keyIds.mKids) {
- if (kid.IsEmpty()) {
- return false;
- }
- }
- }
- return true;
-}
-
-// Generates a license request based on the initData. A message of type
-// "license-request" or "individualization-request" will always be queued
-// if the algorithm succeeds and the promise is resolved.
-already_AddRefed<Promise>
-MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
- const ArrayBufferViewOrArrayBuffer& aInitData,
- ErrorResult& aRv)
-{
- RefPtr<DetailedPromise> promise(MakePromise(aRv,
- NS_LITERAL_CSTRING("MediaKeySession.generateRequest")));
- if (aRv.Failed()) {
- return nullptr;
- }
-
- // If this object is closed, return a promise rejected with an InvalidStateError.
- if (IsClosed()) {
- EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, closed",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Session is closed in MediaKeySession.generateRequest()"));
- return promise.forget();
- }
-
- // If this object's uninitialized value is false, return a promise rejected
- // with an InvalidStateError.
- if (!mUninitialized) {
- EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, uninitialized",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Session is already initialized in MediaKeySession.generateRequest()"));
- return promise.forget();
- }
-
- // Let this object's uninitialized value be false.
- mUninitialized = false;
-
- // If initDataType is the empty string, return a promise rejected
- // with a newly created TypeError.
- if (aInitDataType.IsEmpty()) {
- promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("Empty initDataType passed to MediaKeySession.generateRequest()"));
- EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initDataType",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- return promise.forget();
- }
-
- // If initData is an empty array, return a promise rejected with
- // a newly created TypeError.
- nsTArray<uint8_t> data;
- CopyArrayBufferViewOrArrayBufferData(aInitData, data);
- if (data.IsEmpty()) {
- promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("Empty initData passed to MediaKeySession.generateRequest()"));
- EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initData",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- return promise.forget();
- }
-
- // If the Key System implementation represented by this object's
- // cdm implementation value does not support initDataType as an
- // Initialization Data Type, return a promise rejected with a
- // NotSupportedError. String comparison is case-sensitive.
- if (!MediaKeySystemAccess::KeySystemSupportsInitDataType(mKeySystem, aInitDataType)) {
- promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
- NS_LITERAL_CSTRING("Unsupported initDataType passed to MediaKeySession.generateRequest()"));
- EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, unsupported initDataType",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- return promise.forget();
- }
-
- // Let init data be a copy of the contents of the initData parameter.
- // Note: Handled by the CopyArrayBufferViewOrArrayBufferData call above.
-
- // Let session type be this object's session type.
-
- // Let promise be a new promise.
-
- // Run the following steps in parallel:
-
- // If the init data is not valid for initDataType, reject promise with
- // a newly created TypeError.
- if (!ValidateInitData(data, aInitDataType)) {
- // If the preceding step failed, reject promise with a newly created TypeError.
- promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("initData sanitization failed in MediaKeySession.generateRequest()"));
- EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() initData sanitization failed",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- return promise.forget();
- }
-
- // Let sanitized init data be a validated and sanitized version of init data.
-
- // If sanitized init data is empty, reject promise with a NotSupportedError.
-
- // Note: Remaining steps of generateRequest method continue in CDM.
-
- // Convert initData to base64 for easier logging.
- // Note: CreateSession() Move()s the data out of the array, so we have
- // to copy it here.
- nsAutoCString base64InitData(ToBase64(data));
- PromiseId pid = mKeys->StorePromise(promise);
- mKeys->ConnectPendingPromiseIdWithToken(pid, Token());
- mKeys->GetCDMProxy()->CreateSession(Token(),
- mSessionType,
- pid,
- aInitDataType, data);
-
- EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() sent, "
- "promiseId=%d initData(base64)='%s' initDataType='%s'",
- this,
- NS_ConvertUTF16toUTF8(mSessionId).get(),
- pid,
- base64InitData.get(),
- NS_ConvertUTF16toUTF8(aInitDataType).get());
-
- return promise.forget();
-}
-
-already_AddRefed<Promise>
-MediaKeySession::Load(const nsAString& aSessionId, ErrorResult& aRv)
-{
- RefPtr<DetailedPromise> promise(MakePromise(aRv,
- NS_LITERAL_CSTRING("MediaKeySession.load")));
- if (aRv.Failed()) {
- return nullptr;
- }
-
- // 1. If this object is closed, return a promise rejected with an InvalidStateError.
- if (IsClosed()) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Session is closed in MediaKeySession.load()"));
- EME_LOG("MediaKeySession[%p,'%s'] Load() failed, closed",
- this, NS_ConvertUTF16toUTF8(aSessionId).get());
- return promise.forget();
- }
-
- // 2.If this object's uninitialized value is false, return a promise rejected
- // with an InvalidStateError.
- if (!mUninitialized) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Session is already initialized in MediaKeySession.load()"));
- EME_LOG("MediaKeySession[%p,'%s'] Load() failed, uninitialized",
- this, NS_ConvertUTF16toUTF8(aSessionId).get());
- return promise.forget();
- }
-
- // 3.Let this object's uninitialized value be false.
- mUninitialized = false;
-
- // 4. If sessionId is the empty string, return a promise rejected with a newly created TypeError.
- if (aSessionId.IsEmpty()) {
- promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("Trying to load a session with empty session ID"));
- // "The sessionId parameter is empty."
- EME_LOG("MediaKeySession[%p,''] Load() failed, no sessionId", this);
- return promise.forget();
- }
-
- // 5. If the result of running the Is persistent session type? algorithm
- // on this object's session type is false, return a promise rejected with
- // a newly created TypeError.
- if (mSessionType == MediaKeySessionType::Temporary) {
- promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("Trying to load() into a non-persistent session"));
- EME_LOG("MediaKeySession[%p,''] Load() failed, can't load in a non-persistent session", this);
- return promise.forget();
- }
-
- // Note: We don't support persistent sessions in any keysystem, so all calls
- // to Load() should reject with a TypeError in the preceding check. Omitting
- // implementing the rest of the specified MediaKeySession::Load() algorithm.
-
- // We now know the sessionId being loaded into this session. Remove the
- // session from its owning MediaKey's set of sessions awaiting a sessionId.
- RefPtr<MediaKeySession> session(mKeys->GetPendingSession(Token()));
- MOZ_ASSERT(session == this, "Session should be awaiting id on its own token");
-
- // Associate with the known sessionId.
- SetSessionId(aSessionId);
-
- PromiseId pid = mKeys->StorePromise(promise);
- mKeys->GetCDMProxy()->LoadSession(pid, aSessionId);
-
- EME_LOG("MediaKeySession[%p,'%s'] Load() sent to CDM, promiseId=%d",
- this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid);
-
- return promise.forget();
-}
-
-already_AddRefed<Promise>
-MediaKeySession::Update(const ArrayBufferViewOrArrayBuffer& aResponse, ErrorResult& aRv)
-{
- RefPtr<DetailedPromise> promise(MakePromise(aRv,
- NS_LITERAL_CSTRING("MediaKeySession.update")));
- if (aRv.Failed()) {
- return nullptr;
- }
-
- if (!IsCallable()) {
- // If this object's callable value is false, return a promise rejected
- // with a new DOMException whose name is InvalidStateError.
- EME_LOG("MediaKeySession[%p,''] Update() called before sessionId set by CDM", this);
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("MediaKeySession.Update() called before sessionId set by CDM"));
- return promise.forget();
- }
-
- nsTArray<uint8_t> data;
- if (IsClosed() || !mKeys->GetCDMProxy()) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Session is closed or was not properly initialized"));
- EME_LOG("MediaKeySession[%p,'%s'] Update() failed, session is closed or was not properly initialised.",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- return promise.forget();
- }
- CopyArrayBufferViewOrArrayBufferData(aResponse, data);
- if (data.IsEmpty()) {
- promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("Empty response buffer passed to MediaKeySession.update()"));
- EME_LOG("MediaKeySession[%p,'%s'] Update() failed, empty response buffer",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- return promise.forget();
- }
-
-
- // Convert response to base64 for easier logging.
- // Note: UpdateSession() Move()s the data out of the array, so we have
- // to copy it here.
- nsAutoCString base64Response(ToBase64(data));
-
- PromiseId pid = mKeys->StorePromise(promise);
- mKeys->GetCDMProxy()->UpdateSession(mSessionId,
- pid,
- data);
-
- EME_LOG("MediaKeySession[%p,'%s'] Update() sent to CDM, "
- "promiseId=%d Response(base64)='%s'",
- this,
- NS_ConvertUTF16toUTF8(mSessionId).get(),
- pid,
- base64Response.get());
-
- return promise.forget();
-}
-
-already_AddRefed<Promise>
-MediaKeySession::Close(ErrorResult& aRv)
-{
- RefPtr<DetailedPromise> promise(MakePromise(aRv,
- NS_LITERAL_CSTRING("MediaKeySession.close")));
- if (aRv.Failed()) {
- return nullptr;
- }
- // 1. Let session be the associated MediaKeySession object.
- // 2. If session is closed, return a resolved promise.
- if (IsClosed()) {
- EME_LOG("MediaKeySession[%p,'%s'] Close() already closed",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- promise->MaybeResolveWithUndefined();
- return promise.forget();
- }
- // 3. If session's callable value is false, return a promise rejected
- // with an InvalidStateError.
- if (!IsCallable()) {
- EME_LOG("MediaKeySession[%p,''] Close() called before sessionId set by CDM", this);
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("MediaKeySession.Close() called before sessionId set by CDM"));
- return promise.forget();
- }
- if (!mKeys->GetCDMProxy()) {
- EME_LOG("MediaKeySession[%p,'%s'] Close() null CDMProxy",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("MediaKeySession.Close() lost reference to CDM"));
- return promise.forget();
- }
- // 4. Let promise be a new promise.
- PromiseId pid = mKeys->StorePromise(promise);
- // 5. Run the following steps in parallel:
- // 5.1 Let cdm be the CDM instance represented by session's cdm instance value.
- // 5.2 Use cdm to close the session associated with session.
- mKeys->GetCDMProxy()->CloseSession(mSessionId, pid);
-
- EME_LOG("MediaKeySession[%p,'%s'] Close() sent to CDM, promiseId=%d",
- this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid);
-
- // Session Closed algorithm is run when CDM causes us to run OnSessionClosed().
-
- // 6. Return promise.
- return promise.forget();
-}
-
-void
-MediaKeySession::OnClosed()
-{
- if (IsClosed()) {
- return;
- }
- EME_LOG("MediaKeySession[%p,'%s'] session close operation complete.",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- mIsClosed = true;
- mKeys->OnSessionClosed(this);
- mKeys = nullptr;
- mClosed->MaybeResolveWithUndefined();
-}
-
-bool
-MediaKeySession::IsClosed() const
-{
- return mIsClosed;
-}
-
-already_AddRefed<Promise>
-MediaKeySession::Remove(ErrorResult& aRv)
-{
- RefPtr<DetailedPromise> promise(MakePromise(aRv,
- NS_LITERAL_CSTRING("MediaKeySession.remove")));
- if (aRv.Failed()) {
- return nullptr;
- }
- if (!IsCallable()) {
- // If this object's callable value is false, return a promise rejected
- // with a new DOMException whose name is InvalidStateError.
- EME_LOG("MediaKeySession[%p,''] Remove() called before sessionId set by CDM", this);
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("MediaKeySession.Remove() called before sessionId set by CDM"));
- return promise.forget();
- }
- if (mSessionType != MediaKeySessionType::Persistent_license) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
- NS_LITERAL_CSTRING("Calling MediaKeySession.remove() on non-persistent session"));
- // "The operation is not supported on session type sessions."
- EME_LOG("MediaKeySession[%p,'%s'] Remove() failed, sesion not persisrtent.",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- return promise.forget();
- }
- if (IsClosed() || !mKeys->GetCDMProxy()) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("MediaKeySesison.remove() called but session is not active"));
- // "The session is closed."
- EME_LOG("MediaKeySession[%p,'%s'] Remove() failed, already session closed.",
- this, NS_ConvertUTF16toUTF8(mSessionId).get());
- return promise.forget();
- }
- PromiseId pid = mKeys->StorePromise(promise);
- mKeys->GetCDMProxy()->RemoveSession(mSessionId, pid);
- EME_LOG("MediaKeySession[%p,'%s'] Remove() sent to CDM, promiseId=%d.",
- this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid);
-
- return promise.forget();
-}
-
-void
-MediaKeySession::DispatchKeyMessage(MediaKeyMessageType aMessageType,
- const nsTArray<uint8_t>& aMessage)
-{
- if (EME_LOG_ENABLED()) {
- EME_LOG("MediaKeySession[%p,'%s'] DispatchKeyMessage() type=%s message(base64)='%s'",
- this, NS_ConvertUTF16toUTF8(mSessionId).get(),
- MediaKeyMessageTypeValues::strings[uint32_t(aMessageType)].value,
- ToBase64(aMessage).get());
- }
-
- RefPtr<MediaKeyMessageEvent> event(
- MediaKeyMessageEvent::Constructor(this, aMessageType, aMessage));
- RefPtr<AsyncEventDispatcher> asyncDispatcher =
- new AsyncEventDispatcher(this, event);
- asyncDispatcher->PostDOMEvent();
-}
-
-void
-MediaKeySession::DispatchKeyError(uint32_t aSystemCode)
-{
- EME_LOG("MediaKeySession[%p,'%s'] DispatchKeyError() systemCode=%u.",
- this, NS_ConvertUTF16toUTF8(mSessionId).get(), aSystemCode);
-
- RefPtr<MediaKeyError> event(new MediaKeyError(this, aSystemCode));
- RefPtr<AsyncEventDispatcher> asyncDispatcher =
- new AsyncEventDispatcher(this, event);
- asyncDispatcher->PostDOMEvent();
-}
-
-void
-MediaKeySession::DispatchKeyStatusesChange()
-{
- if (IsClosed()) {
- return;
- }
-
- UpdateKeyStatusMap();
-
- RefPtr<AsyncEventDispatcher> asyncDispatcher =
- new AsyncEventDispatcher(this, NS_LITERAL_STRING("keystatuseschange"), false);
- asyncDispatcher->PostDOMEvent();
-}
-
-uint32_t
-MediaKeySession::Token() const
-{
- return mToken;
-}
-
-already_AddRefed<DetailedPromise>
-MediaKeySession::MakePromise(ErrorResult& aRv, const nsACString& aName)
-{
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
- if (!global) {
- NS_WARNING("Passed non-global to MediaKeys ctor!");
- aRv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
- return DetailedPromise::Create(global, aRv, aName);
-}
-
-void
-MediaKeySession::SetExpiration(double aExpiration)
-{
- EME_LOG("MediaKeySession[%p,'%s'] SetExpiry(%lf)",
- this,
- NS_ConvertUTF16toUTF8(mSessionId).get(),
- aExpiration);
- mExpiration = aExpiration;
-}
-
-EventHandlerNonNull*
-MediaKeySession::GetOnkeystatuseschange()
-{
- return GetEventHandler(nsGkAtoms::onkeystatuseschange, EmptyString());
-}
-
-void
-MediaKeySession::SetOnkeystatuseschange(EventHandlerNonNull* aCallback)
-{
- SetEventHandler(nsGkAtoms::onkeystatuseschange, EmptyString(), aCallback);
-}
-
-EventHandlerNonNull*
-MediaKeySession::GetOnmessage()
-{
- return GetEventHandler(nsGkAtoms::onmessage, EmptyString());
-}
-
-void
-MediaKeySession::SetOnmessage(EventHandlerNonNull* aCallback)
-{
- SetEventHandler(nsGkAtoms::onmessage, EmptyString(), aCallback);
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/MediaKeySession.h b/dom/media/eme/MediaKeySession.h
deleted file mode 100644
index 6b71370469..0000000000
--- a/dom/media/eme/MediaKeySession.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_MediaKeySession_h
-#define mozilla_dom_MediaKeySession_h
-
-#include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
-#include "nsCycleCollectionParticipant.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "nsCOMPtr.h"
-#include "mozilla/dom/TypedArray.h"
-#include "mozilla/Mutex.h"
-#include "mozilla/dom/Date.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/DetailedPromise.h"
-#include "mozilla/dom/MediaKeySessionBinding.h"
-#include "mozilla/dom/MediaKeysBinding.h"
-#include "mozilla/dom/MediaKeyMessageEventBinding.h"
-
-struct JSContext;
-
-namespace mozilla {
-namespace dom {
-
-class ArrayBufferViewOrArrayBuffer;
-class MediaKeyError;
-class MediaKeyStatusMap;
-
-class MediaKeySession final : public DOMEventTargetHelper
-{
-public:
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaKeySession,
- DOMEventTargetHelper)
-public:
- MediaKeySession(JSContext* aCx,
- nsPIDOMWindowInner* aParent,
- MediaKeys* aKeys,
- const nsAString& aKeySystem,
- MediaKeySessionType aSessionType,
- ErrorResult& aRv);
-
- void SetSessionId(const nsAString& aSessionId);
-
- JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- // Mark this as resultNotAddRefed to return raw pointers
- MediaKeyError* GetError() const;
-
- MediaKeyStatusMap* KeyStatuses() const;
-
- void GetKeySystem(nsString& aRetval) const;
-
- void GetSessionId(nsString& aRetval) const;
-
- const nsString& GetSessionId() const;
-
- // Number of ms since epoch at which expiration occurs, or NaN if unknown.
- // TODO: The type of this attribute is still under contention.
- // https://www.w3.org/Bugs/Public/show_bug.cgi?id=25902
- double Expiration() const;
-
- Promise* Closed() const;
-
- already_AddRefed<Promise> GenerateRequest(const nsAString& aInitDataType,
- const ArrayBufferViewOrArrayBuffer& aInitData,
- ErrorResult& aRv);
-
- already_AddRefed<Promise> Load(const nsAString& aSessionId,
- ErrorResult& aRv);
-
- already_AddRefed<Promise> Update(const ArrayBufferViewOrArrayBuffer& response,
- ErrorResult& aRv);
-
- already_AddRefed<Promise> Close(ErrorResult& aRv);
-
- already_AddRefed<Promise> Remove(ErrorResult& aRv);
-
- void DispatchKeyMessage(MediaKeyMessageType aMessageType,
- const nsTArray<uint8_t>& aMessage);
-
- void DispatchKeyError(uint32_t system_code);
-
- void DispatchKeyStatusesChange();
-
- void OnClosed();
-
- bool IsClosed() const;
-
- void SetExpiration(double aExpiry);
-
- mozilla::dom::EventHandlerNonNull* GetOnkeystatuseschange();
- void SetOnkeystatuseschange(mozilla::dom::EventHandlerNonNull* aCallback);
-
- mozilla::dom::EventHandlerNonNull* GetOnmessage();
- void SetOnmessage(mozilla::dom::EventHandlerNonNull* aCallback);
-
- // Process-unique identifier.
- uint32_t Token() const;
-
-private:
- ~MediaKeySession();
-
- void UpdateKeyStatusMap();
-
- bool IsCallable() const {
- // The EME spec sets the "callable value" to true whenever the CDM sets
- // the sessionId. When the session is initialized, sessionId is empty and
- // callable is thus false.
- return !mSessionId.IsEmpty();
- }
-
- already_AddRefed<DetailedPromise> MakePromise(ErrorResult& aRv,
- const nsACString& aName);
-
- RefPtr<DetailedPromise> mClosed;
-
- RefPtr<MediaKeyError> mMediaKeyError;
- RefPtr<MediaKeys> mKeys;
- const nsString mKeySystem;
- nsString mSessionId;
- const MediaKeySessionType mSessionType;
- const uint32_t mToken;
- bool mIsClosed;
- bool mUninitialized;
- RefPtr<MediaKeyStatusMap> mKeyStatusMap;
- double mExpiration;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/eme/MediaKeyStatusMap.cpp b/dom/media/eme/MediaKeyStatusMap.cpp
deleted file mode 100644
index 677fd0db2e..0000000000
--- a/dom/media/eme/MediaKeyStatusMap.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/MediaKeyStatusMap.h"
-#include "nsPIDOMWindow.h"
-#include "mozilla/dom/UnionTypes.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "mozilla/EMEUtils.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeyStatusMap)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeyStatusMap)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaKeyStatusMap)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MediaKeyStatusMap, mParent)
-
-MediaKeyStatusMap::MediaKeyStatusMap(nsPIDOMWindowInner* aParent)
- : mParent(aParent)
-{
-}
-
-MediaKeyStatusMap::~MediaKeyStatusMap()
-{
-}
-
-JSObject*
-MediaKeyStatusMap::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return MediaKeyStatusMapBinding::Wrap(aCx, this, aGivenProto);
-}
-
-nsPIDOMWindowInner*
-MediaKeyStatusMap::GetParentObject() const
-{
- return mParent;
-}
-
-void
-MediaKeyStatusMap::Get(JSContext* aCx,
- const ArrayBufferViewOrArrayBuffer& aKey,
- JS::MutableHandle<JS::Value> aOutValue,
- ErrorResult& aOutRv) const
-{
- ArrayData keyId = GetArrayBufferViewOrArrayBufferData(aKey);
- if (!keyId.IsValid()) {
- aOutValue.setUndefined();
- return;
- }
- for (const KeyStatus& status : mStatuses) {
- if (keyId == status.mKeyId) {
- bool ok = ToJSValue(aCx, status.mStatus, aOutValue);
- if (!ok) {
- aOutRv.NoteJSContextException(aCx);
- }
- return;
- }
- }
- aOutValue.setUndefined();
-}
-
-bool
-MediaKeyStatusMap::Has(const ArrayBufferViewOrArrayBuffer& aKey) const
-{
- ArrayData keyId = GetArrayBufferViewOrArrayBufferData(aKey);
- if (!keyId.IsValid()) {
- return false;
- }
-
- for (const KeyStatus& status : mStatuses) {
- if (keyId == status.mKeyId) {
- return true;
- }
- }
-
- return false;
-}
-
-uint32_t
-MediaKeyStatusMap::GetIterableLength() const
-{
- return mStatuses.Length();
-}
-
-TypedArrayCreator<ArrayBuffer>
-MediaKeyStatusMap::GetKeyAtIndex(uint32_t aIndex) const
-{
- MOZ_ASSERT(aIndex < GetIterableLength());
- return TypedArrayCreator<ArrayBuffer>(mStatuses[aIndex].mKeyId);
-}
-
-MediaKeyStatus
-MediaKeyStatusMap::GetValueAtIndex(uint32_t aIndex) const
-{
- MOZ_ASSERT(aIndex < GetIterableLength());
- return mStatuses[aIndex].mStatus;
-}
-
-uint32_t
-MediaKeyStatusMap::Size() const
-{
- return mStatuses.Length();
-}
-
-void
-MediaKeyStatusMap::Update(const nsTArray<CDMCaps::KeyStatus>& aKeys)
-{
- mStatuses.Clear();
- for (const auto& key : aKeys) {
- mStatuses.InsertElementSorted(KeyStatus(key.mId, key.mStatus));
- }
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/MediaKeyStatusMap.h b/dom/media/eme/MediaKeyStatusMap.h
deleted file mode 100644
index 8bfbd4d07c..0000000000
--- a/dom/media/eme/MediaKeyStatusMap.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_MediaKeyStatuses_h
-#define mozilla_dom_MediaKeyStatuses_h
-
-#include "mozilla/ErrorResult.h"
-#include "mozilla/Attributes.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsWrapperCache.h"
-
-#include "mozilla/dom/TypedArray.h"
-#include "mozilla/dom/MediaKeyStatusMapBinding.h"
-#include "mozilla/CDMCaps.h"
-
-class nsPIDOMWindowInner;
-
-namespace mozilla {
-namespace dom {
-
-class ArrayBufferViewOrArrayBuffer;
-
-// The MediaKeyStatusMap WebIDL interface; maps a keyId to its status.
-// Note that the underlying "map" is stored in an array, since we assume
-// that a MediaKeySession won't have many key statuses to report.
-class MediaKeyStatusMap final : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaKeyStatusMap)
-
-public:
- explicit MediaKeyStatusMap(nsPIDOMWindowInner* aParent);
-
-protected:
- ~MediaKeyStatusMap();
-
-public:
- nsPIDOMWindowInner* GetParentObject() const;
-
- JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- void Get(JSContext* aCx,
- const ArrayBufferViewOrArrayBuffer& aKey,
- JS::MutableHandle<JS::Value> aOutValue,
- ErrorResult& aOutRv) const;
- bool Has(const ArrayBufferViewOrArrayBuffer& aKey) const;
- uint32_t Size() const;
-
- uint32_t GetIterableLength() const;
- TypedArrayCreator<ArrayBuffer> GetKeyAtIndex(uint32_t aIndex) const;
- MediaKeyStatus GetValueAtIndex(uint32_t aIndex) const;
-
- void Update(const nsTArray<CDMCaps::KeyStatus>& keys);
-
-private:
-
- nsCOMPtr<nsPIDOMWindowInner> mParent;
-
- struct KeyStatus {
- KeyStatus(const nsTArray<uint8_t>& aKeyId,
- MediaKeyStatus aStatus)
- : mKeyId(aKeyId)
- , mStatus(aStatus)
- {
- }
- bool operator== (const KeyStatus& aOther) const {
- return aOther.mKeyId == mKeyId;
- }
- bool operator<(const KeyStatus& aOther) const {
- // Copy chromium and compare keys' bytes.
- // Update once https://github.com/w3c/encrypted-media/issues/69
- // is resolved.
- const nsTArray<uint8_t>& other = aOther.mKeyId;
- const nsTArray<uint8_t>& self = mKeyId;
- size_t length = std::min<size_t>(other.Length(), self.Length());
- int cmp = memcmp(self.Elements(), other.Elements(), length);
- if (cmp != 0) {
- return cmp < 0;
- }
- return self.Length() <= other.Length();
- }
- nsTArray<uint8_t> mKeyId;
- MediaKeyStatus mStatus;
- };
-
- nsTArray<KeyStatus> mStatuses;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/eme/MediaKeySystemAccess.cpp b/dom/media/eme/MediaKeySystemAccess.cpp
deleted file mode 100644
index 3c594f9191..0000000000
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ /dev/null
@@ -1,1041 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/MediaKeySystemAccess.h"
-#include "mozilla/dom/MediaKeySystemAccessBinding.h"
-#include "mozilla/Preferences.h"
-#include "MediaPrefs.h"
-#include "nsContentTypeParser.h"
-#ifdef MOZ_FMP4
-#include "MP4Decoder.h"
-#endif
-#ifdef XP_WIN
-#include "mozilla/WindowsVersion.h"
-#include "WMFDecoderModule.h"
-#endif
-#include "nsContentCID.h"
-#include "nsServiceManagerUtils.h"
-#include "mozIGeckoMediaPluginService.h"
-#include "VideoUtils.h"
-#include "mozilla/Services.h"
-#include "nsIObserverService.h"
-#include "mozilla/EMEUtils.h"
-#include "GMPUtils.h"
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsDirectoryServiceUtils.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsXULAppAPI.h"
-#include "gmp-audio-decode.h"
-#include "gmp-video-decode.h"
-#include "DecoderDoctorDiagnostics.h"
-#include "WebMDecoder.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/ClearOnShutdown.h"
-#include "nsUnicharUtils.h"
-#include "mozilla/dom/MediaSource.h"
-#include "DecoderTraits.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MediaKeySystemAccess,
- mParent)
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeySystemAccess)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeySystemAccess)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaKeySystemAccess)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-MediaKeySystemAccess::MediaKeySystemAccess(nsPIDOMWindowInner* aParent,
- const nsAString& aKeySystem,
- const MediaKeySystemConfiguration& aConfig)
- : mParent(aParent)
- , mKeySystem(aKeySystem)
- , mConfig(aConfig)
-{
-}
-
-MediaKeySystemAccess::~MediaKeySystemAccess()
-{
-}
-
-JSObject*
-MediaKeySystemAccess::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return MediaKeySystemAccessBinding::Wrap(aCx, this, aGivenProto);
-}
-
-nsPIDOMWindowInner*
-MediaKeySystemAccess::GetParentObject() const
-{
- return mParent;
-}
-
-void
-MediaKeySystemAccess::GetKeySystem(nsString& aOutKeySystem) const
-{
- aOutKeySystem.Assign(mKeySystem);
-}
-
-void
-MediaKeySystemAccess::GetConfiguration(MediaKeySystemConfiguration& aConfig)
-{
- aConfig = mConfig;
-}
-
-already_AddRefed<Promise>
-MediaKeySystemAccess::CreateMediaKeys(ErrorResult& aRv)
-{
- RefPtr<MediaKeys> keys(new MediaKeys(mParent,
- mKeySystem,
- mConfig));
- return keys->Init(aRv);
-}
-
-static bool
-HavePluginForKeySystem(const nsCString& aKeySystem)
-{
- bool havePlugin = HaveGMPFor(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
- { aKeySystem });
- return havePlugin;
-}
-
-static MediaKeySystemStatus
-EnsureCDMInstalled(const nsAString& aKeySystem,
- nsACString& aOutMessage)
-{
- if (!HavePluginForKeySystem(NS_ConvertUTF16toUTF8(aKeySystem))) {
- aOutMessage = NS_LITERAL_CSTRING("CDM is not installed");
- return MediaKeySystemStatus::Cdm_not_installed;
- }
-
- return MediaKeySystemStatus::Available;
-}
-
-/* static */
-MediaKeySystemStatus
-MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
- nsACString& aOutMessage)
-{
- MOZ_ASSERT(MediaPrefs::EMEEnabled() || IsClearkeyKeySystem(aKeySystem));
-
- if (IsClearkeyKeySystem(aKeySystem)) {
- return EnsureCDMInstalled(aKeySystem, aOutMessage);
- }
-
- if (IsWidevineKeySystem(aKeySystem)) {
- if (Preferences::GetBool("media.gmp-widevinecdm.visible", false)) {
- if (!Preferences::GetBool("media.gmp-widevinecdm.enabled", false)) {
- aOutMessage = NS_LITERAL_CSTRING("Widevine EME disabled");
- return MediaKeySystemStatus::Cdm_disabled;
- }
- return EnsureCDMInstalled(aKeySystem, aOutMessage);
- }
- }
-
- return MediaKeySystemStatus::Cdm_not_supported;
-}
-
-typedef nsCString EMECodecString;
-
-static NS_NAMED_LITERAL_CSTRING(EME_CODEC_AAC, "aac");
-static NS_NAMED_LITERAL_CSTRING(EME_CODEC_OPUS, "opus");
-static NS_NAMED_LITERAL_CSTRING(EME_CODEC_VORBIS, "vorbis");
-static NS_NAMED_LITERAL_CSTRING(EME_CODEC_H264, "h264");
-static NS_NAMED_LITERAL_CSTRING(EME_CODEC_VP8, "vp8");
-static NS_NAMED_LITERAL_CSTRING(EME_CODEC_VP9, "vp9");
-
-EMECodecString
-ToEMEAPICodecString(const nsString& aCodec)
-{
- if (IsAACCodecString(aCodec)) {
- return EME_CODEC_AAC;
- }
- if (aCodec.EqualsLiteral("opus")) {
- return EME_CODEC_OPUS;
- }
- if (aCodec.EqualsLiteral("vorbis")) {
- return EME_CODEC_VORBIS;
- }
- if (IsH264CodecString(aCodec)) {
- return EME_CODEC_H264;
- }
- if (IsVP8CodecString(aCodec)) {
- return EME_CODEC_VP8;
- }
- if (IsVP9CodecString(aCodec)) {
- return EME_CODEC_VP9;
- }
- return EmptyCString();
-}
-
-// A codec can be decrypted-and-decoded by the CDM, or only decrypted
-// by the CDM and decoded by Gecko. Not both.
-struct KeySystemContainerSupport
-{
- bool IsSupported() const
- {
- return !mCodecsDecoded.IsEmpty() || !mCodecsDecrypted.IsEmpty();
- }
-
- // CDM decrypts and decodes using a DRM robust decoder, and passes decoded
- // samples back to Gecko for rendering.
- bool DecryptsAndDecodes(EMECodecString aCodec) const
- {
- return mCodecsDecoded.Contains(aCodec);
- }
-
- // CDM decrypts and passes the decrypted samples back to Gecko for decoding.
- bool Decrypts(EMECodecString aCodec) const
- {
- return mCodecsDecrypted.Contains(aCodec);
- }
-
- void SetCanDecryptAndDecode(EMECodecString aCodec)
- {
- // Can't both decrypt and decrypt-and-decode a codec.
- MOZ_ASSERT(!Decrypts(aCodec));
- // Prevent duplicates.
- MOZ_ASSERT(!DecryptsAndDecodes(aCodec));
- mCodecsDecoded.AppendElement(aCodec);
- }
-
- void SetCanDecrypt(EMECodecString aCodec)
- {
- // Prevent duplicates.
- MOZ_ASSERT(!Decrypts(aCodec));
- // Can't both decrypt and decrypt-and-decode a codec.
- MOZ_ASSERT(!DecryptsAndDecodes(aCodec));
- mCodecsDecrypted.AppendElement(aCodec);
- }
-
-private:
- nsTArray<EMECodecString> mCodecsDecoded;
- nsTArray<EMECodecString> mCodecsDecrypted;
-};
-
-enum class KeySystemFeatureSupport
-{
- Prohibited = 1,
- Requestable = 2,
- Required = 3,
-};
-
-struct KeySystemConfig
-{
- nsString mKeySystem;
- nsTArray<nsString> mInitDataTypes;
- KeySystemFeatureSupport mPersistentState = KeySystemFeatureSupport::Prohibited;
- KeySystemFeatureSupport mDistinctiveIdentifier = KeySystemFeatureSupport::Prohibited;
- nsTArray<MediaKeySessionType> mSessionTypes;
- nsTArray<nsString> mVideoRobustness;
- nsTArray<nsString> mAudioRobustness;
- KeySystemContainerSupport mMP4;
- KeySystemContainerSupport mWebM;
-};
-
-static nsTArray<KeySystemConfig>
-GetSupportedKeySystems()
-{
- nsTArray<KeySystemConfig> keySystemConfigs;
-
- {
- if (HavePluginForKeySystem(kEMEKeySystemClearkey)) {
- KeySystemConfig clearkey;
- clearkey.mKeySystem = NS_ConvertUTF8toUTF16(kEMEKeySystemClearkey);
- clearkey.mInitDataTypes.AppendElement(NS_LITERAL_STRING("cenc"));
- clearkey.mInitDataTypes.AppendElement(NS_LITERAL_STRING("keyids"));
- clearkey.mInitDataTypes.AppendElement(NS_LITERAL_STRING("webm"));
- clearkey.mPersistentState = KeySystemFeatureSupport::Requestable;
- clearkey.mDistinctiveIdentifier = KeySystemFeatureSupport::Prohibited;
- clearkey.mSessionTypes.AppendElement(MediaKeySessionType::Temporary);
- if (MediaPrefs::ClearKeyPersistentLicenseEnabled()) {
- clearkey.mSessionTypes.AppendElement(MediaKeySessionType::Persistent_license);
- }
-#if defined(XP_WIN)
- // Clearkey CDM uses WMF decoders on Windows.
- if (WMFDecoderModule::HasAAC()) {
- clearkey.mMP4.SetCanDecryptAndDecode(EME_CODEC_AAC);
- } else {
- clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC);
- }
- if (WMFDecoderModule::HasH264()) {
- clearkey.mMP4.SetCanDecryptAndDecode(EME_CODEC_H264);
- } else {
- clearkey.mMP4.SetCanDecrypt(EME_CODEC_H264);
- }
-#else
- clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC);
- clearkey.mMP4.SetCanDecrypt(EME_CODEC_H264);
-#endif
- clearkey.mWebM.SetCanDecrypt(EME_CODEC_VORBIS);
- clearkey.mWebM.SetCanDecrypt(EME_CODEC_OPUS);
- clearkey.mWebM.SetCanDecrypt(EME_CODEC_VP8);
- clearkey.mWebM.SetCanDecrypt(EME_CODEC_VP9);
- keySystemConfigs.AppendElement(Move(clearkey));
- }
- }
- {
- if (HavePluginForKeySystem(kEMEKeySystemWidevine)) {
- KeySystemConfig widevine;
- widevine.mKeySystem = NS_ConvertUTF8toUTF16(kEMEKeySystemWidevine);
- widevine.mInitDataTypes.AppendElement(NS_LITERAL_STRING("cenc"));
- widevine.mInitDataTypes.AppendElement(NS_LITERAL_STRING("keyids"));
- widevine.mInitDataTypes.AppendElement(NS_LITERAL_STRING("webm"));
- widevine.mPersistentState = KeySystemFeatureSupport::Requestable;
- widevine.mDistinctiveIdentifier = KeySystemFeatureSupport::Prohibited;
- widevine.mSessionTypes.AppendElement(MediaKeySessionType::Temporary);
- widevine.mAudioRobustness.AppendElement(NS_LITERAL_STRING("SW_SECURE_CRYPTO"));
- widevine.mVideoRobustness.AppendElement(NS_LITERAL_STRING("SW_SECURE_DECODE"));
-#if defined(XP_WIN)
- // Widevine CDM doesn't include an AAC decoder. So if WMF can't
- // decode AAC, and a codec wasn't specified, be conservative
- // and reject the MediaKeys request, since our policy is to prevent
- // the Adobe GMP's unencrypted AAC decoding path being used to
- // decode content decrypted by the Widevine CDM.
- if (WMFDecoderModule::HasAAC()) {
- widevine.mMP4.SetCanDecrypt(EME_CODEC_AAC);
- }
-#endif
-
- widevine.mMP4.SetCanDecryptAndDecode(EME_CODEC_H264);
- widevine.mWebM.SetCanDecrypt(EME_CODEC_VORBIS);
- widevine.mWebM.SetCanDecrypt(EME_CODEC_OPUS);
- widevine.mWebM.SetCanDecryptAndDecode(EME_CODEC_VP8);
- widevine.mWebM.SetCanDecryptAndDecode(EME_CODEC_VP9);
- keySystemConfigs.AppendElement(Move(widevine));
- }
- }
-
- return keySystemConfigs;
-}
-
-static bool
-GetKeySystemConfig(const nsAString& aKeySystem, KeySystemConfig& aOutKeySystemConfig)
-{
- for (auto&& config : GetSupportedKeySystems()) {
- if (config.mKeySystem.Equals(aKeySystem)) {
- aOutKeySystemConfig = mozilla::Move(config);
- return true;
- }
- }
- // No matching key system found.
- return false;
-}
-
-/* static */
-bool
-MediaKeySystemAccess::KeySystemSupportsInitDataType(const nsAString& aKeySystem,
- const nsAString& aInitDataType)
-{
- KeySystemConfig implementation;
- return GetKeySystemConfig(aKeySystem, implementation) &&
- implementation.mInitDataTypes.Contains(aInitDataType);
-}
-
-enum CodecType
-{
- Audio,
- Video,
- Invalid
-};
-
-static bool
-CanDecryptAndDecode(const nsString& aKeySystem,
- const nsString& aContentType,
- CodecType aCodecType,
- const KeySystemContainerSupport& aContainerSupport,
- const nsTArray<EMECodecString>& aCodecs,
- DecoderDoctorDiagnostics* aDiagnostics)
-{
- MOZ_ASSERT(aCodecType != Invalid);
- for (const EMECodecString& codec : aCodecs) {
- MOZ_ASSERT(!codec.IsEmpty());
-
- if (aContainerSupport.DecryptsAndDecodes(codec)) {
- // GMP can decrypt-and-decode this codec.
- continue;
- }
-
- if (aContainerSupport.Decrypts(codec) &&
- NS_SUCCEEDED(MediaSource::IsTypeSupported(aContentType, aDiagnostics))) {
- // GMP can decrypt and is allowed to return compressed samples to
- // Gecko to decode, and Gecko has a decoder.
- continue;
- }
-
- // Neither the GMP nor Gecko can both decrypt and decode. We don't
- // support this codec.
-
-#if defined(XP_WIN)
- // Widevine CDM doesn't include an AAC decoder. So if WMF can't
- // decode AAC, and a codec wasn't specified, be conservative
- // and reject the MediaKeys request, since our policy is to prevent
- // the Adobe GMP's unencrypted AAC decoding path being used to
- // decode content decrypted by the Widevine CDM.
- if (codec == EME_CODEC_AAC &&
- IsWidevineKeySystem(aKeySystem) &&
- !WMFDecoderModule::HasAAC()) {
- if (aDiagnostics) {
- aDiagnostics->SetKeySystemIssue(
- DecoderDoctorDiagnostics::eWidevineWithNoWMF);
- }
- }
-#endif
- return false;
- }
- return true;
-}
-
-static bool
-ToSessionType(const nsAString& aSessionType, MediaKeySessionType& aOutType)
-{
- using MediaKeySessionTypeValues::strings;
- const char* temporary =
- strings[static_cast<uint32_t>(MediaKeySessionType::Temporary)].value;
- if (aSessionType.EqualsASCII(temporary)) {
- aOutType = MediaKeySessionType::Temporary;
- return true;
- }
- const char* persistentLicense =
- strings[static_cast<uint32_t>(MediaKeySessionType::Persistent_license)].value;
- if (aSessionType.EqualsASCII(persistentLicense)) {
- aOutType = MediaKeySessionType::Persistent_license;
- return true;
- }
- return false;
-}
-
-// 5.2.1 Is persistent session type?
-static bool
-IsPersistentSessionType(MediaKeySessionType aSessionType)
-{
- return aSessionType == MediaKeySessionType::Persistent_license;
-}
-
-CodecType
-GetMajorType(const nsAString& aContentType)
-{
- if (CaseInsensitiveFindInReadable(NS_LITERAL_STRING("audio/"), aContentType)) {
- return Audio;
- }
- if (CaseInsensitiveFindInReadable(NS_LITERAL_STRING("video/"), aContentType)) {
- return Video;
- }
- return Invalid;
-}
-
-static CodecType
-GetCodecType(const EMECodecString& aCodec)
-{
- if (aCodec.Equals(EME_CODEC_AAC) ||
- aCodec.Equals(EME_CODEC_OPUS) ||
- aCodec.Equals(EME_CODEC_VORBIS)) {
- return Audio;
- }
- if (aCodec.Equals(EME_CODEC_H264) ||
- aCodec.Equals(EME_CODEC_VP8) ||
- aCodec.Equals(EME_CODEC_VP9)) {
- return Video;
- }
- return Invalid;
-}
-
-static bool
-AllCodecsOfType(const nsTArray<EMECodecString>& aCodecs, const CodecType aCodecType)
-{
- for (const EMECodecString& codec : aCodecs) {
- if (GetCodecType(codec) != aCodecType) {
- return false;
- }
- }
- return true;
-}
-
-static bool
-IsParameterUnrecognized(const nsAString& aContentType)
-{
- nsAutoString contentType(aContentType);
- contentType.StripWhitespace();
-
- nsTArray<nsString> params;
- nsAString::const_iterator start, end, semicolon, equalSign;
- contentType.BeginReading(start);
- contentType.EndReading(end);
- semicolon = start;
- // Find any substring between ';' & '='.
- while (semicolon != end) {
- if (FindCharInReadable(';', semicolon, end)) {
- equalSign = ++semicolon;
- if (FindCharInReadable('=', equalSign, end)) {
- params.AppendElement(Substring(semicolon, equalSign));
- semicolon = equalSign;
- }
- }
- }
-
- for (auto param : params) {
- if (!param.LowerCaseEqualsLiteral("codecs") &&
- !param.LowerCaseEqualsLiteral("profiles")) {
- return true;
- }
- }
- return false;
-}
-
-// 3.1.2.3 Get Supported Capabilities for Audio/Video Type
-static Sequence<MediaKeySystemMediaCapability>
-GetSupportedCapabilities(const CodecType aCodecType,
- const nsTArray<MediaKeySystemMediaCapability>& aRequestedCapabilities,
- const MediaKeySystemConfiguration& aPartialConfig,
- const KeySystemConfig& aKeySystem,
- DecoderDoctorDiagnostics* aDiagnostics)
-{
- // Let local accumulated configuration be a local copy of partial configuration.
- // (Note: It's not necessary for us to maintain a local copy, as we don't need
- // to test whether capabilites from previous calls to this algorithm work with
- // the capabilities currently being considered in this call. )
-
- // Let supported media capabilities be an empty sequence of
- // MediaKeySystemMediaCapability dictionaries.
- Sequence<MediaKeySystemMediaCapability> supportedCapabilities;
-
- // For each requested media capability in requested media capabilities:
- for (const MediaKeySystemMediaCapability& capabilities : aRequestedCapabilities) {
- // Let content type be requested media capability's contentType member.
- const nsString& contentType = capabilities.mContentType;
- // Let robustness be requested media capability's robustness member.
- const nsString& robustness = capabilities.mRobustness;
- // If content type is the empty string, return null.
- if (contentType.IsEmpty()) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') rejected; "
- "audio or video capability has empty contentType.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- return Sequence<MediaKeySystemMediaCapability>();
- }
- // If content type is an invalid or unrecognized MIME type, continue
- // to the next iteration.
- nsAutoString container;
- nsTArray<nsString> codecStrings;
- if (!ParseMIMETypeString(contentType, container, codecStrings)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "failed to parse contentType as MIME type.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
- bool invalid = false;
- nsTArray<EMECodecString> codecs;
- for (const nsString& codecString : codecStrings) {
- EMECodecString emeCodec = ToEMEAPICodecString(codecString);
- if (emeCodec.IsEmpty()) {
- invalid = true;
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "'%s' is an invalid codec string.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get(),
- NS_ConvertUTF16toUTF8(codecString).get());
- break;
- }
- codecs.AppendElement(emeCodec);
- }
- if (invalid) {
- continue;
- }
-
- // If the user agent does not support container, continue to the next iteration.
- // The case-sensitivity of string comparisons is determined by the appropriate RFC.
- // (Note: Per RFC 6838 [RFC6838], "Both top-level type and subtype names are
- // case-insensitive."'. We're using nsContentTypeParser and that is
- // case-insensitive and converts all its parameter outputs to lower case.)
- NS_ConvertUTF16toUTF8 container_utf8(container);
- const bool isMP4 = DecoderTraits::IsMP4TypeAndEnabled(container_utf8, aDiagnostics);
- if (isMP4 && !aKeySystem.mMP4.IsSupported()) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "MP4 requested but unsupported.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
- const bool isWebM = DecoderTraits::IsWebMTypeAndEnabled(container_utf8);
- if (isWebM && !aKeySystem.mWebM.IsSupported()) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "WebM requested but unsupported.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
- if (!isMP4 && !isWebM) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "Unsupported or unrecognized container requested.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
-
- // Let parameters be the RFC 6381[RFC6381] parameters, if any, specified by
- // content type.
- // If the user agent does not recognize one or more parameters, continue to
- // the next iteration.
- if (IsParameterUnrecognized(contentType)) {
- continue;
- }
-
- // Let media types be the set of codecs and codec constraints specified by
- // parameters. The case-sensitivity of string comparisons is determined by
- // the appropriate RFC or other specification.
- // (Note: codecs array is 'parameter').
-
- // If media types is empty:
- if (codecs.IsEmpty()) {
- // If container normatively implies a specific set of codecs and codec constraints:
- // Let parameters be that set.
- if (isMP4) {
- if (aCodecType == Audio) {
- codecs.AppendElement(EME_CODEC_AAC);
- } else if (aCodecType == Video) {
- codecs.AppendElement(EME_CODEC_H264);
- }
- } else if (isWebM) {
- if (aCodecType == Audio) {
- codecs.AppendElement(EME_CODEC_VORBIS);
- } else if (aCodecType == Video) {
- codecs.AppendElement(EME_CODEC_VP8);
- }
- }
- // Otherwise: Continue to the next iteration.
- // (Note: all containers we support have implied codecs, so don't continue here.)
- }
-
- // If content type is not strictly a audio/video type, continue to the next iteration.
- const auto majorType = GetMajorType(container);
- if (majorType == Invalid) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "MIME type is not an audio or video MIME type.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
- if (majorType != aCodecType || !AllCodecsOfType(codecs, aCodecType)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "MIME type mixes audio codecs in video capabilities "
- "or video codecs in audio capabilities.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
- // If robustness is not the empty string and contains an unrecognized
- // value or a value not supported by implementation, continue to the
- // next iteration. String comparison is case-sensitive.
- if (!robustness.IsEmpty()) {
- if (majorType == Audio && !aKeySystem.mAudioRobustness.Contains(robustness)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "unsupported robustness string.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
- if (majorType == Video && !aKeySystem.mVideoRobustness.Contains(robustness)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "unsupported robustness string.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
- // Note: specified robustness requirements are satisfied.
- }
-
- // If the user agent and implementation definitely support playback of
- // encrypted media data for the combination of container, media types,
- // robustness and local accumulated configuration in combination with
- // restrictions...
- const auto& containerSupport = isMP4 ? aKeySystem.mMP4 : aKeySystem.mWebM;
- if (!CanDecryptAndDecode(aKeySystem.mKeySystem,
- contentType,
- majorType,
- containerSupport,
- codecs,
- aDiagnostics)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') "
- "MediaKeySystemMediaCapability('%s','%s') unsupported; "
- "codec unsupported by CDM requested.",
- NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
- NS_ConvertUTF16toUTF8(contentType).get(),
- NS_ConvertUTF16toUTF8(robustness).get());
- continue;
- }
-
- // ... add requested media capability to supported media capabilities.
- if (!supportedCapabilities.AppendElement(capabilities, mozilla::fallible)) {
- NS_WARNING("GetSupportedCapabilities: Malloc failure");
- return Sequence<MediaKeySystemMediaCapability>();
- }
-
- // Note: omitting steps 3.13.2, our robustness is not sophisticated enough
- // to require considering all requirements together.
- }
- return Move(supportedCapabilities);
-}
-
-// "Get Supported Configuration and Consent" algorithm, steps 4-7 for
-// distinctive identifier, and steps 8-11 for persistent state. The steps
-// are the same for both requirements/features, so we factor them out into
-// a single function.
-static bool
-CheckRequirement(const MediaKeysRequirement aRequirement,
- const KeySystemFeatureSupport aFeatureSupport,
- MediaKeysRequirement& aOutRequirement)
-{
- // Let requirement be the value of candidate configuration's member.
- MediaKeysRequirement requirement = aRequirement;
- // If requirement is "optional" and feature is not allowed according to
- // restrictions, set requirement to "not-allowed".
- if (aRequirement == MediaKeysRequirement::Optional &&
- aFeatureSupport == KeySystemFeatureSupport::Prohibited) {
- requirement = MediaKeysRequirement::Not_allowed;
- }
-
- // Follow the steps for requirement from the following list:
- switch (requirement) {
- case MediaKeysRequirement::Required: {
- // If the implementation does not support use of requirement in combination
- // with accumulated configuration and restrictions, return NotSupported.
- if (aFeatureSupport == KeySystemFeatureSupport::Prohibited) {
- return false;
- }
- break;
- }
- case MediaKeysRequirement::Optional: {
- // Continue with the following steps.
- break;
- }
- case MediaKeysRequirement::Not_allowed: {
- // If the implementation requires use of feature in combination with
- // accumulated configuration and restrictions, return NotSupported.
- if (aFeatureSupport == KeySystemFeatureSupport::Required) {
- return false;
- }
- break;
- }
- default: {
- return false;
- }
- }
-
- // Set the requirement member of accumulated configuration to equal
- // calculated requirement.
- aOutRequirement = requirement;
-
- return true;
-}
-
-// 3.1.2.2, step 12
-// Follow the steps for the first matching condition from the following list:
-// If the sessionTypes member is present in candidate configuration.
-// Let session types be candidate configuration's sessionTypes member.
-// Otherwise let session types be ["temporary"].
-// Note: This returns an empty array on malloc failure.
-static Sequence<nsString>
-UnboxSessionTypes(const Optional<Sequence<nsString>>& aSessionTypes)
-{
- Sequence<nsString> sessionTypes;
- if (aSessionTypes.WasPassed()) {
- sessionTypes = aSessionTypes.Value();
- } else {
- using MediaKeySessionTypeValues::strings;
- const char* temporary = strings[static_cast<uint32_t>(MediaKeySessionType::Temporary)].value;
- // Note: fallible. Results in an empty array.
- sessionTypes.AppendElement(NS_ConvertUTF8toUTF16(nsDependentCString(temporary)), mozilla::fallible);
- }
- return sessionTypes;
-}
-
-// 3.1.2.2 Get Supported Configuration and Consent
-static bool
-GetSupportedConfig(const KeySystemConfig& aKeySystem,
- const MediaKeySystemConfiguration& aCandidate,
- MediaKeySystemConfiguration& aOutConfig,
- DecoderDoctorDiagnostics* aDiagnostics)
-{
- // Let accumulated configuration be a new MediaKeySystemConfiguration dictionary.
- MediaKeySystemConfiguration config;
- // Set the label member of accumulated configuration to equal the label member of
- // candidate configuration.
- config.mLabel = aCandidate.mLabel;
- // If the initDataTypes member of candidate configuration is non-empty, run the
- // following steps:
- if (!aCandidate.mInitDataTypes.IsEmpty()) {
- // Let supported types be an empty sequence of DOMStrings.
- nsTArray<nsString> supportedTypes;
- // For each value in candidate configuration's initDataTypes member:
- for (const nsString& initDataType : aCandidate.mInitDataTypes) {
- // Let initDataType be the value.
- // If the implementation supports generating requests based on initDataType,
- // add initDataType to supported types. String comparison is case-sensitive.
- // The empty string is never supported.
- if (aKeySystem.mInitDataTypes.Contains(initDataType)) {
- supportedTypes.AppendElement(initDataType);
- }
- }
- // If supported types is empty, return NotSupported.
- if (supportedTypes.IsEmpty()) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "no supported initDataTypes provided.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
- return false;
- }
- // Set the initDataTypes member of accumulated configuration to supported types.
- if (!config.mInitDataTypes.Assign(supportedTypes)) {
- return false;
- }
- }
-
- if (!CheckRequirement(aCandidate.mDistinctiveIdentifier,
- aKeySystem.mDistinctiveIdentifier,
- config.mDistinctiveIdentifier)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "distinctiveIdentifier requirement not satisfied.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
- return false;
- }
-
- if (!CheckRequirement(aCandidate.mPersistentState,
- aKeySystem.mPersistentState,
- config.mPersistentState)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "persistentState requirement not satisfied.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
- return false;
- }
-
- Sequence<nsString> sessionTypes(UnboxSessionTypes(aCandidate.mSessionTypes));
- if (sessionTypes.IsEmpty()) {
- // Malloc failure.
- return false;
- }
-
- // For each value in session types:
- for (const auto& sessionTypeString : sessionTypes) {
- // Let session type be the value.
- MediaKeySessionType sessionType;
- if (!ToSessionType(sessionTypeString, sessionType)) {
- // (Assume invalid sessionType is unsupported as per steps below).
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "invalid session type specified.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
- return false;
- }
- // If accumulated configuration's persistentState value is "not-allowed"
- // and the Is persistent session type? algorithm returns true for session
- // type return NotSupported.
- if (config.mPersistentState == MediaKeysRequirement::Not_allowed &&
- IsPersistentSessionType(sessionType)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "persistent session requested but keysystem doesn't"
- "support persistent state.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
- return false;
- }
- // If the implementation does not support session type in combination
- // with accumulated configuration and restrictions for other reasons,
- // return NotSupported.
- if (!aKeySystem.mSessionTypes.Contains(sessionType)) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "session type '%s' unsupported by keySystem.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get(),
- NS_ConvertUTF16toUTF8(sessionTypeString).get());
- return false;
- }
- // If accumulated configuration's persistentState value is "optional"
- // and the result of running the Is persistent session type? algorithm
- // on session type is true, change accumulated configuration's
- // persistentState value to "required".
- if (config.mPersistentState == MediaKeysRequirement::Optional &&
- IsPersistentSessionType(sessionType)) {
- config.mPersistentState = MediaKeysRequirement::Required;
- }
- }
- // Set the sessionTypes member of accumulated configuration to session types.
- config.mSessionTypes.Construct(Move(sessionTypes));
-
- // If the videoCapabilities and audioCapabilities members in candidate
- // configuration are both empty, return NotSupported.
- // TODO: Most sites using EME still don't pass capabilities, so we
- // can't reject on it yet without breaking them. So add this later.
-
- // If the videoCapabilities member in candidate configuration is non-empty:
- if (!aCandidate.mVideoCapabilities.IsEmpty()) {
- // Let video capabilities be the result of executing the Get Supported
- // Capabilities for Audio/Video Type algorithm on Video, candidate
- // configuration's videoCapabilities member, accumulated configuration,
- // and restrictions.
- Sequence<MediaKeySystemMediaCapability> caps =
- GetSupportedCapabilities(Video,
- aCandidate.mVideoCapabilities,
- config,
- aKeySystem,
- aDiagnostics);
- // If video capabilities is null, return NotSupported.
- if (caps.IsEmpty()) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "no supported video capabilities.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
- return false;
- }
- // Set the videoCapabilities member of accumulated configuration to video capabilities.
- config.mVideoCapabilities = Move(caps);
- } else {
- // Otherwise:
- // Set the videoCapabilities member of accumulated configuration to an empty sequence.
- }
-
- // If the audioCapabilities member in candidate configuration is non-empty:
- if (!aCandidate.mAudioCapabilities.IsEmpty()) {
- // Let audio capabilities be the result of executing the Get Supported Capabilities
- // for Audio/Video Type algorithm on Audio, candidate configuration's audioCapabilities
- // member, accumulated configuration, and restrictions.
- Sequence<MediaKeySystemMediaCapability> caps =
- GetSupportedCapabilities(Audio,
- aCandidate.mAudioCapabilities,
- config,
- aKeySystem,
- aDiagnostics);
- // If audio capabilities is null, return NotSupported.
- if (caps.IsEmpty()) {
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "no supported audio capabilities.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
- return false;
- }
- // Set the audioCapabilities member of accumulated configuration to audio capabilities.
- config.mAudioCapabilities = Move(caps);
- } else {
- // Otherwise:
- // Set the audioCapabilities member of accumulated configuration to an empty sequence.
- }
-
- // If accumulated configuration's distinctiveIdentifier value is "optional", follow the
- // steps for the first matching condition from the following list:
- if (config.mDistinctiveIdentifier == MediaKeysRequirement::Optional) {
- // If the implementation requires use Distinctive Identifier(s) or
- // Distinctive Permanent Identifier(s) for any of the combinations
- // in accumulated configuration
- if (aKeySystem.mDistinctiveIdentifier == KeySystemFeatureSupport::Required) {
- // Change accumulated configuration's distinctiveIdentifier value to "required".
- config.mDistinctiveIdentifier = MediaKeysRequirement::Required;
- } else {
- // Otherwise, change accumulated configuration's distinctiveIdentifier
- // value to "not-allowed".
- config.mDistinctiveIdentifier = MediaKeysRequirement::Not_allowed;
- }
- }
-
- // If accumulated configuration's persistentState value is "optional", follow the
- // steps for the first matching condition from the following list:
- if (config.mPersistentState == MediaKeysRequirement::Optional) {
- // If the implementation requires persisting state for any of the combinations
- // in accumulated configuration
- if (aKeySystem.mPersistentState == KeySystemFeatureSupport::Required) {
- // Change accumulated configuration's persistentState value to "required".
- config.mPersistentState = MediaKeysRequirement::Required;
- } else {
- // Otherwise, change accumulated configuration's persistentState
- // value to "not-allowed".
- config.mPersistentState = MediaKeysRequirement::Not_allowed;
- }
- }
-
- // Note: Omitting steps 20-22. We don't ask for consent.
-
-#if defined(XP_WIN)
- // Widevine CDM doesn't include an AAC decoder. So if WMF can't decode AAC,
- // and a codec wasn't specified, be conservative and reject the MediaKeys request.
- if (IsWidevineKeySystem(aKeySystem.mKeySystem) &&
- (aCandidate.mAudioCapabilities.IsEmpty() ||
- aCandidate.mVideoCapabilities.IsEmpty()) &&
- !WMFDecoderModule::HasAAC()) {
- if (aDiagnostics) {
- aDiagnostics->SetKeySystemIssue(
- DecoderDoctorDiagnostics::eWidevineWithNoWMF);
- }
- EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
- "WMF required for Widevine decoding, but it's not available.",
- NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
- return false;
- }
-#endif
-
- // Return accumulated configuration.
- aOutConfig = config;
-
- return true;
-}
-
-/* static */
-bool
-MediaKeySystemAccess::GetSupportedConfig(const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs,
- MediaKeySystemConfiguration& aOutConfig,
- DecoderDoctorDiagnostics* aDiagnostics)
-{
- KeySystemConfig implementation;
- if (!GetKeySystemConfig(aKeySystem, implementation)) {
- return false;
- }
- for (const MediaKeySystemConfiguration& candidate : aConfigs) {
- if (mozilla::dom::GetSupportedConfig(implementation,
- candidate,
- aOutConfig,
- aDiagnostics)) {
- return true;
- }
- }
-
- return false;
-}
-
-
-/* static */
-void
-MediaKeySystemAccess::NotifyObservers(nsPIDOMWindowInner* aWindow,
- const nsAString& aKeySystem,
- MediaKeySystemStatus aStatus)
-{
- RequestMediaKeySystemAccessNotification data;
- data.mKeySystem = aKeySystem;
- data.mStatus = aStatus;
- nsAutoString json;
- data.ToJSON(json);
- EME_LOG("MediaKeySystemAccess::NotifyObservers() %s", NS_ConvertUTF16toUTF8(json).get());
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- if (obs) {
- obs->NotifyObservers(aWindow, "mediakeys-request", json.get());
- }
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/MediaKeySystemAccess.h b/dom/media/eme/MediaKeySystemAccess.h
deleted file mode 100644
index c260e92b5c..0000000000
--- a/dom/media/eme/MediaKeySystemAccess.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_MediaKeySystemAccess_h
-#define mozilla_dom_MediaKeySystemAccess_h
-
-#include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsWrapperCache.h"
-
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/MediaKeySystemAccessBinding.h"
-#include "mozilla/dom/MediaKeysRequestStatusBinding.h"
-
-#include "js/TypeDecls.h"
-
-namespace mozilla {
-
-class DecoderDoctorDiagnostics;
-
-namespace dom {
-
-class MediaKeySystemAccess final : public nsISupports,
- public nsWrapperCache
-{
-public:
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaKeySystemAccess)
-
-public:
- explicit MediaKeySystemAccess(nsPIDOMWindowInner* aParent,
- const nsAString& aKeySystem,
- const MediaKeySystemConfiguration& aConfig);
-
-protected:
- ~MediaKeySystemAccess();
-
-public:
- nsPIDOMWindowInner* GetParentObject() const;
-
- JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- void GetKeySystem(nsString& aRetVal) const;
-
- void GetConfiguration(MediaKeySystemConfiguration& aConfig);
-
- already_AddRefed<Promise> CreateMediaKeys(ErrorResult& aRv);
-
- static MediaKeySystemStatus GetKeySystemStatus(const nsAString& aKeySystem,
- nsACString& aOutExceptionMessage);
-
- static bool IsSupported(const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs,
- DecoderDoctorDiagnostics* aDiagnostics);
-
- static void NotifyObservers(nsPIDOMWindowInner* aWindow,
- const nsAString& aKeySystem,
- MediaKeySystemStatus aStatus);
-
- static bool GetSupportedConfig(const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs,
- MediaKeySystemConfiguration& aOutConfig,
- DecoderDoctorDiagnostics* aDiagnostics);
-
- static bool KeySystemSupportsInitDataType(const nsAString& aKeySystem,
- const nsAString& aInitDataType);
-
-private:
- nsCOMPtr<nsPIDOMWindowInner> mParent;
- const nsString mKeySystem;
- const MediaKeySystemConfiguration mConfig;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_MediaKeySystemAccess_h
diff --git a/dom/media/eme/MediaKeySystemAccessManager.cpp b/dom/media/eme/MediaKeySystemAccessManager.cpp
deleted file mode 100644
index ed31059e22..0000000000
--- a/dom/media/eme/MediaKeySystemAccessManager.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this
-* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "MediaKeySystemAccessManager.h"
-#include "DecoderDoctorDiagnostics.h"
-#include "MediaPrefs.h"
-#include "mozilla/EMEUtils.h"
-#include "nsServiceManagerUtils.h"
-#include "nsComponentManagerUtils.h"
-#include "nsIObserverService.h"
-#include "mozilla/Services.h"
-#include "mozilla/DetailedPromise.h"
-#ifdef XP_WIN
-#include "mozilla/WindowsVersion.h"
-#endif
-#ifdef XP_MACOSX
-#include "nsCocoaFeatures.h"
-#endif
-#include "nsPrintfCString.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaKeySystemAccessManager)
- NS_INTERFACE_MAP_ENTRY(nsISupports)
- NS_INTERFACE_MAP_ENTRY(nsIObserver)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeySystemAccessManager)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeySystemAccessManager)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(MediaKeySystemAccessManager)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MediaKeySystemAccessManager)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
- for (size_t i = 0; i < tmp->mRequests.Length(); i++) {
- tmp->mRequests[i].RejectPromise(NS_LITERAL_CSTRING("Promise still outstanding at MediaKeySystemAccessManager GC"));
- tmp->mRequests[i].CancelTimer();
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mRequests[i].mPromise)
- }
- tmp->mRequests.Clear();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MediaKeySystemAccessManager)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
- for (size_t i = 0; i < tmp->mRequests.Length(); i++) {
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequests[i].mPromise)
- }
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-MediaKeySystemAccessManager::MediaKeySystemAccessManager(nsPIDOMWindowInner* aWindow)
- : mWindow(aWindow)
- , mAddedObservers(false)
-{
-}
-
-MediaKeySystemAccessManager::~MediaKeySystemAccessManager()
-{
- Shutdown();
-}
-
-void
-MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
- const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs)
-{
- Request(aPromise, aKeySystem, aConfigs, RequestType::Initial);
-}
-
-void
-MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
- const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs,
- RequestType aType)
-{
- EME_LOG("MediaKeySystemAccessManager::Request %s", NS_ConvertUTF16toUTF8(aKeySystem).get());
-
- if (aKeySystem.IsEmpty()) {
- aPromise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("Key system string is empty"));
- // Don't notify DecoderDoctor, as there's nothing we or the user can
- // do to fix this situation; the site is using the API wrong.
- return;
- }
- if (aConfigs.IsEmpty()) {
- aPromise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("Candidate MediaKeySystemConfigs is empty"));
- // Don't notify DecoderDoctor, as there's nothing we or the user can
- // do to fix this situation; the site is using the API wrong.
- return;
- }
-
- DecoderDoctorDiagnostics diagnostics;
-
- // Ensure keysystem is supported.
- if (!IsWidevineKeySystem(aKeySystem) &&
- !IsClearkeyKeySystem(aKeySystem)) {
- // Not to inform user, because nothing to do if the keySystem is not
- // supported.
- aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
- NS_LITERAL_CSTRING("Key system is unsupported"));
- diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
- aKeySystem, false, __func__);
- return;
- }
-
- if (!MediaPrefs::EMEEnabled() && !IsClearkeyKeySystem(aKeySystem)) {
- // EME disabled by user, send notification to chrome so UI can inform user.
- // Clearkey is allowed even when EME is disabled because we want the pref
- // "media.eme.enabled" only taking effect on proprietary DRMs.
- MediaKeySystemAccess::NotifyObservers(mWindow,
- aKeySystem,
- MediaKeySystemStatus::Api_disabled);
- aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
- NS_LITERAL_CSTRING("EME has been preffed off"));
- diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
- aKeySystem, false, __func__);
- return;
- }
-
- nsAutoCString message;
- MediaKeySystemStatus status =
- MediaKeySystemAccess::GetKeySystemStatus(aKeySystem, message);
-
- nsPrintfCString msg("MediaKeySystemAccess::GetKeySystemStatus(%s) "
- "result=%s msg='%s'",
- NS_ConvertUTF16toUTF8(aKeySystem).get(),
- MediaKeySystemStatusValues::strings[(size_t)status].value,
- message.get());
- LogToBrowserConsole(NS_ConvertUTF8toUTF16(msg));
-
- if (status == MediaKeySystemStatus::Cdm_not_installed &&
- IsWidevineKeySystem(aKeySystem)) {
- // These are cases which could be resolved by downloading a new(er) CDM.
- // When we send the status to chrome, chrome's GMPProvider will attempt to
- // download or update the CDM. In AwaitInstall() we add listeners to wait
- // for the update to complete, and we'll call this function again with
- // aType==Subsequent once the download has completed and the GMPService
- // has had a new plugin added. AwaitInstall() sets a timer to fail if the
- // update/download takes too long or fails.
- if (aType == RequestType::Initial &&
- AwaitInstall(aPromise, aKeySystem, aConfigs)) {
- // Notify chrome that we're going to wait for the CDM to download/update.
- // Note: If we're re-trying, we don't re-send the notification,
- // as chrome is already displaying the "we can't play, updating"
- // notification.
- MediaKeySystemAccess::NotifyObservers(mWindow, aKeySystem, status);
- } else {
- // We waited or can't wait for an update and we still can't service
- // the request. Give up. Chrome will still be showing a "I can't play,
- // updating" notification.
- aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
- NS_LITERAL_CSTRING("Gave up while waiting for a CDM update"));
- }
- diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
- aKeySystem, false, __func__);
- return;
- }
- if (status != MediaKeySystemStatus::Available) {
- // Failed due to user disabling something, send a notification to
- // chrome, so we can show some UI to explain how the user can rectify
- // the situation.
- MediaKeySystemAccess::NotifyObservers(mWindow, aKeySystem, status);
- aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR, message);
- return;
- }
-
- MediaKeySystemConfiguration config;
- if (MediaKeySystemAccess::GetSupportedConfig(aKeySystem, aConfigs, config, &diagnostics)) {
- RefPtr<MediaKeySystemAccess> access(
- new MediaKeySystemAccess(mWindow, aKeySystem, config));
- aPromise->MaybeResolve(access);
- diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
- aKeySystem, true, __func__);
- return;
- }
- // Not to inform user, because nothing to do if the corresponding keySystem
- // configuration is not supported.
- aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
- NS_LITERAL_CSTRING("Key system configuration is not supported"));
- diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
- aKeySystem, false, __func__);
-}
-
-MediaKeySystemAccessManager::PendingRequest::PendingRequest(DetailedPromise* aPromise,
- const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs,
- nsITimer* aTimer)
- : mPromise(aPromise)
- , mKeySystem(aKeySystem)
- , mConfigs(aConfigs)
- , mTimer(aTimer)
-{
- MOZ_COUNT_CTOR(MediaKeySystemAccessManager::PendingRequest);
-}
-
-MediaKeySystemAccessManager::PendingRequest::PendingRequest(const PendingRequest& aOther)
- : mPromise(aOther.mPromise)
- , mKeySystem(aOther.mKeySystem)
- , mConfigs(aOther.mConfigs)
- , mTimer(aOther.mTimer)
-{
- MOZ_COUNT_CTOR(MediaKeySystemAccessManager::PendingRequest);
-}
-
-MediaKeySystemAccessManager::PendingRequest::~PendingRequest()
-{
- MOZ_COUNT_DTOR(MediaKeySystemAccessManager::PendingRequest);
-}
-
-void
-MediaKeySystemAccessManager::PendingRequest::CancelTimer()
-{
- if (mTimer) {
- mTimer->Cancel();
- }
-}
-
-void
-MediaKeySystemAccessManager::PendingRequest::RejectPromise(const nsCString& aReason)
-{
- if (mPromise) {
- mPromise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR, aReason);
- }
-}
-
-bool
-MediaKeySystemAccessManager::AwaitInstall(DetailedPromise* aPromise,
- const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfigs)
-{
- EME_LOG("MediaKeySystemAccessManager::AwaitInstall %s", NS_ConvertUTF16toUTF8(aKeySystem).get());
-
- if (!EnsureObserversAdded()) {
- NS_WARNING("Failed to add pref observer");
- return false;
- }
-
- nsCOMPtr<nsITimer> timer(do_CreateInstance("@mozilla.org/timer;1"));
- if (!timer || NS_FAILED(timer->Init(this, 60 * 1000, nsITimer::TYPE_ONE_SHOT))) {
- NS_WARNING("Failed to create timer to await CDM install.");
- return false;
- }
-
- mRequests.AppendElement(PendingRequest(aPromise, aKeySystem, aConfigs, timer));
- return true;
-}
-
-void
-MediaKeySystemAccessManager::RetryRequest(PendingRequest& aRequest)
-{
- aRequest.CancelTimer();
- Request(aRequest.mPromise, aRequest.mKeySystem, aRequest.mConfigs, RequestType::Subsequent);
-}
-
-nsresult
-MediaKeySystemAccessManager::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
-{
- EME_LOG("MediaKeySystemAccessManager::Observe %s", aTopic);
-
- if (!strcmp(aTopic, "gmp-changed")) {
- // Filter out the requests where the CDM's install-status is no longer
- // "unavailable". This will be the CDMs which have downloaded since the
- // initial request.
- // Note: We don't have a way to communicate from chrome that the CDM has
- // failed to download, so we'll just let the timeout fail us in that case.
- nsTArray<PendingRequest> requests;
- for (size_t i = mRequests.Length(); i-- > 0; ) {
- PendingRequest& request = mRequests[i];
- nsAutoCString message;
- MediaKeySystemStatus status =
- MediaKeySystemAccess::GetKeySystemStatus(request.mKeySystem, message);
- if (status == MediaKeySystemStatus::Cdm_not_installed) {
- // Not yet installed, don't retry. Keep waiting until timeout.
- continue;
- }
- // Status has changed, retry request.
- requests.AppendElement(Move(request));
- mRequests.RemoveElementAt(i);
- }
- // Retry all pending requests, but this time fail if the CDM is not installed.
- for (PendingRequest& request : requests) {
- RetryRequest(request);
- }
- } else if (!strcmp(aTopic, "timer-callback")) {
- // Find the timer that expired and re-run the request for it.
- nsCOMPtr<nsITimer> timer(do_QueryInterface(aSubject));
- for (size_t i = 0; i < mRequests.Length(); i++) {
- if (mRequests[i].mTimer == timer) {
- EME_LOG("MediaKeySystemAccessManager::AwaitInstall resuming request");
- PendingRequest request = mRequests[i];
- mRequests.RemoveElementAt(i);
- RetryRequest(request);
- break;
- }
- }
- }
- return NS_OK;
-}
-
-bool
-MediaKeySystemAccessManager::EnsureObserversAdded()
-{
- if (mAddedObservers) {
- return true;
- }
-
- nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
- if (NS_WARN_IF(!obsService)) {
- return false;
- }
- mAddedObservers = NS_SUCCEEDED(obsService->AddObserver(this, "gmp-changed", false));
- return mAddedObservers;
-}
-
-void
-MediaKeySystemAccessManager::Shutdown()
-{
- EME_LOG("MediaKeySystemAccessManager::Shutdown");
- nsTArray<PendingRequest> requests(Move(mRequests));
- for (PendingRequest& request : requests) {
- // Cancel all requests; we're shutting down.
- request.CancelTimer();
- request.RejectPromise(NS_LITERAL_CSTRING("Promise still outstanding at MediaKeySystemAccessManager shutdown"));
- }
- if (mAddedObservers) {
- nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
- if (obsService) {
- obsService->RemoveObserver(this, "gmp-changed");
- mAddedObservers = false;
- }
- }
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/MediaKeySystemAccessManager.h b/dom/media/eme/MediaKeySystemAccessManager.h
deleted file mode 100644
index 9c092248e2..0000000000
--- a/dom/media/eme/MediaKeySystemAccessManager.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this
-* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_MediaKeySystemAccessManager_h
-#define mozilla_dom_MediaKeySystemAccessManager_h
-
-#include "mozilla/dom/MediaKeySystemAccess.h"
-#include "nsIObserver.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsISupportsImpl.h"
-#include "nsITimer.h"
-
-namespace mozilla {
-namespace dom {
-
-class DetailedPromise;
-class TestGMPVideoDecoder;
-
-class MediaKeySystemAccessManager final : public nsIObserver
-{
-public:
-
- explicit MediaKeySystemAccessManager(nsPIDOMWindowInner* aWindow);
-
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(MediaKeySystemAccessManager, nsIObserver)
- NS_DECL_NSIOBSERVER
-
- void Request(DetailedPromise* aPromise,
- const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfig);
-
- void Shutdown();
-
- struct PendingRequest {
- PendingRequest(DetailedPromise* aPromise,
- const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfig,
- nsITimer* aTimer);
- PendingRequest(const PendingRequest& aOther);
- ~PendingRequest();
- void CancelTimer();
- void RejectPromise(const nsCString& aReason);
-
- RefPtr<DetailedPromise> mPromise;
- const nsString mKeySystem;
- const Sequence<MediaKeySystemConfiguration> mConfigs;
- nsCOMPtr<nsITimer> mTimer;
- };
-
-private:
-
- enum RequestType {
- Initial,
- Subsequent
- };
-
- void Request(DetailedPromise* aPromise,
- const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfig,
- RequestType aType);
-
- ~MediaKeySystemAccessManager();
-
- bool EnsureObserversAdded();
-
- bool AwaitInstall(DetailedPromise* aPromise,
- const nsAString& aKeySystem,
- const Sequence<MediaKeySystemConfiguration>& aConfig);
-
- void RetryRequest(PendingRequest& aRequest);
-
- nsTArray<PendingRequest> mRequests;
-
- nsCOMPtr<nsPIDOMWindowInner> mWindow;
- bool mAddedObservers;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/eme/MediaKeys.cpp b/dom/media/eme/MediaKeys.cpp
deleted file mode 100644
index 8621007579..0000000000
--- a/dom/media/eme/MediaKeys.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/MediaKeys.h"
-#include "GMPService.h"
-#include "mozilla/dom/HTMLMediaElement.h"
-#include "mozilla/dom/MediaKeysBinding.h"
-#include "mozilla/dom/MediaKeyMessageEvent.h"
-#include "mozilla/dom/MediaKeyError.h"
-#include "mozilla/dom/MediaKeySession.h"
-#include "mozilla/dom/DOMException.h"
-#include "mozilla/dom/UnionTypes.h"
-#include "GMPCDMProxy.h"
-#include "mozilla/EMEUtils.h"
-#include "nsContentUtils.h"
-#include "nsIScriptObjectPrincipal.h"
-#include "nsContentTypeParser.h"
-#ifdef MOZ_FMP4
-#include "MP4Decoder.h"
-#endif
-#ifdef XP_WIN
-#include "mozilla/WindowsVersion.h"
-#endif
-#include "nsContentCID.h"
-#include "nsServiceManagerUtils.h"
-#include "mozilla/dom/MediaKeySystemAccess.h"
-#include "nsPrintfCString.h"
-
-namespace mozilla {
-
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MediaKeys,
- mElement,
- mParent,
- mKeySessions,
- mPromises,
- mPendingSessions);
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeys)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeys)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaKeys)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-MediaKeys::MediaKeys(nsPIDOMWindowInner* aParent,
- const nsAString& aKeySystem,
- const MediaKeySystemConfiguration& aConfig)
- : mParent(aParent)
- , mKeySystem(aKeySystem)
- , mCreatePromiseId(0)
- , mConfig(aConfig)
-{
- EME_LOG("MediaKeys[%p] constructed keySystem=%s",
- this, NS_ConvertUTF16toUTF8(mKeySystem).get());
-}
-
-MediaKeys::~MediaKeys()
-{
- Shutdown();
- EME_LOG("MediaKeys[%p] destroyed", this);
-}
-
-void
-MediaKeys::Terminated()
-{
- EME_LOG("MediaKeys[%p] CDM crashed unexpectedly", this);
-
- KeySessionHashMap keySessions;
- // Remove entries during iteration will screw it. Make a copy first.
- for (auto iter = mKeySessions.Iter(); !iter.Done(); iter.Next()) {
- RefPtr<MediaKeySession>& session = iter.Data();
- keySessions.Put(session->GetSessionId(), session);
- }
- for (auto iter = keySessions.Iter(); !iter.Done(); iter.Next()) {
- RefPtr<MediaKeySession>& session = iter.Data();
- session->OnClosed();
- }
- keySessions.Clear();
- MOZ_ASSERT(mKeySessions.Count() == 0);
-
- // Notify the element about that CDM has terminated.
- if (mElement) {
- mElement->DecodeError(NS_ERROR_DOM_MEDIA_CDM_ERR);
- }
-
- Shutdown();
-}
-
-void
-MediaKeys::Shutdown()
-{
- if (mProxy) {
- mProxy->Shutdown();
- mProxy = nullptr;
- }
-
- RefPtr<MediaKeys> kungFuDeathGrip = this;
-
- for (auto iter = mPromises.Iter(); !iter.Done(); iter.Next()) {
- RefPtr<dom::DetailedPromise>& promise = iter.Data();
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Promise still outstanding at MediaKeys shutdown"));
- Release();
- }
- mPromises.Clear();
-}
-
-nsPIDOMWindowInner*
-MediaKeys::GetParentObject() const
-{
- return mParent;
-}
-
-JSObject*
-MediaKeys::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return MediaKeysBinding::Wrap(aCx, this, aGivenProto);
-}
-
-void
-MediaKeys::GetKeySystem(nsString& aOutKeySystem) const
-{
- aOutKeySystem.Assign(mKeySystem);
-}
-
-already_AddRefed<DetailedPromise>
-MediaKeys::SetServerCertificate(const ArrayBufferViewOrArrayBuffer& aCert, ErrorResult& aRv)
-{
- RefPtr<DetailedPromise> promise(MakePromise(aRv,
- NS_LITERAL_CSTRING("MediaKeys.setServerCertificate")));
- if (aRv.Failed()) {
- return nullptr;
- }
-
- if (!mProxy) {
- NS_WARNING("Tried to use a MediaKeys without a CDM");
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Null CDM in MediaKeys.setServerCertificate()"));
- return promise.forget();
- }
-
- nsTArray<uint8_t> data;
- CopyArrayBufferViewOrArrayBufferData(aCert, data);
- if (data.IsEmpty()) {
- promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
- NS_LITERAL_CSTRING("Empty certificate passed to MediaKeys.setServerCertificate()"));
- return promise.forget();
- }
-
- mProxy->SetServerCertificate(StorePromise(promise), data);
- return promise.forget();
-}
-
-already_AddRefed<DetailedPromise>
-MediaKeys::MakePromise(ErrorResult& aRv, const nsACString& aName)
-{
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
- if (!global) {
- NS_WARNING("Passed non-global to MediaKeys ctor!");
- aRv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
- return DetailedPromise::Create(global, aRv, aName);
-}
-
-PromiseId
-MediaKeys::StorePromise(DetailedPromise* aPromise)
-{
- static uint32_t sEMEPromiseCount = 1;
- MOZ_ASSERT(aPromise);
- uint32_t id = sEMEPromiseCount++;
-
- EME_LOG("MediaKeys[%p]::StorePromise() id=%d", this, id);
-
- // Keep MediaKeys alive for the lifetime of its promises. Any still-pending
- // promises are rejected in Shutdown().
- AddRef();
-
-#ifdef DEBUG
- // We should not have already stored this promise!
- for (auto iter = mPromises.ConstIter(); !iter.Done(); iter.Next()) {
- MOZ_ASSERT(iter.Data() != aPromise);
- }
-#endif
-
- mPromises.Put(id, aPromise);
- return id;
-}
-
-void
-MediaKeys::ConnectPendingPromiseIdWithToken(PromiseId aId, uint32_t aToken)
-{
- // Should only be called from MediaKeySession::GenerateRequest.
- mPromiseIdToken.Put(aId, aToken);
- EME_LOG("MediaKeys[%p]::ConnectPendingPromiseIdWithToken() id=%u => token(%u)",
- this, aId, aToken);
-}
-
-already_AddRefed<DetailedPromise>
-MediaKeys::RetrievePromise(PromiseId aId)
-{
- if (!mPromises.Contains(aId)) {
- NS_WARNING(nsPrintfCString("Tried to retrieve a non-existent promise id=%d", aId).get());
- return nullptr;
- }
- RefPtr<DetailedPromise> promise;
- mPromises.Remove(aId, getter_AddRefs(promise));
- Release();
- return promise.forget();
-}
-
-void
-MediaKeys::RejectPromise(PromiseId aId, nsresult aExceptionCode,
- const nsCString& aReason)
-{
- EME_LOG("MediaKeys[%p]::RejectPromise(%d, 0x%x)", this, aId, aExceptionCode);
-
- RefPtr<DetailedPromise> promise(RetrievePromise(aId));
- if (!promise) {
- return;
- }
-
- // This promise could be a createSession or loadSession promise,
- // so we might have a pending session waiting to be resolved into
- // the promise on success. We've been directed to reject to promise,
- // so we can throw away the corresponding session object.
- uint32_t token = 0;
- if (mPromiseIdToken.Get(aId, &token)) {
- MOZ_ASSERT(mPendingSessions.Contains(token));
- mPendingSessions.Remove(token);
- mPromiseIdToken.Remove(aId);
- }
-
- MOZ_ASSERT(NS_FAILED(aExceptionCode));
- promise->MaybeReject(aExceptionCode, aReason);
-
- if (mCreatePromiseId == aId) {
- // Note: This will probably destroy the MediaKeys object!
- Release();
- }
-}
-
-void
-MediaKeys::OnSessionIdReady(MediaKeySession* aSession)
-{
- if (!aSession) {
- NS_WARNING("Invalid MediaKeySession passed to OnSessionIdReady()");
- return;
- }
- if (mKeySessions.Contains(aSession->GetSessionId())) {
- NS_WARNING("MediaKeySession's made ready multiple times!");
- return;
- }
- if (mPendingSessions.Contains(aSession->Token())) {
- NS_WARNING("MediaKeySession made ready when it wasn't waiting to be ready!");
- return;
- }
- if (aSession->GetSessionId().IsEmpty()) {
- NS_WARNING("MediaKeySession with invalid sessionId passed to OnSessionIdReady()");
- return;
- }
- mKeySessions.Put(aSession->GetSessionId(), aSession);
-}
-
-void
-MediaKeys::ResolvePromise(PromiseId aId)
-{
- EME_LOG("MediaKeys[%p]::ResolvePromise(%d)", this, aId);
-
- RefPtr<DetailedPromise> promise(RetrievePromise(aId));
- MOZ_ASSERT(!mPromises.Contains(aId));
- if (!promise) {
- return;
- }
-
- uint32_t token = 0;
- if (!mPromiseIdToken.Get(aId, &token)) {
- promise->MaybeResolveWithUndefined();
- return;
- } else if (!mPendingSessions.Contains(token)) {
- // Pending session for CreateSession() should be removed when sessionId
- // is ready.
- promise->MaybeResolveWithUndefined();
- mPromiseIdToken.Remove(aId);
- return;
- }
- mPromiseIdToken.Remove(aId);
-
- // We should only resolve LoadSession calls via this path,
- // not CreateSession() promises.
- RefPtr<MediaKeySession> session;
- mPendingSessions.Remove(token, getter_AddRefs(session));
- if (!session || session->GetSessionId().IsEmpty()) {
- NS_WARNING("Received activation for non-existent session!");
- promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
- NS_LITERAL_CSTRING("CDM LoadSession() returned a different session ID than requested"));
- return;
- }
- mKeySessions.Put(session->GetSessionId(), session);
- promise->MaybeResolve(session);
-}
-
-class MediaKeysGMPCrashHelper : public GMPCrashHelper
-{
-public:
- explicit MediaKeysGMPCrashHelper(MediaKeys* aMediaKeys)
- : mMediaKeys(aMediaKeys)
- {
- MOZ_ASSERT(NS_IsMainThread()); // WeakPtr isn't thread safe.
- }
- already_AddRefed<nsPIDOMWindowInner>
- GetPluginCrashedEventTarget() override
- {
- MOZ_ASSERT(NS_IsMainThread()); // WeakPtr isn't thread safe.
- EME_LOG("MediaKeysGMPCrashHelper::GetPluginCrashedEventTarget()");
- return (mMediaKeys && mMediaKeys->GetParentObject()) ?
- do_AddRef(mMediaKeys->GetParentObject()) : nullptr;
- }
-private:
- WeakPtr<MediaKeys> mMediaKeys;
-};
-
-already_AddRefed<CDMProxy>
-MediaKeys::CreateCDMProxy()
-{
- RefPtr<CDMProxy> proxy;
- {
- proxy = new GMPCDMProxy(this,
- mKeySystem,
- new MediaKeysGMPCrashHelper(this),
- mConfig.mDistinctiveIdentifier == MediaKeysRequirement::Required,
- mConfig.mPersistentState == MediaKeysRequirement::Required);
- }
- return proxy.forget();
-}
-
-already_AddRefed<DetailedPromise>
-MediaKeys::Init(ErrorResult& aRv)
-{
- RefPtr<DetailedPromise> promise(MakePromise(aRv,
- NS_LITERAL_CSTRING("MediaKeys::Init()")));
- if (aRv.Failed()) {
- return nullptr;
- }
-
- mProxy = CreateCDMProxy();
-
- // Determine principal (at creation time) of the MediaKeys object.
- nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(GetParentObject());
- if (!sop) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get script principal in MediaKeys::Init"));
- return promise.forget();
- }
- mPrincipal = sop->GetPrincipal();
-
- // Determine principal of the "top-level" window; the principal of the
- // page that will display in the URL bar.
- nsCOMPtr<nsPIDOMWindowInner> window = GetParentObject();
- if (!window) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get top-level window in MediaKeys::Init"));
- return promise.forget();
- }
- nsCOMPtr<nsPIDOMWindowOuter> top = window->GetOuterWindow()->GetTop();
- if (!top || !top->GetExtantDoc()) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get document in MediaKeys::Init"));
- return promise.forget();
- }
-
- mTopLevelPrincipal = top->GetExtantDoc()->NodePrincipal();
-
- if (!mPrincipal || !mTopLevelPrincipal) {
- NS_WARNING("Failed to get principals when creating MediaKeys");
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get principal(s) in MediaKeys::Init"));
- return promise.forget();
- }
-
- nsAutoCString origin;
- nsresult rv = mPrincipal->GetOrigin(origin);
- if (NS_FAILED(rv)) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get principal origin string in MediaKeys::Init"));
- return promise.forget();
- }
- nsAutoCString topLevelOrigin;
- rv = mTopLevelPrincipal->GetOrigin(topLevelOrigin);
- if (NS_FAILED(rv)) {
- promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get top-level principal origin string in MediaKeys::Init"));
- return promise.forget();
- }
-
- nsIDocument* doc = window->GetExtantDoc();
- const bool inPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(doc);
-
- EME_LOG("MediaKeys[%p]::Create() (%s, %s), %s",
- this,
- origin.get(),
- topLevelOrigin.get(),
- (inPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"));
-
- // The CDMProxy's initialization is asynchronous. The MediaKeys is
- // refcounted, and its instance is returned to JS by promise once
- // it's been initialized. No external refs exist to the MediaKeys while
- // we're waiting for the promise to be resolved, so we must hold a
- // reference to the new MediaKeys object until it's been created,
- // or its creation has failed. Store the id of the promise returned
- // here, and hold a self-reference until that promise is resolved or
- // rejected.
- MOZ_ASSERT(!mCreatePromiseId, "Should only be created once!");
- mCreatePromiseId = StorePromise(promise);
- AddRef();
- mProxy->Init(mCreatePromiseId,
- NS_ConvertUTF8toUTF16(origin),
- NS_ConvertUTF8toUTF16(topLevelOrigin),
- KeySystemToGMPName(mKeySystem),
- inPrivateBrowsing);
-
- return promise.forget();
-}
-
-void
-MediaKeys::OnCDMCreated(PromiseId aId, const nsACString& aNodeId, const uint32_t aPluginId)
-{
- RefPtr<DetailedPromise> promise(RetrievePromise(aId));
- if (!promise) {
- return;
- }
- mNodeId = aNodeId;
- RefPtr<MediaKeys> keys(this);
- EME_LOG("MediaKeys[%p]::OnCDMCreated() resolve promise id=%d", this, aId);
- promise->MaybeResolve(keys);
- if (mCreatePromiseId == aId) {
- Release();
- }
-
- MediaKeySystemAccess::NotifyObservers(mParent,
- mKeySystem,
- MediaKeySystemStatus::Cdm_created);
-
-}
-
-static bool
-IsSessionTypeSupported(const MediaKeySessionType aSessionType,
- const MediaKeySystemConfiguration& aConfig)
-{
- if (aSessionType == MediaKeySessionType::Temporary) {
- // Temporary is always supported.
- return true;
- }
- if (!aConfig.mSessionTypes.WasPassed()) {
- // No other session types supported.
- return false;
- }
- using MediaKeySessionTypeValues::strings;
- const char* sessionType = strings[static_cast<uint32_t>(aSessionType)].value;
- for (const nsString& s : aConfig.mSessionTypes.Value()) {
- if (s.EqualsASCII(sessionType)) {
- return true;
- }
- }
- return false;
-}
-
-already_AddRefed<MediaKeySession>
-MediaKeys::CreateSession(JSContext* aCx,
- MediaKeySessionType aSessionType,
- ErrorResult& aRv)
-{
- if (!IsSessionTypeSupported(aSessionType, mConfig)) {
- EME_LOG("MediaKeys[%p,'%s'] CreateSession() failed, unsupported session type", this);
- aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return nullptr;
- }
-
- if (!mProxy) {
- NS_WARNING("Tried to use a MediaKeys which lost its CDM");
- aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return nullptr;
- }
-
- EME_LOG("MediaKeys[%p] Creating session", this);
-
- RefPtr<MediaKeySession> session = new MediaKeySession(aCx,
- GetParentObject(),
- this,
- mKeySystem,
- aSessionType,
- aRv);
-
- if (aRv.Failed()) {
- return nullptr;
- }
-
- // Add session to the set of sessions awaiting their sessionId being ready.
- mPendingSessions.Put(session->Token(), session);
-
- return session.forget();
-}
-
-void
-MediaKeys::OnSessionLoaded(PromiseId aId, bool aSuccess)
-{
- RefPtr<DetailedPromise> promise(RetrievePromise(aId));
- if (!promise) {
- return;
- }
- EME_LOG("MediaKeys[%p]::OnSessionLoaded() resolve promise id=%d", this, aId);
-
- promise->MaybeResolve(aSuccess);
-}
-
-void
-MediaKeys::OnSessionClosed(MediaKeySession* aSession)
-{
- nsAutoString id;
- aSession->GetSessionId(id);
- mKeySessions.Remove(id);
-}
-
-already_AddRefed<MediaKeySession>
-MediaKeys::GetSession(const nsAString& aSessionId)
-{
- RefPtr<MediaKeySession> session;
- mKeySessions.Get(aSessionId, getter_AddRefs(session));
- return session.forget();
-}
-
-already_AddRefed<MediaKeySession>
-MediaKeys::GetPendingSession(uint32_t aToken)
-{
- RefPtr<MediaKeySession> session;
- mPendingSessions.Get(aToken, getter_AddRefs(session));
- mPendingSessions.Remove(aToken);
- return session.forget();
-}
-
-const nsCString&
-MediaKeys::GetNodeId() const
-{
- MOZ_ASSERT(NS_IsMainThread());
- return mNodeId;
-}
-
-bool
-MediaKeys::IsBoundToMediaElement() const
-{
- MOZ_ASSERT(NS_IsMainThread());
- return mElement != nullptr;
-}
-
-nsresult
-MediaKeys::Bind(HTMLMediaElement* aElement)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (IsBoundToMediaElement()) {
- return NS_ERROR_FAILURE;
- }
-
- mElement = aElement;
-
- return NS_OK;
-}
-
-void
-MediaKeys::Unbind()
-{
- MOZ_ASSERT(NS_IsMainThread());
- mElement = nullptr;
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/media/eme/MediaKeys.h b/dom/media/eme/MediaKeys.h
deleted file mode 100644
index 4919639342..0000000000
--- a/dom/media/eme/MediaKeys.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_mediakeys_h__
-#define mozilla_dom_mediakeys_h__
-
-#include "nsWrapperCache.h"
-#include "nsISupports.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/RefPtr.h"
-#include "nsCOMPtr.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsRefPtrHashtable.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/MediaKeysBinding.h"
-#include "mozilla/dom/MediaKeySystemAccessBinding.h"
-#include "mozIGeckoMediaPluginService.h"
-#include "mozilla/DetailedPromise.h"
-#include "mozilla/WeakPtr.h"
-
-namespace mozilla {
-
-class CDMProxy;
-
-namespace dom {
-
-class ArrayBufferViewOrArrayBuffer;
-class MediaKeySession;
-class HTMLMediaElement;
-
-typedef nsRefPtrHashtable<nsStringHashKey, MediaKeySession> KeySessionHashMap;
-typedef nsRefPtrHashtable<nsUint32HashKey, dom::DetailedPromise> PromiseHashMap;
-typedef nsRefPtrHashtable<nsUint32HashKey, MediaKeySession> PendingKeySessionsHashMap;
-typedef nsDataHashtable<nsUint32HashKey, uint32_t> PendingPromiseIdTokenHashMap;
-typedef uint32_t PromiseId;
-
-// This class is used on the main thread only.
-// Note: its addref/release is not (and can't be) thread safe!
-class MediaKeys final : public nsISupports,
- public nsWrapperCache,
- public SupportsWeakPtr<MediaKeys>
-{
- ~MediaKeys();
-
-public:
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaKeys)
- MOZ_DECLARE_WEAKREFERENCE_TYPENAME(MediaKeys)
-
- MediaKeys(nsPIDOMWindowInner* aParentWindow,
- const nsAString& aKeySystem,
- const MediaKeySystemConfiguration& aConfig);
-
- already_AddRefed<DetailedPromise> Init(ErrorResult& aRv);
-
- nsPIDOMWindowInner* GetParentObject() const;
-
- JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- nsresult Bind(HTMLMediaElement* aElement);
- void Unbind();
-
- // Javascript: readonly attribute DOMString keySystem;
- void GetKeySystem(nsString& retval) const;
-
- // JavaScript: MediaKeys.createSession()
- already_AddRefed<MediaKeySession> CreateSession(JSContext* aCx,
- MediaKeySessionType aSessionType,
- ErrorResult& aRv);
-
- // JavaScript: MediaKeys.SetServerCertificate()
- already_AddRefed<DetailedPromise>
- SetServerCertificate(const ArrayBufferViewOrArrayBuffer& aServerCertificate,
- ErrorResult& aRv);
-
- already_AddRefed<MediaKeySession> GetSession(const nsAString& aSessionId);
-
- // Removes and returns MediaKeySession from the set of sessions awaiting
- // their sessionId to be assigned.
- already_AddRefed<MediaKeySession> GetPendingSession(uint32_t aToken);
-
- // Called once a Init() operation succeeds.
- void OnCDMCreated(PromiseId aId,
- const nsACString& aNodeId, const uint32_t aPluginId);
-
- // Called once the CDM generates a sessionId while servicing a
- // MediaKeySession.generateRequest() or MediaKeySession.load() call,
- // once the sessionId of a MediaKeySession is known.
- void OnSessionIdReady(MediaKeySession* aSession);
-
- // Called once a LoadSession succeeds.
- void OnSessionLoaded(PromiseId aId, bool aSuccess);
-
- // Called once a session has closed.
- void OnSessionClosed(MediaKeySession* aSession);
-
- CDMProxy* GetCDMProxy() { return mProxy; }
-
- // Makes a new promise, or nullptr on failure.
- already_AddRefed<DetailedPromise> MakePromise(ErrorResult& aRv,
- const nsACString& aName);
- // Stores promise in mPromises, returning an ID that can be used to retrieve
- // it later. The ID is passed to the CDM, so that it can signal specific
- // promises to be resolved.
- PromiseId StorePromise(DetailedPromise* aPromise);
-
- // Stores a map from promise id to pending session token. Using this
- // mapping, when a promise is rejected via its ID, we can check if the
- // promise corresponds to a pending session and retrieve that session
- // via the mapped-to token, and remove the pending session from the
- // list of sessions awaiting a session id.
- void ConnectPendingPromiseIdWithToken(PromiseId aId, uint32_t aToken);
-
- // Reject promise with DOMException corresponding to aExceptionCode.
- void RejectPromise(PromiseId aId, nsresult aExceptionCode,
- const nsCString& aReason);
- // Resolves promise with "undefined".
- void ResolvePromise(PromiseId aId);
-
- const nsCString& GetNodeId() const;
-
- void Shutdown();
-
- // Called by CDMProxy when CDM crashes or shuts down. It is different from
- // Shutdown which is called from the script/dom side.
- void Terminated();
-
- // Returns true if this MediaKeys has been bound to a media element.
- bool IsBoundToMediaElement() const;
-
-private:
-
- // Instantiate CDMProxy instance.
- // It could be MediaDrmCDMProxy (Widevine on Fennec) or GMPCDMProxy (the rest).
- already_AddRefed<CDMProxy> CreateCDMProxy();
-
- // Removes promise from mPromises, and returns it.
- already_AddRefed<DetailedPromise> RetrievePromise(PromiseId aId);
-
- // Owning ref to proxy. The proxy has a weak reference back to the MediaKeys,
- // and the MediaKeys destructor clears the proxy's reference to the MediaKeys.
- RefPtr<CDMProxy> mProxy;
-
- RefPtr<HTMLMediaElement> mElement;
-
- nsCOMPtr<nsPIDOMWindowInner> mParent;
- const nsString mKeySystem;
- nsCString mNodeId;
- KeySessionHashMap mKeySessions;
- PromiseHashMap mPromises;
- PendingKeySessionsHashMap mPendingSessions;
- PromiseId mCreatePromiseId;
-
- RefPtr<nsIPrincipal> mPrincipal;
- RefPtr<nsIPrincipal> mTopLevelPrincipal;
-
- const MediaKeySystemConfiguration mConfig;
-
- PendingPromiseIdTokenHashMap mPromiseIdToken;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_mediakeys_h__
diff --git a/dom/media/eme/moz.build b/dom/media/eme/moz.build
deleted file mode 100644
index 31ab9ffd87..0000000000
--- a/dom/media/eme/moz.build
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS.mozilla.dom += [
- 'MediaEncryptedEvent.h',
- 'MediaKeyError.h',
- 'MediaKeyMessageEvent.h',
- 'MediaKeys.h',
- 'MediaKeySession.h',
- 'MediaKeyStatusMap.h',
- 'MediaKeySystemAccess.h',
- 'MediaKeySystemAccessManager.h',
-]
-
-EXPORTS.mozilla += [
- 'CDMCaps.h',
- 'CDMProxy.h',
- 'DecryptorProxyCallback.h',
- 'DetailedPromise.h',
- 'EMEUtils.h',
-]
-
-UNIFIED_SOURCES += [
- 'CDMCaps.cpp',
- 'DetailedPromise.cpp',
- 'EMEUtils.cpp',
- 'MediaEncryptedEvent.cpp',
- 'MediaKeyError.cpp',
- 'MediaKeyMessageEvent.cpp',
- 'MediaKeys.cpp',
- 'MediaKeySession.cpp',
- 'MediaKeyStatusMap.cpp',
- 'MediaKeySystemAccess.cpp',
- 'MediaKeySystemAccessManager.cpp',
-]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
diff --git a/dom/media/fmp4/MP4Decoder.cpp b/dom/media/fmp4/MP4Decoder.cpp
index 3cfe5b1374..ed212992c0 100644
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -9,9 +9,6 @@
#include "MP4Demuxer.h"
#include "mozilla/Preferences.h"
#include "nsCharSeparatedTokenizer.h"
-#ifdef MOZ_EME
-#include "mozilla/CDMProxy.h"
-#endif
#include "mozilla/Logging.h"
#include "mozilla/SharedThreadPool.h"
#include "nsMimeTypes.h"
diff --git a/dom/media/gmp/GMPCDMCallbackProxy.cpp b/dom/media/gmp/GMPCDMCallbackProxy.cpp
deleted file mode 100644
index a0b490849a..0000000000
--- a/dom/media/gmp/GMPCDMCallbackProxy.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "GMPCDMCallbackProxy.h"
-#include "mozilla/CDMProxy.h"
-#include "nsString.h"
-#include "mozilla/dom/MediaKeys.h"
-#include "mozilla/dom/MediaKeySession.h"
-#include "mozIGeckoMediaPluginService.h"
-#include "nsContentCID.h"
-#include "nsServiceManagerUtils.h"
-#include "MainThreadUtils.h"
-#include "mozilla/EMEUtils.h"
-
-namespace mozilla {
-
-GMPCDMCallbackProxy::GMPCDMCallbackProxy(CDMProxy* aProxy)
- : mProxy(aProxy)
-{}
-
-void
-GMPCDMCallbackProxy::SetDecryptorId(uint32_t aId)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- RefPtr<CDMProxy> proxy = mProxy;
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy, aId] ()
- {
- proxy->OnSetDecryptorId(aId);
- })
- );}
-
-void
-GMPCDMCallbackProxy::SetSessionId(uint32_t aToken,
- const nsCString& aSessionId)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- RefPtr<CDMProxy> proxy = mProxy;
- auto sid = NS_ConvertUTF8toUTF16(aSessionId);
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy,
- aToken,
- sid] ()
- {
- proxy->OnSetSessionId(aToken, sid);
- })
- );
-}
-
-void
-GMPCDMCallbackProxy::ResolveLoadSessionPromise(uint32_t aPromiseId,
- bool aSuccess)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- RefPtr<CDMProxy> proxy = mProxy;
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy, aPromiseId, aSuccess] ()
- {
- proxy->OnResolveLoadSessionPromise(aPromiseId, aSuccess);
- })
- );
-}
-
-void
-GMPCDMCallbackProxy::ResolvePromise(uint32_t aPromiseId)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- // Note: CDMProxy proxies this from non-main threads to main thread.
- mProxy->ResolvePromise(aPromiseId);
-}
-
-void
-GMPCDMCallbackProxy::RejectPromise(uint32_t aPromiseId,
- nsresult aException,
- const nsCString& aMessage)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- RefPtr<CDMProxy> proxy = mProxy;
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy,
- aPromiseId,
- aException,
- aMessage] ()
- {
- proxy->OnRejectPromise(aPromiseId, aException, aMessage);
- })
- );
-}
-
-void
-GMPCDMCallbackProxy::SessionMessage(const nsCString& aSessionId,
- dom::MediaKeyMessageType aMessageType,
- const nsTArray<uint8_t>& aMessage)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- RefPtr<CDMProxy> proxy = mProxy;
- auto sid = NS_ConvertUTF8toUTF16(aSessionId);
- nsTArray<uint8_t> msg(aMessage);
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy,
- sid,
- aMessageType,
- msg] () mutable
- {
- proxy->OnSessionMessage(sid, aMessageType, msg);
- })
- );
-}
-
-void
-GMPCDMCallbackProxy::ExpirationChange(const nsCString& aSessionId,
- GMPTimestamp aExpiryTime)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- RefPtr<CDMProxy> proxy = mProxy;
- auto sid = NS_ConvertUTF8toUTF16(aSessionId);
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy,
- sid,
- aExpiryTime] ()
- {
- proxy->OnExpirationChange(sid, aExpiryTime);
- })
- );
-}
-
-void
-GMPCDMCallbackProxy::SessionClosed(const nsCString& aSessionId)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- bool keyStatusesChange = false;
- auto sid = NS_ConvertUTF8toUTF16(aSessionId);
- {
- CDMCaps::AutoLock caps(mProxy->Capabilites());
- keyStatusesChange = caps.RemoveKeysForSession(NS_ConvertUTF8toUTF16(aSessionId));
- }
- if (keyStatusesChange) {
- RefPtr<CDMProxy> proxy = mProxy;
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy, sid] ()
- {
- proxy->OnKeyStatusesChange(sid);
- })
- );
- }
-
- RefPtr<CDMProxy> proxy = mProxy;
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy, sid] ()
- {
- proxy->OnSessionClosed(sid);
- })
- );
-}
-
-void
-GMPCDMCallbackProxy::SessionError(const nsCString& aSessionId,
- nsresult aException,
- uint32_t aSystemCode,
- const nsCString& aMessage)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- RefPtr<CDMProxy> proxy = mProxy;
- auto sid = NS_ConvertUTF8toUTF16(aSessionId);
- auto msg = NS_ConvertUTF8toUTF16(aMessage);
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy,
- sid,
- aException,
- aSystemCode,
- msg] ()
- {
- proxy->OnSessionError(sid,
- aException,
- aSystemCode,
- msg);
- })
- );
-}
-
-void
-GMPCDMCallbackProxy::BatchedKeyStatusChanged(const nsCString& aSessionId,
- const nsTArray<CDMKeyInfo>& aKeyInfos)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
- BatchedKeyStatusChangedInternal(aSessionId, aKeyInfos);
-}
-
-void
-GMPCDMCallbackProxy::BatchedKeyStatusChangedInternal(const nsCString& aSessionId,
- const nsTArray<CDMKeyInfo>& aKeyInfos)
-{
- bool keyStatusesChange = false;
- {
- CDMCaps::AutoLock caps(mProxy->Capabilites());
- for (size_t i = 0; i < aKeyInfos.Length(); i++) {
- keyStatusesChange |=
- caps.SetKeyStatus(aKeyInfos[i].mKeyId,
- NS_ConvertUTF8toUTF16(aSessionId),
- aKeyInfos[i].mStatus);
- }
- }
- if (keyStatusesChange) {
- RefPtr<CDMProxy> proxy = mProxy;
- auto sid = NS_ConvertUTF8toUTF16(aSessionId);
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy, sid] ()
- {
- proxy->OnKeyStatusesChange(sid);
- })
- );
- }
-}
-
-void
-GMPCDMCallbackProxy::Decrypted(uint32_t aId,
- DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData)
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- mProxy->OnDecrypted(aId, aResult, aDecryptedData);
-}
-
-void
-GMPCDMCallbackProxy::Terminated()
-{
- MOZ_ASSERT(mProxy->IsOnOwnerThread());
-
- RefPtr<CDMProxy> proxy = mProxy;
- NS_DispatchToMainThread(
- NS_NewRunnableFunction([proxy] ()
- {
- proxy->Terminated();
- })
- );
-}
-
-} // namespace mozilla
diff --git a/dom/media/gmp/GMPCDMCallbackProxy.h b/dom/media/gmp/GMPCDMCallbackProxy.h
deleted file mode 100644
index d2cc806825..0000000000
--- a/dom/media/gmp/GMPCDMCallbackProxy.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef GMPCDMCallbackProxy_h_
-#define GMPCDMCallbackProxy_h_
-
-#include "mozilla/CDMProxy.h"
-#include "gmp-decryption.h"
-#include "GMPDecryptorProxy.h"
-
-namespace mozilla {
-
-// Proxies call backs from the CDM on the GMP thread back to the MediaKeys
-// object on the main thread.
-class GMPCDMCallbackProxy : public GMPDecryptorProxyCallback {
-public:
-
- void SetDecryptorId(uint32_t aId) override;
-
- void SetSessionId(uint32_t aCreateSessionToken,
- const nsCString& aSessionId) override;
-
- void ResolveLoadSessionPromise(uint32_t aPromiseId,
- bool aSuccess) override;
-
- void ResolvePromise(uint32_t aPromiseId) override;
-
- void RejectPromise(uint32_t aPromiseId,
- nsresult aException,
- const nsCString& aSessionId) override;
-
- void SessionMessage(const nsCString& aSessionId,
- dom::MediaKeyMessageType aMessageType,
- const nsTArray<uint8_t>& aMessage) override;
-
- void ExpirationChange(const nsCString& aSessionId,
- UnixTime aExpiryTime) override;
-
- void SessionClosed(const nsCString& aSessionId) override;
-
- void SessionError(const nsCString& aSessionId,
- nsresult aException,
- uint32_t aSystemCode,
- const nsCString& aMessage) override;
-
- void Decrypted(uint32_t aId,
- DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData) override;
-
- void BatchedKeyStatusChanged(const nsCString& aSessionId,
- const nsTArray<CDMKeyInfo>& aKeyInfos) override;
-
- void Terminated() override;
-
- ~GMPCDMCallbackProxy() {}
-
-private:
- friend class GMPCDMProxy;
- explicit GMPCDMCallbackProxy(CDMProxy* aProxy);
-
- void BatchedKeyStatusChangedInternal(const nsCString& aSessionId,
- const nsTArray<CDMKeyInfo>& aKeyInfos);
- // Warning: Weak ref.
- CDMProxy* mProxy;
-};
-
-} // namespace mozilla
-
-#endif // GMPCDMCallbackProxy_h_
diff --git a/dom/media/gmp/GMPCDMProxy.cpp b/dom/media/gmp/GMPCDMProxy.cpp
deleted file mode 100644
index 0f19586321..0000000000
--- a/dom/media/gmp/GMPCDMProxy.cpp
+++ /dev/null
@@ -1,798 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "GMPCDMProxy.h"
-#include "mozilla/EMEUtils.h"
-#include "mozilla/PodOperations.h"
-
-#include "mozilla/dom/MediaKeys.h"
-#include "mozilla/dom/MediaKeySession.h"
-
-#include "mozIGeckoMediaPluginService.h"
-#include "nsContentCID.h"
-#include "nsIConsoleService.h"
-#include "nsPrintfCString.h"
-#include "nsServiceManagerUtils.h"
-#include "nsString.h"
-#include "prenv.h"
-#include "GMPCDMCallbackProxy.h"
-#include "GMPService.h"
-#include "MainThreadUtils.h"
-#include "MediaData.h"
-
-namespace mozilla {
-
-GMPCDMProxy::GMPCDMProxy(dom::MediaKeys* aKeys,
- const nsAString& aKeySystem,
- GMPCrashHelper* aCrashHelper,
- bool aDistinctiveIdentifierRequired,
- bool aPersistentStateRequired)
- : CDMProxy(aKeys,
- aKeySystem,
- aDistinctiveIdentifierRequired,
- aPersistentStateRequired)
- , mCrashHelper(aCrashHelper)
- , mCDM(nullptr)
- , mDecryptionJobCount(0)
- , mShutdownCalled(false)
- , mDecryptorId(0)
- , mCreatePromiseId(0)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_COUNT_CTOR(GMPCDMProxy);
-}
-
-GMPCDMProxy::~GMPCDMProxy()
-{
- MOZ_COUNT_DTOR(GMPCDMProxy);
-}
-
-void
-GMPCDMProxy::Init(PromiseId aPromiseId,
- const nsAString& aOrigin,
- const nsAString& aTopLevelOrigin,
- const nsAString& aGMPName,
- bool aInPrivateBrowsing)
-{
- MOZ_ASSERT(NS_IsMainThread());
- NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
-
- EME_LOG("GMPCDMProxy::Init (%s, %s) %s",
- NS_ConvertUTF16toUTF8(aOrigin).get(),
- NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
- (aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"));
-
- nsCString pluginVersion;
- if (!mOwnerThread) {
- nsCOMPtr<mozIGeckoMediaPluginService> mps =
- do_GetService("@mozilla.org/gecko-media-plugin-service;1");
- if (!mps) {
- RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::Init"));
- return;
- }
- mps->GetThread(getter_AddRefs(mOwnerThread));
- if (!mOwnerThread) {
- RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get GMP thread GMPCDMProxy::Init"));
- return;
- }
- }
-
- if (aGMPName.IsEmpty()) {
- RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- nsPrintfCString("Unknown GMP for keysystem '%s'", NS_ConvertUTF16toUTF8(mKeySystem).get()));
- return;
- }
-
- nsAutoPtr<InitData> data(new InitData());
- data->mPromiseId = aPromiseId;
- data->mOrigin = aOrigin;
- data->mTopLevelOrigin = aTopLevelOrigin;
- data->mGMPName = aGMPName;
- data->mInPrivateBrowsing = aInPrivateBrowsing;
- data->mCrashHelper = mCrashHelper;
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<nsAutoPtr<InitData>>(this,
- &GMPCDMProxy::gmp_Init,
- Move(data)));
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
-}
-
-#ifdef DEBUG
-bool
-GMPCDMProxy::IsOnOwnerThread()
-{
- return NS_GetCurrentThread() == mOwnerThread;
-}
-#endif
-
-void
-GMPCDMProxy::gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData)
-{
- EME_LOG("GMPCDMProxy::gmp_InitDone");
- if (mShutdownCalled) {
- if (aCDM) {
- aCDM->Close();
- }
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("GMPCDMProxy was shut down before init could complete"));
- return;
- }
- if (!aCDM) {
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("GetGMPDecryptor failed to return a CDM"));
- return;
- }
-
- mCDM = aCDM;
- mCallback = new GMPCDMCallbackProxy(this);
- mCDM->Init(mCallback,
- mDistinctiveIdentifierRequired,
- mPersistentStateRequired);
-
- // Await the OnSetDecryptorId callback.
- mCreatePromiseId = aData->mPromiseId;
-}
-
-void GMPCDMProxy::OnSetDecryptorId(uint32_t aId)
-{
- MOZ_ASSERT(mCreatePromiseId);
- mDecryptorId = aId;
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<uint32_t>(this,
- &GMPCDMProxy::OnCDMCreated,
- mCreatePromiseId));
- NS_DispatchToMainThread(task);
-}
-
-class gmp_InitDoneCallback : public GetGMPDecryptorCallback
-{
-public:
- gmp_InitDoneCallback(GMPCDMProxy* aGMPCDMProxy,
- nsAutoPtr<GMPCDMProxy::InitData>&& aData)
- : mGMPCDMProxy(aGMPCDMProxy),
- mData(Move(aData))
- {
- }
-
- void Done(GMPDecryptorProxy* aCDM)
- {
- mGMPCDMProxy->gmp_InitDone(aCDM, Move(mData));
- }
-
-private:
- RefPtr<GMPCDMProxy> mGMPCDMProxy;
- nsAutoPtr<GMPCDMProxy::InitData> mData;
-};
-
-class gmp_InitGetGMPDecryptorCallback : public GetNodeIdCallback
-{
-public:
- gmp_InitGetGMPDecryptorCallback(GMPCDMProxy* aGMPCDMProxy,
- nsAutoPtr<GMPCDMProxy::InitData>&& aData)
- : mGMPCDMProxy(aGMPCDMProxy),
- mData(aData)
- {
- }
-
- void Done(nsresult aResult, const nsACString& aNodeId)
- {
- mGMPCDMProxy->gmp_InitGetGMPDecryptor(aResult, aNodeId, Move(mData));
- }
-
-private:
- RefPtr<GMPCDMProxy> mGMPCDMProxy;
- nsAutoPtr<GMPCDMProxy::InitData> mData;
-};
-
-void
-GMPCDMProxy::gmp_Init(nsAutoPtr<InitData>&& aData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
-
- nsCOMPtr<mozIGeckoMediaPluginService> mps =
- do_GetService("@mozilla.org/gecko-media-plugin-service;1");
- if (!mps) {
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::gmp_Init"));
- return;
- }
-
- // Make a copy before we transfer ownership of aData to the
- // gmp_InitGetGMPDecryptorCallback.
- InitData data(*aData);
- UniquePtr<GetNodeIdCallback> callback(
- new gmp_InitGetGMPDecryptorCallback(this, Move(aData)));
- nsresult rv = mps->GetNodeId(data.mOrigin,
- data.mTopLevelOrigin,
- data.mGMPName,
- data.mInPrivateBrowsing,
- Move(callback));
- if (NS_FAILED(rv)) {
- RejectPromise(data.mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Call to GetNodeId() failed early"));
- }
-}
-
-void
-GMPCDMProxy::gmp_InitGetGMPDecryptor(nsresult aResult,
- const nsACString& aNodeId,
- nsAutoPtr<InitData>&& aData)
-{
- uint32_t promiseID = aData->mPromiseId;
- if (NS_FAILED(aResult)) {
- RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("GetNodeId() called back, but with a failure result"));
- return;
- }
-
- mNodeId = aNodeId;
- MOZ_ASSERT(!GetNodeId().IsEmpty());
-
- nsCOMPtr<mozIGeckoMediaPluginService> mps =
- do_GetService("@mozilla.org/gecko-media-plugin-service;1");
- if (!mps) {
- RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::gmp_InitGetGMPDecryptor"));
- return;
- }
-
- EME_LOG("GMPCDMProxy::gmp_Init (%s, %s) %s NodeId=%s",
- NS_ConvertUTF16toUTF8(aData->mOrigin).get(),
- NS_ConvertUTF16toUTF8(aData->mTopLevelOrigin).get(),
- (aData->mInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"),
- GetNodeId().get());
-
- nsTArray<nsCString> tags;
- tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
-
- // Note: must capture helper refptr here, before the Move()
- // when we create the GetGMPDecryptorCallback below.
- RefPtr<GMPCrashHelper> crashHelper = Move(aData->mCrashHelper);
- UniquePtr<GetGMPDecryptorCallback> callback(new gmp_InitDoneCallback(this,
- Move(aData)));
- nsresult rv = mps->GetGMPDecryptor(crashHelper,
- &tags,
- GetNodeId(),
- Move(callback));
- if (NS_FAILED(rv)) {
- RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Call to GetGMPDecryptor() failed early"));
- }
-}
-
-void
-GMPCDMProxy::OnCDMCreated(uint32_t aPromiseId)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mKeys.IsNull()) {
- return;
- }
- MOZ_ASSERT(!GetNodeId().IsEmpty());
- if (mCDM) {
- mKeys->OnCDMCreated(aPromiseId, GetNodeId(), mCDM->GetPluginId());
- } else {
- // No CDM? Just reject the promise.
- mKeys->RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Null CDM in OnCDMCreated()"));
- }
-}
-
-void
-GMPCDMProxy::CreateSession(uint32_t aCreateSessionToken,
- dom::MediaKeySessionType aSessionType,
- PromiseId aPromiseId,
- const nsAString& aInitDataType,
- nsTArray<uint8_t>& aInitData)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(mOwnerThread);
-
- nsAutoPtr<CreateSessionData> data(new CreateSessionData());
- data->mSessionType = aSessionType;
- data->mCreateSessionToken = aCreateSessionToken;
- data->mPromiseId = aPromiseId;
- data->mInitDataType = NS_ConvertUTF16toUTF8(aInitDataType);
- data->mInitData = Move(aInitData);
-
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<nsAutoPtr<CreateSessionData>>(this, &GMPCDMProxy::gmp_CreateSession, data));
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
-}
-
-GMPSessionType
-ToGMPSessionType(dom::MediaKeySessionType aSessionType) {
- switch (aSessionType) {
- case dom::MediaKeySessionType::Temporary: return kGMPTemporySession;
- case dom::MediaKeySessionType::Persistent_license: return kGMPPersistentSession;
- default: return kGMPTemporySession;
- };
-};
-
-void
-GMPCDMProxy::gmp_CreateSession(nsAutoPtr<CreateSessionData> aData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
- if (!mCDM) {
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Null CDM in gmp_CreateSession"));
- return;
- }
- mCDM->CreateSession(aData->mCreateSessionToken,
- aData->mPromiseId,
- aData->mInitDataType,
- aData->mInitData,
- ToGMPSessionType(aData->mSessionType));
-}
-
-void
-GMPCDMProxy::LoadSession(PromiseId aPromiseId,
- const nsAString& aSessionId)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(mOwnerThread);
-
- nsAutoPtr<SessionOpData> data(new SessionOpData());
- data->mPromiseId = aPromiseId;
- data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_LoadSession, data));
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
-}
-
-void
-GMPCDMProxy::gmp_LoadSession(nsAutoPtr<SessionOpData> aData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
-
- if (!mCDM) {
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Null CDM in gmp_LoadSession"));
- return;
- }
- mCDM->LoadSession(aData->mPromiseId, aData->mSessionId);
-}
-
-void
-GMPCDMProxy::SetServerCertificate(PromiseId aPromiseId,
- nsTArray<uint8_t>& aCert)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(mOwnerThread);
-
- nsAutoPtr<SetServerCertificateData> data(new SetServerCertificateData());
- data->mPromiseId = aPromiseId;
- data->mCert = Move(aCert);
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<nsAutoPtr<SetServerCertificateData>>(this, &GMPCDMProxy::gmp_SetServerCertificate, data));
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
-}
-
-void
-GMPCDMProxy::gmp_SetServerCertificate(nsAutoPtr<SetServerCertificateData> aData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
- if (!mCDM) {
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Null CDM in gmp_SetServerCertificate"));
- return;
- }
- mCDM->SetServerCertificate(aData->mPromiseId, aData->mCert);
-}
-
-void
-GMPCDMProxy::UpdateSession(const nsAString& aSessionId,
- PromiseId aPromiseId,
- nsTArray<uint8_t>& aResponse)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(mOwnerThread);
- NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
-
- nsAutoPtr<UpdateSessionData> data(new UpdateSessionData());
- data->mPromiseId = aPromiseId;
- data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
- data->mResponse = Move(aResponse);
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<nsAutoPtr<UpdateSessionData>>(this, &GMPCDMProxy::gmp_UpdateSession, data));
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
-}
-
-void
-GMPCDMProxy::gmp_UpdateSession(nsAutoPtr<UpdateSessionData> aData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
- if (!mCDM) {
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Null CDM in gmp_UpdateSession"));
- return;
- }
- mCDM->UpdateSession(aData->mPromiseId,
- aData->mSessionId,
- aData->mResponse);
-}
-
-void
-GMPCDMProxy::CloseSession(const nsAString& aSessionId,
- PromiseId aPromiseId)
-{
- MOZ_ASSERT(NS_IsMainThread());
- NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
-
- nsAutoPtr<SessionOpData> data(new SessionOpData());
- data->mPromiseId = aPromiseId;
- data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_CloseSession, data));
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
-}
-
-void
-GMPCDMProxy::gmp_CloseSession(nsAutoPtr<SessionOpData> aData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
- if (!mCDM) {
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Null CDM in gmp_CloseSession"));
- return;
- }
- mCDM->CloseSession(aData->mPromiseId, aData->mSessionId);
-}
-
-void
-GMPCDMProxy::RemoveSession(const nsAString& aSessionId,
- PromiseId aPromiseId)
-{
- MOZ_ASSERT(NS_IsMainThread());
- NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
-
- nsAutoPtr<SessionOpData> data(new SessionOpData());
- data->mPromiseId = aPromiseId;
- data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId);
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_RemoveSession, data));
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
-}
-
-void
-GMPCDMProxy::gmp_RemoveSession(nsAutoPtr<SessionOpData> aData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
- if (!mCDM) {
- RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
- NS_LITERAL_CSTRING("Null CDM in gmp_RemoveSession"));
- return;
- }
- mCDM->RemoveSession(aData->mPromiseId, aData->mSessionId);
-}
-
-void
-GMPCDMProxy::Shutdown()
-{
- MOZ_ASSERT(NS_IsMainThread());
- mKeys.Clear();
- // Note: This may end up being the last owning reference to the GMPCDMProxy.
- nsCOMPtr<nsIRunnable> task(NewRunnableMethod(this, &GMPCDMProxy::gmp_Shutdown));
- if (mOwnerThread) {
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
- }
-}
-
-void
-GMPCDMProxy::gmp_Shutdown()
-{
- MOZ_ASSERT(IsOnOwnerThread());
-
- mShutdownCalled = true;
-
- // Abort any pending decrypt jobs, to awaken any clients waiting on a job.
- for (size_t i = 0; i < mDecryptionJobs.Length(); i++) {
- DecryptJob* job = mDecryptionJobs[i];
- job->PostResult(AbortedErr);
- }
- mDecryptionJobs.Clear();
-
- if (mCDM) {
- mCDM->Close();
- mCDM = nullptr;
- }
-}
-
-void
-GMPCDMProxy::RejectPromise(PromiseId aId, nsresult aCode,
- const nsCString& aReason)
-{
- if (NS_IsMainThread()) {
- if (!mKeys.IsNull()) {
- mKeys->RejectPromise(aId, aCode, aReason);
- }
- } else {
- nsCOMPtr<nsIRunnable> task(new RejectPromiseTask(this, aId, aCode,
- aReason));
- NS_DispatchToMainThread(task);
- }
-}
-
-void
-GMPCDMProxy::ResolvePromise(PromiseId aId)
-{
- if (NS_IsMainThread()) {
- if (!mKeys.IsNull()) {
- mKeys->ResolvePromise(aId);
- } else {
- NS_WARNING("GMPCDMProxy unable to resolve promise!");
- }
- } else {
- nsCOMPtr<nsIRunnable> task;
- task = NewRunnableMethod<PromiseId>(this,
- &GMPCDMProxy::ResolvePromise,
- aId);
- NS_DispatchToMainThread(task);
- }
-}
-
-const nsCString&
-GMPCDMProxy::GetNodeId() const
-{
- return mNodeId;
-}
-
-void
-GMPCDMProxy::OnSetSessionId(uint32_t aCreateSessionToken,
- const nsAString& aSessionId)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mKeys.IsNull()) {
- return;
- }
-
- RefPtr<dom::MediaKeySession> session(mKeys->GetPendingSession(aCreateSessionToken));
- if (session) {
- session->SetSessionId(aSessionId);
- }
-}
-
-void
-GMPCDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mKeys.IsNull()) {
- return;
- }
- mKeys->OnSessionLoaded(aPromiseId, aSuccess);
-}
-
-void
-GMPCDMProxy::OnSessionMessage(const nsAString& aSessionId,
- dom::MediaKeyMessageType aMessageType,
- nsTArray<uint8_t>& aMessage)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mKeys.IsNull()) {
- return;
- }
- RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
- if (session) {
- session->DispatchKeyMessage(aMessageType, aMessage);
- }
-}
-
-void
-GMPCDMProxy::OnKeyStatusesChange(const nsAString& aSessionId)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mKeys.IsNull()) {
- return;
- }
- RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
- if (session) {
- session->DispatchKeyStatusesChange();
- }
-}
-
-void
-GMPCDMProxy::OnExpirationChange(const nsAString& aSessionId,
- GMPTimestamp aExpiryTime)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mKeys.IsNull()) {
- return;
- }
- RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
- if (session) {
- session->SetExpiration(static_cast<double>(aExpiryTime));
- }
-}
-
-void
-GMPCDMProxy::OnSessionClosed(const nsAString& aSessionId)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mKeys.IsNull()) {
- return;
- }
- RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
- if (session) {
- session->OnClosed();
- }
-}
-
-void
-GMPCDMProxy::OnDecrypted(uint32_t aId,
- DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
- gmp_Decrypted(aId, aResult, aDecryptedData);
-}
-
-static void
-LogToConsole(const nsAString& aMsg)
-{
- nsCOMPtr<nsIConsoleService> console(
- do_GetService("@mozilla.org/consoleservice;1"));
- if (!console) {
- NS_WARNING("Failed to log message to console.");
- return;
- }
- nsAutoString msg(aMsg);
- console->LogStringMessage(msg.get());
-}
-
-void
-GMPCDMProxy::OnSessionError(const nsAString& aSessionId,
- nsresult aException,
- uint32_t aSystemCode,
- const nsAString& aMsg)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mKeys.IsNull()) {
- return;
- }
- RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
- if (session) {
- session->DispatchKeyError(aSystemCode);
- }
- LogToConsole(aMsg);
-}
-
-void
-GMPCDMProxy::OnRejectPromise(uint32_t aPromiseId,
- nsresult aDOMException,
- const nsCString& aMsg)
-{
- MOZ_ASSERT(NS_IsMainThread());
- RejectPromise(aPromiseId, aDOMException, aMsg);
-}
-
-const nsString&
-GMPCDMProxy::KeySystem() const
-{
- return mKeySystem;
-}
-
-CDMCaps&
-GMPCDMProxy::Capabilites() {
- return mCapabilites;
-}
-
-RefPtr<GMPCDMProxy::DecryptPromise>
-GMPCDMProxy::Decrypt(MediaRawData* aSample)
-{
- RefPtr<DecryptJob> job(new DecryptJob(aSample));
- RefPtr<DecryptPromise> promise(job->Ensure());
-
- nsCOMPtr<nsIRunnable> task(
- NewRunnableMethod<RefPtr<DecryptJob>>(this, &GMPCDMProxy::gmp_Decrypt, job));
- mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL);
- return promise;
-}
-
-void
-GMPCDMProxy::gmp_Decrypt(RefPtr<DecryptJob> aJob)
-{
- MOZ_ASSERT(IsOnOwnerThread());
-
- if (!mCDM) {
- aJob->PostResult(AbortedErr);
- return;
- }
-
- aJob->mId = ++mDecryptionJobCount;
- nsTArray<uint8_t> data;
- data.AppendElements(aJob->mSample->Data(), aJob->mSample->Size());
- mCDM->Decrypt(aJob->mId, aJob->mSample->mCrypto, data);
- mDecryptionJobs.AppendElement(aJob.forget());
-}
-
-void
-GMPCDMProxy::gmp_Decrypted(uint32_t aId,
- DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData)
-{
- MOZ_ASSERT(IsOnOwnerThread());
-#ifdef DEBUG
- bool jobIdFound = false;
-#endif
- for (size_t i = 0; i < mDecryptionJobs.Length(); i++) {
- DecryptJob* job = mDecryptionJobs[i];
- if (job->mId == aId) {
-#ifdef DEBUG
- jobIdFound = true;
-#endif
- job->PostResult(aResult, aDecryptedData);
- mDecryptionJobs.RemoveElementAt(i);
- }
- }
-#ifdef DEBUG
- if (!jobIdFound) {
- NS_WARNING("GMPDecryptorChild returned incorrect job ID");
- }
-#endif
-}
-
-void
-GMPCDMProxy::DecryptJob::PostResult(DecryptStatus aResult)
-{
- nsTArray<uint8_t> empty;
- PostResult(aResult, empty);
-}
-
-void
-GMPCDMProxy::DecryptJob::PostResult(DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData)
-{
- if (aDecryptedData.Length() != mSample->Size()) {
- NS_WARNING("CDM returned incorrect number of decrypted bytes");
- }
- if (aResult == Ok) {
- nsAutoPtr<MediaRawDataWriter> writer(mSample->CreateWriter());
- PodCopy(writer->Data(),
- aDecryptedData.Elements(),
- std::min<size_t>(aDecryptedData.Length(), mSample->Size()));
- } else if (aResult == NoKeyErr) {
- NS_WARNING("CDM returned NoKeyErr");
- // We still have the encrypted sample, so we can re-enqueue it to be
- // decrypted again once the key is usable again.
- } else {
- nsAutoCString str("CDM returned decode failure DecryptStatus=");
- str.AppendInt(aResult);
- NS_WARNING(str.get());
- }
- mPromise.Resolve(DecryptResult(aResult, mSample), __func__);
-}
-
-void
-GMPCDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
- nsTArray<nsCString>& aSessionIds)
-{
- CDMCaps::AutoLock caps(Capabilites());
- caps.GetSessionIdsForKeyId(aKeyId, aSessionIds);
-}
-
-void
-GMPCDMProxy::Terminated()
-{
- MOZ_ASSERT(NS_IsMainThread());
- NS_WARNING("CDM terminated");
- if (mCreatePromiseId) {
- RejectPromise(mCreatePromiseId,
- NS_ERROR_DOM_MEDIA_FATAL_ERR,
- NS_LITERAL_CSTRING("Crashed waiting for CDM to initialize"));
- mCreatePromiseId = 0;
- }
- if (!mKeys.IsNull()) {
- mKeys->Terminated();
- }
-}
-
-uint32_t
-GMPCDMProxy::GetDecryptorId()
-{
- return mDecryptorId;
-}
-
-} // namespace mozilla
diff --git a/dom/media/gmp/GMPCDMProxy.h b/dom/media/gmp/GMPCDMProxy.h
deleted file mode 100644
index a7fae235b6..0000000000
--- a/dom/media/gmp/GMPCDMProxy.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef GMPCDMProxy_h_
-#define GMPCDMProxy_h_
-
-#include "mozilla/CDMProxy.h"
-#include "GMPCDMCallbackProxy.h"
-#include "GMPDecryptorProxy.h"
-
-namespace mozilla {
-class MediaRawData;
-
-// Implementation of CDMProxy which is based on GMP architecture.
-class GMPCDMProxy : public CDMProxy {
-public:
-
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPCDMProxy, override)
-
- typedef MozPromise<DecryptResult, DecryptResult, /* IsExclusive = */ true> DecryptPromise;
-
- GMPCDMProxy(dom::MediaKeys* aKeys,
- const nsAString& aKeySystem,
- GMPCrashHelper* aCrashHelper,
- bool aDistinctiveIdentifierRequired,
- bool aPersistentStateRequired);
-
- void Init(PromiseId aPromiseId,
- const nsAString& aOrigin,
- const nsAString& aTopLevelOrigin,
- const nsAString& aGMPName,
- bool aInPrivateBrowsing) override;
-
- void OnSetDecryptorId(uint32_t aId) override;
-
- void CreateSession(uint32_t aCreateSessionToken,
- dom::MediaKeySessionType aSessionType,
- PromiseId aPromiseId,
- const nsAString& aInitDataType,
- nsTArray<uint8_t>& aInitData) override;
-
- void LoadSession(PromiseId aPromiseId,
- const nsAString& aSessionId) override;
-
- void SetServerCertificate(PromiseId aPromiseId,
- nsTArray<uint8_t>& aCert) override;
-
- void UpdateSession(const nsAString& aSessionId,
- PromiseId aPromiseId,
- nsTArray<uint8_t>& aResponse) override;
-
- void CloseSession(const nsAString& aSessionId,
- PromiseId aPromiseId) override;
-
- void RemoveSession(const nsAString& aSessionId,
- PromiseId aPromiseId) override;
-
- void Shutdown() override;
-
- void Terminated() override;
-
- const nsCString& GetNodeId() const override;
-
- void OnSetSessionId(uint32_t aCreateSessionToken,
- const nsAString& aSessionId) override;
-
- void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess) override;
-
- void OnSessionMessage(const nsAString& aSessionId,
- dom::MediaKeyMessageType aMessageType,
- nsTArray<uint8_t>& aMessage) override;
-
- void OnExpirationChange(const nsAString& aSessionId,
- GMPTimestamp aExpiryTime) override;
-
- void OnSessionClosed(const nsAString& aSessionId) override;
-
- void OnSessionError(const nsAString& aSessionId,
- nsresult aException,
- uint32_t aSystemCode,
- const nsAString& aMsg) override;
-
- void OnRejectPromise(uint32_t aPromiseId,
- nsresult aDOMException,
- const nsCString& aMsg) override;
-
- RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) override;
-
- void OnDecrypted(uint32_t aId,
- DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData) override;
-
- void RejectPromise(PromiseId aId, nsresult aExceptionCode,
- const nsCString& aReason) override;
-
- void ResolvePromise(PromiseId aId) override;
-
- const nsString& KeySystem() const override;
-
- CDMCaps& Capabilites() override;
-
- void OnKeyStatusesChange(const nsAString& aSessionId) override;
-
- void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
- nsTArray<nsCString>& aSessionIds) override;
-
-#ifdef DEBUG
- bool IsOnOwnerThread() override;
-#endif
-
- uint32_t GetDecryptorId() override;
-
-private:
- friend class gmp_InitDoneCallback;
- friend class gmp_InitGetGMPDecryptorCallback;
-
- struct InitData {
- uint32_t mPromiseId;
- nsString mOrigin;
- nsString mTopLevelOrigin;
- nsString mGMPName;
- RefPtr<GMPCrashHelper> mCrashHelper;
- bool mInPrivateBrowsing;
- };
-
- // GMP thread only.
- void gmp_Init(nsAutoPtr<InitData>&& aData);
- void gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData);
- void gmp_InitGetGMPDecryptor(nsresult aResult,
- const nsACString& aNodeId,
- nsAutoPtr<InitData>&& aData);
-
- // GMP thread only.
- void gmp_Shutdown();
-
- // Main thread only.
- void OnCDMCreated(uint32_t aPromiseId);
-
- struct CreateSessionData {
- dom::MediaKeySessionType mSessionType;
- uint32_t mCreateSessionToken;
- PromiseId mPromiseId;
- nsCString mInitDataType;
- nsTArray<uint8_t> mInitData;
- };
- // GMP thread only.
- void gmp_CreateSession(nsAutoPtr<CreateSessionData> aData);
-
- struct SessionOpData {
- PromiseId mPromiseId;
- nsCString mSessionId;
- };
- // GMP thread only.
- void gmp_LoadSession(nsAutoPtr<SessionOpData> aData);
-
- struct SetServerCertificateData {
- PromiseId mPromiseId;
- nsTArray<uint8_t> mCert;
- };
- // GMP thread only.
- void gmp_SetServerCertificate(nsAutoPtr<SetServerCertificateData> aData);
-
- struct UpdateSessionData {
- PromiseId mPromiseId;
- nsCString mSessionId;
- nsTArray<uint8_t> mResponse;
- };
- // GMP thread only.
- void gmp_UpdateSession(nsAutoPtr<UpdateSessionData> aData);
-
- // GMP thread only.
- void gmp_CloseSession(nsAutoPtr<SessionOpData> aData);
-
- // GMP thread only.
- void gmp_RemoveSession(nsAutoPtr<SessionOpData> aData);
-
- class DecryptJob {
- public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecryptJob)
-
- explicit DecryptJob(MediaRawData* aSample)
- : mId(0)
- , mSample(aSample)
- {
- }
-
- void PostResult(DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData);
- void PostResult(DecryptStatus aResult);
-
- RefPtr<DecryptPromise> Ensure() {
- return mPromise.Ensure(__func__);
- }
-
- uint32_t mId;
- RefPtr<MediaRawData> mSample;
- private:
- ~DecryptJob() {}
- MozPromiseHolder<DecryptPromise> mPromise;
- };
- // GMP thread only.
- void gmp_Decrypt(RefPtr<DecryptJob> aJob);
-
- // GMP thread only.
- void gmp_Decrypted(uint32_t aId,
- DecryptStatus aResult,
- const nsTArray<uint8_t>& aDecryptedData);
-
- class RejectPromiseTask : public Runnable {
- public:
- RejectPromiseTask(GMPCDMProxy* aProxy,
- PromiseId aId,
- nsresult aCode,
- const nsCString& aReason)
- : mProxy(aProxy)
- , mId(aId)
- , mCode(aCode)
- , mReason(aReason)
- {
- }
- NS_IMETHOD Run() override {
- mProxy->RejectPromise(mId, mCode, mReason);
- return NS_OK;
- }
- private:
- RefPtr<GMPCDMProxy> mProxy;
- PromiseId mId;
- nsresult mCode;
- nsCString mReason;
- };
-
- ~GMPCDMProxy();
-
- GMPCrashHelper* mCrashHelper;
-
- GMPDecryptorProxy* mCDM;
-
- nsAutoPtr<GMPCDMCallbackProxy> mCallback;
-
- // Decryption jobs sent to CDM, awaiting result.
- // GMP thread only.
- nsTArray<RefPtr<DecryptJob>> mDecryptionJobs;
-
- // Number of buffers we've decrypted. Used to uniquely identify
- // decryption jobs sent to CDM. Note we can't just use the length of
- // mDecryptionJobs as that shrinks as jobs are completed and removed
- // from it.
- // GMP thread only.
- uint32_t mDecryptionJobCount;
-
- // True if GMPCDMProxy::gmp_Shutdown was called.
- // GMP thread only.
- bool mShutdownCalled;
-
- uint32_t mDecryptorId;
-
- PromiseId mCreatePromiseId;
-};
-
-
-} // namespace mozilla
-
-#endif // GMPCDMProxy_h_
diff --git a/dom/media/gmp/GMPChild.cpp b/dom/media/gmp/GMPChild.cpp
index fa6f2f4c83..0bf9d44036 100644
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -22,9 +22,6 @@
#include "GMPUtils.h"
#include "prio.h"
#include "base/task.h"
-#ifdef MOZ_EME
-#include "widevine-adapter/WidevineAdapter.h"
-#endif
using namespace mozilla::ipc;
@@ -256,13 +253,7 @@ GMPChild::AnswerStartPlugin(const nsString& aAdapter)
return false;
}
-#ifdef MOZ_EME
- bool isWidevine = aAdapter.EqualsLiteral("widevine");
-
- GMPAdapter* adapter = (isWidevine) ? new WidevineAdapter() : nullptr;
-#else
GMPAdapter* adapter = nullptr;
-#endif
if (!mGMPLoader->Load(libPath.get(),
libPath.Length(),
mNodeId.BeginWriting(),
diff --git a/dom/media/gmp/GMPDecryptorChild.cpp b/dom/media/gmp/GMPDecryptorChild.cpp
index 6da3c6c43e..a1b561ab59 100644
--- a/dom/media/gmp/GMPDecryptorChild.cpp
+++ b/dom/media/gmp/GMPDecryptorChild.cpp
@@ -73,11 +73,6 @@ GMPDecryptorChild::Init(GMPDecryptor* aSession)
{
MOZ_ASSERT(aSession);
mSession = aSession;
- // The ID of this decryptor is the IPDL actor ID. Note it's unique inside
- // the child process, but not necessarily across all gecko processes. However,
- // since GMPDecryptors are segregated by node ID/origin, we shouldn't end up
- // with clashes in the content process.
- SendSetDecryptorId(Id());
}
void
diff --git a/dom/media/gmp/GMPDecryptorParent.cpp b/dom/media/gmp/GMPDecryptorParent.cpp
index 56474e9736..c41d5d18f5 100644
--- a/dom/media/gmp/GMPDecryptorParent.cpp
+++ b/dom/media/gmp/GMPDecryptorParent.cpp
@@ -42,19 +42,6 @@ GMPDecryptorParent::~GMPDecryptorParent()
{
}
-bool
-GMPDecryptorParent::RecvSetDecryptorId(const uint32_t& aId)
-{
-#ifdef MOZ_EME
- if (!mIsOpen) {
- NS_WARNING("Trying to use a dead GMP decrypter!");
- return false;
- }
- mCallback->SetDecryptorId(aId);
-#endif
- return true;
-}
-
nsresult
GMPDecryptorParent::Init(GMPDecryptorProxyCallback* aCallback,
bool aDistinctiveIdentifierRequired,
diff --git a/dom/media/gmp/GMPDecryptorParent.h b/dom/media/gmp/GMPDecryptorParent.h
index 30ff246901..3acf7dbd96 100644
--- a/dom/media/gmp/GMPDecryptorParent.h
+++ b/dom/media/gmp/GMPDecryptorParent.h
@@ -72,8 +72,6 @@ private:
// PGMPDecryptorParent
- bool RecvSetDecryptorId(const uint32_t& aId) override;
-
bool RecvSetSessionId(const uint32_t& aCreateSessionToken,
const nsCString& aSessionId) override;
diff --git a/dom/media/gmp/GMPDecryptorProxy.h b/dom/media/gmp/GMPDecryptorProxy.h
index ed16755f89..f9e34a45fd 100644
--- a/dom/media/gmp/GMPDecryptorProxy.h
+++ b/dom/media/gmp/GMPDecryptorProxy.h
@@ -6,9 +6,6 @@
#ifndef GMPDecryptorProxy_h_
#define GMPDecryptorProxy_h_
-#ifdef MOZ_EME
-#include "mozilla/DecryptorProxyCallback.h"
-#endif
#include "GMPCallbackBase.h"
#include "gmp-decryption.h"
#include "nsString.h"
@@ -17,12 +14,7 @@ namespace mozilla {
class CryptoSample;
} // namespace mozilla
-#ifdef MOZ_EME
-class GMPDecryptorProxyCallback : public DecryptorProxyCallback,
- public GMPCallbackBase {
-#else
class GMPDecryptorProxyCallback : public GMPCallbackBase {
-#endif
public:
virtual ~GMPDecryptorProxyCallback() {}
diff --git a/dom/media/gmp/GMPParent.cpp b/dom/media/gmp/GMPParent.cpp
index e6f7972649..c4a7a84a09 100644
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -28,11 +28,6 @@ using mozilla::ipc::GeckoChildProcessHost;
#include "WMFDecoderModule.h"
#endif
-#ifdef MOZ_EME
-#include "mozilla/dom/WidevineCDMManifestBinding.h"
-#include "widevine-adapter/WidevineAdapter.h"
-#endif
-
namespace mozilla {
#undef LOG
@@ -654,18 +649,7 @@ GMPParent::ReadGMPMetaData()
return ReadGMPInfoFile(infoFile);
}
-#ifdef MOZ_EME
- // Maybe this is the Widevine adapted plugin?
- nsCOMPtr<nsIFile> manifestFile;
- rv = mDirectory->Clone(getter_AddRefs(manifestFile));
- if (NS_FAILED(rv)) {
- return GenericPromise::CreateAndReject(rv, __func__);
- }
- manifestFile->AppendRelativePath(NS_LITERAL_STRING("manifest.json"));
- return ReadChromiumManifestFile(manifestFile);
-#else
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
-#endif
}
RefPtr<GenericPromise>
@@ -758,48 +742,8 @@ GMPParent::ReadChromiumManifestFile(nsIFile* aFile)
RefPtr<GenericPromise>
GMPParent::ParseChromiumManifest(nsString aJSON)
{
-#ifdef MOZ_EME
- LOGD("%s: for '%s'", __FUNCTION__, NS_LossyConvertUTF16toASCII(aJSON).get());
-
- MOZ_ASSERT(NS_IsMainThread());
- mozilla::dom::WidevineCDMManifest m;
- if (!m.Init(aJSON)) {
- return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
- }
-
- nsresult ignored; // Note: ToInteger returns 0 on failure.
- if (!WidevineAdapter::Supports(m.mX_cdm_module_versions.ToInteger(&ignored),
- m.mX_cdm_interface_versions.ToInteger(&ignored),
- m.mX_cdm_host_versions.ToInteger(&ignored))) {
- return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
- }
-
- mDisplayName = NS_ConvertUTF16toUTF8(m.mName);
- mDescription = NS_ConvertUTF16toUTF8(m.mDescription);
- mVersion = NS_ConvertUTF16toUTF8(m.mVersion);
-
- GMPCapability video(NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER));
- video.mAPITags.AppendElement(NS_LITERAL_CSTRING("h264"));
- video.mAPITags.AppendElement(NS_LITERAL_CSTRING("vp8"));
- video.mAPITags.AppendElement(NS_LITERAL_CSTRING("vp9"));
- video.mAPITags.AppendElement(kEMEKeySystemWidevine);
- mCapabilities.AppendElement(Move(video));
-
- GMPCapability decrypt(NS_LITERAL_CSTRING(GMP_API_DECRYPTOR));
- decrypt.mAPITags.AppendElement(kEMEKeySystemWidevine);
- mCapabilities.AppendElement(Move(decrypt));
-
- MOZ_ASSERT(mName.EqualsLiteral("widevinecdm"));
- mAdapter = NS_LITERAL_STRING("widevine");
-#ifdef XP_WIN
- mLibs = NS_LITERAL_CSTRING("dxva2.dll");
-#endif
-
- return GenericPromise::CreateAndResolve(true, __func__);
-#else // !MOZ_EME
MOZ_ASSERT_UNREACHABLE("don't call me if EME isn't enabled");
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
-#endif // !MOZ_EME
}
bool
diff --git a/dom/media/gmp/PGMPDecryptor.ipdl b/dom/media/gmp/PGMPDecryptor.ipdl
index 06b9b9cb60..207933e8a6 100644
--- a/dom/media/gmp/PGMPDecryptor.ipdl
+++ b/dom/media/gmp/PGMPDecryptor.ipdl
@@ -53,8 +53,6 @@ child:
parent:
async __delete__();
- async SetDecryptorId(uint32_t aId);
-
async SetSessionId(uint32_t aCreateSessionToken,
nsCString aSessionId);
diff --git a/dom/media/gmp/moz.build b/dom/media/gmp/moz.build
index c4da2573fb..82d091168d 100644
--- a/dom/media/gmp/moz.build
+++ b/dom/media/gmp/moz.build
@@ -70,12 +70,6 @@ EXPORTS += [
'GMPVideoPlaneImpl.h',
]
-if CONFIG['MOZ_EME']:
- EXPORTS += [
- 'GMPCDMCallbackProxy.h',
- 'GMPCDMProxy.h',
- ]
-
UNIFIED_SOURCES += [
'GMPAudioDecoderChild.cpp',
'GMPAudioDecoderParent.cpp',
@@ -111,17 +105,8 @@ UNIFIED_SOURCES += [
'GMPVideoPlaneImpl.cpp',
]
-if CONFIG['MOZ_EME']:
- UNIFIED_SOURCES += [
- 'GMPCDMCallbackProxy.cpp',
- 'GMPCDMProxy.cpp',
- ]
-
DIRS += ['rlz']
-if CONFIG['MOZ_EME']:
- DIRS += ['widevine-adapter']
-
IPDL_SOURCES += [
'GMPTypes.ipdlh',
'PGMP.ipdl',
diff --git a/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp b/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp
deleted file mode 100644
index 57d4ecec27..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "WidevineAdapter.h"
-#include "content_decryption_module.h"
-#include "VideoUtils.h"
-#include "WidevineDecryptor.h"
-#include "WidevineUtils.h"
-#include "WidevineVideoDecoder.h"
-#include "gmp-api/gmp-entrypoints.h"
-#include "gmp-api/gmp-decryption.h"
-#include "gmp-api/gmp-video-codec.h"
-#include "gmp-api/gmp-platform.h"
-
-static const GMPPlatformAPI* sPlatform = nullptr;
-
-namespace mozilla {
-
-GMPErr GMPGetCurrentTime(GMPTimestamp* aOutTime) {
- return sPlatform->getcurrenttime(aOutTime);
-}
-
-// Call on main thread only.
-GMPErr GMPSetTimerOnMainThread(GMPTask* aTask, int64_t aTimeoutMS) {
- return sPlatform->settimer(aTask, aTimeoutMS);
-}
-
-GMPErr GMPCreateRecord(const char* aRecordName,
- uint32_t aRecordNameSize,
- GMPRecord** aOutRecord,
- GMPRecordClient* aClient)
-{
- return sPlatform->createrecord(aRecordName, aRecordNameSize, aOutRecord, aClient);
-}
-
-void
-WidevineAdapter::SetAdaptee(PRLibrary* aLib)
-{
- mLib = aLib;
-}
-
-void* GetCdmHost(int aHostInterfaceVersion, void* aUserData)
-{
- Log("GetCdmHostFunc(%d, %p)", aHostInterfaceVersion, aUserData);
- WidevineDecryptor* decryptor = reinterpret_cast<WidevineDecryptor*>(aUserData);
- MOZ_ASSERT(decryptor);
- return static_cast<cdm::Host_9*>(decryptor);
-}
-
-#define STRINGIFY(s) _STRINGIFY(s)
-#define _STRINGIFY(s) #s
-
-GMPErr
-WidevineAdapter::GMPInit(const GMPPlatformAPI* aPlatformAPI)
-{
-#ifdef ENABLE_WIDEVINE_LOG
- if (getenv("GMP_LOG_FILE")) {
- // Clear log file.
- FILE* f = fopen(getenv("GMP_LOG_FILE"), "w");
- if (f) {
- fclose(f);
- }
- }
-#endif
-
- sPlatform = aPlatformAPI;
- if (!mLib) {
- return GMPGenericErr;
- }
-
- auto init = reinterpret_cast<decltype(::INITIALIZE_CDM_MODULE)*>(
- PR_FindFunctionSymbol(mLib, STRINGIFY(INITIALIZE_CDM_MODULE)));
- if (!init) {
- return GMPGenericErr;
- }
-
- Log(STRINGIFY(INITIALIZE_CDM_MODULE)"()");
- init();
-
- return GMPNoErr;
-}
-
-GMPErr
-WidevineAdapter::GMPGetAPI(const char* aAPIName,
- void* aHostAPI,
- void** aPluginAPI,
- uint32_t aDecryptorId)
-{
- Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p",
- aAPIName, aHostAPI, aPluginAPI, this, aDecryptorId);
- if (!strcmp(aAPIName, GMP_API_DECRYPTOR)) {
- if (WidevineDecryptor::GetInstance(aDecryptorId)) {
- // We only support one CDM instance per PGMPDecryptor. Fail!
- Log("WidevineAdapter::GMPGetAPI() Tried to create more than once CDM per IPDL actor! FAIL!");
- return GMPQuotaExceededErr;
- }
- auto create = reinterpret_cast<decltype(::CreateCdmInstance)*>(
- PR_FindFunctionSymbol(mLib, "CreateCdmInstance"));
- if (!create) {
- Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p FAILED to find CreateCdmInstance",
- aAPIName, aHostAPI, aPluginAPI, this, aDecryptorId);
- return GMPGenericErr;
- }
-
- WidevineDecryptor* decryptor = new WidevineDecryptor();
-
- auto cdm = reinterpret_cast<cdm::ContentDecryptionModule_9*>(
- create(cdm::ContentDecryptionModule_9::kVersion,
- kEMEKeySystemWidevine.get(),
- kEMEKeySystemWidevine.Length(),
- &GetCdmHost,
- decryptor));
- if (!cdm) {
- Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p FAILED to create cdm",
- aAPIName, aHostAPI, aPluginAPI, this, aDecryptorId);
- return GMPGenericErr;
- }
- Log("cdm: 0x%x", cdm);
- RefPtr<CDMWrapper> wrapper(new CDMWrapper(cdm, decryptor));
- decryptor->SetCDM(wrapper, aDecryptorId);
- *aPluginAPI = decryptor;
-
- } else if (!strcmp(aAPIName, GMP_API_VIDEO_DECODER)) {
- RefPtr<CDMWrapper> wrapper = WidevineDecryptor::GetInstance(aDecryptorId);
- if (!wrapper) {
- Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p No cdm for video decoder",
- aAPIName, aHostAPI, aPluginAPI, thiss, aDecryptorId);
- return GMPGenericErr;
- }
- *aPluginAPI = new WidevineVideoDecoder(static_cast<GMPVideoHost*>(aHostAPI),
- wrapper);
- }
- return *aPluginAPI ? GMPNoErr : GMPNotImplementedErr;
-}
-
-void
-WidevineAdapter::GMPShutdown()
-{
- Log("WidevineAdapter::GMPShutdown()");
-
- decltype(::DeinitializeCdmModule)* deinit;
- deinit = (decltype(deinit))(PR_FindFunctionSymbol(mLib, "DeinitializeCdmModule"));
- if (deinit) {
- Log("DeinitializeCdmModule()");
- deinit();
- }
-}
-
-void
-WidevineAdapter::GMPSetNodeId(const char* aNodeId, uint32_t aLength)
-{
-
-}
-
-/* static */
-bool
-WidevineAdapter::Supports(int32_t aModuleVersion,
- int32_t aInterfaceVersion,
- int32_t aHostVersion)
-{
- return aModuleVersion == CDM_MODULE_VERSION &&
- aInterfaceVersion == cdm::ContentDecryptionModule_9::kVersion &&
- aHostVersion == cdm::Host_9::kVersion;
-}
-
-} // namespace mozilla
diff --git a/dom/media/gmp/widevine-adapter/WidevineAdapter.h b/dom/media/gmp/widevine-adapter/WidevineAdapter.h
deleted file mode 100644
index 714e041bef..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineAdapter.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef WidevineAdapter_h_
-#define WidevineAdapter_h_
-
-#include "GMPLoader.h"
-#include "prlink.h"
-#include "GMPUtils.h"
-
-struct GMPPlatformAPI;
-
-namespace mozilla {
-
-class WidevineAdapter : public gmp::GMPAdapter {
-public:
-
- void SetAdaptee(PRLibrary* aLib) override;
-
- // These are called in place of the corresponding GMP API functions.
- GMPErr GMPInit(const GMPPlatformAPI* aPlatformAPI) override;
- GMPErr GMPGetAPI(const char* aAPIName,
- void* aHostAPI,
- void** aPluginAPI,
- uint32_t aDecryptorId) override;
- void GMPShutdown() override;
- void GMPSetNodeId(const char* aNodeId, uint32_t aLength) override;
-
- static bool Supports(int32_t aModuleVersion,
- int32_t aInterfaceVersion,
- int32_t aHostVersion);
-
-private:
- PRLibrary* mLib = nullptr;
-};
-
-GMPErr GMPCreateThread(GMPThread** aThread);
-GMPErr GMPRunOnMainThread(GMPTask* aTask);
-GMPErr GMPCreateMutex(GMPMutex** aMutex);
-
-// Call on main thread only.
-GMPErr GMPCreateRecord(const char* aRecordName,
- uint32_t aRecordNameSize,
- GMPRecord** aOutRecord,
- GMPRecordClient* aClient);
-
-// Call on main thread only.
-GMPErr GMPSetTimerOnMainThread(GMPTask* aTask, int64_t aTimeoutMS);
-
-GMPErr GMPGetCurrentTime(GMPTimestamp* aOutTime);
-
-GMPErr GMPCreateRecordIterator(RecvGMPRecordIteratorPtr aRecvIteratorFunc,
- void* aUserArg);
-
-} // namespace mozilla
-
-#endif // WidevineAdapter_h_
diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp
deleted file mode 100644
index 4d3408804f..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp
+++ /dev/null
@@ -1,554 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "WidevineDecryptor.h"
-
-#include "WidevineAdapter.h"
-#include "WidevineUtils.h"
-#include "WidevineFileIO.h"
-#include <mozilla/SizePrintfMacros.h>
-#include <stdarg.h>
-#include "base/time.h"
-
-using namespace cdm;
-using namespace std;
-
-namespace mozilla {
-
-static map<uint32_t, RefPtr<CDMWrapper>> sDecryptors;
-
-/* static */
-RefPtr<CDMWrapper>
-WidevineDecryptor::GetInstance(uint32_t aInstanceId)
-{
- auto itr = sDecryptors.find(aInstanceId);
- if (itr != sDecryptors.end()) {
- return itr->second;
- }
- return nullptr;
-}
-
-
-WidevineDecryptor::WidevineDecryptor()
- : mCallback(nullptr)
-{
- Log("WidevineDecryptor created this=%p", this);
- AddRef(); // Released in DecryptingComplete().
-}
-
-WidevineDecryptor::~WidevineDecryptor()
-{
- Log("WidevineDecryptor destroyed this=%p", this);
-}
-
-void
-WidevineDecryptor::SetCDM(RefPtr<CDMWrapper> aCDM, uint32_t aInstanceId)
-{
- mCDM = aCDM;
- mInstanceId = aInstanceId;
- sDecryptors[mInstanceId] = aCDM;
-}
-
-void
-WidevineDecryptor::Init(GMPDecryptorCallback* aCallback,
- bool aDistinctiveIdentifierRequired,
- bool aPersistentStateRequired)
-{
- Log("WidevineDecryptor::Init() this=%p distinctiveId=%d persistentState=%d",
- this, aDistinctiveIdentifierRequired, aPersistentStateRequired);
- MOZ_ASSERT(aCallback);
- mCallback = aCallback;
- MOZ_ASSERT(mCDM);
- mDistinctiveIdentifierRequired = aDistinctiveIdentifierRequired;
- mPersistentStateRequired = aPersistentStateRequired;
- if (CDM()) {
- CDM()->Initialize(aDistinctiveIdentifierRequired,
- aPersistentStateRequired);
- }
-}
-
-static SessionType
-ToCDMSessionType(GMPSessionType aSessionType)
-{
- switch (aSessionType) {
- case kGMPTemporySession: return kTemporary;
- case kGMPPersistentSession: return kPersistentLicense;
- case kGMPSessionInvalid: return kTemporary;
- // TODO: kPersistentKeyRelease
- }
- MOZ_ASSERT(false); // Not supposed to get here.
- return kTemporary;
-}
-
-void
-WidevineDecryptor::CreateSession(uint32_t aCreateSessionToken,
- uint32_t aPromiseId,
- const char* aInitDataType,
- uint32_t aInitDataTypeSize,
- const uint8_t* aInitData,
- uint32_t aInitDataSize,
- GMPSessionType aSessionType)
-{
- Log("Decryptor::CreateSession(token=%d, pid=%d)", aCreateSessionToken, aPromiseId);
- InitDataType initDataType;
- if (!strcmp(aInitDataType, "cenc")) {
- initDataType = kCenc;
- } else if (!strcmp(aInitDataType, "webm")) {
- initDataType = kWebM;
- } else if (!strcmp(aInitDataType, "keyids")) {
- initDataType = kKeyIds;
- } else {
- // Invalid init data type
- const char* errorMsg = "Invalid init data type when creating session.";
- OnRejectPromise(aPromiseId, kExceptionNotSupportedError, 0, errorMsg, sizeof(errorMsg));
- return;
- }
- mPromiseIdToNewSessionTokens[aPromiseId] = aCreateSessionToken;
- CDM()->CreateSessionAndGenerateRequest(aPromiseId,
- ToCDMSessionType(aSessionType),
- initDataType,
- aInitData, aInitDataSize);
-}
-
-void
-WidevineDecryptor::LoadSession(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdLength)
-{
- Log("Decryptor::LoadSession(pid=%d, %s)", aPromiseId, aSessionId);
- // TODO: session type??
- CDM()->LoadSession(aPromiseId, kPersistentLicense, aSessionId, aSessionIdLength);
-}
-
-void
-WidevineDecryptor::UpdateSession(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdLength,
- const uint8_t* aResponse,
- uint32_t aResponseSize)
-{
- Log("Decryptor::UpdateSession(pid=%d, session=%s)", aPromiseId, aSessionId);
- CDM()->UpdateSession(aPromiseId, aSessionId, aSessionIdLength, aResponse, aResponseSize);
-}
-
-void
-WidevineDecryptor::CloseSession(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdLength)
-{
- Log("Decryptor::CloseSession(pid=%d, session=%s)", aPromiseId, aSessionId);
- CDM()->CloseSession(aPromiseId, aSessionId, aSessionIdLength);
-}
-
-void
-WidevineDecryptor::RemoveSession(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdLength)
-{
- Log("Decryptor::RemoveSession(%s)", aSessionId);
- CDM()->RemoveSession(aPromiseId, aSessionId, aSessionIdLength);
-}
-
-void
-WidevineDecryptor::SetServerCertificate(uint32_t aPromiseId,
- const uint8_t* aServerCert,
- uint32_t aServerCertSize)
-{
- Log("Decryptor::SetServerCertificate()");
- CDM()->SetServerCertificate(aPromiseId, aServerCert, aServerCertSize);
-}
-
-class WidevineDecryptedBlock : public cdm::DecryptedBlock {
-public:
-
- WidevineDecryptedBlock()
- : mBuffer(nullptr)
- , mTimestamp(0)
- {
- }
-
- ~WidevineDecryptedBlock() {
- if (mBuffer) {
- mBuffer->Destroy();
- mBuffer = nullptr;
- }
- }
-
- void SetDecryptedBuffer(cdm::Buffer* aBuffer) override {
- mBuffer = aBuffer;
- }
-
- cdm::Buffer* DecryptedBuffer() override {
- return mBuffer;
- }
-
- void SetTimestamp(int64_t aTimestamp) override {
- mTimestamp = aTimestamp;
- }
-
- int64_t Timestamp() const override {
- return mTimestamp;
- }
-
-private:
- cdm::Buffer* mBuffer;
- int64_t mTimestamp;
-};
-
-void
-WidevineDecryptor::Decrypt(GMPBuffer* aBuffer,
- GMPEncryptedBufferMetadata* aMetadata)
-{
- if (!mCallback) {
- Log("WidevineDecryptor::Decrypt() this=%p FAIL; !mCallback", this);
- return;
- }
- const GMPEncryptedBufferMetadata* crypto = aMetadata;
- InputBuffer sample;
- nsTArray<SubsampleEntry> subsamples;
- InitInputBuffer(crypto, aBuffer->Id(), aBuffer->Data(), aBuffer->Size(), sample, subsamples);
- WidevineDecryptedBlock decrypted;
- Status rv = CDM()->Decrypt(sample, &decrypted);
- Log("Decryptor::Decrypt(timestamp=%lld) rv=%d sz=%d",
- sample.timestamp, rv, decrypted.DecryptedBuffer()->Size());
- if (rv == kSuccess) {
- aBuffer->Resize(decrypted.DecryptedBuffer()->Size());
- memcpy(aBuffer->Data(),
- decrypted.DecryptedBuffer()->Data(),
- decrypted.DecryptedBuffer()->Size());
- }
- mCallback->Decrypted(aBuffer, ToGMPErr(rv));
-}
-
-void
-WidevineDecryptor::DecryptingComplete()
-{
- Log("WidevineDecryptor::DecryptingComplete() this=%p", this);
- // Drop our references to the CDMWrapper. When any other references
- // held elsewhere are dropped (for example references held by a
- // WidevineVideoDecoder, or a runnable), the CDMWrapper destroys
- // the CDM.
- mCDM = nullptr;
- sDecryptors.erase(mInstanceId);
- mCallback = nullptr;
- Release();
-}
-
-class WidevineBuffer : public cdm::Buffer {
-public:
- explicit WidevineBuffer(size_t aSize) {
- Log("WidevineBuffer(size=" PRIuSIZE ") created", aSize);
- mBuffer.SetLength(aSize);
- }
- ~WidevineBuffer() {
- Log("WidevineBuffer(size=" PRIuSIZE ") destroyed", Size());
- }
- void Destroy() override { delete this; }
- uint32_t Capacity() const override { return mBuffer.Length(); };
- uint8_t* Data() override { return mBuffer.Elements(); }
- void SetSize(uint32_t aSize) override { mBuffer.SetLength(aSize); }
- uint32_t Size() const override { return mBuffer.Length(); }
-
-private:
- WidevineBuffer(const WidevineBuffer&);
- void operator=(const WidevineBuffer&);
-
- nsTArray<uint8_t> mBuffer;
-};
-
-Buffer*
-WidevineDecryptor::Allocate(uint32_t aCapacity)
-{
- Log("Decryptor::Allocate(capacity=%u)", aCapacity);
- return new WidevineBuffer(aCapacity);
-}
-
-class TimerTask : public GMPTask {
-public:
- TimerTask(WidevineDecryptor* aDecryptor,
- RefPtr<CDMWrapper> aCDM,
- void* aContext)
- : mDecryptor(aDecryptor)
- , mCDM(aCDM)
- , mContext(aContext)
- {
- }
- ~TimerTask() override {}
- void Run() override {
- mCDM->GetCDM()->TimerExpired(mContext);
- }
- void Destroy() override { delete this; }
-private:
- RefPtr<WidevineDecryptor> mDecryptor;
- RefPtr<CDMWrapper> mCDM;
- void* mContext;
-};
-
-void
-WidevineDecryptor::SetTimer(int64_t aDelayMs, void* aContext)
-{
- Log("Decryptor::SetTimer(delay_ms=%lld, context=0x%x)", aDelayMs, aContext);
- if (mCDM) {
- GMPSetTimerOnMainThread(new TimerTask(this, mCDM, aContext), aDelayMs);
- }
-}
-
-Time
-WidevineDecryptor::GetCurrentWallTime()
-{
- return base::Time::Now().ToDoubleT();
-}
-
-void
-WidevineDecryptor::OnResolveKeyStatusPromise(uint32_t aPromiseId,
- cdm::KeyStatus aKeyStatus) {
- //TODO: The callback of GetStatusForPolicy. See Mozilla bug 1404230.
-}
-
-void
-WidevineDecryptor::OnResolveNewSessionPromise(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdSize)
-{
- if (!mCallback) {
- Log("Decryptor::OnResolveNewSessionPromise(aPromiseId=0x%d) FAIL; !mCallback", aPromiseId);
- return;
- }
- Log("Decryptor::OnResolveNewSessionPromise(aPromiseId=0x%d)", aPromiseId);
- auto iter = mPromiseIdToNewSessionTokens.find(aPromiseId);
- if (iter == mPromiseIdToNewSessionTokens.end()) {
- Log("FAIL: Decryptor::OnResolveNewSessionPromise(aPromiseId=%d) unknown aPromiseId", aPromiseId);
- return;
- }
- mCallback->SetSessionId(iter->second, aSessionId, aSessionIdSize);
- mCallback->ResolvePromise(aPromiseId);
- mPromiseIdToNewSessionTokens.erase(iter);
-}
-
-void
-WidevineDecryptor::OnResolvePromise(uint32_t aPromiseId)
-{
- if (!mCallback) {
- Log("Decryptor::OnResolvePromise(aPromiseId=0x%d) FAIL; !mCallback", aPromiseId);
- return;
- }
- Log("Decryptor::OnResolvePromise(aPromiseId=%d)", aPromiseId);
- mCallback->ResolvePromise(aPromiseId);
-}
-
-static GMPDOMException
-ConvertCDMExceptionToGMPDOMException(cdm::Exception aException)
-{
- switch (aException) {
- case kExceptionNotSupportedError: return kGMPNotSupportedError;
- case kExceptionInvalidStateError: return kGMPInvalidStateError;
- case kExceptionTypeError: return kGMPTypeError;
- case kExceptionQuotaExceededError: return kGMPQuotaExceededError;
- case kUnknownError: return kGMPInvalidModificationError; // Note: Unique placeholder.
- case kClientError: return kGMPAbortError; // Note: Unique placeholder.
- case kOutputError: return kGMPSecurityError; // Note: Unique placeholder.
- };
- return kGMPInvalidStateError; // Note: Unique placeholder.
-}
-
-// Align with spec, the Exceptions used by CDM to reject promises .
-// https://w3c.github.io/encrypted-media/#exceptions
-cdm::Exception
-ConvertCDMErrorToCDMException(cdm::Error error) {
- switch (error) {
- case cdm::kNotSupportedError:
- return cdm::Exception::kExceptionNotSupportedError;
- case cdm::kInvalidStateError:
- return cdm::Exception::kExceptionInvalidStateError;
- case cdm::kInvalidAccessError:
- return cdm::Exception::kExceptionTypeError;
- case cdm::kQuotaExceededError:
- return cdm::Exception::kExceptionQuotaExceededError;
-
- case cdm::kUnknownError:
- case cdm::kClientError:
- case cdm::kOutputError:
- break;
- }
-
- return cdm::Exception::kExceptionInvalidStateError;
-}
-
-void
-WidevineDecryptor::OnRejectPromise(uint32_t aPromiseId,
- cdm::Exception aException,
- uint32_t aSystemCode,
- const char* aErrorMessage,
- uint32_t aErrorMessageSize)
-{
- if (!mCallback) {
- Log("Decryptor::OnRejectPromise(aPromiseId=%d, err=%d, sysCode=%u, msg=%s) FAIL; !mCallback",
- aPromiseId, (int)aException, aSystemCode, aErrorMessage);
- return;
- }
- Log("Decryptor::OnRejectPromise(aPromiseId=%d, err=%d, sysCode=%u, msg=%s)",
- aPromiseId, (int)aException, aSystemCode, aErrorMessage);
- mCallback->RejectPromise(aPromiseId,
- ConvertCDMExceptionToGMPDOMException(aException),
- !aErrorMessageSize ? "" : aErrorMessage,
- aErrorMessageSize);
-}
-
-static GMPSessionMessageType
-ToGMPMessageType(MessageType message_type)
-{
- switch (message_type) {
- case kLicenseRequest: return kGMPLicenseRequest;
- case kLicenseRenewal: return kGMPLicenseRenewal;
- case kLicenseRelease: return kGMPLicenseRelease;
- }
- return kGMPMessageInvalid;
-}
-
-void
-WidevineDecryptor::OnSessionMessage(const char* aSessionId,
- uint32_t aSessionIdSize,
- cdm::MessageType aMessageType,
- const char* aMessage,
- uint32_t aMessageSize)
-{
- if (!mCallback) {
- Log("Decryptor::OnSessionMessage() FAIL; !mCallback");
- return;
- }
- Log("Decryptor::OnSessionMessage()");
- mCallback->SessionMessage(aSessionId,
- aSessionIdSize,
- ToGMPMessageType(aMessageType),
- reinterpret_cast<const uint8_t*>(aMessage),
- aMessageSize);
-}
-
-static GMPMediaKeyStatus
-ToGMPKeyStatus(KeyStatus aStatus)
-{
- switch (aStatus) {
- case kUsable: return kGMPUsable;
- case kInternalError: return kGMPInternalError;
- case kExpired: return kGMPExpired;
- case kOutputRestricted: return kGMPOutputRestricted;
- case kOutputDownscaled: return kGMPOutputDownscaled;
- case kStatusPending: return kGMPStatusPending;
- case kReleased: return kGMPReleased;
- }
- return kGMPUnknown;
-}
-
-void
-WidevineDecryptor::OnSessionKeysChange(const char* aSessionId,
- uint32_t aSessionIdSize,
- bool aHasAdditionalUsableKey,
- const KeyInformation* aKeysInfo,
- uint32_t aKeysInfoCount)
-{
- if (!mCallback) {
- Log("Decryptor::OnSessionKeysChange() FAIL; !mCallback");
- return;
- }
- Log("Decryptor::OnSessionKeysChange()");
-
- nsTArray<GMPMediaKeyInfo> key_infos;
- for (uint32_t i = 0; i < aKeysInfoCount; i++) {
- key_infos.AppendElement(GMPMediaKeyInfo(aKeysInfo[i].key_id,
- aKeysInfo[i].key_id_size,
- ToGMPKeyStatus(aKeysInfo[i].status)));
- }
- mCallback->BatchedKeyStatusChanged(aSessionId, aSessionIdSize,
- key_infos.Elements(), key_infos.Length());
-}
-
-static GMPTimestamp
-ToGMPTime(Time aCDMTime)
-{
- return static_cast<GMPTimestamp>(aCDMTime * 1000);
-}
-
-void
-WidevineDecryptor::OnExpirationChange(const char* aSessionId,
- uint32_t aSessionIdSize,
- Time aNewExpiryTime)
-{
- if (!mCallback) {
- Log("Decryptor::OnExpirationChange(sid=%s) t=%lf FAIL; !mCallback",
- aSessionId, aNewExpiryTime);
- return;
- }
- Log("Decryptor::OnExpirationChange(sid=%s) t=%lf", aSessionId, aNewExpiryTime);
- GMPTimestamp expiry = ToGMPTime(aNewExpiryTime);
- if (aNewExpiryTime == 0) {
- return;
- }
- mCallback->ExpirationChange(aSessionId, aSessionIdSize, expiry);
-}
-
-void
-WidevineDecryptor::OnSessionClosed(const char* aSessionId,
- uint32_t aSessionIdSize)
-{
- if (!mCallback) {
- Log("Decryptor::OnSessionClosed(sid=%s) FAIL; !mCallback", aSessionId);
- return;
- }
- Log("Decryptor::OnSessionClosed(sid=%s)", aSessionId);
- mCallback->SessionClosed(aSessionId, aSessionIdSize);
-}
-
-void
-WidevineDecryptor::SendPlatformChallenge(const char* aServiceId,
- uint32_t aServiceIdSize,
- const char* aChallenge,
- uint32_t aChallengeSize)
-{
- Log("Decryptor::SendPlatformChallenge(service_id=%s)", aServiceId);
-}
-
-void
-WidevineDecryptor::EnableOutputProtection(uint32_t aDesiredProtectionMask)
-{
- Log("Decryptor::EnableOutputProtection(mask=0x%x)", aDesiredProtectionMask);
-}
-
-void
-WidevineDecryptor::QueryOutputProtectionStatus()
-{
- Log("Decryptor::QueryOutputProtectionStatus()");
-}
-
-void
-WidevineDecryptor::OnDeferredInitializationDone(StreamType aStreamType,
- Status aDecoderStatus)
-{
- Log("Decryptor::OnDeferredInitializationDone()");
-}
-
-FileIO*
-WidevineDecryptor::CreateFileIO(FileIOClient* aClient)
-{
- Log("Decryptor::CreateFileIO()");
- if (!mPersistentStateRequired) {
- return nullptr;
- }
- return new WidevineFileIO(aClient);
-}
-
-void
-WidevineDecryptor::RequestStorageId(uint32_t aVersion)
-{
- Log("Decryptor::RequestStorageId() aVersion = %u", aVersion);
- if (aVersion >= 0x80000000) {
- mCDM->OnStorageId(aVersion, nullptr, 0);
- return;
- }
-
- //TODO: Need to provide a menaingful buffer instead of a dummy one.
- mCDM->OnStorageId(aVersion, new uint8_t[1024*1024], 1024 * 1024);
-}
-
-} // namespace mozilla
diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.h b/dom/media/gmp/widevine-adapter/WidevineDecryptor.h
deleted file mode 100644
index f291c321d3..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef WidevineDecryptor_h_
-#define WidevineDecryptor_h_
-
-#include "stddef.h"
-#include "content_decryption_module.h"
-#include "gmp-api/gmp-decryption.h"
-#include "mozilla/RefPtr.h"
-#include "WidevineUtils.h"
-#include <map>
-
-namespace mozilla {
-
-class WidevineDecryptor : public GMPDecryptor
- , public cdm::Host_9
-{
-public:
-
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WidevineDecryptor)
-
- WidevineDecryptor();
-
- void SetCDM(RefPtr<CDMWrapper> aCDM, uint32_t aDecryptorId);
-
- static RefPtr<CDMWrapper> GetInstance(uint32_t aDecryptorId);
-
- // GMPDecryptor
- void Init(GMPDecryptorCallback* aCallback,
- bool aDistinctiveIdentifierRequired,
- bool aPersistentStateRequired) override;
-
- void CreateSession(uint32_t aCreateSessionToken,
- uint32_t aPromiseId,
- const char* aInitDataType,
- uint32_t aInitDataTypeSize,
- const uint8_t* aInitData,
- uint32_t aInitDataSize,
- GMPSessionType aSessionType) override;
-
- void LoadSession(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdLength) override;
-
- void UpdateSession(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdLength,
- const uint8_t* aResponse,
- uint32_t aResponseSize) override;
-
- void CloseSession(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdLength) override;
-
- void RemoveSession(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdLength) override;
-
- void SetServerCertificate(uint32_t aPromiseId,
- const uint8_t* aServerCert,
- uint32_t aServerCertSize) override;
-
- void Decrypt(GMPBuffer* aBuffer,
- GMPEncryptedBufferMetadata* aMetadata) override;
-
- void DecryptingComplete() override;
-
-
- // cdm::Host_9 implementation
- cdm::Buffer* Allocate(uint32_t aCapacity) override;
- void SetTimer(int64_t aDelayMs, void* aContext) override;
- cdm::Time GetCurrentWallTime() override;
- // cdm::Host_9 interface
- void OnResolveKeyStatusPromise(uint32_t aPromiseId,
- cdm::KeyStatus aKeyStatus) override;
- void OnResolveNewSessionPromise(uint32_t aPromiseId,
- const char* aSessionId,
- uint32_t aSessionIdSize) override;
- void OnResolvePromise(uint32_t aPromiseId) override;
- void OnRejectPromise(uint32_t aPromiseId,
- cdm::Exception aException,
- uint32_t aSystemCode,
- const char* aErrorMessage,
- uint32_t aErrorMessageSize) override;
- void OnSessionMessage(const char* aSessionId,
- uint32_t aSessionIdSize,
- cdm::MessageType aMessageType,
- const char* aMessage,
- uint32_t aMessageSize) override;
- void OnSessionKeysChange(const char* aSessionId,
- uint32_t aSessionIdSize,
- bool aHasAdditionalUsableKey,
- const cdm::KeyInformation* aKeysInfo,
- uint32_t aKeysInfoCount) override;
- void OnExpirationChange(const char* aSessionId,
- uint32_t aSessionIdSize,
- cdm::Time aNewExpiryTime) override;
- void OnSessionClosed(const char* aSessionId,
- uint32_t aSessionIdSize) override;
- void SendPlatformChallenge(const char* aServiceId,
- uint32_t aServiceIdSize,
- const char* aChallenge,
- uint32_t aChallengeSize) override;
- void EnableOutputProtection(uint32_t aDesiredProtectionMask) override;
- void QueryOutputProtectionStatus() override;
- void OnDeferredInitializationDone(cdm::StreamType aStreamType,
- cdm::Status aDecoderStatus) override;
- // cdm::Host_9 interface
- // NOTE: the interface has changed upstream.
- void RequestStorageId(uint32_t aVersion) override;
- cdm::FileIO* CreateFileIO(cdm::FileIOClient* aClient) override;
-
- GMPDecryptorCallback* Callback() const { return mCallback; }
- RefPtr<CDMWrapper> GetCDMWrapper() const { return mCDM; }
-private:
- ~WidevineDecryptor();
- RefPtr<CDMWrapper> mCDM;
- cdm::ContentDecryptionModule_9* CDM() { return mCDM->GetCDM(); }
-
- GMPDecryptorCallback* mCallback;
- std::map<uint32_t, uint32_t> mPromiseIdToNewSessionTokens;
- bool mDistinctiveIdentifierRequired = false;
- bool mPersistentStateRequired = false;
- uint32_t mInstanceId = 0;
-};
-
-} // namespace mozilla
-
-#endif // WidevineDecryptor_h_
diff --git a/dom/media/gmp/widevine-adapter/WidevineFileIO.cpp b/dom/media/gmp/widevine-adapter/WidevineFileIO.cpp
deleted file mode 100644
index b5fb1d705c..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineFileIO.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#include "WidevineFileIO.h"
-#include "WidevineUtils.h"
-#include "WidevineAdapter.h"
-
-using namespace cdm;
-
-namespace mozilla {
-
-void
-WidevineFileIO::Open(const char* aFilename, uint32_t aFilenameLength)
-{
- mName = std::string(aFilename, aFilename + aFilenameLength);
- GMPRecord* record = nullptr;
- GMPErr err = GMPCreateRecord(aFilename, aFilenameLength, &record, static_cast<GMPRecordClient*>(this));
- if (GMP_FAILED(err)) {
- Log("WidevineFileIO::Open() '%s' GMPCreateRecord failed", mName.c_str());
- mClient->OnOpenComplete(FileIOClient::kError);
- return;
- }
- if (GMP_FAILED(record->Open())) {
- Log("WidevineFileIO::Open() '%s' record open failed", mName.c_str());
- mClient->OnOpenComplete(FileIOClient::kError);
- return;
- }
-
- Log("WidevineFileIO::Open() '%s'", mName.c_str());
- mRecord = record;
-}
-
-void
-WidevineFileIO::Read()
-{
- if (!mRecord) {
- Log("WidevineFileIO::Read() '%s' used uninitialized!", mName.c_str());
- mClient->OnReadComplete(FileIOClient::kError, nullptr, 0);
- return;
- }
- Log("WidevineFileIO::Read() '%s'", mName.c_str());
- mRecord->Read();
-}
-
-void
-WidevineFileIO::Write(const uint8_t* aData, uint32_t aDataSize)
-{
- if (!mRecord) {
- Log("WidevineFileIO::Write() '%s' used uninitialized!", mName.c_str());
- mClient->OnWriteComplete(FileIOClient::kError);
- return;
- }
- mRecord->Write(aData, aDataSize);
-}
-
-void
-WidevineFileIO::Close()
-{
- Log("WidevineFileIO::Close() '%s'", mName.c_str());
- if (mRecord) {
- mRecord->Close();
- mRecord = nullptr;
- }
- delete this;
-}
-
-static FileIOClient::Status
-GMPToWidevineFileStatus(GMPErr aStatus)
-{
- switch (aStatus) {
- case GMPRecordInUse: return FileIOClient::kInUse;
- case GMPNoErr: return FileIOClient::kSuccess;
- default: return FileIOClient::kError;
- }
-}
-
-void
-WidevineFileIO::OpenComplete(GMPErr aStatus)
-{
- Log("WidevineFileIO::OpenComplete() '%s' status=%d", mName.c_str(), aStatus);
- mClient->OnOpenComplete(GMPToWidevineFileStatus(aStatus));
-}
-
-void
-WidevineFileIO::ReadComplete(GMPErr aStatus,
- const uint8_t* aData,
- uint32_t aDataSize)
-{
- Log("WidevineFileIO::OnReadComplete() '%s' status=%d", mName.c_str(), aStatus);
- mClient->OnReadComplete(GMPToWidevineFileStatus(aStatus), aData, aDataSize);
-}
-
-void
-WidevineFileIO::WriteComplete(GMPErr aStatus)
-{
- Log("WidevineFileIO::WriteComplete() '%s' status=%d", mName.c_str(), aStatus);
- mClient->OnWriteComplete(GMPToWidevineFileStatus(aStatus));
-}
-
-} // namespace mozilla
diff --git a/dom/media/gmp/widevine-adapter/WidevineFileIO.h b/dom/media/gmp/widevine-adapter/WidevineFileIO.h
deleted file mode 100644
index 63003d9b60..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineFileIO.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this
-* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef WidevineFileIO_h_
-#define WidevineFileIO_h_
-
-#include <stddef.h>
-#include "content_decryption_module.h"
-#include "gmp-api/gmp-storage.h"
-#include <string>
-
-namespace mozilla {
-
-class WidevineFileIO : public cdm::FileIO
- , public GMPRecordClient
-{
-public:
- explicit WidevineFileIO(cdm::FileIOClient* aClient)
- : mClient(aClient)
- , mRecord(nullptr)
- {}
-
- // cdm::FileIO
- void Open(const char* aFilename, uint32_t aFilenameLength) override;
- void Read() override;
- void Write(const uint8_t* aData, uint32_t aDataSize) override;
- void Close() override;
-
- // GMPRecordClient
- void OpenComplete(GMPErr aStatus) override;
- void ReadComplete(GMPErr aStatus,
- const uint8_t* aData,
- uint32_t aDataSize) override;
- void WriteComplete(GMPErr aStatus) override;
-
-private:
- cdm::FileIOClient* mClient;
- GMPRecord* mRecord;
- std::string mName;
-};
-
-} // namespace mozilla
-
-#endif // WidevineFileIO_h_ \ No newline at end of file
diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp
deleted file mode 100644
index 10c6c2e18c..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "WidevineUtils.h"
-#include "WidevineDecryptor.h"
-
-#include "gmp-api/gmp-errors.h"
-#include <stdarg.h>
-#include <stdio.h>
-
-namespace mozilla {
-
-#ifdef ENABLE_WIDEVINE_LOG
-void
-Log(const char* aFormat, ...)
-{
- va_list ap;
- va_start(ap, aFormat);
- const size_t len = 1024;
- char buf[len];
- vsnprintf(buf, len, aFormat, ap);
- va_end(ap);
- if (getenv("GMP_LOG_FILE")) {
- FILE* f = fopen(getenv("GMP_LOG_FILE"), "a");
- if (f) {
- fprintf(f, "%s\n", buf);
- fflush(f);
- fclose(f);
- f = nullptr;
- }
- } else {
- printf("LOG: %s\n", buf);
- }
-}
-#endif // ENABLE_WIDEVINE_LOG
-
-GMPErr
-ToGMPErr(cdm::Status aStatus)
-{
- switch (aStatus) {
- case cdm::kSuccess: return GMPNoErr;
- case cdm::kNeedMoreData: return GMPGenericErr;
- case cdm::kNoKey: return GMPNoKeyErr;
- case cdm::kInitializationError: return GMPGenericErr;
- case cdm::kDecryptError: return GMPCryptoErr;
- case cdm::kDecodeError: return GMPDecodeErr;
- case cdm::kDeferredInitialization: return GMPGenericErr;
- default: return GMPGenericErr;
- }
-}
-
-void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto,
- int64_t aTimestamp,
- const uint8_t* aData,
- size_t aDataSize,
- cdm::InputBuffer &aInputBuffer,
- nsTArray<cdm::SubsampleEntry> &aSubsamples)
-{
- if (aCrypto) {
- aInputBuffer.key_id = aCrypto->KeyId();
- aInputBuffer.key_id_size = aCrypto->KeyIdSize();
- aInputBuffer.iv = aCrypto->IV();
- aInputBuffer.iv_size = aCrypto->IVSize();
- aInputBuffer.num_subsamples = aCrypto->NumSubsamples();
- aSubsamples.SetCapacity(aInputBuffer.num_subsamples);
- const uint16_t* clear = aCrypto->ClearBytes();
- const uint32_t* cipher = aCrypto->CipherBytes();
- for (size_t i = 0; i < aCrypto->NumSubsamples(); i++) {
- aSubsamples.AppendElement(cdm::SubsampleEntry(clear[i], cipher[i]));
- }
- }
- aInputBuffer.data = aData;
- aInputBuffer.data_size = aDataSize;
- aInputBuffer.subsamples = aSubsamples.Elements();
- aInputBuffer.timestamp = aTimestamp;
-}
-
-CDMWrapper::CDMWrapper(cdm::ContentDecryptionModule_9* aCDM,
- WidevineDecryptor* aDecryptor)
- : mCDM(aCDM)
- , mDecryptor(aDecryptor)
-{
- MOZ_ASSERT(mCDM);
-}
-
-CDMWrapper::~CDMWrapper()
-{
- Log("CDMWrapper destroying CDM=%p", mCDM);
- mCDM->Destroy();
- mCDM = nullptr;
-}
-
-} // namespace mozilla
diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.h b/dom/media/gmp/widevine-adapter/WidevineUtils.h
deleted file mode 100644
index 2f6137fe3b..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineUtils.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef WidevineUtils_h_
-#define WidevineUtils_h_
-
-#include "stddef.h"
-#include "content_decryption_module.h"
-#include "gmp-api/gmp-decryption.h"
-#include "gmp-api/gmp-platform.h"
-#include "nsISupportsImpl.h"
-#include "nsTArray.h"
-
-namespace mozilla {
-
-// Uncomment for logging...
-//#define ENABLE_WIDEVINE_LOG 1
-#ifdef ENABLE_WIDEVINE_LOG
-void
-Log(const char* aFormat, ...);
-#else
-#define Log(...)
-#endif // ENABLE_WIDEVINE_LOG
-
-
-#define ENSURE_TRUE(condition, rv) { \
- if (!(condition)) {\
- Log("ENSURE_TRUE FAILED %s:%d", __FILE__, __LINE__); \
- return rv; \
- } \
-} \
-
-#define ENSURE_GMP_SUCCESS(err, rv) { \
- if (GMP_FAILED(err)) {\
- Log("ENSURE_GMP_SUCCESS FAILED %s:%d", __FILE__, __LINE__); \
- return rv; \
- } \
-} \
-
-GMPErr
-ToGMPErr(cdm::Status aStatus);
-
-class WidevineDecryptor;
-
-class CDMWrapper {
-public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CDMWrapper)
-
- explicit CDMWrapper(cdm::ContentDecryptionModule_9* aCDM,
- WidevineDecryptor* aDecryptor);
- cdm::ContentDecryptionModule_9* GetCDM() const { return mCDM; }
- void OnStorageId(uint32_t aVersion, const uint8_t* aStorageId,
- uint32_t aStorageIdSize) {
- mCDM->OnStorageId(aVersion, aStorageId, aStorageIdSize);
- }
-private:
- ~CDMWrapper();
- cdm::ContentDecryptionModule_9* mCDM;
- RefPtr<WidevineDecryptor> mDecryptor;
-};
-
-void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto,
- int64_t aTimestamp,
- const uint8_t* aData,
- size_t aDataSize,
- cdm::InputBuffer &aInputBuffer,
- nsTArray<cdm::SubsampleEntry> &aSubsamples);
-
-} // namespace mozilla
-
-#endif // WidevineUtils_h_
diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp
deleted file mode 100644
index 70d2fd8e08..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "WidevineVideoDecoder.h"
-
-#include "mp4_demuxer/AnnexB.h"
-#include "WidevineUtils.h"
-#include "WidevineVideoFrame.h"
-#include "mozilla/Move.h"
-
-using namespace cdm;
-
-namespace mozilla {
-
-WidevineVideoDecoder::WidevineVideoDecoder(GMPVideoHost* aVideoHost,
- RefPtr<CDMWrapper> aCDMWrapper)
- : mVideoHost(aVideoHost)
- , mCDMWrapper(Move(aCDMWrapper))
- , mExtraData(new MediaByteBuffer())
- , mSentInput(false)
- , mCodecType(kGMPVideoCodecInvalid)
- , mReturnOutputCallDepth(0)
- , mDrainPending(false)
- , mResetInProgress(false)
-{
- // Expect to start with a CDM wrapper, will release it in DecodingComplete().
- MOZ_ASSERT(mCDMWrapper);
- Log("WidevineVideoDecoder created this=%p", this);
-
- // Corresponding Release is in DecodingComplete().
- AddRef();
-}
-
-WidevineVideoDecoder::~WidevineVideoDecoder()
-{
- Log("WidevineVideoDecoder destroyed this=%p", this);
-}
-
-static
-VideoDecoderConfig::VideoCodecProfile
-ToCDMH264Profile(uint8_t aProfile)
-{
- switch (aProfile) {
- case 66: return VideoDecoderConfig::kH264ProfileBaseline;
- case 77: return VideoDecoderConfig::kH264ProfileMain;
- case 88: return VideoDecoderConfig::kH264ProfileExtended;
- case 100: return VideoDecoderConfig::kH264ProfileHigh;
- case 110: return VideoDecoderConfig::kH264ProfileHigh10;
- case 122: return VideoDecoderConfig::kH264ProfileHigh422;
- case 144: return VideoDecoderConfig::kH264ProfileHigh444Predictive;
- }
- return VideoDecoderConfig::kUnknownVideoCodecProfile;
-}
-
-void
-WidevineVideoDecoder::InitDecode(const GMPVideoCodec& aCodecSettings,
- const uint8_t* aCodecSpecific,
- uint32_t aCodecSpecificLength,
- GMPVideoDecoderCallback* aCallback,
- int32_t aCoreCount)
-{
- mCallback = aCallback;
- VideoDecoderConfig config;
- mCodecType = aCodecSettings.mCodecType;
- if (mCodecType == kGMPVideoCodecH264) {
- config.codec = VideoDecoderConfig::kCodecH264;
- const GMPVideoCodecH264* h264 = (const GMPVideoCodecH264*)(aCodecSpecific);
- config.profile = ToCDMH264Profile(h264->mAVCC.mProfile);
- } else if (mCodecType == kGMPVideoCodecVP8) {
- config.codec = VideoDecoderConfig::kCodecVp8;
- config.profile = VideoDecoderConfig::kProfileNotNeeded;
- } else if (mCodecType == kGMPVideoCodecVP9) {
- config.codec = VideoDecoderConfig::kCodecVp9;
- config.profile = VideoDecoderConfig::kProfileNotNeeded;
- } else {
- mCallback->Error(GMPInvalidArgErr);
- return;
- }
- config.format = kYv12;
- config.coded_size = Size(aCodecSettings.mWidth, aCodecSettings.mHeight);
- mExtraData->AppendElements(aCodecSpecific + 1, aCodecSpecificLength);
- config.extra_data = mExtraData->Elements();
- config.extra_data_size = mExtraData->Length();
- Status rv = CDM()->InitializeVideoDecoder(config);
- if (rv != kSuccess) {
- mCallback->Error(ToGMPErr(rv));
- return;
- }
- Log("WidevineVideoDecoder::InitDecode() rv=%d", rv);
- mAnnexB = mp4_demuxer::AnnexB::ConvertExtraDataToAnnexB(mExtraData);
-}
-
-void
-WidevineVideoDecoder::Decode(GMPVideoEncodedFrame* aInputFrame,
- bool aMissingFrames,
- const uint8_t* aCodecSpecificInfo,
- uint32_t aCodecSpecificInfoLength,
- int64_t aRenderTimeMs)
-{
- // We should not be given new input if a drain has been initiated
- MOZ_ASSERT(!mDrainPending);
- // We may not get the same out of the CDM decoder as we put in, and there
- // may be some latency, i.e. we may need to input (say) 30 frames before
- // we receive output. So we need to store the durations of the frames input,
- // and retrieve them on output.
- mFrameDurations[aInputFrame->TimeStamp()] = aInputFrame->Duration();
-
- mSentInput = true;
- InputBuffer sample;
-
- RefPtr<MediaRawData> raw(
- new MediaRawData(aInputFrame->Buffer(), aInputFrame->Size()));
- if (aInputFrame->Size() && !raw->Data()) {
- // OOM.
- mCallback->Error(GMPAllocErr);
- return;
- }
- raw->mExtraData = mExtraData;
- raw->mKeyframe = (aInputFrame->FrameType() == kGMPKeyFrame);
- if (mCodecType == kGMPVideoCodecH264) {
- // Convert input from AVCC, which GMPAPI passes in, to AnnexB, which
- // Chromium uses internally.
- mp4_demuxer::AnnexB::ConvertSampleToAnnexB(raw);
- }
-
- const GMPEncryptedBufferMetadata* crypto = aInputFrame->GetDecryptionData();
- nsTArray<SubsampleEntry> subsamples;
- InitInputBuffer(crypto, aInputFrame->TimeStamp(), raw->Data(), raw->Size(), sample, subsamples);
-
- // For keyframes, ConvertSampleToAnnexB will stick the AnnexB extra data
- // at the start of the input. So we need to account for that as clear data
- // in the subsamples.
- if (raw->mKeyframe && !subsamples.IsEmpty() && mCodecType == kGMPVideoCodecH264) {
- subsamples[0].clear_bytes += mAnnexB->Length();
- }
-
- WidevineVideoFrame frame;
- Status rv = CDM()->DecryptAndDecodeFrame(sample, &frame);
- Log("WidevineVideoDecoder::Decode(timestamp=%lld) rv=%d", sample.timestamp, rv);
-
- // Destroy frame, so that the shmem is now free to be used to return
- // output to the Gecko process.
- aInputFrame->Destroy();
- aInputFrame = nullptr;
-
- if (rv == kSuccess) {
- if (!ReturnOutput(frame)) {
- Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
- mCallback->Error(GMPDecodeErr);
- return;
- }
- // A reset should only be started at most at level mReturnOutputCallDepth 1,
- // and if it's started it should be finished by that call by the time
- // the it returns, so it should always be false by this point.
- MOZ_ASSERT(!mResetInProgress);
- // Only request more data if we don't have pending samples.
- if (mFrameAllocationQueue.empty()) {
- MOZ_ASSERT(mCDMWrapper);
- mCallback->InputDataExhausted();
- }
- } else if (rv == kNeedMoreData) {
- MOZ_ASSERT(mCDMWrapper);
- mCallback->InputDataExhausted();
- } else {
- mCallback->Error(ToGMPErr(rv));
- }
- // Finish a drain if pending and we have no pending ReturnOutput calls on the stack.
- if (mDrainPending && mReturnOutputCallDepth == 0) {
- Drain();
- }
-}
-
-// Util class to assist with counting mReturnOutputCallDepth.
-class CounterHelper {
-public:
- // RAII, increment counter
- explicit CounterHelper(int32_t& counter)
- : mCounter(counter)
- {
- mCounter++;
- }
-
- // RAII, decrement counter
- ~CounterHelper()
- {
- mCounter--;
- }
-
-private:
- int32_t& mCounter;
-};
-
-// Util class to make sure GMP frames are freed. Holds a GMPVideoi420Frame*
-// and will destroy it when the helper is destroyed unless the held frame
-// if forgotten with ForgetFrame.
-class FrameDestroyerHelper {
-public:
- explicit FrameDestroyerHelper(GMPVideoi420Frame*& frame)
- : frame(frame)
- {
- }
-
- // RAII, destroy frame if held.
- ~FrameDestroyerHelper()
- {
- if (frame) {
- frame->Destroy();
- }
- frame = nullptr;
- }
-
- // Forget the frame without destroying it.
- void ForgetFrame()
- {
- frame = nullptr;
- }
-
-private:
- GMPVideoi420Frame* frame;
-};
-
-
-// Special handing is needed around ReturnOutput as it spins the IPC message
-// queue when creating an empty frame and can end up with reentrant calls into
-// the class methods.
-bool
-WidevineVideoDecoder::ReturnOutput(WidevineVideoFrame& aCDMFrame)
-{
- MOZ_ASSERT(mReturnOutputCallDepth >= 0);
- CounterHelper counterHelper(mReturnOutputCallDepth);
- mFrameAllocationQueue.push_back(Move(aCDMFrame));
- if (mReturnOutputCallDepth > 1) {
- // In a reentrant call.
- return true;
- }
- while (!mFrameAllocationQueue.empty()) {
- MOZ_ASSERT(mReturnOutputCallDepth == 1);
- // If we're at call level 1 a reset should not have been started. A
- // reset may be received during CreateEmptyFrame below, but we should not
- // be in a reset at this stage -- this would indicate receiving decode
- // messages before completing our reset, which we should not.
- MOZ_ASSERT(!mResetInProgress);
- WidevineVideoFrame currentCDMFrame = Move(mFrameAllocationQueue.front());
- mFrameAllocationQueue.pop_front();
- GMPVideoFrame* f = nullptr;
- auto err = mVideoHost->CreateFrame(kGMPI420VideoFrame, &f);
- if (GMP_FAILED(err) || !f) {
- Log("Failed to create i420 frame!\n");
- return false;
- }
- auto gmpFrame = static_cast<GMPVideoi420Frame*>(f);
- FrameDestroyerHelper frameDestroyerHelper(gmpFrame);
- Size size = currentCDMFrame.Size();
- const int32_t yStride = currentCDMFrame.Stride(VideoFrame::kYPlane);
- const int32_t uStride = currentCDMFrame.Stride(VideoFrame::kUPlane);
- const int32_t vStride = currentCDMFrame.Stride(VideoFrame::kVPlane);
- const int32_t halfHeight = size.height / 2;
- // This call can cause a shmem alloc, during this alloc other calls
- // may be made to this class and placed on the stack. ***WARNING***:
- // other IPC calls can happen during this call, resulting in calls
- // being made to the CDM. After this call state can have changed,
- // and should be reevaluated.
- err = gmpFrame->CreateEmptyFrame(size.width,
- size.height,
- yStride,
- uStride,
- vStride);
- // Assert possible reentrant calls or resets haven't altered level unexpectedly.
- MOZ_ASSERT(mReturnOutputCallDepth == 1);
- ENSURE_GMP_SUCCESS(err, false);
-
- // If a reset started we need to dump the current frame and complete the reset.
- if (mResetInProgress) {
- MOZ_ASSERT(mCDMWrapper);
- MOZ_ASSERT(mFrameAllocationQueue.empty());
- CompleteReset();
- return true;
- }
-
- err = gmpFrame->SetWidth(size.width);
- ENSURE_GMP_SUCCESS(err, false);
-
- err = gmpFrame->SetHeight(size.height);
- ENSURE_GMP_SUCCESS(err, false);
-
- Buffer* buffer = currentCDMFrame.FrameBuffer();
- uint8_t* outBuffer = gmpFrame->Buffer(kGMPYPlane);
- ENSURE_TRUE(outBuffer != nullptr, false);
- MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPYPlane) >= yStride*size.height);
- memcpy(outBuffer,
- buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kYPlane),
- yStride * size.height);
-
- outBuffer = gmpFrame->Buffer(kGMPUPlane);
- ENSURE_TRUE(outBuffer != nullptr, false);
- MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPUPlane) >= uStride * halfHeight);
- memcpy(outBuffer,
- buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kUPlane),
- uStride * halfHeight);
-
- outBuffer = gmpFrame->Buffer(kGMPVPlane);
- ENSURE_TRUE(outBuffer != nullptr, false);
- MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPVPlane) >= vStride * halfHeight);
- memcpy(outBuffer,
- buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kVPlane),
- vStride * halfHeight);
-
- gmpFrame->SetTimestamp(currentCDMFrame.Timestamp());
-
- auto d = mFrameDurations.find(currentCDMFrame.Timestamp());
- if (d != mFrameDurations.end()) {
- gmpFrame->SetDuration(d->second);
- mFrameDurations.erase(d);
- }
-
- // Forget frame so it's not deleted, call back taking ownership.
- frameDestroyerHelper.ForgetFrame();
- mCallback->Decoded(gmpFrame);
- }
-
- return true;
-}
-
-void
-WidevineVideoDecoder::Reset()
-{
- Log("WidevineVideoDecoder::Reset() mSentInput=%d", mSentInput);
- // We shouldn't reset if a drain is pending.
- MOZ_ASSERT(!mDrainPending);
- mResetInProgress = true;
- if (mSentInput) {
- CDM()->ResetDecoder(kStreamTypeVideo);
- }
- // Remove queued frames, but do not reset mReturnOutputCallDepth, let the
- // ReturnOutput calls unwind and decrement the counter as needed.
- mFrameAllocationQueue.clear();
- mFrameDurations.clear();
- // Only if no ReturnOutput calls are in progress can we complete, otherwise
- // ReturnOutput needs to finalize the reset.
- if (mReturnOutputCallDepth == 0) {
- CompleteReset();
- }
-}
-
-void
-WidevineVideoDecoder::CompleteReset()
-{
- mCallback->ResetComplete();
- mSentInput = false;
- mResetInProgress = false;
-}
-
-void
-WidevineVideoDecoder::Drain()
-{
- Log("WidevineVideoDecoder::Drain()");
- if (mReturnOutputCallDepth > 0) {
- Log("Drain call is reentrant, postponing drain");
- mDrainPending = true;
- return;
- }
-
- Status rv = kSuccess;
- while (rv == kSuccess) {
- WidevineVideoFrame frame;
- InputBuffer sample;
- Status rv = CDM()->DecryptAndDecodeFrame(sample, &frame);
- Log("WidevineVideoDecoder::Drain(); DecryptAndDecodeFrame() rv=%d", rv);
- if (frame.Format() == kUnknownVideoFormat) {
- break;
- }
- if (rv == kSuccess) {
- if (!ReturnOutput(frame)) {
- Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()");
- }
- }
- }
- // Shouldn't be reset while draining.
- MOZ_ASSERT(!mResetInProgress);
-
- CDM()->ResetDecoder(kStreamTypeVideo);
- mDrainPending = false;
- mCallback->DrainComplete();
-}
-
-void
-WidevineVideoDecoder::DecodingComplete()
-{
- Log("WidevineVideoDecoder::DecodingComplete()");
- if (mCDMWrapper) {
- CDM()->DeinitializeDecoder(kStreamTypeVideo);
- mCDMWrapper = nullptr;
- }
- // Release that corresponds to AddRef() in constructor.
- Release();
-}
-
-} // namespace mozilla
diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
deleted file mode 100644
index f5e63519be..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef WidevineVideoDecoder_h_
-#define WidevineVideoDecoder_h_
-
-#include "stddef.h"
-#include "content_decryption_module.h"
-#include "gmp-api/gmp-video-decode.h"
-#include "gmp-api/gmp-video-host.h"
-#include "MediaData.h"
-#include "nsISupportsImpl.h"
-#include "nsTArray.h"
-#include "WidevineDecryptor.h"
-#include "WidevineVideoFrame.h"
-#include <map>
-#include <deque>
-
-namespace mozilla {
-
-class WidevineVideoDecoder : public GMPVideoDecoder {
-public:
-
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WidevineVideoDecoder)
-
- WidevineVideoDecoder(GMPVideoHost* aVideoHost,
- RefPtr<CDMWrapper> aCDMWrapper);
- void InitDecode(const GMPVideoCodec& aCodecSettings,
- const uint8_t* aCodecSpecific,
- uint32_t aCodecSpecificLength,
- GMPVideoDecoderCallback* aCallback,
- int32_t aCoreCount) override;
- void Decode(GMPVideoEncodedFrame* aInputFrame,
- bool aMissingFrames,
- const uint8_t* aCodecSpecificInfo,
- uint32_t aCodecSpecificInfoLength,
- int64_t aRenderTimeMs = -1) override;
- void Reset() override;
- void Drain() override;
- void DecodingComplete() override;
-
-private:
-
- ~WidevineVideoDecoder();
-
- cdm::ContentDecryptionModule_9* CDM() const {
- // CDM should only be accessed before 'DecodingComplete'.
- MOZ_ASSERT(mCDMWrapper);
- // CDMWrapper ensure the CDM is non-null, no need to check again.
- return mCDMWrapper->GetCDM();
- }
-
- bool ReturnOutput(WidevineVideoFrame& aFrame);
- void CompleteReset();
-
- GMPVideoHost* mVideoHost;
- RefPtr<CDMWrapper> mCDMWrapper;
- RefPtr<MediaByteBuffer> mExtraData;
- RefPtr<MediaByteBuffer> mAnnexB;
- GMPVideoDecoderCallback* mCallback;
- std::map<uint64_t, uint64_t> mFrameDurations;
- bool mSentInput;
- GMPVideoCodecType mCodecType;
- // Frames waiting on allocation
- std::deque<WidevineVideoFrame> mFrameAllocationQueue;
- // Number of calls of ReturnOutput currently in progress.
- int32_t mReturnOutputCallDepth;
- // If we're waiting to drain. Used to prevent drain completing while
- // ReturnOutput calls are still on the stack.
- bool mDrainPending;
- // If a reset is being performed. Used to track if ReturnOutput should
- // dump current frame.
- bool mResetInProgress;
-};
-
-} // namespace mozilla
-
-#endif // WidevineVideoDecoder_h_
diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
deleted file mode 100644
index 4221bf15b8..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "WidevineVideoFrame.h"
-
-#include "WidevineUtils.h"
-
-using namespace cdm;
-
-namespace mozilla {
-
-WidevineVideoFrame::WidevineVideoFrame()
- : mFormat(kUnknownVideoFormat)
- , mSize(0,0)
- , mBuffer(nullptr)
- , mTimestamp(0)
-{
- Log("WidevineVideoFrame::WidevineVideoFrame() this=%p", this);
- memset(mPlaneOffsets, 0, sizeof(mPlaneOffsets));
- memset(mPlaneStrides, 0, sizeof(mPlaneStrides));
-}
-
-WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&& aOther)
- : mFormat(aOther.mFormat)
- , mSize(aOther.mSize)
- , mBuffer(aOther.mBuffer)
- , mTimestamp(aOther.mTimestamp)
-{
- Log("WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&&) this=%p, other=%p",
- this, &aOther);
- memcpy(mPlaneOffsets, aOther.mPlaneOffsets, sizeof(mPlaneOffsets));
- memcpy(mPlaneStrides, aOther.mPlaneStrides, sizeof(mPlaneStrides));
- aOther.mBuffer = nullptr;
-}
-
-WidevineVideoFrame::~WidevineVideoFrame()
-{
- if (mBuffer) {
- mBuffer->Destroy();
- mBuffer = nullptr;
- }
-}
-
-void
-WidevineVideoFrame::SetFormat(cdm::VideoFormat aFormat)
-{
- Log("WidevineVideoFrame::SetFormat(%d) this=%p", aFormat, this);
- mFormat = aFormat;
-}
-
-cdm::VideoFormat
-WidevineVideoFrame::Format() const
-{
- return mFormat;
-}
-
-void
-WidevineVideoFrame::SetSize(cdm::Size aSize)
-{
- Log("WidevineVideoFrame::SetSize(%d,%d) this=%p", aSize.width, aSize.height, this);
- mSize.width = aSize.width;
- mSize.height = aSize.height;
-}
-
-cdm::Size
-WidevineVideoFrame::Size() const
-{
- return mSize;
-}
-
-void
-WidevineVideoFrame::SetFrameBuffer(cdm::Buffer* aFrameBuffer)
-{
- Log("WidevineVideoFrame::SetFrameBuffer(%p) this=%p", aFrameBuffer, this);
- MOZ_ASSERT(!mBuffer);
- mBuffer = aFrameBuffer;
-}
-
-cdm::Buffer*
-WidevineVideoFrame::FrameBuffer()
-{
- return mBuffer;
-}
-
-void
-WidevineVideoFrame::SetPlaneOffset(cdm::VideoFrame::VideoPlane aPlane, uint32_t aOffset)
-{
- Log("WidevineVideoFrame::SetPlaneOffset(%d, %d) this=%p", aPlane, aOffset, this);
- mPlaneOffsets[aPlane] = aOffset;
-}
-
-uint32_t
-WidevineVideoFrame::PlaneOffset(cdm::VideoFrame::VideoPlane aPlane)
-{
- return mPlaneOffsets[aPlane];
-}
-
-void
-WidevineVideoFrame::SetStride(cdm::VideoFrame::VideoPlane aPlane, uint32_t aStride)
-{
- Log("WidevineVideoFrame::SetStride(%d, %d) this=%p", aPlane, aStride, this);
- mPlaneStrides[aPlane] = aStride;
-}
-
-uint32_t
-WidevineVideoFrame::Stride(cdm::VideoFrame::VideoPlane aPlane)
-{
- return mPlaneStrides[aPlane];
-}
-
-void
-WidevineVideoFrame::SetTimestamp(int64_t timestamp)
-{
- Log("WidevineVideoFrame::SetTimestamp(%lld) this=%p", timestamp, this);
- mTimestamp = timestamp;
-}
-
-int64_t
-WidevineVideoFrame::Timestamp() const
-{
- return mTimestamp;
-}
-
-} // namespace mozilla
diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h
deleted file mode 100644
index 96d4f20f8e..0000000000
--- a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef WidevineVideoFrame_h_
-#define WidevineVideoFrame_h_
-
-#include "stddef.h"
-#include "content_decryption_module.h"
-#include <vector>
-
-namespace mozilla {
-
-class WidevineVideoFrame : public cdm::VideoFrame {
-public:
- WidevineVideoFrame();
- WidevineVideoFrame(WidevineVideoFrame&& other);
- ~WidevineVideoFrame();
-
- void SetFormat(cdm::VideoFormat aFormat) override;
- cdm::VideoFormat Format() const override;
-
- void SetSize(cdm::Size aSize) override;
- cdm::Size Size() const override;
-
- void SetFrameBuffer(cdm::Buffer* aFrameBuffer) override;
- cdm::Buffer* FrameBuffer() override;
-
- void SetPlaneOffset(cdm::VideoFrame::VideoPlane aPlane, uint32_t aOffset) override;
- uint32_t PlaneOffset(cdm::VideoFrame::VideoPlane aPlane) override;
-
- void SetStride(cdm::VideoFrame::VideoPlane aPlane, uint32_t aStride) override;
- uint32_t Stride(cdm::VideoFrame::VideoPlane aPlane) override;
-
- void SetTimestamp(int64_t aTimestamp) override;
- int64_t Timestamp() const override;
-
-protected:
- cdm::VideoFormat mFormat;
- cdm::Size mSize;
- cdm::Buffer* mBuffer;
- uint32_t mPlaneOffsets[kMaxPlanes];
- uint32_t mPlaneStrides[kMaxPlanes];
- int64_t mTimestamp;
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module.h b/dom/media/gmp/widevine-adapter/content_decryption_module.h
deleted file mode 100644
index 0539135fbe..0000000000
--- a/dom/media/gmp/widevine-adapter/content_decryption_module.h
+++ /dev/null
@@ -1,1278 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CDM_CONTENT_DECRYPTION_MODULE_H_
-#define CDM_CONTENT_DECRYPTION_MODULE_H_
-
-#include "content_decryption_module_export.h"
-
-#if defined(_MSC_VER)
-typedef unsigned char uint8_t;
-typedef unsigned int uint32_t;
-typedef int int32_t;
-typedef __int64 int64_t;
-#else
-#include <stdint.h>
-#endif
-
-// Define CDM_CLASS_API to export class types. We have to add visibility
-// attributes to make sure virtual tables in CDM consumer and CDM implementation
-// are the same. Generally, it was always a good idea, as there're no guarantees
-// about that for the internal symbols, but it has only become a practical issue
-// after introduction of LTO devirtualization. See more details on
-// https://crbug.com/609564#c35
-#if defined(_WIN32)
-#if defined(__clang__)
-#define CDM_CLASS_API [[clang::lto_visibility_public]]
-#else
-#define CDM_CLASS_API
-#endif
-#else // defined(_WIN32)
-#define CDM_CLASS_API __attribute__((visibility("default")))
-#endif // defined(_WIN32)
-
-// The version number must be rolled when the exported functions are updated!
-// If the CDM and the adapter use different versions of these functions, the
-// adapter will fail to load or crash!
-#define CDM_MODULE_VERSION 4
-
-// Build the versioned entrypoint name.
-// The extra macros are necessary to expand version to an actual value.
-#define INITIALIZE_CDM_MODULE \
- BUILD_ENTRYPOINT(InitializeCdmModule, CDM_MODULE_VERSION)
-#define BUILD_ENTRYPOINT(name, version) \
- BUILD_ENTRYPOINT_NO_EXPANSION(name, version)
-#define BUILD_ENTRYPOINT_NO_EXPANSION(name, version) name##_##version
-
-extern "C" {
-CDM_API void INITIALIZE_CDM_MODULE();
-
-CDM_API void DeinitializeCdmModule();
-
-// Returns a pointer to the requested CDM Host interface upon success.
-// Returns NULL if the requested CDM Host interface is not supported.
-// The caller should cast the returned pointer to the type matching
-// |host_interface_version|.
-typedef void* (*GetCdmHostFunc)(int host_interface_version, void* user_data);
-
-// Returns a pointer to the requested CDM upon success.
-// Returns NULL if an error occurs or the requested |cdm_interface_version| or
-// |key_system| is not supported or another error occurs.
-// The caller should cast the returned pointer to the type matching
-// |cdm_interface_version|.
-// Caller retains ownership of arguments and must call Destroy() on the returned
-// object.
-CDM_API void* CreateCdmInstance(
- int cdm_interface_version,
- const char* key_system, uint32_t key_system_size,
- GetCdmHostFunc get_cdm_host_func, void* user_data);
-
-CDM_API const char* GetCdmVersion();
-}
-
-namespace cdm {
-
-class CDM_CLASS_API AudioFrames;
-class CDM_CLASS_API DecryptedBlock;
-class CDM_CLASS_API VideoFrame;
-
-class CDM_CLASS_API Host_8;
-class CDM_CLASS_API Host_9;
-
-enum Status {
- kSuccess = 0,
- kNeedMoreData, // Decoder needs more data to produce a decoded frame/sample.
- kNoKey, // The required decryption key is not available.
- kInitializationError, // Initialization error.
- kDecryptError, // Decryption failed.
- kDecodeError, // Error decoding audio or video.
- kDeferredInitialization // Decoder is not ready for initialization.
-};
-
-// This must at least contain the exceptions defined in the spec:
-// https://w3c.github.io/encrypted-media/#exceptions
-// The following starts with the list of DOM4 exceptions from:
-// http://www.w3.org/TR/dom/#domexception
-// Some DOM4 exceptions are not included as they are not expected to be used.
-// Should only be used on Host_8 and before.
-enum Error {
- kNotSupportedError = 9,
- kInvalidStateError = 11,
- kInvalidAccessError = 15,
- kQuotaExceededError = 22,
-
- // Additional exceptions that do not have assigned codes.
- // There are other non-EME-specific values, not included in this list.
- kUnknownError = 30,
-
- // Additional values from previous EME versions. They currently have no
- // matching DOMException.
- kClientError = 100,
- kOutputError = 101
-};
-
-// Exceptions used by the CDM to reject promises.
-// https://w3c.github.io/encrypted-media/#exceptions
-enum Exception {
- kExceptionTypeError,
- kExceptionNotSupportedError,
- kExceptionInvalidStateError,
- kExceptionQuotaExceededError
-};
-
-// Time is defined as the number of seconds since the Epoch
-// (00:00:00 UTC, January 1, 1970), not including any added leap second.
-// Also see Time definition in spec: https://w3c.github.io/encrypted-media/#time
-// Note that Time is defined in millisecond accuracy in the spec but in second
-// accuracy here.
-typedef double Time;
-
-// An input buffer can be split into several continuous subsamples.
-// A SubsampleEntry specifies the number of clear and cipher bytes in each
-// subsample. For example, the following buffer has three subsamples:
-//
-// |<----- subsample1 ----->|<----- subsample2 ----->|<----- subsample3 ----->|
-// | clear1 | cipher1 | clear2 | cipher2 | clear3 | cipher3 |
-//
-// For decryption, all of the cipher bytes in a buffer should be concatenated
-// (in the subsample order) into a single logical stream. The clear bytes should
-// not be considered as part of decryption.
-//
-// Stream to decrypt: | cipher1 | cipher2 | cipher3 |
-// Decrypted stream: | decrypted1| decrypted2 | decrypted3 |
-//
-// After decryption, the decrypted bytes should be copied over the position
-// of the corresponding cipher bytes in the original buffer to form the output
-// buffer. Following the above example, the decrypted buffer should be:
-//
-// |<----- subsample1 ----->|<----- subsample2 ----->|<----- subsample3 ----->|
-// | clear1 | decrypted1| clear2 | decrypted2 | clear3 | decrypted3 |
-//
-struct SubsampleEntry {
- SubsampleEntry(uint32_t clear_bytes, uint32_t cipher_bytes)
- : clear_bytes(clear_bytes), cipher_bytes(cipher_bytes) {}
-
- uint32_t clear_bytes;
- uint32_t cipher_bytes;
-};
-
-// Represents an input buffer to be decrypted (and possibly decoded). It does
-// not own any pointers in this struct. If |iv_size| = 0, the data is
-// unencrypted.
-struct InputBuffer {
- InputBuffer()
- : data(nullptr),
- data_size(0),
- key_id(nullptr),
- key_id_size(0),
- iv(nullptr),
- iv_size(0),
- subsamples(nullptr),
- num_subsamples(0),
- timestamp(0) {}
-
- const uint8_t* data; // Pointer to the beginning of the input data.
- uint32_t data_size; // Size (in bytes) of |data|.
-
- const uint8_t* key_id; // Key ID to identify the decryption key.
- uint32_t key_id_size; // Size (in bytes) of |key_id|.
-
- const uint8_t* iv; // Initialization vector.
- uint32_t iv_size; // Size (in bytes) of |iv|.
-
- const struct SubsampleEntry* subsamples;
- uint32_t num_subsamples; // Number of subsamples in |subsamples|.
-
- int64_t timestamp; // Presentation timestamp in microseconds.
-};
-
-struct AudioDecoderConfig {
- enum AudioCodec {
- kUnknownAudioCodec = 0,
- kCodecVorbis,
- kCodecAac
- };
-
- AudioDecoderConfig()
- : codec(kUnknownAudioCodec),
- channel_count(0),
- bits_per_channel(0),
- samples_per_second(0),
- extra_data(nullptr),
- extra_data_size(0) {}
-
- AudioCodec codec;
- int32_t channel_count;
- int32_t bits_per_channel;
- int32_t samples_per_second;
-
- // Optional byte data required to initialize audio decoders, such as the
- // vorbis setup header.
- uint8_t* extra_data;
- uint32_t extra_data_size;
-};
-
-// Supported sample formats for AudioFrames.
-enum AudioFormat {
- kUnknownAudioFormat = 0, // Unknown format value. Used for error reporting.
- kAudioFormatU8, // Interleaved unsigned 8-bit w/ bias of 128.
- kAudioFormatS16, // Interleaved signed 16-bit.
- kAudioFormatS32, // Interleaved signed 32-bit.
- kAudioFormatF32, // Interleaved float 32-bit.
- kAudioFormatPlanarS16, // Signed 16-bit planar.
- kAudioFormatPlanarF32, // Float 32-bit planar.
-};
-
-// Surface formats based on FOURCC labels, see: http://www.fourcc.org/yuv.php
-// Values are chosen to be consistent with Chromium's VideoPixelFormat values.
-enum VideoFormat {
- kUnknownVideoFormat = 0, // Unknown format value. Used for error reporting.
- kYv12 = 1, // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
- kI420 = 2, // 12bpp YUV planar 1x1 Y, 2x2 UV samples.
-
- // In the following formats, each sample uses 16-bit in storage, while the
- // sample value is stored in the least significant N bits where N is
- // specified by the number after "P". For example, for YUV420P9, each Y, U,
- // and V sample is stored in the least significant 9 bits in a 2-byte block.
- kYUV420P9 = 16,
- kYUV420P10 = 17,
- kYUV422P9 = 18,
- kYUV422P10 = 19,
- kYUV444P9 = 20,
- kYUV444P10 = 21,
- kYUV420P12 = 22,
- kYUV422P12 = 23,
- kYUV444P12 = 24,
-};
-
-struct Size {
- Size() : width(0), height(0) {}
- Size(int32_t width, int32_t height) : width(width), height(height) {}
-
- int32_t width;
- int32_t height;
-};
-
-struct VideoDecoderConfig {
- enum VideoCodec {
- kUnknownVideoCodec = 0,
- kCodecVp8,
- kCodecH264,
- kCodecVp9
- };
-
- enum VideoCodecProfile {
- kUnknownVideoCodecProfile = 0,
- kProfileNotNeeded,
- kH264ProfileBaseline,
- kH264ProfileMain,
- kH264ProfileExtended,
- kH264ProfileHigh,
- kH264ProfileHigh10,
- kH264ProfileHigh422,
- kH264ProfileHigh444Predictive,
- // VP9 Profiles are only passed in starting from CDM_9.
- kVP9Profile0,
- kVP9Profile1,
- kVP9Profile2,
- kVP9Profile3
- };
-
- VideoDecoderConfig()
- : codec(kUnknownVideoCodec),
- profile(kUnknownVideoCodecProfile),
- format(kUnknownVideoFormat),
- extra_data(nullptr),
- extra_data_size(0) {}
-
- VideoCodec codec;
- VideoCodecProfile profile;
- VideoFormat format;
-
- // Width and height of video frame immediately post-decode. Not all pixels
- // in this region are valid.
- Size coded_size;
-
- // Optional byte data required to initialize video decoders, such as H.264
- // AAVC data.
- uint8_t* extra_data;
- uint32_t extra_data_size;
-};
-
-enum StreamType {
- kStreamTypeAudio = 0,
- kStreamTypeVideo = 1
-};
-
-// Structure provided to ContentDecryptionModule::OnPlatformChallengeResponse()
-// after a platform challenge was initiated via Host::SendPlatformChallenge().
-// All values will be NULL / zero in the event of a challenge failure.
-struct PlatformChallengeResponse {
- // |challenge| provided during Host::SendPlatformChallenge() combined with
- // nonce data and signed with the platform's private key.
- const uint8_t* signed_data;
- uint32_t signed_data_length;
-
- // RSASSA-PKCS1-v1_5-SHA256 signature of the |signed_data| block.
- const uint8_t* signed_data_signature;
- uint32_t signed_data_signature_length;
-
- // X.509 device specific certificate for the |service_id| requested.
- const uint8_t* platform_key_certificate;
- uint32_t platform_key_certificate_length;
-};
-
-// Used when passing arrays of binary data. Does not own the referenced data.
-struct BinaryData {
- BinaryData() : data(nullptr), length(0) {}
- const uint8_t* data;
- uint32_t length;
-};
-
-// The current status of the associated key. The valid types are defined in the
-// spec: https://w3c.github.io/encrypted-media/#idl-def-MediaKeyStatus
-enum KeyStatus {
- kUsable = 0,
- kInternalError = 1,
- kExpired = 2,
- kOutputRestricted = 3,
- kOutputDownscaled = 4,
- kStatusPending = 5,
- kReleased = 6
-};
-
-// Used when passing arrays of key information. Does not own the referenced
-// data. |system_code| is an additional error code for unusable keys and
-// should be 0 when |status| == kUsable.
-struct KeyInformation {
- KeyInformation()
- : key_id(nullptr),
- key_id_size(0),
- status(kInternalError),
- system_code(0) {}
- const uint8_t* key_id;
- uint32_t key_id_size;
- KeyStatus status;
- uint32_t system_code;
-};
-
-// Supported output protection methods for use with EnableOutputProtection() and
-// returned by OnQueryOutputProtectionStatus().
-enum OutputProtectionMethods {
- kProtectionNone = 0,
- kProtectionHDCP = 1 << 0
-};
-
-// Connected output link types returned by OnQueryOutputProtectionStatus().
-enum OutputLinkTypes {
- kLinkTypeNone = 0,
- kLinkTypeUnknown = 1 << 0,
- kLinkTypeInternal = 1 << 1,
- kLinkTypeVGA = 1 << 2,
- kLinkTypeHDMI = 1 << 3,
- kLinkTypeDVI = 1 << 4,
- kLinkTypeDisplayPort = 1 << 5,
- kLinkTypeNetwork = 1 << 6
-};
-
-// Result of the QueryOutputProtectionStatus() call.
-enum QueryResult {
- kQuerySucceeded = 0,
- kQueryFailed
-};
-
-// The Initialization Data Type. The valid types are defined in the spec:
-// http://w3c.github.io/encrypted-media/initdata-format-registry.html#registry
-enum InitDataType {
- kCenc = 0,
- kKeyIds = 1,
- kWebM = 2
-};
-
-// The type of session to create. The valid types are defined in the spec:
-// https://w3c.github.io/encrypted-media/#idl-def-SessionType
-enum SessionType {
- kTemporary = 0,
- kPersistentLicense = 1,
- kPersistentKeyRelease = 2
-};
-
-// The type of the message event. The valid types are defined in the spec:
-// https://w3c.github.io/encrypted-media/#idl-def-MediaKeyMessageType
-enum MessageType {
- kLicenseRequest = 0,
- kLicenseRenewal = 1,
- kLicenseRelease = 2
-};
-
-enum HdcpVersion {
- kHdcpVersionNone,
- kHdcpVersion1_0,
- kHdcpVersion1_1,
- kHdcpVersion1_2,
- kHdcpVersion1_3,
- kHdcpVersion1_4,
- kHdcpVersion2_0,
- kHdcpVersion2_1,
- kHdcpVersion2_2
-};
-
-struct Policy {
- Policy() : min_hdcp_version(kHdcpVersionNone) {}
-
- HdcpVersion min_hdcp_version;
-};
-
-// FileIO interface provides a way for the CDM to store data in a file in
-// persistent storage. This interface aims only at providing basic read/write
-// capabilities and should not be used as a full fledged file IO API.
-// Each CDM and origin (e.g. HTTPS, "foo.example.com", 443) combination has
-// its own persistent storage. All instances of a given CDM associated with a
-// given origin share the same persistent storage.
-// Note to implementors of this interface:
-// Per-origin storage and the ability for users to clear it are important.
-// See http://www.w3.org/TR/encrypted-media/#privacy-storedinfo.
-class CDM_CLASS_API FileIO {
- public:
- // Opens the file with |file_name| for read and write.
- // FileIOClient::OnOpenComplete() will be called after the opening
- // operation finishes.
- // - When the file is opened by a CDM instance, it will be classified as "in
- // use". In this case other CDM instances in the same domain may receive
- // kInUse status when trying to open it.
- // - |file_name| must only contain letters (A-Za-z), digits(0-9), or "._-".
- // It must not start with an underscore ('_'), and must be at least 1
- // character and no more than 256 characters long.
- virtual void Open(const char* file_name, uint32_t file_name_size) = 0;
-
- // Reads the contents of the file. FileIOClient::OnReadComplete() will be
- // called with the read status. Read() should not be called if a previous
- // Read() or Write() call is still pending; otherwise OnReadComplete() will
- // be called with kInUse.
- virtual void Read() = 0;
-
- // Writes |data_size| bytes of |data| into the file.
- // FileIOClient::OnWriteComplete() will be called with the write status.
- // All existing contents in the file will be overwritten. Calling Write() with
- // NULL |data| will clear all contents in the file. Write() should not be
- // called if a previous Write() or Read() call is still pending; otherwise
- // OnWriteComplete() will be called with kInUse.
- virtual void Write(const uint8_t* data, uint32_t data_size) = 0;
-
- // Closes the file if opened, destroys this FileIO object and releases any
- // resources allocated. The CDM must call this method when it finished using
- // this object. A FileIO object must not be used after Close() is called.
- virtual void Close() = 0;
-
- protected:
- FileIO() {}
- virtual ~FileIO() {}
-};
-
-// Responses to FileIO calls. All responses will be called asynchronously.
-// When kError is returned, the FileIO object could be in an error state. All
-// following calls (other than Close()) could return kError. The CDM should
-// still call Close() to destroy the FileIO object.
-class CDM_CLASS_API FileIOClient {
- public:
- enum Status {
- kSuccess = 0,
- kInUse,
- kError
- };
-
- // Response to a FileIO::Open() call with the open |status|.
- virtual void OnOpenComplete(Status status) = 0;
-
- // Response to a FileIO::Read() call to provide |data_size| bytes of |data|
- // read from the file.
- // - kSuccess indicates that all contents of the file has been successfully
- // read. In this case, 0 |data_size| means that the file is empty.
- // - kInUse indicates that there are other read/write operations pending.
- // - kError indicates read failure, e.g. the storage is not open or cannot be
- // fully read.
- virtual void OnReadComplete(Status status,
- const uint8_t* data, uint32_t data_size) = 0;
-
- // Response to a FileIO::Write() call.
- // - kSuccess indicates that all the data has been written into the file
- // successfully.
- // - kInUse indicates that there are other read/write operations pending.
- // - kError indicates write failure, e.g. the storage is not open or cannot be
- // fully written. Upon write failure, the contents of the file should be
- // regarded as corrupt and should not used.
- virtual void OnWriteComplete(Status status) = 0;
-
- protected:
- FileIOClient() {}
- virtual ~FileIOClient() {}
-};
-
-// ContentDecryptionModule interface that all CDMs need to implement.
-// The interface is versioned for backward compatibility.
-// Note: ContentDecryptionModule implementations must use the allocator
-// provided in CreateCdmInstance() to allocate any Buffer that needs to
-// be passed back to the caller. Implementations must call Buffer::Destroy()
-// when a Buffer is created that will never be returned to the caller.
-class CDM_CLASS_API ContentDecryptionModule_8 {
- public:
- static const int kVersion = 8;
- typedef Host_8 Host;
-
- // Initializes the CDM instance, providing information about permitted
- // functionalities.
- // If |allow_distinctive_identifier| is false, messages from the CDM,
- // such as message events, must not contain a Distinctive Identifier,
- // even in an encrypted form.
- // If |allow_persistent_state| is false, the CDM must not attempt to
- // persist state. Calls to CreateFileIO() will fail.
- virtual void Initialize(bool allow_distinctive_identifier,
- bool allow_persistent_state) = 0;
-
- // SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(),
- // UpdateSession(), CloseSession(), and RemoveSession() all accept a
- // |promise_id|, which must be passed to the completion Host method
- // (e.g. Host::OnResolveNewSessionPromise()).
-
- // Provides a server certificate to be used to encrypt messages to the
- // license server. The CDM must respond by calling either
- // Host::OnResolvePromise() or Host::OnRejectPromise().
- virtual void SetServerCertificate(uint32_t promise_id,
- const uint8_t* server_certificate_data,
- uint32_t server_certificate_data_size) = 0;
-
- // Creates a session given |session_type|, |init_data_type|, and |init_data|.
- // The CDM must respond by calling either Host::OnResolveNewSessionPromise()
- // or Host::OnRejectPromise().
- virtual void CreateSessionAndGenerateRequest(uint32_t promise_id,
- SessionType session_type,
- InitDataType init_data_type,
- const uint8_t* init_data,
- uint32_t init_data_size) = 0;
-
- // Loads the session of type |session_type| specified by |session_id|.
- // The CDM must respond by calling either Host::OnResolveNewSessionPromise()
- // or Host::OnRejectPromise(). If the session is not found, call
- // Host::OnResolveNewSessionPromise() with session_id = NULL.
- virtual void LoadSession(uint32_t promise_id,
- SessionType session_type,
- const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Updates the session with |response|. The CDM must respond by calling
- // either Host::OnResolvePromise() or Host::OnRejectPromise().
- virtual void UpdateSession(uint32_t promise_id,
- const char* session_id,
- uint32_t session_id_size,
- const uint8_t* response,
- uint32_t response_size) = 0;
-
- // Requests that the CDM close the session. The CDM must respond by calling
- // either Host::OnResolvePromise() or Host::OnRejectPromise() when the request
- // has been processed. This may be before the session is closed. Once the
- // session is closed, Host::OnSessionClosed() must also be called.
- virtual void CloseSession(uint32_t promise_id,
- const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Removes any stored session data associated with this session. Will only be
- // called for persistent sessions. The CDM must respond by calling either
- // Host::OnResolvePromise() or Host::OnRejectPromise() when the request has
- // been processed.
- virtual void RemoveSession(uint32_t promise_id,
- const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Performs scheduled operation with |context| when the timer fires.
- virtual void TimerExpired(void* context) = 0;
-
- // Decrypts the |encrypted_buffer|.
- //
- // Returns kSuccess if decryption succeeded, in which case the callee
- // should have filled the |decrypted_buffer| and passed the ownership of
- // |data| in |decrypted_buffer| to the caller.
- // Returns kNoKey if the CDM did not have the necessary decryption key
- // to decrypt.
- // Returns kDecryptError if any other error happened.
- // If the return value is not kSuccess, |decrypted_buffer| should be ignored
- // by the caller.
- virtual Status Decrypt(const InputBuffer& encrypted_buffer,
- DecryptedBlock* decrypted_buffer) = 0;
-
- // Initializes the CDM audio decoder with |audio_decoder_config|. This
- // function must be called before DecryptAndDecodeSamples() is called.
- //
- // Returns kSuccess if the |audio_decoder_config| is supported and the CDM
- // audio decoder is successfully initialized.
- // Returns kSessionError if |audio_decoder_config| is not supported. The CDM
- // may still be able to do Decrypt().
- // Returns kDeferredInitialization if the CDM is not ready to initialize the
- // decoder at this time. Must call Host::OnDeferredInitializationDone() once
- // initialization is complete.
- virtual Status InitializeAudioDecoder(
- const AudioDecoderConfig& audio_decoder_config) = 0;
-
- // Initializes the CDM video decoder with |video_decoder_config|. This
- // function must be called before DecryptAndDecodeFrame() is called.
- //
- // Returns kSuccess if the |video_decoder_config| is supported and the CDM
- // video decoder is successfully initialized.
- // Returns kSessionError if |video_decoder_config| is not supported. The CDM
- // may still be able to do Decrypt().
- // Returns kDeferredInitialization if the CDM is not ready to initialize the
- // decoder at this time. Must call Host::OnDeferredInitializationDone() once
- // initialization is complete.
- virtual Status InitializeVideoDecoder(
- const VideoDecoderConfig& video_decoder_config) = 0;
-
- // De-initializes the CDM decoder and sets it to an uninitialized state. The
- // caller can initialize the decoder again after this call to re-initialize
- // it. This can be used to reconfigure the decoder if the configuration
- // changes.
- virtual void DeinitializeDecoder(StreamType decoder_type) = 0;
-
- // Resets the CDM decoder to an initialized clean state. All internal buffers
- // MUST be flushed.
- virtual void ResetDecoder(StreamType decoder_type) = 0;
-
- // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into a
- // |video_frame|. Upon end-of-stream, the caller should call this function
- // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
- // |video_frame| (|format| == kEmptyVideoFrame) is produced.
- //
- // Returns kSuccess if decryption and decoding both succeeded, in which case
- // the callee will have filled the |video_frame| and passed the ownership of
- // |frame_buffer| in |video_frame| to the caller.
- // Returns kNoKey if the CDM did not have the necessary decryption key
- // to decrypt.
- // Returns kNeedMoreData if more data was needed by the decoder to generate
- // a decoded frame (e.g. during initialization and end-of-stream).
- // Returns kDecryptError if any decryption error happened.
- // Returns kDecodeError if any decoding error happened.
- // If the return value is not kSuccess, |video_frame| should be ignored by
- // the caller.
- virtual Status DecryptAndDecodeFrame(const InputBuffer& encrypted_buffer,
- VideoFrame* video_frame) = 0;
-
- // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into
- // |audio_frames|. Upon end-of-stream, the caller should call this function
- // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
- // |audio_frames| is produced.
- //
- // Returns kSuccess if decryption and decoding both succeeded, in which case
- // the callee will have filled |audio_frames| and passed the ownership of
- // |data| in |audio_frames| to the caller.
- // Returns kNoKey if the CDM did not have the necessary decryption key
- // to decrypt.
- // Returns kNeedMoreData if more data was needed by the decoder to generate
- // audio samples (e.g. during initialization and end-of-stream).
- // Returns kDecryptError if any decryption error happened.
- // Returns kDecodeError if any decoding error happened.
- // If the return value is not kSuccess, |audio_frames| should be ignored by
- // the caller.
- virtual Status DecryptAndDecodeSamples(const InputBuffer& encrypted_buffer,
- AudioFrames* audio_frames) = 0;
-
- // Called by the host after a platform challenge was initiated via
- // Host::SendPlatformChallenge().
- virtual void OnPlatformChallengeResponse(
- const PlatformChallengeResponse& response) = 0;
-
- // Called by the host after a call to Host::QueryOutputProtectionStatus(). The
- // |link_mask| is a bit mask of OutputLinkTypes and |output_protection_mask|
- // is a bit mask of OutputProtectionMethods. If |result| is kQueryFailed,
- // then |link_mask| and |output_protection_mask| are undefined and should
- // be ignored.
- virtual void OnQueryOutputProtectionStatus(
- QueryResult result,
- uint32_t link_mask,
- uint32_t output_protection_mask) = 0;
-
- // Destroys the object in the same context as it was created.
- virtual void Destroy() = 0;
-
- protected:
- ContentDecryptionModule_8() {}
- virtual ~ContentDecryptionModule_8() {}
-};
-
-// ContentDecryptionModule interface that all CDMs need to implement.
-// The interface is versioned for backward compatibility.
-// Note: ContentDecryptionModule implementations must use the allocator
-// provided in CreateCdmInstance() to allocate any Buffer that needs to
-// be passed back to the caller. Implementations must call Buffer::Destroy()
-// when a Buffer is created that will never be returned to the caller.
-class CDM_CLASS_API ContentDecryptionModule_9 {
- public:
- static const int kVersion = 9;
- typedef Host_9 Host;
-
- // Initializes the CDM instance, providing information about permitted
- // functionalities.
- // If |allow_distinctive_identifier| is false, messages from the CDM,
- // such as message events, must not contain a Distinctive Identifier,
- // even in an encrypted form.
- // If |allow_persistent_state| is false, the CDM must not attempt to
- // persist state. Calls to CreateFileIO() will fail.
- virtual void Initialize(bool allow_distinctive_identifier,
- bool allow_persistent_state) = 0;
-
- // Gets the key status if the CDM has a hypothetical key with the |policy|.
- // The CDM must respond by calling either Host::OnResolveKeyStatusPromise()
- // with the result key status or Host::OnRejectPromise() if an unexpected
- // error happened or this method is not supported.
- virtual void GetStatusForPolicy(uint32_t promise_id,
- const Policy& policy) = 0;
-
- // SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(),
- // UpdateSession(), CloseSession(), and RemoveSession() all accept a
- // |promise_id|, which must be passed to the completion Host method
- // (e.g. Host::OnResolveNewSessionPromise()).
-
- // Provides a server certificate to be used to encrypt messages to the
- // license server. The CDM must respond by calling either
- // Host::OnResolvePromise() or Host::OnRejectPromise().
- virtual void SetServerCertificate(uint32_t promise_id,
- const uint8_t* server_certificate_data,
- uint32_t server_certificate_data_size) = 0;
-
- // Creates a session given |session_type|, |init_data_type|, and |init_data|.
- // The CDM must respond by calling either Host::OnResolveNewSessionPromise()
- // or Host::OnRejectPromise().
- virtual void CreateSessionAndGenerateRequest(uint32_t promise_id,
- SessionType session_type,
- InitDataType init_data_type,
- const uint8_t* init_data,
- uint32_t init_data_size) = 0;
-
- // Loads the session of type |session_type| specified by |session_id|.
- // The CDM must respond by calling either Host::OnResolveNewSessionPromise()
- // or Host::OnRejectPromise(). If the session is not found, call
- // Host::OnResolveNewSessionPromise() with session_id = NULL.
- virtual void LoadSession(uint32_t promise_id,
- SessionType session_type,
- const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Updates the session with |response|. The CDM must respond by calling
- // either Host::OnResolvePromise() or Host::OnRejectPromise().
- virtual void UpdateSession(uint32_t promise_id,
- const char* session_id,
- uint32_t session_id_size,
- const uint8_t* response,
- uint32_t response_size) = 0;
-
- // Requests that the CDM close the session. The CDM must respond by calling
- // either Host::OnResolvePromise() or Host::OnRejectPromise() when the request
- // has been processed. This may be before the session is closed. Once the
- // session is closed, Host::OnSessionClosed() must also be called.
- virtual void CloseSession(uint32_t promise_id,
- const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Removes any stored session data associated with this session. Will only be
- // called for persistent sessions. The CDM must respond by calling either
- // Host::OnResolvePromise() or Host::OnRejectPromise() when the request has
- // been processed.
- virtual void RemoveSession(uint32_t promise_id,
- const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Performs scheduled operation with |context| when the timer fires.
- virtual void TimerExpired(void* context) = 0;
-
- // Decrypts the |encrypted_buffer|.
- //
- // Returns kSuccess if decryption succeeded, in which case the callee
- // should have filled the |decrypted_buffer| and passed the ownership of
- // |data| in |decrypted_buffer| to the caller.
- // Returns kNoKey if the CDM did not have the necessary decryption key
- // to decrypt.
- // Returns kDecryptError if any other error happened.
- // If the return value is not kSuccess, |decrypted_buffer| should be ignored
- // by the caller.
- virtual Status Decrypt(const InputBuffer& encrypted_buffer,
- DecryptedBlock* decrypted_buffer) = 0;
-
- // Initializes the CDM audio decoder with |audio_decoder_config|. This
- // function must be called before DecryptAndDecodeSamples() is called.
- //
- // Returns kSuccess if the |audio_decoder_config| is supported and the CDM
- // audio decoder is successfully initialized.
- // Returns kInitializationError if |audio_decoder_config| is not supported.
- // The CDM may still be able to do Decrypt().
- // Returns kDeferredInitialization if the CDM is not ready to initialize the
- // decoder at this time. Must call Host::OnDeferredInitializationDone() once
- // initialization is complete.
- virtual Status InitializeAudioDecoder(
- const AudioDecoderConfig& audio_decoder_config) = 0;
-
- // Initializes the CDM video decoder with |video_decoder_config|. This
- // function must be called before DecryptAndDecodeFrame() is called.
- //
- // Returns kSuccess if the |video_decoder_config| is supported and the CDM
- // video decoder is successfully initialized.
- // Returns kInitializationError if |video_decoder_config| is not supported.
- // The CDM may still be able to do Decrypt().
- // Returns kDeferredInitialization if the CDM is not ready to initialize the
- // decoder at this time. Must call Host::OnDeferredInitializationDone() once
- // initialization is complete.
- virtual Status InitializeVideoDecoder(
- const VideoDecoderConfig& video_decoder_config) = 0;
-
- // De-initializes the CDM decoder and sets it to an uninitialized state. The
- // caller can initialize the decoder again after this call to re-initialize
- // it. This can be used to reconfigure the decoder if the configuration
- // changes.
- virtual void DeinitializeDecoder(StreamType decoder_type) = 0;
-
- // Resets the CDM decoder to an initialized clean state. All internal buffers
- // MUST be flushed.
- virtual void ResetDecoder(StreamType decoder_type) = 0;
-
- // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into a
- // |video_frame|. Upon end-of-stream, the caller should call this function
- // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
- // |video_frame| (|format| == kEmptyVideoFrame) is produced.
- //
- // Returns kSuccess if decryption and decoding both succeeded, in which case
- // the callee will have filled the |video_frame| and passed the ownership of
- // |frame_buffer| in |video_frame| to the caller.
- // Returns kNoKey if the CDM did not have the necessary decryption key
- // to decrypt.
- // Returns kNeedMoreData if more data was needed by the decoder to generate
- // a decoded frame (e.g. during initialization and end-of-stream).
- // Returns kDecryptError if any decryption error happened.
- // Returns kDecodeError if any decoding error happened.
- // If the return value is not kSuccess, |video_frame| should be ignored by
- // the caller.
- virtual Status DecryptAndDecodeFrame(const InputBuffer& encrypted_buffer,
- VideoFrame* video_frame) = 0;
-
- // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into
- // |audio_frames|. Upon end-of-stream, the caller should call this function
- // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
- // |audio_frames| is produced.
- //
- // Returns kSuccess if decryption and decoding both succeeded, in which case
- // the callee will have filled |audio_frames| and passed the ownership of
- // |data| in |audio_frames| to the caller.
- // Returns kNoKey if the CDM did not have the necessary decryption key
- // to decrypt.
- // Returns kNeedMoreData if more data was needed by the decoder to generate
- // audio samples (e.g. during initialization and end-of-stream).
- // Returns kDecryptError if any decryption error happened.
- // Returns kDecodeError if any decoding error happened.
- // If the return value is not kSuccess, |audio_frames| should be ignored by
- // the caller.
- virtual Status DecryptAndDecodeSamples(const InputBuffer& encrypted_buffer,
- AudioFrames* audio_frames) = 0;
-
- // Called by the host after a platform challenge was initiated via
- // Host::SendPlatformChallenge().
- virtual void OnPlatformChallengeResponse(
- const PlatformChallengeResponse& response) = 0;
-
- // Called by the host after a call to Host::QueryOutputProtectionStatus(). The
- // |link_mask| is a bit mask of OutputLinkTypes and |output_protection_mask|
- // is a bit mask of OutputProtectionMethods. If |result| is kQueryFailed,
- // then |link_mask| and |output_protection_mask| are undefined and should
- // be ignored.
- virtual void OnQueryOutputProtectionStatus(
- QueryResult result,
- uint32_t link_mask,
- uint32_t output_protection_mask) = 0;
-
- // Called by the host after a call to Host::RequestStorageId(). If the
- // version of the storage ID requested is available, |storage_id| and
- // |storage_id_size| are set appropriately. |version| will be the same as
- // what was requested, unless 0 (latest) was requested, in which case
- // |version| will be the actual version number for the |storage_id| returned.
- // If the requested version is not available, null/zero will be provided as
- // |storage_id| and |storage_id_size|, respectively, and |version| should be
- // ignored.
- virtual void OnStorageId(uint32_t version,
- const uint8_t* storage_id,
- uint32_t storage_id_size) = 0;
-
- // Destroys the object in the same context as it was created.
- virtual void Destroy() = 0;
-
- protected:
- ContentDecryptionModule_9() {}
- virtual ~ContentDecryptionModule_9() {}
-};
-
-typedef ContentDecryptionModule_9 ContentDecryptionModule;
-
-// Represents a buffer created by Allocator implementations.
-class CDM_CLASS_API Buffer {
- public:
- // Destroys the buffer in the same context as it was created.
- virtual void Destroy() = 0;
-
- virtual uint32_t Capacity() const = 0;
- virtual uint8_t* Data() = 0;
- virtual void SetSize(uint32_t size) = 0;
- virtual uint32_t Size() const = 0;
-
- protected:
- Buffer() {}
- virtual ~Buffer() {}
-
- private:
- Buffer(const Buffer&);
- void operator=(const Buffer&);
-};
-
-class CDM_CLASS_API Host_8 {
- public:
- static const int kVersion = 8;
-
- // Returns a Buffer* containing non-zero members upon success, or NULL on
- // failure. The caller owns the Buffer* after this call. The buffer is not
- // guaranteed to be zero initialized. The capacity of the allocated Buffer
- // is guaranteed to be not less than |capacity|.
- virtual Buffer* Allocate(uint32_t capacity) = 0;
-
- // Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms|
- // from now with |context|.
- virtual void SetTimer(int64_t delay_ms, void* context) = 0;
-
- // Returns the current wall time.
- virtual Time GetCurrentWallTime() = 0;
-
- // Called by the CDM when a session is created or loaded and the value for the
- // MediaKeySession's sessionId attribute is available (|session_id|).
- // This must be called before OnSessionMessage() or
- // OnSessionKeysChange() is called for the same session. |session_id_size|
- // should not include null termination.
- // When called in response to LoadSession(), the |session_id| must be the
- // same as the |session_id| passed in LoadSession(), or NULL if the
- // session could not be loaded.
- virtual void OnResolveNewSessionPromise(uint32_t promise_id,
- const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Called by the CDM when a session is updated or released.
- virtual void OnResolvePromise(uint32_t promise_id) = 0;
-
- // Called by the CDM when an error occurs as a result of one of the
- // ContentDecryptionModule calls that accept a |promise_id|.
- // |error| must be specified, |error_message| and |system_code|
- // are optional. |error_message_size| should not include null termination.
- virtual void OnRejectPromise(uint32_t promise_id,
- Error error,
- uint32_t system_code,
- const char* error_message,
- uint32_t error_message_size) = 0;
-
- // Called by the CDM when it has a message for session |session_id|.
- // Size parameters should not include null termination.
- // |legacy_destination_url| is only for supporting the prefixed EME API and
- // is ignored by unprefixed EME. It should only be non-null if |message_type|
- // is kLicenseRenewal.
- virtual void OnSessionMessage(const char* session_id,
- uint32_t session_id_size,
- MessageType message_type,
- const char* message,
- uint32_t message_size,
- const char* legacy_destination_url,
- uint32_t legacy_destination_url_length) = 0;
-
- // Called by the CDM when there has been a change in keys or their status for
- // session |session_id|. |has_additional_usable_key| should be set if a
- // key is newly usable (e.g. new key available, previously expired key has
- // been renewed, etc.) and the browser should attempt to resume playback.
- // |key_ids| is the list of key ids for this session along with their
- // current status. |key_ids_count| is the number of entries in |key_ids|.
- // Size parameter for |session_id| should not include null termination.
- virtual void OnSessionKeysChange(const char* session_id,
- uint32_t session_id_size,
- bool has_additional_usable_key,
- const KeyInformation* keys_info,
- uint32_t keys_info_count) = 0;
-
- // Called by the CDM when there has been a change in the expiration time for
- // session |session_id|. This can happen as the result of an Update() call
- // or some other event. If this happens as a result of a call to Update(),
- // it must be called before resolving the Update() promise. |new_expiry_time|
- // represents the time after which the key(s) in the session will no longer
- // be usable for decryption. It can be 0 if no such time exists or if the
- // license explicitly never expires. Size parameter should not include null
- // termination.
- virtual void OnExpirationChange(const char* session_id,
- uint32_t session_id_size,
- Time new_expiry_time) = 0;
-
- // Called by the CDM when session |session_id| is closed. Size
- // parameter should not include null termination.
- virtual void OnSessionClosed(const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Called by the CDM when an error occurs in session |session_id|
- // unrelated to one of the ContentDecryptionModule calls that accept a
- // |promise_id|. |error| must be specified, |error_message| and
- // |system_code| are optional. Length parameters should not include null
- // termination.
- // Note:
- // - This method is only for supporting prefixed EME API.
- // - This method will be ignored by unprefixed EME. All errors reported
- // in this method should probably also be reported by one of other methods.
- virtual void OnLegacySessionError(
- const char* session_id, uint32_t session_id_length,
- Error error,
- uint32_t system_code,
- const char* error_message, uint32_t error_message_length) = 0;
-
- // The following are optional methods that may not be implemented on all
- // platforms.
-
- // Sends a platform challenge for the given |service_id|. |challenge| is at
- // most 256 bits of data to be signed. Once the challenge has been completed,
- // the host will call ContentDecryptionModule::OnPlatformChallengeResponse()
- // with the signed challenge response and platform certificate. Size
- // parameters should not include null termination.
- virtual void SendPlatformChallenge(const char* service_id,
- uint32_t service_id_size,
- const char* challenge,
- uint32_t challenge_size) = 0;
-
- // Attempts to enable output protection (e.g. HDCP) on the display link. The
- // |desired_protection_mask| is a bit mask of OutputProtectionMethods. No
- // status callback is issued, the CDM must call QueryOutputProtectionStatus()
- // periodically to ensure the desired protections are applied.
- virtual void EnableOutputProtection(uint32_t desired_protection_mask) = 0;
-
- // Requests the current output protection status. Once the host has the status
- // it will call ContentDecryptionModule::OnQueryOutputProtectionStatus().
- virtual void QueryOutputProtectionStatus() = 0;
-
- // Must be called by the CDM if it returned kDeferredInitialization during
- // InitializeAudioDecoder() or InitializeVideoDecoder().
- virtual void OnDeferredInitializationDone(StreamType stream_type,
- Status decoder_status) = 0;
-
- // Creates a FileIO object from the host to do file IO operation. Returns NULL
- // if a FileIO object cannot be obtained. Once a valid FileIO object is
- // returned, |client| must be valid until FileIO::Close() is called. The
- // CDM can call this method multiple times to operate on different files.
- virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
-
- protected:
- Host_8() {}
- virtual ~Host_8() {}
-};
-
-class CDM_CLASS_API Host_9 {
- public:
- static const int kVersion = 9;
-
- // Returns a Buffer* containing non-zero members upon success, or NULL on
- // failure. The caller owns the Buffer* after this call. The buffer is not
- // guaranteed to be zero initialized. The capacity of the allocated Buffer
- // is guaranteed to be not less than |capacity|.
- virtual Buffer* Allocate(uint32_t capacity) = 0;
-
- // Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms|
- // from now with |context|.
- virtual void SetTimer(int64_t delay_ms, void* context) = 0;
-
- // Returns the current wall time.
- virtual Time GetCurrentWallTime() = 0;
-
- // Called by the CDM when a key status is available in response to
- // GetStatusForPolicy().
- virtual void OnResolveKeyStatusPromise(uint32_t promise_id,
- KeyStatus key_status) = 0;
-
- // Called by the CDM when a session is created or loaded and the value for the
- // MediaKeySession's sessionId attribute is available (|session_id|).
- // This must be called before OnSessionMessage() or
- // OnSessionKeysChange() is called for the same session. |session_id_size|
- // should not include null termination.
- // When called in response to LoadSession(), the |session_id| must be the
- // same as the |session_id| passed in LoadSession(), or NULL if the
- // session could not be loaded.
- virtual void OnResolveNewSessionPromise(uint32_t promise_id,
- const char* session_id,
- uint32_t session_id_size) = 0;
-
- // Called by the CDM when a session is updated or released.
- virtual void OnResolvePromise(uint32_t promise_id) = 0;
-
- // Called by the CDM when an error occurs as a result of one of the
- // ContentDecryptionModule calls that accept a |promise_id|.
- // |exception| must be specified. |error_message| and |system_code|
- // are optional. |error_message_size| should not include null termination.
- virtual void OnRejectPromise(uint32_t promise_id,
- Exception exception,
- uint32_t system_code,
- const char* error_message,
- uint32_t error_message_size) = 0;
-
- // Called by the CDM when it has a message for session |session_id|.
- // Size parameters should not include null termination.
- virtual void OnSessionMessage(const char* session_id,
- uint32_t session_id_size,
- MessageType message_type,
- const char* message,
- uint32_t message_size) = 0;
-
- // Called by the CDM when there has been a change in keys or their status for
- // session |session_id|. |has_additional_usable_key| should be set if a
- // key is newly usable (e.g. new key available, previously expired key has
- // been renewed, etc.) and the browser should attempt to resume playback.
- // |key_ids| is the list of key ids for this session along with their
- // current status. |key_ids_count| is the number of entries in |key_ids|.
- // Size parameter for |session_id| should not include null termination.
- virtual void OnSessionKeysChange(const char* session_id,
- uint32_t session_id_size,
- bool has_additional_usable_key,
- const KeyInformation* keys_info,
- uint32_t keys_info_count) = 0;
-
- // Called by the CDM when there has been a change in the expiration time for
- // session |session_id|. This can happen as the result of an Update() call
- // or some other event. If this happens as a result of a call to Update(),
- // it must be called before resolving the Update() promise. |new_expiry_time|
- // represents the time after which the key(s) in the session will no longer
- // be usable for decryption. It can be 0 if no such time exists or if the
- // license explicitly never expires. Size parameter should not include null
- // termination.
- virtual void OnExpirationChange(const char* session_id,
- uint32_t session_id_size,
- Time new_expiry_time) = 0;
-
- // Called by the CDM when session |session_id| is closed. Size
- // parameter should not include null termination.
- virtual void OnSessionClosed(const char* session_id,
- uint32_t session_id_size) = 0;
-
- // The following are optional methods that may not be implemented on all
- // platforms.
-
- // Sends a platform challenge for the given |service_id|. |challenge| is at
- // most 256 bits of data to be signed. Once the challenge has been completed,
- // the host will call ContentDecryptionModule::OnPlatformChallengeResponse()
- // with the signed challenge response and platform certificate. Size
- // parameters should not include null termination.
- virtual void SendPlatformChallenge(const char* service_id,
- uint32_t service_id_size,
- const char* challenge,
- uint32_t challenge_size) = 0;
-
- // Attempts to enable output protection (e.g. HDCP) on the display link. The
- // |desired_protection_mask| is a bit mask of OutputProtectionMethods. No
- // status callback is issued, the CDM must call QueryOutputProtectionStatus()
- // periodically to ensure the desired protections are applied.
- virtual void EnableOutputProtection(uint32_t desired_protection_mask) = 0;
-
- // Requests the current output protection status. Once the host has the status
- // it will call ContentDecryptionModule::OnQueryOutputProtectionStatus().
- virtual void QueryOutputProtectionStatus() = 0;
-
- // Must be called by the CDM if it returned kDeferredInitialization during
- // InitializeAudioDecoder() or InitializeVideoDecoder().
- virtual void OnDeferredInitializationDone(StreamType stream_type,
- Status decoder_status) = 0;
-
- // Creates a FileIO object from the host to do file IO operation. Returns NULL
- // if a FileIO object cannot be obtained. Once a valid FileIO object is
- // returned, |client| must be valid until FileIO::Close() is called. The
- // CDM can call this method multiple times to operate on different files.
- virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
-
- // Requests a specific version of the storage ID. A storage ID is a stable,
- // device specific ID used by the CDM to securely store persistent data. The
- // ID will be returned by the host via ContentDecryptionModule::OnStorageId().
- // If |version| is 0, the latest version will be returned. All |version|s
- // that are greater than or equal to 0x80000000 are reserved for the CDM and
- // should not be supported or returned by the host. The CDM must not expose
- // the ID outside the client device, even in encrypted form.
- virtual void RequestStorageId(uint32_t version) = 0;
-
- protected:
- Host_9() {}
- virtual ~Host_9() {}
-};
-
-// Represents a decrypted block that has not been decoded.
-class CDM_CLASS_API DecryptedBlock {
- public:
- virtual void SetDecryptedBuffer(Buffer* buffer) = 0;
- virtual Buffer* DecryptedBuffer() = 0;
-
- // TODO(tomfinegan): Figure out if timestamp is really needed. If it is not,
- // we can just pass Buffer pointers around.
- virtual void SetTimestamp(int64_t timestamp) = 0;
- virtual int64_t Timestamp() const = 0;
-
- protected:
- DecryptedBlock() {}
- virtual ~DecryptedBlock() {}
-};
-
-class CDM_CLASS_API VideoFrame {
- public:
- enum VideoPlane {
- kYPlane = 0,
- kUPlane = 1,
- kVPlane = 2,
- kMaxPlanes = 3,
- };
-
- virtual void SetFormat(VideoFormat format) = 0;
- virtual VideoFormat Format() const = 0;
-
- virtual void SetSize(cdm::Size size) = 0;
- virtual cdm::Size Size() const = 0;
-
- virtual void SetFrameBuffer(Buffer* frame_buffer) = 0;
- virtual Buffer* FrameBuffer() = 0;
-
- virtual void SetPlaneOffset(VideoPlane plane, uint32_t offset) = 0;
- virtual uint32_t PlaneOffset(VideoPlane plane) = 0;
-
- virtual void SetStride(VideoPlane plane, uint32_t stride) = 0;
- virtual uint32_t Stride(VideoPlane plane) = 0;
-
- virtual void SetTimestamp(int64_t timestamp) = 0;
- virtual int64_t Timestamp() const = 0;
-
- protected:
- VideoFrame() {}
- virtual ~VideoFrame() {}
-};
-
-// Represents decrypted and decoded audio frames. AudioFrames can contain
-// multiple audio output buffers, which are serialized into this format:
-//
-// |<------------------- serialized audio buffer ------------------->|
-// | int64_t timestamp | int64_t length | length bytes of audio data |
-//
-// For example, with three audio output buffers, the AudioFrames will look
-// like this:
-//
-// |<----------------- AudioFrames ------------------>|
-// | audio buffer 0 | audio buffer 1 | audio buffer 2 |
-class CDM_CLASS_API AudioFrames {
- public:
- virtual void SetFrameBuffer(Buffer* buffer) = 0;
- virtual Buffer* FrameBuffer() = 0;
-
- // The CDM must call this method, providing a valid format, when providing
- // frame buffers. Planar data should be stored end to end; e.g.,
- // |ch1 sample1||ch1 sample2|....|ch1 sample_last||ch2 sample1|...
- virtual void SetFormat(AudioFormat format) = 0;
- virtual AudioFormat Format() const = 0;
-
- protected:
- AudioFrames() {}
- virtual ~AudioFrames() {}
-};
-
-} // namespace cdm
-
-#endif // CDM_CONTENT_DECRYPTION_MODULE_H_
diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module_export.h b/dom/media/gmp/widevine-adapter/content_decryption_module_export.h
deleted file mode 100644
index 51d485892b..0000000000
--- a/dom/media/gmp/widevine-adapter/content_decryption_module_export.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
-#define CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
-
-// Define CDM_API so that functionality implemented by the CDM module
-// can be exported to consumers.
-#if defined(_WIN32)
-
-#if defined(CDM_IMPLEMENTATION)
-#define CDM_API __declspec(dllexport)
-#else
-#define CDM_API __declspec(dllimport)
-#endif // defined(CDM_IMPLEMENTATION)
-
-#else // defined(_WIN32)
-#define CDM_API __attribute__((visibility("default")))
-#endif // defined(_WIN32)
-
-#endif // CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h b/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h
deleted file mode 100644
index 5df8344e60..0000000000
--- a/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
-#define CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
-
-#if defined(_WIN32)
-#include <windows.h>
-#endif
-
-#include "content_decryption_module_export.h"
-
-#if defined(_MSC_VER)
-typedef unsigned int uint32_t;
-#else
-#include <stdint.h>
-#endif
-
-namespace cdm {
-
-#if defined(_WIN32)
-typedef wchar_t FilePathCharType;
-typedef HANDLE PlatformFile;
-const PlatformFile kInvalidPlatformFile = INVALID_HANDLE_VALUE;
-#else
-typedef char FilePathCharType;
-typedef int PlatformFile;
-const PlatformFile kInvalidPlatformFile = -1;
-#endif // defined(_WIN32)
-
-struct HostFile {
- HostFile(const FilePathCharType* file_path,
- PlatformFile file,
- PlatformFile sig_file)
- : file_path(file_path), file(file), sig_file(sig_file) {}
-
- // File that is part of the host of the CDM.
- const FilePathCharType* file_path = nullptr;
- PlatformFile file = kInvalidPlatformFile;
-
- // Signature file for |file|.
- PlatformFile sig_file = kInvalidPlatformFile;
-};
-
-} // namespace cdm
-
-extern "C" {
-
-// Functions in this file are dynamically retrieved by their versioned function
-// names. Increment the version number for any backward incompatible API
-// changes.
-
-// Verifies CDM host. All files in |host_files| are opened in read-only mode.
-//
-// Returns false and closes all files if there is an immediate failure.
-// Otherwise returns true as soon as possible and processes the files
-// asynchronously. All files MUST be closed by the CDM after this one-time
-// processing is finished.
-CDM_API bool VerifyCdmHost_0(const cdm::HostFile* host_files,
- uint32_t num_files);
-}
-
-#endif // CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
diff --git a/dom/media/gmp/widevine-adapter/moz.build b/dom/media/gmp/widevine-adapter/moz.build
deleted file mode 100644
index 4a3a079cec..0000000000
--- a/dom/media/gmp/widevine-adapter/moz.build
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-SOURCES += [
- 'WidevineAdapter.cpp',
- 'WidevineDecryptor.cpp',
- 'WidevineFileIO.cpp',
- 'WidevineUtils.cpp',
- 'WidevineVideoDecoder.cpp',
- 'WidevineVideoFrame.cpp',
-]
-
-FINAL_LIBRARY = 'xul'
-
-LOCAL_INCLUDES += [
- '/dom/media/gmp',
-]
-
-if CONFIG['CLANG_CXX']:
- CXXFLAGS += ['-Wno-error=shadow']
-
-include('/ipc/chromium/chromium-config.mozbuild')
diff --git a/dom/media/gtest/MockMediaDecoderOwner.h b/dom/media/gtest/MockMediaDecoderOwner.h
index 1009ca30a1..64d7290187 100644
--- a/dom/media/gtest/MockMediaDecoderOwner.h
+++ b/dom/media/gtest/MockMediaDecoderOwner.h
@@ -34,10 +34,6 @@ public:
void DownloadProgressed() override {}
void UpdateReadyState() override {}
void FirstFrameLoaded() override {}
-#ifdef MOZ_EME
- void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
- const nsAString& aInitDataType) override {}
-#endif
bool IsActive() const override { return true; }
bool IsHidden() const override { return false; }
void DownloadSuspended() override {}
diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp
index 022bb5bd10..907ee40e8f 100644
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -58,34 +58,6 @@ AppendStateToStr(SourceBufferAttributes::AppendState aState)
static Atomic<uint32_t> sStreamSourceID(0u);
-#ifdef MOZ_EME
-class DispatchKeyNeededEvent : public Runnable {
-public:
- DispatchKeyNeededEvent(AbstractMediaDecoder* aDecoder,
- nsTArray<uint8_t>& aInitData,
- const nsString& aInitDataType)
- : mDecoder(aDecoder)
- , mInitData(aInitData)
- , mInitDataType(aInitDataType)
- {
- }
- NS_IMETHOD Run() override {
- // Note: Null check the owner, as the decoder could have been shutdown
- // since this event was dispatched.
- MediaDecoderOwner* owner = mDecoder->GetOwner();
- if (owner) {
- owner->DispatchEncrypted(mInitData, mInitDataType);
- }
- mDecoder = nullptr;
- return NS_OK;
- }
-private:
- RefPtr<AbstractMediaDecoder> mDecoder;
- nsTArray<uint8_t> mInitData;
- nsString mInitDataType;
-};
-#endif // MOZ_EME
-
TrackBuffersManager::TrackBuffersManager(MediaSourceDecoder* aParentDecoder,
const nsACString& aType)
: mInputBuffer(new MediaByteBuffer)
@@ -1101,14 +1073,6 @@ TrackBuffersManager::OnDemuxerInitDone(nsresult)
UniquePtr<EncryptionInfo> crypto = mInputDemuxer->GetCrypto();
if (crypto && crypto->IsEncrypted()) {
-#ifdef MOZ_EME
- // Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
- for (uint32_t i = 0; i < crypto->mInitDatas.Length(); i++) {
- NS_DispatchToMainThread(
- new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData,
- crypto->mInitDatas[i].mType));
- }
-#endif
info.mCrypto = *crypto;
// We clear our crypto init data array, so the MediaFormatReader will
// not emit an encrypted event for the same init data again.
diff --git a/dom/media/moz.build b/dom/media/moz.build
index ef018d4a75..ca3cdac1ca 100644
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -44,9 +44,6 @@ if CONFIG['MOZ_FMP4']:
if CONFIG['MOZ_WEBRTC']:
DIRS += ['bridge']
-if CONFIG['MOZ_EME']:
- DIRS += ['eme']
-
if CONFIG['MOZ_GMP']:
DIRS += [
'gmp',
diff --git a/dom/media/platforms/PDMFactory.cpp b/dom/media/platforms/PDMFactory.cpp
index 029b88cecb..02cbd3d92b 100644
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -35,11 +35,6 @@
#include "AgnosticDecoderModule.h"
-#ifdef MOZ_EME
-#include "mozilla/CDMProxy.h"
-#include "EMEDecoderModule.h"
-#endif
-
#include "DecoderDoctorDiagnostics.h"
#include "MP4Decoder.h"
@@ -206,11 +201,6 @@ PDMFactory::CreateDecoder(const CreateDecoderParams& aParams)
}
const TrackInfo& config = aParams.mConfig;
- bool isEncrypted = mEMEPDM && config.mCrypto.mValid;
-
- if (isEncrypted) {
- return CreateDecoderWithPDM(mEMEPDM, aParams);
- }
DecoderDoctorDiagnostics* diagnostics = aParams.mDiagnostics;
if (diagnostics) {
@@ -334,9 +324,6 @@ bool
PDMFactory::Supports(const TrackInfo& aTrackInfo,
DecoderDoctorDiagnostics* aDiagnostics) const
{
- if (mEMEPDM) {
- return mEMEPDM->Supports(aTrackInfo, aDiagnostics);
- }
RefPtr<PlatformDecoderModule> current = GetDecoder(aTrackInfo, aDiagnostics);
return !!current;
}
@@ -444,13 +431,4 @@ PDMFactory::GetDecoder(const TrackInfo& aTrackInfo,
return pdm.forget();
}
-#ifdef MOZ_EME
-void
-PDMFactory::SetCDMProxy(CDMProxy* aProxy)
-{
- RefPtr<PDMFactory> m = new PDMFactory();
- mEMEPDM = new EMEDecoderModule(aProxy, m);
-}
-#endif
-
} // namespace mozilla
diff --git a/dom/media/platforms/PDMFactory.h b/dom/media/platforms/PDMFactory.h
index 186c05ca4e..313633ab57 100644
--- a/dom/media/platforms/PDMFactory.h
+++ b/dom/media/platforms/PDMFactory.h
@@ -10,10 +10,6 @@
#include "mozilla/Function.h"
#include "mozilla/StaticMutex.h"
-#ifdef MOZ_EME
-class CDMProxy;
-#endif
-
namespace mozilla {
class DecoderDoctorDiagnostics;
@@ -39,15 +35,6 @@ public:
bool Supports(const TrackInfo& aTrackInfo,
DecoderDoctorDiagnostics* aDiagnostics) const;
-#ifdef MOZ_EME
- // Creates a PlatformDecoderModule that uses a CDMProxy to decrypt or
- // decrypt-and-decode EME encrypted content. If the CDM only decrypts and
- // does not decode, we create a PDM and use that to create MediaDataDecoders
- // that we use on on aTaskQueue to decode the decrypted stream.
- // This is called on the decode task queue.
- void SetCDMProxy(CDMProxy* aProxy);
-#endif
-
static const int kYUV400 = 0;
static const int kYUV420 = 1;
static const int kYUV422 = 2;
@@ -69,7 +56,6 @@ private:
const CreateDecoderParams& aParams);
nsTArray<RefPtr<PlatformDecoderModule>> mCurrentPDMs;
- RefPtr<PlatformDecoderModule> mEMEPDM;
RefPtr<PlatformDecoderModule> mBlankPDM;
bool mWMFFailedToLoad = false;
diff --git a/dom/media/platforms/PlatformDecoderModule.h b/dom/media/platforms/PlatformDecoderModule.h
index f2abe4b7f7..63b4e00d5c 100644
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -39,9 +39,6 @@ class RemoteDecoderModule;
class MediaDataDecoder;
class MediaDataDecoderCallback;
class TaskQueue;
-#ifdef MOZ_EME
-class CDMProxy;
-#endif
static LazyLogModule sPDMLog("PlatformDecoderModule");
diff --git a/dom/media/platforms/agnostic/eme/EMEAudioDecoder.cpp b/dom/media/platforms/agnostic/eme/EMEAudioDecoder.cpp
deleted file mode 100644
index fd0449d66f..0000000000
--- a/dom/media/platforms/agnostic/eme/EMEAudioDecoder.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "EMEAudioDecoder.h"
-#include "mozilla/CDMProxy.h"
-
-namespace mozilla {
-
-void
-EMEAudioCallbackAdapter::Error(GMPErr aErr)
-{
- if (aErr == GMPNoKeyErr) {
- // The GMP failed to decrypt a frame due to not having a key. This can
- // happen if a key expires or a session is closed during playback.
- NS_WARNING("GMP failed to decrypt due to lack of key");
- return;
- }
- AudioCallbackAdapter::Error(aErr);
-}
-
-EMEAudioDecoder::EMEAudioDecoder(CDMProxy* aProxy,
- const GMPAudioDecoderParams& aParams)
- : GMPAudioDecoder(GMPAudioDecoderParams(aParams).WithAdapter(
- new EMEAudioCallbackAdapter(aParams.mCallback)))
- , mProxy(aProxy)
-{}
-
-void
-EMEAudioDecoder::InitTags(nsTArray<nsCString>& aTags)
-{
- aTags.AppendElement(NS_LITERAL_CSTRING("aac"));
- aTags.AppendElement(NS_ConvertUTF16toUTF8(mProxy->KeySystem()));
-}
-
-nsCString
-EMEAudioDecoder::GetNodeId()
-{
- return mProxy->GetNodeId();
-}
-
-} // namespace mozilla
diff --git a/dom/media/platforms/agnostic/eme/EMEAudioDecoder.h b/dom/media/platforms/agnostic/eme/EMEAudioDecoder.h
deleted file mode 100644
index fd41125d87..0000000000
--- a/dom/media/platforms/agnostic/eme/EMEAudioDecoder.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef EMEAudioDecoder_h_
-#define EMEAudioDecoder_h_
-
-#include "GMPAudioDecoder.h"
-#include "PlatformDecoderModule.h"
-
-namespace mozilla {
-
-class EMEAudioCallbackAdapter : public AudioCallbackAdapter {
-public:
- explicit EMEAudioCallbackAdapter(MediaDataDecoderCallbackProxy* aCallback)
- : AudioCallbackAdapter(aCallback)
- {}
-
- void Error(GMPErr aErr) override;
-};
-
-class EMEAudioDecoder : public GMPAudioDecoder {
-public:
- EMEAudioDecoder(CDMProxy* aProxy, const GMPAudioDecoderParams& aParams);
-
-private:
- void InitTags(nsTArray<nsCString>& aTags) override;
- nsCString GetNodeId() override;
-
- RefPtr<CDMProxy> mProxy;
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
deleted file mode 100644
index a293824608..0000000000
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "EMEDecoderModule.h"
-#include "EMEAudioDecoder.h"
-#include "EMEVideoDecoder.h"
-#include "MediaDataDecoderProxy.h"
-#include "mozIGeckoMediaPluginService.h"
-#include "mozilla/CDMProxy.h"
-#include "mozilla/Unused.h"
-#include "nsAutoPtr.h"
-#include "nsServiceManagerUtils.h"
-#include "MediaInfo.h"
-#include "nsClassHashtable.h"
-#include "GMPDecoderModule.h"
-#include "MP4Decoder.h"
-
-namespace mozilla {
-
-typedef MozPromiseRequestHolder<CDMProxy::DecryptPromise> DecryptPromiseRequestHolder;
-
-class EMEDecryptor : public MediaDataDecoder {
-
-public:
-
- EMEDecryptor(MediaDataDecoder* aDecoder,
- MediaDataDecoderCallback* aCallback,
- CDMProxy* aProxy,
- TaskQueue* aDecodeTaskQueue)
- : mDecoder(aDecoder)
- , mCallback(aCallback)
- , mTaskQueue(aDecodeTaskQueue)
- , mProxy(aProxy)
- , mSamplesWaitingForKey(new SamplesWaitingForKey(this, this->mCallback,
- mTaskQueue, mProxy))
- , mIsShutdown(false)
- {
- }
-
- RefPtr<InitPromise> Init() override {
- MOZ_ASSERT(!mIsShutdown);
- return mDecoder->Init();
- }
-
- void Input(MediaRawData* aSample) override {
- MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
- if (mIsShutdown) {
- NS_WARNING("EME encrypted sample arrived after shutdown");
- return;
- }
- if (mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)) {
- return;
- }
-
- nsAutoPtr<MediaRawDataWriter> writer(aSample->CreateWriter());
- mProxy->GetSessionIdsForKeyId(aSample->mCrypto.mKeyId,
- writer->mCrypto.mSessionIds);
-
- mDecrypts.Put(aSample, new DecryptPromiseRequestHolder());
- mDecrypts.Get(aSample)->Begin(mProxy->Decrypt(aSample)->Then(
- mTaskQueue, __func__, this,
- &EMEDecryptor::Decrypted,
- &EMEDecryptor::Decrypted));
- return;
- }
-
- void Decrypted(const DecryptResult& aDecrypted) {
- MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
- MOZ_ASSERT(aDecrypted.mSample);
-
- nsAutoPtr<DecryptPromiseRequestHolder> holder;
- mDecrypts.RemoveAndForget(aDecrypted.mSample, holder);
- if (holder) {
- holder->Complete();
- } else {
- // Decryption is not in the list of decrypt operations waiting
- // for a result. It must have been flushed or drained. Ignore result.
- return;
- }
-
- if (mIsShutdown) {
- NS_WARNING("EME decrypted sample arrived after shutdown");
- return;
- }
-
- if (aDecrypted.mStatus == NoKeyErr) {
- // Key became unusable after we sent the sample to CDM to decrypt.
- // Call Input() again, so that the sample is enqueued for decryption
- // if the key becomes usable again.
- Input(aDecrypted.mSample);
- } else if (aDecrypted.mStatus != Ok) {
- if (mCallback) {
- mCallback->Error(MediaResult(
- NS_ERROR_DOM_MEDIA_FATAL_ERR,
- RESULT_DETAIL("decrypted.mStatus=%u", uint32_t(aDecrypted.mStatus))));
- }
- } else {
- MOZ_ASSERT(!mIsShutdown);
- // The Adobe GMP AAC decoder gets confused if we pass it non-encrypted
- // samples with valid crypto data. So clear the crypto data, since the
- // sample should be decrypted now anyway. If we don't do this and we're
- // using the Adobe GMP for unencrypted decoding of data that is decrypted
- // by gmp-clearkey, decoding will fail.
- UniquePtr<MediaRawDataWriter> writer(aDecrypted.mSample->CreateWriter());
- writer->mCrypto = CryptoSample();
- mDecoder->Input(aDecrypted.mSample);
- }
- }
-
- void Flush() override {
- MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
- MOZ_ASSERT(!mIsShutdown);
- for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) {
- nsAutoPtr<DecryptPromiseRequestHolder>& holder = iter.Data();
- holder->DisconnectIfExists();
- iter.Remove();
- }
- mDecoder->Flush();
- mSamplesWaitingForKey->Flush();
- }
-
- void Drain() override {
- MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
- MOZ_ASSERT(!mIsShutdown);
- for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) {
- nsAutoPtr<DecryptPromiseRequestHolder>& holder = iter.Data();
- holder->DisconnectIfExists();
- iter.Remove();
- }
- mDecoder->Drain();
- }
-
- void Shutdown() override {
- MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
- MOZ_ASSERT(!mIsShutdown);
- mIsShutdown = true;
- mDecoder->Shutdown();
- mSamplesWaitingForKey->BreakCycles();
- mSamplesWaitingForKey = nullptr;
- mDecoder = nullptr;
- mProxy = nullptr;
- mCallback = nullptr;
- }
-
- const char* GetDescriptionName() const override {
- return mDecoder->GetDescriptionName();
- }
-
-private:
-
- RefPtr<MediaDataDecoder> mDecoder;
- MediaDataDecoderCallback* mCallback;
- RefPtr<TaskQueue> mTaskQueue;
- RefPtr<CDMProxy> mProxy;
- nsClassHashtable<nsRefPtrHashKey<MediaRawData>, DecryptPromiseRequestHolder> mDecrypts;
- RefPtr<SamplesWaitingForKey> mSamplesWaitingForKey;
- bool mIsShutdown;
-};
-
-class EMEMediaDataDecoderProxy : public MediaDataDecoderProxy {
-public:
- EMEMediaDataDecoderProxy(already_AddRefed<AbstractThread> aProxyThread,
- MediaDataDecoderCallback* aCallback,
- CDMProxy* aProxy,
- TaskQueue* aTaskQueue)
- : MediaDataDecoderProxy(Move(aProxyThread), aCallback)
- , mSamplesWaitingForKey(new SamplesWaitingForKey(this, aCallback,
- aTaskQueue, aProxy))
- , mProxy(aProxy)
- {
- }
-
- void Input(MediaRawData* aSample) override;
- void Shutdown() override;
-
-private:
- RefPtr<SamplesWaitingForKey> mSamplesWaitingForKey;
- RefPtr<CDMProxy> mProxy;
-};
-
-void
-EMEMediaDataDecoderProxy::Input(MediaRawData* aSample)
-{
- if (mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)) {
- return;
- }
-
- nsAutoPtr<MediaRawDataWriter> writer(aSample->CreateWriter());
- mProxy->GetSessionIdsForKeyId(aSample->mCrypto.mKeyId,
- writer->mCrypto.mSessionIds);
-
- MediaDataDecoderProxy::Input(aSample);
-}
-
-void
-EMEMediaDataDecoderProxy::Shutdown()
-{
- MediaDataDecoderProxy::Shutdown();
-
- mSamplesWaitingForKey->BreakCycles();
- mSamplesWaitingForKey = nullptr;
- mProxy = nullptr;
-}
-
-EMEDecoderModule::EMEDecoderModule(CDMProxy* aProxy, PDMFactory* aPDM)
- : mProxy(aProxy)
- , mPDM(aPDM)
-{
-}
-
-EMEDecoderModule::~EMEDecoderModule()
-{
-}
-
-static already_AddRefed<MediaDataDecoderProxy>
-CreateDecoderWrapper(MediaDataDecoderCallback* aCallback, CDMProxy* aProxy, TaskQueue* aTaskQueue)
-{
- RefPtr<gmp::GeckoMediaPluginService> s(gmp::GeckoMediaPluginService::GetGeckoMediaPluginService());
- if (!s) {
- return nullptr;
- }
- RefPtr<AbstractThread> thread(s->GetAbstractGMPThread());
- if (!thread) {
- return nullptr;
- }
- RefPtr<MediaDataDecoderProxy> decoder(
- new EMEMediaDataDecoderProxy(thread.forget(), aCallback, aProxy, aTaskQueue));
- return decoder.forget();
-}
-
-already_AddRefed<MediaDataDecoder>
-EMEDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
-{
- MOZ_ASSERT(aParams.mConfig.mCrypto.mValid);
-
- if (SupportsMimeType(aParams.mConfig.mMimeType, nullptr)) {
- // GMP decodes. Assume that means it can decrypt too.
- RefPtr<MediaDataDecoderProxy> wrapper =
- CreateDecoderWrapper(aParams.mCallback, mProxy, aParams.mTaskQueue);
- auto params = GMPVideoDecoderParams(aParams).WithCallback(wrapper);
- wrapper->SetProxyTarget(new EMEVideoDecoder(mProxy, params));
- return wrapper.forget();
- }
-
- MOZ_ASSERT(mPDM);
- RefPtr<MediaDataDecoder> decoder(mPDM->CreateDecoder(aParams));
- if (!decoder) {
- return nullptr;
- }
-
- RefPtr<MediaDataDecoder> emeDecoder(new EMEDecryptor(decoder,
- aParams.mCallback,
- mProxy,
- AbstractThread::GetCurrent()->AsTaskQueue()));
- return emeDecoder.forget();
-}
-
-already_AddRefed<MediaDataDecoder>
-EMEDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
-{
- MOZ_ASSERT(aParams.mConfig.mCrypto.mValid);
-
- if (SupportsMimeType(aParams.mConfig.mMimeType, nullptr)) {
- // GMP decodes. Assume that means it can decrypt too.
- RefPtr<MediaDataDecoderProxy> wrapper =
- CreateDecoderWrapper(aParams.mCallback, mProxy, aParams.mTaskQueue);
- auto gmpParams = GMPAudioDecoderParams(aParams).WithCallback(wrapper);
- wrapper->SetProxyTarget(new EMEAudioDecoder(mProxy, gmpParams));
- return wrapper.forget();
- }
-
- MOZ_ASSERT(mPDM);
- RefPtr<MediaDataDecoder> decoder(mPDM->CreateDecoder(aParams));
- if (!decoder) {
- return nullptr;
- }
-
- RefPtr<MediaDataDecoder> emeDecoder(new EMEDecryptor(decoder,
- aParams.mCallback,
- mProxy,
- AbstractThread::GetCurrent()->AsTaskQueue()));
- return emeDecoder.forget();
-}
-
-PlatformDecoderModule::ConversionRequired
-EMEDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
-{
- if (aConfig.IsVideo() && MP4Decoder::IsH264(aConfig.mMimeType)) {
- return ConversionRequired::kNeedAVCC;
- } else {
- return ConversionRequired::kNeedNone;
- }
-}
-
-bool
-EMEDecoderModule::SupportsMimeType(const nsACString& aMimeType,
- DecoderDoctorDiagnostics* aDiagnostics) const
-{
- Maybe<nsCString> gmp;
- gmp.emplace(NS_ConvertUTF16toUTF8(mProxy->KeySystem()));
- return GMPDecoderModule::SupportsMimeType(aMimeType, gmp);
-}
-
-} // namespace mozilla
diff --git a/dom/media/platforms/agnostic/eme/EMEDecoderModule.h b/dom/media/platforms/agnostic/eme/EMEDecoderModule.h
deleted file mode 100644
index 8480e54536..0000000000
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(EMEDecoderModule_h_)
-#define EMEDecoderModule_h_
-
-#include "PlatformDecoderModule.h"
-#include "PDMFactory.h"
-#include "gmp-decryption.h"
-
-namespace mozilla {
-
-class CDMProxy;
-
-class EMEDecoderModule : public PlatformDecoderModule {
-private:
-
-public:
- EMEDecoderModule(CDMProxy* aProxy, PDMFactory* aPDM);
-
- virtual ~EMEDecoderModule();
-
-protected:
- // Decode thread.
- already_AddRefed<MediaDataDecoder>
- CreateVideoDecoder(const CreateDecoderParams& aParams) override;
-
- // Decode thread.
- already_AddRefed<MediaDataDecoder>
- CreateAudioDecoder(const CreateDecoderParams& aParams) override;
-
- ConversionRequired
- DecoderNeedsConversion(const TrackInfo& aConfig) const override;
-
- bool
- SupportsMimeType(const nsACString& aMimeType,
- DecoderDoctorDiagnostics* aDiagnostics) const override;
-
-private:
- RefPtr<CDMProxy> mProxy;
- // Will be null if CDM has decoding capability.
- RefPtr<PDMFactory> mPDM;
- // We run the PDM on its own task queue.
- RefPtr<TaskQueue> mTaskQueue;
-};
-
-} // namespace mozilla
-
-#endif // EMEDecoderModule_h_
diff --git a/dom/media/platforms/agnostic/eme/EMEVideoDecoder.cpp b/dom/media/platforms/agnostic/eme/EMEVideoDecoder.cpp
deleted file mode 100644
index d7b4b1c250..0000000000
--- a/dom/media/platforms/agnostic/eme/EMEVideoDecoder.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "EMEVideoDecoder.h"
-#include "GMPVideoEncodedFrameImpl.h"
-#include "mozilla/CDMProxy.h"
-#include "MediaData.h"
-#include "MP4Decoder.h"
-#include "VPXDecoder.h"
-
-namespace mozilla {
-
-void
-EMEVideoCallbackAdapter::Error(GMPErr aErr)
-{
- if (aErr == GMPNoKeyErr) {
- // The GMP failed to decrypt a frame due to not having a key. This can
- // happen if a key expires or a session is closed during playback.
- NS_WARNING("GMP failed to decrypt due to lack of key");
- return;
- }
- VideoCallbackAdapter::Error(aErr);
-}
-
-EMEVideoDecoder::EMEVideoDecoder(CDMProxy* aProxy,
- const GMPVideoDecoderParams& aParams)
- : GMPVideoDecoder(GMPVideoDecoderParams(aParams).WithAdapter(
- new EMEVideoCallbackAdapter(aParams.mCallback,
- VideoInfo(aParams.mConfig.mDisplay),
- aParams.mImageContainer)))
- , mProxy(aProxy)
- , mDecryptorId(aProxy->GetDecryptorId())
-{}
-
-void
-EMEVideoDecoder::InitTags(nsTArray<nsCString>& aTags)
-{
- VideoInfo config = GetConfig();
- if (MP4Decoder::IsH264(config.mMimeType)) {
- aTags.AppendElement(NS_LITERAL_CSTRING("h264"));
- } else if (VPXDecoder::IsVP8(config.mMimeType)) {
- aTags.AppendElement(NS_LITERAL_CSTRING("vp8"));
- } else if (VPXDecoder::IsVP9(config.mMimeType)) {
- aTags.AppendElement(NS_LITERAL_CSTRING("vp9"));
- }
- aTags.AppendElement(NS_ConvertUTF16toUTF8(mProxy->KeySystem()));
-}
-
-nsCString
-EMEVideoDecoder::GetNodeId()
-{
- return mProxy->GetNodeId();
-}
-
-GMPUniquePtr<GMPVideoEncodedFrame>
-EMEVideoDecoder::CreateFrame(MediaRawData* aSample)
-{
- GMPUniquePtr<GMPVideoEncodedFrame> frame = GMPVideoDecoder::CreateFrame(aSample);
- if (frame && aSample->mCrypto.mValid) {
- static_cast<gmp::GMPVideoEncodedFrameImpl*>(frame.get())->InitCrypto(aSample->mCrypto);
- }
- return frame;
-}
-
-} // namespace mozilla
diff --git a/dom/media/platforms/agnostic/eme/EMEVideoDecoder.h b/dom/media/platforms/agnostic/eme/EMEVideoDecoder.h
deleted file mode 100644
index e3b63b5066..0000000000
--- a/dom/media/platforms/agnostic/eme/EMEVideoDecoder.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef EMEVideoDecoder_h_
-#define EMEVideoDecoder_h_
-
-#include "GMPVideoDecoder.h"
-#include "PlatformDecoderModule.h"
-
-namespace mozilla {
-
-class CDMProxy;
-class TaskQueue;
-
-class EMEVideoCallbackAdapter : public VideoCallbackAdapter {
-public:
- EMEVideoCallbackAdapter(MediaDataDecoderCallbackProxy* aCallback,
- VideoInfo aVideoInfo,
- layers::ImageContainer* aImageContainer)
- : VideoCallbackAdapter(aCallback, aVideoInfo, aImageContainer)
- {}
-
- void Error(GMPErr aErr) override;
-};
-
-class EMEVideoDecoder : public GMPVideoDecoder {
-public:
- EMEVideoDecoder(CDMProxy* aProxy, const GMPVideoDecoderParams& aParams);
-
-private:
- void InitTags(nsTArray<nsCString>& aTags) override;
- nsCString GetNodeId() override;
- uint32_t DecryptorId() const override { return mDecryptorId; }
- GMPUniquePtr<GMPVideoEncodedFrame> CreateFrame(MediaRawData* aSample) override;
-
- RefPtr<CDMProxy> mProxy;
- uint32_t mDecryptorId;
-};
-
-} // namespace mozilla
-
-#endif // EMEVideoDecoder_h_
diff --git a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp b/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
deleted file mode 100644
index 532fc63c01..0000000000
--- a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SamplesWaitingForKey.h"
-#include "mozilla/CDMProxy.h"
-#include "mozilla/CDMCaps.h"
-#include "MediaData.h"
-
-namespace mozilla {
-
-SamplesWaitingForKey::SamplesWaitingForKey(MediaDataDecoder* aDecoder,
- MediaDataDecoderCallback* aCallback,
- TaskQueue* aTaskQueue,
- CDMProxy* aProxy)
- : mMutex("SamplesWaitingForKey")
- , mDecoder(aDecoder)
- , mDecoderCallback(aCallback)
- , mTaskQueue(aTaskQueue)
- , mProxy(aProxy)
-{
-}
-
-SamplesWaitingForKey::~SamplesWaitingForKey()
-{
-}
-
-bool
-SamplesWaitingForKey::WaitIfKeyNotUsable(MediaRawData* aSample)
-{
- if (!aSample || !aSample->mCrypto.mValid || !mProxy) {
- return false;
- }
- CDMCaps::AutoLock caps(mProxy->Capabilites());
- const auto& keyid = aSample->mCrypto.mKeyId;
- if (!caps.IsKeyUsable(keyid)) {
- {
- MutexAutoLock lock(mMutex);
- mSamples.AppendElement(aSample);
- }
- mDecoderCallback->WaitingForKey();
- caps.NotifyWhenKeyIdUsable(aSample->mCrypto.mKeyId, this);
- return true;
- }
- return false;
-}
-
-void
-SamplesWaitingForKey::NotifyUsable(const CencKeyId& aKeyId)
-{
- MutexAutoLock lock(mMutex);
- size_t i = 0;
- while (i < mSamples.Length()) {
- if (aKeyId == mSamples[i]->mCrypto.mKeyId) {
- RefPtr<nsIRunnable> task;
- task = NewRunnableMethod<RefPtr<MediaRawData>>(mDecoder,
- &MediaDataDecoder::Input,
- RefPtr<MediaRawData>(mSamples[i]));
- mSamples.RemoveElementAt(i);
- mTaskQueue->Dispatch(task.forget());
- } else {
- i++;
- }
- }
-}
-
-void
-SamplesWaitingForKey::Flush()
-{
- MutexAutoLock lock(mMutex);
- mSamples.Clear();
-}
-
-void
-SamplesWaitingForKey::BreakCycles()
-{
- MutexAutoLock lock(mMutex);
- mDecoder = nullptr;
- mTaskQueue = nullptr;
- mProxy = nullptr;
- mSamples.Clear();
-}
-
-} // namespace mozilla
diff --git a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h b/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h
deleted file mode 100644
index 8672bccdd1..0000000000
--- a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef SamplesWaitingForKey_h_
-#define SamplesWaitingForKey_h_
-
-#include "mozilla/TaskQueue.h"
-
-#include "PlatformDecoderModule.h"
-
-namespace mozilla {
-
-typedef nsTArray<uint8_t> CencKeyId;
-
-class CDMProxy;
-
-// Encapsulates the task of waiting for the CDMProxy to have the necessary
-// keys to decrypt a given sample.
-class SamplesWaitingForKey {
-public:
-
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SamplesWaitingForKey)
-
- explicit SamplesWaitingForKey(MediaDataDecoder* aDecoder,
- MediaDataDecoderCallback* aCallback,
- TaskQueue* aTaskQueue,
- CDMProxy* aProxy);
-
- // Returns true if we need to wait for a key to become usable.
- // Will callback MediaDataDecoder::Input(aSample) on mDecoder once the
- // sample is ready to be decrypted. The order of input samples is
- // preserved.
- bool WaitIfKeyNotUsable(MediaRawData* aSample);
-
- void NotifyUsable(const CencKeyId& aKeyId);
-
- void Flush();
-
- void BreakCycles();
-
-protected:
- ~SamplesWaitingForKey();
-
-private:
- Mutex mMutex;
- RefPtr<MediaDataDecoder> mDecoder;
- MediaDataDecoderCallback* mDecoderCallback;
- RefPtr<TaskQueue> mTaskQueue;
- RefPtr<CDMProxy> mProxy;
- nsTArray<RefPtr<MediaRawData>> mSamples;
-};
-
-} // namespace mozilla
-
-#endif // SamplesWaitingForKey_h_
diff --git a/dom/media/platforms/agnostic/eme/moz.build b/dom/media/platforms/agnostic/eme/moz.build
deleted file mode 100644
index 74260b3ba2..0000000000
--- a/dom/media/platforms/agnostic/eme/moz.build
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
- 'EMEAudioDecoder.h',
- 'EMEDecoderModule.h',
- 'EMEVideoDecoder.h',
- 'SamplesWaitingForKey.h',
-]
-
-UNIFIED_SOURCES += [
- 'EMEAudioDecoder.cpp',
- 'EMEDecoderModule.cpp',
- 'EMEVideoDecoder.cpp',
- 'SamplesWaitingForKey.cpp',
-]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
diff --git a/dom/media/platforms/moz.build b/dom/media/platforms/moz.build
index 09d9afa4d2..d4dc579b19 100644
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -32,9 +32,6 @@ DIRS += [
'omx'
]
-if CONFIG['MOZ_EME']:
- DIRS += ['agnostic/eme']
-
if CONFIG['MOZ_GMP']:
DIRS += ['agnostic/gmp']
diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini
index 516c2beb03..2699c03ac2 100644
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -425,9 +425,6 @@ support-files =
dirac.ogg^headers^
dynamic_redirect.sjs
dynamic_resource.sjs
-#ifdef MOZ_EME
- eme.js
-#endif
file_access_controls.html
flac-s24.flac
flac-s24.flac^headers^
@@ -684,38 +681,6 @@ tags=capturestream
[test_decoder_disable.html]
[test_defaultMuted.html]
[test_delay_load.html]
-#ifdef MOZ_EME
-[test_eme_session_callable_value.html]
-[test_eme_canvas_blocked.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_detach_media_keys.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_initDataTypes.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_missing_pssh.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_non_mse_fails.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_request_notifications.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_playback.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_requestKeySystemAccess.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_setMediaKeys_before_attach_MediaSource.html]
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_stream_capture_blocked_case1.html]
-tags=msg capturestream
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_stream_capture_blocked_case2.html]
-tags=msg capturestream
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_stream_capture_blocked_case3.html]
-tags=msg capturestream
-skip-if = toolkit == 'android' # bug 1149374
-[test_eme_waitingforkey.html]
-skip-if = toolkit == 'android' # bug 1149374
-#endif
[test_empty_resource.html]
[test_error_in_video_document.html]
[test_error_on_404.html]
diff --git a/dom/media/test/test_eme_canvas_blocked.html b/dom/media/test/test_eme_canvas_blocked.html
deleted file mode 100644
index e84b6db402..0000000000
--- a/dom/media/test/test_eme_canvas_blocked.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-var manager = new MediaTestManager;
-
-function startTest(test, token)
-{
- manager.started(token);
-
- var sessions = [];
-
- var v = SetupEME(test, token);
- v.preload = "auto"; // Required due to "canplay" not firing for MSE unless we do this.
-
- v.addEventListener("loadeddata", function(ev) {
- var video = ev.target;
- var canvas = document.createElement("canvas");
- canvas.width = video.videoWidth;
- canvas.height = video.videoHeight;
- document.body.appendChild(canvas);
- var ctx = canvas.getContext("2d");
- var threwError = false;
- try {
- ctx.drawImage(video, 0, 0);
- } catch (ex) {
- threwError = true;
- }
- ok(threwError, TimeStamp(token) + " - Should throw an error when trying to draw EME video to canvas.");
- manager.finished(token);
- });
-
- LoadTestWithManagedLoadToken(test, v, manager, token,
- { onlyLoadFirstFragments:2, noEndOfStream:false });
-}
-
-function beginTest() {
- manager.runTests(gEMETests, startTest);
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_detach_media_keys.html b/dom/media/test/test_eme_detach_media_keys.html
deleted file mode 100644
index 6d3dc8467e..0000000000
--- a/dom/media/test/test_eme_detach_media_keys.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<video id="v" controls></video>
-<script class="testbody" type="text/javascript">
-
-SimpleTest.waitForExplicitFinish();
-
-function createAndSet() {
- return new Promise(function(resolve, reject) {
- var m;
- navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, gCencMediaKeySystemConfig)
- .then(function (access) {
- return access.createMediaKeys();
- })
- .then(function (mediaKeys) {
- m = mediaKeys;
- return document.getElementById("v").setMediaKeys(mediaKeys);
- })
- .then(function() {
- resolve(m);
- });
- }
-)}
-
-var m1,m2;
-
-// Test that if we create and set two MediaKeys on one video element,
-// that if the first MediaKeys we set on the media elemnt is still usable
-// after the second MediaKeys has been set on the media element.
-SetupEMEPref(() => {
- createAndSet().then((m) => {
- m1 = m; // Stash MediaKeys.
- return createAndSet();
- })
- .then((m) => {
- m2 = m;
- is(document.getElementById("v").mediaKeys, m2, "Should have set MediaKeys on media element");
- ok(document.getElementById("v").mediaKeys != m1, "First MediaKeys should no longer be set on media element");
- var s = m1.createSession("temporary");
- return s.generateRequest("webm", StringToArrayBuffer(atob('YAYeAX5Hfod+V9ANHtANHg==')));
- })
- .then(() => {
- ok(true, "Was able to generateRequest using second CDM");
- SimpleTest.finish();
- }, () => {
- ok(false, "Was *NOT* able to generateRequest using second CDM");
- SimpleTest.finish();
- });
-});
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_initDataTypes.html b/dom/media/test/test_eme_initDataTypes.html
deleted file mode 100644
index 4821c3cb82..0000000000
--- a/dom/media/test/test_eme_initDataTypes.html
+++ /dev/null
@@ -1,133 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-var tests = [
- {
- name: "One keyId",
- initDataType: 'keyids',
- initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"]}',
- expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"],"type":"temporary"}',
- sessionType: 'temporary',
- expectPass: true,
- },
- {
- name: "Two keyIds",
- initDataType: 'keyids',
- initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}',
- expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"temporary"}',
- sessionType: 'temporary',
- expectPass: true,
- },
- {
- name: "Two keyIds, temporary session",
- initDataType: 'keyids',
- initData: '{"type":"temporary", "kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}',
- expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"temporary"}',
- sessionType: 'temporary',
- expectPass: true,
- },
- {
- name: "Two keyIds, persistent session, type before kids",
- initDataType: 'keyids',
- initData: '{"type":"persistent-license", "kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}',
- expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"persistent-license"}',
- sessionType: 'persistent-license',
- expectPass: false,
- },
- {
- name: "Invalid keyId",
- initDataType: 'keyids',
- initData: '{"kids":["0"]}',
- sessionType: 'temporary',
- expectPass: false,
- },
- {
- name: "Empty keyId",
- initDataType: 'keyids',
- initData: '{"kids":[""]}',
- sessionType: 'temporary',
- expectPass: false,
- },
- {
- name: "Invalid initData",
- initDataType: 'keyids',
- initData: 'invalid initData',
- sessionType: 'temporary',
- expectPass: false,
- },
- {
- name: "'webm' initDataType",
- initDataType: 'webm',
- initData: 'YAYeAX5Hfod+V9ANHtANHg==',
- expectedRequest: '{"kids":["YAYeAX5Hfod-V9ANHtANHg"],"type":"temporary"}',
- sessionType: 'temporary',
- expectPass: true,
- },
- {
- name: "'webm' initDataType with non 16 byte keyid",
- initDataType: 'webm',
- initData: 'YAYeAX5Hfod',
- expectedRequest: '{\"kids\":[\"YAYeAX5Hfoc\"],\"type\":\"temporary\"}',
- sessionType: 'temporary',
- expectPass: true,
- },
-];
-
-function PrepareInitData(initDataType, initData)
-{
- if (initDataType == "keyids") {
- return new TextEncoder().encode(initData);
- } else if (initDataType == "webm") {
- return StringToArrayBuffer(atob(initData));
- }
-}
-
-function Test(test) {
- return new Promise(function(resolve, reject) {
- var configs = [{
- initDataTypes: [test.initDataType],
- videoCapabilities: [{contentType: 'video/mp4' }],
- }];
- navigator.requestMediaKeySystemAccess('org.w3.clearkey', configs)
- .then((access) => access.createMediaKeys())
- .then((mediaKeys) => {
- var session = mediaKeys.createSession(test.sessionType);
- session.addEventListener("message", function(event) {
- is(event.messageType, "license-request", "'" + test.name + "' MediaKeyMessage type should be license-request.");
- var text = new TextDecoder().decode(event.message);
- is(text, test.expectedRequest, "'" + test.name + "' got expected response.");
- is(text == test.expectedRequest, test.expectPass,
- "'" + test.name + "' expected to " + (test.expectPass ? "pass" : "fail"));
- resolve();
- });
- var initData = PrepareInitData(test.initDataType, test.initData);
- return session.generateRequest(test.initDataType, initData);
- }
- ).catch((x) => {
- ok(!test.expectPass, "'" + test.name + "' expected to fail.");
- resolve();
- });
- });
-}
-
-function beginTest() {
- Promise.all(tests.map(Test)).then(function() { SimpleTest.finish(); });
-}
-
-SimpleTest.waitForExplicitFinish();
-SetupEMEPref(beginTest);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_missing_pssh.html b/dom/media/test/test_eme_missing_pssh.html
deleted file mode 100644
index 196ced4022..0000000000
--- a/dom/media/test/test_eme_missing_pssh.html
+++ /dev/null
@@ -1,92 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
- </head>
- <body>
- <audio controls id="audio"></audio>
- <pre id="test">
- <script class="testbody" type="text/javascript">
-
- // Tests that a fragmented MP4 file without a PSSH, but with valid encrypted
- // tracks with valid TENC boxes, is able to load with EME.
- // We setup MSE before starting up EME, so that we exercise the "waiting for
- // cdm" step in the MediaDecoderStateMachine.
-
- SimpleTest.waitForExplicitFinish();
-
- var pssh = [
- 0x00, 0x00, 0x00, 0x00,
- 0x70, 0x73, 0x73, 0x68, // BMFF box header (76 bytes, 'pssh')
- 0x01, 0x00, 0x00, 0x00, // Full box header (version = 1, flags = 0)
- 0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // SystemID
- 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
- 0x00, 0x00, 0x00, 0x01, // KID_count (1)
- 0x2f, 0xef, 0x8a, 0xd8, 0x12, 0xdf, 0x42, 0x97,
- 0x83, 0xe9, 0xbf, 0x6e, 0x5e, 0x49, 0x3e, 0x53,
- 0x00, 0x00, 0x00, 0x00 // Size of Data (0)
- ];
-
- var audio = document.getElementById("audio");
-
- function LoadEME() {
- var options = [{
- initDataType: 'cenc',
- audioType: 'audio/mp4; codecs="mp4a.40.2"',
- }];
- navigator.requestMediaKeySystemAccess("org.w3.clearkey", options)
- .then((keySystemAccess) => {
- return keySystemAccess.createMediaKeys();
- }, bail("Failed to request key system access."))
-
- .then((mediaKeys) => {
- audio.setMediaKeys(mediaKeys);
- var session = mediaKeys.createSession();
- once(session, "message", (message) => {
- is(message.messageType, 'license-request', "Expected a license-request");
- var license = new TextEncoder().encode(JSON.stringify({
- 'keys': [{
- 'kty':'oct',
- 'kid':'L--K2BLfQpeD6b9uXkk-Uw',
- 'k':HexToBase64('7f412f0575f44f718259beef56ec7771')
- }],
- 'type': 'temporary'
- }));
- session.update(license);
- });
- session.generateRequest('cenc', new Uint8Array(pssh));
- });
- }
-
- function DownloadMedia(url, type, mediaSource) {
- return new Promise(function(resolve, reject) {
- var sourceBuffer = mediaSource.addSourceBuffer(type);
- fetchWithXHR(url, (response) => {
- once(sourceBuffer, "updateend", resolve);
- sourceBuffer.appendBuffer(new Uint8Array(response));
- });
- });
- }
-
- function LoadMSE() {
- var ms = new MediaSource();
- audio.src = URL.createObjectURL(ms);
-
- once(ms, "sourceopen", ()=>{
- DownloadMedia('short-audio-fragmented-cenc-without-pssh.mp4', 'audio/mp4; codecs="mp4a.40.2"', ms)
- .then(() => { ms.endOfStream(); LoadEME();});
- });
-
- audio.addEventListener("loadeddata", SimpleTest.finish);
- }
-
- SetupEMEPref(LoadMSE);
-
- </script>
- </pre>
- </body>
-</html>
diff --git a/dom/media/test/test_eme_non_mse_fails.html b/dom/media/test/test_eme_non_mse_fails.html
deleted file mode 100644
index ede3edc5f2..0000000000
--- a/dom/media/test/test_eme_non_mse_fails.html
+++ /dev/null
@@ -1,103 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Bug 1131392 - Test that EME does not work for non-MSE media</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-var manager = new MediaTestManager;
-
-function DoSetMediaKeys(v, test)
-{
- var options = [{
- initDataTypes: ["cenc"],
- audioCapabilities: [{contentType: test.audioType}],
- videoCapabilities: [{contentType: test.videoType}],
- }];
-
- return navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, options)
-
- .then(function(keySystemAccess) {
- return keySystemAccess.createMediaKeys();
- })
-
- .catch(function() {
- ok(false, token + " was not expecting failure (yet)");
- })
-
- .then(function(mediaKeys) {
- return v.setMediaKeys(mediaKeys);
- });
-}
-
-function TestSetMediaKeys(test, token)
-{
- manager.started(token);
-
- var v = document.createElement("video");
-
- v.addEventListener("encrypted", function() {
- ok(false, token + " should not fire encrypted event");
- });
-
- var loadedMetadata = false;
- v.addEventListener("loadedmetadata", function() {
- loadedMetadata = true;
- });
-
- v.addEventListener("error", function() {
- ok(true, token + " expected error event");
- ok(loadedMetadata, token + " expected loadedmetadata to have fired");
- manager.finished(token);
- });
-
- v.src = test.name;
-}
-
-function TestSetSrc(test, token)
-{
- manager.started(token);
-
- var v = document.createElement("video");
- v.addEventListener("error", function(err) {
- ok(true, token + " got error setting src on video element, as expected");
- manager.finished(token);
- });
-
- DoSetMediaKeys(v, test)
-
- .then(function() {
- v.src = test.name;
- })
-
- .catch(function() {
- ok(false, token + " got error setting media keys");
- });
-}
-
-function startTest(test, token)
-{
- TestSetMediaKeys(test, token + "_setMediaKeys");
- TestSetSrc(test, token + "_setSrc");
-}
-
-function beginTest() {
- manager.runTests(gEMENonMSEFailTests, startTest);
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-</script>
-</pre>
-</body>
-</html>
-
diff --git a/dom/media/test/test_eme_playback.html b/dom/media/test/test_eme_playback.html
deleted file mode 100644
index a568402cd6..0000000000
--- a/dom/media/test/test_eme_playback.html
+++ /dev/null
@@ -1,188 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="http://test1.mochi.test:8888/tests/dom/media/test/eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-var manager = new MediaTestManager;
-
-function ArrayBuffersEqual(a, b) {
- if (a.byteLength != b.byteLength) {
- return false;
- }
- var ua = new Uint8Array(a);
- var ub = new Uint8Array(b);
- for (var i = 0; i < ua.length; i++) {
- if (ua[i] != ub[i]) {
- return false;
- }
- }
- return true;
-}
-
-function KeysChangeFunc(session, keys, token) {
- session.keyIdsReceived = [];
- for (var keyid in keys) {
- Log(token, "Set " + keyid + " to false in session[" + session.sessionId + "].keyIdsReceived");
- session.keyIdsReceived[keyid] = false;
- }
- return function(ev) {
- var session = ev.target;
- session.gotKeysChanged = true;
-
- var keyList = [];
- var valueList = [];
- var map = session.keyStatuses;
-
- // Test that accessing keys not known to the CDM has expected behaviour.
- var absentKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
- 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
- is(map.has(absentKey), false, "Shouldn't have a key that's not in the media");
- is(map.get(absentKey), undefined, "Unknown keys should undefined status");
-
- // Verify known keys have expected status.
- for (var [key, val] of map.entries()) {
- is(key.constructor, ArrayBuffer, "keyId should be ArrayBuffer");
- ok(map.has(key), "MediaKeyStatusMap.has() should work.");
- is(map.get(key), val, "MediaKeyStatusMap.get() should work.");
- keyList.push(key);
- valueList.push(val);
- is(val, "usable", token + ": key status should be usable");
- var kid = Base64ToHex(window.btoa(ArrayBufferToString(key)));
- ok(kid in session.keyIdsReceived, TimeStamp(token) + " session[" + session.sessionId + "].keyIdsReceived contained " + kid + " as expected.");
- session.keyIdsReceived[kid] = true;
- }
-
- var index = 0;
- for (var keyId of map.keys()) {
- ok(ArrayBuffersEqual(keyId, keyList[index]), "MediaKeyStatusMap.keys() should correspond to entries");
- index++;
- }
- index = 0;
- for (var val of map.values()) {
- is(val, valueList[index], "MediaKeyStatusMap.values() should correspond to entries");
- index++;
- }
- }
-}
-
-function startTest(test, token)
-{
- manager.started(token);
-
- var sessions = [];
-
- var v = SetupEME(test, token,
- {
- onsessioncreated: function(session) {
- sessions.push(session);
- session.addEventListener("keystatuseschange", KeysChangeFunc(session, test.keys, token), false);
-
- session.numKeystatuseschangeEvents = 0;
- session.numOnkeystatuseschangeEvents = 0;
-
- session.addEventListener("keystatuseschange", function() {
- session.numKeystatuseschangeEvents += 1;
- });
- session.onkeystatuseschange = function() {
- session.numOnkeystatuseschangeEvents += 1;
- };
-
- session.numMessageEvents = 0;
- session.numOnMessageEvents = 0;
- session.addEventListener("message", function() {
- session.numMessageEvents += 1;
- });
- session.onmessage = function() {
- session.numOnMessageEvents += 1;
- };
- }
- }
- );
-
- document.body.appendChild(v);
-
- var gotEncrypted = 0;
-
- v.addEventListener("encrypted", function(ev) {
- gotEncrypted += 1;
- });
-
- v.addEventListener("loadedmetadata", function() {
- ok(SpecialPowers.do_lookupGetter(v, "isEncrypted").apply(v),
- TimeStamp(token) + " isEncrypted should be true");
- is(v.isEncrypted, undefined, "isEncrypted should not be accessible from content");
- });
-
- v.addEventListener("ended", function(ev) {
- ok(true, TimeStamp(token) + " got ended event");
-
- is(gotEncrypted, test.sessionCount,
- TimeStamp(token) + " encrypted events expected: " + test.sessionCount
- + ", actual: " + gotEncrypted);
-
- ok(Math.abs(test.duration - v.duration) < 0.1,
- TimeStamp(token) + " Duration of video should be corrrect");
- ok(Math.abs(test.duration - v.currentTime) < 0.1,
- TimeStamp(token) + " Current time should be same as duration");
-
- // Verify all sessions had all keys went sent to the CDM usable, and thus
- // that we received keystatuseschange event(s).
- is(sessions.length, test.sessionCount, TimeStamp(token) + " should have "
- + test.sessionCount
- + " session" + (test.sessionCount === 1 ? "" : "s"));
- var keyIdsReceived = [];
- for (var keyid in test.keys) { keyIdsReceived[keyid] = false; }
- for (var i = 0; i < sessions.length; i++) {
- var session = sessions[i];
- ok(session.gotKeysChanged,
- TimeStamp(token) + " session[" + session.sessionId
- + "] should have received at least one keychange event");
- for (var kid in session.keyIdsReceived) {
- Log(token, "session[" + session.sessionId + "] key " + kid + " = " + (session.keyIdsReceived[kid] ? "true" : "false"));
- if (session.keyIdsReceived[kid]) { keyIdsReceived[kid] = true; }
- }
- ok(session.numKeystatuseschangeEvents > 0, TimeStamp(token) + " should get key status changes");
- is(session.numKeystatuseschangeEvents, session.numOnkeystatuseschangeEvents,
- TimeStamp(token) + " should have as many keystatuseschange event listener calls as event handler calls.");
-
- ok(session.numMessageEvents > 0, TimeStamp(token) + " should get message events");
- is(session.numMessageEvents, session.numOnMessageEvents,
- TimeStamp(token) + " should have as many message event listener calls as event handler calls.");
- }
- for (var kid in keyIdsReceived) {
- ok(keyIdsReceived[kid], TimeStamp(token) + " key with id " + kid + " was usable as expected");
- }
-
- v.closeSessions().then(() => manager.finished(token));
- });
-
- LoadTest(test, v, token)
- .then(function() {
- v.play();
- }).catch(function() {
- ok(false, token + " failed to load");
- manager.finished(token);
- });
-}
-
-function beginTest() {
- manager.runTests(gEMETests, startTest);
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_requestKeySystemAccess.html b/dom/media/test/test_eme_requestKeySystemAccess.html
deleted file mode 100644
index 21ee91a68c..0000000000
--- a/dom/media/test/test_eme_requestKeySystemAccess.html
+++ /dev/null
@@ -1,484 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-const SUPPORTED_LABEL = "pass label";
-
-function ValidateConfig(name, expected, observed) {
- info("ValidateConfig " + name);
- info("expected cfg=" + JSON.stringify(expected));
- info("observed cfg=" + JSON.stringify(observed));
-
- is(observed.label, expected.label, name + " label should match");
- if (expected.initDataTypes) {
- ok(expected.initDataTypes.every((element, index, array) => observed.initDataTypes.includes(element)), name + " initDataTypes should match.");
- }
-
- if (expected.audioCapabilities) {
- ok(expected.audioCapabilities.length == 1, "Test function can only handle one capability.");
- ok(observed.audioCapabilities.length == 1, "Test function can only handle one capability.");
- is(observed.audioCapabilities[0].contentType, expected.audioCapabilities[0].contentType, name + " audioCapabilities should match.");
- }
- if (typeof expected.videoCapabilities !== 'undefined') {
- info("expected.videoCapabilities=" + expected.videoCapabilities);
- dump("expected.videoCapabilities=" + expected.videoCapabilities + "\n");
- ok(expected.videoCapabilities.length == 1, "Test function can only handle one capability.");
- ok(observed.videoCapabilities.length == 1, "Test function can only handle one capability.");
- is(observed.videoCapabilities[0].contentType, expected.videoCapabilities[0].contentType, name + " videoCapabilities should match.");
- }
- if (expected.sessionTypes) {
- is(expected.sessionTypes.length, observed.sessionTypes.length, "Should have expected number of sessionTypes");
- for (var i = 0; i < expected.sessionTypes.length; i++) {
- is(expected[i], observed[i], "Session type " + i + " should match");
- }
- }
-}
-
-function Test(test) {
- var name = "'" + test.name + "'";
- return new Promise(function(resolve, reject) {
- var p;
- if (test.options) {
- var keySystem = (test.keySystem !== undefined) ? test.keySystem : CLEARKEY_KEYSYSTEM;
- p = navigator.requestMediaKeySystemAccess(keySystem, test.options);
- } else {
- p = navigator.requestMediaKeySystemAccess(keySystem);
- }
- p.then(
- function(keySystemAccess) {
- ok(test.shouldPass, name + " passed and was expected to " + (test.shouldPass ? "pass" : "fail"));
- is(keySystemAccess.keySystem, CLEARKEY_KEYSYSTEM, "CDM keySystem should be in MediaKeySystemAccess.keySystem");
- ValidateConfig(name, test.expectedConfig, keySystemAccess.getConfiguration());
- resolve();
- },
- function(ex) {
- if (test.shouldPass) {
- info(name + " failed: " + ex);
- }
- ok(!test.shouldPass, name + " failed and was expected to " + (test.shouldPass ? "pass" : "fail"));
- resolve();
- });
- });
-}
-
-var tests = [
- {
- name: 'Empty keySystem string',
- keySystem: '',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'Empty options specified',
- options: [ ],
- shouldPass: false,
- },
- {
- name: 'Undefined options',
- shouldPass: false,
- },
- {
- name: 'Basic MP4 cenc',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4'}],
- videoCapabilities: [{contentType: 'video/mp4'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4'}],
- videoCapabilities: [{contentType: 'video/mp4'}],
- },
- shouldPass: true,
- },
- {
- name: 'Invalid keysystem failure',
- keySystem: 'bogusKeySystem',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'Invalid initDataType',
- options: [
- {
- initDataTypes: ['bogus'],
- audioCapabilities: [{contentType: 'audio/mp4'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'Valid initDataType after invalid',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['bogus', 'invalid', 'cenc'],
- audioCapabilities: [{contentType: 'audio/mp4'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4'}],
- },
- shouldPass: true,
- },
- {
- name: 'Invalid videoType',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/bogus'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'Invalid distinctiveIdentifier fails',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- distinctiveIdentifier: 'bogus',
- persistentState: 'bogus',
- }
- ],
- shouldPass: false,
- },
- {
- name: 'distinctiveIdentifier is prohibited for ClearKey',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- distinctiveIdentifier: 'required',
- }
- ],
- shouldPass: false,
- },
- {
- name: 'Invalid persistentState fails',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- persistentState: 'bogus',
- }
- ],
- shouldPass: false,
- },
- {
- name: 'Invalid robustness unsupported',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4', robustness: 'very much so'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'Unexpected config entry should be ignored',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- unexpectedEntry: 'this should be ignored',
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- },
- shouldPass: true,
- },
- {
- name: 'Invalid option followed by valid',
- options: [
- {
- label: "this config should not be supported",
- initDataTypes: ['bogus'],
- },
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- },
- shouldPass: true,
- },
- {
- name: 'Persistent-license should not be supported by ClearKey',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- sessionTypes: ['persistent-license'],
- persistentState: 'optional',
- }
- ],
- shouldPass: false,
- },
- {
- name: 'Persistent-usage-record should not be supported by ClearKey',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4'}],
- sessionTypes: ['persistent-usage-record'],
- persistentState: 'optional',
- }
- ],
- shouldPass: false,
- },
- {
- name: 'MP4 audio container',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4'}],
- },
- shouldPass: true,
- },
- {
- name: 'MP4 audio container with AAC-LC',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
- },
- shouldPass: true,
- },
- {
- name: 'MP4 audio container with invalid codecs',
- options: [
- {
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4; codecs="bogus"'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'MP4 audio container with mp3 is unsupported',
- options: [
- {
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4; codecs="mp3"'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'MP4 video container type with an mp3 codec is unsupported',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4; codecs="mp3"'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'MP4 audio container type with a video codec is unsupported',
- options: [
- {
- initDataTypes: ['cenc'],
- audioCapabilities: [{contentType: 'audio/mp4; codecs="avc1.42E01E"'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'MP4 video container with constrained baseline h.264',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
- },
- shouldPass: true,
- },
- {
- name: 'MP4 video container with invalid codecs',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4; codecs="bogus"'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'MP4 video container with both audio and video codec type in videoType',
- options: [
- {
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E,mp4a.40.2"'}],
- }
- ],
- shouldPass: false,
- },
- {
- name: 'MP4 audio and video type both specified',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
- audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['cenc'],
- videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
- audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
- },
- shouldPass: true,
- },
- {
- name: 'Basic WebM video',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['webm'],
- videoCapabilities: [{contentType: 'video/webm'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['webm'],
- videoCapabilities: [{contentType: 'video/webm'}],
- },
- shouldPass: true,
- },
- {
- name: 'Basic WebM audio',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['webm'],
- audioCapabilities: [{contentType: 'audio/webm'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['webm'],
- audioCapabilities: [{contentType: 'audio/webm'}],
- },
- shouldPass: true,
- },
- {
- name: 'Webm with Vorbis audio and VP8 video.',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['webm'],
- videoCapabilities: [{contentType: 'video/webm;codecs="vp8"'}],
- audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['webm'],
- videoCapabilities: [{contentType: 'video/webm;codecs="vp8"'}],
- audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
- },
- shouldPass: true,
- },
- {
- name: 'Webm with Vorbis audio and VP9 video.',
- options: [
- {
- label: SUPPORTED_LABEL,
- initDataTypes: ['webm'],
- videoCapabilities: [{contentType: 'video/webm;codecs="vp9"'}],
- audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
- }
- ],
- expectedConfig: {
- label: SUPPORTED_LABEL,
- initDataTypes: ['webm'],
- videoCapabilities: [{contentType: 'video/webm;codecs="vp9"'}],
- audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
- },
- shouldPass: true,
- },
- {
- name: 'Webm with bogus video.',
- options: [
- {
- initDataTypes: ['webm'],
- videoCapabilities: [{contentType: 'video/webm;codecs="bogus"'}],
- }
- ],
- shouldPass: false,
- },
-];
-
-function beginTest() {
- Promise.all(tests.map(Test)).then(function() { SimpleTest.finish(); });
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_request_notifications.html b/dom/media/test/test_eme_request_notifications.html
deleted file mode 100644
index c2fab5b152..0000000000
--- a/dom/media/test/test_eme_request_notifications.html
+++ /dev/null
@@ -1,88 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-var manager = new MediaTestManager;
-
-function SetPrefs(prefs) {
- return new Promise(function(resolve, reject) {
- SpecialPowers.pushPrefEnv({"set": prefs}, function() { resolve(); });
- });
-}
-
-function observe() {
- return new Promise(function(resolve, reject) {
- var observer = function(subject, topic, data) {
- SpecialPowers.Services.obs.removeObserver(observer, "mediakeys-request");
- resolve(JSON.parse(data).status);
- };
- SpecialPowers.Services.obs.addObserver(observer, "mediakeys-request", false);
- });
-}
-
-function Test(test) {
- var p = test.prefs ? SetPrefs(test.prefs) : Promise.resolve();
- observedStatus = "nothing";
- var name = "'" + test.keySystem + "'";
-
- var res = observe().then((status) => {
- is(status, test.expectedStatus, name + " expected status");
- });
-
- p.then(() => navigator.requestMediaKeySystemAccess(test.keySystem, gCencMediaKeySystemConfig))
- .then((keySystemAccess) => keySystemAccess.createMediaKeys());
-
- return res;
-}
-
-const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
-
-var tests = [
- {
- keySystem: CLEARKEY_KEYSYSTEM,
- expectedStatus: 'cdm-created',
- prefs: [["media.eme.enabled", false]]
- },
- {
- keySystem: "com.widevine.alpha",
- expectedStatus: 'api-disabled',
- prefs: [["media.eme.enabled", false]]
- },
- {
- keySystem: "com.widevine.alpha",
- expectedStatus: (isWinXP ? 'cdm-not-supported' : 'cdm-disabled'),
- prefs: [["media.eme.enabled", true], ["media.gmp-widevinecdm.enabled", false]]
- },
- {
- keySystem: "com.widevine.alpha",
- expectedStatus: (isWinXP ? 'cdm-not-supported' : 'cdm-not-installed'),
- prefs: [["media.eme.enabled", true], , ["media.gmp-widevinecdm.enabled", true]]
- },
- {
- keySystem: CLEARKEY_KEYSYSTEM,
- expectedStatus: 'cdm-created',
- prefs: [["media.eme.enabled", true]]
- }
-];
-
-SetupEMEPref(function() {
- tests.reduce(function(p,c,i,array) {
- return p.then(function() { return Test(c); });
- }, Promise.resolve()).then(SimpleTest.finish);
-});
-
-
-SimpleTest.waitForExplicitFinish();
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_session_callable_value.html b/dom/media/test/test_eme_session_callable_value.html
deleted file mode 100644
index 5c5f51e307..0000000000
--- a/dom/media/test/test_eme_session_callable_value.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-function Test() {
- navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, gCencMediaKeySystemConfig)
- .then(access => access.createMediaKeys())
- .then(mediaKeys => {
- var initData = (new TextEncoder()).encode( 'this is an invalid license, and that is ok');
- var s = mediaKeys.createSession("temporary");
- s.generateRequest("cenc", initData); // ignore result.
- // "update()" call should fail, because MediaKeySession is "not callable"
- // yet, since CDM won't have had a chance to set the sessionId on MediaKeySession.
- return s.update(initData);
- })
- .then(()=>{ok(false, "An exception should be thrown; MediaKeySession should be not callable."); SimpleTest.finish();},
- ()=>{ok(true, "We expect this to fail; MediaKeySession should be not callable."); SimpleTest.finish();});
-}
-
-SimpleTest.waitForExplicitFinish();
-SetupEMEPref(Test);
-
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_setMediaKeys_before_attach_MediaSource.html b/dom/media/test/test_eme_setMediaKeys_before_attach_MediaSource.html
deleted file mode 100644
index 72bc77124d..0000000000
--- a/dom/media/test/test_eme_setMediaKeys_before_attach_MediaSource.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-function beginTest() {
- var video = document.createElement("video");
-
- navigator.requestMediaKeySystemAccess(CLEARKEY_KEYSYSTEM, gCencMediaKeySystemConfig)
- .then(function(keySystemAccess) {
- return keySystemAccess.createMediaKeys();
- })
- .then(mediaKeys => {
- return video.setMediaKeys(mediaKeys);
- })
- .then(() => {
- var ms = new MediaSource();
- ms.addEventListener("sourceopen", ()=>{ok(true, "MediaSource should open"); SimpleTest.finish();});
- video.addEventListener("error", ()=>{ok(false, "Shouldn't error."); SimpleTest.finish();});
- video.src = URL.createObjectURL(ms);
- });
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_stream_capture_blocked_case1.html b/dom/media/test/test_eme_stream_capture_blocked_case1.html
deleted file mode 100644
index 61e8d673f3..0000000000
--- a/dom/media/test/test_eme_stream_capture_blocked_case1.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-var manager = new MediaTestManager;
-
-function startTest(test, token)
-{
- // Three cases:
- // 1. setting MediaKeys on an element captured by MediaElementSource should fail, and
- // 2. creating a MediaElementSource on a media element with a MediaKeys should fail, and
- // 3. capturing a media element with mozCaptureStream that has a MediaKeys should fail.
-
- // Case 1. setting MediaKeys on an element captured by MediaElementSource should fail.
- var case1token = token + "_case1";
- var setKeysFailed = function() {
- ok(true, TimeStamp(case1token) + " setMediaKeys failed as expected.");
- manager.finished(case1token);
- };
- var v1 = SetupEME(test, case1token, { onSetKeysFail: setKeysFailed });
- var context = new AudioContext();
- var node = context.createMediaElementSource(v1);
- v1.addEventListener("loadeddata", function(ev) {
- ok(false, TimeStamp(case1token) + " should never reach loadeddata, as setMediaKeys should fail");
- });
- manager.started(case1token);
- LoadTestWithManagedLoadToken(test, v1, manager, case1token,
- { onlyLoadFirstFragments:2, noEndOfStream:false });
-}
-
-function beginTest() {
- manager.runTests(gEMETests, startTest);
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_stream_capture_blocked_case2.html b/dom/media/test/test_eme_stream_capture_blocked_case2.html
deleted file mode 100644
index 48c8bf3e4a..0000000000
--- a/dom/media/test/test_eme_stream_capture_blocked_case2.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-var manager = new MediaTestManager;
-
-function startTest(test, token)
-{
- // Three cases:
- // 1. setting MediaKeys on an element captured by MediaElementSource should fail, and
- // 2. creating a MediaElementSource on a media element with a MediaKeys should fail, and
- // 3. capturing a media element with mozCaptureStream that has a MediaKeys should fail.
-
- // Case 2. creating a MediaElementSource on a media element with a MediaKeys should fail.
- var case2token = token + "_case2";
- var v2 = SetupEME(test, case2token);
- v2.addEventListener("loadeddata", function(ev) {
- ok(true, case2token + " should reach loadeddata");
- var threw = false;
- try {
- var context = new AudioContext();
- var node = context.createMediaElementSource(v2);
- } catch (e) {
- threw = true;
- }
- ok(threw, "Should throw an error creating a MediaElementSource on an EME video.");
- manager.finished(case2token);
- });
- manager.started(case2token);
- LoadTestWithManagedLoadToken(test, v2, manager, case2token,
- { onlyLoadFirstFragments:2, noEndOfStream:false });
-}
-
-function beginTest() {
- manager.runTests(gEMETests, startTest);
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_stream_capture_blocked_case3.html b/dom/media/test/test_eme_stream_capture_blocked_case3.html
deleted file mode 100644
index 1af4e0aadf..0000000000
--- a/dom/media/test/test_eme_stream_capture_blocked_case3.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-var manager = new MediaTestManager;
-
-function startTest(test, token)
-{
- // Three cases:
- // 1. setting MediaKeys on an element captured by MediaElementSource should fail, and
- // 2. creating a MediaElementSource on a media element with a MediaKeys should fail, and
- // 3. capturing a media element with mozCaptureStream that has a MediaKeys should fail.
-
- // Case 3. capturing a media element with mozCaptureStream that has a MediaKeys should fail.
- var case3token = token + "_case3";
- var v3 = SetupEME(test, case3token);
- v3.addEventListener("loadeddata", function(ev) {
- ok(true, TimeStamp(case3token) + " should reach loadeddata");
- var threw = false;
- try {
- var stream = v3.mozCaptureStreamUntilEnded();
- } catch (e) {
- threw = true;
- }
- ok(threw, TimeStamp(case3token) + " Should throw an error calling mozCaptureStreamUntilEnded an EME video.");
- manager.finished(case3token);
- });
- manager.started(case3token);
- LoadTestWithManagedLoadToken(test, v3, manager, case3token,
- { onlyLoadFirstFragments:2, noEndOfStream:false });
-}
-
-function beginTest() {
- manager.runTests(gEMETests, startTest);
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/test/test_eme_waitingforkey.html b/dom/media/test/test_eme_waitingforkey.html
deleted file mode 100644
index ce808342bb..0000000000
--- a/dom/media/test/test_eme_waitingforkey.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test Encrypted Media Extensions</title>
- <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
- <script type="text/javascript" src="manifest.js"></script>
- <script type="text/javascript" src="http://test1.mochi.test:8888/tests/dom/media/test/eme.js"></script>
-</head>
-<body>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-var manager = new MediaTestManager;
-
-function startTest(test, token)
-{
- // Test if the appropriate preconditions are met such that we can start
- // prcoessing delayed sessions.
- function TestIfDoneDelaying()
- {
- var got = "Got:";
- if (loaded) { got += " loaded,"; }
- got += " " + gotEncrypted + "/" + test.sessionCount + " sessions,";
- got += " " + gotWaitingForKey + " waiting for key events"
- if (loaded && gotEncrypted == test.sessionCount && gotWaitingForKey > 0) {
- Log(token, got + " -> Update sessions with keys");
- params.ProcessSessions();
- } else {
- Log(token, got + " -> Wait for more...");
- }
- }
-
- manager.started(token);
-
- var updatedSessionsCount = 0;
- var loaded = false;
-
- var params = {
- // params will be populated with a ProcessSessions() callback, that can be
- // called to process delayed sessions.
- delaySessions: true,
- // Function to be called once we start processing and updating sessions.
- // This should only be called once the preconditions in TestIfDoneDealying
- // are met.
- onsessionupdated: function(session) {
- updatedSessionsCount += 1;
- if (updatedSessionsCount == test.sessionCount) {
- info(TimeStamp(token) + " Updated all sessions, loading complete -> Play");
- v.play();
- } else {
- info(TimeStamp(token) + " Updated " + updatedSessionsCount + "/" + test.sessionCount + " sessions so far");
- }
- },
- };
- var v = SetupEME(test, token, params);
-
- document.body.appendChild(v);
-
- var gotEncrypted = 0;
- var gotWaitingForKey = 0;
- var gotOnwaitingforkey = 0;
-
- v.addEventListener("encrypted", function() {
- gotEncrypted += 1;
- TestIfDoneDelaying();
- });
-
- v.addEventListener("waitingforkey", function() {
- gotWaitingForKey += 1;
- TestIfDoneDelaying()
- });
-
- v.onwaitingforkey = function() {
- gotOnwaitingforkey += 1;
- };
-
- v.addEventListener("loadedmetadata", function() {
- ok(SpecialPowers.do_lookupGetter(v, "isEncrypted").apply(v),
- TimeStamp(token) + " isEncrypted should be true");
- is(v.isEncrypted, undefined, "isEncrypted should not be accessible from content");
- });
-
- v.addEventListener("ended", function() {
- ok(true, TimeStamp(token) + " got ended event");
- // We expect only one waitingForKey as we delay until all sessions are ready.
- // I.e. one waitingForKey should be fired, after which, we process all sessions,
- // so it should not be possible to be blocked by a key after that point.
- ok(gotWaitingForKey == 1, "Expected number 1 wait, got: " + gotWaitingForKey);
- ok(gotOnwaitingforkey == gotWaitingForKey, "Should have as many event listener calls as event handler calls, got: " + gotOnwaitingforkey);
-
- v.closeSessions().then(() => manager.finished(token));
- });
-
- LoadTest(test, v, token)
- .then(function() {
- loaded = true;
- TestIfDoneDelaying();
- }).catch(function() {
- ok(false, token + " failed to load");
- manager.finished(token);
- });
-}
-
-function beginTest() {
- manager.runTests(gEMETests, startTest);
-}
-
-if (!IsMacOSSnowLeopardOrEarlier()) {
- SimpleTest.waitForExplicitFinish();
- SetupEMEPref(beginTest);
-} else {
- todo(false, "Test disabled on this platform.");
-}
-</script>
-</pre>
-</body>
-</html>
diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp
index 44285735be..9539133a4f 100755
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -372,13 +372,6 @@ AudioContext::CreateMediaElementSource(HTMLMediaElement& aMediaElement,
return nullptr;
}
-#ifdef MOZ_EME
- if (aMediaElement.ContainsRestrictedContent()) {
- aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return nullptr;
- }
-#endif
-
if (CheckClosed(aRv)) {
return nullptr;
}
diff --git a/dom/webidl/HTMLMediaElement.webidl b/dom/webidl/HTMLMediaElement.webidl
index ad31f38cbc..7f0f9f8571 100644
--- a/dom/webidl/HTMLMediaElement.webidl
+++ b/dom/webidl/HTMLMediaElement.webidl
@@ -153,24 +153,6 @@ partial interface HTMLMediaElement {
attribute EventHandler onmozinterruptend;
};
-#ifdef MOZ_EME
-// Encrypted Media Extensions
-partial interface HTMLMediaElement {
- [Pref="media.eme.apiVisible"]
- readonly attribute MediaKeys? mediaKeys;
-
- // void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
- [Pref="media.eme.apiVisible", NewObject]
- Promise<void> setMediaKeys(MediaKeys? mediaKeys);
-
- [Pref="media.eme.apiVisible"]
- attribute EventHandler onencrypted;
-
- [Pref="media.eme.apiVisible"]
- attribute EventHandler onwaitingforkey;
-};
-#endif
-
// This is just for testing
partial interface HTMLMediaElement {
[Pref="media.useAudioChannelService.testing"]
diff --git a/dom/webidl/MediaEncryptedEvent.webidl b/dom/webidl/MediaEncryptedEvent.webidl
deleted file mode 100644
index 28d7a17b79..0000000000
--- a/dom/webidl/MediaEncryptedEvent.webidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
- *
- * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
- * W3C liability, trademark and document use rules apply.
- */
-
-[Pref="media.eme.apiVisible", Constructor(DOMString type, optional MediaKeyNeededEventInit eventInitDict)]
-interface MediaEncryptedEvent : Event {
- readonly attribute DOMString initDataType;
- [Throws]
- readonly attribute ArrayBuffer? initData;
-};
-
-dictionary MediaKeyNeededEventInit : EventInit {
- DOMString initDataType = "";
- ArrayBuffer? initData = null;
-};
diff --git a/dom/webidl/MediaKeyError.webidl b/dom/webidl/MediaKeyError.webidl
deleted file mode 100644
index d0dde20320..0000000000
--- a/dom/webidl/MediaKeyError.webidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
- *
- * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
- * W3C liability, trademark and document use rules apply.
- */
-
-// According to the spec, "The future of error events and MediaKeyError
-// is uncertain."
-// https://www.w3.org/Bugs/Public/show_bug.cgi?id=21798
-[Pref="media.eme.apiVisible"]
-interface MediaKeyError : Event {
- readonly attribute unsigned long systemCode;
-};
diff --git a/dom/webidl/MediaKeyMessageEvent.webidl b/dom/webidl/MediaKeyMessageEvent.webidl
deleted file mode 100644
index 057924bb73..0000000000
--- a/dom/webidl/MediaKeyMessageEvent.webidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
- *
- * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
- * W3C liability, trademark and document use rules apply.
- */
-
-enum MediaKeyMessageType {
- "license-request",
- "license-renewal",
- "license-release",
- "individualization-request"
-};
-
-[Pref="media.eme.apiVisible", Constructor(DOMString type, MediaKeyMessageEventInit eventInitDict)]
-interface MediaKeyMessageEvent : Event {
- readonly attribute MediaKeyMessageType messageType;
- [Throws]
- readonly attribute ArrayBuffer message;
-};
-
-dictionary MediaKeyMessageEventInit : EventInit {
- required MediaKeyMessageType messageType;
- required ArrayBuffer message;
-};
diff --git a/dom/webidl/MediaKeySession.webidl b/dom/webidl/MediaKeySession.webidl
deleted file mode 100644
index 8ca5745c44..0000000000
--- a/dom/webidl/MediaKeySession.webidl
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
- *
- * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
- * W3C liability, trademark and document use rules apply.
- */
-
-[Pref="media.eme.apiVisible"]
-interface MediaKeySession : EventTarget {
- // error state
- readonly attribute MediaKeyError? error;
-
- // session properties
- readonly attribute DOMString keySystem;
- readonly attribute DOMString sessionId;
-
- readonly attribute unrestricted double expiration;
-
- readonly attribute Promise<void> closed;
-
- readonly attribute MediaKeyStatusMap keyStatuses;
-
- attribute EventHandler onkeystatuseschange;
-
- attribute EventHandler onmessage;
-
- [NewObject]
- Promise<void> generateRequest(DOMString initDataType, BufferSource initData);
-
- [NewObject]
- Promise<boolean> load(DOMString sessionId);
-
- // session operations
- [NewObject]
- Promise<void> update(BufferSource response);
-
- [NewObject]
- Promise<void> close();
-
- [NewObject]
- Promise<void> remove();
-};
diff --git a/dom/webidl/MediaKeyStatusMap.webidl b/dom/webidl/MediaKeyStatusMap.webidl
deleted file mode 100644
index 1f34b5dc7c..0000000000
--- a/dom/webidl/MediaKeyStatusMap.webidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
- *
- * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
- * W3C liability, trademark and document use rules apply.
- */
-
-enum MediaKeyStatus {
- "usable",
- "expired",
- "released",
- "output-restricted",
- "output-downscaled",
- "status-pending",
- "internal-error"
-};
-
-[Pref="media.eme.apiVisible"]
-interface MediaKeyStatusMap {
- iterable<ArrayBuffer,MediaKeyStatus>;
- readonly attribute unsigned long size;
- boolean has (BufferSource keyId);
- [Throws]
- any get (BufferSource keyId);
-};
diff --git a/dom/webidl/MediaKeySystemAccess.webidl b/dom/webidl/MediaKeySystemAccess.webidl
deleted file mode 100644
index 01552e4490..0000000000
--- a/dom/webidl/MediaKeySystemAccess.webidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
- *
- * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
- * W3C liability, trademark and document use rules apply.
- */
-
-enum MediaKeysRequirement {
- "required",
- "optional",
- "not-allowed"
-};
-
-dictionary MediaKeySystemMediaCapability {
- DOMString contentType = "";
- DOMString robustness = "";
-};
-
-dictionary MediaKeySystemConfiguration {
- DOMString label = "";
- sequence<DOMString> initDataTypes = [];
- sequence<MediaKeySystemMediaCapability> audioCapabilities = [];
- sequence<MediaKeySystemMediaCapability> videoCapabilities = [];
- MediaKeysRequirement distinctiveIdentifier = "optional";
- MediaKeysRequirement persistentState = "optional";
- sequence<DOMString> sessionTypes;
-};
-
-[Pref="media.eme.apiVisible"]
-interface MediaKeySystemAccess {
- readonly attribute DOMString keySystem;
- [NewObject]
- MediaKeySystemConfiguration getConfiguration();
- [NewObject]
- Promise<MediaKeys> createMediaKeys();
-};
diff --git a/dom/webidl/MediaKeys.webidl b/dom/webidl/MediaKeys.webidl
deleted file mode 100644
index cb84cdab6d..0000000000
--- a/dom/webidl/MediaKeys.webidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
- *
- * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
- * W3C liability, trademark and document use rules apply.
- */
-
-// Note: "persistent-usage-record" session type is unsupported yet, as
-// it's marked as "at risk" in the spec, and Chrome doesn't support it.
-enum MediaKeySessionType {
- "temporary",
- "persistent-license",
- // persistent-usage-record,
-};
-
-[Pref="media.eme.apiVisible"]
-interface MediaKeys {
- readonly attribute DOMString keySystem;
-
- [NewObject, Throws]
- MediaKeySession createSession(optional MediaKeySessionType sessionType = "temporary");
-
- [NewObject]
- Promise<void> setServerCertificate((ArrayBufferView or ArrayBuffer) serverCertificate);
-};
diff --git a/dom/webidl/MediaKeysRequestStatus.webidl b/dom/webidl/MediaKeysRequestStatus.webidl
deleted file mode 100644
index 737372f664..0000000000
--- a/dom/webidl/MediaKeysRequestStatus.webidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-enum MediaKeySystemStatus {
- "available",
- "api-disabled",
- "cdm-disabled",
- "cdm-not-supported",
- "cdm-not-installed",
- "cdm-created",
-};
-
-/* Note: This dictionary and enum is only used by Gecko to convey messages
- * to chrome JS code. It is not exposed to the web.
- */
-
-dictionary RequestMediaKeySystemAccessNotification {
- required DOMString keySystem;
- required MediaKeySystemStatus status;
-};
diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl
index 5f2ac63e1e..c91d262c0c 100644
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -304,15 +304,6 @@ partial interface Navigator {
readonly attribute LegacyMozTCPSocket mozTCPSocket;
};
-#ifdef MOZ_EME
-partial interface Navigator {
- [Pref="media.eme.apiVisible", NewObject]
- Promise<MediaKeySystemAccess>
- requestMediaKeySystemAccess(DOMString keySystem,
- sequence<MediaKeySystemConfiguration> supportedConfigurations);
-};
-#endif
-
[NoInterfaceObject, Exposed=(Window,Worker)]
interface NavigatorConcurrentHardware {
readonly attribute unsigned long long hardwareConcurrency;
diff --git a/dom/webidl/WidevineCDMManifest.webidl b/dom/webidl/WidevineCDMManifest.webidl
deleted file mode 100644
index 83e14e0b0b..0000000000
--- a/dom/webidl/WidevineCDMManifest.webidl
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-dictionary WidevineCDMManifest {
- required DOMString name;
- required DOMString description;
- required DOMString version;
- required DOMString x-cdm-module-versions;
- required DOMString x-cdm-interface-versions;
- required DOMString x-cdm-host-versions;
- required DOMString x-cdm-codecs;
-};
diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
index 1cefdacabb..dfcc11182b 100644
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -572,19 +572,6 @@ WEBIDL_FILES = [
'XULElement.webidl',
]
-if CONFIG['MOZ_EME']:
- WEBIDL_FILES += [
- 'MediaEncryptedEvent.webidl',
- 'MediaKeyError.webidl',
- 'MediaKeyMessageEvent.webidl',
- 'MediaKeys.webidl',
- 'MediaKeySession.webidl',
- 'MediaKeysRequestStatus.webidl',
- 'MediaKeyStatusMap.webidl',
- 'MediaKeySystemAccess.webidl',
- 'WidevineCDMManifest.webidl',
- ]
-
if CONFIG['MOZ_AUDIO_CHANNEL_MANAGER']:
WEBIDL_FILES += [
'AudioChannelManager.webidl',