summaryrefslogtreecommitdiff
path: root/dom/media/eme/MediaKeySystemAccessManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/eme/MediaKeySystemAccessManager.cpp')
-rw-r--r--dom/media/eme/MediaKeySystemAccessManager.cpp339
1 files changed, 0 insertions, 339 deletions
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