Commit cc6f674d authored by RJ Ascani's avatar RJ Ascani Committed by Commit Bot

[Fuchsia] Wait for CDM OnProvisioned event

The fuchsia.media.drm.ContentDecryptionModule sends an event upon the
completion of provisioning[1]. This is an indication that the CDM is
ready for use. This CL pends the CDM creation callback until after the
OnProvisioned event has been received, ensuring the CDM is ready prior
to any calls being made to it.

[1] https://fuchsia.dev/reference/fidl/fuchsia.media.drm#fuchsia.media.drm/ContentDecryptionModule.OnProvisioned

Bug: fuchsia: 13619
Change-Id: Ie119daa58610b2cab0cade14b7dbf1ef93b3dcfc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2315000
Commit-Queue: RJ Ascani <rjascani@google.com>
Reviewed-by: default avatarSergey Ulanov <sergeyu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791987}
parent c086a216
......@@ -240,17 +240,28 @@ FuchsiaCdm::SessionCallbacks& FuchsiaCdm::SessionCallbacks::operator=(
SessionCallbacks&&) = default;
FuchsiaCdm::FuchsiaCdm(fuchsia::media::drm::ContentDecryptionModulePtr cdm,
ReadyCB ready_cb,
SessionCallbacks callbacks)
: cdm_(std::move(cdm)),
ready_cb_(std::move(ready_cb)),
session_callbacks_(std::move(callbacks)),
decryptor_(cdm_.get()) {
DCHECK(cdm_);
cdm_.events().OnProvisioned =
fit::bind_member(this, &FuchsiaCdm::OnProvisioned);
cdm_.set_error_handler([this](zx_status_t status) {
ZX_LOG(ERROR, status) << "The fuchsia.media.drm.ContentDecryptionModule"
<< " channel was terminated.";
// Reject all the pending promises.
promises_.Clear();
// If the channel closed prior to invoking the ready_cb_, we should invoke
// it here with failure.
if (ready_cb_) {
std::move(ready_cb_).Run(
false, "ContentDecryptionModule closed prior to being ready");
}
});
}
......@@ -346,6 +357,12 @@ void FuchsiaCdm::CreateSessionAndGenerateRequest(
base::Unretained(this), session_ptr, promise_id));
}
void FuchsiaCdm::OnProvisioned() {
if (ready_cb_) {
std::move(ready_cb_).Run(true, "");
}
}
void FuchsiaCdm::OnCreateSession(std::unique_ptr<CdmSession> session,
uint32_t promise_id,
const std::string& session_id) {
......
......@@ -7,6 +7,7 @@
#include <fuchsia/media/drm/cpp/fidl.h>
#include "base/callback_forward.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/optional.h"
......@@ -37,8 +38,10 @@ class FuchsiaCdm : public ContentDecryptionModule,
DISALLOW_COPY_AND_ASSIGN(SessionCallbacks);
};
using ReadyCB = base::OnceCallback<void(bool, const std::string&)>;
FuchsiaCdm(fuchsia::media::drm::ContentDecryptionModulePtr cdm,
ReadyCB ready_cb,
SessionCallbacks callbacks);
// ContentDecryptionModule implementation:
......@@ -76,6 +79,7 @@ class FuchsiaCdm : public ContentDecryptionModule,
~FuchsiaCdm() override;
void OnProvisioned();
void OnCreateSession(std::unique_ptr<CdmSession> session,
uint32_t promise_id,
const std::string& session_id);
......@@ -93,6 +97,7 @@ class FuchsiaCdm : public ContentDecryptionModule,
base::flat_map<std::string, std::unique_ptr<CdmSession>> session_map_;
fuchsia::media::drm::ContentDecryptionModulePtr cdm_;
ReadyCB ready_cb_;
SessionCallbacks session_callbacks_;
FuchsiaDecryptor decryptor_;
......
......@@ -43,7 +43,7 @@ void FuchsiaCdmFactory::Create(
}
fuchsia::media::drm::ContentDecryptionModulePtr cdm_ptr;
cdm_provider_->CreateCdmInterface(key_system, cdm_ptr.NewRequest());
auto cdm_request = cdm_ptr.NewRequest();
FuchsiaCdm::SessionCallbacks callbacks;
callbacks.message_cb = session_message_cb;
......@@ -51,10 +51,28 @@ void FuchsiaCdmFactory::Create(
callbacks.keys_change_cb = session_keys_change_cb;
callbacks.expiration_update_cb = session_expiration_update_cb;
auto cdm = base::MakeRefCounted<FuchsiaCdm>(std::move(cdm_ptr),
std::move(callbacks));
uint32_t creation_id = creation_id_++;
std::move(bound_cdm_created_cb).Run(std::move(cdm), "");
auto cdm = base::MakeRefCounted<FuchsiaCdm>(
std::move(cdm_ptr),
base::BindOnce(&FuchsiaCdmFactory::OnCdmReady, weak_factory_.GetWeakPtr(),
creation_id, std::move(bound_cdm_created_cb)),
std::move(callbacks));
cdm_provider_->CreateCdmInterface(key_system, std::move(cdm_request));
pending_cdms_.emplace(creation_id, std::move(cdm));
}
void FuchsiaCdmFactory::OnCdmReady(uint32_t creation_id,
CdmCreatedCB cdm_created_cb,
bool success,
const std::string& error_message) {
auto it = pending_cdms_.find(creation_id);
DCHECK(it != pending_cdms_.end());
scoped_refptr<ContentDecryptionModule> cdm = std::move(it->second);
pending_cdms_.erase(it);
std::move(cdm_created_cb)
.Run(success ? std::move(cdm) : nullptr, error_message);
}
} // namespace media
......@@ -5,10 +5,15 @@
#ifndef MEDIA_FUCHSIA_CDM_FUCHSIA_CDM_FACTORY_H_
#define MEDIA_FUCHSIA_CDM_FUCHSIA_CDM_FACTORY_H_
#include <stdint.h>
#include <memory>
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "media/base/cdm_factory.h"
#include "media/base/content_decryption_module.h"
#include "media/base/media_export.h"
#include "media/fuchsia/cdm/fuchsia_cdm_provider.h"
......@@ -30,7 +35,19 @@ class MEDIA_EXPORT FuchsiaCdmFactory : public CdmFactory {
CdmCreatedCB cdm_created_cb) final;
private:
void OnCdmReady(uint32_t creation_id,
CdmCreatedCB cdm_created_cb,
bool success,
const std::string& error_message);
std::unique_ptr<FuchsiaCdmProvider> cdm_provider_;
uint32_t creation_id_ = 0;
// Map between creation id and pending cdms
base::flat_map<uint32_t, scoped_refptr<ContentDecryptionModule>>
pending_cdms_;
base::WeakPtrFactory<FuchsiaCdmFactory> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(FuchsiaCdmFactory);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment