1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set et sw=2 ts=4: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsIObserverService.h"
8 #include "nsNetworkLinkService.h"
10 #include "mozilla/Logging.h"
11 #include "mozilla/IntegerPrintfMacros.h"
12 #include "nsNetAddr.h"
14 #include "mozilla/StaticPrefs_network.h"
15 #include "mozilla/Services.h"
17 using namespace mozilla
;
19 static LazyLogModule
gNotifyAddrLog("nsNetworkLinkService");
20 #define LOG(args) MOZ_LOG(gNotifyAddrLog, mozilla::LogLevel::Debug, args)
22 NS_IMPL_ISUPPORTS(nsNetworkLinkService
, nsINetworkLinkService
, nsIObserver
)
24 nsNetworkLinkService::nsNetworkLinkService() : mStatusIsKnown(false) {}
27 nsNetworkLinkService::GetIsLinkUp(bool* aIsUp
) {
29 return NS_ERROR_NOT_AVAILABLE
;
32 mNetlinkSvc
->GetIsLinkUp(aIsUp
);
37 nsNetworkLinkService::GetLinkStatusKnown(bool* aIsKnown
) {
38 *aIsKnown
= mStatusIsKnown
;
43 nsNetworkLinkService::GetLinkType(uint32_t* aLinkType
) {
44 NS_ENSURE_ARG_POINTER(aLinkType
);
46 // XXX This function has not yet been implemented for this platform
47 *aLinkType
= nsINetworkLinkService::LINK_TYPE_UNKNOWN
;
52 nsNetworkLinkService::GetNetworkID(nsACString
& aNetworkID
) {
54 return NS_ERROR_NOT_AVAILABLE
;
57 mNetlinkSvc
->GetNetworkID(aNetworkID
);
62 nsNetworkLinkService::GetDnsSuffixList(nsTArray
<nsCString
>& aDnsSuffixList
) {
64 return NS_ERROR_NOT_AVAILABLE
;
67 return mNetlinkSvc
->GetDnsSuffixList(aDnsSuffixList
);
71 nsNetworkLinkService::GetResolvers(nsTArray
<RefPtr
<nsINetAddr
>>& aResolvers
) {
72 nsTArray
<mozilla::net::NetAddr
> addresses
;
73 nsresult rv
= GetNativeResolvers(addresses
);
78 for (const auto& addr
: addresses
) {
79 aResolvers
.AppendElement(MakeRefPtr
<nsNetAddr
>(&addr
));
85 nsNetworkLinkService::GetNativeResolvers(
86 nsTArray
<mozilla::net::NetAddr
>& aResolvers
) {
88 return NS_ERROR_NOT_AVAILABLE
;
90 return mNetlinkSvc
->GetResolvers(aResolvers
);
94 nsNetworkLinkService::GetPlatformDNSIndications(
95 uint32_t* aPlatformDNSIndications
) {
96 return NS_ERROR_NOT_IMPLEMENTED
;
100 nsNetworkLinkService::Observe(nsISupports
* subject
, const char* topic
,
101 const char16_t
* data
) {
102 if (!strcmp("xpcom-shutdown-threads", topic
)) {
109 nsresult
nsNetworkLinkService::Init() {
110 nsCOMPtr
<nsIObserverService
> observerService
=
111 mozilla::services::GetObserverService();
112 if (!observerService
) {
113 return NS_ERROR_FAILURE
;
117 rv
= observerService
->AddObserver(this, "xpcom-shutdown-threads", false);
118 NS_ENSURE_SUCCESS(rv
, rv
);
120 mNetlinkSvc
= new mozilla::net::NetlinkService();
121 rv
= mNetlinkSvc
->Init(this);
123 mNetlinkSvc
= nullptr;
124 LOG(("Cannot initialize NetlinkService [rv=0x%08" PRIx32
"]",
125 static_cast<uint32_t>(rv
)));
128 NS_ENSURE_SUCCESS(rv
, rv
);
133 nsresult
nsNetworkLinkService::Shutdown() {
134 // remove xpcom shutdown observer
135 nsCOMPtr
<nsIObserverService
> observerService
=
136 mozilla::services::GetObserverService();
137 if (observerService
) {
138 observerService
->RemoveObserver(this, "xpcom-shutdown-threads");
142 mNetlinkSvc
->Shutdown();
143 mNetlinkSvc
= nullptr;
149 void nsNetworkLinkService::OnNetworkChanged() {
150 if (StaticPrefs::network_notify_changed()) {
151 RefPtr
<nsNetworkLinkService
> self
= this;
152 NS_DispatchToMainThread(NS_NewRunnableFunction(
153 "nsNetworkLinkService::OnNetworkChanged", [self
]() {
154 self
->NotifyObservers(NS_NETWORK_LINK_TOPIC
,
155 NS_NETWORK_LINK_DATA_CHANGED
);
160 void nsNetworkLinkService::OnNetworkIDChanged() {
161 RefPtr
<nsNetworkLinkService
> self
= this;
162 NS_DispatchToMainThread(NS_NewRunnableFunction(
163 "nsNetworkLinkService::OnNetworkIDChanged", [self
]() {
164 self
->NotifyObservers(NS_NETWORK_ID_CHANGED_TOPIC
, nullptr);
168 void nsNetworkLinkService::OnLinkUp() {
169 RefPtr
<nsNetworkLinkService
> self
= this;
170 NS_DispatchToMainThread(
171 NS_NewRunnableFunction("nsNetworkLinkService::OnLinkUp", [self
]() {
172 self
->NotifyObservers(NS_NETWORK_LINK_TOPIC
, NS_NETWORK_LINK_DATA_UP
);
176 void nsNetworkLinkService::OnLinkDown() {
177 RefPtr
<nsNetworkLinkService
> self
= this;
178 NS_DispatchToMainThread(
179 NS_NewRunnableFunction("nsNetworkLinkService::OnLinkDown", [self
]() {
180 self
->NotifyObservers(NS_NETWORK_LINK_TOPIC
, NS_NETWORK_LINK_DATA_DOWN
);
184 void nsNetworkLinkService::OnLinkStatusKnown() { mStatusIsKnown
= true; }
186 void nsNetworkLinkService::OnDnsSuffixListUpdated() {
187 RefPtr
<nsNetworkLinkService
> self
= this;
188 NS_DispatchToMainThread(NS_NewRunnableFunction(
189 "nsNetworkLinkService::OnDnsSuffixListUpdated", [self
]() {
190 self
->NotifyObservers(NS_DNS_SUFFIX_LIST_UPDATED_TOPIC
, nullptr);
194 /* Sends the given event. Assumes aTopic/aData never goes out of scope (static
195 * strings are ideal).
197 void nsNetworkLinkService::NotifyObservers(const char* aTopic
,
199 MOZ_ASSERT(NS_IsMainThread());
201 LOG(("nsNetworkLinkService::NotifyObservers: topic:%s data:%s\n", aTopic
,
202 aData
? aData
: ""));
204 nsCOMPtr
<nsIObserverService
> observerService
=
205 mozilla::services::GetObserverService();
207 if (observerService
) {
208 observerService
->NotifyObservers(
209 static_cast<nsINetworkLinkService
*>(this), aTopic
,
210 aData
? NS_ConvertASCIItoUTF16(aData
).get() : nullptr);
215 bool nsINetworkLinkService::HasNonLocalIPv6Address() {
216 return mozilla::net::NetlinkService::HasNonLocalIPv6Address();