// nsIObserver interface NS_IMETHODIMP nsIOService::Observe(nsISupports *subject, const char *topic, const PRUnichar *data) { if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject); if (prefBranch) PrefsChanged(prefBranch, NS_ConvertUTF16toUTF8(data).get()); } else if (!strcmp(topic, kProfileChangeNetTeardownTopic)) { if (!mOffline) { SetOffline(true); mOfflineForProfileChange = true; } } else if (!strcmp(topic, kProfileChangeNetRestoreTopic)) { if (mOfflineForProfileChange) { mOfflineForProfileChange = false; if (!mManageOfflineStatus || NS_FAILED(TrackNetworkLinkStatusForOffline())) { SetOffline(false); } } } else if (!strcmp(topic, kProfileDoChange)) { if (data && NS_LITERAL_STRING("startup").Equals(data)) { // Lazy initialization of network link service (see bug 620472) InitializeNetworkLinkService(); // Set up the initilization flag regardless the actuall result. // If we fail here, we will fail always on. mNetworkLinkServiceInitialized = true; } } else if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { // Remember we passed XPCOM shutdown notification to prevent any // changes of the offline status from now. We must not allow going // online after this point. mShutdown = true; SetOffline(true); // Break circular reference. mProxyService = nullptr; } else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) { if (!mOfflineForProfileChange && mManageOfflineStatus) { TrackNetworkLinkStatusForOffline(); } } return NS_OK; }
NS_IMETHODIMP nsIOService::SetManageOfflineStatus(bool aManage) { nsresult rv = NS_OK; InitializeNetworkLinkService(); bool wasManaged = mManageOfflineStatus; mManageOfflineStatus = aManage; if (mManageOfflineStatus && !wasManaged) { rv = TrackNetworkLinkStatusForOffline(); if (NS_FAILED(rv)) mManageOfflineStatus = false; } return rv; }
nsresult nsIOService::InitializeNetworkLinkService() { NS_TIME_FUNCTION; nsresult rv = NS_OK; if (mNetworkLinkServiceInitialized) return rv; if (!NS_IsMainThread()) { NS_WARNING("Network link service should be created on main thread"); return NS_ERROR_FAILURE; } // go into managed mode if we can, and chrome process if (XRE_GetProcessType() == GeckoProcessType_Default) { mNetworkLinkService = do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID, &rv); } 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) TrackNetworkLinkStatusForOffline(); else SetOffline(false); return rv; }
NS_IMETHODIMP nsIOService::SetManageOfflineStatus(bool aManage) { nsresult rv = NS_OK; // 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 // TrackNetworkLinkStatusForOffline(). 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; InitializeNetworkLinkService(); if (mManageOfflineStatus && !wasManaged) { rv = TrackNetworkLinkStatusForOffline(); if (NS_FAILED(rv)) mManageOfflineStatus = false; } return rv; }