зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1059043 - Move MediaKeys.createSession into MediaKeySession as per spec - r=cpearce,smaug
This commit is contained in:
Родитель
0afabd88d4
Коммит
e18043e3ad
|
@ -56,6 +56,38 @@ CDMCallbackProxy::ResolveNewSessionPromise(uint32_t aPromiseId,
|
|||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
|
||||
class LoadSessionTask : public nsRunnable {
|
||||
public:
|
||||
LoadSessionTask(CDMProxy* aProxy,
|
||||
uint32_t aPromiseId,
|
||||
bool aSuccess)
|
||||
: mProxy(aProxy)
|
||||
, mPid(aPromiseId)
|
||||
, mSuccess(aSuccess)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
mProxy->OnResolveLoadSessionPromise(mPid, mSuccess);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<CDMProxy> mProxy;
|
||||
dom::PromiseId mPid;
|
||||
bool mSuccess;
|
||||
};
|
||||
|
||||
void
|
||||
CDMCallbackProxy::ResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess)
|
||||
{
|
||||
MOZ_ASSERT(mProxy->IsOnGMPThread());
|
||||
|
||||
nsRefPtr<nsIRunnable> task(new LoadSessionTask(mProxy,
|
||||
aPromiseId,
|
||||
aSuccess));
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
|
||||
void
|
||||
CDMCallbackProxy::ResolvePromise(uint32_t aPromiseId)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,9 @@ public:
|
|||
virtual void ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ResolveLoadSessionPromise(uint32_t aPromiseId,
|
||||
bool aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ResolvePromise(uint32_t aPromiseId) MOZ_OVERRIDE;
|
||||
|
||||
virtual void RejectPromise(uint32_t aPromiseId,
|
||||
|
@ -66,4 +69,4 @@ private:
|
|||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // CDMCallbackProxy_h_
|
||||
#endif // CDMCallbackProxy_h_
|
||||
|
|
|
@ -373,6 +373,16 @@ CDMProxy::OnResolveNewSessionPromise(uint32_t aPromiseId,
|
|||
mKeys->OnSessionCreated(aPromiseId, aSessionId);
|
||||
}
|
||||
|
||||
void
|
||||
CDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mKeys.IsNull()) {
|
||||
return;
|
||||
}
|
||||
mKeys->OnSessionLoaded(aPromiseId, aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
CDMProxy::OnSessionMessage(const nsAString& aSessionId,
|
||||
nsTArray<uint8_t>& aMessage,
|
||||
|
|
|
@ -108,6 +108,9 @@ public:
|
|||
void OnResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const nsAString& aSessionId);
|
||||
|
||||
// Main thread only.
|
||||
void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess);
|
||||
|
||||
// Main thread only.
|
||||
void OnSessionMessage(const nsAString& aSessionId,
|
||||
nsTArray<uint8_t>& aMessage,
|
||||
|
|
|
@ -39,6 +39,7 @@ MediaKeySession::MediaKeySession(nsPIDOMWindow* aParent,
|
|||
, mKeySystem(aKeySystem)
|
||||
, mSessionType(aSessionType)
|
||||
, mIsClosed(false)
|
||||
, mUninitialized(true)
|
||||
{
|
||||
MOZ_ASSERT(aParent);
|
||||
mClosed = mKeys->MakePromise(aRv);
|
||||
|
@ -95,6 +96,70 @@ MediaKeySession::Closed() const
|
|||
return mClosed;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
|
||||
const ArrayBufferViewOrArrayBuffer& aInitData,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise(mKeys->MakePromise(aRv));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mUninitialized) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
mUninitialized = false;
|
||||
|
||||
nsTArray<uint8_t> data;
|
||||
if (aInitDataType.IsEmpty() ||
|
||||
!CopyArrayBufferViewOrArrayBufferData(aInitData, data)) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
PromiseId pid = mKeys->StorePromise(promise);
|
||||
mKeys->OnSessionPending(pid, this);
|
||||
|
||||
mKeys->GetCDMProxy()->CreateSession(mSessionType,
|
||||
pid,
|
||||
aInitDataType, data);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeySession::Load(const nsAString& aSessionId, ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise(mKeys->MakePromise(aRv));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aSessionId.IsEmpty()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
// "The sessionId parameter is empty."
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (!mUninitialized) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
mUninitialized = false;
|
||||
|
||||
Init(aSessionId);
|
||||
auto pid = mKeys->StorePromise(promise);
|
||||
mKeys->OnSessionPending(pid, this);
|
||||
|
||||
mKeys->GetCDMProxy()->LoadSession(pid, aSessionId);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeySession::Update(const ArrayBufferViewOrArrayBuffer& aResponse, ErrorResult& aRv)
|
||||
{
|
||||
|
|
|
@ -63,6 +63,13 @@ public:
|
|||
|
||||
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);
|
||||
|
||||
|
@ -92,6 +99,7 @@ private:
|
|||
nsString mSessionId;
|
||||
const SessionType mSessionType;
|
||||
bool mIsClosed;
|
||||
bool mUninitialized;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -274,73 +274,25 @@ MediaKeys::OnCDMCreated(PromiseId aId)
|
|||
}
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeys::LoadSession(const nsAString& aSessionId, ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise(MakePromise(aRv));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aSessionId.IsEmpty()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
// "The sessionId parameter is empty."
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// TODO: The spec doesn't specify what to do in this case...
|
||||
if (mKeySessions.Contains(aSessionId)) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// Create session.
|
||||
nsRefPtr<MediaKeySession> session(
|
||||
new MediaKeySession(GetParentObject(), this, mKeySystem, SessionType::Persistent, aRv));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
session->Init(aSessionId);
|
||||
auto pid = StorePromise(promise);
|
||||
mPendingSessions.Put(pid, session);
|
||||
mProxy->LoadSession(pid, aSessionId);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeys::CreateSession(const nsAString& initDataType,
|
||||
const ArrayBufferViewOrArrayBuffer& aInitData,
|
||||
SessionType aSessionType,
|
||||
already_AddRefed<MediaKeySession>
|
||||
MediaKeys::CreateSession(SessionType aSessionType,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise(MakePromise(aRv));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> data;
|
||||
if (initDataType.IsEmpty() ||
|
||||
!CopyArrayBufferViewOrArrayBufferData(aInitData, data)) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsRefPtr<MediaKeySession> session = new MediaKeySession(GetParentObject(),
|
||||
this,
|
||||
mKeySystem,
|
||||
aSessionType,
|
||||
aRv);
|
||||
auto pid = StorePromise(promise);
|
||||
// Hang onto session until the CDM has finished setting it up.
|
||||
mPendingSessions.Put(pid, session);
|
||||
mProxy->CreateSession(aSessionType,
|
||||
pid,
|
||||
initDataType,
|
||||
data);
|
||||
|
||||
return promise.forget();
|
||||
return session.forget();
|
||||
}
|
||||
|
||||
void
|
||||
MediaKeys::OnSessionPending(PromiseId aId, MediaKeySession* aSession)
|
||||
{
|
||||
MOZ_ASSERT(mPromises.Contains(aId));
|
||||
MOZ_ASSERT(!mPendingSessions.Contains(aId));
|
||||
mPendingSessions.Put(aId, aSession);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -370,6 +322,35 @@ MediaKeys::OnSessionCreated(PromiseId aId, const nsAString& aSessionId)
|
|||
promise->MaybeResolve(session);
|
||||
}
|
||||
|
||||
void
|
||||
MediaKeys::OnSessionLoaded(PromiseId aId, bool aSuccess)
|
||||
{
|
||||
nsRefPtr<Promise> promise(RetrievePromise(aId));
|
||||
if (!promise) {
|
||||
NS_WARNING("MediaKeys tried to resolve a non-existent promise");
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mPendingSessions.Contains(aId));
|
||||
|
||||
nsRefPtr<MediaKeySession> session;
|
||||
bool gotSession = mPendingSessions.Get(aId, getter_AddRefs(session));
|
||||
// Session has completed creation/loading, remove it from mPendingSessions,
|
||||
// and resolve the promise with it. We store it in mKeySessions, so we can
|
||||
// find it again if we need to send messages to it etc.
|
||||
mPendingSessions.Remove(aId);
|
||||
if (!gotSession || !session) {
|
||||
NS_WARNING("Received activation for non-existent session!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!session->GetSessionId().IsEmpty() &&
|
||||
!mKeySessions.Contains(session->GetSessionId()));
|
||||
|
||||
mKeySessions.Put(session->GetSessionId(), session);
|
||||
promise->MaybeResolve(aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
MediaKeys::OnSessionClosed(MediaKeySession* aSession)
|
||||
{
|
||||
|
|
|
@ -59,14 +59,8 @@ public:
|
|||
void GetKeySystem(nsString& retval) const;
|
||||
|
||||
// JavaScript: MediaKeys.createSession()
|
||||
already_AddRefed<Promise> CreateSession(const nsAString& aInitDataType,
|
||||
const ArrayBufferViewOrArrayBuffer& aInitData,
|
||||
SessionType aSessionType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// JavaScript: MediaKeys.loadSession()
|
||||
already_AddRefed<Promise> LoadSession(const nsAString& aSessionId,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<MediaKeySession> CreateSession(SessionType aSessionType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// JavaScript: MediaKeys.SetServerCertificate()
|
||||
already_AddRefed<Promise> SetServerCertificate(const ArrayBufferViewOrArrayBuffer& aServerCertificate,
|
||||
|
@ -89,8 +83,13 @@ public:
|
|||
|
||||
// Called once a Create() operation succeeds.
|
||||
void OnCDMCreated(PromiseId aId);
|
||||
// Called once a CreateSession or LoadSession succeeds.
|
||||
// Called when GenerateRequest or Load have been called on a MediaKeySession
|
||||
// and we are waiting for its initialisation to finish.
|
||||
void OnSessionPending(PromiseId aId, MediaKeySession* aSession);
|
||||
// Called once a CreateSession succeeds.
|
||||
void OnSessionCreated(PromiseId aId, const nsAString& aSessionId);
|
||||
// Called once a LoadSession succeeds.
|
||||
void OnSessionLoaded(PromiseId aId, bool aSuccess);
|
||||
// Called once a session has closed.
|
||||
void OnSessionClosed(MediaKeySession* aSession);
|
||||
|
||||
|
|
|
@ -53,6 +53,13 @@ GMPDecryptorChild::ResolveNewSessionPromise(uint32_t aPromiseId,
|
|||
aPromiseId, nsAutoCString(aSessionId, aSessionIdLength));
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::ResolveLoadSessionPromise(uint32_t aPromiseId,
|
||||
bool aSuccess)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendResolveLoadSessionPromise, aPromiseId, aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::ResolvePromise(uint32_t aPromiseId)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,8 @@ public:
|
|||
virtual void ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) MOZ_OVERRIDE;
|
||||
virtual void ResolveLoadSessionPromise(uint32_t aPromiseId,
|
||||
bool aSuccess) MOZ_OVERRIDE;
|
||||
virtual void ResolvePromise(uint32_t aPromiseId) MOZ_OVERRIDE;
|
||||
|
||||
virtual void RejectPromise(uint32_t aPromiseId,
|
||||
|
|
|
@ -152,6 +152,18 @@ GMPDecryptorParent::RecvResolveNewSessionPromise(const uint32_t& aPromiseId,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvResolveLoadSessionPromise(const uint32_t& aPromiseId,
|
||||
const bool& aSuccess)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->ResolveLoadSessionPromise(aPromiseId, aSuccess);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvResolvePromise(const uint32_t& aPromiseId)
|
||||
{
|
||||
|
|
|
@ -67,6 +67,9 @@ private:
|
|||
virtual bool RecvResolveNewSessionPromise(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvResolveLoadSessionPromise(const uint32_t& aPromiseId,
|
||||
const bool& aSuccess) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvResolvePromise(const uint32_t& aPromiseId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvRejectPromise(const uint32_t& aPromiseId,
|
||||
|
|
|
@ -20,6 +20,9 @@ public:
|
|||
virtual void ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
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,
|
||||
|
|
|
@ -53,6 +53,9 @@ parent:
|
|||
ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
nsCString aSessionId);
|
||||
|
||||
ResolveLoadSessionPromise(uint32_t aPromiseId,
|
||||
bool aSuccess);
|
||||
|
||||
ResolvePromise(uint32_t aPromiseId);
|
||||
|
||||
RejectPromise(uint32_t aPromiseId,
|
||||
|
|
|
@ -94,7 +94,7 @@ typedef int64_t GMPTimestamp;
|
|||
// Callbacks to be called from the CDM. Threadsafe.
|
||||
class GMPDecryptorCallback {
|
||||
public:
|
||||
// Resolves a promise for a session created or loaded.
|
||||
// Resolves a promise for a session created.
|
||||
// Passes the session id to be exposed to JavaScript.
|
||||
// Must be called before SessionMessage().
|
||||
// aSessionId must be null terminated.
|
||||
|
@ -102,6 +102,13 @@ public:
|
|||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
|
||||
// Resolves a promise for a session loaded.
|
||||
// Resolves to false if we don't have any session data stored for the given
|
||||
// session ID.
|
||||
// Must be called before SessionMessage().
|
||||
virtual void ResolveLoadSessionPromise(uint32_t aPromiseId,
|
||||
bool aSuccess) = 0;
|
||||
|
||||
// Called to resolve a specified promise with "undefined".
|
||||
virtual void ResolvePromise(uint32_t aPromiseId) = 0;
|
||||
|
||||
|
|
|
@ -24,6 +24,12 @@ interface MediaKeySession : EventTarget {
|
|||
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
|
||||
readonly attribute Promise<void> closed;
|
||||
|
||||
[NewObject, Throws]
|
||||
Promise<void> generateRequest(DOMString initDataType, (ArrayBufferView or ArrayBuffer) initData);
|
||||
|
||||
[NewObject, Throws]
|
||||
Promise<boolean> load(DOMString sessionId);
|
||||
|
||||
// session operations
|
||||
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
|
||||
[NewObject, Throws]
|
||||
|
|
|
@ -18,10 +18,7 @@ interface MediaKeys {
|
|||
readonly attribute DOMString keySystem;
|
||||
|
||||
[NewObject, Throws]
|
||||
Promise<MediaKeySession> createSession(DOMString initDataType, (ArrayBufferView or ArrayBuffer) initData, optional SessionType sessionType = "temporary");
|
||||
|
||||
[NewObject, Throws]
|
||||
Promise<MediaKeySession> loadSession(DOMString sessionId);
|
||||
MediaKeySession createSession(optional SessionType sessionType = "temporary");
|
||||
|
||||
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
|
||||
[NewObject, Throws]
|
||||
|
|
|
@ -169,8 +169,8 @@ ClearKeyDecryptionManager::LoadSession(uint32_t aPromiseId,
|
|||
uint32_t aSessionIdLength)
|
||||
{
|
||||
// TODO implement "persistent" sessions.
|
||||
mCallback->RejectPromise(aPromiseId, kGMPNotSupportedError,
|
||||
nullptr /* message */, 0 /* messageLen */);
|
||||
mCallback->ResolveLoadSessionPromise(aPromiseId, false);
|
||||
|
||||
CK_LOGD("ClearKeyDecryptionManager::LoadSession");
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче