mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1134596 - Separate nsIOService's network detection from offlineMode r=honzab
This commit is contained in:
parent
c63887599f
commit
5882106bb7
@ -610,7 +610,7 @@ pref("mousewheel.with_win.action", 1);
|
||||
pref("browser.xul.error_pages.enabled", true);
|
||||
pref("browser.xul.error_pages.expert_bad_cert", false);
|
||||
|
||||
// Work Offline is best manually managed by the user.
|
||||
// If true, network link events will change the value of navigator.onLine
|
||||
pref("network.manage-offline-status", false);
|
||||
|
||||
// We want to make sure mail URLs are handled externally...
|
||||
|
@ -806,12 +806,15 @@ ContentChild::InitXPCOM()
|
||||
NS_WARNING("Couldn't register console listener for child process");
|
||||
|
||||
bool isOffline, isLangRTL;
|
||||
bool isConnected;
|
||||
ClipboardCapabilities clipboardCaps;
|
||||
DomainPolicyClone domainPolicy;
|
||||
|
||||
SendGetXPCOMProcessAttributes(&isOffline, &isLangRTL, &mAvailableDictionaries,
|
||||
SendGetXPCOMProcessAttributes(&isOffline, &isConnected,
|
||||
&isLangRTL, &mAvailableDictionaries,
|
||||
&clipboardCaps, &domainPolicy);
|
||||
RecvSetOffline(isOffline);
|
||||
RecvSetConnectivity(isConnected);
|
||||
RecvBidiKeyboardNotify(isLangRTL);
|
||||
|
||||
// Create the CPOW manager as soon as possible.
|
||||
@ -1883,6 +1886,18 @@ ContentChild::RecvSetOffline(const bool& offline)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvSetConnectivity(const bool& connectivity)
|
||||
{
|
||||
nsCOMPtr<nsIIOService> io(do_GetIOService());
|
||||
nsCOMPtr<nsIIOServiceInternal> ioInternal(do_QueryInterface(io));
|
||||
NS_ASSERTION(ioInternal, "IO Service can not be null");
|
||||
|
||||
ioInternal->SetConnectivity(connectivity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ContentChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
|
@ -294,6 +294,7 @@ public:
|
||||
virtual bool DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild*) override;
|
||||
|
||||
virtual bool RecvSetOffline(const bool& offline) override;
|
||||
virtual bool RecvSetConnectivity(const bool& connectivity) override;
|
||||
|
||||
virtual bool RecvSpeakerManagerNotify() override;
|
||||
|
||||
|
@ -405,6 +405,7 @@ bool ContentParent::sNuwaReady = false;
|
||||
#endif
|
||||
|
||||
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
|
||||
#define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
|
||||
|
||||
class MemoryReportRequestParent : public PMemoryReportRequestParent
|
||||
{
|
||||
@ -643,6 +644,7 @@ static const char* sObserverTopics[] = {
|
||||
"xpcom-shutdown",
|
||||
"profile-before-change",
|
||||
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
|
||||
NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC,
|
||||
"child-memory-reporter-request",
|
||||
"memory-pressure",
|
||||
"child-gc-request",
|
||||
@ -2935,13 +2937,16 @@ ContentParent::RecvAddNewProcess(const uint32_t& aPid,
|
||||
|
||||
// Update offline settings.
|
||||
bool isOffline, isLangRTL;
|
||||
bool isConnected;
|
||||
InfallibleTArray<nsString> unusedDictionaries;
|
||||
ClipboardCapabilities clipboardCaps;
|
||||
DomainPolicyClone domainPolicy;
|
||||
|
||||
RecvGetXPCOMProcessAttributes(&isOffline, &isLangRTL, &unusedDictionaries,
|
||||
RecvGetXPCOMProcessAttributes(&isOffline, &isConnected,
|
||||
&isLangRTL, &unusedDictionaries,
|
||||
&clipboardCaps, &domainPolicy);
|
||||
mozilla::unused << content->SendSetOffline(isOffline);
|
||||
mozilla::unused << content->SendSetConnectivity(isConnected);
|
||||
MOZ_ASSERT(!clipboardCaps.supportsSelectionClipboard() &&
|
||||
!clipboardCaps.supportsFindClipboard(),
|
||||
"Unexpected values");
|
||||
@ -3032,6 +3037,17 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
}
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC)) {
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!(IsNuwaReady() && IsNuwaProcess())) {
|
||||
#endif
|
||||
if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// listening for alert notifications
|
||||
@ -3282,6 +3298,7 @@ ContentParent::RecvGetProcessAttributes(ContentParentId* aCpId,
|
||||
|
||||
bool
|
||||
ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline,
|
||||
bool* aIsConnected,
|
||||
bool* aIsLangRTL,
|
||||
InfallibleTArray<nsString>* dictionaries,
|
||||
ClipboardCapabilities* clipboardCaps,
|
||||
@ -3292,6 +3309,9 @@ ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline,
|
||||
DebugOnly<nsresult> rv = io->GetOffline(aIsOffline);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting offline?");
|
||||
|
||||
rv = io->GetConnectivity(aIsConnected);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting connectivity?");
|
||||
|
||||
nsIBidiKeyboard* bidi = nsContentUtils::GetBidiKeyboard();
|
||||
|
||||
*aIsLangRTL = false;
|
||||
|
@ -546,6 +546,7 @@ private:
|
||||
bool* aIsForApp,
|
||||
bool* aIsForBrowser) override;
|
||||
virtual bool RecvGetXPCOMProcessAttributes(bool* aIsOffline,
|
||||
bool* aIsConnected,
|
||||
bool* aIsLangRTL,
|
||||
InfallibleTArray<nsString>* dictionaries,
|
||||
ClipboardCapabilities* clipboardCaps,
|
||||
|
@ -525,6 +525,7 @@ child:
|
||||
RegisterChromeItem(ChromeRegistryItem item);
|
||||
|
||||
async SetOffline(bool offline);
|
||||
async SetConnectivity(bool connectivity);
|
||||
|
||||
async NotifyVisited(URIParams uri);
|
||||
|
||||
@ -669,7 +670,7 @@ parent:
|
||||
sync GetProcessAttributes()
|
||||
returns (ContentParentId cpId, bool isForApp, bool isForBrowser);
|
||||
sync GetXPCOMProcessAttributes()
|
||||
returns (bool isOffline, bool isLangRTL, nsString[] dictionaries,
|
||||
returns (bool isOffline, bool isConnected, bool isLangRTL, nsString[] dictionaries,
|
||||
ClipboardCapabilities clipboardCaps,
|
||||
DomainPolicyClone domainPolicy);
|
||||
|
||||
|
@ -22,7 +22,7 @@ interface nsILoadInfo;
|
||||
* as a convenience to the programmer and in some cases to improve performance
|
||||
* by eliminating intermediate data structures and interfaces.
|
||||
*/
|
||||
[scriptable, uuid(b1c3c61d-2df9-4240-ae16-0355b51a2770)]
|
||||
[scriptable, uuid(4286de5a-b2ea-446f-8f70-e2a461f42694)]
|
||||
interface nsIIOService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -178,6 +178,11 @@ interface nsIIOService : nsISupports
|
||||
*/
|
||||
attribute boolean offline;
|
||||
|
||||
/**
|
||||
* Returns false if there are no interfaces for a network request
|
||||
*/
|
||||
readonly attribute boolean connectivity;
|
||||
|
||||
/**
|
||||
* Set whether network appears to be offline for network connections from
|
||||
* a given appID.
|
||||
@ -269,3 +274,14 @@ interface nsIAppOfflineInfo : nsISupports
|
||||
*/
|
||||
#define NS_IOSERVICE_APP_OFFLINE_STATUS_TOPIC "network:app-offline-status-changed"
|
||||
%}
|
||||
|
||||
[builtinclass, uuid(cd66ffef-3bc3-40de-841a-e2dcbea213a2)]
|
||||
interface nsIIOServiceInternal : nsISupports
|
||||
{
|
||||
/**
|
||||
* This is an internal method that should only be called from ContentChild
|
||||
* in order to pass the connectivity state from the chrome process to the
|
||||
* content process. It throws if called outside the content process.
|
||||
*/
|
||||
void SetConnectivity(in boolean connectivity);
|
||||
};
|
||||
|
@ -158,7 +158,8 @@ NS_IMPL_ISUPPORTS(nsAppOfflineInfo, nsIAppOfflineInfo)
|
||||
nsIOService::nsIOService()
|
||||
: mOffline(true)
|
||||
, mOfflineForProfileChange(false)
|
||||
, mManageOfflineStatus(false)
|
||||
, mManageLinkStatus(false)
|
||||
, mConnectivity(true)
|
||||
, mSettingOffline(false)
|
||||
, mSetOfflineValue(false)
|
||||
, mShutdown(false)
|
||||
@ -284,17 +285,10 @@ nsIOService::InitializeNetworkLinkService()
|
||||
if (mNetworkLinkService) {
|
||||
mNetworkLinkServiceInitialized = true;
|
||||
}
|
||||
else {
|
||||
// We can't really determine if the machine has a usable network connection,
|
||||
// so let's cross our fingers!
|
||||
mManageOfflineStatus = false;
|
||||
}
|
||||
|
||||
if (mManageOfflineStatus)
|
||||
OnNetworkLinkEvent(NS_NETWORK_LINK_DATA_UNKNOWN);
|
||||
else
|
||||
SetOffline(false);
|
||||
|
||||
// After initializing the networkLinkService, query the connectivity state
|
||||
OnNetworkLinkEvent(NS_NETWORK_LINK_DATA_UNKNOWN);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -323,6 +317,7 @@ NS_IMPL_ISUPPORTS(nsIOService,
|
||||
nsINetUtil,
|
||||
nsISpeculativeConnect,
|
||||
nsIObserver,
|
||||
nsIIOServiceInternal,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -955,7 +950,8 @@ nsIOService::SetOffline(bool offline)
|
||||
mProxyService->ReloadPAC();
|
||||
|
||||
// don't care if notification fails
|
||||
if (observerService)
|
||||
// Only send the ONLINE notification if there is connectivity
|
||||
if (observerService && mConnectivity)
|
||||
observerService->NotifyObservers(subject,
|
||||
NS_IOSERVICE_OFFLINE_STATUS_TOPIC,
|
||||
NS_LITERAL_STRING(NS_IOSERVICE_ONLINE).get());
|
||||
@ -981,6 +977,72 @@ nsIOService::SetOffline(bool offline)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::GetConnectivity(bool *aConnectivity)
|
||||
{
|
||||
*aConnectivity = mConnectivity;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::SetConnectivity(bool aConnectivity)
|
||||
{
|
||||
// This should only be called from ContentChild to pass the connectivity
|
||||
// value from the chrome process to the content process.
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return SetConnectivityInternal(aConnectivity);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsIOService::SetConnectivityInternal(bool aConnectivity)
|
||||
{
|
||||
if (mConnectivity == aConnectivity) {
|
||||
// Nothing to do here.
|
||||
return NS_OK;
|
||||
}
|
||||
mConnectivity = aConnectivity;
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (!observerService) {
|
||||
return NS_OK;
|
||||
}
|
||||
// This notification sends the connectivity to the child processes
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
observerService->NotifyObservers(nullptr,
|
||||
NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC, aConnectivity ?
|
||||
MOZ_UTF16("true") :
|
||||
MOZ_UTF16("false"));
|
||||
}
|
||||
|
||||
if (mOffline) {
|
||||
// We don't need to send any notifications if we're offline
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aConnectivity) {
|
||||
// If we were previously offline due to connectivity=false,
|
||||
// send the ONLINE notification
|
||||
observerService->NotifyObservers(
|
||||
static_cast<nsIIOService *>(this),
|
||||
NS_IOSERVICE_OFFLINE_STATUS_TOPIC,
|
||||
NS_LITERAL_STRING(NS_IOSERVICE_ONLINE).get());
|
||||
} else {
|
||||
// If we were previously online and lost connectivity
|
||||
// send the OFFLINE notification
|
||||
const nsLiteralString offlineString(MOZ_UTF16(NS_IOSERVICE_OFFLINE));
|
||||
observerService->NotifyObservers(static_cast<nsIIOService *>(this),
|
||||
NS_IOSERVICE_GOING_OFFLINE_TOPIC,
|
||||
offlineString.get());
|
||||
observerService->NotifyObservers(static_cast<nsIIOService *>(this),
|
||||
NS_IOSERVICE_OFFLINE_STATUS_TOPIC,
|
||||
offlineString.get());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::AllowPort(int32_t inPort, const char *scheme, bool *_retval)
|
||||
@ -1209,11 +1271,8 @@ nsIOService::Observe(nsISupports *subject,
|
||||
} else if (!strcmp(topic, kProfileChangeNetRestoreTopic)) {
|
||||
if (mOfflineForProfileChange) {
|
||||
mOfflineForProfileChange = false;
|
||||
if (!mManageOfflineStatus ||
|
||||
NS_FAILED(OnNetworkLinkEvent(NS_NETWORK_LINK_DATA_UNKNOWN))) {
|
||||
SetOffline(false);
|
||||
}
|
||||
}
|
||||
SetOffline(false);
|
||||
}
|
||||
} else if (!strcmp(topic, kProfileDoChange)) {
|
||||
if (data && NS_LITERAL_STRING("startup").Equals(data)) {
|
||||
// Lazy initialization of network link service (see bug 620472)
|
||||
@ -1221,6 +1280,10 @@ nsIOService::Observe(nsISupports *subject,
|
||||
// Set up the initilization flag regardless the actuall result.
|
||||
// If we fail here, we will fail always on.
|
||||
mNetworkLinkServiceInitialized = true;
|
||||
|
||||
// The browser starts off as offline. We go into online mode after this.
|
||||
SetOffline(false);
|
||||
|
||||
// And now reflect the preference setting
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
GetPrefBranch(getter_AddRefs(prefBranch));
|
||||
@ -1237,9 +1300,7 @@ nsIOService::Observe(nsISupports *subject,
|
||||
// Break circular reference.
|
||||
mProxyService = nullptr;
|
||||
} else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
|
||||
if (!mOfflineForProfileChange && mManageOfflineStatus) {
|
||||
OnNetworkLinkEvent(NS_ConvertUTF16toUTF8(data).get());
|
||||
}
|
||||
OnNetworkLinkEvent(NS_ConvertUTF16toUTF8(data).get());
|
||||
} else if (!strcmp(topic, NS_WIDGET_WAKE_OBSERVER_TOPIC)) {
|
||||
// coming back alive from sleep
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
@ -1383,32 +1444,26 @@ nsIOService::NewSimpleNestedURI(nsIURI* aURI, nsIURI** aResult)
|
||||
NS_IMETHODIMP
|
||||
nsIOService::SetManageOfflineStatus(bool aManage)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
mManageLinkStatus = aManage;
|
||||
|
||||
// SetManageOfflineStatus must throw when we fail to go from non-managed
|
||||
// to managed. Usually because there is no link monitoring service
|
||||
// available. Failure to do this switch is detected by a failure of
|
||||
// OnNetworkLinkEvent(). When there is no network link available during
|
||||
// call to InitializeNetworkLinkService(), application is put to offline
|
||||
// mode. And when we change mMangeOfflineStatus to false on the next line
|
||||
// we get stuck on being offline even though the link becomes later
|
||||
// available.
|
||||
bool wasManaged = mManageOfflineStatus;
|
||||
mManageOfflineStatus = aManage;
|
||||
// When detection is not activated, the default connectivity state is true.
|
||||
if (!mManageLinkStatus) {
|
||||
SetConnectivityInternal(true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
InitializeNetworkLinkService();
|
||||
|
||||
if (mManageOfflineStatus && !wasManaged) {
|
||||
rv = OnNetworkLinkEvent(NS_NETWORK_LINK_DATA_UNKNOWN);
|
||||
if (NS_FAILED(rv))
|
||||
mManageOfflineStatus = false;
|
||||
}
|
||||
return rv;
|
||||
// If the NetworkLinkService is already initialized, it does not call
|
||||
// OnNetworkLinkEvent. This is needed, when mManageLinkStatus goes from
|
||||
// false to true.
|
||||
OnNetworkLinkEvent(NS_NETWORK_LINK_DATA_UNKNOWN);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::GetManageOfflineStatus(bool* aManage) {
|
||||
*aManage = mManageOfflineStatus;
|
||||
nsIOService::GetManageOfflineStatus(bool* aManage)
|
||||
{
|
||||
*aManage = mManageLinkStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1422,7 +1477,7 @@ nsIOService::OnNetworkLinkEvent(const char *data)
|
||||
if (mShutdown)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (!mManageOfflineStatus) {
|
||||
if (!mManageLinkStatus) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1435,21 +1490,19 @@ nsIOService::OnNetworkLinkEvent(const char *data)
|
||||
// dial option is set to always autodial. If so, then we are
|
||||
// always up for the purposes of offline management.
|
||||
if (autodialEnabled) {
|
||||
bool isUp = true;
|
||||
#if defined(XP_WIN)
|
||||
// On Windows, we should first check with the OS to see if
|
||||
// autodial is enabled. If it is enabled then we are allowed
|
||||
// to manage the offline state.
|
||||
if (nsNativeConnectionHelper::IsAutodialEnabled()) {
|
||||
return SetOffline(false);
|
||||
}
|
||||
#else
|
||||
return SetOffline(false);
|
||||
isUp = nsNativeConnectionHelper::IsAutodialEnabled();
|
||||
#endif
|
||||
return SetConnectivityInternal(isUp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isUp;
|
||||
bool isUp = true;
|
||||
if (!strcmp(data, NS_NETWORK_LINK_DATA_CHANGED)) {
|
||||
// CHANGED means UP/DOWN didn't change
|
||||
return NS_OK;
|
||||
@ -1465,7 +1518,7 @@ nsIOService::OnNetworkLinkEvent(const char *data)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return SetOffline(!isUp);
|
||||
return SetConnectivityInternal(isUp);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -26,6 +26,7 @@
|
||||
// Intended internal use only for remoting offline/inline events.
|
||||
// See Bug 552829
|
||||
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
|
||||
#define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
|
||||
|
||||
static const char gScheme[][sizeof("resource")] =
|
||||
{"chrome", "file", "http", "https", "jar", "data", "resource"};
|
||||
@ -49,6 +50,7 @@ class nsIOService final : public nsIIOService2
|
||||
, public nsINetUtil
|
||||
, public nsISpeculativeConnect
|
||||
, public nsSupportsWeakReference
|
||||
, public nsIIOServiceInternal
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
@ -57,6 +59,7 @@ public:
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSINETUTIL
|
||||
NS_DECL_NSISPECULATIVECONNECT
|
||||
NS_DECL_NSIIOSERVICEINTERNAL
|
||||
|
||||
// Gets the singleton instance of the IO Service, creating it as needed
|
||||
// Returns nullptr on out of memory or failure to initialize.
|
||||
@ -86,6 +89,7 @@ private:
|
||||
// - destroy using Release
|
||||
nsIOService();
|
||||
~nsIOService();
|
||||
nsresult SetConnectivityInternal(bool aConnectivity);
|
||||
|
||||
nsresult OnNetworkLinkEvent(const char *data);
|
||||
|
||||
@ -121,7 +125,8 @@ private:
|
||||
private:
|
||||
bool mOffline;
|
||||
bool mOfflineForProfileChange;
|
||||
bool mManageOfflineStatus;
|
||||
bool mManageLinkStatus;
|
||||
bool mConnectivity;
|
||||
|
||||
// Used to handle SetOffline() reentrancy. See the comment in
|
||||
// SetOffline() for more details.
|
||||
|
@ -1963,10 +1963,13 @@ inline bool
|
||||
NS_IsOffline()
|
||||
{
|
||||
bool offline = true;
|
||||
bool connectivity = true;
|
||||
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
||||
if (ios)
|
||||
if (ios) {
|
||||
ios->GetOffline(&offline);
|
||||
return offline;
|
||||
ios->GetConnectivity(&connectivity);
|
||||
}
|
||||
return offline || !connectivity;
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
Loading…
Reference in New Issue
Block a user