Commit bf166056 authored by yucliu's avatar yucliu Committed by Commit Bot

[Clank] Load origin id before create MediaDrmBridge

Async Create MediaDrmBridge. When persistent license support is enabled,
we need to load origin id from persistent storage before create
MediaDrmStorage.

BUG=493521
TEST=Test page, MediaDrmBridgeTest

Review-Url: https://codereview.chromium.org/2823513002
Cr-Commit-Position: refs/heads/master@{#488784}
parent 7a2ac6c7
......@@ -94,19 +94,24 @@ void MediaDrmCredentialManager::ResetCredentialsInternal(
base::Bind(&content::CreateProvisionFetcher,
g_browser_process->system_request_context());
ResetCredentialsCB reset_credentials_cb =
base::Bind(&MediaDrmCredentialManager::OnResetCredentialsCompleted,
base::Unretained(this), security_level);
media_drm_bridge_ = media::MediaDrmBridge::CreateWithoutSessionSupport(
kWidevineKeySystem, security_level, create_fetcher_cb);
media::MediaDrmBridge::CreateWithoutSessionSupport(
kWidevineKeySystem, security_level, create_fetcher_cb,
base::BindOnce(
&MediaDrmCredentialManager::OnMediaDrmCreated, base::Unretained(this),
base::Bind(&MediaDrmCredentialManager::OnResetCredentialsCompleted,
base::Unretained(this), security_level)));
}
void MediaDrmCredentialManager::OnMediaDrmCreated(
const ResetCredentialsCB& reset_credentials_cb,
scoped_refptr<media::MediaDrmBridge> cdm) {
// No need to reset credentials for unsupported |security_level|.
if (!media_drm_bridge_) {
if (!cdm) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(reset_credentials_cb, true));
return;
}
media_drm_bridge_ = std::move(cdm);
media_drm_bridge_->ResetDeviceCredentials(reset_credentials_cb);
}
......@@ -53,6 +53,9 @@ class MediaDrmCredentialManager {
// returned asynchronously in OnResetCredentialsCompleted() function.
void ResetCredentialsInternal(SecurityLevel security_level);
void OnMediaDrmCreated(const ResetCredentialsCB& reset_credentials_cb,
scoped_refptr<media::MediaDrmBridge> media_drm_bridge);
// The MediaDrmBridge object used to perform the credential reset.
scoped_refptr<media::MediaDrmBridge> media_drm_bridge_;
......
......@@ -18,6 +18,24 @@
#include "url/gurl.h"
namespace media {
namespace {
void OnCdmCreated(const std::string& key_system,
MediaDrmBridge::SecurityLevel security_level,
const CdmCreatedCB& bound_cdm_created_cb,
scoped_refptr<MediaDrmBridge> cdm) {
if (!cdm) {
std::string error_message = "MediaDrmBridge cannot be created for " +
key_system + " with security level " +
base::IntToString(security_level);
LOG(ERROR) << error_message;
bound_cdm_created_cb.Run(nullptr, error_message);
return;
}
// Success!
bound_cdm_created_cb.Run(cdm, "");
}
} // namespace
AndroidCdmFactory::AndroidCdmFactory(const CreateFetcherCB& create_fetcher_cb,
const CreateStorageCB& create_storage_cb)
......@@ -80,20 +98,12 @@ void AndroidCdmFactory::Create(
return;
}
scoped_refptr<MediaDrmBridge> cdm(MediaDrmBridge::Create(
key_system, security_origin, security_level, create_fetcher_cb_,
create_storage_cb_, session_message_cb, session_closed_cb,
session_keys_change_cb, session_expiration_update_cb));
if (!cdm) {
error_message = "MediaDrmBridge cannot be created for " + key_system +
" with security level " + base::IntToString(security_level);
LOG(ERROR) << error_message;
bound_cdm_created_cb.Run(nullptr, error_message);
return;
}
// Success!
bound_cdm_created_cb.Run(cdm, "");
MediaDrmBridge::Create(key_system, security_origin, security_level,
create_fetcher_cb_, create_storage_cb_,
session_message_cb, session_closed_cb,
session_keys_change_cb, session_expiration_update_cb,
base::BindOnce(&OnCdmCreated, key_system,
security_level, bound_cdm_created_cb));
}
} // namespace media
......@@ -319,36 +319,35 @@ std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() {
}
// static
scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal(
const std::string& key_system,
const GURL& security_origin,
void MediaDrmBridge::CreateInternal(
const std::vector<uint8_t>& scheme_uuid,
SecurityLevel security_level,
std::unique_ptr<MediaDrmStorageBridge> storage,
const CreateFetcherCB& create_fetcher_cb,
const CreateStorageCB& create_storage_cb,
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb) {
const SessionExpirationUpdateCB& session_expiration_update_cb,
CreatedCB created_cb) {
// All paths requires the MediaDrmApis.
DCHECK(AreMediaDrmApisAvailable());
UUID scheme_uuid = GetKeySystemManager()->GetUUID(key_system);
if (scheme_uuid.empty())
return nullptr;
DCHECK(!scheme_uuid.empty());
scoped_refptr<MediaDrmBridge> media_drm_bridge(new MediaDrmBridge(
scheme_uuid, security_origin, security_level, create_fetcher_cb,
create_storage_cb, session_message_cb, session_closed_cb,
session_keys_change_cb, session_expiration_update_cb));
scheme_uuid, security_level, std::move(storage), create_fetcher_cb,
session_message_cb, session_closed_cb, session_keys_change_cb,
session_expiration_update_cb));
if (media_drm_bridge->j_media_drm_.is_null())
media_drm_bridge = nullptr;
return media_drm_bridge;
// Return |media_drm_bridge| asynchronously to make the callback binding
// easier.
std::move(created_cb).Run(std::move(media_drm_bridge));
}
// static
scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
void MediaDrmBridge::Create(
const std::string& key_system,
const GURL& security_origin,
SecurityLevel security_level,
......@@ -357,33 +356,59 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb) {
const SessionExpirationUpdateCB& session_expiration_update_cb,
CreatedCB created_cb) {
DVLOG(1) << __func__;
if (!IsAvailable())
return nullptr;
if (!IsAvailable()) {
std::move(created_cb).Run(nullptr);
return;
}
UUID scheme_uuid = GetKeySystemManager()->GetUUID(key_system);
if (scheme_uuid.empty()) {
std::move(created_cb).Run(nullptr);
return;
}
// MediaDrmStorage may be lazy created in MediaDrmStorageBridge.
auto storage = base::MakeUnique<MediaDrmStorageBridge>();
MediaDrmStorageBridge* raw_storage = storage.get();
return CreateInternal(key_system, security_origin, security_level,
create_fetcher_cb, create_storage_cb,
session_message_cb, session_closed_cb,
session_keys_change_cb, session_expiration_update_cb);
base::OnceClosure create_media_drm_cb = base::BindOnce(
&MediaDrmBridge::CreateInternal, scheme_uuid, security_level,
base::Passed(&storage), create_fetcher_cb, session_message_cb,
session_closed_cb, session_keys_change_cb, session_expiration_update_cb,
base::Passed(&created_cb));
if (IsPersistentLicenseTypeSupported(key_system) &&
!security_origin.is_empty() && !create_storage_cb.is_null()) {
raw_storage->Initialize(url::Origin(security_origin), create_storage_cb,
std::move(create_media_drm_cb));
} else {
std::move(create_media_drm_cb).Run();
}
}
// static
scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport(
void MediaDrmBridge::CreateWithoutSessionSupport(
const std::string& key_system,
SecurityLevel security_level,
const CreateFetcherCB& create_fetcher_cb) {
const CreateFetcherCB& create_fetcher_cb,
CreatedCB created_cb) {
DVLOG(1) << __func__;
// Sessions won't be used so decoding capability is not required.
if (!AreMediaDrmApisAvailable())
return nullptr;
if (!AreMediaDrmApisAvailable()) {
std::move(created_cb).Run(nullptr);
return;
}
return MediaDrmBridge::Create(
key_system, GURL::EmptyGURL(), security_level, create_fetcher_cb,
CreateStorageCB(), SessionMessageCB(), SessionClosedCB(),
SessionKeysChangeCB(), SessionExpirationUpdateCB());
MediaDrmBridge::Create(key_system, GURL::EmptyGURL(), security_level,
create_fetcher_cb, CreateStorageCB(),
SessionMessageCB(), SessionClosedCB(),
SessionKeysChangeCB(), SessionExpirationUpdateCB(),
std::move(created_cb));
}
void MediaDrmBridge::SetServerCertificate(
......@@ -801,16 +826,15 @@ void MediaDrmBridge::OnResetDeviceCredentialsCompleted(
MediaDrmBridge::MediaDrmBridge(
const std::vector<uint8_t>& scheme_uuid,
const GURL& security_origin,
SecurityLevel security_level,
std::unique_ptr<MediaDrmStorageBridge> storage,
const CreateFetcherCB& create_fetcher_cb,
const CreateStorageCB& create_storage_cb,
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb)
: scheme_uuid_(scheme_uuid),
storage_(url::Origin(security_origin), create_storage_cb),
storage_(std::move(storage)),
create_fetcher_cb_(create_fetcher_cb),
session_message_cb_(session_message_cb),
session_closed_cb_(session_closed_cb),
......@@ -821,7 +845,8 @@ MediaDrmBridge::MediaDrmBridge(
weak_factory_(this) {
DVLOG(1) << __func__;
DCHECK(!create_fetcher_cb_.is_null());
DCHECK(storage_);
DCHECK(create_fetcher_cb_);
JNIEnv* env = AttachCurrentThread();
CHECK(env);
......@@ -838,13 +863,16 @@ MediaDrmBridge::MediaDrmBridge(
// supported and check if origin is valid.
base::FeatureList::IsEnabled(kMediaDrmPersistentLicense) &&
// MediaDrm implements origin isolated storage on M.
base::android::BuildInfo::GetInstance()->sdk_int() >= 23;
base::android::BuildInfo::GetInstance()->sdk_int() >= 23 &&
// origin id can be empty when MediaDrmBridge is created by
// CreateWithoutSessionSupport, which is used to reset credentials.
!storage_->origin_id().empty();
// TODO(yucliu): Per EME spec on individualization, implementation should not
// expose application-specific information. Considering encode origin before
// passing to MediaDrm.
ScopedJavaLocalRef<jstring> j_security_origin = ConvertUTF8ToJavaString(
env, use_origin_isolated_storage ? security_origin.spec() : "");
env, use_origin_isolated_storage ? storage_->origin_id() : "");
// TODO(yucliu): Use |create_storage_cb_| to create MediaDrmStorage which can
// be used by Java side to store/retrieve persistent data. This should only
......@@ -853,7 +881,8 @@ MediaDrmBridge::MediaDrmBridge(
// Note: OnMediaCryptoReady() could be called in this call.
j_media_drm_.Reset(Java_MediaDrmBridge_create(
env, j_scheme_uuid, j_security_origin, j_security_level,
reinterpret_cast<intptr_t>(this), reinterpret_cast<intptr_t>(&storage_)));
reinterpret_cast<intptr_t>(this),
reinterpret_cast<intptr_t>(storage_.get())));
}
MediaDrmBridge::~MediaDrmBridge() {
......
......@@ -68,6 +68,8 @@ class MEDIA_EXPORT MediaDrmBridge : public ContentDecryptionModule,
base::Callback<void(JavaObjectPtr media_crypto,
bool requires_secure_video_codec)>;
using CreatedCB = base::OnceCallback<void(scoped_refptr<MediaDrmBridge>)>;
// Checks whether MediaDRM is available and usable, including for decoding.
// All other static methods check IsAvailable() or equivalent internally.
// There is no need to check IsAvailable() explicitly before calling them.
......@@ -93,7 +95,7 @@ class MEDIA_EXPORT MediaDrmBridge : public ContentDecryptionModule,
// Returns a MediaDrmBridge instance if |key_system| and |security_level| are
// supported, and nullptr otherwise. The default security level will be used
// if |security_level| is SECURITY_LEVEL_DEFAULT.
static scoped_refptr<MediaDrmBridge> Create(
static void Create(
const std::string& key_system,
const GURL& security_origin,
SecurityLevel security_level,
......@@ -102,16 +104,18 @@ class MEDIA_EXPORT MediaDrmBridge : public ContentDecryptionModule,
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb);
const SessionExpirationUpdateCB& session_expiration_update_cb,
CreatedCB created_cb);
// Same as Create() except that no session callbacks are provided. This is
// used when we need to use MediaDrmBridge without creating any sessions.
// TODO(yucliu): Pass |security_origin| here to clear per-origin certs and
// licenses.
static scoped_refptr<MediaDrmBridge> CreateWithoutSessionSupport(
static void CreateWithoutSessionSupport(
const std::string& key_system,
SecurityLevel security_level,
const CreateFetcherCB& create_fetcher_cb);
const CreateFetcherCB& create_fetcher_cb,
CreatedCB created_cb);
// ContentDecryptionModule implementation.
void SetServerCertificate(
......@@ -246,26 +250,25 @@ class MEDIA_EXPORT MediaDrmBridge : public ContentDecryptionModule,
// For DeleteSoon() in DeleteOnCorrectThread().
friend class base::DeleteHelper<MediaDrmBridge>;
static scoped_refptr<MediaDrmBridge> CreateInternal(
const std::string& key_system,
const GURL& security_origin,
static void CreateInternal(
const std::vector<uint8_t>& scheme_uuid,
SecurityLevel security_level,
std::unique_ptr<MediaDrmStorageBridge> storage,
const CreateFetcherCB& create_fetcher_cb,
const CreateStorageCB& create_storage_cb,
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb);
const SessionExpirationUpdateCB& session_expiration_update_cb,
CreatedCB bound_cdm_created_cb);
// Constructs a MediaDrmBridge for |scheme_uuid| and |security_level|. The
// default security level will be used if |security_level| is
// SECURITY_LEVEL_DEFAULT. Sessions should not be created if session callbacks
// are null.
MediaDrmBridge(const std::vector<uint8_t>& scheme_uuid,
const GURL& security_origin,
SecurityLevel security_level,
std::unique_ptr<MediaDrmStorageBridge> storage,
const CreateFetcherCB& create_fetcher_cb,
const CreateStorageCB& create_storage_cb,
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
......@@ -293,7 +296,7 @@ class MEDIA_EXPORT MediaDrmBridge : public ContentDecryptionModule,
std::vector<uint8_t> scheme_uuid_;
// Persistent storage for session ID map.
MediaDrmStorageBridge storage_;
std::unique_ptr<MediaDrmStorageBridge> storage_;
// Java MediaDrm instance.
base::android::ScopedJavaGlobalRef<jobject> j_media_drm_;
......
......@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "media/base/android/media_drm_bridge.h"
#include "media/base/provision_fetcher.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -60,6 +61,15 @@ class MockProvisionFetcher : public ProvisionFetcher {
const ResponseCB& response_cb) override {}
};
void CheckMediaDrmBridge(bool expect_success,
scoped_refptr<MediaDrmBridge> media_drm_bridge) {
if (expect_success) {
EXPECT_TRUE_IF_WIDEVINE_AVAILABLE(media_drm_bridge);
} else {
EXPECT_FALSE(media_drm_bridge);
}
}
} // namespace (anonymous)
TEST(MediaDrmBridgeTest, IsKeySystemSupported_Widevine) {
......@@ -98,15 +108,21 @@ TEST(MediaDrmBridgeTest, IsKeySystemSupported_InvalidKeySystem) {
TEST(MediaDrmBridgeTest, CreateWithoutSessionSupport_Widevine) {
base::MessageLoop message_loop_;
EXPECT_TRUE_IF_WIDEVINE_AVAILABLE(MediaDrmBridge::CreateWithoutSessionSupport(
kWidevineKeySystem, kDefault, base::Bind(&MockProvisionFetcher::Create)));
MediaDrmBridge::CreateWithoutSessionSupport(
kWidevineKeySystem, kDefault, base::Bind(&MockProvisionFetcher::Create),
base::BindOnce(&CheckMediaDrmBridge, true));
base::RunLoop().RunUntilIdle();
}
// Invalid key system is NOT supported regardless whether MediaDrm is available.
TEST(MediaDrmBridgeTest, CreateWithoutSessionSupport_InvalidKeySystem) {
base::MessageLoop message_loop_;
EXPECT_FALSE(MediaDrmBridge::CreateWithoutSessionSupport(
kInvalidKeySystem, kDefault, base::Bind(&MockProvisionFetcher::Create)));
MediaDrmBridge::CreateWithoutSessionSupport(
kInvalidKeySystem, kDefault, base::Bind(&MockProvisionFetcher::Create),
base::BindOnce(&CheckMediaDrmBridge, false));
base::RunLoop().RunUntilIdle();
}
TEST(MediaDrmBridgeTest, CreateWithSecurityLevel_Widevine) {
......@@ -114,11 +130,15 @@ TEST(MediaDrmBridgeTest, CreateWithSecurityLevel_Widevine) {
// We test "L3" fully. But for "L1" we don't check the result as it depends on
// whether the test device supports "L1".
EXPECT_TRUE_IF_WIDEVINE_AVAILABLE(MediaDrmBridge::CreateWithoutSessionSupport(
kWidevineKeySystem, kL3, base::Bind(&MockProvisionFetcher::Create)));
MediaDrmBridge::CreateWithoutSessionSupport(
kWidevineKeySystem, kL3, base::Bind(&MockProvisionFetcher::Create),
base::BindOnce(&CheckMediaDrmBridge, true));
MediaDrmBridge::CreateWithoutSessionSupport(
kWidevineKeySystem, kL1, base::Bind(&MockProvisionFetcher::Create));
kWidevineKeySystem, kL1, base::Bind(&MockProvisionFetcher::Create),
base::BindOnce([](scoped_refptr<MediaDrmBridge>) {}));
base::RunLoop().RunUntilIdle();
}
} // namespace media
......@@ -33,25 +33,35 @@ bool MediaDrmStorageBridge::RegisterMediaDrmStorageBridge(JNIEnv* env) {
return RegisterNativesImpl(env);
}
MediaDrmStorageBridge::MediaDrmStorageBridge(
const url::Origin& origin,
const CreateStorageCB& create_storage_cb)
: create_storage_cb_(create_storage_cb),
origin_(origin),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
weak_factory_(this) {}
MediaDrmStorageBridge::MediaDrmStorageBridge()
: task_runner_(base::ThreadTaskRunnerHandle::Get()), weak_factory_(this) {}
MediaDrmStorageBridge::~MediaDrmStorageBridge() = default;
void MediaDrmStorageBridge::Initialize(const url::Origin& origin,
const CreateStorageCB& create_storage_cb,
base::OnceClosure on_init) {
DCHECK(create_storage_cb);
impl_ = create_storage_cb.Run();
// TODO(yucliu): MediaDrmStorage should generate and return origin id
// asynchronously in a callback.
impl_->Initialize(origin);
origin_id_ = origin.Serialize();
std::move(on_init).Run();
}
void MediaDrmStorageBridge::OnProvisioned(
JNIEnv* env,
const JavaParamRef<jobject>& j_storage,
// Callback<Boolean>
const JavaParamRef<jobject>& j_callback) {
DCHECK(impl_);
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&MediaDrmStorage::OnProvisioned, GetStorageImpl()->AsWeakPtr(),
&MediaDrmStorage::OnProvisioned, impl_->AsWeakPtr(),
base::BindOnce(&MediaDrmStorageBridge::RunAndroidBoolCallback,
// Bind callback to WeakPtr in case callback is called
// after object is deleted.
......@@ -65,12 +75,13 @@ void MediaDrmStorageBridge::OnLoadInfo(
const JavaParamRef<jbyteArray>& j_session_id,
// Callback<PersistentInfo>
const JavaParamRef<jobject>& j_callback) {
DCHECK(impl_);
std::string session_id = JavaBytesToString(env, j_session_id);
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&MediaDrmStorage::LoadPersistentSession,
GetStorageImpl()->AsWeakPtr(), session_id,
&MediaDrmStorage::LoadPersistentSession, impl_->AsWeakPtr(),
session_id,
base::BindOnce(&MediaDrmStorageBridge::OnSessionDataLoaded,
weak_factory_.GetWeakPtr(),
base::Passed(CreateJavaObjectPtr(j_callback.obj())),
......@@ -83,6 +94,7 @@ void MediaDrmStorageBridge::OnSaveInfo(
const JavaParamRef<jobject>& j_persist_info,
// Callback<Boolean>
const JavaParamRef<jobject>& j_callback) {
DCHECK(impl_);
std::vector<uint8_t> key_set_id;
JavaByteArrayToByteVector(
env, Java_PersistentInfo_keySetId(env, j_persist_info.obj()).obj(),
......@@ -97,8 +109,8 @@ void MediaDrmStorageBridge::OnSaveInfo(
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&MediaDrmStorage::SavePersistentSession,
GetStorageImpl()->AsWeakPtr(), session_id,
&MediaDrmStorage::SavePersistentSession, impl_->AsWeakPtr(),
session_id,
MediaDrmStorage::SessionData(std::move(key_set_id), std::move(mime)),
base::BindOnce(&MediaDrmStorageBridge::RunAndroidBoolCallback,
weak_factory_.GetWeakPtr(),
......@@ -111,11 +123,12 @@ void MediaDrmStorageBridge::OnClearInfo(
const JavaParamRef<jbyteArray>& j_session_id,
// Callback<Boolean>
const JavaParamRef<jobject>& j_callback) {
DCHECK(impl_);
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&MediaDrmStorage::RemovePersistentSession,
GetStorageImpl()->AsWeakPtr(), JavaBytesToString(env, j_session_id),
&MediaDrmStorage::RemovePersistentSession, impl_->AsWeakPtr(),
JavaBytesToString(env, j_session_id),
base::BindOnce(&MediaDrmStorageBridge::RunAndroidBoolCallback,
weak_factory_.GetWeakPtr(),
base::Passed(CreateJavaObjectPtr(j_callback.obj())))));
......@@ -146,14 +159,4 @@ void MediaDrmStorageBridge::OnSessionDataLoaded(
env, j_eme_id, j_key_set_id, j_mime));
}
MediaDrmStorage* MediaDrmStorageBridge::GetStorageImpl() {
if (!impl_) {
DCHECK(create_storage_cb_);
impl_ = std::move(create_storage_cb_).Run();
impl_->Initialize(origin_);
}
return impl_.get();
}
} // namespace media
......@@ -29,10 +29,18 @@ class MediaDrmStorageBridge {
public:
static bool RegisterMediaDrmStorageBridge(JNIEnv* env);
MediaDrmStorageBridge(const url::Origin& origin,
const CreateStorageCB& create_storage_cb);
MediaDrmStorageBridge();
~MediaDrmStorageBridge();
// Bind origin to |this|. Once storage is initialized, |on_init| will be
// called and it will have a random generated origin id for later usage. If
// this function isn't called, all the other functions will fail.
void Initialize(const url::Origin& origin,
const CreateStorageCB& create_storage_cb,
base::OnceClosure init_cb);
std::string origin_id() const { return origin_id_; }
// The following OnXXX functions are called by Java. The functions will post
// task on message loop immediately to avoid reentrancy issues.
......@@ -73,12 +81,10 @@ class MediaDrmStorageBridge {
const std::string& session_id,
std::unique_ptr<MediaDrmStorage::SessionData> session_data);
MediaDrmStorage* GetStorageImpl();
CreateStorageCB create_storage_cb_;
std::unique_ptr<MediaDrmStorage> impl_;
const url::Origin origin_;
// Randomly generated ID for origin.
std::string origin_id_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
......
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