Bug 786419 - Part 2 - Modify calls to NS_IsOffline to check for NS_IsAppOffline as well r=jduell,sicking
--- 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(¬ificationAppId);
+
+ 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: