Bug 1149420 - Make the IndexedDB permissions prompt work in e10s. r=bent/mfinkle, a=lizzard
authorBlake Kaplan <mrbkap@gmail.com>
Fri, 10 Apr 2015 18:10:00 +0200
changeset 267471 e8c791225ca0d8f7d2e8d2a38d3fadd40fd4299c
parent 267470 360a68921cd5e083bf940a1cf45172612df38222
child 267472 1291a13c1fc5ea7e47ce4c985ed54edfae46f69f
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, mfinkle, lizzard
bugs1149420
milestone39.0
Bug 1149420 - Make the IndexedDB permissions prompt work in e10s. r=bent/mfinkle, a=lizzard
browser/base/content/browser.js
dom/indexedDB/ActorsChild.cpp
dom/indexedDB/ActorsParent.cpp
dom/indexedDB/ActorsParent.h
dom/indexedDB/PermissionRequestBase.cpp
dom/indexedDB/PermissionRequestBase.h
dom/ipc/TabParent.cpp
mobile/android/chrome/content/browser.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6182,30 +6182,23 @@ var IndexedDBPromptHelper = {
   observe:
   function IndexedDBPromptHelper_observe(subject, topic, data) {
     if (topic != this._permissionsPrompt) {
       throw new Error("Unexpected topic!");
     }
 
     var requestor = subject.QueryInterface(Ci.nsIInterfaceRequestor);
 
-    var contentWindow = requestor.getInterface(Ci.nsIDOMWindow);
-    var contentDocument = contentWindow.document;
-    var browserWindow =
-      OfflineApps._getBrowserWindowForContentWindow(contentWindow);
-
-    if (browserWindow != window) {
-      // Must belong to some other window.
+    var browser = requestor.getInterface(Ci.nsIDOMNode);
+    if (browser.ownerDocument.defaultView != window) {
+      // Only listen for notifications for browsers in our chrome window.
       return;
     }
 
-    var browser =
-      OfflineApps._getBrowserForContentWindow(browserWindow, contentWindow);
-
-    var host = contentDocument.documentURIObject.asciiHost;
+    var host = browser.currentURI.asciiHost;
 
     var message;
     var responseTopic;
     if (topic == this._permissionsPrompt) {
       message = gNavigatorBundle.getFormattedString("offlineApps.available",
                                                     [ host ]);
       responseTopic = this._permissionsResponse;
     }
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -14,16 +14,17 @@
 #include "IDBMutableFile.h"
 #include "IDBRequest.h"
 #include "IDBTransaction.h"
 #include "IndexedDatabase.h"
 #include "IndexedDatabaseInlines.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/TypeTraits.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseFileChild.h"
 #include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
 #include "mozilla/dom/ipc/BlobChild.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
@@ -529,19 +530,19 @@ class PermissionRequestMainProcessHelper
   : public PermissionRequestBase
 {
   BackgroundFactoryRequestChild* mActor;
   nsRefPtr<IDBFactory> mFactory;
 
 public:
   PermissionRequestMainProcessHelper(BackgroundFactoryRequestChild* aActor,
                                      IDBFactory* aFactory,
-                                     nsPIDOMWindow* aWindow,
+                                     Element* aOwnerElement,
                                      nsIPrincipal* aPrincipal)
-    : PermissionRequestBase(aWindow, aPrincipal)
+    : PermissionRequestBase(aOwnerElement, aPrincipal)
     , mActor(aActor)
     , mFactory(aFactory)
   {
     MOZ_ASSERT(aActor);
     MOZ_ASSERT(aFactory);
     aActor->AssertIsOnOwningThread();
   }
 
@@ -1130,18 +1131,24 @@ BackgroundFactoryRequestChild::RecvPermi
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return false;
   }
 
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     nsCOMPtr<nsPIDOMWindow> window = mFactory->GetParentObject();
     MOZ_ASSERT(window);
 
+    nsCOMPtr<Element> ownerElement =
+      do_QueryInterface(window->GetChromeEventHandler());
+    if (NS_WARN_IF(!ownerElement)) {
+      return false;
+    }
+
     nsRefPtr<PermissionRequestMainProcessHelper> helper =
-      new PermissionRequestMainProcessHelper(this, mFactory, window, principal);
+      new PermissionRequestMainProcessHelper(this, mFactory, ownerElement, principal);
 
     PermissionRequestBase::PermissionValue permission;
     if (NS_WARN_IF(NS_FAILED(helper->PromptIfNeeded(&permission)))) {
       return false;
     }
 
     MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed ||
                permission == PermissionRequestBase::kPermissionDenied ||
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -5012,19 +5012,19 @@ private:
 
 class PermissionRequestHelper final
   : public PermissionRequestBase
   , public PIndexedDBPermissionRequestParent
 {
   bool mActorDestroyed;
 
 public:
-  PermissionRequestHelper(nsPIDOMWindow* aWindow,
+  PermissionRequestHelper(Element* aOwnerElement,
                           nsIPrincipal* aPrincipal)
-    : PermissionRequestBase(aWindow, aPrincipal)
+    : PermissionRequestBase(aOwnerElement, aPrincipal)
     , mActorDestroyed(false)
   { }
 
 protected:
   ~PermissionRequestHelper()
   { }
 
 private:
@@ -5673,23 +5673,23 @@ DeallocPBackgroundIDBFactoryParent(PBack
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);
 
   nsRefPtr<Factory> actor = dont_AddRef(static_cast<Factory*>(aActor));
   return true;
 }
 
 PIndexedDBPermissionRequestParent*
-AllocPIndexedDBPermissionRequestParent(nsPIDOMWindow* aWindow,
+AllocPIndexedDBPermissionRequestParent(Element* aOwnerElement,
                                        nsIPrincipal* aPrincipal)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsRefPtr<PermissionRequestHelper> actor =
-    new PermissionRequestHelper(aWindow, aPrincipal);
+    new PermissionRequestHelper(aOwnerElement, aPrincipal);
   return actor.forget().take();
 }
 
 bool
 RecvPIndexedDBPermissionRequestConstructor(
                                       PIndexedDBPermissionRequestParent* aActor)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/indexedDB/ActorsParent.h
+++ b/dom/indexedDB/ActorsParent.h
@@ -9,16 +9,17 @@ template <class> struct already_AddRefed
 class nsCString;
 struct nsID;
 class nsIPrincipal;
 class nsPIDOMWindow;
 
 namespace mozilla {
 namespace dom {
 
+class Element;
 class TabParent;
 
 namespace quota {
 
 class Client;
 
 } // namespace quota
 
@@ -34,17 +35,17 @@ AllocPBackgroundIDBFactoryParent(const L
 bool
 RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor,
                                      const LoggingInfo& aLoggingInfo);
 
 bool
 DeallocPBackgroundIDBFactoryParent(PBackgroundIDBFactoryParent* aActor);
 
 PIndexedDBPermissionRequestParent*
-AllocPIndexedDBPermissionRequestParent(nsPIDOMWindow* aWindow,
+AllocPIndexedDBPermissionRequestParent(Element* aOwnerElement,
                                        nsIPrincipal* aPrincipal);
 
 bool
 RecvPIndexedDBPermissionRequestConstructor(
                                      PIndexedDBPermissionRequestParent* aActor);
 
 bool
 DeallocPIndexedDBPermissionRequestParent(
--- a/dom/indexedDB/PermissionRequestBase.cpp
+++ b/dom/indexedDB/PermissionRequestBase.cpp
@@ -2,16 +2,17 @@
  * 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 "PermissionRequestBase.h"
 
 #include "MainThreadUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Services.h"
+#include "mozilla/dom/Element.h"
 #include "nsIDOMWindow.h"
 #include "nsIObserverService.h"
 #include "nsIPrincipal.h"
 #include "nsPIDOMWindow.h"
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace dom {
@@ -41,23 +42,23 @@ void
 AssertSanity()
 {
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 } // anonymous namespace
 
-PermissionRequestBase::PermissionRequestBase(nsPIDOMWindow* aWindow,
+PermissionRequestBase::PermissionRequestBase(Element* aOwnerElement,
                                              nsIPrincipal* aPrincipal)
-  : mWindow(aWindow)
+  : mOwnerElement(aOwnerElement)
   , mPrincipal(aPrincipal)
 {
   AssertSanity();
-  MOZ_ASSERT(aWindow);
+  MOZ_ASSERT(aOwnerElement);
   MOZ_ASSERT(aPrincipal);
 }
 
 PermissionRequestBase::~PermissionRequestBase()
 {
   AssertSanity();
 }
 
@@ -120,18 +121,18 @@ nsresult
 PermissionRequestBase::PromptIfNeeded(PermissionValue* aCurrentValue)
 {
   AssertSanity();
   MOZ_ASSERT(aCurrentValue);
   MOZ_ASSERT(mPrincipal);
 
   // Tricky, we want to release the window and principal in all cases except
   // when we successfully prompt.
-  nsCOMPtr<nsPIDOMWindow> window;
-  mWindow.swap(window);
+  nsCOMPtr<Element> element;
+  mOwnerElement.swap(element);
 
   nsCOMPtr<nsIPrincipal> principal;
   mPrincipal.swap(principal);
 
   PermissionValue currentValue;
   nsresult rv = GetCurrentPermission(principal, &currentValue);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -141,25 +142,25 @@ PermissionRequestBase::PromptIfNeeded(Pe
 
   if (currentValue == kPermissionPrompt) {
     nsCOMPtr<nsIObserverService> obsSvc = GetObserverService();
     if (NS_WARN_IF(!obsSvc)) {
       return NS_ERROR_FAILURE;
     }
 
     // We're about to prompt so swap the members back.
-    window.swap(mWindow);
+    element.swap(mOwnerElement);
     principal.swap(mPrincipal);
 
     rv = obsSvc->NotifyObservers(static_cast<nsIObserver*>(this),
                                  kPermissionPromptTopic,
                                  nullptr);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       // Finally release if we failed the prompt.
-      mWindow = nullptr;
+      mOwnerElement = nullptr;
       mPrincipal = nullptr;
       return rv;
     }
   }
 
   *aCurrentValue = currentValue;
   return NS_OK;
 }
@@ -195,36 +196,36 @@ PermissionRequestBase::GetInterface(cons
                                     void** aResult)
 {
   AssertSanity();
 
   if (aIID.Equals(NS_GET_IID(nsIObserver))) {
     return QueryInterface(aIID, aResult);
   }
 
-  if (aIID.Equals(NS_GET_IID(nsIDOMWindow)) && mWindow) {
-    return mWindow->QueryInterface(aIID, aResult);
+  if (aIID.Equals(NS_GET_IID(nsIDOMNode)) && mOwnerElement) {
+    return mOwnerElement->QueryInterface(aIID, aResult);
   }
 
   *aResult = nullptr;
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
 PermissionRequestBase::Observe(nsISupports* aSubject,
                                const char* aTopic,
                                const char16_t* aData)
 {
   AssertSanity();
   MOZ_ASSERT(!strcmp(aTopic, kPermissionResponseTopic));
-  MOZ_ASSERT(mWindow);
+  MOZ_ASSERT(mOwnerElement);
   MOZ_ASSERT(mPrincipal);
 
-  nsCOMPtr<nsPIDOMWindow> window;
-  mWindow.swap(window);
+  nsCOMPtr<Element> element;
+  element.swap(mOwnerElement);
 
   nsCOMPtr<nsIPrincipal> principal;
   mPrincipal.swap(principal);
 
   nsresult rv;
   uint32_t promptResult = nsDependentString(aData).ToInteger(&rv);
   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
 
--- a/dom/indexedDB/PermissionRequestBase.h
+++ b/dom/indexedDB/PermissionRequestBase.h
@@ -13,23 +13,26 @@
 #include "nsISupportsImpl.h"
 #include "nsString.h"
 
 class nsIPrincipal;
 class nsPIDOMWindow;
 
 namespace mozilla {
 namespace dom {
+
+class Element;
+
 namespace indexedDB {
 
 class PermissionRequestBase
   : public nsIObserver
   , public nsIInterfaceRequestor
 {
-  nsCOMPtr<nsPIDOMWindow> mWindow;
+  nsCOMPtr<Element> mOwnerElement;
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
 public:
   enum PermissionValue {
     kPermissionAllowed = nsIPermissionManager::ALLOW_ACTION,
     kPermissionDenied = nsIPermissionManager::DENY_ACTION,
     kPermissionPrompt = nsIPermissionManager::PROMPT_ACTION
   };
@@ -46,17 +49,17 @@ public:
   static PermissionValue
   PermissionValueForIntPermission(uint32_t aIntPermission);
 
   // This function will prompt if needed. It may only be called once.
   nsresult
   PromptIfNeeded(PermissionValue* aCurrentValue);
 
 protected:
-  PermissionRequestBase(nsPIDOMWindow* aWindow,
+  PermissionRequestBase(Element* aOwnerElement,
                         nsIPrincipal* aPrincipal);
 
   // Reference counted.
   virtual
   ~PermissionRequestBase();
 
   virtual void
   OnPromptComplete(PermissionValue aPermissionValue) = 0;
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -1116,29 +1116,22 @@ TabParent::AllocPIndexedDBPermissionRequ
     if (NS_WARN_IF(!AssertAppPrincipal(manager->AsContentParent(),
                                        principal))) {
       return nullptr;
     }
   } else {
     MOZ_CRASH("Figure out security checks for bridged content!");
   }
 
-  nsCOMPtr<nsPIDOMWindow> window;
-  nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
-  if (frame) {
-    MOZ_ASSERT(frame->OwnerDoc());
-    window = do_QueryInterface(frame->OwnerDoc()->GetWindow());
-  }
-
-  if (!window) {
+  if (NS_WARN_IF(!mFrameElement)) {
     return nullptr;
   }
 
   return
-    mozilla::dom::indexedDB::AllocPIndexedDBPermissionRequestParent(window,
+    mozilla::dom::indexedDB::AllocPIndexedDBPermissionRequestParent(mFrameElement,
                                                                     principal);
 }
 
 bool
 TabParent::RecvPIndexedDBPermissionRequestConstructor(
                                       PIndexedDBPermissionRequestParent* aActor,
                                       const Principal& aPrincipal)
 {
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -6652,23 +6652,22 @@ var IndexedDB = {
 
   observe: function IndexedDB_observe(subject, topic, data) {
     if (topic != this._permissionsPrompt) {
       throw new Error("Unexpected topic!");
     }
 
     let requestor = subject.QueryInterface(Ci.nsIInterfaceRequestor);
 
-    let contentWindow = requestor.getInterface(Ci.nsIDOMWindow);
-    let contentDocument = contentWindow.document;
-    let tab = BrowserApp.getTabForWindow(contentWindow);
+    let browser = requestor.getInterface(Ci.nsIDOMNode);
+    let tab = BrowserApp.getTabForBrowser(browser);
     if (!tab)
       return;
 
-    let host = contentDocument.documentURIObject.asciiHost;
+    let host = browser.currentURI.asciiHost;
 
     let strings = Strings.browser;
 
     let message, responseTopic;
     if (topic == this._permissionsPrompt) {
       message = strings.formatStringFromName("offlineApps.ask", [host], 1);
       responseTopic = this._permissionsResponse;
     }