Bug 1334111 - Reject MediaKeys requests for persistent storage when in PB mode. r=gerald draft
authorChris Pearce <cpearce@mozilla.com>
Mon, 29 May 2017 10:21:18 +1200
changeset 585827 ad4e22629acfdd82aff8ead764949939726adbf4
parent 585789 701e0ebc2b4b7ae57248e44fd06278e5309e1a05
child 585828 a2dfeb7b263108ac1c60bfe2f47755e0a73d6324
push id61199
push usercpearce@mozilla.com
push dateMon, 29 May 2017 03:30:36 +0000
reviewersgerald
bugs1334111
milestone55.0a1
Bug 1334111 - Reject MediaKeys requests for persistent storage when in PB mode. r=gerald We want requests for MediaKeySystemAccess with persistentState to be rejected if the window is in Private Browsing mode. This is primarily so that users in Private Browsing mode don't unknowningly use up their "device limits"; some DRM streamers have limits on the numbers of unique devices that can be provisioned/used in a given time period, and the device ID is persisted in the persistent state. So if we're flushing that state, the user will use up one of their device quota on every new session, and quickly hit their limit, and be unable to continue watching DRM video. MozReview-Commit-ID: JWNO1kcU2ST
dom/media/eme/MediaKeySystemAccess.cpp
dom/media/eme/MediaKeySystemAccess.h
dom/media/eme/MediaKeySystemAccessManager.cpp
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -816,17 +816,18 @@ UnboxSessionTypes(const Optional<Sequenc
   return sessionTypes;
 }
 
 // 3.1.2.2 Get Supported Configuration and Consent
 static bool
 GetSupportedConfig(const KeySystemConfig& aKeySystem,
                    const MediaKeySystemConfiguration& aCandidate,
                    MediaKeySystemConfiguration& aOutConfig,
-                   DecoderDoctorDiagnostics* aDiagnostics)
+                   DecoderDoctorDiagnostics* aDiagnostics,
+                   bool aInPrivateBrowsing)
 {
   // Let accumulated configuration be a new MediaKeySystemConfiguration dictionary.
   MediaKeySystemConfiguration config;
   // Set the label member of accumulated configuration to equal the label member of
   // candidate configuration.
   config.mLabel = aCandidate.mLabel;
   // If the initDataTypes member of candidate configuration is non-empty, run the
   // following steps:
@@ -869,16 +870,24 @@ GetSupportedConfig(const KeySystemConfig
                         aKeySystem.mPersistentState,
                         config.mPersistentState)) {
     EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
             "persistentState requirement not satisfied.",
             NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
     return false;
   }
 
+  if (config.mPersistentState == MediaKeysRequirement::Required &&
+      aInPrivateBrowsing) {
+    EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
+            "persistentState requested in Private Browsing window.",
+            NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
+    return false;
+  }
+
   Sequence<nsString> sessionTypes(UnboxSessionTypes(aCandidate.mSessionTypes));
   if (sessionTypes.IsEmpty()) {
     // Malloc failure.
     return false;
   }
 
   // For each value in session types:
   for (const auto& sessionTypeString : sessionTypes) {
@@ -1039,30 +1048,33 @@ GetSupportedConfig(const KeySystemConfig
   // Return accumulated configuration.
   aOutConfig = config;
 
   return true;
 }
 
 /* static */
 bool
-MediaKeySystemAccess::GetSupportedConfig(const nsAString& aKeySystem,
-                                         const Sequence<MediaKeySystemConfiguration>& aConfigs,
-                                         MediaKeySystemConfiguration& aOutConfig,
-                                         DecoderDoctorDiagnostics* aDiagnostics)
+MediaKeySystemAccess::GetSupportedConfig(
+  const nsAString& aKeySystem,
+  const Sequence<MediaKeySystemConfiguration>& aConfigs,
+  MediaKeySystemConfiguration& aOutConfig,
+  DecoderDoctorDiagnostics* aDiagnostics,
+  bool aIsPrivateBrowsing)
 {
   KeySystemConfig implementation;
   if (!GetKeySystemConfig(aKeySystem, implementation)) {
     return false;
   }
   for (const MediaKeySystemConfiguration& candidate : aConfigs) {
     if (mozilla::dom::GetSupportedConfig(implementation,
                                          candidate,
                                          aOutConfig,
-                                         aDiagnostics)) {
+                                         aDiagnostics,
+                                         aIsPrivateBrowsing)) {
       return true;
     }
   }
 
   return false;
 }
 
 
--- a/dom/media/eme/MediaKeySystemAccess.h
+++ b/dom/media/eme/MediaKeySystemAccess.h
@@ -56,20 +56,22 @@ public:
   static bool IsSupported(const nsAString& aKeySystem,
                           const Sequence<MediaKeySystemConfiguration>& aConfigs,
                           DecoderDoctorDiagnostics* aDiagnostics);
 
   static void NotifyObservers(nsPIDOMWindowInner* aWindow,
                               const nsAString& aKeySystem,
                               MediaKeySystemStatus aStatus);
 
-  static bool GetSupportedConfig(const nsAString& aKeySystem,
-                                 const Sequence<MediaKeySystemConfiguration>& aConfigs,
-                                 MediaKeySystemConfiguration& aOutConfig,
-                                 DecoderDoctorDiagnostics* aDiagnostics);
+  static bool GetSupportedConfig(
+    const nsAString& aKeySystem,
+    const Sequence<MediaKeySystemConfiguration>& aConfigs,
+    MediaKeySystemConfiguration& aOutConfig,
+    DecoderDoctorDiagnostics* aDiagnostics,
+    bool aIsPrivateBrowsing);
 
   static bool KeySystemSupportsInitDataType(const nsAString& aKeySystem,
                                             const nsAString& aInitDataType);
 
 private:
   nsCOMPtr<nsPIDOMWindowInner> mParent;
   const nsString mKeySystem;
   const MediaKeySystemConfiguration mConfig;
--- a/dom/media/eme/MediaKeySystemAccessManager.cpp
+++ b/dom/media/eme/MediaKeySystemAccessManager.cpp
@@ -160,18 +160,22 @@ MediaKeySystemAccessManager::Request(Det
     // Failed due to user disabling something, send a notification to
     // chrome, so we can show some UI to explain how the user can rectify
     // the situation.
     MediaKeySystemAccess::NotifyObservers(mWindow, aKeySystem, status);
     aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR, message);
     return;
   }
 
+  bool isPrivateBrowsing =
+    mWindow->GetExtantDoc() &&
+    mWindow->GetExtantDoc()->NodePrincipal()->GetPrivateBrowsingId() > 0;
   MediaKeySystemConfiguration config;
-  if (MediaKeySystemAccess::GetSupportedConfig(aKeySystem, aConfigs, config, &diagnostics)) {
+  if (MediaKeySystemAccess::GetSupportedConfig(
+        aKeySystem, aConfigs, config, &diagnostics, isPrivateBrowsing)) {
     RefPtr<MediaKeySystemAccess> access(
       new MediaKeySystemAccess(mWindow, aKeySystem, config));
     aPromise->MaybeResolve(access);
     diagnostics.StoreMediaKeySystemAccess(mWindow->GetExtantDoc(),
                                           aKeySystem, true, __func__);
     return;
   }
   // Not to inform user, because nothing to do if the corresponding keySystem