зеркало из https://github.com/mozilla/gecko-dev.git
Bug 786419 - Part 1 - Provide way to "set network offline" per app r=jduell
This commit is contained in:
Родитель
f9a4630645
Коммит
087d426a86
|
@ -88,6 +88,24 @@ interface nsIIOService : nsISupports
|
|||
*/
|
||||
attribute boolean offline;
|
||||
|
||||
/**
|
||||
* Set whether network appears to be offline for network connections from
|
||||
* a given appID.
|
||||
*
|
||||
* Calling this function may fire the "network:app-offline-status-changed"
|
||||
* notification, which is also sent to child processes containing this appId.
|
||||
* 'state' must one of nsIAppOfflineInfo::{ONLINE|OFFLINE|WIFI_ONLY}.
|
||||
*/
|
||||
void setAppOffline(in uint32_t appId, in long state);
|
||||
|
||||
/**
|
||||
* Returns true if given appId is currently not allowed to make network
|
||||
* connections. It will return true if the app is in the wifi-only state
|
||||
* and we are currently on a 3G connection.
|
||||
*/
|
||||
boolean isAppOffline(in uint32_t appId);
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a port number is banned. This involves consulting a list of
|
||||
* unsafe ports, corresponding to network services that may be easily
|
||||
|
@ -117,6 +135,18 @@ interface nsIIOService : nsISupports
|
|||
ACString extractScheme(in AUTF8String urlString);
|
||||
};
|
||||
|
||||
[scriptable, uuid(4ac296a0-ca1b-44f4-8787-117a88cb70fb)]
|
||||
interface nsIAppOfflineInfo : nsISupports
|
||||
{
|
||||
readonly attribute unsigned long appId;
|
||||
|
||||
const long ONLINE = 1;
|
||||
const long OFFLINE = 2;
|
||||
const long WIFI_ONLY = 3;
|
||||
|
||||
readonly attribute long mode;
|
||||
};
|
||||
|
||||
%{C++
|
||||
/**
|
||||
* We send notifications through nsIObserverService with topic
|
||||
|
@ -136,4 +166,10 @@ interface nsIIOService : nsISupports
|
|||
#define NS_IOSERVICE_OFFLINE_STATUS_TOPIC "network:offline-status-changed"
|
||||
#define NS_IOSERVICE_OFFLINE "offline"
|
||||
#define NS_IOSERVICE_ONLINE "online"
|
||||
|
||||
/**
|
||||
* When network:app-offline-status-changed is fired,
|
||||
* the 'Subject' argument is a nsIOfflineAppInfo.
|
||||
*/
|
||||
#define NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC "network:app-offline-status-changed"
|
||||
%}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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 "OfflineObserver.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIOService.h"
|
||||
#include "mozilla/net/NeckoCommon.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsThreadUtils.h"
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS(OfflineObserver, nsIObserver)
|
||||
|
||||
void
|
||||
OfflineObserver::RegisterOfflineObserver()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
RegisterOfflineObserverMainThread();
|
||||
} else {
|
||||
nsRefPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(this, &OfflineObserver::RegisterOfflineObserverMainThread);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OfflineObserver::RemoveOfflineObserver()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
RemoveOfflineObserverMainThread();
|
||||
} else {
|
||||
nsRefPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(this, &OfflineObserver::RemoveOfflineObserverMainThread);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OfflineObserver::RegisterOfflineObserverMainThread()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (!observerService) {
|
||||
return;
|
||||
}
|
||||
nsresult rv = observerService->AddObserver(this,
|
||||
NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to register observer");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OfflineObserver::RemoveOfflineObserverMainThread()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
observerService->RemoveObserver(this, NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC);
|
||||
}
|
||||
}
|
||||
|
||||
OfflineObserver::OfflineObserver(DisconnectableParent * parent)
|
||||
{
|
||||
mParent = parent;
|
||||
RegisterOfflineObserver();
|
||||
}
|
||||
|
||||
void
|
||||
OfflineObserver::RemoveObserver()
|
||||
{
|
||||
RemoveOfflineObserver();
|
||||
mParent = nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *aData)
|
||||
{
|
||||
if (mParent &&
|
||||
!strcmp(aTopic, NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC)) {
|
||||
mParent->OfflineNotification(aSubject);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
DisconnectableParent::GetAppId()
|
||||
{
|
||||
return NECKO_UNKNOWN_APP_ID;
|
||||
}
|
||||
|
||||
nsresult
|
||||
DisconnectableParent::OfflineNotification(nsISupports *aSubject)
|
||||
{
|
||||
nsCOMPtr<nsIAppOfflineInfo> info(do_QueryInterface(aSubject));
|
||||
if (!info) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
uint32_t targetAppId = NECKO_UNKNOWN_APP_ID;
|
||||
info->GetAppId(&targetAppId);
|
||||
|
||||
// Obtain App ID
|
||||
uint32_t appId = GetAppId();
|
||||
if (appId != targetAppId) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the app is offline, close the socket
|
||||
if (NS_IsAppOffline(appId)) {
|
||||
OfflineDisconnect();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // net namespace
|
||||
} // mozilla namespace
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#ifndef nsOfflineObserver_h__
|
||||
#define nsOfflineObserver_h__
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
/**
|
||||
* Parents should extend this class and have a nsRefPtr<OfflineObserver> member.
|
||||
* The constructor should initialize the member to new OfflineObserver(this)
|
||||
* and the destructor should call RemoveObserver on the member.
|
||||
*
|
||||
* GetAppId and OfflineDisconnect are called from the default implementation
|
||||
* of OfflineNotification. These should be overridden by classes that don't
|
||||
* provide an implementation of OfflineNotification.
|
||||
*/
|
||||
class DisconnectableParent
|
||||
{
|
||||
public:
|
||||
// This is called on the main thread, by the OfflineObserver.
|
||||
// aSubject is of type nsAppOfflineInfo and contains appId and offline mode.
|
||||
virtual nsresult OfflineNotification(nsISupports *aSubject);
|
||||
|
||||
// GetAppId returns the appId for the app associated with the parent
|
||||
virtual uint32_t GetAppId();
|
||||
|
||||
// OfflineDisconnect cancels all existing connections in the parent when
|
||||
// the app becomes offline.
|
||||
virtual void OfflineDisconnect() { }
|
||||
};
|
||||
|
||||
/**
|
||||
* This class observes the "network:app-offline-status-changed" topic and calls
|
||||
* OfflineNotification on the DisconnectableParent with the subject.
|
||||
*/
|
||||
class OfflineObserver
|
||||
: public nsIObserver
|
||||
{
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
public:
|
||||
// A nsRefPtr to this object should be kept by the disconnectable parent.
|
||||
|
||||
OfflineObserver(DisconnectableParent * parent);
|
||||
// This method needs to be called in the destructor of the parent
|
||||
// It removes the observer from the nsObserverService list, and it clears
|
||||
// the pointer it holds to the disconnectable parent.
|
||||
void RemoveObserver();
|
||||
private:
|
||||
|
||||
// These methods are called to register and unregister the observer.
|
||||
// If they are called on the main thread they register the observer right
|
||||
// away, otherwise they dispatch and event to the main thread
|
||||
void RegisterOfflineObserver();
|
||||
void RemoveOfflineObserver();
|
||||
void RegisterOfflineObserverMainThread();
|
||||
void RemoveOfflineObserverMainThread();
|
||||
private:
|
||||
virtual ~OfflineObserver() { }
|
||||
DisconnectableParent * mParent;
|
||||
};
|
||||
|
||||
} // net namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // nsOfflineObserver_h__
|
|
@ -17,6 +17,7 @@ EXPORTS.mozilla.net += [
|
|||
'ChannelDiverterParent.h',
|
||||
'Dashboard.h',
|
||||
'DashboardTypes.h',
|
||||
'OfflineObserver.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -85,6 +86,7 @@ SOURCES += [
|
|||
'nsAsyncRedirectVerifyHelper.cpp',
|
||||
'nsSocketTransport2.cpp',
|
||||
'nsSocketTransportService2.cpp',
|
||||
'OfflineObserver.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nsIConsoleService.h"
|
||||
#include "nsIUploadChannel2.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIProtocolProxyCallback.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "nsINetworkLinkService.h"
|
||||
|
@ -39,6 +40,10 @@
|
|||
#include "MainThreadUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsINetworkManager.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "nsNativeConnectionHelper.h"
|
||||
#endif
|
||||
|
@ -133,11 +138,14 @@ int16_t gBadPortList[] = {
|
|||
static const char kProfileChangeNetTeardownTopic[] = "profile-change-net-teardown";
|
||||
static const char kProfileChangeNetRestoreTopic[] = "profile-change-net-restore";
|
||||
static const char kProfileDoChange[] = "profile-do-change";
|
||||
static const char kNetworkActiveChanged[] = "network-active-changed";
|
||||
|
||||
// Necko buffer defaults
|
||||
uint32_t nsIOService::gDefaultSegmentSize = 4096;
|
||||
uint32_t nsIOService::gDefaultSegmentCount = 24;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAppOfflineInfo, nsIAppOfflineInfo)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsIOService::nsIOService()
|
||||
|
@ -151,6 +159,7 @@ nsIOService::nsIOService()
|
|||
, mChannelEventSinks(NS_CHANNEL_EVENT_SINK_CATEGORY)
|
||||
, mAutoDialEnabled(false)
|
||||
, mNetworkNotifyChanged(true)
|
||||
, mPreviousWifiState(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -204,6 +213,7 @@ nsIOService::Init()
|
|||
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
|
||||
observerService->AddObserver(this, NS_NETWORK_LINK_TOPIC, true);
|
||||
observerService->AddObserver(this, NS_WIDGET_WAKE_OBSERVER_TOPIC, true);
|
||||
observerService->AddObserver(this, kNetworkActiveChanged, true);
|
||||
}
|
||||
else
|
||||
NS_WARNING("failed to get observer service");
|
||||
|
@ -914,6 +924,61 @@ nsIOService::GetPrefBranch(nsIPrefBranch **result)
|
|||
CallGetService(NS_PREFSERVICE_CONTRACTID, result);
|
||||
}
|
||||
|
||||
// This returns true if wifi-only apps should have connectivity.
|
||||
static bool
|
||||
IsWifiActive()
|
||||
{
|
||||
// We don't need to do this check inside the child process
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
return false;
|
||||
}
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// On B2G we query the network manager for the active interface
|
||||
nsCOMPtr<nsINetworkManager> networkManager =
|
||||
do_GetService("@mozilla.org/network/manager;1");
|
||||
if (!networkManager) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsINetworkInterface> active;
|
||||
networkManager->GetActive(getter_AddRefs(active));
|
||||
if (!active) {
|
||||
return false;
|
||||
}
|
||||
int32_t type;
|
||||
if (NS_FAILED(active->GetType(&type))) {
|
||||
return false;
|
||||
}
|
||||
switch (type) {
|
||||
case nsINetworkInterface::NETWORK_TYPE_WIFI:
|
||||
case nsINetworkInterface::NETWORK_TYPE_WIFI_P2P:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
// On anything else than B2G we return true so than wifi-only
|
||||
// apps don't think they are offline.
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct EnumeratorParams {
|
||||
nsIOService *service;
|
||||
int32_t status;
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
nsIOService::EnumerateWifiAppsChangingState(const unsigned int &aKey,
|
||||
int32_t aValue,
|
||||
void *aUserArg)
|
||||
{
|
||||
EnumeratorParams *params = reinterpret_cast<EnumeratorParams*>(aUserArg);
|
||||
if (aValue == nsIAppOfflineInfo::WIFI_ONLY) {
|
||||
params->service->NotifyAppOfflineStatus(aKey, params->status);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// nsIObserver interface
|
||||
NS_IMETHODIMP
|
||||
nsIOService::Observe(nsISupports *subject,
|
||||
|
@ -976,6 +1041,35 @@ nsIOService::Observe(nsISupports *subject,
|
|||
NS_NETWORK_LINK_TOPIC,
|
||||
MOZ_UTF16(NS_NETWORK_LINK_DATA_CHANGED));
|
||||
}
|
||||
} else if (!strcmp(topic, kNetworkActiveChanged)) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (IsNeckoChild()) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsINetworkInterface> interface = do_QueryInterface(subject);
|
||||
if (!interface) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
int32_t state;
|
||||
if (NS_FAILED(interface->GetState(&state))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool wifiActive = IsWifiActive();
|
||||
int32_t newWifiState = wifiActive ?
|
||||
nsINetworkInterface::NETWORK_TYPE_WIFI :
|
||||
nsINetworkInterface::NETWORK_TYPE_MOBILE;
|
||||
if (mPreviousWifiState != newWifiState) {
|
||||
// Notify wifi-only apps of their new status
|
||||
int32_t status = wifiActive ?
|
||||
nsIAppOfflineInfo::ONLINE : nsIAppOfflineInfo::OFFLINE;
|
||||
|
||||
EnumeratorParams params = {this, status};
|
||||
mAppsOfflineStatus.EnumerateRead(EnumerateWifiAppsChangingState, ¶ms);
|
||||
}
|
||||
|
||||
mPreviousWifiState = newWifiState;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1288,3 +1382,143 @@ nsIOService::SpeculativeConnect(nsIURI *aURI,
|
|||
new IOServiceProxyCallback(aCallbacks, this);
|
||||
return pps->AsyncResolve(aURI, 0, callback, getter_AddRefs(cancelable));
|
||||
}
|
||||
|
||||
void
|
||||
nsIOService::NotifyAppOfflineStatus(uint32_t appId, int32_t state)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread(),
|
||||
"Should be called on the main thread");
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
MOZ_ASSERT(observerService, "The observer service should not be null");
|
||||
|
||||
if (observerService) {
|
||||
nsRefPtr<nsAppOfflineInfo> info = new nsAppOfflineInfo(appId, state);
|
||||
observerService->NotifyObservers(
|
||||
info,
|
||||
NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC,
|
||||
MOZ_UTF16("all data in nsIAppOfflineInfo subject argument"));
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class SetAppOfflineMainThread : public nsRunnable
|
||||
{
|
||||
public:
|
||||
SetAppOfflineMainThread(uint32_t aAppId, int32_t aState)
|
||||
: mAppId(aAppId)
|
||||
, mState(aState)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gIOService->SetAppOfflineInternal(mAppId, mState);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
uint32_t mAppId;
|
||||
int32_t mState;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::SetAppOffline(uint32_t aAppId, int32_t aState)
|
||||
{
|
||||
NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(aAppId != nsIScriptSecurityManager::NO_APP_ID,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
NS_ENSURE_TRUE(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
NS_DispatchToMainThread(new SetAppOfflineMainThread(aAppId, aState));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SetAppOfflineInternal(aAppId, aState);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsIOService::SetAppOfflineInternal(uint32_t aAppId, int32_t aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_TRUE_VOID(NS_IsMainThread());
|
||||
|
||||
int32_t state;
|
||||
if (mAppsOfflineStatus.Get(aAppId, &state) && state == aState) {
|
||||
// The app is already in this state. Nothing needs to be done.
|
||||
return;
|
||||
}
|
||||
|
||||
bool wifiActive = IsWifiActive();
|
||||
bool offline = (state == nsIAppOfflineInfo::OFFLINE) ||
|
||||
(state == nsIAppOfflineInfo::WIFI_ONLY && !wifiActive);
|
||||
|
||||
switch (aState) {
|
||||
case nsIAppOfflineInfo::OFFLINE:
|
||||
mAppsOfflineStatus.Put(aAppId, nsIAppOfflineInfo::OFFLINE);
|
||||
if (!offline) {
|
||||
NotifyAppOfflineStatus(aAppId, nsIAppOfflineInfo::OFFLINE);
|
||||
}
|
||||
break;
|
||||
case nsIAppOfflineInfo::WIFI_ONLY:
|
||||
mAppsOfflineStatus.Put(aAppId, nsIAppOfflineInfo::WIFI_ONLY);
|
||||
if (offline && wifiActive) {
|
||||
NotifyAppOfflineStatus(aAppId, nsIAppOfflineInfo::ONLINE);
|
||||
} else if (!offline && !wifiActive) {
|
||||
NotifyAppOfflineStatus(aAppId, nsIAppOfflineInfo::OFFLINE);
|
||||
}
|
||||
break;
|
||||
case nsIAppOfflineInfo::ONLINE:
|
||||
mAppsOfflineStatus.Remove(aAppId);
|
||||
if (offline) {
|
||||
NotifyAppOfflineStatus(aAppId, nsIAppOfflineInfo::ONLINE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::IsAppOffline(uint32_t aAppId, bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(aResult);
|
||||
*aResult = mOffline;
|
||||
|
||||
if (mOffline) {
|
||||
// If the entire browser is offline, return that status
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aAppId == NECKO_NO_APP_ID ||
|
||||
aAppId == NECKO_UNKNOWN_APP_ID) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
int32_t state;
|
||||
if (mAppsOfflineStatus.Get(aAppId, &state)) {
|
||||
switch (state) {
|
||||
case nsIAppOfflineInfo::OFFLINE:
|
||||
*aResult = true;
|
||||
break;
|
||||
case nsIAppOfflineInfo::WIFI_ONLY:
|
||||
*aResult = !IsWifiActive();
|
||||
break;
|
||||
default:
|
||||
// The app is online by default
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "nsIChannelEventSink.h"
|
||||
#include "nsCategoryCache.h"
|
||||
#include "nsISpeculativeConnect.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#define NS_N(x) (sizeof(x)/sizeof(*x))
|
||||
|
@ -37,6 +38,12 @@ class nsIProxyInfo;
|
|||
class nsPIDNSService;
|
||||
class nsPISocketTransportService;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
class NeckoChild;
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
class nsIOService MOZ_FINAL : public nsIIOService2
|
||||
, public nsIObserver
|
||||
, public nsINetUtil
|
||||
|
@ -74,6 +81,9 @@ public:
|
|||
return mOffline && mSettingOffline && !mSetOfflineValue;
|
||||
}
|
||||
|
||||
// Should only be called from NeckoChild. Use SetAppOffline instead.
|
||||
void SetAppOfflineInternal(uint32_t appId, int32_t status);
|
||||
|
||||
private:
|
||||
// These shouldn't be called directly:
|
||||
// - construct using GetInstance
|
||||
|
@ -102,6 +112,11 @@ private:
|
|||
void LookupProxyInfo(nsIURI *aURI, nsIURI *aProxyURI, uint32_t aProxyFlags,
|
||||
nsCString *aScheme, nsIProxyInfo **outPI);
|
||||
|
||||
// notify content processes of offline status
|
||||
// 'status' must be a nsIAppOfflineInfo mode constant.
|
||||
void NotifyAppOfflineStatus(uint32_t appId, int32_t status);
|
||||
static PLDHashOperator EnumerateWifiAppsChangingState(const unsigned int &, int32_t, void*);
|
||||
|
||||
private:
|
||||
bool mOffline;
|
||||
bool mOfflineForProfileChange;
|
||||
|
@ -130,12 +145,49 @@ private:
|
|||
|
||||
bool mAutoDialEnabled;
|
||||
bool mNetworkNotifyChanged;
|
||||
int32_t mPreviousWifiState;
|
||||
// Hashtable of (appId, nsIAppOffineInfo::mode) pairs
|
||||
// that is used especially in IsAppOffline
|
||||
nsDataHashtable<nsUint32HashKey, int32_t> mAppsOfflineStatus;
|
||||
public:
|
||||
// Used for all default buffer sizes that necko allocates.
|
||||
static uint32_t gDefaultSegmentSize;
|
||||
static uint32_t gDefaultSegmentCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is passed as the subject to a NotifyObservers call for the
|
||||
* "network:app-offline-status-changed" topic.
|
||||
* Observers will use the appId and mode to get the offline status of an app.
|
||||
*/
|
||||
class nsAppOfflineInfo : public nsIAppOfflineInfo
|
||||
{
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
public:
|
||||
nsAppOfflineInfo(uint32_t aAppId, int32_t aMode)
|
||||
: mAppId(aAppId), mMode(aMode)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP GetMode(int32_t *aMode)
|
||||
{
|
||||
*aMode = mMode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP GetAppId(uint32_t *aAppId)
|
||||
{
|
||||
*aAppId = mAppId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~nsAppOfflineInfo() {}
|
||||
|
||||
uint32_t mAppId;
|
||||
int32_t mMode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reference to the IO service singleton. May be null.
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "mozilla/net/RtspChannelChild.h"
|
||||
#endif
|
||||
#include "SerializedLoadContext.h"
|
||||
#include "nsIOService.h"
|
||||
|
||||
using mozilla::dom::TCPSocketChild;
|
||||
using mozilla::dom::TCPServerSocketChild;
|
||||
|
@ -317,5 +318,17 @@ NeckoChild::RecvAsyncAuthPromptForNestedFrame(const uint64_t& aNestedFrameId,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoChild::RecvAppOfflineStatus(const uint32_t& aId, const bool& aOffline)
|
||||
{
|
||||
// Instantiate the service to make sure gIOService is initialized
|
||||
nsCOMPtr<nsIIOService> ioService = do_GetIOService();
|
||||
if (gIOService) {
|
||||
gIOService->SetAppOfflineInternal(aId, aOffline ?
|
||||
nsIAppOfflineInfo::OFFLINE : nsIAppOfflineInfo::ONLINE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}} // mozilla::net
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ protected:
|
|||
const nsCString& aUri,
|
||||
const nsString& aRealm,
|
||||
const uint64_t& aCallbackId) MOZ_OVERRIDE;
|
||||
virtual bool RecvAppOfflineStatus(const uint32_t& aId, const bool& aOffline) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "nsAuthInformationHolder.h"
|
||||
#include "nsIAuthPromptCallback.h"
|
||||
#include "nsPrincipal.h"
|
||||
#include "nsIOService.h"
|
||||
#include "mozilla/net/OfflineObserver.h"
|
||||
|
||||
using mozilla::dom::ContentParent;
|
||||
using mozilla::dom::TabParent;
|
||||
|
@ -74,10 +76,15 @@ NeckoParent::NeckoParent()
|
|||
LossyCopyUTF16toASCII(corePath, mCoreAppsBasePath);
|
||||
LossyCopyUTF16toASCII(webPath, mWebAppsBasePath);
|
||||
}
|
||||
|
||||
mObserver = new OfflineObserver(this);
|
||||
}
|
||||
|
||||
NeckoParent::~NeckoParent()
|
||||
{
|
||||
if (mObserver) {
|
||||
mObserver->RemoveObserver();
|
||||
}
|
||||
}
|
||||
|
||||
static PBOverrideStatus
|
||||
|
@ -796,4 +803,43 @@ NeckoParent::RecvOnAuthCancelled(const uint64_t& aCallbackId,
|
|||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NeckoParent::OfflineNotification(nsISupports *aSubject)
|
||||
{
|
||||
nsCOMPtr<nsIAppOfflineInfo> info(do_QueryInterface(aSubject));
|
||||
if (!info) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t targetAppId = NECKO_UNKNOWN_APP_ID;
|
||||
info->GetAppId(&targetAppId);
|
||||
|
||||
for (uint32_t i = 0; i < Manager()->ManagedPBrowserParent().Length(); ++i) {
|
||||
nsRefPtr<TabParent> tabParent =
|
||||
static_cast<TabParent*>(Manager()->ManagedPBrowserParent()[i]);
|
||||
uint32_t appId = tabParent->OwnOrContainingAppId();
|
||||
|
||||
if (appId == targetAppId) {
|
||||
if (gIOService) {
|
||||
bool offline = false;
|
||||
nsresult rv = gIOService->IsAppOffline(appId, &offline);
|
||||
if (NS_FAILED(rv)) {
|
||||
printf_stderr("Unexpected - NeckoParent: "
|
||||
"appId not found by isAppOffline(): %u\n", appId);
|
||||
break;
|
||||
}
|
||||
if (!SendAppOfflineStatus(appId, offline)) {
|
||||
printf_stderr("NeckoParent: "
|
||||
"SendAppOfflineStatus failed for appId: %u\n", appId);
|
||||
}
|
||||
// Once we found the targetAppId, we don't need to continue
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}} // mozilla::net
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "mozilla/net/PNeckoParent.h"
|
||||
#include "mozilla/net/NeckoCommon.h"
|
||||
#include "mozilla/net/OfflineObserver.h"
|
||||
|
||||
#ifndef mozilla_net_NeckoParent_h
|
||||
#define mozilla_net_NeckoParent_h
|
||||
|
@ -22,8 +23,9 @@ enum PBOverrideStatus {
|
|||
};
|
||||
|
||||
// Header file contents
|
||||
class NeckoParent :
|
||||
public PNeckoParent
|
||||
class NeckoParent
|
||||
: public PNeckoParent
|
||||
, public DisconnectableParent
|
||||
{
|
||||
public:
|
||||
NeckoParent();
|
||||
|
@ -51,7 +53,7 @@ public:
|
|||
nsCOMPtr<nsILoadContext> &aResult);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult OfflineNotification(nsISupports *) MOZ_OVERRIDE;
|
||||
virtual void
|
||||
CloneManagees(ProtocolBase* aSource,
|
||||
mozilla::ipc::ProtocolCloneContext* aCtx) MOZ_OVERRIDE;
|
||||
|
@ -201,6 +203,7 @@ protected:
|
|||
private:
|
||||
nsCString mCoreAppsBasePath;
|
||||
nsCString mWebAppsBasePath;
|
||||
nsRefPtr<OfflineObserver> mObserver;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -100,6 +100,8 @@ child:
|
|||
*/
|
||||
AsyncAuthPromptForNestedFrame(uint64_t nestedFrameId, nsCString uri,
|
||||
nsString realm, uint64_t callbackId);
|
||||
// Notifies child that a given app is now offline (or online)
|
||||
AppOfflineStatus(uint32_t appId, bool offline);
|
||||
|
||||
both:
|
||||
// Actually we need PTCPSocket() for parent. But ipdl disallows us having different
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "SerializedLoadContext.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "nsIOService.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
|
@ -39,11 +40,16 @@ FTPChannelParent::FTPChannelParent(nsILoadContext* aLoadContext, PBOverrideStatu
|
|||
nsIProtocolHandler* handler;
|
||||
CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &handler);
|
||||
NS_ASSERTION(handler, "no ftp handler");
|
||||
|
||||
mObserver = new OfflineObserver(this);
|
||||
}
|
||||
|
||||
FTPChannelParent::~FTPChannelParent()
|
||||
{
|
||||
gFtpHandler->Release();
|
||||
if (mObserver) {
|
||||
mObserver->RemoveObserver();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -115,6 +121,17 @@ FTPChannelParent::DoAsyncOpen(const URIParams& aURI,
|
|||
this, uriSpec.get()));
|
||||
#endif
|
||||
|
||||
bool app_offline = false;
|
||||
uint32_t appId = GetAppId();
|
||||
if (appId != NECKO_UNKNOWN_APP_ID &&
|
||||
appId != NECKO_NO_APP_ID) {
|
||||
gIOService->IsAppOffline(appId, &app_offline);
|
||||
LOG(("FTP app id %u is offline %d\n", appId, app_offline));
|
||||
}
|
||||
|
||||
if (app_offline)
|
||||
return SendFailedAsyncOpen(NS_ERROR_OFFLINE);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
||||
if (NS_FAILED(rv))
|
||||
|
@ -196,6 +213,7 @@ FTPChannelParent::RecvCancel(const nsresult& status)
|
|||
{
|
||||
if (mChannel)
|
||||
mChannel->Cancel(status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -642,6 +660,25 @@ FTPChannelParent::NotifyDiversionFailed(nsresult aErrorCode,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
FTPChannelParent::OfflineDisconnect()
|
||||
{
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(NS_ERROR_OFFLINE);
|
||||
}
|
||||
mStatus = NS_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
FTPChannelParent::GetAppId()
|
||||
{
|
||||
uint32_t appId = NECKO_UNKNOWN_APP_ID;
|
||||
if (mLoadContext) {
|
||||
mLoadContext->GetAppId(&appId);
|
||||
}
|
||||
return appId;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent::nsIChannelEventSink
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "nsIParentChannel.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "OfflineObserver.h"
|
||||
|
||||
class nsFtpChannel;
|
||||
class nsILoadContext;
|
||||
|
@ -25,6 +26,7 @@ class FTPChannelParent : public PFTPChannelParent
|
|||
, public nsIInterfaceRequestor
|
||||
, public ADivertableParentChannel
|
||||
, public nsIChannelEventSink
|
||||
, public DisconnectableParent
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -82,6 +84,9 @@ protected:
|
|||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
|
||||
void OfflineDisconnect() MOZ_OVERRIDE;
|
||||
uint32_t GetAppId() MOZ_OVERRIDE;
|
||||
|
||||
// if configured to use HTTP proxy for FTP, this can an an HTTP channel.
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
||||
|
@ -106,6 +111,7 @@ protected:
|
|||
// Set if we successfully suspended the nsHttpChannel for diversion. Unset
|
||||
// when we call ResumeForDiversion.
|
||||
bool mSuspendedForDiversion;
|
||||
nsRefPtr<OfflineObserver> mObserver;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include "nsIAuthPromptCallback.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "nsIOService.h"
|
||||
#include "nsICachingChannel.h"
|
||||
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::ipc;
|
||||
|
@ -66,10 +69,15 @@ HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding,
|
|||
} else {
|
||||
mNestedFrameId = iframeEmbedding.get_uint64_t();
|
||||
}
|
||||
|
||||
mObserver = new OfflineObserver(this);
|
||||
}
|
||||
|
||||
HttpChannelParent::~HttpChannelParent()
|
||||
{
|
||||
if (mObserver) {
|
||||
mObserver->RemoveObserver();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -164,7 +172,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
|||
const OptionalURIParams& aDocURI,
|
||||
const OptionalURIParams& aReferrerURI,
|
||||
const OptionalURIParams& aAPIRedirectToURI,
|
||||
const uint32_t& loadFlags,
|
||||
const uint32_t& aLoadFlags,
|
||||
const RequestHeaderTuples& requestHeaders,
|
||||
const nsCString& requestMethod,
|
||||
const OptionalInputStreamParams& uploadStream,
|
||||
|
@ -213,6 +221,18 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
|||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
bool appOffline = false;
|
||||
uint32_t appId = GetAppId();
|
||||
if (appId != NECKO_UNKNOWN_APP_ID &&
|
||||
appId != NECKO_NO_APP_ID) {
|
||||
gIOService->IsAppOffline(appId, &appOffline);
|
||||
}
|
||||
|
||||
uint32_t loadFlags = aLoadFlags;
|
||||
if (appOffline) {
|
||||
loadFlags |= nsICachingChannel::LOAD_ONLY_FROM_CACHE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
uri,
|
||||
|
@ -309,10 +329,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
|||
|
||||
if (setChooseApplicationCache) {
|
||||
bool inBrowser = false;
|
||||
uint32_t appId = NECKO_NO_APP_ID;
|
||||
if (mLoadContext) {
|
||||
mLoadContext->GetIsInBrowserElement(&inBrowser);
|
||||
mLoadContext->GetAppId(&appId);
|
||||
}
|
||||
|
||||
bool chooseAppCache = false;
|
||||
|
@ -357,6 +375,18 @@ HttpChannelParent::ConnectChannel(const uint32_t& channelId)
|
|||
}
|
||||
}
|
||||
|
||||
bool appOffline = false;
|
||||
uint32_t appId = GetAppId();
|
||||
if (appId != NECKO_UNKNOWN_APP_ID &&
|
||||
appId != NECKO_NO_APP_ID) {
|
||||
gIOService->IsAppOffline(appId, &appOffline);
|
||||
}
|
||||
|
||||
if (appOffline) {
|
||||
mChannel->Cancel(NS_ERROR_OFFLINE);
|
||||
mStatus = NS_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1036,6 +1066,25 @@ HttpChannelParent::NotifyDiversionFailed(nsresult aErrorCode,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelParent::OfflineDisconnect()
|
||||
{
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(NS_ERROR_OFFLINE);
|
||||
}
|
||||
mStatus = NS_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
HttpChannelParent::GetAppId()
|
||||
{
|
||||
uint32_t appId = NECKO_UNKNOWN_APP_ID;
|
||||
if (mLoadContext) {
|
||||
mLoadContext->GetAppId(&appId);
|
||||
}
|
||||
return appId;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelParent::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
|
||||
void** aResult)
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "mozilla/net/PHttpChannelParent.h"
|
||||
#include "mozilla/net/NeckoCommon.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "OfflineObserver.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIParentRedirectingChannel.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsHttpChannel.h"
|
||||
|
@ -38,6 +40,7 @@ class HttpChannelParent : public PHttpChannelParent
|
|||
, public nsIInterfaceRequestor
|
||||
, public ADivertableParentChannel
|
||||
, public nsIAuthPromptProvider
|
||||
, public DisconnectableParent
|
||||
{
|
||||
virtual ~HttpChannelParent();
|
||||
|
||||
|
@ -129,6 +132,9 @@ protected:
|
|||
friend class HttpChannelParentListener;
|
||||
nsRefPtr<mozilla::dom::TabParent> mTabParent;
|
||||
|
||||
void OfflineDisconnect() MOZ_OVERRIDE;
|
||||
uint32_t GetAppId() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsRefPtr<nsHttpChannel> mChannel;
|
||||
nsCOMPtr<nsICacheEntry> mCacheEntry;
|
||||
|
@ -150,6 +156,8 @@ private:
|
|||
bool mSentRedirect1BeginFailed : 1;
|
||||
bool mReceivedRedirect2Verify : 1;
|
||||
|
||||
nsRefPtr<OfflineObserver> mObserver;
|
||||
|
||||
PBOverrideStatus mPBOverride;
|
||||
|
||||
nsCOMPtr<nsILoadContext> mLoadContext;
|
||||
|
|
|
@ -2584,8 +2584,16 @@ nsHttpChannel::OpenCacheEntry(bool usingSSL)
|
|||
openURI = mURI;
|
||||
}
|
||||
|
||||
uint32_t appId = info->AppId();
|
||||
bool appOffline = false;
|
||||
|
||||
if (appId != NECKO_NO_APP_ID) {
|
||||
gIOService->IsAppOffline(appId, &appOffline);
|
||||
LOG(("nsHttpChannel::OpenCacheEntry appId: %u, offline: %d\n", appId, appOffline));
|
||||
}
|
||||
|
||||
uint32_t cacheEntryOpenFlags;
|
||||
bool offline = gIOService->IsOffline();
|
||||
bool offline = gIOService->IsOffline() || appOffline;
|
||||
if (offline || (mLoadFlags & INHIBIT_CACHING)) {
|
||||
if (BYPASS_LOCAL_CACHE(mLoadFlags) && !offline) {
|
||||
goto bypassCacheEntryOpen;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "SerializedLoadContext.h"
|
||||
#include "nsIOService.h"
|
||||
#include "mozilla/net/NeckoCommon.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
|
@ -33,8 +35,15 @@ WebSocketChannelParent::WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvi
|
|||
if (!webSocketLog)
|
||||
webSocketLog = PR_NewLogModule("nsWebSocket");
|
||||
#endif
|
||||
mObserver = new OfflineObserver(this);
|
||||
}
|
||||
|
||||
WebSocketChannelParent::~WebSocketChannelParent()
|
||||
{
|
||||
if (mObserver) {
|
||||
mObserver->RemoveObserver();
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// WebSocketChannelParent::PWebSocketChannelParent
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -63,6 +72,17 @@ WebSocketChannelParent::RecvAsyncOpen(const URIParams& aURI,
|
|||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
||||
|
||||
bool appOffline = false;
|
||||
uint32_t appId = GetAppId();
|
||||
if (appId != NECKO_UNKNOWN_APP_ID &&
|
||||
appId != NECKO_NO_APP_ID) {
|
||||
gIOService->IsAppOffline(appId, &appOffline);
|
||||
if (appOffline) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (aSecure) {
|
||||
mChannel =
|
||||
do_CreateInstance("@mozilla.org/network/protocol;1?name=wss", &rv);
|
||||
|
@ -117,6 +137,7 @@ WebSocketChannelParent::RecvClose(const uint16_t& code, const nsCString& reason)
|
|||
nsresult rv = mChannel->Close(code, reason);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -258,6 +279,24 @@ WebSocketChannelParent::GetInterface(const nsIID & iid, void **result)
|
|||
return QueryInterface(iid, result);
|
||||
}
|
||||
|
||||
void
|
||||
WebSocketChannelParent::OfflineDisconnect()
|
||||
{
|
||||
if (mChannel) {
|
||||
mChannel->Close(nsIWebSocketChannel::CLOSE_GOING_AWAY,
|
||||
nsCString("App is offline"));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WebSocketChannelParent::GetAppId()
|
||||
{
|
||||
uint32_t appId = NECKO_UNKNOWN_APP_ID;
|
||||
if (mLoadContext) {
|
||||
mLoadContext->GetAppId(&appId);
|
||||
}
|
||||
return appId;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsILoadContext.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "OfflineObserver.h"
|
||||
|
||||
class nsIAuthPromptProvider;
|
||||
|
||||
|
@ -23,10 +24,10 @@ namespace net {
|
|||
|
||||
class WebSocketChannelParent : public PWebSocketParent,
|
||||
public nsIWebSocketListener,
|
||||
public DisconnectableParent,
|
||||
public nsIInterfaceRequestor
|
||||
{
|
||||
~WebSocketChannelParent() {}
|
||||
|
||||
~WebSocketChannelParent();
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIWEBSOCKETLISTENER
|
||||
|
@ -54,6 +55,10 @@ class WebSocketChannelParent : public PWebSocketParent,
|
|||
|
||||
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
|
||||
void OfflineDisconnect() MOZ_OVERRIDE;
|
||||
uint32_t GetAppId() MOZ_OVERRIDE;
|
||||
nsRefPtr<OfflineObserver> mObserver;
|
||||
|
||||
nsCOMPtr<nsIAuthPromptProvider> mAuthProvider;
|
||||
nsCOMPtr<nsIWebSocketChannel> mChannel;
|
||||
nsCOMPtr<nsILoadContext> mLoadContext;
|
||||
|
|
Загрузка…
Ссылка в новой задаче