Bug 1513039 - part1 : remove caching temporary autoplay permission. r=smaug,florian
authoralwu <alwu@mozilla.com>
Mon, 07 Jan 2019 18:29:10 +0000
changeset 509871 612d05e15b6f99c7f5efb688ea9513f21bfa5491
parent 509870 b7e4f2bbfe5705e81877fdbe2170445f5979a65c
child 509872 838615dbf1f307e1adc83c7152fcb22cc8584e4d
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, florian
bugs1513039
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1513039 - part1 : remove caching temporary autoplay permission. r=smaug,florian We're going to remove all autoplay temporary permission related codes, so we don't need to cache it anymore. Differential Revision: https://phabricator.services.mozilla.com/D14325
browser/modules/SitePermissions.jsm
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/base/nsPIDOMWindow.h
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/media/AutoplayPolicy.cpp
toolkit/actors/AudioPlaybackChild.jsm
toolkit/modules/ActorManagerParent.jsm
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -59,29 +59,27 @@ const TemporaryPermissions = {
       this._stateByBrowser.set(browser, {});
     }
     let entry = this._stateByBrowser.get(browser);
     let prePath = browser.currentURI.prePath;
     if (!entry[prePath]) {
       entry[prePath] = {};
     }
     entry[prePath][id] = {timeStamp: Date.now(), state};
-    this.notifyWhenTemporaryPermissionChanged(browser, id, prePath, state);
   },
 
   // Removes a permission with the specified id for the specified browser.
   remove(browser, id) {
     if (!browser) {
       return;
     }
     let entry = this._stateByBrowser.get(browser);
     let prePath = browser.currentURI.prePath;
     if (entry && entry[prePath]) {
       delete entry[prePath][id];
-      this.notifyWhenTemporaryPermissionChanged(browser, id, prePath, SitePermissions.UNKNOWN);
     }
   },
 
   // Gets a permission with the specified id for the specified browser.
   get(browser, id) {
     if (!browser || !browser.currentURI) {
       return null;
     }
@@ -109,63 +107,31 @@ const TemporaryPermissions = {
         if (permission) {
           permissions.push(permission);
         }
       }
     }
     return permissions;
   },
 
-  // Gets all permissions ID for the specified browser, this method will return
-  // all permissions ID stored in browser without checking current URI.
-  getAllPermissionIds(browser) {
-    let permissions = new Set();
-    let entry = this._stateByBrowser.get(browser);
-    for (let prePath in entry) {
-      for (let id in entry[prePath]) {
-        permissions.add(id);
-      }
-    }
-    return permissions;
-  },
-
   // Clears all permissions for the specified browser.
   // Unlike other methods, this does NOT clear only for
   // the currentURI but the whole browser state.
   clear(browser) {
-    let permissions = this.getAllPermissionIds(browser);
     this._stateByBrowser.delete(browser);
-    for (let permission of permissions) {
-      this.notifyWhenTemporaryPermissionChanged(browser, permission, null,
-                                                SitePermissions.UNKNOWN);
-    }
   },
 
   // Copies the temporary permission state of one browser
   // into a new entry for the other browser.
   copy(browser, newBrowser) {
     let entry = this._stateByBrowser.get(browser);
     if (entry) {
       this._stateByBrowser.set(newBrowser, entry);
     }
   },
-
-  // If permission has property 'notifyWhenTemporaryPermissionChanged', then
-  // notify browser when the temporary permission changed.
-  notifyWhenTemporaryPermissionChanged(browser, id, prePath, state) {
-    if (!(id in gPermissionObject) ||
-        !gPermissionObject[id].notifyWhenTemporaryPermissionChanged) {
-      return;
-    }
-    browser.messageManager
-           .sendAsyncMessage("TemporaryPermissionChanged",
-                             { permission: id,
-                               prePath,
-                               state });
-  },
 };
 
 // This hold a flag per browser to indicate whether we should show the
 // user a notification as a permission has been requested that has been
 // blocked globally. We only want to notify the user in the case that
 // they actually requested the permission within the current page load
 // so will clear the flag on navigation.
 const GloballyBlockedPermissions = {
@@ -742,17 +708,16 @@ var gPermissionObject = {
    *    Defaults to ALLOW, BLOCK and the default state (see getDefault).
    *    The PROMPT_HIDE state is deliberately excluded from "plugin:flash" since we
    *    don't want to expose a "Hide Prompt" button to the user through pageinfo.
    */
 
   "autoplay-media": {
     exactHostMatch: true,
     permitTemporaryAllow: true,
-    notifyWhenTemporaryPermissionChanged: true,
     getDefault() {
       let state = Services.prefs.getIntPref("media.autoplay.default",
                                             Ci.nsIAutoplay.PROMPT);
       if (state == Ci.nsIAutoplay.ALLOWED) {
         return SitePermissions.ALLOW;
       } if (state == Ci.nsIAutoplay.BLOCKED) {
         return SitePermissions.BLOCK;
       }
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3983,46 +3983,16 @@ nsDOMWindowUtils::ResetPrefersReducedMot
   nsIWidget* widget = GetWidget();
   if (!widget) {
     return NS_OK;
   }
 
   return widget->ResetPrefersReducedMotionOverrideForTest();
 }
 
-NS_IMETHODIMP
-nsDOMWindowUtils::NotifyTemporaryAutoplayPermissionChanged(
-    int32_t aState, const nsAString& aPrePath) {
-  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
-  NS_ENSURE_STATE(window);
-
-  nsCOMPtr<nsPIDOMWindowOuter> topWindow = window->GetScriptableTop();
-  if (!topWindow) {
-    return NS_OK;
-  }
-
-  topWindow->NotifyTemporaryAutoplayPermissionChanged(aState, aPrePath);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMWindowUtils::IsAutoplayTemporarilyAllowed(bool* aResult) {
-  *aResult = false;
-  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
-  NS_ENSURE_STATE(window);
-
-  nsCOMPtr<nsPIDOMWindowOuter> topWindow = window->GetScriptableTop();
-  if (!topWindow) {
-    return NS_OK;
-  }
-
-  *aResult = topWindow->HasTemporaryAutoplayPermission();
-  return NS_OK;
-}
-
 NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsTranslationNodeList)
 NS_IMPL_RELEASE(nsTranslationNodeList)
 
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -247,18 +247,16 @@
 #ifdef HAVE_SIDEBAR
 #include "mozilla/dom/ExternalBinding.h"
 #endif
 
 #ifdef MOZ_WEBSPEECH
 #include "mozilla/dom/SpeechSynthesis.h"
 #endif
 
-#include "mozilla/HashFunctions.h"
-
 // Apple system headers seem to have a check() macro.  <sigh>
 #ifdef check
 class nsIScriptTimeoutHandler;
 #undef check
 #endif  // check
 #include "AccessCheck.h"
 
 #ifdef ANDROID
@@ -317,21 +315,16 @@ using mozilla::TimeStamp;
 
 static LazyLogModule gDOMLeakPRLogOuter("DOMLeakOuter");
 
 static int32_t gOpenPopupSpamCount = 0;
 
 nsGlobalWindowOuter::OuterWindowByIdTable*
     nsGlobalWindowOuter::sOuterWindowsById = nullptr;
 
-extern mozilla::LazyLogModule gAutoplayPermissionLog;
-
-#define AUTOPLAY_LOG(msg, ...) \
-  MOZ_LOG(gAutoplayPermissionLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
-
 /* static */
 nsPIDOMWindowOuter* nsPIDOMWindowOuter::GetFromCurrentInner(
     nsPIDOMWindowInner* aInner) {
   if (!aInner) {
     return nullptr;
   }
 
   nsPIDOMWindowOuter* outer = aInner->GetOuterWindow();
@@ -7374,78 +7367,16 @@ mozilla::dom::TabGroup* nsPIDOMWindowOut
   }
   return window.forget();
 }
 
 nsIURI* nsPIDOMWindowOuter::GetDocumentURI() const {
   return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
 }
 
-void nsPIDOMWindowOuter::NotifyTemporaryAutoplayPermissionChanged(
-    int32_t aState, const nsAString& aPrePath) {
-  MOZ_ASSERT(int32_t(nsIPermissionManager::ALLOW_ACTION) ==
-                 int32_t(nsIDOMWindowUtils::PERMISSION_ALLOW) &&
-             int32_t(nsIPermissionManager::DENY_ACTION) ==
-                 int32_t(nsIDOMWindowUtils::PERMISSION_DENY) &&
-             int32_t(nsIPermissionManager::UNKNOWN_ACTION) ==
-                 int32_t(nsIDOMWindowUtils::PERMISSION_UNKNOWN));
-
-  bool isAllowed = aState == nsIDOMWindowUtils::PERMISSION_ALLOW;
-  switch (aState) {
-    case nsIDOMWindowUtils::PERMISSION_ALLOW:
-    case nsIDOMWindowUtils::PERMISSION_DENY:
-      AUTOPLAY_LOG("update temporary autoplay permission");
-      mAutoplayTemporaryPermission.Put(
-          aPrePath, PermissionInfo(isAllowed, TimeStamp::Now()));
-      break;
-    case nsIDOMWindowUtils::PERMISSION_UNKNOWN:
-      if (!aPrePath.Length()) {
-        AUTOPLAY_LOG("remove temporary autoplay permission for all domains");
-        mAutoplayTemporaryPermission.Clear();
-      } else {
-        AUTOPLAY_LOG("remove temporary autoplay permission");
-        mAutoplayTemporaryPermission.Remove(aPrePath);
-      }
-      break;
-    default:
-      AUTOPLAY_LOG("ERROR! non-defined permission state!");
-  }
-}
-
-bool nsPIDOMWindowOuter::HasTemporaryAutoplayPermission() {
-  if (!mDoc) {
-    return false;
-  }
-
-  nsIPrincipal* principal = mDoc->NodePrincipal();
-  if (!principal) {
-    return false;
-  }
-
-  nsCOMPtr<nsIURI> URI;
-  nsresult rv = principal->GetURI(getter_AddRefs(URI));
-  if (NS_FAILED(rv) || !URI) {
-    return false;
-  }
-
-  nsAutoCString prePath;
-  URI->GetPrePath(prePath);
-  NS_ConvertUTF8toUTF16 key(prePath);
-  PermissionInfo info = mAutoplayTemporaryPermission.Get(key);
-  int32_t expireTime = Preferences::GetInt(
-      "privacy.temporary_permission_expire_time_ms", 3600 * 1000);
-  if (info.first && TimeStamp::Now() - info.second >=
-                        TimeDuration::FromMilliseconds(expireTime)) {
-    AUTOPLAY_LOG("remove expired temporary autoplay permission");
-    mAutoplayTemporaryPermission.Remove(key);
-    return false;
-  }
-  return info.first;
-}
-
 void nsPIDOMWindowOuter::MaybeCreateDoc() {
   MOZ_ASSERT(!mDoc);
   if (nsIDocShell* docShell = GetDocShell()) {
     // Note that |document| here is the same thing as our mDoc, but we
     // don't have to explicitly set the member variable because the docshell
     // has already called SetNewDocument().
     nsCOMPtr<Document> document = docShell->GetDocument();
     Unused << document;
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -6,21 +6,19 @@
 
 #ifndef nsPIDOMWindow_h__
 #define nsPIDOMWindow_h__
 
 #include "nsIDOMWindow.h"
 #include "mozIDOMWindow.h"
 
 #include "nsCOMPtr.h"
-#include "nsDataHashtable.h"
 #include "nsTArray.h"
 #include "mozilla/dom/EventTarget.h"
 #include "mozilla/TaskCategory.h"
-#include "mozilla/TimeStamp.h"
 #include "js/TypeDecls.h"
 #include "nsRefPtrHashtable.h"
 
 // Only fired for inner windows.
 #define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed"
 #define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen"
 #define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed"
 
@@ -785,23 +783,16 @@ class nsPIDOMWindowOuter : public mozIDO
 
   mozilla::dom::TabGroup* TabGroup();
 
   virtual nsPIDOMWindowOuter* GetPrivateRoot() = 0;
 
   virtual void ActivateOrDeactivate(bool aActivate) = 0;
 
   /**
-   * These functions are used to modify and check temporary autoplay permission.
-   */
-  void NotifyTemporaryAutoplayPermissionChanged(int32_t aState,
-                                                const nsAString& aPrePath);
-  bool HasTemporaryAutoplayPermission();
-
-  /**
    * |top| gets the root of the window hierarchy.
    *
    * This function does not cross chrome-content boundaries, so if this
    * window's parent is of a different type, |top| will return this window.
    *
    * When script reads the top property, we run GetScriptableTop, which
    * will not cross an <iframe mozbrowser> boundary.
    *
@@ -1185,18 +1176,15 @@ class nsPIDOMWindowOuter : public mozIDO
 
   // Let the service workers plumbing know that some feature are enabled while
   // testing.
   bool mServiceWorkersTestingEnabled;
 
   mozilla::dom::LargeAllocStatus mLargeAllocStatus;
 
   RefPtr<mozilla::dom::BrowsingContext> mOpenerForInitialContentBrowser;
-
-  using PermissionInfo = std::pair<bool, mozilla::TimeStamp>;
-  nsDataHashtable<nsStringHashKey, PermissionInfo> mAutoplayTemporaryPermission;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowOuter, NS_PIDOMWINDOWOUTER_IID)
 
 #include "nsPIDOMWindowInlines.h"
 
 #endif  // nsPIDOMWindow_h__
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -825,19 +825,19 @@ interface nsIDOMWindowUtils : nsISupport
 
   /**
    * Returns the given element's bounds without flushing pending layout changes.
    */
   DOMRect getBoundsWithoutFlushing(in Element aElement);
 
   /**
    * Returns the offset of the window's visual viewport relative to the
-   * layout viewport. 
+   * layout viewport.
    */
-  void getVisualViewportOffsetRelativeToLayoutViewport(out float aOffsetX, 
+  void getVisualViewportOffsetRelativeToLayoutViewport(out float aOffsetX,
                                                        out float aOffsetY);
 
   const long FLUSH_NONE = -1;
   const long FLUSH_STYLE = 0;
   const long FLUSH_LAYOUT = 1;
   const long FLUSH_DISPLAY = 2;
 
   /**
@@ -1928,33 +1928,16 @@ interface nsIDOMWindowUtils : nsISupport
    * Currently this function is available only on MacOSX.
    */
   void setPrefersReducedMotionOverrideForTest(in boolean aValue);
   /**
    * Reset the internal state to be used for above setPrefersReducedMotion.
    */
   void resetPrefersReducedMotionOverrideForTest();
 
-  /**
-   * Used to notify temporary autoplay permission change and cache it on the dom
-   * window. These states are equal to nsIPermissionManager's action states.
-   */
-  const long PERMISSION_UNKNOWN = 0;
-  const long PERMISSION_ALLOW = 1;
-  const long PERMISSION_DENY = 2;
-
-  void notifyTemporaryAutoplayPermissionChanged(in long aState,
-                                                in AString aPrePath);
-
-  /**
-   * Used to check whether the window temporarily allows autoplay for current
-   * domain.
-   */
-  bool isAutoplayTemporarilyAllowed();
-
   // These consts are only for testing purposes.
   const long DEFAULT_MOUSE_POINTER_ID = 0;
   const long DEFAULT_PEN_POINTER_ID   = 1;
   const long DEFAULT_TOUCH_POINTER_ID = 2;
 
   // Match WidgetMouseEventBase::buttonType.
   const long MOUSE_BUTTON_LEFT_BUTTON   = 0;
   const long MOUSE_BUTTON_MIDDLE_BUTTON = 1;
--- a/dom/media/AutoplayPolicy.cpp
+++ b/dom/media/AutoplayPolicy.cpp
@@ -82,23 +82,16 @@ static bool IsWindowAllowedToPlay(nsPIDO
   // content document and check permissions etc on the top level content
   // document. FeaturePolicy propagates the permission to any sub-documents if
   // they don't have special directives.
   if (!FeaturePolicyUtils::IsFeatureAllowed(aWindow->GetExtantDoc(),
                                             NS_LITERAL_STRING("autoplay"))) {
     return false;
   }
 
-  nsCOMPtr<nsPIDOMWindowOuter> topWindow = aWindow->GetScriptableTop();
-  if (topWindow && topWindow->HasTemporaryAutoplayPermission()) {
-    AUTOPLAY_LOG(
-        "Allow autoplay as document has temporary autoplay permission.");
-    return true;
-  }
-
   Document* approver = ApproverDocOf(*aWindow->GetExtantDoc());
   if (!approver) {
     return false;
   }
 
   if (nsContentUtils::IsExactSitePermAllow(approver->NodePrincipal(),
                                            "autoplay-media")) {
     AUTOPLAY_LOG(
--- a/toolkit/actors/AudioPlaybackChild.jsm
+++ b/toolkit/actors/AudioPlaybackChild.jsm
@@ -64,19 +64,11 @@ class AudioPlaybackChild extends ActorCh
     }
   }
 
   receiveMessage({name, data}) {
     switch (name) {
       case "AudioPlayback":
         this.handleMediaControlMessage(data.type);
         break;
-      case "TemporaryPermissionChanged":
-        if (data.permission !== "autoplay-media") {
-          return;
-        }
-        let utils = this.content.windowUtils;
-        utils.notifyTemporaryAutoplayPermissionChanged(data.state,
-                                                       data.prePath);
-        break;
     }
   }
 }
--- a/toolkit/modules/ActorManagerParent.jsm
+++ b/toolkit/modules/ActorManagerParent.jsm
@@ -101,17 +101,16 @@ ChromeUtils.import("resource://gre/modul
 const {DefaultMap} = ExtensionUtils;
 
 let ACTORS = {
   AudioPlayback: {
     child: {
       module: "resource://gre/actors/AudioPlaybackChild.jsm",
       messages: [
         "AudioPlayback",
-        "TemporaryPermissionChanged",
       ],
       observers: [
         "audio-playback",
       ],
     },
   },
 
   Autoplay: {