Bug 1106116 - Load images for notifications triggered from private browsing windows as private; r=jdm
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 28 Nov 2014 14:08:29 -0500
changeset 243906 c2aabf638fb48ad347ae6a78c5d901050216c945
parent 243847 3bc3a1bffafe2f49b4b877a8d1925b8630ebd710
child 243907 606533535f9bc89c3bb0031dcf51d4f713947180
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs1106116
milestone36.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 1106116 - Load images for notifications triggered from private browsing windows as private; r=jdm
b2g/components/AlertsHelper.jsm
b2g/components/AlertsService.js
browser/modules/WebappManager.jsm
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/notification/DesktopNotification.cpp
dom/notification/Notification.cpp
toolkit/components/alerts/nsAlertsService.cpp
toolkit/components/alerts/nsIAlertsService.idl
toolkit/components/alerts/nsXULAlerts.cpp
toolkit/components/alerts/nsXULAlerts.h
toolkit/components/downloads/nsDownloadManager.cpp
toolkit/system/gnome/nsAlertsIconListener.cpp
toolkit/system/gnome/nsAlertsIconListener.h
toolkit/system/gnome/nsSystemAlertsService.cpp
widget/cocoa/OSXNotificationCenter.mm
--- a/b2g/components/AlertsHelper.jsm
+++ b/b2g/components/AlertsHelper.jsm
@@ -265,17 +265,17 @@ let AlertsHelper = {
     if (currentListener && currentListener.observer) {
       currentListener.observer.observe(null, kTopicAlertFinished, currentListener.cookie);
     }
 
     let dataObj = this.deserializeStructuredClone(data.dataStr);
     this.registerListener(data.name, data.cookie, data.alertListener);
     this.showNotification(data.imageURL, data.title, data.text,
                           data.textClickable, data.cookie, data.name, data.bidi,
-                          data.lang, dataObj, null);
+                          data.lang, dataObj, null, data.inPrivateBrowsing);
   },
 
   showAppNotification: function(aMessage) {
     let data = aMessage.data;
     let details = data.details;
     let dataObject = this.deserializeStructuredClone(details.data);
     let listener = {
       mm: aMessage.target,
--- a/b2g/components/AlertsService.js
+++ b/b2g/components/AlertsService.js
@@ -63,28 +63,30 @@ AlertsService.prototype = {
         cpmm.removeMessageListener(kMessageAppNotificationReturn, this);
         break;
     }
   },
 
   // nsIAlertsService
   showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable,
                                   aCookie, aAlertListener, aName, aBidi,
-                                  aLang, aDataStr) {
+                                  aLang, aDataStr, aPrincipal,
+                                  aInPrivateBrowsing) {
     cpmm.sendAsyncMessage(kMessageAlertNotificationSend, {
       imageURL: aImageUrl,
       title: aTitle,
       text: aText,
       clickable: aTextClickable,
       cookie: aCookie,
       listener: aAlertListener,
       id: aName,
       dir: aBidi,
       lang: aLang,
-      dataStr: aDataStr
+      dataStr: aDataStr,
+      inPrivateBrowsing: aInPrivateBrowsing
     });
   },
 
   closeAlert: function(aName) {
     cpmm.sendAsyncMessage(kMessageAlertNotificationClose, {
       name: aName
     });
   },
--- a/browser/modules/WebappManager.jsm
+++ b/browser/modules/WebappManager.jsm
@@ -9,16 +9,17 @@ let Cc = Components.classes;
 let Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Webapps.jsm");
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
+Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NativeApp",
   "resource://gre/modules/NativeApp.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "WebappOSUtils",
   "resource://gre/modules/WebappOSUtils.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
@@ -145,17 +146,18 @@ this.WebappManager = {
 
         let manifestURL = aData.app.manifestURL;
 
         let nativeApp = new NativeApp(aData.app, jsonManifest,
                                       aData.app.categories);
 
         this.installations[manifestURL] = Promise.defer();
         this.installations[manifestURL].promise.then(() => {
-          notifyInstallSuccess(aData.app, nativeApp, bundle);
+          notifyInstallSuccess(aData.app, nativeApp, bundle,
+                               PrivateBrowsingUtils.isWindowPrivate(aWindow));
         }, (error) => {
           Cu.reportError("Error installing webapp: " + error);
         }).then(() => {
           popupProgressContent.removeChild(progressMeter);
           delete this.installations[manifestURL];
           if (Object.getOwnPropertyNames(this.installations).length == 0) {
             notification.remove();
           }
@@ -243,27 +245,28 @@ this.WebappManager = {
 
     notification = chromeWin.PopupNotifications.show(
                      browser, "webapps-uninstall", message,
                      "webapps-notification-icon",
                      mainAction, [secondaryAction]);
   }
 }
 
-function notifyInstallSuccess(aApp, aNativeApp, aBundle) {
+function notifyInstallSuccess(aApp, aNativeApp, aBundle, aInPrivateBrowsing) {
   let launcher = {
     observe: function(aSubject, aTopic) {
       if (aTopic == "alertclickcallback") {
         WebappOSUtils.launch(aApp);
       }
     }
   };
 
   try {
     let notifier = Cc["@mozilla.org/alerts-service;1"].
                    getService(Ci.nsIAlertsService);
 
     notifier.showAlertNotification(aNativeApp.iconURI.spec,
                                    aBundle.getString("webapps.install.success"),
                                    aNativeApp.appNameAsFilename,
-                                   true, null, launcher);
+                                   true, null, launcher, "", "", "", "", null,
+                                   aInPrivateBrowsing);
   } catch (ex) {}
 }
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3652,31 +3652,32 @@ ContentParent::RecvLoadURIExternal(const
 }
 
 bool
 ContentParent::RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
                                          const nsString& aText, const bool& aTextClickable,
                                          const nsString& aCookie, const nsString& aName,
                                          const nsString& aBidi, const nsString& aLang,
                                          const nsString& aData,
-                                         const IPC::Principal& aPrincipal)
+                                         const IPC::Principal& aPrincipal,
+                                         const bool& aInPrivateBrowsing)
 {
 #ifdef MOZ_CHILD_PERMISSIONS
     uint32_t permission = mozilla::CheckPermission(this, aPrincipal,
                                                    "desktop-notification");
     if (permission != nsIPermissionManager::ALLOW_ACTION) {
         return true;
     }
 #endif /* MOZ_CHILD_PERMISSIONS */
 
     nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
     if (sysAlerts) {
         sysAlerts->ShowAlertNotification(aImageUrl, aTitle, aText, aTextClickable,
                                          aCookie, this, aName, aBidi, aLang,
-                                         aData, aPrincipal);
+                                         aData, aPrincipal, aInPrivateBrowsing);
     }
     return true;
 }
 
 bool
 ContentParent::RecvCloseAlert(const nsString& aName,
                               const IPC::Principal& aPrincipal)
 {
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -597,17 +597,18 @@ private:
     virtual bool RecvSetURITitle(const URIParams& uri,
                                  const nsString& title) MOZ_OVERRIDE;
 
     virtual bool RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
                                            const nsString& aText, const bool& aTextClickable,
                                            const nsString& aCookie, const nsString& aName,
                                            const nsString& aBidi, const nsString& aLang,
                                            const nsString& aData,
-                                           const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
+                                           const IPC::Principal& aPrincipal,
+                                           const bool& aInPrivateBrowsing) MOZ_OVERRIDE;
 
     virtual bool RecvCloseAlert(const nsString& aName,
                                 const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
 
     virtual bool RecvLoadURIExternal(const URIParams& uri) MOZ_OVERRIDE;
 
     virtual bool RecvSyncMessage(const nsString& aMsg,
                                  const ClonedMessageData& aData,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -648,17 +648,18 @@ parent:
                           nsString title,
                           nsString text,
                           bool textClickable,
                           nsString cookie,
                           nsString name,
                           nsString bidi,
                           nsString lang,
                           nsString data,
-                          Principal principal);
+                          Principal principal,
+                          bool inPrivateBrowsing);
 
     CloseAlert(nsString name, Principal principal);
 
     PExternalHelperApp(OptionalURIParams uri,
                        nsCString aMimeContentType,
                        nsCString aContentDisposition,
                        uint32_t aContentDispositionHint,
                        nsString aContentDispositionFilename,
--- a/dom/notification/DesktopNotification.cpp
+++ b/dom/notification/DesktopNotification.cpp
@@ -10,16 +10,17 @@
 #include "mozilla/dom/PBrowserChild.h"
 #include "nsIDOMDesktopNotification.h"
 #include "mozilla/Preferences.h"
 #include "nsGlobalWindow.h"
 #include "nsIAppsService.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsServiceManagerUtils.h"
 #include "PermissionMessageUtils.h"
+#include "nsILoadContext.h"
 
 namespace mozilla {
 namespace dom {
 
 /*
  * Simple Request
  */
 class DesktopNotificationRequest : public nsIContentPermissionRequest
@@ -98,26 +99,30 @@ DesktopNotification::PostDesktopNotifica
   }
 
   // Generate a unique name (which will also be used as a cookie) because
   // the nsIAlertsService will coalesce notifications with the same name.
   // In the case of IPC, the parent process will use the cookie to map
   // to nsIObservers, thus cookies must be unique to differentiate observers.
   nsString uniqueName = NS_LITERAL_STRING("desktop-notification:");
   uniqueName.AppendInt(sCount++);
-  nsIPrincipal* principal = GetOwner()->GetDoc()->NodePrincipal();
+  nsCOMPtr<nsIDocument> doc = GetOwner()->GetDoc();
+  nsIPrincipal* principal = doc->NodePrincipal();
+  nsCOMPtr<nsILoadContext> loadContext = doc->GetLoadContext();
+  bool inPrivateBrowsing = loadContext && loadContext->UsePrivateBrowsing();
   return alerts->ShowAlertNotification(mIconURL, mTitle, mDescription,
                                        true,
                                        uniqueName,
                                        mObserver,
                                        uniqueName,
                                        NS_LITERAL_STRING("auto"),
                                        EmptyString(),
                                        EmptyString(),
-                                       principal);
+                                       principal,
+                                       inPrivateBrowsing);
 }
 
 DesktopNotification::DesktopNotification(const nsAString & title,
                                          const nsAString & description,
                                          const nsAString & iconURL,
                                          nsPIDOMWindow *aWindow,
                                          nsIPrincipal* principal)
   : DOMEventTargetHelper(aWindow)
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -22,16 +22,17 @@
 #include "nsGlobalWindow.h"
 #include "nsDOMJSUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/Services.h"
 #include "nsContentPermissionHelper.h"
+#include "nsILoadContext.h"
 #ifdef MOZ_B2G
 #include "nsIDOMDesktopNotification.h"
 #endif
 
 namespace mozilla {
 namespace dom {
 
 class NotificationStorageCallback MOZ_FINAL : public nsINotificationStorageCallback
@@ -672,20 +673,26 @@ Notification::ShowInternal()
     }
   }
 #endif
 
   // In the case of IPC, the parent process uses the cookie to map to
   // nsIObserver. Thus the cookie must be unique to differentiate observers.
   nsString uniqueCookie = NS_LITERAL_STRING("notification:");
   uniqueCookie.AppendInt(sCount++);
+  bool inPrivateBrowsing = false;
+  if (doc) {
+    nsCOMPtr<nsILoadContext> loadContext = doc->GetLoadContext();
+    inPrivateBrowsing = loadContext && loadContext->UsePrivateBrowsing();
+  }
   alertService->ShowAlertNotification(absoluteUrl, mTitle, mBody, true,
                                       uniqueCookie, observer, mAlertName,
                                       DirectionToString(mDir), mLang,
-                                      dataStr, GetPrincipal());
+                                      dataStr, GetPrincipal(),
+                                      inPrivateBrowsing);
 }
 
 void
 Notification::RequestPermission(const GlobalObject& aGlobal,
                                 const Optional<OwningNonNull<NotificationPermissionCallback> >& aCallback,
                                 ErrorResult& aRv)
 {
   // Get principal from global to make permission request for notifications.
--- a/toolkit/components/alerts/nsAlertsService.cpp
+++ b/toolkit/components/alerts/nsAlertsService.cpp
@@ -65,65 +65,68 @@ bool nsAlertsService::ShouldShowAlert()
 NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl, const nsAString & aAlertTitle, 
                                                      const nsAString & aAlertText, bool aAlertTextClickable,
                                                      const nsAString & aAlertCookie,
                                                      nsIObserver * aAlertListener,
                                                      const nsAString & aAlertName,
                                                      const nsAString & aBidi,
                                                      const nsAString & aLang,
                                                      const nsAString & aData,
-                                                     nsIPrincipal * aPrincipal)
+                                                     nsIPrincipal * aPrincipal,
+                                                     bool aInPrivateBrowsing)
 {
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     ContentChild* cpc = ContentChild::GetSingleton();
 
     if (aAlertListener)
       cpc->AddRemoteAlertObserver(PromiseFlatString(aAlertCookie), aAlertListener);
 
     cpc->SendShowAlertNotification(PromiseFlatString(aImageUrl),
                                    PromiseFlatString(aAlertTitle),
                                    PromiseFlatString(aAlertText),
                                    aAlertTextClickable,
                                    PromiseFlatString(aAlertCookie),
                                    PromiseFlatString(aAlertName),
                                    PromiseFlatString(aBidi),
                                    PromiseFlatString(aLang),
                                    PromiseFlatString(aData),
-                                   IPC::Principal(aPrincipal));
+                                   IPC::Principal(aPrincipal),
+                                   aInPrivateBrowsing);
     return NS_OK;
   }
 
 #ifdef MOZ_WIDGET_ANDROID
   mozilla::AndroidBridge::Bridge()->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertCookie,
                                                           aAlertListener, aAlertName);
   return NS_OK;
 #else
   // Check if there is an optional service that handles system-level notifications
   nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
   nsresult rv;
   if (sysAlerts) {
     rv = sysAlerts->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
                                           aAlertCookie, aAlertListener, aAlertName,
                                           aBidi, aLang, aData,
-                                          IPC::Principal(aPrincipal));
+                                          IPC::Principal(aPrincipal),
+                                          aInPrivateBrowsing);
     if (NS_SUCCEEDED(rv))
       return NS_OK;
   }
 
   if (!ShouldShowAlert()) {
     // Do not display the alert. Instead call alertfinished and get out.
     if (aAlertListener)
       aAlertListener->Observe(nullptr, "alertfinished", PromiseFlatString(aAlertCookie).get());
     return NS_OK;
   }
 
   // Use XUL notifications as a fallback if above methods have failed.
   rv = mXULAlerts.ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
                                         aAlertCookie, aAlertListener, aAlertName,
-                                        aBidi, aLang);
+                                        aBidi, aLang, aInPrivateBrowsing);
   return rv;
 #endif // !MOZ_WIDGET_ANDROID
 }
 
 NS_IMETHODIMP nsAlertsService::CloseAlert(const nsAString& aAlertName,
                                           nsIPrincipal* aPrincipal)
 {
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
--- a/toolkit/components/alerts/nsIAlertsService.idl
+++ b/toolkit/components/alerts/nsIAlertsService.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 #include "nsISupports.idl"
 #include "nsIObserver.idl"
 
 interface nsIPrincipal;
 
-[scriptable, uuid(d446bede-fcf7-403d-b6b6-5fd67b19ba58)]
+[scriptable, uuid(9d0284bf-db40-42da-8f0d-c2769dbde7aa)]
 interface nsIAlertsService : nsISupports
 {
    /**
     * Displays a sliding notification window.
     *
     * @param imageUrl       A URL identifying the image to put in the alert.
     *                       The OS X implemenation limits the amount of time it
     *                       will wait for an icon to load to six seconds. After
@@ -32,16 +32,18 @@ interface nsIAlertsService : nsISupports
     *                       used on Android and OS X. On Android the name is
     *                       hashed and used as a notification ID. Notifications
     *                       will replace previous notifications with the same name.
     * @param dir            Bidi override for the title. Valid values are
     *                       "auto", "ltr" or "rtl". Only available on supported
     *                       platforms.
     * @param lang           Language of title and text of the alert. Only available
     *                       on supported platforms.
+    * @param inPrivateBrowsing If set to true, imageUrl will be loaded in private
+    *                          browsing mode.
     * @throws NS_ERROR_NOT_AVAILABLE If the notification cannot be displayed.
     *
     * The following arguments will be passed to the alertListener's observe() 
     * method:
     *   subject - null
     *   topic   - "alertfinished" when the alert goes away
     *             "alertclickcallback" when the text is clicked
     *             "alertshow" when the alert is shown
@@ -57,17 +59,18 @@ interface nsIAlertsService : nsISupports
                               in AString  text,
                               [optional] in boolean textClickable,
                               [optional] in AString cookie,
                               [optional] in nsIObserver alertListener,
                               [optional] in AString name,
                               [optional] in AString dir,
                               [optional] in AString lang,
                               [optional] in AString data,
-                              [optional] in nsIPrincipal principal);
+                              [optional] in nsIPrincipal principal,
+                              [optional] in boolean inPrivateBrowsing);
 
    /**
     * Close alerts created by the service.
     *
     * @param name           The name of the notification to close. If no name
     *                       is provided then only a notification created with
     *                       no name (if any) will be closed.
     */
--- a/toolkit/components/alerts/nsXULAlerts.cpp
+++ b/toolkit/components/alerts/nsXULAlerts.cpp
@@ -39,17 +39,17 @@ nsXULAlertObserver::Observe(nsISupports*
   return rv;
 }
 
 nsresult
 nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle,
                                    const nsAString& aAlertText, bool aAlertTextClickable,
                                    const nsAString& aAlertCookie, nsIObserver* aAlertListener,
                                    const nsAString& aAlertName, const nsAString& aBidi,
-                                   const nsAString& aLang)
+                                   const nsAString& aLang, bool aInPrivateBrowsing)
 {
   nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
 
   nsCOMPtr<nsISupportsArray> argsArray;
   nsresult rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // create scriptable versions of our strings that we can store in our nsISupportsArray....
@@ -130,19 +130,22 @@ nsXULAlerts::ShowAlertNotification(const
   nsRefPtr<nsXULAlertObserver> alertObserver = new nsXULAlertObserver(this, aAlertName, aAlertListener);
   nsCOMPtr<nsISupports> iSupports(do_QueryInterface(alertObserver));
   ifptr->SetData(iSupports);
   ifptr->SetDataIID(&NS_GET_IID(nsIObserver));
   rv = argsArray->AppendElement(ifptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMWindow> newWindow;
-  rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank",
-                          "chrome,dialog=yes,titlebar=no,popup=yes", argsArray,
-                          getter_AddRefs(newWindow));
+  nsAutoCString features("chrome,dialog=yes,titlebar=no,popup=yes");
+  if (aInPrivateBrowsing) {
+    features.AppendLiteral(",private");
+  }
+  rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank", features.get(),
+                          argsArray, getter_AddRefs(newWindow));
   NS_ENSURE_SUCCESS(rv, rv);
 
   mNamedWindows.Put(aAlertName, newWindow);
   alertObserver->SetAlertWindow(newWindow);
 
   return NS_OK;
 }
 
--- a/toolkit/components/alerts/nsXULAlerts.h
+++ b/toolkit/components/alerts/nsXULAlerts.h
@@ -20,17 +20,17 @@ public:
   }
 
   virtual ~nsXULAlerts() {}
 
   nsresult ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle,
                                  const nsAString& aAlertText, bool aAlertTextClickable,
                                  const nsAString& aAlertCookie, nsIObserver* aAlertListener,
                                  const nsAString& aAlertName, const nsAString& aBidi,
-                                 const nsAString& aLang);
+                                 const nsAString& aLang, bool aInPrivateBrowsing);
 
   nsresult CloseAlert(const nsAString& aAlertName);
 protected:
   nsInterfaceHashtable<nsStringHashKey, nsIDOMWindow> mNamedWindows;
 };
 
 /**
  * This class wraps observers for alerts and watches
--- a/toolkit/components/downloads/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/nsDownloadManager.cpp
@@ -2751,17 +2751,17 @@ nsDownload::SetState(DownloadState aStat
               // retention policy, there's no reason to make the text clickable
               // because if it is, they'll click open the download manager and
               // the items they downloaded will have been removed.
               alerts->ShowAlertNotification(
                   NS_LITERAL_STRING(DOWNLOAD_MANAGER_ALERT_ICON), title,
                   message, !removeWhenDone,
                   mPrivate ? NS_LITERAL_STRING("private") : NS_LITERAL_STRING("non-private"),
                   mDownloadManager, EmptyString(), NS_LITERAL_STRING("auto"),
-                  EmptyString(), EmptyString(), nullptr);
+                  EmptyString(), EmptyString(), nullptr, mPrivate);
             }
         }
       }
 
 #if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
       nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mTarget);
       nsCOMPtr<nsIFile> file;
       nsAutoString path;
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
@@ -195,17 +195,17 @@ nsAlertsIconListener::ShowAlert(GdkPixbu
 
   if (result && mAlertListener)
     mAlertListener->Observe(nullptr, "alertshow", mAlertCookie.get());
 
   return result ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
-nsAlertsIconListener::StartRequest(const nsAString & aImageUrl)
+nsAlertsIconListener::StartRequest(const nsAString & aImageUrl, bool aInPrivateBrowsing)
 {
   if (mIconRequest) {
     // Another icon request is already in flight.  Kill it.
     mIconRequest->Cancel(NS_BINDING_ABORTED);
     mIconRequest = nullptr;
   }
 
   nsCOMPtr<nsIURI> imageUri;
@@ -214,18 +214,21 @@ nsAlertsIconListener::StartRequest(const
     return ShowAlert(nullptr);
 
   nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1"));
   if (!il)
     return ShowAlert(nullptr);
 
   nsresult rv = il->LoadImageXPCOM(imageUri, nullptr, nullptr,
                                    NS_LITERAL_STRING("default"), nullptr, nullptr,
-                                   this, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
-                                   0 /* use default */, getter_AddRefs(mIconRequest));
+                                   this, nullptr,
+                                   aInPrivateBrowsing ? nsIRequest::LOAD_ANONYMOUS :
+                                                        nsIRequest::LOAD_NORMAL,
+                                   nullptr, 0 /* use default */,
+                                   getter_AddRefs(mIconRequest));
   if (NS_FAILED(rv))
     return rv;
 
   mIconRequest->StartDecoding();
 
   return NS_OK;
 }
 
@@ -262,17 +265,18 @@ nsAlertsIconListener::Observe(nsISupport
 }
 
 nsresult
 nsAlertsIconListener::InitAlertAsync(const nsAString & aImageUrl,
                                      const nsAString & aAlertTitle, 
                                      const nsAString & aAlertText,
                                      bool aAlertTextClickable,
                                      const nsAString & aAlertCookie,
-                                     nsIObserver * aAlertListener)
+                                     nsIObserver * aAlertListener,
+                                     bool aInPrivateBrowsing)
 {
   if (!libNotifyHandle)
     return NS_ERROR_FAILURE;
 
   if (!notify_is_initted()) {
     // Give the name of this application to libnotify
     nsCOMPtr<nsIStringBundleService> bundleService = 
       do_GetService(NS_STRINGBUNDLE_CONTRACTID);
@@ -336,10 +340,10 @@ nsAlertsIconListener::InitAlertAsync(con
   }
 
   mAlertText = NS_ConvertUTF16toUTF8(aAlertText);
   mAlertHasAction = aAlertTextClickable;
 
   mAlertListener = aAlertListener;
   mAlertCookie = aAlertCookie;
 
-  return StartRequest(aImageUrl);
+  return StartRequest(aImageUrl, aInPrivateBrowsing);
 }
--- a/toolkit/system/gnome/nsAlertsIconListener.h
+++ b/toolkit/system/gnome/nsAlertsIconListener.h
@@ -29,17 +29,18 @@ public:
 
   nsAlertsIconListener();
 
   nsresult InitAlertAsync(const nsAString & aImageUrl,
                           const nsAString & aAlertTitle, 
                           const nsAString & aAlertText,
                           bool aAlertTextClickable,
                           const nsAString & aAlertCookie,
-                          nsIObserver * aAlertListener);
+                          nsIObserver * aAlertListener,
+                          bool aInPrivateBrowsing);
 
   void SendCallback();
   void SendClosed();
 
 protected:
   virtual ~nsAlertsIconListener();
 
   nsresult OnLoadComplete(imgIRequest* aRequest);
@@ -77,13 +78,13 @@ protected:
   static notify_get_server_caps_t notify_get_server_caps;
   static notify_notification_new_t notify_notification_new;
   static notify_notification_show_t notify_notification_show;
   static notify_notification_set_icon_from_pixbuf_t notify_notification_set_icon_from_pixbuf;
   static notify_notification_add_action_t notify_notification_add_action;
   NotifyNotification* mNotification;
   gulong mClosureHandler;
 
-  nsresult StartRequest(const nsAString & aImageUrl);
+  nsresult StartRequest(const nsAString & aImageUrl, bool aInPrivateBrowsing);
   nsresult ShowAlert(GdkPixbuf* aPixbuf);
 };
 
 #endif
--- a/toolkit/system/gnome/nsSystemAlertsService.cpp
+++ b/toolkit/system/gnome/nsSystemAlertsService.cpp
@@ -32,23 +32,24 @@ nsSystemAlertsService::Init()
 NS_IMETHODIMP nsSystemAlertsService::ShowAlertNotification(const nsAString & aImageUrl, const nsAString & aAlertTitle, 
                                                            const nsAString & aAlertText, bool aAlertTextClickable,
                                                            const nsAString & aAlertCookie,
                                                            nsIObserver * aAlertListener,
                                                            const nsAString & aAlertName,
                                                            const nsAString & aBidi,
                                                            const nsAString & aLang,
                                                            const nsAString & aData,
-                                                           nsIPrincipal * aPrincipal)
+                                                           nsIPrincipal * aPrincipal,
+                                                           bool aInPrivateBrowsing)
 {
   nsRefPtr<nsAlertsIconListener> alertListener = new nsAlertsIconListener();
   if (!alertListener)
     return NS_ERROR_OUT_OF_MEMORY;
 
   return alertListener->InitAlertAsync(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
-                                       aAlertCookie, aAlertListener);
+                                       aAlertCookie, aAlertListener, aInPrivateBrowsing);
 }
 
 NS_IMETHODIMP nsSystemAlertsService::CloseAlert(const nsAString& aAlertName,
                                                 nsIPrincipal* aPrincipal)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/widget/cocoa/OSXNotificationCenter.mm
+++ b/widget/cocoa/OSXNotificationCenter.mm
@@ -199,17 +199,18 @@ NS_IMETHODIMP
 OSXNotificationCenter::ShowAlertNotification(const nsAString & aImageUrl, const nsAString & aAlertTitle,
                                              const nsAString & aAlertText, bool aAlertTextClickable,
                                              const nsAString & aAlertCookie,
                                              nsIObserver * aAlertListener,
                                              const nsAString & aAlertName,
                                              const nsAString & aBidi,
                                              const nsAString & aLang,
                                              const nsAString & aData,
-                                             nsIPrincipal * aPrincipal)
+                                             nsIPrincipal * aPrincipal,
+                                             bool aInPrivateBrowsing)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   Class unClass = NSClassFromString(@"NSUserNotification");
   id<FakeNSUserNotification> notification = [[unClass alloc] init];
   notification.title = [NSString stringWithCharacters:(const unichar *)aAlertTitle.BeginReading()
                                                length:aAlertTitle.Length()];
   notification.informativeText = [NSString stringWithCharacters:(const unichar *)aAlertText.BeginReading()
@@ -241,18 +242,21 @@ OSXNotificationCenter::ShowAlertNotifica
     nsRefPtr<imgLoader> il = imgLoader::GetInstance();
     if (il) {
       nsCOMPtr<nsIURI> imageUri;
       NS_NewURI(getter_AddRefs(imageUri), aImageUrl);
       if (imageUri) {
         nsresult rv = il->LoadImage(imageUri, nullptr, nullptr,
                                     mozilla::net::RP_Default,
                                     aPrincipal, nullptr,
-                                    this, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
-                                    nsIContentPolicy::TYPE_IMAGE, EmptyString(),
+                                    this, nullptr,
+                                    aInPrivateBrowsing ? nsIRequest::LOAD_ANONYMOUS :
+                                                         nsIRequest::LOAD_NORMAL,
+                                    nullptr, nsIContentPolicy::TYPE_IMAGE,
+                                    EmptyString(),
                                     getter_AddRefs(osxni->mIconRequest));
         if (NS_SUCCEEDED(rv)) {
           // Set a timer for six seconds. If we don't have an icon by the time this
           // goes off then we go ahead without an icon.
           nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
           osxni->mIconTimeoutTimer = timer;
           timer->InitWithCallback(this, 6000, nsITimer::TYPE_ONE_SHOT);
           return NS_OK;