/* 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/. */
// Any non-zero value is valid and we don't care about overflow beyond // that we never want the index to be zero. if (sNextPollingIndex == 0) {
++sNextPollingIndex;
} return sNextPollingIndex;
}
// Should we poll wifi or just check it when our network changes? // We poll when we are on a network where the wifi environment // could reasonably be expected to change much -- so, on mobile. staticbool ShouldPollForNetworkType(const char16_t* aLinkType) { auto linkTypeU8 = NS_ConvertUTF16toUTF8(aLinkType); return linkTypeU8 == NS_NETWORK_LINK_TYPE_WIMAX ||
linkTypeU8 == NS_NETWORK_LINK_TYPE_MOBILE ||
linkTypeU8 == NS_NETWORK_LINK_TYPE_UNKNOWN;
}
if (!strcmp(topic, "xpcom-shutdown")) { // Make sure any wifi-polling stops.
LOG(("nsWifiMonitor received shutdown"));
Close();
} elseif (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) { // Network connectivity has either been gained, lost, or changed (e.g. // by changing Wifi network). Issue an immediate one-time scan. // If we were polling, keep polling.
LOG(("nsWifiMonitor %p | mPollingId %" PRIu64 " | received: " NS_NETWORK_LINK_TOPIC " with status %s", this, static_cast<uint64_t>(mPollingId),
NS_ConvertUTF16toUTF8(data).get()));
DispatchScanToBackgroundThread(0);
} elseif (!strcmp(topic, NS_NETWORK_LINK_TYPE_TOPIC)) { // Network type has changed (e.g. from wifi to mobile). When on some // network types, we poll wifi. This event does not indicate that a // new scan would be beneficial right now, so we only issue one if // we need to begin polling. // Use IDs to make sure only one task is polling at a time.
LOG(("nsWifiMonitor %p | mPollingId %" PRIu64 " | received: " NS_NETWORK_LINK_TYPE_TOPIC " with status %s", this, static_cast<uint64_t>(mPollingId),
NS_ConvertUTF16toUTF8(data).get()));
if (!mListeners.InsertOrUpdate(aListener, WifiListenerData(aForcePolling),
mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY;
}
// Run a new scan to update the new listener. If we were polling then // stop that polling and start a new polling interval now.
MOZ_ASSERT(mPollingId == 0 || ShouldPoll()); if (aForcePolling) {
++mNumPollingListeners;
} if (ShouldPoll()) {
mPollingId = NextPollingIndex();
} return DispatchScanToBackgroundThread(mPollingId);
}
#ifndef XP_MACOSX
nsIThreadManager::ThreadCreationOptions options = {}; #else // If this ASSERT fails, we've increased our default stack size and // may no longer need to special-case the stack size on macOS.
static_assert(kMacOSWifiMonitorStackSize >
nsIThreadManager::DEFAULT_STACK_SIZE);
// Mac needs a stack size larger than the default for CoreWLAN.
nsIThreadManager::ThreadCreationOptions options = {
.stackSize = kMacOSWifiMonitorStackSize}; #endif
// If we are using a stale polling ID then stop. If this request to // Scan is not for polling (aPollingId is 0) then always allow it. if (aPollingId && mPollingId != aPollingId) {
LOG(("nsWifiMonitor::Scan stopping polling")); return;
}
// If we are polling then we re-issue Scan after a delay. // We re-check the polling IDs since mPollingId may have changed. if (aPollingId && aPollingId == mPollingId) {
uint32_t periodMs = StaticPrefs::network_wifi_scanning_period(); if (periodMs) {
LOG(("nsWifiMonitor::Scan requesting future scan with id: %" PRIu64 " | periodMs: %u",
aPollingId, periodMs));
DispatchScanToBackgroundThread(aPollingId, periodMs);
} else { // Polling for wifi-scans is disabled.
mPollingId = 0;
}
}
// Sorted compare to see if access point list has changed.
LOG(("Checking for new access points")); bool accessPointsChanged =
accessPoints.Length() != mLastAccessPoints.Length(); if (!accessPointsChanged) { auto itAp = accessPoints.begin(); auto itLastAp = mLastAccessPoints.begin(); while (itAp != accessPoints.end()) { constauto& a = static_cast<const nsWifiAccessPoint&>(**itAp); constauto& b = static_cast<const nsWifiAccessPoint&>(**itLastAp); if (a != b) {
accessPointsChanged = true; break;
}
++itAp;
++itLastAp;
}
}
mLastAccessPoints = std::move(accessPoints);
LOG(("Sending Wifi access points to the main thread")); auto* mainThread = GetMainThreadSerialEventTarget(); if (!mainThread) { return NS_ERROR_UNEXPECTED;
}
template <typename CallbackFn>
nsresult nsWifiMonitor::NotifyListeners(CallbackFn&& aCallback) { // Listeners may (un)register other listeners while we iterate, // so we iterate over a copy and re-check membership as we go. // Iteration order is not important. auto listenersCopy(mListeners.Clone()); for (auto iter = listenersCopy.begin(); iter != listenersCopy.end(); ++iter) { auto maybeIter = mListeners.MaybeGet(iter->GetKey()); if (maybeIter) {
aCallback(iter->GetKey(), *maybeIter);
}
} return NS_OK;
}
nsresult nsWifiMonitor::PassErrorToWifiListeners(nsresult rv) {
MOZ_ASSERT(NS_IsMainThread());
LOG(("About to send error to the wifi listeners")); return NotifyListeners([&](nsIWifiListener* aListener, WifiListenerData&) {
aListener->OnError(rv);
});
}
bool nsWifiMonitor::GetHasWifiAdapter() { #ifdef XP_WIN
EnsureWifiScanner();
MOZ_ASSERT(mWifiScanner); returnstatic_cast<WifiScannerImpl*>(mWifiScanner.get())->HasWifiAdapter(); #else
MOZ_ASSERT_UNREACHABLE( "nsWifiMonitor::HasWifiAdapter is not available on this platform"); returnfalse; #endif
}
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.