Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Unified Diff: media/blink/webcontentdecryptionmodulesession_impl.cc

Issue 2484873002: EME: Make sure sessions are closed before they are destroyed (Closed)
Patch Set: update spec comment Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/blink/webcontentdecryptionmodulesession_impl.cc
diff --git a/media/blink/webcontentdecryptionmodulesession_impl.cc b/media/blink/webcontentdecryptionmodulesession_impl.cc
index ab138e7447d95a9786b94b88895939907fe4ab60..0c431f8cb17f4291076aec3a10b08a21c8c96603 100644
--- a/media/blink/webcontentdecryptionmodulesession_impl.cc
+++ b/media/blink/webcontentdecryptionmodulesession_impl.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -224,16 +225,53 @@ static bool SanitizeResponse(const std::string& key_system,
return true;
}
+// If we need to close the session while destroying this object, we need a
+// dummy promise that won't call back into this object (or try to pass
+// something back to blink).
+class IgnoreResponsePromise : public SimpleCdmPromise {
xhwang 2016/11/11 18:52:46 move this to an anonymous namespace, maybe togethe
jrummell 2016/11/11 21:14:23 Done.
+ public:
+ IgnoreResponsePromise() {}
+ ~IgnoreResponsePromise() override {}
+
+ // SimpleCdmPromise implementation.
+ void resolve() final { MarkPromiseSettled(); }
+ void reject(CdmPromise::Exception exception_code,
+ uint32_t system_code,
+ const std::string& error_message) final {
+ MarkPromiseSettled();
+ }
+};
+
WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl(
const scoped_refptr<CdmSessionAdapter>& adapter)
- : adapter_(adapter), is_closed_(false), weak_ptr_factory_(this) {
-}
+ : adapter_(adapter),
+ is_closed_(false),
+ has_close_been_called_(false),
+ weak_ptr_factory_(this) {}
WebContentDecryptionModuleSessionImpl::
~WebContentDecryptionModuleSessionImpl() {
DCHECK(thread_checker_.CalledOnValidThread());
- if (!session_id_.empty())
+
+ if (!session_id_.empty()) {
adapter_->UnregisterSession(session_id_);
+
+ // From http://w3c.github.io/encrypted-media/#mediakeysession-interface
+ // "If a MediaKeySession object is not closed when it becomes inaccessible
+ // to the page, the CDM shall close the key session associated with the
+ // object."
+ //
+ // This object is destroyed when the corresponding blink object is no
+ // longer needed (which may be due to it becoming inaccessible to the
+ // page), so if the session is not closed and CloseSession() has not yet
+ // been called, call CloseSession() now. Since this object is being
+ // destroyed, there is no need for the promise to do anything as this
+ // session will be gone.
+ if (!is_closed_ && !has_close_been_called_) {
xhwang 2016/11/11 18:52:46 There's a corner case where the CDM may self-close
jrummell 2016/11/11 21:14:23 Acknowledged.
+ adapter_->CloseSession(session_id_,
+ base::MakeUnique<IgnoreResponsePromise>());
+ }
+ }
}
void WebContentDecryptionModuleSessionImpl::setClientInterface(Client* client) {
@@ -394,6 +432,8 @@ void WebContentDecryptionModuleSessionImpl::close(
blink::WebContentDecryptionModuleResult result) {
DCHECK(!session_id_.empty());
DCHECK(thread_checker_.CalledOnValidThread());
xhwang 2016/11/11 18:52:46 DCHECK(!has_close_been_called_) since we can't clo
jrummell 2016/11/11 21:14:23 Done. We shouldn't call close() if |is_closed_| is
+
+ has_close_been_called_ = true;
adapter_->CloseSession(
session_id_,
std::unique_ptr<SimpleCdmPromise>(new CdmResultPromise<>(

Powered by Google App Engine
This is Rietveld 408576698