Diff
Modified: trunk/Source/WTF/ChangeLog (258294 => 258295)
--- trunk/Source/WTF/ChangeLog 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WTF/ChangeLog 2020-03-11 23:49:59 UTC (rev 258295)
@@ -1,3 +1,13 @@
+2020-03-11 Jer Noble <[email protected]>
+
+ [EME] Issue an "encrypted" event when a new encrypted initialization segment is encountered
+ https://bugs.webkit.org/show_bug.cgi?id=208923
+
+ Reviewed by Eric Carlson.
+
+ * wtf/LoggerHelper.h:
+ (WTF::LoggerHelper::childLogIdentifier): Made static.
+
2020-03-11 Per Arne Vollan <[email protected]>
[macOS] Crash under WebKit::WebProcessPool::platformInitialize()
Modified: trunk/Source/WTF/wtf/LoggerHelper.h (258294 => 258295)
--- trunk/Source/WTF/wtf/LoggerHelper.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WTF/wtf/LoggerHelper.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -56,7 +56,14 @@
#define INFO_LOG_IF(condition, ...) if (condition) logger().info(logChannel(), __VA_ARGS__)
#define DEBUG_LOG_IF(condition, ...) if (condition) logger().debug(logChannel(), __VA_ARGS__)
- const void* childLogIdentifier(const void* parentIdentifier, uint64_t childIdentifier) const
+#define ALWAYS_LOG_IF_POSSIBLE(...) if (loggerPtr()) loggerPtr()->logAlways(logChannel(), __VA_ARGS__)
+#define ERROR_LOG_IF_POSSIBLE(...) if (loggerPtr()) loggerPtr()->error(logChannel(), __VA_ARGS__)
+#define WARNING_LOG_IF_POSSIBLE(...) if (loggerPtr()) loggerPtr()->warning(logChannel(), __VA_ARGS__)
+#define INFO_LOG_IF_POSSIBLE(...) if (loggerPtr()) loggerPtr()->info(logChannel(), __VA_ARGS__)
+#define DEBUG_LOG_IF_POSSIBLE(...) if (loggerPtr()) loggerPtr()->debug(logChannel(), __VA_ARGS__)
+#define WILL_LOG_IF_POSSIBLE(_level_) if (loggerPtr()) loggerPtr()->willLog(logChannel(), _level_)
+
+ static const void* childLogIdentifier(const void* parentIdentifier, uint64_t childIdentifier)
{
static constexpr uint64_t parentMask = 0xffffffffffff0000ull;
static constexpr uint64_t maskLowerWord = 0xffffull;
@@ -88,6 +95,13 @@
#define INFO_LOG_IF(condition, ...) ((void)0)
#define DEBUG_LOG_IF(condition, ...) ((void)0)
+#define ALWAYS_LOG_IF_POSSIBLE(...) ((void)0)
+#define ERROR_LOG_IF_POSSIBLE(...) ((void)0)
+#define WARNING_LOG_IF_POSSIBLE(...) ((void)0)
+#define INFO_LOG_IF_POSSIBLE(...) ((void)0)
+#define DEBUG_LOG_IF_POSSIBLE(...) ((void)0)
+#define WILL_LOG_IF_POSSIBLE(_level_) ((void)0)
+
#endif // RELEASE_LOG_DISABLED
};
Modified: trunk/Source/WebCore/ChangeLog (258294 => 258295)
--- trunk/Source/WebCore/ChangeLog 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/ChangeLog 2020-03-11 23:49:59 UTC (rev 258295)
@@ -1,3 +1,98 @@
+2020-03-11 Jer Noble <[email protected]>
+
+ [EME] Issue an "encrypted" event when a new encrypted initialization segment is encountered
+ https://bugs.webkit.org/show_bug.cgi?id=208923
+
+ Reviewed by Eric Carlson.
+
+ When AVStreamDataParser encounters an initialization segment indicating encrypted content, it
+ will issue a -streamDataParser:didProvideContentKeyRequestInitializationData:forTrackID: message
+ to its delegate. If the parser is already associated with an AVContentKeySession, it will instead
+ allow the session to handle the initialization segment and the delagete method will not be called.
+
+ When the latter situation occurs, we can detect that the -didProvideRequest callback did not
+ occur due to the client calling MediaKeySession.generateRequest() and therefore must have been
+ due to parsing an encrypted segment. In response, store the request in a list of "unexpected"
+ requests to be checked the next time a MediaKeySession tries to generateRequest(). Then, we will
+ pass the initalizationData and type to HTMLMediaElement through a new client interface, where it
+ will use that initializationData to issue an "encrypted" event. If the client passes that same
+ initializationData back into MediaKeySession, the "unexpected" request can be found, and re-used.
+
+ Drive-by fixes: Added a ton of debug logging messages to the CDMPrivate classes.
+
+ * Modules/encryptedmedia/CDM.cpp:
+ (WebCore::CDM::CDM):
+ * Modules/encryptedmedia/CDM.h:
+ * Modules/encryptedmedia/CDMClient.h:
+ * Modules/encryptedmedia/MediaKeySession.cpp:
+ (WebCore::MediaKeySession::create):
+ (WebCore::MediaKeySession::MediaKeySession):
+ * Modules/encryptedmedia/MediaKeySession.h:
+ * Modules/encryptedmedia/MediaKeySystemAccess.cpp:
+ (WebCore::MediaKeySystemAccess::createMediaKeys):
+ * Modules/encryptedmedia/MediaKeySystemAccess.h:
+ * Modules/encryptedmedia/MediaKeySystemAccess.idl:
+ * Modules/encryptedmedia/MediaKeys.cpp:
+ (WebCore::MediaKeys::MediaKeys):
+ (WebCore::MediaKeys::createSession):
+ (WebCore::MediaKeys::setServerCertificate):
+ (WebCore::MediaKeys::attachCDMClient):
+ (WebCore::MediaKeys::detachCDMClient):
+ (WebCore::MediaKeys::attemptToResumePlaybackOnClients):
+ (WebCore::MediaKeys::unrequestedInitializationDataReceived):
+ (WebCore::MediaKeys::nextChildIdentifier const):
+ * Modules/encryptedmedia/MediaKeys.h:
+ (WebCore::MediaKeys::create): Deleted.
+ (WebCore::MediaKeys::cdmInstance): Deleted.
+ (WebCore::MediaKeys::cdmInstance const): Deleted.
+ * Modules/encryptedmedia/MediaKeys.idl:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::cdmClientUnrequestedInitializationDataReceived):
+ * html/HTMLMediaElement.h:
+ * platform/encryptedmedia/CDMFactory.h:
+ * platform/encryptedmedia/CDMInstance.h:
+ (WebCore::CDMInstance::setClient):
+ (WebCore::CDMInstance::clearClient):
+ (WebCore::CDMInstance::setLogger):
+ * platform/encryptedmedia/CDMInstanceSession.h:
+ (WebCore::CDMInstanceSession::setLogger):
+ (WebCore::CDMInstanceSession::setClient):
+ * platform/encryptedmedia/CDMPrivate.h:
+ (WebCore::CDMPrivate::setLogger):
+ * platform/graphics/avfoundation/CDMFairPlayStreaming.cpp:
+ (WebCore::logChannel):
+ (WebCore::CDMPrivateFairPlayStreaming::setLogger):
+ (WebCore::CDMPrivateFairPlayStreaming::supportsConfiguration const):
+ * platform/graphics/avfoundation/CDMFairPlayStreaming.h:
+ * platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h:
+ * platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm:
+ (WebCore::logChannel):
+ (WebCore::initTypeForRequest):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::setLogger):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::takeUnexpectedKeyRequestForInitializationData):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::setServerCertificate):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::setStorageDirectory):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::setClient):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::clearClient):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::didProvideRequest):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::didProvideRequests):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::didProvideRenewingRequest):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::didProvidePersistableRequest):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::didFailToProvideRequest):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::requestDidSucceed):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::shouldRetryRequestForReason):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::groupSessionIdentifierChanged):
+ (WebCore::CDMInstanceFairPlayStreamingAVFObjC::sessionForRequest const):
+ (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::setLogger):
+ (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::requestLicense):
+ (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::updateLicense):
+ (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::loadSession):
+ (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::closeSession):
+ (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::removeSessionData):
+ (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::setClient):
+ (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::hasRequest const):
+
2020-03-11 Jiewen Tan <[email protected]>
[WebAuthn] Formalize the Keychain schema
Modified: trunk/Source/WebCore/Modules/encryptedmedia/CDM.cpp (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/CDM.cpp 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/CDM.cpp 2020-03-11 23:49:59 UTC (rev 258295)
@@ -42,6 +42,8 @@
#include "SecurityOriginData.h"
#include "Settings.h"
#include <wtf/FileSystem.h>
+#include <wtf/Logger.h>
+#include <wtf/LoggerHelper.h>
#include <wtf/NeverDestroyed.h>
namespace WebCore {
@@ -62,6 +64,10 @@
CDM::CDM(Document& document, const String& keySystem)
: ContextDestructionObserver(&document)
+#if !RELEASE_LOG_DISABLED
+ , m_logger(document.logger())
+ , m_logIdentifier(LoggerHelper::uniqueLogIdentifier())
+#endif
, m_keySystem(keySystem)
{
ASSERT(supportsKeySystem(keySystem));
@@ -68,6 +74,9 @@
for (auto* factory : CDMFactory::registeredFactories()) {
if (factory->supportsKeySystem(keySystem)) {
m_private = factory->createCDM(keySystem);
+#if !RELEASE_LOG_DISABLED
+ m_private->setLogger(m_logger, m_logIdentifier);
+#endif
break;
}
}
Modified: trunk/Source/WebCore/Modules/encryptedmedia/CDM.h (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/CDM.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/CDM.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -40,6 +40,12 @@
#include <wtf/WeakPtr.h>
#include <wtf/text/WTFString.h>
+#if !RELEASE_LOG_DISABLED
+namespace WTF {
+class Logger;
+}
+#endif
+
namespace WebCore {
class CDMFactory;
@@ -80,6 +86,10 @@
private:
CDM(Document&, const String& keySystem);
+#if !RELEASE_LOG_DISABLED
+ Ref<WTF::Logger> m_logger;
+ const void* m_logIdentifier;
+#endif
String m_keySystem;
std::unique_ptr<CDMPrivate> m_private;
};
Modified: trunk/Source/WebCore/Modules/encryptedmedia/CDMClient.h (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/CDMClient.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/CDMClient.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -30,15 +30,20 @@
#if ENABLE(ENCRYPTED_MEDIA)
+#include <wtf/Forward.h>
+#include <wtf/WeakPtr.h>
+
namespace WebCore {
class CDMInstance;
+class SharedBuffer;
-class CDMClient {
+class CDMClient : public CanMakeWeakPtr<CDMClient> {
public:
virtual ~CDMClient() = default;
virtual void cdmClientAttemptToResumePlaybackIfNecessary() = 0;
+ virtual void cdmClientUnrequestedInitializationDataReceived(const String&, Ref<SharedBuffer>&&) = 0;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp 2020-03-11 23:49:59 UTC (rev 258295)
@@ -64,7 +64,10 @@
MediaKeySession::MediaKeySession(Document& document, WeakPtr<MediaKeys>&& keys, MediaKeySessionType sessionType, bool useDistinctiveIdentifier, Ref<CDM>&& implementation, Ref<CDMInstanceSession>&& instanceSession)
: ActiveDOMObject(&document)
+#if !RELEASE_LOG_DISABLED
, m_logger(document.logger())
+ , m_logIdentifier(keys ? keys->nextChildIdentifier() : nullptr)
+#endif
, m_keys(WTFMove(keys))
, m_expiration(std::numeric_limits<double>::quiet_NaN())
, m_closedPromise(makeUniqueRef<ClosedPromise>())
@@ -98,6 +101,9 @@
UNUSED_PARAM(m_closed);
UNUSED_PARAM(m_uninitialized);
+#if !RELEASE_LOG_DISABLED
+ m_instanceSession->setLogger(m_logger, m_logIdentifier);
+#endif
m_instanceSession->setClient(makeWeakPtr(*this));
}
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -43,9 +43,11 @@
#include <wtf/WeakPtr.h>
#include <wtf/text/WTFString.h>
+#if !RELEASE_LOG_DISABLED
namespace WTF {
class Logger;
}
+#endif
namespace WebCore {
@@ -113,10 +115,12 @@
const WTF::Logger& logger() const { return m_logger; }
const char* logClassName() const { return "MediaKeySession"; }
WTFLogChannel& logChannel() const;
- const void* logIdentifier() const { return this; }
+ const void* logIdentifier() const { return m_logIdentifier; }
+
+ Ref<WTF::Logger> m_logger;
+ const void* m_logIdentifier;
#endif
- Ref<WTF::Logger> m_logger;
WeakPtr<MediaKeys> m_keys;
String m_sessionId;
double m_expiration;
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.cpp (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.cpp 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.cpp 2020-03-11 23:49:59 UTC (rev 258295)
@@ -33,6 +33,7 @@
#include "CDM.h"
#include "CDMInstance.h"
+#include "Document.h"
#include "JSDOMPromiseDeferred.h"
#include "JSMediaKeys.h"
#include "MediaKeys.h"
@@ -54,7 +55,7 @@
MediaKeySystemAccess::~MediaKeySystemAccess() = default;
-void MediaKeySystemAccess::createMediaKeys(Ref<DeferredPromise>&& promise)
+void MediaKeySystemAccess::createMediaKeys(Document& document, Ref<DeferredPromise>&& promise)
{
// https://w3c.github.io/encrypted-media/#dom-mediakeysystemaccess-createmediakeys
// W3C Editor's Draft 09 November 2016
@@ -62,7 +63,7 @@
// When this method is invoked, the user agent must run the following steps:
// 1. Let promise be a new promise.
// 2. Run the following steps in parallel:
- m_taskQueue.enqueueTask([this, promise = WTFMove(promise)] () mutable {
+ m_taskQueue.enqueueTask([this, weakDocument = makeWeakPtr(document), promise = WTFMove(promise)] () mutable {
// 2.1. Let configuration be the value of this object's configuration value.
// 2.2. Let use distinctive identifier be true if the value of configuration's distinctiveIdentifier member is "required" and false otherwise.
bool useDistinctiveIdentifier = m_configuration->distinctiveIdentifier == MediaKeysRequirement::Required;
@@ -86,8 +87,8 @@
auto allowDistinctiveIdentifiers = useDistinctiveIdentifier ? CDMInstance::AllowDistinctiveIdentifiers::Yes : CDMInstance::AllowDistinctiveIdentifiers::No;
auto allowPersistentState = persistentStateAllowed ? CDMInstance::AllowPersistentState::Yes : CDMInstance::AllowPersistentState::No;
- instance->initializeWithConfiguration(*m_configuration, allowDistinctiveIdentifiers, allowPersistentState, [sessionTypes = m_configuration->sessionTypes, implementation = m_implementation.copyRef(), useDistinctiveIdentifier, persistentStateAllowed, instance = instance.releaseNonNull(), promise = WTFMove(promise)] (auto successValue) mutable {
- if (successValue == CDMInstance::Failed) {
+ instance->initializeWithConfiguration(*m_configuration, allowDistinctiveIdentifiers, allowPersistentState, [weakDocument = WTFMove(weakDocument), sessionTypes = m_configuration->sessionTypes, implementation = m_implementation.copyRef(), useDistinctiveIdentifier, persistentStateAllowed, instance = instance.releaseNonNull(), promise = WTFMove(promise)] (auto successValue) mutable {
+ if (successValue == CDMInstance::Failed || !weakDocument) {
promise->reject(NotAllowedError);
return;
}
@@ -99,7 +100,7 @@
// 2.10.3. Let the supported session types value be be the value of configuration's sessionTypes member.
// 2.10.4. Let the cdm implementation value be this object's cdm implementation value.
// 2.10.5. Let the cdm instance value be instance.
- auto mediaKeys = MediaKeys::create(useDistinctiveIdentifier, persistentStateAllowed, sessionTypes, WTFMove(implementation), WTFMove(instance));
+ auto mediaKeys = MediaKeys::create(*weakDocument, useDistinctiveIdentifier, persistentStateAllowed, sessionTypes, WTFMove(implementation), WTFMove(instance));
// 2.11. Resolve promise with media keys.
promise->resolveWithNewlyCreated<IDLInterface<MediaKeys>>(WTFMove(mediaKeys));
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.h (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -39,6 +39,7 @@
class CDM;
class DeferredPromise;
+class Document;
class MediaKeys;
class MediaKeySystemAccess : public RefCounted<MediaKeySystemAccess> {
@@ -48,7 +49,7 @@
const String& keySystem() const { return m_keySystem; }
const MediaKeySystemConfiguration& getConfiguration() const { return *m_configuration; }
- void createMediaKeys(Ref<DeferredPromise>&&);
+ void createMediaKeys(Document&, Ref<DeferredPromise>&&);
private:
MediaKeySystemAccess(const String& keySystem, MediaKeySystemConfiguration&&, Ref<CDM>&&);
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.idl (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.idl 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySystemAccess.idl 2020-03-11 23:49:59 UTC (rev 258295)
@@ -34,5 +34,5 @@
] interface MediaKeySystemAccess {
readonly attribute DOMString keySystem;
MediaKeySystemConfiguration getConfiguration();
- Promise<MediaKeys> createMediaKeys();
+ [CallWith=Document] Promise<MediaKeys> createMediaKeys();
};
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp 2020-03-11 23:49:59 UTC (rev 258295)
@@ -40,26 +40,31 @@
#include "Logging.h"
#include "MediaKeySession.h"
#include "SharedBuffer.h"
+#include <wtf/Logger.h>
+#include <wtf/LoggerHelper.h>
namespace WebCore {
-template<typename... Arguments>
-inline void infoLog(Logger& logger, const Arguments&... arguments)
-{
-#if !LOG_DISABLED || !RELEASE_LOG_DISABLED
- logger.info(LogEME, arguments...);
-#else
- UNUSED_PARAM(logger);
+#if !RELEASE_LOG_DISABLED
+static WTFLogChannel& logChannel() { return LogEME; }
+static const char* logClassName() { return "MediaKeys"; }
#endif
-}
-MediaKeys::MediaKeys(bool useDistinctiveIdentifier, bool persistentStateAllowed, const Vector<MediaKeySessionType>& supportedSessionTypes, Ref<CDM>&& implementation, Ref<CDMInstance>&& instance)
+MediaKeys::MediaKeys(Document& document, bool useDistinctiveIdentifier, bool persistentStateAllowed, const Vector<MediaKeySessionType>& supportedSessionTypes, Ref<CDM>&& implementation, Ref<CDMInstance>&& instance)
: m_useDistinctiveIdentifier(useDistinctiveIdentifier)
, m_persistentStateAllowed(persistentStateAllowed)
, m_supportedSessionTypes(supportedSessionTypes)
, m_implementation(WTFMove(implementation))
, m_instance(WTFMove(instance))
+#if !RELEASE_LOG_DISABLED
+ , m_logger(document.logger())
+ , m_logIdentifier(LoggerHelper::uniqueLogIdentifier())
+#endif
{
+#if !RELEASE_LOG_DISABLED
+ m_instance->setLogger(document.logger(), m_logIdentifier);
+#endif
+ m_instance->setClient(makeWeakPtr(this));
}
MediaKeys::~MediaKeys() = default;
@@ -68,26 +73,25 @@
{
// https://w3c.github.io/encrypted-media/#dom-mediakeys-setservercertificate
// W3C Editor's Draft 09 November 2016
- LOG(EME, "EME - check if a new session can be created");
- auto identifier = WTF::Logger::LogSiteIdentifier("MediaKeys", __func__, this);
- Ref<Logger> logger = document.logger();
+ auto identifier = LOGIDENTIFIER;
+ INFO_LOG(identifier, "EME - check if a new session can be created");
// When this method is invoked, the user agent must run the following steps:
// 1. If this object's supported session types value does not contain sessionType, throw [WebIDL] a NotSupportedError.
if (!m_supportedSessionTypes.contains(sessionType)) {
- infoLog(logger, identifier, "Exception: unsupported sessionType: ", sessionType);
+ INFO_LOG(identifier, "Exception: unsupported sessionType: ", sessionType);
return Exception(NotSupportedError);
}
// 2. If the implementation does not support MediaKeySession operations in the current state, throw [WebIDL] an InvalidStateError.
if (!m_implementation->supportsSessions()) {
- infoLog(logger, identifier, "Exception: implementation does not support sessions");
+ INFO_LOG(identifier, "Exception: implementation does not support sessions");
return Exception(InvalidStateError);
}
auto instanceSession = m_instance->createSession();
if (!instanceSession) {
- infoLog(logger, identifier, "Exception: could not create session");
+ INFO_LOG(identifier, "Exception: could not create session");
return Exception(InvalidStateError);
}
@@ -95,23 +99,22 @@
// NOTE: Continued in MediaKeySession.
// 4. Return session.
auto session = MediaKeySession::create(document, makeWeakPtr(*this), sessionType, m_useDistinctiveIdentifier, m_implementation.copyRef(), instanceSession.releaseNonNull());
- infoLog(logger, identifier, " Created session");
+ INFO_LOG(identifier, "Created session");
m_sessions.append(session.copyRef());
return session;
}
-void MediaKeys::setServerCertificate(Document& document, const BufferSource& serverCertificate, Ref<DeferredPromise>&& promise)
+void MediaKeys::setServerCertificate(const BufferSource& serverCertificate, Ref<DeferredPromise>&& promise)
{
// https://w3c.github.io/encrypted-media/#dom-mediakeys-setservercertificate
// W3C Editor's Draft 09 November 2016
- auto identifier = WTF::Logger::LogSiteIdentifier("MediaKeys", __func__, this);
- Ref<Logger> logger = document.logger();
+ auto identifier = LOGIDENTIFIER;
// When this method is invoked, the user agent must run the following steps:
// 1. If the Key System implementation represented by this object's cdm implementation value does not support
// server certificates, return a promise resolved with false.
if (!m_implementation->supportsServerCertificates()) {
- infoLog(logger, identifier, "Rejected: !supportsServerCertificates()");
+ INFO_LOG(identifier, "Rejected: !supportsServerCertificates()");
promise->resolve<IDLBoolean>(false);
return;
}
@@ -118,7 +121,7 @@
// 2. If serverCertificate is an empty array, return a promise rejected with a new a newly created TypeError.
if (!serverCertificate.length()) {
- infoLog(logger, identifier, "Rejected: empty serverCertificate");
+ INFO_LOG(identifier, "Rejected: empty serverCertificate");
promise->reject(TypeError);
return;
}
@@ -130,16 +133,16 @@
// 5. Run the following steps in parallel:
// 5.1. Use this object's cdm instance to process certificate.
- m_instance->setServerCertificate(WTFMove(certificate), [promise = WTFMove(promise), logger = WTFMove(logger), identifier = WTFMove(identifier)] (auto success) {
+ m_instance->setServerCertificate(WTFMove(certificate), [this, protectedThis = makeRef(*this), promise = WTFMove(promise), identifier = WTFMove(identifier)] (auto success) {
// 5.2. If the preceding step failed, resolve promise with a new DOMException whose name is the appropriate error name.
// 5.1. [Else,] Resolve promise with true.
if (success == CDMInstance::Failed) {
- infoLog(logger, identifier, "Rejected, setServerCertificate() failed");
+ INFO_LOG(identifier, "::task() - Rejected, setServerCertificate() failed");
promise->reject(InvalidStateError);
return;
}
- infoLog(logger, identifier, "Resolved");
+ INFO_LOG(identifier, "::task() - Resolved");
promise->resolve<IDLBoolean>(true);
});
@@ -148,20 +151,20 @@
void MediaKeys::attachCDMClient(CDMClient& client)
{
- ASSERT(!m_cdmClients.contains(&client));
- m_cdmClients.append(&client);
+ ASSERT(!m_cdmClients.contains(client));
+ m_cdmClients.add(client);
}
void MediaKeys::detachCDMClient(CDMClient& client)
{
- ASSERT(m_cdmClients.contains(&client));
- m_cdmClients.removeFirst(&client);
+ ASSERT(m_cdmClients.contains(client));
+ m_cdmClients.remove(client);
}
void MediaKeys::attemptToResumePlaybackOnClients()
{
- for (auto* cdmClient : m_cdmClients)
- cdmClient->cdmClientAttemptToResumePlaybackIfNecessary();
+ for (auto& cdmClient : m_cdmClients)
+ cdmClient.cdmClientAttemptToResumePlaybackIfNecessary();
}
bool MediaKeys::hasOpenSessions() const
@@ -172,6 +175,19 @@
});
}
+void MediaKeys::unrequestedInitializationDataReceived(const String& initDataType, Ref<SharedBuffer>&& initData)
+{
+ for (auto& cdmClient : m_cdmClients)
+ cdmClient.cdmClientUnrequestedInitializationDataReceived(initDataType, initData.copyRef());
+}
+
+#if !RELEASE_LOG_DISABLED
+const void* MediaKeys::nextChildIdentifier() const
+{
+ return LoggerHelper::childLogIdentifier(m_logIdentifier, ++m_childIdentifierSeed);
+}
+#endif
+
} // namespace WebCore
#endif // ENABLE(ENCRYPTED_MEDIA)
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -30,12 +30,18 @@
#if ENABLE(ENCRYPTED_MEDIA)
+#include "CDMInstance.h"
#include "ExceptionOr.h"
#include "MediaKeySessionType.h"
#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
+#include <wtf/WeakHashSet.h>
#include <wtf/WeakPtr.h>
+namespace WTF {
+class Logger;
+}
+
namespace WebCore {
class CDM;
@@ -46,19 +52,21 @@
class Document;
class MediaKeySession;
-class MediaKeys : public RefCounted<MediaKeys>, public CanMakeWeakPtr<MediaKeys> {
+class MediaKeys final
+ : public RefCounted<MediaKeys>
+ , public CDMInstanceClient {
public:
using KeySessionType = MediaKeySessionType;
- static Ref<MediaKeys> create(bool useDistinctiveIdentifier, bool persistentStateAllowed, const Vector<MediaKeySessionType>& supportedSessionTypes, Ref<CDM>&& implementation, Ref<CDMInstance>&& instance)
+ static Ref<MediaKeys> create(Document& document, bool useDistinctiveIdentifier, bool persistentStateAllowed, const Vector<MediaKeySessionType>& supportedSessionTypes, Ref<CDM>&& implementation, Ref<CDMInstance>&& instance)
{
- return adoptRef(*new MediaKeys(useDistinctiveIdentifier, persistentStateAllowed, supportedSessionTypes, WTFMove(implementation), WTFMove(instance)));
+ return adoptRef(*new MediaKeys(document, useDistinctiveIdentifier, persistentStateAllowed, supportedSessionTypes, WTFMove(implementation), WTFMove(instance)));
}
~MediaKeys();
ExceptionOr<Ref<MediaKeySession>> createSession(Document&, MediaKeySessionType);
- void setServerCertificate(Document&, const BufferSource&, Ref<DeferredPromise>&&);
+ void setServerCertificate(const BufferSource&, Ref<DeferredPromise>&&);
void attachCDMClient(CDMClient&);
void detachCDMClient(CDMClient&);
@@ -68,9 +76,21 @@
CDMInstance& cdmInstance() { return m_instance; }
const CDMInstance& cdmInstance() const { return m_instance; }
+#if !RELEASE_LOG_DISABLED
+ const void* nextChildIdentifier() const;
+#endif
+
protected:
- MediaKeys(bool useDistinctiveIdentifier, bool persistentStateAllowed, const Vector<MediaKeySessionType>&, Ref<CDM>&&, Ref<CDMInstance>&&);
+ MediaKeys(Document&, bool useDistinctiveIdentifier, bool persistentStateAllowed, const Vector<MediaKeySessionType>&, Ref<CDM>&&, Ref<CDMInstance>&&);
+ // CDMInstanceClient
+ void unrequestedInitializationDataReceived(const String&, Ref<SharedBuffer>&&) final;
+
+#if !RELEASE_LOG_DISABLED
+ const WTF::Logger& logger() const { return m_logger; }
+ const void* logIdentifier() const { return m_logIdentifier; }
+#endif
+
bool m_useDistinctiveIdentifier;
bool m_persistentStateAllowed;
Vector<MediaKeySessionType> m_supportedSessionTypes;
@@ -78,7 +98,13 @@
Ref<CDMInstance> m_instance;
Vector<Ref<MediaKeySession>> m_sessions;
- Vector<CDMClient*> m_cdmClients;
+ WeakHashSet<CDMClient> m_cdmClients;
+
+#if !RELEASE_LOG_DISABLED
+ Ref<WTF::Logger> m_logger;
+ const void* m_logIdentifier;
+ mutable uint64_t m_childIdentifierSeed { 0 };
+#endif
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.idl (258294 => 258295)
--- trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.idl 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.idl 2020-03-11 23:49:59 UTC (rev 258295)
@@ -30,8 +30,7 @@
Conditional=ENCRYPTED_MEDIA,
EnabledAtRuntime=EncryptedMediaAPI,
DisabledByQuirk=hasBrokenEncryptedMediaAPISupport,
- ImplementationLacksVTable,
] interface MediaKeys {
[CallWith=Document, MayThrowException] MediaKeySession createSession(optional MediaKeySessionType sessionType = "temporary");
- [CallWith=Document] Promise<bool> setServerCertificate(BufferSource serverCertificate);
+ Promise<bool> setServerCertificate(BufferSource serverCertificate);
};
Modified: trunk/Source/WebCore/PAL/ChangeLog (258294 => 258295)
--- trunk/Source/WebCore/PAL/ChangeLog 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/PAL/ChangeLog 2020-03-11 23:49:59 UTC (rev 258295)
@@ -1,3 +1,12 @@
+2020-03-11 Jer Noble <[email protected]>
+
+ [EME] Issue an "encrypted" event when a new encrypted initialization segment is encountered
+ https://bugs.webkit.org/show_bug.cgi?id=208923
+
+ Reviewed by Eric Carlson.
+
+ * pal/spi/cocoa/AVFoundationSPI.h:
+
2020-03-09 Don Olmstead <[email protected]>
Remove obsolete feature flags
Modified: trunk/Source/WebCore/PAL/pal/spi/cocoa/AVFoundationSPI.h (258294 => 258295)
--- trunk/Source/WebCore/PAL/pal/spi/cocoa/AVFoundationSPI.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/PAL/pal/spi/cocoa/AVFoundationSPI.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -174,6 +174,7 @@
@property (readonly, nullable) NSData *contentProtectionSessionIdentifier;
- (void)expire;
- (void)processContentKeyRequestWithIdentifier:(nullable id)identifier initializationData:(nullable NSData *)initializationData options:(nullable NSDictionary<NSString *, id> *)options;
+- (void)associateContentKeyRequest:(nonnull AVContentKeyRequest *)contentKeyRequest;
@end
@interface AVContentKeySession (AVContentKeyGroup_Support)
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (258294 => 258295)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2020-03-11 23:49:59 UTC (rev 258295)
@@ -2876,6 +2876,11 @@
attemptToResumePlaybackIfNecessary();
}
+void HTMLMediaElement::cdmClientUnrequestedInitializationDataReceived(const String& initDataType, Ref<SharedBuffer>&& initData)
+{
+ mediaPlayerInitializationDataEncountered(initDataType, initData->tryCreateArrayBuffer());
+}
+
#endif // ENABLE(ENCRYPTED_MEDIA)
void HTMLMediaElement::progressEventTimerFired()
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (258294 => 258295)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -701,6 +701,7 @@
// CDMClient
void cdmClientAttemptToResumePlaybackIfNecessary() final;
+ void cdmClientUnrequestedInitializationDataReceived(const String&, Ref<SharedBuffer>&&) final;
#endif
#if ENABLE(LEGACY_ENCRYPTED_MEDIA) && ENABLE(ENCRYPTED_MEDIA)
Modified: trunk/Source/WebCore/platform/encryptedmedia/CDMFactory.h (258294 => 258295)
--- trunk/Source/WebCore/platform/encryptedmedia/CDMFactory.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/platform/encryptedmedia/CDMFactory.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -32,6 +32,12 @@
#include <memory>
#include <wtf/Forward.h>
+#if !RELEASE_LOG_DISABLED
+namespace WTF {
+class Logger;
+}
+#endif
+
namespace WebCore {
class CDMPrivate;
Modified: trunk/Source/WebCore/platform/encryptedmedia/CDMInstance.h (258294 => 258295)
--- trunk/Source/WebCore/platform/encryptedmedia/CDMInstance.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/platform/encryptedmedia/CDMInstance.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -36,7 +36,14 @@
#include <wtf/RefCounted.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/TypeCasts.h>
+#include <wtf/WeakPtr.h>
+#if !RELEASE_LOG_DISABLED
+namespace WTF {
+class Logger;
+}
+#endif
+
namespace WebCore {
class SharedBuffer;
@@ -43,6 +50,13 @@
class CDMInstanceSession;
struct CDMKeySystemConfiguration;
+class CDMInstanceClient : public CanMakeWeakPtr<CDMInstanceClient> {
+public:
+ virtual ~CDMInstanceClient() = default;
+
+ virtual void unrequestedInitializationDataReceived(const String&, Ref<SharedBuffer>&&) = 0;
+};
+
// _javascript_'s handle to a CDMInstance, must be used from the
// main-thread only!
class CDMInstance : public RefCounted<CDMInstance> {
@@ -49,6 +63,13 @@
public:
virtual ~CDMInstance() = default;
+ virtual void setClient(WeakPtr<CDMInstanceClient>&&) { }
+ virtual void clearClient() { }
+
+#if !RELEASE_LOG_DISABLED
+ virtual void setLogger(WTF::Logger&, const void*) { }
+#endif
+
enum class ImplementationType {
Mock,
ClearKey,
Modified: trunk/Source/WebCore/platform/encryptedmedia/CDMInstanceSession.h (258294 => 258295)
--- trunk/Source/WebCore/platform/encryptedmedia/CDMInstanceSession.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/platform/encryptedmedia/CDMInstanceSession.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -35,6 +35,12 @@
#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>
+#if !RELEASE_LOG_DISABLED
+namespace WTF {
+class Logger;
+}
+#endif
+
namespace WebCore {
class SharedBuffer;
@@ -58,6 +64,10 @@
using LicenseType = CDMSessionType;
using MessageType = CDMMessageType;
+#if !RELEASE_LOG_DISABLED
+ virtual void setLogger(WTF::Logger&, const void*) { }
+#endif
+
virtual void setClient(WeakPtr<CDMInstanceSessionClient>&&) { }
virtual void clearClient() { }
Modified: trunk/Source/WebCore/platform/encryptedmedia/CDMPrivate.h (258294 => 258295)
--- trunk/Source/WebCore/platform/encryptedmedia/CDMPrivate.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/platform/encryptedmedia/CDMPrivate.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -33,6 +33,12 @@
#include <wtf/Forward.h>
#include <wtf/WeakPtr.h>
+#if !RELEASE_LOG_DISABLED
+namespace WTF {
+class Logger;
+}
+#endif
+
namespace WebCore {
struct CDMKeySystemConfiguration;
@@ -43,6 +49,10 @@
public:
WEBCORE_EXPORT virtual ~CDMPrivate();
+#if !RELEASE_LOG_DISABLED
+ virtual void setLogger(WTF::Logger&, const void*) { };
+#endif
+
enum class LocalStorageAccess : bool {
NotAllowed,
Allowed,
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/CDMFairPlayStreaming.cpp (258294 => 258295)
--- trunk/Source/WebCore/platform/graphics/avfoundation/CDMFairPlayStreaming.cpp 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/CDMFairPlayStreaming.cpp 2020-03-11 23:49:59 UTC (rev 258295)
@@ -37,11 +37,13 @@
#include "ISOSchemeTypeBox.h"
#include "ISOTrackEncryptionBox.h"
#include "InitDataRegistry.h"
+#include "Logging.h"
#include "NotImplemented.h"
#include <_javascript_Core/ArrayBuffer.h>
#include <_javascript_Core/DataView.h>
#include <wtf/Algorithms.h>
#include <wtf/JSONValues.h>
+#include <wtf/LoggerHelper.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/Base64.h>
@@ -55,6 +57,10 @@
namespace WebCore {
+#if !RELEASE_LOG_DISABLED
+static WTFLogChannel& logChannel() { return LogEME; }
+#endif
+
const Vector<FourCC>& CDMPrivateFairPlayStreaming::validFairPlayStreamingSchemes()
{
static NeverDestroyed<Vector<FourCC>> validSchemes = Vector<FourCC>({
@@ -250,6 +256,14 @@
CDMPrivateFairPlayStreaming::CDMPrivateFairPlayStreaming() = default;
CDMPrivateFairPlayStreaming::~CDMPrivateFairPlayStreaming() = default;
+#if !RELEASE_LOG_DISABLED
+void CDMPrivateFairPlayStreaming::setLogger(Logger& logger, const void* logIdentifier)
+{
+ m_logger = makeRefPtr(logger);
+ m_logIdentifier = logIdentifier;
+}
+#endif
+
Vector<AtomString> CDMPrivateFairPlayStreaming::supportedInitDataTypes() const
{
return copyToVector(validInitDataTypes());
@@ -257,33 +271,47 @@
bool CDMPrivateFairPlayStreaming::supportsConfiguration(const CDMKeySystemConfiguration& configuration) const
{
- if (!WTF::anyOf(configuration.initDataTypes, [] (auto& initDataType) { return validInitDataTypes().contains(initDataType); }))
+ if (!WTF::anyOf(configuration.initDataTypes, [] (auto& initDataType) { return validInitDataTypes().contains(initDataType); })) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " false, no initDataType supported");
return false;
+ }
#if HAVE(AVCONTENTKEYSESSION)
// FIXME: verify that FairPlayStreaming does not (and cannot) expose a distinctive identifier to the client
- if (configuration.distinctiveIdentifier == CDMRequirement::Required)
+ if (configuration.distinctiveIdentifier == CDMRequirement::Required) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "false, requried distinctiveIdentifier not supported");
return false;
- if (configuration.persistentState == CDMRequirement::Required && !CDMInstanceFairPlayStreamingAVFObjC::supportsPersistableState())
+ }
+
+ if (configuration.persistentState == CDMRequirement::Required && !CDMInstanceFairPlayStreamingAVFObjC::supportsPersistableState()) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "false, required persistentState not supported");
return false;
+ }
if (configuration.sessionTypes.contains(CDMSessionType::PersistentLicense)
&& !configuration.sessionTypes.contains(CDMSessionType::Temporary)
- && !CDMInstanceFairPlayStreamingAVFObjC::supportsPersistentKeys())
+ && !CDMInstanceFairPlayStreamingAVFObjC::supportsPersistentKeys()) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "false, sessionType PersistentLicense not supported");
return false;
+ }
if (!configuration.audioCapabilities.isEmpty()
&& !WTF::anyOf(configuration.audioCapabilities, [](auto& capability) {
return CDMInstanceFairPlayStreamingAVFObjC::supportsMediaCapability(capability);
- }))
+ })) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "false, no audio configuration supported");
return false;
+ }
if (!configuration.videoCapabilities.isEmpty()
&& !WTF::anyOf(configuration.videoCapabilities, [](auto& capability) {
return CDMInstanceFairPlayStreamingAVFObjC::supportsMediaCapability(capability);
- }))
+ })) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "false, no video configuration supported");
return false;
+ }
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "true, supported");
return true;
#else
return false;
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/CDMFairPlayStreaming.h (258294 => 258295)
--- trunk/Source/WebCore/platform/graphics/avfoundation/CDMFairPlayStreaming.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/CDMFairPlayStreaming.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -55,6 +55,10 @@
CDMPrivateFairPlayStreaming();
virtual ~CDMPrivateFairPlayStreaming();
+#if !RELEASE_LOG_DISABLED
+ void setLogger(WTF::Logger&, const void* logIdentifier) final;
+#endif
+
Vector<AtomString> supportedInitDataTypes() const override;
bool supportsConfiguration(const CDMKeySystemConfiguration&) const override;
bool supportsConfigurationWithRestrictions(const CDMKeySystemConfiguration&, const CDMRestrictions&) const override;
@@ -80,6 +84,16 @@
static RefPtr<SharedBuffer> sanitizeSkd(const SharedBuffer&);
static const Vector<FourCC>& validFairPlayStreamingSchemes();
+
+private:
+#if !RELEASE_LOG_DISABLED
+ WTF::Logger* loggerPtr() const { return m_logger.get(); };
+ const void* logIdentifier() const { return m_logIdentifier; }
+ const char* logClassName() const { return "CDMPrivateFairPlayStreaming"; }
+
+ RefPtr<WTF::Logger> m_logger;
+ const void* m_logIdentifier;
+#endif
};
}
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h (258294 => 258295)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h 2020-03-11 23:49:59 UTC (rev 258295)
@@ -42,6 +42,12 @@
OBJC_CLASS NSURL;
OBJC_CLASS WebCoreFPSContentKeySessionDelegate;
+#if !RELEASE_LOG_DISABLED
+namespace WTF {
+class Logger;
+}
+#endif
+
namespace WebCore {
class CDMInstanceSessionFairPlayStreamingAVFObjC;
@@ -67,6 +73,10 @@
CDMInstanceFairPlayStreamingAVFObjC();
virtual ~CDMInstanceFairPlayStreamingAVFObjC() = default;
+#if !RELEASE_LOG_DISABLED
+ void setLogger(WTF::Logger&, const void* logIdentifier);
+#endif
+
static bool supportsPersistableState();
static bool supportsPersistentKeys();
static bool supportsMediaCapability(const CDMMediaCapability&);
@@ -78,6 +88,8 @@
void setServerCertificate(Ref<SharedBuffer>&&, SuccessCallback&&) final;
void setStorageDirectory(const String&) final;
RefPtr<CDMInstanceSession> createSession() final;
+ void setClient(WeakPtr<CDMInstanceClient>&&) final;
+ void clearClient() final;
const String& keySystem() const final;
@@ -86,6 +98,8 @@
SharedBuffer* serverCertificate() const { return m_serverCertificate.get(); }
AVContentKeySession* contentKeySession();
+ RetainPtr<AVContentKeyRequest> takeUnexpectedKeyRequestForInitializationData(const AtomString& initDataType, SharedBuffer& initData);
+
// AVContentKeySessionDelegateClient
void didProvideRequest(AVContentKeyRequest*) final;
void didProvideRequests(Vector<RetainPtr<AVContentKeyRequest>>&&) final;
@@ -101,8 +115,16 @@
using Keys = Vector<Ref<SharedBuffer>>;
CDMInstanceSessionFairPlayStreamingAVFObjC* sessionForKeyIDs(const Keys&) const;
CDMInstanceSessionFairPlayStreamingAVFObjC* sessionForGroup(AVContentKeyReportGroup*) const;
+ CDMInstanceSessionFairPlayStreamingAVFObjC* sessionForRequest(AVContentKeyRequest*) const;
private:
+#if !RELEASE_LOG_DISABLED
+ WTF::Logger* loggerPtr() const { return m_logger.get(); };
+ const void* logIdentifier() const { return m_logIdentifier; }
+ const char* logClassName() const { return "CDMInstanceFairPlayStreamingAVFObjC"; }
+#endif
+
+ WeakPtr<CDMInstanceClient> m_client;
RetainPtr<AVContentKeySession> m_session;
RetainPtr<WebCoreFPSContentKeySessionDelegate> m_delegate;
RefPtr<SharedBuffer> m_serverCertificate;
@@ -109,6 +131,11 @@
bool m_persistentStateAllowed { true };
RetainPtr<NSURL> m_storageURL;
Vector<WeakPtr<CDMInstanceSessionFairPlayStreamingAVFObjC>> m_sessions;
+ HashSet<RetainPtr<AVContentKeyRequest>> m_unexpectedKeyRequests;
+#if !RELEASE_LOG_DISABLED
+ RefPtr<WTF::Logger> m_logger;
+ const void* m_logIdentifier { nullptr };
+#endif
};
class CDMInstanceSessionFairPlayStreamingAVFObjC final : public CDMInstanceSession, public AVContentKeySessionDelegateClient, public CanMakeWeakPtr<CDMInstanceSessionFairPlayStreamingAVFObjC> {
@@ -116,6 +143,10 @@
CDMInstanceSessionFairPlayStreamingAVFObjC(Ref<CDMInstanceFairPlayStreamingAVFObjC>&&);
virtual ~CDMInstanceSessionFairPlayStreamingAVFObjC();
+#if !RELEASE_LOG_DISABLED
+ void setLogger(WTF::Logger&, const void* logIdentifier);
+#endif
+
// CDMInstanceSession
void requestLicense(LicenseType, const AtomString& initDataType, Ref<SharedBuffer>&& initData, LicenseCallback&&) final;
void updateLicense(const String&, LicenseType, Ref<SharedBuffer>&&, LicenseUpdateCallback&&) final;
@@ -149,6 +180,8 @@
bool operator==(const Request& other) const { return initType == other.initType && requests == other.requests; }
};
+ bool hasRequest(AVContentKeyRequest*) const;
+
private:
bool ensureSessionOrGroup();
bool isLicenseTypeSupported(LicenseType) const;
@@ -157,6 +190,12 @@
void nextRequest();
AVContentKeyRequest* lastKeyRequest() const;
+#if !RELEASE_LOG_DISABLED
+ WTF::Logger* loggerPtr() const { return m_logger.get(); };
+ const void* logIdentifier() const { return m_logIdentifier; }
+ const char* logClassName() const { return "CDMInstanceSessionFairPlayStreamingAVFObjC"; }
+#endif
+
Ref<CDMInstanceFairPlayStreamingAVFObjC> m_instance;
RetainPtr<AVContentKeyReportGroup> m_group;
RetainPtr<AVContentKeySession> m_session;
@@ -177,6 +216,11 @@
LicenseUpdateCallback m_updateLicenseCallback;
CloseSessionCallback m_closeSessionCallback;
RemoveSessionDataCallback m_removeSessionDataCallback;
+
+#if !RELEASE_LOG_DISABLED
+ RefPtr<WTF::Logger> m_logger;
+ const void* m_logIdentifier { nullptr };
+#endif
};
}
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm (258294 => 258295)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm 2020-03-11 23:27:19 UTC (rev 258294)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm 2020-03-11 23:49:59 UTC (rev 258295)
@@ -42,6 +42,7 @@
#import <wtf/Algorithms.h>
#import <wtf/FileSystem.h>
#import <wtf/JSONValues.h>
+#import <wtf/LoggerHelper.h>
#import <wtf/text/Base64.h>
#import <wtf/text/StringHash.h>
@@ -160,8 +161,41 @@
namespace WebCore {
+#if !RELEASE_LOG_DISABLED
+static WTFLogChannel& logChannel() { return LogEME; }
+#endif
+
+static AtomString initTypeForRequest(AVContentKeyRequest* request)
+{
+ if (![request respondsToSelector:@selector(options)]) {
+ // AVContentKeyRequest.options was added in 10.14.4; if we are running on a previous version
+ // we don't have support for 'cenc' anyway, so just assume 'sinf'.
+ return CDMPrivateFairPlayStreaming::sinfName();
+ }
+
+ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
+ auto nsInitType = (NSString*)[request.options valueForKey:InitializationDataTypeKey];
+ALLOW_NEW_API_WITHOUT_GUARDS_END
+ if (![nsInitType isKindOfClass:NSString.class]) {
+ // The only way for an initialization data to end up here without an appropriate key in
+ // the options dictionary is for that data to have been generated by the AVStreamDataParser
+ // and currently, the only initialization data supported by the parser is the 'sinf' kind.
+ return CDMPrivateFairPlayStreaming::sinfName();
+ }
+
+ return AtomString(nsInitType);
+}
+
CDMInstanceFairPlayStreamingAVFObjC::CDMInstanceFairPlayStreamingAVFObjC() = default;
+#if !RELEASE_LOG_DISABLED
+void CDMInstanceFairPlayStreamingAVFObjC::setLogger(Logger& logger, const void* logIdentifier)
+{
+ m_logger = makeRefPtr(logger);
+ m_logIdentifier = logIdentifier;
+}
+#endif
+
AVContentKeySession* CDMInstanceFairPlayStreamingAVFObjC::contentKeySession()
{
if (m_session)
@@ -189,6 +223,20 @@
return m_session.get();
}
+RetainPtr<AVContentKeyRequest> CDMInstanceFairPlayStreamingAVFObjC::takeUnexpectedKeyRequestForInitializationData(const AtomString& initDataType, SharedBuffer& initData)
+{
+ for (auto requestIter = m_unexpectedKeyRequests.begin(); requestIter != m_unexpectedKeyRequests.end(); ++requestIter) {
+ auto& request = *requestIter;
+ auto requestType = initTypeForRequest(request.get());
+ auto* requestInitData = request.get().initializationData;
+ if (initDataType != requestType || initData != SharedBuffer::create(requestInitData))
+ continue;
+
+ return m_unexpectedKeyRequests.take(requestIter);
+ }
+ return nullptr;
+}
+
class CDMInstanceSessionFairPlayStreamingAVFObjC::UpdateResponseCollector {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -295,6 +343,7 @@
void CDMInstanceFairPlayStreamingAVFObjC::setServerCertificate(Ref<SharedBuffer>&& serverCertificate, SuccessCallback&& callback)
{
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER);
m_serverCertificate = WTFMove(serverCertificate);
callback(Succeeded);
}
@@ -301,6 +350,7 @@
void CDMInstanceFairPlayStreamingAVFObjC::setStorageDirectory(const String& storageDirectory)
{
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER);
if (storageDirectory.isEmpty()) {
m_storageURL = nil;
return;
@@ -334,6 +384,16 @@
return session;
}
+void CDMInstanceFairPlayStreamingAVFObjC::setClient(WeakPtr<CDMInstanceClient>&& client)
+{
+ m_client = WTFMove(client);
+}
+
+void CDMInstanceFairPlayStreamingAVFObjC::clearClient()
+{
+ m_client = nullptr;
+}
+
const String& CDMInstanceFairPlayStreamingAVFObjC::keySystem() const
{
static NeverDestroyed<String> keySystem { "com.apple.fps"_s };
@@ -351,44 +411,81 @@
void CDMInstanceFairPlayStreamingAVFObjC::didProvideRequest(AVContentKeyRequest *request)
{
- if (auto* session = sessionForGroup(groupForRequest(request)))
+ if (auto* session = sessionForRequest(request)) {
session->didProvideRequest(request);
+ return;
+ }
+
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "- Unexpected request");
+
+ m_unexpectedKeyRequests.add(request);
+
+ if (m_client)
+ m_client->unrequestedInitializationDataReceived(initTypeForRequest(request), SharedBuffer::create(request.initializationData));
}
void CDMInstanceFairPlayStreamingAVFObjC::didProvideRequests(Vector<RetainPtr<AVContentKeyRequest>>&& requests)
{
- if (auto* session = sessionForGroup(groupForRequest(requests.first().get())))
+ if (auto* session = sessionForRequest(requests.first().get())) {
session->didProvideRequests(WTFMove(requests));
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+ ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "- no responsible session; dropping");
}
void CDMInstanceFairPlayStreamingAVFObjC::didProvideRenewingRequest(AVContentKeyRequest *request)
{
- if (auto* session = sessionForGroup(groupForRequest(request)))
+ if (auto* session = sessionForRequest(request)) {
session->didProvideRenewingRequest(request);
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+ ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "- no responsible session; dropping");
}
void CDMInstanceFairPlayStreamingAVFObjC::didProvidePersistableRequest(AVContentKeyRequest *request)
{
- if (auto* session = sessionForGroup(groupForRequest(request)))
+ if (auto* session = sessionForRequest(request)) {
session->didProvidePersistableRequest(request);
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+ ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "- no responsible session; dropping");
}
void CDMInstanceFairPlayStreamingAVFObjC::didFailToProvideRequest(AVContentKeyRequest *request, NSError *error)
{
- if (auto* session = sessionForGroup(groupForRequest(request)))
+ if (auto* session = sessionForRequest(request)) {
session->didFailToProvideRequest(request, error);
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+ ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "- no responsible session; dropping");
}
void CDMInstanceFairPlayStreamingAVFObjC::requestDidSucceed(AVContentKeyRequest *request)
{
- if (auto* session = sessionForGroup(groupForRequest(request)))
+ if (auto* session = sessionForRequest(request)) {
session->requestDidSucceed(request);
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+ ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "- no responsible session; dropping");
}
bool CDMInstanceFairPlayStreamingAVFObjC::shouldRetryRequestForReason(AVContentKeyRequest *request, NSString *reason)
{
- if (auto* session = sessionForGroup(groupForRequest(request)))
+ if (auto* session = sessionForRequest(request))
return session->shouldRetryRequestForReason(request, reason);
+
+ ASSERT_NOT_REACHED();
+ ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "- no responsible session; dropping");
return false;
}
@@ -401,8 +498,13 @@
void CDMInstanceFairPlayStreamingAVFObjC::groupSessionIdentifierChanged(AVContentKeyReportGroup* group, NSData *sessionIdentifier)
{
- if (auto* session = sessionForGroup(group))
+ if (auto* session = sessionForGroup(group)) {
session->groupSessionIdentifierChanged(group, sessionIdentifier);
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+ ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "- no responsible session; dropping");
}
void CDMInstanceFairPlayStreamingAVFObjC::outputObscuredDueToInsufficientExternalProtectionChanged(bool obscured)
@@ -428,6 +530,18 @@
return nullptr;
}
+CDMInstanceSessionFairPlayStreamingAVFObjC* CDMInstanceFairPlayStreamingAVFObjC::sessionForRequest(AVContentKeyRequest* request) const
+{
+ auto index = m_sessions.findMatching([&] (auto session) {
+ return session && session->hasRequest(request);
+ });
+
+ if (index != notFound)
+ return m_sessions[index].get();
+
+ return sessionForGroup(groupForRequest(request));
+}
+
CDMInstanceSessionFairPlayStreamingAVFObjC* CDMInstanceFairPlayStreamingAVFObjC::sessionForGroup(AVContentKeyReportGroup* group) const
{
auto index = m_sessions.findMatching([group] (auto session) {
@@ -450,6 +564,14 @@
[m_delegate invalidate];
}
+#if !RELEASE_LOG_DISABLED
+void CDMInstanceSessionFairPlayStreamingAVFObjC::setLogger(Logger& logger, const void* logIdentifier)
+{
+ m_logger = makeRefPtr(logger);
+ m_logIdentifier = logIdentifier;
+}
+#endif
+
using Keys = CDMInstanceSessionFairPlayStreamingAVFObjC::Keys;
static Keys keyIDsForRequest(AVContentKeyRequest* request)
{
@@ -473,27 +595,6 @@
return keyIDs;
}
-static AtomString initTypeForRequest(AVContentKeyRequest* request)
-{
- if (![request respondsToSelector:@selector(options)]) {
- // AVContentKeyRequest.options was added in 10.14.4; if we are running on a previous version
- // we don't have support for 'cenc' anyway, so just assume 'sinf'.
- return CDMPrivateFairPlayStreaming::sinfName();
- }
-
-ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
- auto nsInitType = (NSString*)[request.options valueForKey:InitializationDataTypeKey];
-ALLOW_NEW_API_WITHOUT_GUARDS_END
- if (![nsInitType isKindOfClass:NSString.class]) {
- // The only way for an initialization data to end up here without an appropriate key in
- // the options dictionary is for that data to have been generated by the AVStreamDataParser
- // and currently, the only initialization data supported by the parser is the 'sinf' kind.
- return CDMPrivateFairPlayStreaming::sinfName();
- }
-
- return AtomString(nsInitType);
-}
-
Keys CDMInstanceSessionFairPlayStreamingAVFObjC::keyIDs()
{
// FIXME(rdar://problem/35597141): use the future AVContentKeyRequest keyID property, rather than parsing it out of the init
@@ -510,20 +611,35 @@
void CDMInstanceSessionFairPlayStreamingAVFObjC::requestLicense(LicenseType licenseType, const AtomString& initDataType, Ref<SharedBuffer>&& initData, LicenseCallback&& callback)
{
if (!isLicenseTypeSupported(licenseType)) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " false, licenseType \"", licenseType, "\" not supported");
callback(SharedBuffer::create(), emptyString(), false, Failed);
return;
}
if (!m_instance->serverCertificate()) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " false, no serverCertificate");
callback(SharedBuffer::create(), emptyString(), false, Failed);
return;
}
if (!ensureSessionOrGroup()) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " false, could not create session or group object");
callback(SharedBuffer::create(), emptyString(), false, Failed);
return;
}
+ if (auto unexpectedRequest = m_instance->takeUnexpectedKeyRequestForInitializationData(initDataType, initData)) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " found unexpectedRequest matching initData");
+ if (m_group) {
+ ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
+ [m_group associateContentKeyRequest:unexpectedRequest.get()];
+ ALLOW_NEW_API_WITHOUT_GUARDS_END
+ }
+ m_requestLicenseCallback = WTFMove(callback);
+ didProvideRequest(unexpectedRequest.get());
+ return;
+ }
+
RetainPtr<NSString> identifier;
RetainPtr<NSData> initializationData;
@@ -538,10 +654,12 @@
}
#endif
else {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " false, initDataType not suppported");
callback(SharedBuffer::create(), emptyString(), false, Failed);
return;
}
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " processing request");
m_requestLicenseCallback = WTFMove(callback);
if (m_group) {
@@ -582,10 +700,12 @@
auto* storageURL = m_instance->storageURL();
if (!certificate || !storageURL) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "\"acknowledged\", Failed, no certificate and storageURL");
callback(false, WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed);
return;
}
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "\"acknowledged\", Succeeded, removing expired session report");
RetainPtr<NSData> appIdentifier = certificate->createNSData();
[PAL::getAVContentKeySessionClass() removePendingExpiredSessionReports:expiredSessions.get() withAppIdentifier:appIdentifier.get() storageDirectoryAtURL:storageURL];
callback(false, { }, WTF::nullopt, WTF::nullopt, Succeeded);
@@ -595,9 +715,11 @@
if (!m_requests.isEmpty() && isEqual(responseData, "renew"_s)) {
auto request = lastKeyRequest();
if (!request) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "\"renew\", Failed, no outstanding keys");
callback(false, WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed);
return;
}
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "\"renew\", processing renewal");
auto session = m_session ? m_session.get() : m_instance->contentKeySession();
[session renewExpiringResponseDataForContentKeyRequest:request];
m_updateLicenseCallback = WTFMove(callback);
@@ -605,11 +727,13 @@
}
if (!m_currentRequest) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Failed, no currentRequest");
callback(false, WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed);
return;
}
Keys keyIDs = keyIDsForRequest(m_currentRequest.value());
if (keyIDs.isEmpty()) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Failed, no keyIDs in currentRequest");
callback(false, WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed);
return;
}
@@ -628,10 +752,12 @@
return;
if (!responses || responses.value().isEmpty()) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "'cenc' initData, Failed, no responses");
m_updateLicenseCallback(true, WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed);
return;
}
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "'cenc' initData, Succeeded, no keyIDs in currentRequest");
m_updateLicenseCallback(false, keyStatuses(), WTF::nullopt, WTF::nullopt, Succeeded);
m_updateResponseCollector = nullptr;
m_currentRequest = WTF::nullopt;
@@ -697,12 +823,15 @@
};
for (auto value : *array) {
if (!parseResponse(value)) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "'cenc' initData, Failed, could not parse response");
callback(false, WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed);
return;
}
}
- } else
+ } else {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, "'sinf' initData, processing response");
[m_currentRequest.value().requests.first() processContentKeyResponse:[PAL::getAVContentKeyResponseClass() contentKeyResponseWithFairPlayStreamingKeyResponseData:responseData->createNSData().get()]];
+ }
// FIXME(rdar://problem/35592277): stash the callback and call it once AVContentKeyResponse supports a success callback.
struct objc_method_description method = protocol_getMethodDescription(@protocol(AVContentKeySessionDelegate), @selector(contentKeySession:contentKeyRequestDidSucceed:), NO, YES);
@@ -723,11 +852,13 @@
if (licenseType == LicenseType::PersistentUsageRecord) {
auto* storageURL = m_instance->storageURL();
if (!m_instance->persistentStateAllowed() || !storageURL) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Failed, mismatched session type");
callback(WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed, SessionLoadFailure::MismatchedSessionType);
return;
}
auto* certificate = m_instance->serverCertificate();
if (!certificate) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Failed, no sessionCertificate");
callback(WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed, SessionLoadFailure::NoSessionData);
return;
}
@@ -748,10 +879,12 @@
}
if (changedKeys.isEmpty()) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Failed, no session data found");
callback(WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed, SessionLoadFailure::NoSessionData);
return;
}
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Succeeded, mismatched session type");
callback(WTFMove(changedKeys), WTF::nullopt, WTF::nullopt, Succeeded, SessionLoadFailure::None);
}
}
@@ -758,6 +891,7 @@
void CDMInstanceSessionFairPlayStreamingAVFObjC::closeSession(const String&, CloseSessionCallback&& callback)
{
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER);
if (m_requestLicenseCallback) {
m_requestLicenseCallback(SharedBuffer::create(), m_sessionId, false, Failed);
ASSERT(!m_requestLicenseCallback);
@@ -788,6 +922,7 @@
auto* certificate = m_instance->serverCertificate();
if (!m_instance->persistentStateAllowed() || !storageURL || !certificate) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Failed, persistentState not allowed or no storageURL or no certificate");
callback({ }, WTF::nullopt, Failed);
return;
}
@@ -810,6 +945,7 @@
}
if (!expiredSessionsArray.get().count) {
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Succeeded, no expired sessions");
callback(WTFMove(changedKeys), WTF::nullopt, Succeeded);
return;
}
@@ -819,6 +955,7 @@
// It should not be possible to have a persistent-usage-record session that does not generate
// a persistent-usage-record message on close. Signal this by failing and assert.
ASSERT_NOT_REACHED();
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Failed, no expired session data");
callback(WTFMove(changedKeys), WTF::nullopt, Failed);
return;
}
@@ -828,8 +965,9 @@
RetainPtr<NSData> expiredSessionsData = [NSPropertyListSerialization dataWithPropertyList:propertyList format:NSPropertyListBinaryFormat_v1_0 options:kCFPropertyListImmutable error:nullptr];
if (expiredSessionsCount > 1)
- RELEASE_LOG(EME, "Multiple(%lu) expired session reports found with same sessionID(%s)!", expiredSessionsCount, sessionId.utf8().data());
+ ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "Multiple(", expiredSessionsCount, ") expired session reports found with same sessionID(", sessionId, ")!");
+ DEBUG_LOG_IF_POSSIBLE(LOGIDENTIFIER, " Succeeded");
callback(WTFMove(changedKeys), SharedBuffer::create(expiredSessionsData.get()), Succeeded);
}
}
@@ -1113,6 +1251,15 @@
return lastRequest.requests.last().get();
}
+bool CDMInstanceSessionFairPlayStreamingAVFObjC::hasRequest(AVContentKeyRequest* keyRequest) const
+{
+ for (auto& request : m_requests) {
+ if (request.requests.contains(keyRequest))
+ return true;
+ }
+ return false;
+}
+
bool CDMInstanceSessionFairPlayStreamingAVFObjC::shouldRetryRequestForReason(AVContentKeyRequest *request, NSString *reason)
{
UNUSED_PARAM(request);