Bug 1102852 - add MediaKeyMessageType to and remove destinationURL from MediaKeyMessageEvent. r=cpearce,bz a=lmandel ba=lmandel
authorJW Wang <jwwang@mozilla.com>
Thu, 15 Jan 2015 11:25:47 +1300
changeset 250168 c7d212eecc8e
parent 250166 d29e62045cc8
child 250169 6195599f25e0
push id4521
push usercpearce@mozilla.com
push date2015-03-04 01:22 +0000
treeherdermozilla-beta@8abdbdecd2d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, bz, lmandel
bugs1102852
milestone37.0
Bug 1102852 - add MediaKeyMessageType to and remove destinationURL from MediaKeyMessageEvent. r=cpearce,bz a=lmandel ba=lmandel
dom/media/eme/CDMCallbackProxy.cpp
dom/media/eme/CDMCallbackProxy.h
dom/media/eme/CDMProxy.cpp
dom/media/eme/CDMProxy.h
dom/media/eme/MediaKeyMessageEvent.cpp
dom/media/eme/MediaKeyMessageEvent.h
dom/media/eme/MediaKeySession.cpp
dom/media/eme/MediaKeySession.h
dom/media/gmp-plugin/fake.info
dom/media/gmp-plugin/gmp-test-decryptor.cpp
dom/media/gmp/GMPDecryptorChild.cpp
dom/media/gmp/GMPDecryptorChild.h
dom/media/gmp/GMPDecryptorParent.cpp
dom/media/gmp/GMPDecryptorParent.h
dom/media/gmp/GMPDecryptorProxy.h
dom/media/gmp/GMPMessageUtils.h
dom/media/gmp/PGMPDecryptor.ipdl
dom/media/gmp/gmp-api/gmp-decryption.h
dom/media/gtest/TestGMPCrossOrigin.cpp
dom/webidl/MediaKeyMessageEvent.webidl
media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
media/gmp-clearkey/0.1/clearkey.info
--- a/dom/media/eme/CDMCallbackProxy.cpp
+++ b/dom/media/eme/CDMCallbackProxy.cpp
@@ -136,49 +136,49 @@ CDMCallbackProxy::RejectPromise(uint32_t
                                aMessage);
   NS_DispatchToMainThread(task);
 }
 
 class SessionMessageTask : public nsRunnable {
 public:
   SessionMessageTask(CDMProxy* aProxy,
                      const nsCString& aSessionId,
-                     const nsTArray<uint8_t>& aMessage,
-                     const nsCString& aDestinationURL)
+                     GMPSessionMessageType aMessageType,
+                     const nsTArray<uint8_t>& aMessage)
     : mProxy(aProxy)
     , mSid(NS_ConvertUTF8toUTF16(aSessionId))
-    , mURL(NS_ConvertUTF8toUTF16(aDestinationURL))
+    , mMsgType(aMessageType)
   {
     mMsg.AppendElements(aMessage);
   }
 
   NS_IMETHOD Run() {
-    mProxy->OnSessionMessage(mSid, mMsg, mURL);
+    mProxy->OnSessionMessage(mSid, mMsgType, mMsg);
     return NS_OK;
   }
 
   nsRefPtr<CDMProxy> mProxy;
   dom::PromiseId mPid;
   nsString mSid;
+  GMPSessionMessageType mMsgType;
   nsTArray<uint8_t> mMsg;
-  nsString mURL;
 };
 
 void
 CDMCallbackProxy::SessionMessage(const nsCString& aSessionId,
-                                 const nsTArray<uint8_t>& aMessage,
-                                 const nsCString& aDestinationURL)
+                                 GMPSessionMessageType aMessageType,
+                                 const nsTArray<uint8_t>& aMessage)
 {
   MOZ_ASSERT(mProxy->IsOnGMPThread());
 
   nsRefPtr<nsIRunnable> task;
   task = new SessionMessageTask(mProxy,
                                 aSessionId,
-                                aMessage,
-                                aDestinationURL);
+                                aMessageType,
+                                aMessage);
   NS_DispatchToMainThread(task);
 }
 
 class ExpirationChangeTask : public nsRunnable {
 public:
   ExpirationChangeTask(CDMProxy* aProxy,
                        const nsCString& aSessionId,
                        GMPTimestamp aExpiryTime)
--- a/dom/media/eme/CDMCallbackProxy.h
+++ b/dom/media/eme/CDMCallbackProxy.h
@@ -25,18 +25,18 @@ public:
 
   virtual void ResolvePromise(uint32_t aPromiseId) MOZ_OVERRIDE;
 
   virtual void RejectPromise(uint32_t aPromiseId,
                              nsresult aException,
                              const nsCString& aSessionId) MOZ_OVERRIDE;
 
   virtual void SessionMessage(const nsCString& aSessionId,
-                              const nsTArray<uint8_t>& aMessage,
-                              const nsCString& aDestinationURL) MOZ_OVERRIDE;
+                              GMPSessionMessageType aMessageType,
+                              const nsTArray<uint8_t>& aMessage) MOZ_OVERRIDE;
 
   virtual void ExpirationChange(const nsCString& aSessionId,
                                 GMPTimestamp aExpiryTime) MOZ_OVERRIDE;
 
   virtual void SessionClosed(const nsCString& aSessionId) MOZ_OVERRIDE;
 
   virtual void SessionError(const nsCString& aSessionId,
                             nsresult aException,
--- a/dom/media/eme/CDMProxy.cpp
+++ b/dom/media/eme/CDMProxy.cpp
@@ -404,28 +404,38 @@ CDMProxy::OnResolveLoadSessionPromise(ui
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   mKeys->OnSessionLoaded(aPromiseId, aSuccess);
 }
 
+static dom::MediaKeyMessageType
+ToMediaKeyMessageType(GMPSessionMessageType aMessageType) {
+  switch (aMessageType) {
+    case kGMPLicenseRequest: return dom::MediaKeyMessageType::License_request;
+    case kGMPLicenseRenewal: return dom::MediaKeyMessageType::License_renewal;
+    case kGMPLicenseRelease: return dom::MediaKeyMessageType::License_release;
+    default: return dom::MediaKeyMessageType::License_request;
+  };
+};
+
 void
 CDMProxy::OnSessionMessage(const nsAString& aSessionId,
-                           nsTArray<uint8_t>& aMessage,
-                           const nsAString& aDestinationURL)
+                           GMPSessionMessageType aMessageType,
+                           nsTArray<uint8_t>& aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
   nsRefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
   if (session) {
-    session->DispatchKeyMessage(aMessage, aDestinationURL);
+    session->DispatchKeyMessage(ToMediaKeyMessageType(aMessageType), aMessage);
   }
 }
 
 void
 CDMProxy::OnKeysChange(const nsAString& aSessionId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
--- a/dom/media/eme/CDMProxy.h
+++ b/dom/media/eme/CDMProxy.h
@@ -115,18 +115,18 @@ public:
   void OnSetSessionId(uint32_t aCreateSessionToken,
                       const nsAString& aSessionId);
 
   // Main thread only.
   void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess);
 
   // Main thread only.
   void OnSessionMessage(const nsAString& aSessionId,
-                        nsTArray<uint8_t>& aMessage,
-                        const nsAString& aDestinationURL);
+                        GMPSessionMessageType aMessageType,
+                        nsTArray<uint8_t>& aMessage);
 
   // Main thread only.
   void OnExpirationChange(const nsAString& aSessionId,
                           GMPTimestamp aExpiryTime);
 
   // Main thread only.
   void OnSessionClosed(const nsAString& aSessionId);
 
--- a/dom/media/eme/MediaKeyMessageEvent.cpp
+++ b/dom/media/eme/MediaKeyMessageEvent.cpp
@@ -58,23 +58,23 @@ MediaKeyMessageEvent::AsMediaKeyMessageE
 JSObject*
 MediaKeyMessageEvent::WrapObjectInternal(JSContext* aCx)
 {
   return MediaKeyMessageEventBinding::Wrap(aCx, this);
 }
 
 already_AddRefed<MediaKeyMessageEvent>
 MediaKeyMessageEvent::Constructor(EventTarget* aOwner,
-                                  const nsAString& aURL,
+                                  MediaKeyMessageType aMessageType,
                                   const nsTArray<uint8_t>& aMessage)
 {
   nsRefPtr<MediaKeyMessageEvent> e = new MediaKeyMessageEvent(aOwner);
   e->InitEvent(NS_LITERAL_STRING("message"), false, false);
+  e->mMessageType = aMessageType;
   e->mRawMessage = aMessage;
-  e->mDestinationURL = aURL;
   e->SetTrusted(true);
   return e.forget();
 }
 
 already_AddRefed<MediaKeyMessageEvent>
 MediaKeyMessageEvent::Constructor(const GlobalObject& aGlobal,
                                   const nsAString& aType,
                                   const MediaKeyMessageEventInit& aEventInitDict,
@@ -92,17 +92,17 @@ MediaKeyMessageEvent::Constructor(const 
     data = a.Data();
     length = a.Length();
   }
   e->mMessage = ArrayBuffer::Create(aGlobal.Context(), length, data);
   if (!e->mMessage) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
-  e->mDestinationURL = aEventInitDict.mDestinationURL;
+  e->mMessageType = aEventInitDict.mMessageType;
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 void
 MediaKeyMessageEvent::GetMessage(JSContext* cx,
                                  JS::MutableHandle<JSObject*> aMessage,
                                  ErrorResult& aRv)
@@ -116,16 +116,10 @@ MediaKeyMessageEvent::GetMessage(JSConte
       return;
     }
     mRawMessage.Clear();
   }
   JS::ExposeObjectToActiveJS(mMessage);
   aMessage.set(mMessage);
 }
 
-void
-MediaKeyMessageEvent::GetDestinationURL(nsString& aRetVal) const
-{
-  aRetVal = mDestinationURL;
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/eme/MediaKeyMessageEvent.h
+++ b/dom/media/eme/MediaKeyMessageEvent.h
@@ -26,41 +26,41 @@ class MediaKeyMessageEvent MOZ_FINAL : p
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MediaKeyMessageEvent, Event)
 protected:
   virtual ~MediaKeyMessageEvent();
   explicit MediaKeyMessageEvent(EventTarget* aOwner);
 
+  MediaKeyMessageType mMessageType;
   JS::Heap<JSObject*> mMessage;
-  nsString mDestinationURL;
 
 public:
   virtual MediaKeyMessageEvent* AsMediaKeyMessageEvent();
 
   virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE;
 
   static already_AddRefed<MediaKeyMessageEvent>
-    Constructor(EventTarget* aOwner,
-                const nsAString& aURL,
-                const nsTArray<uint8_t>& aMessage);
+  Constructor(EventTarget* aOwner,
+              MediaKeyMessageType aMessageType,
+              const nsTArray<uint8_t>& aMessage);
 
   static already_AddRefed<MediaKeyMessageEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const MediaKeyMessageEventInit& aEventInitDict,
               ErrorResult& aRv);
 
+  MediaKeyMessageType MessageType() const { return mMessageType; }
+
   void GetMessage(JSContext* cx,
                   JS::MutableHandle<JSObject*> aMessage,
                   ErrorResult& aRv);
 
-  void GetDestinationURL(nsString& aRetVal) const;
-
 private:
   nsTArray<uint8_t> mRawMessage;
 };
 
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/media/eme/MediaKeySession.cpp
+++ b/dom/media/eme/MediaKeySession.cpp
@@ -272,21 +272,21 @@ MediaKeySession::GetUsableKeyIds(ErrorRe
     array.AppendElement(keyIds[i]);
   }
   promise->MaybeResolve(array);
 
   return promise.forget();
 }
 
 void
-MediaKeySession::DispatchKeyMessage(const nsTArray<uint8_t>& aMessage,
-                                    const nsAString& aURL)
+MediaKeySession::DispatchKeyMessage(MediaKeyMessageType aMessageType,
+                                    const nsTArray<uint8_t>& aMessage)
 {
   nsRefPtr<MediaKeyMessageEvent> event(
-    MediaKeyMessageEvent::Constructor(this, aURL, aMessage));
+    MediaKeyMessageEvent::Constructor(this, aMessageType, aMessage));
   nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
     new AsyncEventDispatcher(this, event);
   asyncDispatcher->PostDOMEvent();
 }
 
 void
 MediaKeySession::DispatchKeyError(uint32_t aSystemCode)
 {
--- a/dom/media/eme/MediaKeySession.h
+++ b/dom/media/eme/MediaKeySession.h
@@ -13,16 +13,17 @@
 #include "mozilla/DOMEventTargetHelper.h"
 #include "nsCOMPtr.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/dom/Date.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/MediaKeySessionBinding.h"
 #include "mozilla/dom/MediaKeysBinding.h"
+#include "mozilla/dom/MediaKeyMessageEventBinding.h"
 
 struct JSContext;
 
 namespace mozilla {
 
 class CDMProxy;
 
 namespace dom {
@@ -74,18 +75,18 @@ public:
                                    ErrorResult& aRv);
 
   already_AddRefed<Promise> Close(ErrorResult& aRv);
 
   already_AddRefed<Promise> Remove(ErrorResult& aRv);
 
   already_AddRefed<Promise> GetUsableKeyIds(ErrorResult& aRv);
 
-  void DispatchKeyMessage(const nsTArray<uint8_t>& aMessage,
-                          const nsAString& aURL);
+  void DispatchKeyMessage(MediaKeyMessageType aMessageType,
+                          const nsTArray<uint8_t>& aMessage);
 
   void DispatchKeyError(uint32_t system_code);
 
   void DispatchKeysChange();
 
   void OnClosed();
 
   bool IsClosed() const;
--- a/dom/media/gmp-plugin/fake.info
+++ b/dom/media/gmp-plugin/fake.info
@@ -1,5 +1,5 @@
 Name: fake
 Description: Fake GMP Plugin
 Version: 1.0
-APIs: encode-video[h264], decode-video[h264], eme-decrypt-v2[fake]
+APIs: encode-video[h264], decode-video[h264], eme-decrypt-v3[fake]
 Libraries: dxva2.dll
--- a/dom/media/gmp-plugin/gmp-test-decryptor.cpp
+++ b/dom/media/gmp-plugin/gmp-test-decryptor.cpp
@@ -111,18 +111,18 @@ void FakeDecryptor::DecryptingComplete()
 }
 
 void
 FakeDecryptor::Message(const std::string& aMessage)
 {
   MOZ_ASSERT(sInstance);
   const static std::string sid("fake-session-id");
   sInstance->mCallback->SessionMessage(sid.c_str(), sid.size(),
-                                       (const uint8_t*)aMessage.c_str(), aMessage.size(),
-                                       nullptr, 0);
+                                       kGMPLicenseRequest,
+                                       (const uint8_t*)aMessage.c_str(), aMessage.size());
 }
 
 std::vector<std::string>
 Tokenize(const std::string& aString)
 {
   std::stringstream strstr(aString);
   std::istream_iterator<std::string> it(strstr), end;
   return std::vector<std::string>(it, end);
--- a/dom/media/gmp/GMPDecryptorChild.cpp
+++ b/dom/media/gmp/GMPDecryptorChild.cpp
@@ -78,26 +78,25 @@ GMPDecryptorChild::RejectPromise(uint32_
 {
   CALL_ON_GMP_THREAD(SendRejectPromise,
                      aPromiseId, aException, nsAutoCString(aMessage, aMessageLength));
 }
 
 void
 GMPDecryptorChild::SessionMessage(const char* aSessionId,
                                   uint32_t aSessionIdLength,
+                                  GMPSessionMessageType aMessageType,
                                   const uint8_t* aMessage,
-                                  uint32_t aMessageLength,
-                                  const char* aDestinationURL,
-                                  uint32_t aDestinationURLLength)
+                                  uint32_t aMessageLength)
 {
   nsTArray<uint8_t> msg;
   msg.AppendElements(aMessage, aMessageLength);
   CALL_ON_GMP_THREAD(SendSessionMessage,
-                     nsAutoCString(aSessionId, aSessionIdLength), msg,
-                     nsAutoCString(aDestinationURL, aDestinationURLLength));
+                     nsAutoCString(aSessionId, aSessionIdLength),
+                     aMessageType, msg);
 }
 
 void
 GMPDecryptorChild::ExpirationChange(const char* aSessionId,
                                     uint32_t aSessionIdLength,
                                     GMPTimestamp aExpiryTime)
 {
   CALL_ON_GMP_THREAD(SendExpirationChange,
--- a/dom/media/gmp/GMPDecryptorChild.h
+++ b/dom/media/gmp/GMPDecryptorChild.h
@@ -40,20 +40,19 @@ public:
 
   virtual void RejectPromise(uint32_t aPromiseId,
                              GMPDOMException aException,
                              const char* aMessage,
                              uint32_t aMessageLength) MOZ_OVERRIDE;
 
   virtual void SessionMessage(const char* aSessionId,
                               uint32_t aSessionIdLength,
+                              GMPSessionMessageType aMessageType,
                               const uint8_t* aMessage,
-                              uint32_t aMessageLength,
-                              const char* aDestinationURL,
-                              uint32_t aDestinationURLLength) MOZ_OVERRIDE;
+                              uint32_t aMessageLength) MOZ_OVERRIDE;
 
   virtual void ExpirationChange(const char* aSessionId,
                                  uint32_t aSessionIdLength,
                                  GMPTimestamp aExpiryTime) MOZ_OVERRIDE;
 
    virtual void SessionClosed(const char* aSessionId,
                              uint32_t aSessionIdLength) MOZ_OVERRIDE;
 
--- a/dom/media/gmp/GMPDecryptorParent.cpp
+++ b/dom/media/gmp/GMPDecryptorParent.cpp
@@ -208,24 +208,24 @@ GMPDecryptorParent::RecvRejectPromise(co
     return false;
   }
   mCallback->RejectPromise(aPromiseId, GMPExToNsresult(aException), aMessage);
   return true;
 }
 
 bool
 GMPDecryptorParent::RecvSessionMessage(const nsCString& aSessionId,
-                                       const nsTArray<uint8_t>& aMessage,
-                                       const nsCString& aDestinationURL)
+                                       const GMPSessionMessageType& aMessageType,
+                                       const nsTArray<uint8_t>& aMessage)
 {
   if (!mIsOpen) {
     NS_WARNING("Trying to use a dead GMP decrypter!");
     return false;
   }
-  mCallback->SessionMessage(aSessionId, aMessage, aDestinationURL);
+  mCallback->SessionMessage(aSessionId, aMessageType, aMessage);
   return true;
 }
 
 bool
 GMPDecryptorParent::RecvExpirationChange(const nsCString& aSessionId,
                                          const double& aExpiryTime)
 {
   if (!mIsOpen) {
--- a/dom/media/gmp/GMPDecryptorParent.h
+++ b/dom/media/gmp/GMPDecryptorParent.h
@@ -73,18 +73,18 @@ private:
 
   virtual bool RecvResolvePromise(const uint32_t& aPromiseId) MOZ_OVERRIDE;
 
   virtual bool RecvRejectPromise(const uint32_t& aPromiseId,
                                  const GMPDOMException& aException,
                                  const nsCString& aMessage) MOZ_OVERRIDE;
 
   virtual bool RecvSessionMessage(const nsCString& aSessionId,
-                                  const nsTArray<uint8_t>& aMessage,
-                                  const nsCString& aDestinationURL) MOZ_OVERRIDE;
+                                  const GMPSessionMessageType& aMessageType,
+                                  const nsTArray<uint8_t>& aMessage) MOZ_OVERRIDE;
 
   virtual bool RecvExpirationChange(const nsCString& aSessionId,
                                     const double& aExpiryTime) MOZ_OVERRIDE;
 
   virtual bool RecvSessionClosed(const nsCString& aSessionId) MOZ_OVERRIDE;
 
   virtual bool RecvSessionError(const nsCString& aSessionId,
                                 const GMPDOMException& aException,
--- a/dom/media/gmp/GMPDecryptorProxy.h
+++ b/dom/media/gmp/GMPDecryptorProxy.h
@@ -26,18 +26,18 @@ public:
 
   virtual void ResolvePromise(uint32_t aPromiseId) = 0;
 
   virtual void RejectPromise(uint32_t aPromiseId,
                              nsresult aException,
                              const nsCString& aSessionId) = 0;
 
   virtual void SessionMessage(const nsCString& aSessionId,
-                              const nsTArray<uint8_t>& aMessage,
-                              const nsCString& aDestinationURL) = 0;
+                              GMPSessionMessageType aMessageType,
+                              const nsTArray<uint8_t>& aMessage) = 0;
 
   virtual void ExpirationChange(const nsCString& aSessionId,
                                 GMPTimestamp aExpiryTime) = 0;
 
   virtual void SessionClosed(const nsCString& aSessionId) = 0;
 
   virtual void SessionError(const nsCString& aSessionId,
                             nsresult aException,
--- a/dom/media/gmp/GMPMessageUtils.h
+++ b/dom/media/gmp/GMPMessageUtils.h
@@ -49,16 +49,23 @@ struct ParamTraits<GMPVideoFrameType>
 {};
 
 template<>
 struct ParamTraits<GMPDOMException>
 : public EnumSerializer<GMPDOMException, GMPDomExceptionValidator>
 {};
 
 template <>
+struct ParamTraits<GMPSessionMessageType>
+: public ContiguousEnumSerializer<GMPSessionMessageType,
+                                  kGMPLicenseRequest,
+                                  kGMPMessageInvalid>
+{};
+
+template <>
 struct ParamTraits<GMPSessionType>
 : public ContiguousEnumSerializer<GMPSessionType,
                                   kGMPTemporySession,
                                   kGMPSessionInvalid>
 {};
 
 template <>
 struct ParamTraits<GMPAudioCodecType>
--- a/dom/media/gmp/PGMPDecryptor.ipdl
+++ b/dom/media/gmp/PGMPDecryptor.ipdl
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PGMP;
 include GMPTypes;
 
+using GMPSessionMessageType from  "gmp-decryption.h";
 using GMPSessionType from  "gmp-decryption.h";
 using GMPDOMException from "gmp-decryption.h";
 using GMPErr from "gmp-errors.h";
 
 namespace mozilla {
 namespace gmp {
 
 async protocol PGMPDecryptor
@@ -59,18 +60,18 @@ parent:
 
   ResolvePromise(uint32_t aPromiseId);
 
   RejectPromise(uint32_t aPromiseId,
                 GMPDOMException aDOMExceptionCode,
                 nsCString aMessage);
 
   SessionMessage(nsCString aSessionId,
-                 uint8_t[] aMessage,
-                 nsCString aDestinationURL);
+                 GMPSessionMessageType aMessageType,
+                 uint8_t[] aMessage);
 
   ExpirationChange(nsCString aSessionId, double aExpiryTime);
 
   SessionClosed(nsCString aSessionId);
 
   SessionError(nsCString aSessionId,
                GMPDOMException aDOMExceptionCode,
                uint32_t aSystemCode,
--- a/dom/media/gmp/gmp-api/gmp-decryption.h
+++ b/dom/media/gmp/gmp-api/gmp-decryption.h
@@ -63,16 +63,23 @@ enum GMPDOMException {
   kGMPInvalidModificationError = 13,
   kGMPInvalidAccessError = 15,
   kGMPSecurityError = 18,
   kGMPAbortError = 20,
   kGMPQuotaExceededError = 22,
   kGMPTimeoutError = 23
 };
 
+enum GMPSessionMessageType {
+  kGMPLicenseRequest = 0,
+  kGMPLicenseRenewal = 1,
+  kGMPLicenseRelease = 2,
+  kGMPMessageInvalid = 3 // Must always be last.
+};
+
 // Time in milliseconds, as offset from epoch, 1 Jan 1970.
 typedef int64_t GMPTimestamp;
 
 // Capability definitions. The capabilities of the EME GMP are reported
 // to Gecko by calling the GMPDecryptorCallback::SetCapabilities()
 // callback and specifying the logical OR of the GMP_EME_CAP_* flags below.
 //
 // Note the DECRYPT and the DECRYPT_AND_DECODE are mutually exclusive;
@@ -134,20 +141,19 @@ public:
                              const char* aMessage,
                              uint32_t aMessageLength) = 0;
 
   // Called by the CDM when it has a message for a session.
   // Length parameters should not include null termination.
   // aSessionId must be null terminated.
   virtual void SessionMessage(const char* aSessionId,
                               uint32_t aSessionIdLength,
+                              GMPSessionMessageType aMessageType,
                               const uint8_t* aMessage,
-                              uint32_t aMessageLength,
-                              const char* aDestinationURL,
-                              uint32_t aDestinationURLLength) = 0;
+                              uint32_t aMessageLength) = 0;
 
   // aSessionId must be null terminated.
    virtual void ExpirationChange(const char* aSessionId,
                                  uint32_t aSessionIdLength,
                                  GMPTimestamp aExpiryTime) = 0;
 
   // Called by the GMP when a session is closed. All file IO
   // that a session requires should be complete before calling this.
@@ -208,17 +214,17 @@ public:
 };
 
 enum GMPSessionType {
   kGMPTemporySession = 0,
   kGMPPersistentSession = 1,
   kGMPSessionInvalid = 2 // Must always be last.
 };
 
-#define GMP_API_DECRYPTOR "eme-decrypt-v2"
+#define GMP_API_DECRYPTOR "eme-decrypt-v3"
 
 // API exposed by plugin library to manage decryption sessions.
 // When the Host requests this by calling GMPGetAPIFunc().
 //
 // API name macro: GMP_API_DECRYPTOR
 // Host API: GMPDecryptorHost
 class GMPDecryptor {
 public:
--- a/dom/media/gtest/TestGMPCrossOrigin.cpp
+++ b/dom/media/gtest/TestGMPCrossOrigin.cpp
@@ -887,18 +887,18 @@ class GMPStorageTest : public GMPDecrypt
 
   void SetFinished() {
     mFinished = true;
     Shutdown();
     NS_DispatchToMainThread(NS_NewRunnableMethod(this, &GMPStorageTest::Dummy));
   }
 
   virtual void SessionMessage(const nsCString& aSessionId,
-                              const nsTArray<uint8_t>& aMessage,
-                              const nsCString& aDestinationURL) MOZ_OVERRIDE
+                              GMPSessionMessageType aMessageType,
+                              const nsTArray<uint8_t>& aMessage) MOZ_OVERRIDE
   {
     MonitorAutoLock mon(mMonitor);
 
     nsCString msg((const char*)aMessage.Elements(), aMessage.Length());
     EXPECT_TRUE(mExpected.Length() > 0);
     bool matches = mExpected[0].mMessage.Equals(msg);
     EXPECT_STREQ(mExpected[0].mMessage.get(), msg.get());
     if (mExpected.Length() > 0 && matches) {
--- a/dom/webidl/MediaKeyMessageEvent.webidl
+++ b/dom/webidl/MediaKeyMessageEvent.webidl
@@ -5,19 +5,25 @@
  *
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
  *
  * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
  * W3C liability, trademark and document use rules apply.
  */
 
+enum MediaKeyMessageType {
+  "license-request",
+  "license-renewal",
+  "license-release"
+};
+
 [Pref="media.eme.enabled", Constructor(DOMString type, optional MediaKeyMessageEventInit eventInitDict)]
 interface MediaKeyMessageEvent : Event {
+  readonly attribute MediaKeyMessageType messageType;
   [Throws]
   readonly attribute ArrayBuffer message;
-  readonly attribute DOMString? destinationURL;
 };
 
 dictionary MediaKeyMessageEventInit : EventInit {
+  MediaKeyMessageType messageType = "license-request";
   ArrayBuffer message;
-  DOMString? destinationURL = null;
 };
--- a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
+++ b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
@@ -94,18 +94,18 @@ ClearKeySessionManager::CreateSession(ui
     CK_LOGD("No keys needed from client.");
     return;
   }
 
   // Send a request for needed key data.
   string request;
   ClearKeyUtils::MakeKeyRequest(neededKeys, request, aSessionType);
   mCallback->SessionMessage(&sessionId[0], sessionId.length(),
-                            (uint8_t*)&request[0], request.length(),
-                            "" /* destination url */, 0);
+                            kGMPLicenseRequest,
+                            (uint8_t*)&request[0], request.length());
 }
 
 void
 ClearKeySessionManager::LoadSession(uint32_t aPromiseId,
                                     const char* aSessionId,
                                     uint32_t aSessionIdLength)
 {
   CK_LOGD("ClearKeySessionManager::LoadSession");
--- a/media/gmp-clearkey/0.1/clearkey.info
+++ b/media/gmp-clearkey/0.1/clearkey.info
@@ -1,4 +1,4 @@
 Name: clearkey
 Description: ClearKey decrypt-only GMP plugin
 Version: 0.1
-APIs: eme-decrypt-v2[org.w3.clearkey]
+APIs: eme-decrypt-v3[org.w3.clearkey]