Bug 786419 - Part 2 - Modify calls to NS_IsOffline to check for NS_IsAppOffline as well r=jduell,sicking
authorValentin Gosu <valentin.gosu@gmail.com>
Sat, 23 Aug 2014 06:06:56 +0300
changeset 232384 9474c394d41be2504d3748491d3ab4a7c51b1cf7
parent 232383 7bcb80591690a0b70b8ee1854a7924cddc688003
child 232385 e99c308964f8442e99618ab60be41426081382bc
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell, sicking
bugs786419
milestone35.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 786419 - Part 2 - Modify calls to NS_IsOffline to check for NS_IsAppOffline as well r=jduell,sicking
dom/base/Navigator.cpp
dom/base/nsGlobalWindow.cpp
dom/workers/RuntimeService.cpp
dom/workers/WorkerPrivate.cpp
netwerk/base/public/nsNetUtil.h
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -579,16 +579,20 @@ Navigator::CookieEnabled()
   }
 
   return cookieEnabled;
 }
 
 bool
 Navigator::OnLine()
 {
+  if (mWindow && mWindow->GetDoc()) {
+    return !NS_IsAppOffline(mWindow->GetDoc()->NodePrincipal());
+  }
+
   return !NS_IsOffline();
 }
 
 NS_IMETHODIMP
 Navigator::GetBuildID(nsAString& aBuildID)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     const nsAdoptingString& override =
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -10738,17 +10738,17 @@ nsGlobalWindow::GetInterface(JSContext* 
 }
 
 void
 nsGlobalWindow::FireOfflineStatusEvent()
 {
   if (!IsCurrentInnerWindow())
     return;
   nsAutoString name;
-  if (NS_IsOffline()) {
+  if (NS_IsOffline() || NS_IsAppOffline(GetPrincipal())) {
     name.AssignLiteral("offline");
   } else {
     name.AssignLiteral("online");
   }
   // The event is fired at the body element, or if there is no body element,
   // at the document.
   nsCOMPtr<EventTarget> eventTarget = mDoc.get();
   nsHTMLDocument* htmlDoc = mDoc->AsHTMLDocument();
@@ -11294,17 +11294,18 @@ nsGlobalWindow::UnregisterIdleObserver(n
 
   return NS_OK;
 }
 
 nsresult
 nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
                         const char16_t* aData)
 {
-  if (!nsCRT::strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC)) {
+  if (!nsCRT::strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC) ||
+      !nsCRT::strcmp(aTopic, NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC)) {
     if (IsFrozen()) {
       // if an even number of notifications arrive while we're frozen,
       // we don't need to fire.
       mFireOfflineStatusChangeEventOnThaw = !mFireOfflineStatusChangeEventOnThaw;
     } else {
       FireOfflineStatusEvent();
     }
     return NS_OK;
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2595,16 +2595,38 @@ RuntimeService::Observe(nsISupports* aSu
     GarbageCollectAllWorkers(/* shrinking = */ true);
     CycleCollectAllWorkers();
     return NS_OK;
   }
   if (!strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC)) {
     SendOfflineStatusChangeEventToAllWorkers(NS_IsOffline());
     return NS_OK;
   }
+  if (!strcmp(aTopic, NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC)) {
+    nsCOMPtr<nsIAppOfflineInfo> info(do_QueryInterface(aSubject));
+    if (!info) {
+      return NS_OK;
+    }
+    nsIPrincipal * principal = GetPrincipalForAsmJSCacheOp();
+    if (!principal) {
+      return NS_OK;
+    }
+
+    uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID;
+    principal->GetAppId(&appId);
+
+    uint32_t notificationAppId = nsIScriptSecurityManager::UNKNOWN_APP_ID;
+    info->GetAppId(&notificationAppId);
+
+    if (appId != notificationAppId) {
+      return NS_OK;
+    }
+
+    SendOfflineStatusChangeEventToAllWorkers(NS_IsAppOffline(appId));
+  }
 
   NS_NOTREACHED("Unknown observer topic!");
   return NS_OK;
 }
 
 /* static */ void
 RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
 {
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3575,17 +3575,17 @@ WorkerPrivate::WorkerPrivate(JSContext* 
   if (aParent) {
     aParent->AssertIsOnWorkerThread();
     aParent->GetAllPreferences(mPreferences);
     mOnLine = aParent->OnLine();
   }
   else {
     AssertIsOnMainThread();
     RuntimeService::GetDefaultPreferences(mPreferences);
-    mOnLine = !NS_IsOffline();
+    mOnLine = !NS_IsOffline() && !NS_IsAppOffline(aLoadInfo.mPrincipal);
   }
 }
 
 WorkerPrivate::~WorkerPrivate()
 {
 }
 
 // static
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -70,16 +70,17 @@
 #include "nsIIDNService.h"
 #include "nsIChannelEventSink.h"
 #include "nsIChannelPolicy.h"
 #include "nsISocketProviderService.h"
 #include "nsISocketProvider.h"
 #include "nsIRedirectChannelRegistrar.h"
 #include "nsIMIMEHeaderParam.h"
 #include "nsILoadContext.h"
+#include "nsIScriptSecurityManager.h"
 #include "mozilla/Services.h"
 #include "nsIPrivateBrowsingChannel.h"
 #include "mozIApplicationClearPrivateDataParams.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsIContentSniffer.h"
 #include "nsCategoryCache.h"
 #include "nsStringStream.h"
 #include "nsIViewSourceChannel.h"
@@ -1895,16 +1896,40 @@ NS_IsOffline()
 {
     bool offline = true;
     nsCOMPtr<nsIIOService> ios = do_GetIOService();
     if (ios)
         ios->GetOffline(&offline);
     return offline;
 }
 
+inline bool
+NS_IsAppOffline(uint32_t appId)
+{
+    bool appOffline = false;
+    nsCOMPtr<nsIIOService> io(
+        do_GetService("@mozilla.org/network/io-service;1"));
+    if (io) {
+        io->IsAppOffline(appId, &appOffline);
+    }
+    return appOffline;
+}
+
+inline bool
+NS_IsAppOffline(nsIPrincipal * principal)
+{
+    if (!principal) {
+        return NS_IsOffline();
+    }
+    uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID;
+    principal->GetAppId(&appId);
+
+    return NS_IsAppOffline(appId);
+}
+
 /**
  * Helper functions for implementing nsINestedURI::innermostURI.
  *
  * Note that NS_DoImplGetInnermostURI is "private" -- call
  * NS_ImplGetInnermostURI instead.
  */
 inline nsresult
 NS_DoImplGetInnermostURI(nsINestedURI* nestedURI, nsIURI** result)
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -2509,17 +2509,21 @@ nsFtpState::CheckCache()
                          getter_AddRefs(session));
     if (!session)
         return false;
     session->SetDoomEntriesIfExpired(false);
     session->SetIsPrivate(isPrivate);
 
     // Set cache access requested:
     nsCacheAccessMode accessReq;
-    if (NS_IsOffline()) {
+    uint32_t appId;
+    bool isInBrowser;
+    NS_GetAppInfo(mChannel, &appId, &isInBrowser);
+
+    if (NS_IsOffline() || NS_IsAppOffline(appId)) {
         accessReq = nsICache::ACCESS_READ; // can only read
     } else if (mChannel->HasLoadFlag(nsIRequest::LOAD_BYPASS_CACHE)) {
         accessReq = nsICache::ACCESS_WRITE; // replace cache entry
     } else {
         accessReq = nsICache::ACCESS_READ_WRITE; // normal browsing
     }
 
     // Check to see if we are not allowed to write to the cache: