nsWifiMonitor.h (3559B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef __nsWifiMonitor__ 6 #define __nsWifiMonitor__ 7 8 #include "nsIWifiMonitor.h" 9 #include "nsCOMPtr.h" 10 #include "nsProxyRelease.h" 11 #include "nsIThread.h" 12 #include "nsIRunnable.h" 13 #include "nsCOMArray.h" 14 #include "nsIWifiListener.h" 15 #include "mozilla/Atomics.h" 16 #include "mozilla/ReentrantMonitor.h" 17 #include "mozilla/Logging.h" 18 #include "nsIObserver.h" 19 #include "nsTArray.h" 20 #include "mozilla/Monitor.h" 21 #include "WifiScanner.h" 22 #include "nsTHashMap.h" 23 24 namespace mozilla { 25 class TestWifiMonitor; 26 } 27 28 extern mozilla::LazyLogModule gWifiMonitorLog; 29 30 class nsWifiAccessPoint; 31 32 // Period between scans when on mobile network. 33 #define WIFI_SCAN_INTERVAL_MS_PREF "network.wifi.scanning_period" 34 35 #ifdef XP_MACOSX 36 // Use a larger stack size for the wifi monitor thread of macOS, to 37 // accommodate Core WLAN making large stack allocations. 38 # define kMacOSWifiMonitorStackSize (512 * 1024) 39 #endif 40 41 struct WifiListenerData { 42 bool mShouldPoll; 43 bool mHasSentData = false; 44 45 explicit WifiListenerData(bool aShouldPoll = false) 46 : mShouldPoll(aShouldPoll) {} 47 }; 48 49 class nsWifiMonitor final : public nsIWifiMonitor, public nsIObserver { 50 public: 51 NS_DECL_THREADSAFE_ISUPPORTS 52 NS_DECL_NSIWIFIMONITOR 53 NS_DECL_NSIOBSERVER 54 55 explicit nsWifiMonitor( 56 mozilla::UniquePtr<mozilla::WifiScanner>&& aScanner = nullptr); 57 58 private: 59 friend class mozilla::TestWifiMonitor; 60 61 ~nsWifiMonitor(); 62 63 void EnsureWifiScanner(); 64 65 nsresult DispatchScanToBackgroundThread(uint64_t aPollingId = 0, 66 uint32_t aWaitMs = 0); 67 68 void Scan(uint64_t aPollingId); 69 nsresult DoScan(); 70 71 nsresult CallWifiListeners( 72 const nsTArray<RefPtr<nsIWifiAccessPoint>>& aAccessPoints, 73 bool aAccessPointsChanged); 74 75 nsresult PassErrorToWifiListeners(nsresult rv); 76 77 void Close(); 78 79 bool IsBackgroundThread(); 80 81 bool ShouldPoll() { 82 MOZ_ASSERT(!IsBackgroundThread()); 83 return (mShouldPollForCurrentNetwork && !mListeners.IsEmpty()) || 84 mNumPollingListeners > 0; 85 }; 86 87 template <typename CallbackFn> 88 nsresult NotifyListeners(CallbackFn&& aCallback); 89 90 #ifdef ENABLE_TESTS 91 // Test-only function that confirms we "should" be polling. May be wrong 92 // if somehow the polling tasks are not set to run on the background 93 // thread. 94 bool IsPolling() { return mThread && mPollingId; } 95 #endif 96 97 // Main thread only. 98 nsCOMPtr<nsIThread> mThread; 99 100 // Main thread only. 101 nsTHashMap<RefPtr<nsIWifiListener>, WifiListenerData> mListeners; 102 103 // Background thread only. 104 mozilla::UniquePtr<mozilla::WifiScanner> mWifiScanner; 105 106 // Background thread only. Sorted. 107 nsTArray<RefPtr<nsIWifiAccessPoint>> mLastAccessPoints; 108 109 // Wifi-scanning requests may poll, meaning they will run repeatedly on 110 // a scheduled time period. If this value is 0 then polling is not running, 111 // otherwise, it indicates the "ID" of the polling that is running. if some 112 // other polling (with different ID) is running, it will stop, not iterate. 113 mozilla::Atomic<uint64_t> mPollingId; 114 115 // Number of current listeners that requested that the wifi scan poll 116 // periodically. 117 // Main thread only. 118 uint32_t mNumPollingListeners = 0; 119 120 // True if the current network type is one that requires polling 121 // (i.e. a "mobile" network type). 122 // Main thread only. 123 bool mShouldPollForCurrentNetwork = false; 124 }; 125 126 #endif