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 234818 c2aabf638fb48ad347ae6a78c5d901050216c945
parent 234759 3bc3a1bffafe2f49b4b877a8d1925b8630ebd710
child 234819 606533535f9bc89c3bb0031dcf51d4f713947180
push id7472
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 20:36:27 +0000
treeherdermozilla-aurora@300ca104f8fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs1106116
milestone36.0a1
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;