void SetMediaKeysHandler::clearExistingMediaKeys()
{
    WTF_LOG(Media, "SetMediaKeysHandler::clearExistingMediaKeys");
    HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia::from(*m_element);

    // 3.1 If mediaKeys is not null, it is already in use by another media
    //     element, and the user agent is unable to use it with this element,
    //     reject promise with a new DOMException whose name is
    //     "QuotaExceededError".
    if (m_newMediaKeys) {
        if (!m_newMediaKeys->reserveForMediaElement(m_element.get())) {
            fail(QuotaExceededError, "The MediaKeys object is already in use by another media element.");
            return;
        }
        // Note that |m_newMediaKeys| is now considered reserved for
        // |m_element|, so it needs to be accepted or cancelled.
        m_madeReservation = true;
    }

    // 3.2 If the mediaKeys attribute is not null, run the following steps:
    if (thisElement.m_mediaKeys) {
        WebMediaPlayer* mediaPlayer = m_element->webMediaPlayer();
        if (mediaPlayer) {
            // 3.2.1 If the user agent or CDM do not support removing the
            //       association, return a promise rejected with a new
            //       DOMException whose name is "NotSupportedError".
            // 3.2.2 If the association cannot currently be removed (i.e.
            //       during playback), return a promise rejected with a new
            //       DOMException whose name is "InvalidStateError".
            // 3.2.3 Stop using the CDM instance represented by the mediaKeys
            //       attribute to decrypt media data and remove the association
            //       with the media element.
            // (All 3 steps handled as needed in Chromium.)
            OwnPtr<SuccessCallback> successCallback = bind(&SetMediaKeysHandler::setNewMediaKeys, this);
            OwnPtr<FailureCallback> failureCallback = bind<ExceptionCode, const String&>(&SetMediaKeysHandler::clearFailed, this);
            ContentDecryptionModuleResult* result = new SetContentDecryptionModuleResult(successCallback.release(), failureCallback.release());
            mediaPlayer->setContentDecryptionModule(nullptr, result->result());

            // Don't do anything more until |result| is resolved (or rejected).
            return;
        }
    }

    // MediaKeys not currently set or no player connected, so continue on.
    setNewMediaKeys();
}
void SetMediaKeysHandler::clearExistingMediaKeys()
{
    WTF_LOG(Media, "SetMediaKeysHandler::clearExistingMediaKeys");
    HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia::from(*m_element);

    // 3.1 If mediaKeys is not null, it is already in use by another media
    //     element, and the user agent is unable to use it with this element,
    //     reject promise with a new DOMException whose name is
    //     "QuotaExceededError".
    // FIXME: Need to check whether mediaKeys is already in use by another
    //        media element.
    // 3.2 If the mediaKeys attribute is not null, run the following steps:
    if (thisElement.m_mediaKeys) {
        // 3.2.1 If the user agent or CDM do not support removing the
        //       association, return a promise rejected with a new DOMException
        //       whose name is "NotSupportedError".
        //       (supported by blink).
        // 3.2.2 If the association cannot currently be removed (i.e. during
        //       playback), return a promise rejected with a new DOMException
        //       whose name is "InvalidStateError".
        if (m_element->webMediaPlayer()) {
            reject(DOMException::create(InvalidStateError, "The existing MediaKeys object cannot be removed while a media resource is loaded."));
            return;
        }

        // (next 2 steps not required as there is no player connected).
        // 3.2.3 Stop using the CDM instance represented by the mediaKeys
        //       attribute to decrypt media data and remove the association
        //       with the media element.
        // 3.2.4 If the preceding step failed, reject promise with a new
        //       DOMException whose name is the appropriate error name and
        //       that has an appropriate message.
    }

    // MediaKeys not currently set or no player connected, so continue on.
    setNewMediaKeys();
}