Changeset 252033 in webkit


Ignore:
Timestamp:
Nov 4, 2019 7:03:36 PM (4 years ago)
Author:
Chris Dumez
Message:

MediaKeySession / WebKitMediaKeySession should not prevent entering the back/forward cache
https://bugs.webkit.org/show_bug.cgi?id=203089

Reviewed by Youenn Fablet.

Source/WebCore:

Port MediaKeySession / WebKitMediaKeySession to the HTML5 event loop instead of using its
own GenericEventQueue / GenericTaskQueue. Because the HTML5 event loop plays nicely with
the back/forward cache, we can now let pages using MediaKeySession / WebKitMediaKeySession
into the back/forward cache.

Test: http/tests/navigation/page-cache-mediakeysession.html

  • Modules/encryptedmedia/MediaKeySession.cpp:

(WebCore::MediaKeySession::MediaKeySession):
(WebCore::MediaKeySession::generateRequest):
(WebCore::MediaKeySession::load):
(WebCore::MediaKeySession::update):
(WebCore::MediaKeySession::close):
(WebCore::MediaKeySession::remove):
(WebCore::MediaKeySession::enqueueMessage):
(WebCore::MediaKeySession::updateKeyStatuses):
(WebCore::MediaKeySession::hasPendingActivity const):
(WebCore::MediaKeySession::activeDOMObjectName const):
(WebCore::MediaKeySession::enqueueTask):
(WebCore::MediaKeySession::enqueueEvent):
(WebCore::MediaKeySession::shouldPreventEnteringBackForwardCache_DEPRECATED const): Deleted.
(WebCore::MediaKeySession::stop): Deleted.

  • Modules/encryptedmedia/MediaKeySession.h:
  • Modules/encryptedmedia/legacy/WebKitMediaKeySession.cpp:

(WebCore::WebKitMediaKeySession::WebKitMediaKeySession):
(WebCore::WebKitMediaKeySession::~WebKitMediaKeySession):
(WebCore::WebKitMediaKeySession::addKeyTimerFired):
(WebCore::WebKitMediaKeySession::sendMessage):
(WebCore::WebKitMediaKeySession::sendError):
(WebCore::WebKitMediaKeySession::hasPendingActivity const):
(WebCore::WebKitMediaKeySession::enqueueEvent):
(WebCore::WebKitMediaKeySession::shouldPreventEnteringBackForwardCache_DEPRECATED const): Deleted.

  • Modules/encryptedmedia/legacy/WebKitMediaKeySession.h:

LayoutTests:

Add layout test coverage.

  • http/tests/navigation/page-cache-mediakeysession-expected.txt: Added.
  • http/tests/navigation/page-cache-mediakeysession.html: Added.
Location:
trunk
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r252032 r252033  
     12019-11-04  Chris Dumez  <cdumez@apple.com>
     2
     3        MediaKeySession / WebKitMediaKeySession should not prevent entering the back/forward cache
     4        https://bugs.webkit.org/show_bug.cgi?id=203089
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Add layout test coverage.
     9
     10        * http/tests/navigation/page-cache-mediakeysession-expected.txt: Added.
     11        * http/tests/navigation/page-cache-mediakeysession.html: Added.
     12
    1132019-11-04  Yusuke Suzuki  <ysuzuki@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r252030 r252033  
     12019-11-04  Chris Dumez  <cdumez@apple.com>
     2
     3        MediaKeySession / WebKitMediaKeySession should not prevent entering the back/forward cache
     4        https://bugs.webkit.org/show_bug.cgi?id=203089
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Port MediaKeySession / WebKitMediaKeySession to the HTML5 event loop instead of using its
     9        own GenericEventQueue / GenericTaskQueue. Because the HTML5 event loop plays nicely with
     10        the back/forward cache, we can now let pages using MediaKeySession / WebKitMediaKeySession
     11        into the back/forward cache.
     12
     13        Test: http/tests/navigation/page-cache-mediakeysession.html
     14
     15        * Modules/encryptedmedia/MediaKeySession.cpp:
     16        (WebCore::MediaKeySession::MediaKeySession):
     17        (WebCore::MediaKeySession::generateRequest):
     18        (WebCore::MediaKeySession::load):
     19        (WebCore::MediaKeySession::update):
     20        (WebCore::MediaKeySession::close):
     21        (WebCore::MediaKeySession::remove):
     22        (WebCore::MediaKeySession::enqueueMessage):
     23        (WebCore::MediaKeySession::updateKeyStatuses):
     24        (WebCore::MediaKeySession::hasPendingActivity const):
     25        (WebCore::MediaKeySession::activeDOMObjectName const):
     26        (WebCore::MediaKeySession::enqueueTask):
     27        (WebCore::MediaKeySession::enqueueEvent):
     28        (WebCore::MediaKeySession::shouldPreventEnteringBackForwardCache_DEPRECATED const): Deleted.
     29        (WebCore::MediaKeySession::stop): Deleted.
     30        * Modules/encryptedmedia/MediaKeySession.h:
     31        * Modules/encryptedmedia/legacy/WebKitMediaKeySession.cpp:
     32        (WebCore::WebKitMediaKeySession::WebKitMediaKeySession):
     33        (WebCore::WebKitMediaKeySession::~WebKitMediaKeySession):
     34        (WebCore::WebKitMediaKeySession::addKeyTimerFired):
     35        (WebCore::WebKitMediaKeySession::sendMessage):
     36        (WebCore::WebKitMediaKeySession::sendError):
     37        (WebCore::WebKitMediaKeySession::hasPendingActivity const):
     38        (WebCore::WebKitMediaKeySession::enqueueEvent):
     39        (WebCore::WebKitMediaKeySession::shouldPreventEnteringBackForwardCache_DEPRECATED const): Deleted.
     40        * Modules/encryptedmedia/legacy/WebKitMediaKeySession.h:
     41
    1422019-11-04  Ross Kirsling  <ross.kirsling@sony.com>
    243
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp

    r252008 r252033  
    3232#if ENABLE(ENCRYPTED_MEDIA)
    3333
     34#include "AbstractEventLoop.h"
    3435#include "CDM.h"
    3536#include "CDMInstance.h"
     
    7172    , m_implementation(WTFMove(implementation))
    7273    , m_instanceSession(WTFMove(instanceSession))
    73     , m_eventQueue(MainThreadGenericEventQueue::create(*this))
    7474{
    7575    // https://w3c.github.io/encrypted-media/#dom-mediakeys-createsession
     
    158158    // 9. Let promise be a new promise.
    159159    // 10. Run the following steps in parallel:
    160     m_taskQueue.enqueueTask([this, initData = SharedBuffer::create(initData.data(), initData.length()), initDataType, promise = WTFMove(promise)] () mutable {
     160    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, initData = SharedBuffer::create(initData.data(), initData.length()), initDataType, promise = WTFMove(promise)] () mutable {
    161161        // 10.1. If the init data is not valid for initDataType, reject promise with a newly created TypeError.
    162162        // 10.2. Let sanitized init data be a validated and sanitized version of init data.
     
    227227
    228228            // 10.10. Queue a task to run the following steps:
    229             m_taskQueue.enqueueTask([this, promise = WTFMove(promise), message = WTFMove(message), messageType, sessionId, succeeded] () mutable {
     229            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, promise = WTFMove(promise), message = WTFMove(message), messageType, sessionId, succeeded] () mutable {
    230230                // 10.10.1. If any of the preceding steps failed, reject promise with a new DOMException whose name is the appropriate error name.
    231231                if (succeeded == CDMInstanceSession::SuccessValue::Failed) {
     
    278278    // 7. Let promise be a new promise.
    279279    // 8. Run the following steps in parallel:
    280     m_taskQueue.enqueueTask([this, sessionId, promise = WTFMove(promise)] () mutable {
     280    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, sessionId, promise = WTFMove(promise)] () mutable {
    281281        // 8.1. Let sanitized session ID be a validated and/or sanitized version of sessionId.
    282282        // 8.2. If the preceding step failed, or if sanitized session ID is empty, reject promise with a newly created TypeError.
     
    330330
    331331            // 8.9. Queue a task to run the following steps:
    332             m_taskQueue.enqueueTask([this, knownKeys = WTFMove(knownKeys), expiration = WTFMove(expiration), message = WTFMove(message), sanitizedSessionId, succeeded, promise = WTFMove(promise)] () mutable {
     332            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, knownKeys = WTFMove(knownKeys), expiration = WTFMove(expiration), message = WTFMove(message), sanitizedSessionId, succeeded, promise = WTFMove(promise)] () mutable {
    333333                // 8.9.1. If any of the preceding steps failed, reject promise with a the appropriate error name.
    334334                if (succeeded == CDMInstanceSession::SuccessValue::Failed) {
     
    387387    // 5. Let promise be a new promise.
    388388    // 6. Run the following steps in parallel:
    389     m_taskQueue.enqueueTask([this, response = SharedBuffer::create(response.data(), response.length()), promise = WTFMove(promise)] () mutable {
     389    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, response = SharedBuffer::create(response.data(), response.length()), promise = WTFMove(promise)] () mutable {
    390390        // 6.1. Let sanitized response be a validated and/or sanitized version of response copy.
    391391        RefPtr<SharedBuffer> sanitizedResponse = m_implementation->sanitizeResponse(response);
     
    438438            //   6.7.3.2. Let message type be the appropriate MediaKeyMessageType for the message.
    439439            // 6.8. Queue a task to run the following steps:
    440             m_taskQueue.enqueueTask([this, sessionWasClosed, changedKeys = WTFMove(changedKeys), changedExpiration = WTFMove(changedExpiration), message = WTFMove(message), promise = WTFMove(promise)] () mutable {
     440            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, sessionWasClosed, changedKeys = WTFMove(changedKeys), changedExpiration = WTFMove(changedExpiration), message = WTFMove(message), promise = WTFMove(promise)] () mutable {
    441441                LOG(EME, "EME - updating CDM license succeeded for session %s, sending a message to the license server", m_sessionId.utf8().data());
    442442                // 6.8.1.
     
    515515    // 4. Let promise be a new promise.
    516516    // 5. Run the following steps in parallel:
    517     m_taskQueue.enqueueTask([this, promise = WTFMove(promise)] () mutable {
     517    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, promise = WTFMove(promise)] () mutable {
    518518        // 5.1. Let cdm be the CDM instance represented by session's cdm instance value.
    519519        // 5.2. Use cdm to close the key session associated with session.
     
    524524
    525525            // 5.3. Queue a task to run the following steps:
    526             m_taskQueue.enqueueTask([this, promise = WTFMove(promise)] () mutable {
     526            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, promise = WTFMove(promise)] () mutable {
    527527                // 5.3.1. Run the Session Closed algorithm on the session.
    528528                sessionClosed();
     
    553553    // 3. Let promise be a new promise.
    554554    // 4. Run the following steps in parallel:
    555     m_taskQueue.enqueueTask([this, promise = WTFMove(promise)] () mutable {
     555    queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, promise = WTFMove(promise)] () mutable {
    556556        // 4.1. Let cdm be the CDM instance represented by this object's cdm instance value.
    557557        // 4.2. Let message be null.
     
    578578
    579579            // 4.5. Queue a task to run the following steps:
    580             m_taskQueue.enqueueTask([this, keys = WTFMove(keys), message = WTFMove(message), succeeded, promise = WTFMove(promise)] () mutable {
     580            queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, keys = WTFMove(keys), message = WTFMove(message), succeeded, promise = WTFMove(promise)] () mutable {
    581581                // 4.5.1. Run the Update Key Statuses algorithm on the session, providing all key ID(s) in the session along with the "released" MediaKeyStatus value for each.
    582582                updateKeyStatuses(WTFMove(keys));
     
    617617    //    session.
    618618    auto messageEvent = MediaKeyMessageEvent::create(eventNames().messageEvent, {messageType, message.tryCreateArrayBuffer()}, Event::IsTrusted::Yes);
    619     m_eventQueue->enqueueEvent(WTFMove(messageEvent));
     619    queueTaskToDispatchEvent(*this, TaskSource::Networking, WTFMove(messageEvent));
    620620}
    621621
     
    662662
    663663    // 5. Queue a task to fire a simple event named keystatuseschange at the session.
    664     m_eventQueue->enqueueEvent(Event::create(eventNames().keystatuseschangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
     664    queueTaskToDispatchEvent(*this, TaskSource::Networking, Event::create(eventNames().keystatuseschangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
    665665
    666666    // 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.
    667     m_taskQueue.enqueueTask(
     667    queueTaskKeepingObjectAlive(*this, TaskSource::Networking,
    668668        [this] () mutable {
    669669            if (m_keys)
     
    734734bool MediaKeySession::hasPendingActivity() const
    735735{
    736     notImplemented();
    737     return false;
     736    // A MediaKeySession object SHALL NOT be destroyed and SHALL continue to receive events if it is not closed and the MediaKeys object that created it remains accessible.
     737    return (!m_closed && m_keys) || ActiveDOMObject::hasPendingActivity();
    738738}
    739739
    740740const char* MediaKeySession::activeDOMObjectName() const
    741741{
    742     notImplemented();
    743742    return "MediaKeySession";
    744743}
    745744
    746 // FIXME: This should never prevent entering the back/forward cache.
    747 bool MediaKeySession::shouldPreventEnteringBackForwardCache_DEPRECATED() const
    748 {
    749     notImplemented();
    750     return true;
    751 }
    752 
    753 void MediaKeySession::stop()
    754 {
    755     notImplemented();
    756 }
    757 
    758745} // namespace WebCore
    759746
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h

    r252008 r252033  
    3434#include "CDMInstanceSession.h"
    3535#include "EventTarget.h"
    36 #include "GenericEventQueue.h"
    37 #include "GenericTaskQueue.h"
    3836#include "IDLTypes.h"
    3937#include "MediaKeyMessageType.h"
     
    4139#include "MediaKeyStatus.h"
    4240#include <wtf/RefCounted.h>
     41#include <wtf/UniqueRef.h>
    4342#include <wtf/Vector.h>
    4443#include <wtf/WeakPtr.h>
     
    105104    // ActiveDOMObject
    106105    const char* activeDOMObjectName() const override;
    107     bool shouldPreventEnteringBackForwardCache_DEPRECATED() const override;
    108     void stop() override;
    109106
    110107    WeakPtr<MediaKeys> m_keys;
     
    120117    Ref<CDM> m_implementation;
    121118    Ref<CDMInstanceSession> m_instanceSession;
    122     UniqueRef<MainThreadGenericEventQueue> m_eventQueue;
    123     GenericTaskQueue<Timer> m_taskQueue;
    124119    Vector<Ref<SharedBuffer>> m_recordOfKeyUsage;
    125120    double m_firstDecryptTime { 0 };
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp

    r250735 r252033  
    3232#if ENABLE(ENCRYPTED_MEDIA)
    3333
     34#include "AbstractEventLoop.h"
    3435#include "CDM.h"
    3536#include "CDMClient.h"
     
    3839#include "Logging.h"
    3940#include "MediaKeySession.h"
     41#include "ScriptExecutionContext.h"
    4042#include "SharedBuffer.h"
    4143
     
    8082}
    8183
    82 void MediaKeys::setServerCertificate(const BufferSource& serverCertificate, Ref<DeferredPromise>&& promise)
     84void MediaKeys::setServerCertificate(ScriptExecutionContext& context, const BufferSource& serverCertificate, Ref<DeferredPromise>&& promise)
    8385{
    8486    // https://w3c.github.io/encrypted-media/#dom-mediakeys-setservercertificate
     
    105107    // 5. Run the following steps in parallel:
    106108
    107     m_taskQueue.enqueueTask([this, certificate = WTFMove(certificate), promise = WTFMove(promise)] () mutable {
     109    context.eventLoop().queueTask(TaskSource::Networking, context, [this, certificate = WTFMove(certificate), promise = WTFMove(promise)] () mutable {
    108110        // 5.1. Use this object's cdm instance to process certificate.
    109111        if (m_instance->setServerCertificate(WTFMove(certificate)) == CDMInstance::Failed) {
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h

    r250735 r252033  
    3232
    3333#include "ExceptionOr.h"
    34 #include "GenericTaskQueue.h"
    3534#include "MediaKeySessionType.h"
    3635#include <wtf/Ref.h>
     
    6059
    6160    ExceptionOr<Ref<MediaKeySession>> createSession(ScriptExecutionContext&, MediaKeySessionType);
    62     void setServerCertificate(const BufferSource&, Ref<DeferredPromise>&&);
     61    void setServerCertificate(ScriptExecutionContext&, const BufferSource&, Ref<DeferredPromise>&&);
    6362
    6463    void attachCDMClient(CDMClient&);
     
    8180    Vector<Ref<MediaKeySession>> m_sessions;
    8281    Vector<CDMClient*> m_cdmClients;
    83     GenericTaskQueue<Timer> m_taskQueue;
    8482};
    8583
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.idl

    r236818 r252033  
    3434] interface MediaKeys {
    3535    [CallWith=ScriptExecutionContext, MayThrowException] MediaKeySession createSession(optional MediaKeySessionType sessionType = "temporary");
    36     Promise<bool> setServerCertificate(BufferSource serverCertificate);
     36    [CallWith=ScriptExecutionContext] Promise<bool> setServerCertificate(BufferSource serverCertificate);
    3737};
  • trunk/Source/WebCore/Modules/encryptedmedia/legacy/WebKitMediaKeySession.cpp

    r252008 r252033  
    2929#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
    3030
     31#include "AbstractEventLoop.h"
    3132#include "Document.h"
    3233#include "EventNames.h"
     
    5556    , m_keys(&keys)
    5657    , m_keySystem(keySystem)
    57     , m_asyncEventQueue(MainThreadGenericEventQueue::create(*this))
    5858    , m_session(keys.cdm().createSession(*this))
    5959    , m_keyRequestTimer(*this, &WebKitMediaKeySession::keyRequestTimerFired)
     
    6868    if (m_session)
    6969        m_session->setClient(nullptr);
    70 
    71     m_asyncEventQueue->cancelAllEvents();
    7270}
    7371
     
    184182            auto keyaddedEvent = Event::create(eventNames().webkitkeyaddedEvent, Event::CanBubble::No, Event::IsCancelable::No);
    185183            keyaddedEvent->setTarget(this);
    186             m_asyncEventQueue->enqueueEvent(WTFMove(keyaddedEvent));
     184            queueTaskToDispatchEvent(*this, TaskSource::Networking, WTFMove(keyaddedEvent));
    187185
    188186            ASSERT(m_keys);
     
    208206    auto event = WebKitMediaKeyMessageEvent::create(eventNames().webkitkeymessageEvent, message, destinationURL);
    209207    event->setTarget(this);
    210     m_asyncEventQueue->enqueueEvent(WTFMove(event));
     208    queueTaskToDispatchEvent(*this, TaskSource::Networking, WTFMove(event));
    211209}
    212210
     
    217215    auto keyerrorEvent = Event::create(eventNames().webkitkeyerrorEvent, Event::CanBubble::No, Event::IsCancelable::No);
    218216    keyerrorEvent->setTarget(this);
    219     m_asyncEventQueue->enqueueEvent(WTFMove(keyerrorEvent));
     217    queueTaskToDispatchEvent(*this, TaskSource::Networking, WTFMove(keyerrorEvent));
    220218}
    221219
     
    239237bool WebKitMediaKeySession::hasPendingActivity() const
    240238{
    241     return (m_keys && m_session) || m_asyncEventQueue->hasPendingEvents();
     239    return (m_keys && m_session) || ActiveDOMObject::hasPendingActivity();
    242240}
    243241
     
    252250}
    253251
    254 bool WebKitMediaKeySession::shouldPreventEnteringBackForwardCache_DEPRECATED() const
    255 {
    256     // FIXME: This should never prevent entering the back/forward cache.
    257     return true;
    258 }
    259 
    260252}
    261253
  • trunk/Source/WebCore/Modules/encryptedmedia/legacy/WebKitMediaKeySession.h

    r252008 r252033  
    3131#include "EventTarget.h"
    3232#include "ExceptionOr.h"
    33 #include "GenericEventQueue.h"
    3433#include "LegacyCDMSession.h"
    3534#include "Timer.h"
     
    4241class WebKitMediaKeys;
    4342
    44 class WebKitMediaKeySession final : public RefCounted<WebKitMediaKeySession>, public EventTargetWithInlineData, private ActiveDOMObject, private LegacyCDMSessionClient {
     43class WebKitMediaKeySession final : public RefCounted<WebKitMediaKeySession>, public EventTargetWithInlineData, public ActiveDOMObject, private LegacyCDMSessionClient {
    4544    WTF_MAKE_ISO_ALLOCATED(WebKitMediaKeySession);
    4645public:
     
    7978
    8079    void stop() final;
    81     bool shouldPreventEnteringBackForwardCache_DEPRECATED() const final;
    8280    const char* activeDOMObjectName() const final;
    8381
     
    8987    String m_sessionId;
    9088    RefPtr<WebKitMediaKeyError> m_error;
    91     UniqueRef<MainThreadGenericEventQueue> m_asyncEventQueue;
    9289    std::unique_ptr<LegacyCDMSession> m_session;
    9390
Note: See TracChangeset for help on using the changeset viewer.