diff options
Diffstat (limited to 'netwerk/system/linux/nsNetworkLinkService.cpp')
-rw-r--r-- | netwerk/system/linux/nsNetworkLinkService.cpp | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/netwerk/system/linux/nsNetworkLinkService.cpp b/netwerk/system/linux/nsNetworkLinkService.cpp new file mode 100644 index 0000000000..363b058eed --- /dev/null +++ b/netwerk/system/linux/nsNetworkLinkService.cpp @@ -0,0 +1,211 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set et sw=2 ts=4: */ +/* 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 "nsIObserverService.h" +#include "nsNetworkLinkService.h" +#include "nsString.h" +#include "mozilla/Logging.h" +#include "nsNetAddr.h" + +#include "mozilla/StaticPrefs_network.h" +#include "mozilla/Services.h" + +using namespace mozilla; + +static LazyLogModule gNotifyAddrLog("nsNetworkLinkService"); +#define LOG(args) MOZ_LOG(gNotifyAddrLog, mozilla::LogLevel::Debug, args) + +NS_IMPL_ISUPPORTS(nsNetworkLinkService, nsINetworkLinkService, nsIObserver) + +nsNetworkLinkService::nsNetworkLinkService() : mStatusIsKnown(false) {} + +NS_IMETHODIMP +nsNetworkLinkService::GetIsLinkUp(bool* aIsUp) { + if (!mNetlinkSvc) { + return NS_ERROR_NOT_AVAILABLE; + } + + mNetlinkSvc->GetIsLinkUp(aIsUp); + return NS_OK; +} + +NS_IMETHODIMP +nsNetworkLinkService::GetLinkStatusKnown(bool* aIsKnown) { + *aIsKnown = mStatusIsKnown; + return NS_OK; +} + +NS_IMETHODIMP +nsNetworkLinkService::GetLinkType(uint32_t* aLinkType) { + NS_ENSURE_ARG_POINTER(aLinkType); + + // XXX This function has not yet been implemented for this platform + *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN; + return NS_OK; +} + +NS_IMETHODIMP +nsNetworkLinkService::GetNetworkID(nsACString& aNetworkID) { + if (!mNetlinkSvc) { + return NS_ERROR_NOT_AVAILABLE; + } + + mNetlinkSvc->GetNetworkID(aNetworkID); + return NS_OK; +} + +NS_IMETHODIMP +nsNetworkLinkService::GetDnsSuffixList(nsTArray<nsCString>& aDnsSuffixList) { + if (!mNetlinkSvc) { + return NS_ERROR_NOT_AVAILABLE; + } + + return mNetlinkSvc->GetDnsSuffixList(aDnsSuffixList); +} + +NS_IMETHODIMP +nsNetworkLinkService::GetResolvers(nsTArray<RefPtr<nsINetAddr>>& aResolvers) { + nsTArray<mozilla::net::NetAddr> addresses; + nsresult rv = GetNativeResolvers(addresses); + if (NS_FAILED(rv)) { + return rv; + } + + for (const auto& addr : addresses) { + aResolvers.AppendElement(MakeRefPtr<nsNetAddr>(&addr)); + } + return NS_OK; +} + +NS_IMETHODIMP +nsNetworkLinkService::GetNativeResolvers( + nsTArray<mozilla::net::NetAddr>& aResolvers) { + if (!mNetlinkSvc) { + return NS_ERROR_NOT_AVAILABLE; + } + return mNetlinkSvc->GetResolvers(aResolvers); +} + +NS_IMETHODIMP +nsNetworkLinkService::GetPlatformDNSIndications( + uint32_t* aPlatformDNSIndications) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNetworkLinkService::Observe(nsISupports* subject, const char* topic, + const char16_t* data) { + if (!strcmp("xpcom-shutdown-threads", topic)) { + Shutdown(); + } + + return NS_OK; +} + +nsresult nsNetworkLinkService::Init() { + nsCOMPtr<nsIObserverService> observerService = + mozilla::services::GetObserverService(); + if (!observerService) { + return NS_ERROR_FAILURE; + } + + nsresult rv; + rv = observerService->AddObserver(this, "xpcom-shutdown-threads", false); + NS_ENSURE_SUCCESS(rv, rv); + + mNetlinkSvc = new mozilla::net::NetlinkService(); + rv = mNetlinkSvc->Init(this); + if (NS_FAILED(rv)) { + mNetlinkSvc = nullptr; + LOG(("Cannot initialize NetlinkService [rv=0x%08" PRIx32 "]", + static_cast<uint32_t>(rv))); + return rv; + } + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +nsresult nsNetworkLinkService::Shutdown() { + // remove xpcom shutdown observer + nsCOMPtr<nsIObserverService> observerService = + mozilla::services::GetObserverService(); + if (observerService) { + observerService->RemoveObserver(this, "xpcom-shutdown-threads"); + } + + if (mNetlinkSvc) { + mNetlinkSvc->Shutdown(); + mNetlinkSvc = nullptr; + } + + return NS_OK; +} + +void nsNetworkLinkService::OnNetworkChanged() { + if (StaticPrefs::network_notify_changed()) { + RefPtr<nsNetworkLinkService> self = this; + NS_DispatchToMainThread(NS_NewRunnableFunction( + "nsNetworkLinkService::OnNetworkChanged", [self]() { + self->NotifyObservers(NS_NETWORK_LINK_TOPIC, + NS_NETWORK_LINK_DATA_CHANGED); + })); + } +} + +void nsNetworkLinkService::OnNetworkIDChanged() { + RefPtr<nsNetworkLinkService> self = this; + NS_DispatchToMainThread(NS_NewRunnableFunction( + "nsNetworkLinkService::OnNetworkIDChanged", [self]() { + self->NotifyObservers(NS_NETWORK_ID_CHANGED_TOPIC, nullptr); + })); +} + +void nsNetworkLinkService::OnLinkUp() { + RefPtr<nsNetworkLinkService> self = this; + NS_DispatchToMainThread( + NS_NewRunnableFunction("nsNetworkLinkService::OnLinkUp", [self]() { + self->NotifyObservers(NS_NETWORK_LINK_TOPIC, NS_NETWORK_LINK_DATA_UP); + })); +} + +void nsNetworkLinkService::OnLinkDown() { + RefPtr<nsNetworkLinkService> self = this; + NS_DispatchToMainThread( + NS_NewRunnableFunction("nsNetworkLinkService::OnLinkDown", [self]() { + self->NotifyObservers(NS_NETWORK_LINK_TOPIC, NS_NETWORK_LINK_DATA_DOWN); + })); +} + +void nsNetworkLinkService::OnLinkStatusKnown() { mStatusIsKnown = true; } + +void nsNetworkLinkService::OnDnsSuffixListUpdated() { + RefPtr<nsNetworkLinkService> self = this; + NS_DispatchToMainThread(NS_NewRunnableFunction( + "nsNetworkLinkService::OnDnsSuffixListUpdated", [self]() { + self->NotifyObservers(NS_DNS_SUFFIX_LIST_UPDATED_TOPIC, nullptr); + })); +} + +/* Sends the given event. Assumes aTopic/aData never goes out of scope (static + * strings are ideal). + */ +void nsNetworkLinkService::NotifyObservers(const char* aTopic, + const char* aData) { + MOZ_ASSERT(NS_IsMainThread()); + + LOG(("nsNetworkLinkService::NotifyObservers: topic:%s data:%s\n", aTopic, + aData ? aData : "")); + + nsCOMPtr<nsIObserverService> observerService = + mozilla::services::GetObserverService(); + + if (observerService) { + observerService->NotifyObservers( + static_cast<nsINetworkLinkService*>(this), aTopic, + aData ? NS_ConvertASCIItoUTF16(aData).get() : nullptr); + } +} |