Title: [220905] trunk/Source/WebCore
Revision
220905
Author
zandober...@gmail.com
Date
2017-08-18 00:45:49 -0700 (Fri, 18 Aug 2017)

Log Message

[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:

Modified Paths

Added Paths

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;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to