Diff
Modified: trunk/Source/WebCore/ChangeLog (220904 => 220905)
--- trunk/Source/WebCore/ChangeLog 2017-08-18 07:27:34 UTC (rev 220904)
+++ trunk/Source/WebCore/ChangeLog 2017-08-18 07:45:49 UTC (rev 220905)
@@ -1,3 +1,50 @@
+2017-08-18 Zan Dobersek <zdober...@igalia.com>
+
+ [EME] MediaKeySession has to initiate playback resume on HTMLMediaElement
+ https://bugs.webkit.org/show_bug.cgi?id=175671
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ In MediaKeySession::updateKeyStatuses(), HTMLMediaElement objects that are
+ associated with the MediaKeys instance that created this session have to
+ be notified in order to run the 'Attempt to Resume Playback If Necessary'
+ algorithm.
+
+ MediaKeys object now tracks the sessions that were created through it.
+ MediaKeySession object is passed a MediaKeys reference, and has that
+ reference invalidated if/when the MediaKeys object is destroyed.
+
+ In MediaKeySession::updateKeyStatuses(), a task is now queued, notifying
+ the MediaKeys object, if any, that the associated HTMLMediaElement
+ instances have to run the mentioned algorithm. The associated media
+ elements are stored through CDMClient pointers, with HTMLMediaElement
+ class inheriting from the newly-introduced CDMClient interface.
+
+ HTMLMediaElement::cdmClientAttemptToResumePlaybackIfNecessary() is left
+ unimplemented for now. The object will attach itself to and detach from
+ the associated MediaKeys object in setMediaKeys() and the destructor,
+ enabling the MediaKeys object to properly dispatch the playback resume
+ requests for the attached clients.
+
+ * Modules/encryptedmedia/CDMClient.h: Copied from Source/WebCore/Modules/encryptedmedia/MediaKeys.h.
+ (WebCore::CDMClient::~CDMClient):
+ * Modules/encryptedmedia/MediaKeySession.cpp:
+ (WebCore::MediaKeySession::create):
+ (WebCore::MediaKeySession::MediaKeySession):
+ (WebCore::MediaKeySession::detachKeys):
+ (WebCore::MediaKeySession::updateKeyStatuses):
+ * Modules/encryptedmedia/MediaKeySession.h:
+ * Modules/encryptedmedia/MediaKeys.cpp:
+ (WebCore::MediaKeys::~MediaKeys):
+ (WebCore::MediaKeys::createSession):
+ (WebCore::MediaKeys::attachCDMClient):
+ (WebCore::MediaKeys::detachCDMClient):
+ (WebCore::MediaKeys::attemptToResumePlaybackOnClients):
+ * Modules/encryptedmedia/MediaKeys.h:
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::cdmClientAttemptToResumePlaybackIfNecessary):
+ * html/HTMLMediaElement.h:
+
2017-08-18 Commit Queue <commit-qu...@webkit.org>
Unreviewed, rolling out r220854.
Added: trunk/Source/WebCore/Modules/encryptedmedia/CDMClient.h (0 => 220905)
--- trunk/Source/WebCore/Modules/encryptedmedia/CDMClient.h (rev 0)
+++ trunk/Source/WebCore/Modules/encryptedmedia/CDMClient.h 2017-08-18 07:45:49 UTC (rev 220905)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 Metrological Group B.V.
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(ENCRYPTED_MEDIA)
+
+namespace WebCore {
+
+class CDMInstance;
+
+class CDMClient {
+public:
+ virtual ~CDMClient() { }
+
+ virtual void cdmClientAttemptToResumePlaybackIfNecessary() = 0;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(ENCRYPTED_MEDIA)
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp (220904 => 220905)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp 2017-08-18 07:27:34 UTC (rev 220904)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp 2017-08-18 07:45:49 UTC (rev 220905)
@@ -38,6 +38,7 @@
#include "MediaKeyMessageEvent.h"
#include "MediaKeyMessageType.h"
#include "MediaKeyStatusMap.h"
+#include "MediaKeys.h"
#include "NotImplemented.h"
#include "SecurityOrigin.h"
#include "SharedBuffer.h"
@@ -44,15 +45,16 @@
namespace WebCore {
-Ref<MediaKeySession> MediaKeySession::create(ScriptExecutionContext& context, MediaKeySessionType sessionType, bool useDistinctiveIdentifier, Ref<CDM>&& implementation, Ref<CDMInstance>&& instance)
+Ref<MediaKeySession> MediaKeySession::create(ScriptExecutionContext& context, MediaKeys& keys, MediaKeySessionType sessionType, bool useDistinctiveIdentifier, Ref<CDM>&& implementation, Ref<CDMInstance>&& instance)
{
- auto session = adoptRef(*new MediaKeySession(context, sessionType, useDistinctiveIdentifier, WTFMove(implementation), WTFMove(instance)));
+ auto session = adoptRef(*new MediaKeySession(context, keys, sessionType, useDistinctiveIdentifier, WTFMove(implementation), WTFMove(instance)));
session->suspendIfNeeded();
return session;
}
-MediaKeySession::MediaKeySession(ScriptExecutionContext& context, MediaKeySessionType sessionType, bool useDistinctiveIdentifier, Ref<CDM>&& implementation, Ref<CDMInstance>&& instance)
+MediaKeySession::MediaKeySession(ScriptExecutionContext& context, MediaKeys& keys, MediaKeySessionType sessionType, bool useDistinctiveIdentifier, Ref<CDM>&& implementation, Ref<CDMInstance>&& instance)
: ActiveDOMObject(&context)
+ , m_keys(&keys)
, m_expiration(std::numeric_limits<double>::quiet_NaN())
, m_keyStatuses(MediaKeyStatusMap::create(*this))
, m_useDistinctiveIdentifier(useDistinctiveIdentifier)
@@ -90,6 +92,11 @@
m_keyStatuses->detachSession();
}
+void MediaKeySession::detachKeys()
+{
+ m_keys = nullptr;
+}
+
const String& MediaKeySession::sessionId() const
{
return m_sessionId;
@@ -637,7 +644,11 @@
m_eventQueue.enqueueEvent(Event::create(eventNames().keystatuseschangeEvent, false, false));
// 6. Queue a task to run the Attempt to Resume Playback If Necessary algorithm on each of the media element(s) whose mediaKeys attribute is the MediaKeys object that created the session.
- // FIXME: Implement.
+ m_taskQueue.enqueueTask(
+ [this] () mutable {
+ if (m_keys)
+ m_keys->attemptToResumePlaybackOnClients();
+ });
}
void MediaKeySession::updateExpiration(double)
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h (220904 => 220905)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h 2017-08-18 07:27:34 UTC (rev 220904)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h 2017-08-18 07:45:49 UTC (rev 220905)
@@ -54,12 +54,14 @@
class MediaKeySession final : public RefCounted<MediaKeySession>, public EventTargetWithInlineData, public ActiveDOMObject {
public:
- static Ref<MediaKeySession> create(ScriptExecutionContext&, MediaKeySessionType, bool useDistinctiveIdentifier, Ref<CDM>&&, Ref<CDMInstance>&&);
+ static Ref<MediaKeySession> create(ScriptExecutionContext&, MediaKeys&, MediaKeySessionType, bool useDistinctiveIdentifier, Ref<CDM>&&, Ref<CDMInstance>&&);
virtual ~MediaKeySession();
using RefCounted<MediaKeySession>::ref;
using RefCounted<MediaKeySession>::deref;
+ void detachKeys();
+
const String& sessionId() const;
double expiration() const;
Ref<MediaKeyStatusMap> keyStatuses() const;
@@ -76,7 +78,7 @@
const Vector<std::pair<Ref<SharedBuffer>, MediaKeyStatus>>& statuses() const { return m_statuses; }
private:
- MediaKeySession(ScriptExecutionContext&, MediaKeySessionType, bool useDistinctiveIdentifier, Ref<CDM>&&, Ref<CDMInstance>&&);
+ MediaKeySession(ScriptExecutionContext&, MediaKeys&, MediaKeySessionType, bool useDistinctiveIdentifier, Ref<CDM>&&, Ref<CDMInstance>&&);
void enqueueMessage(MediaKeyMessageType, const SharedBuffer&);
void updateKeyStatuses(CDMInstance::KeyStatusVector&&);
void updateExpiration(double);
@@ -94,6 +96,7 @@
bool canSuspendForDocumentSuspension() const override;
void stop() override;
+ MediaKeys* m_keys;
String m_sessionId;
double m_expiration;
ClosedPromise m_closedPromise;
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp (220904 => 220905)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp 2017-08-18 07:27:34 UTC (rev 220904)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp 2017-08-18 07:45:49 UTC (rev 220905)
@@ -32,6 +32,7 @@
#if ENABLE(ENCRYPTED_MEDIA)
#include "CDM.h"
+#include "CDMClient.h"
#include "CDMInstance.h"
#include "MediaKeySession.h"
#include "SharedBuffer.h"
@@ -47,7 +48,11 @@
{
}
-MediaKeys::~MediaKeys() = default;
+MediaKeys::~MediaKeys()
+{
+ for (auto& session : m_sessions)
+ session->detachKeys();
+}
ExceptionOr<Ref<MediaKeySession>> MediaKeys::createSession(ScriptExecutionContext& context, MediaKeySessionType sessionType)
{
@@ -66,7 +71,9 @@
// 3. Let session be a new MediaKeySession object, and initialize it as follows:
// NOTE: Continued in MediaKeySession.
// 4. Return session.
- return MediaKeySession::create(context, sessionType, m_useDistinctiveIdentifier, m_implementation.copyRef(), m_instance.copyRef());
+ auto session = MediaKeySession::create(context, *this, sessionType, m_useDistinctiveIdentifier, m_implementation.copyRef(), m_instance.copyRef());
+ m_sessions.append(session.copyRef());
+ return WTFMove(session);
}
void MediaKeys::setServerCertificate(const BufferSource& serverCertificate, Ref<DeferredPromise>&& promise)
@@ -109,6 +116,24 @@
// 6. Return promise.
}
+void MediaKeys::attachCDMClient(CDMClient& client)
+{
+ ASSERT(!m_cdmClients.contains(&client));
+ m_cdmClients.append(&client);
+}
+
+void MediaKeys::detachCDMClient(CDMClient& client)
+{
+ ASSERT(m_cdmClients.contains(&client));
+ m_cdmClients.removeFirst(&client);
+}
+
+void MediaKeys::attemptToResumePlaybackOnClients()
+{
+ for (auto* cdmClient : m_cdmClients)
+ cdmClient->cdmClientAttemptToResumePlaybackIfNecessary();
+}
+
} // namespace WebCore
#endif // ENABLE(ENCRYPTED_MEDIA)
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h (220904 => 220905)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h 2017-08-18 07:27:34 UTC (rev 220904)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h 2017-08-18 07:45:49 UTC (rev 220905)
@@ -40,6 +40,7 @@
namespace WebCore {
class CDM;
+class CDMClient;
class CDMInstance;
class BufferSource;
class MediaKeySession;
@@ -56,9 +57,12 @@
~MediaKeys();
ExceptionOr<Ref<MediaKeySession>> createSession(ScriptExecutionContext&, MediaKeySessionType);
-
void setServerCertificate(const BufferSource&, Ref<DeferredPromise>&&);
+ void attachCDMClient(CDMClient&);
+ void detachCDMClient(CDMClient&);
+ void attemptToResumePlaybackOnClients();
+
protected:
MediaKeys(bool useDistinctiveIdentifier, bool persistentStateAllowed, const Vector<MediaKeySessionType>&, Ref<CDM>&&, Ref<CDMInstance>&&);
@@ -67,6 +71,9 @@
Vector<MediaKeySessionType> m_supportedSessionTypes;
Ref<CDM> m_implementation;
Ref<CDMInstance> m_instance;
+
+ Vector<Ref<MediaKeySession>> m_sessions;
+ Vector<CDMClient*> m_cdmClients;
GenericTaskQueue<Timer> m_taskQueue;
};
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (220904 => 220905)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2017-08-18 07:27:34 UTC (rev 220904)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2017-08-18 07:45:49 UTC (rev 220905)
@@ -2565,6 +2565,11 @@
notImplemented();
}
+void HTMLMediaElement::cdmClientAttemptToResumePlaybackIfNecessary()
+{
+ notImplemented();
+}
+
#endif // ENABLE(ENCRYPTED_MEDIA)
void HTMLMediaElement::progressEventTimerFired()
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (220904 => 220905)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2017-08-18 07:27:34 UTC (rev 220904)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2017-08-18 07:45:49 UTC (rev 220905)
@@ -55,6 +55,10 @@
#include "AudioSession.h"
#endif
+#if ENABLE(ENCRYPTED_MEDIA)
+#include "CDMClient.h"
+#endif
+
#ifndef NDEBUG
#include <wtf/StringPrintStream.h>
#endif
@@ -131,6 +135,9 @@
#if USE(AUDIO_SESSION) && PLATFORM(MAC)
, private AudioSession::MutedStateObserver
#endif
+#if ENABLE(ENCRYPTED_MEDIA)
+ , private CDMClient
+#endif
{
public:
WeakPtr<HTMLMediaElement> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
@@ -627,6 +634,11 @@
bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override;
String mediaPlayerMediaKeysStorageDirectory() const override;
#endif
+
+#if ENABLE(ENCRYPTED_MEDIA)
+ // CDMClient
+ void cdmClientAttemptToResumePlaybackIfNecessary() override;
+#endif
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;