|
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 #include "nsCOMPtr.h" |
|
6 #include "nsComponentManagerUtils.h" |
|
7 #include "nsServiceManagerUtils.h" |
|
8 #include "nsThreadUtils.h" |
|
9 #include "nsXPCOM.h" |
|
10 #include "nsXPCOMCID.h" |
|
11 #include "nsIObserver.h" |
|
12 #include "nsIObserverService.h" |
|
13 #include "nsWifiMonitor.h" |
|
14 #include "nsWifiAccessPoint.h" |
|
15 |
|
16 #include "nsServiceManagerUtils.h" |
|
17 #include "nsComponentManagerUtils.h" |
|
18 #include "mozilla/Services.h" |
|
19 |
|
20 #include "nsIInterfaceRequestor.h" |
|
21 #include "nsIInterfaceRequestorUtils.h" |
|
22 |
|
23 using namespace mozilla; |
|
24 |
|
25 #if defined(PR_LOGGING) |
|
26 PRLogModuleInfo *gWifiMonitorLog; |
|
27 #endif |
|
28 |
|
29 NS_IMPL_ISUPPORTS(nsWifiMonitor, |
|
30 nsIWifiMonitor, |
|
31 nsIObserver, |
|
32 nsIWifiScanResultsReady) |
|
33 |
|
34 nsWifiMonitor::nsWifiMonitor() |
|
35 { |
|
36 #if defined(PR_LOGGING) |
|
37 gWifiMonitorLog = PR_NewLogModule("WifiMonitor"); |
|
38 #endif |
|
39 |
|
40 nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService(); |
|
41 if (obsSvc) { |
|
42 obsSvc->AddObserver(this, "xpcom-shutdown", false); |
|
43 } |
|
44 LOG(("@@@@@ wifimonitor created\n")); |
|
45 } |
|
46 |
|
47 nsWifiMonitor::~nsWifiMonitor() |
|
48 { |
|
49 } |
|
50 |
|
51 NS_IMETHODIMP |
|
52 nsWifiMonitor::StartWatching(nsIWifiListener *aListener) |
|
53 { |
|
54 LOG(("@@@@@ nsWifiMonitor::StartWatching\n")); |
|
55 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
56 if (!aListener) { |
|
57 return NS_ERROR_NULL_POINTER; |
|
58 } |
|
59 |
|
60 mListeners.AppendElement(nsWifiListener(new nsMainThreadPtrHolder<nsIWifiListener>(aListener))); |
|
61 |
|
62 if (!mTimer) { |
|
63 mTimer = do_CreateInstance("@mozilla.org/timer;1"); |
|
64 mTimer->Init(this, 5000, nsITimer::TYPE_REPEATING_SLACK); |
|
65 } |
|
66 return NS_OK; |
|
67 } |
|
68 |
|
69 NS_IMETHODIMP |
|
70 nsWifiMonitor::StopWatching(nsIWifiListener *aListener) |
|
71 { |
|
72 LOG(("@@@@@ nsWifiMonitor::StopWatching\n")); |
|
73 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
74 if (!aListener) { |
|
75 return NS_ERROR_NULL_POINTER; |
|
76 } |
|
77 |
|
78 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
79 if (mListeners[i].mListener == aListener) { |
|
80 mListeners.RemoveElementAt(i); |
|
81 break; |
|
82 } |
|
83 } |
|
84 |
|
85 if (mListeners.Length() == 0) { |
|
86 ClearTimer(); |
|
87 } |
|
88 return NS_OK; |
|
89 } |
|
90 |
|
91 NS_IMETHODIMP |
|
92 nsWifiMonitor::Observe(nsISupports *subject, const char *topic, |
|
93 const char16_t *data) |
|
94 { |
|
95 if (!strcmp(topic, "timer-callback")) { |
|
96 LOG(("timer callback\n")); |
|
97 |
|
98 nsCOMPtr<nsIInterfaceRequestor> ir = do_GetService("@mozilla.org/telephony/system-worker-manager;1"); |
|
99 nsCOMPtr<nsIWifi> wifi = do_GetInterface(ir); |
|
100 if (!wifi) { |
|
101 return NS_ERROR_UNEXPECTED; |
|
102 } |
|
103 |
|
104 wifi->GetWifiScanResults(this); |
|
105 return NS_OK; |
|
106 } |
|
107 |
|
108 if (!strcmp(topic, "xpcom-shutdown")) { |
|
109 LOG(("Shutting down\n")); |
|
110 ClearTimer(); |
|
111 return NS_OK; |
|
112 } |
|
113 |
|
114 return NS_ERROR_UNEXPECTED; |
|
115 } |
|
116 |
|
117 NS_IMETHODIMP |
|
118 nsWifiMonitor::Onready(uint32_t count, nsIWifiScanResult **results) |
|
119 { |
|
120 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
121 LOG(("@@@@@ About to send data to the wifi listeners\n")); |
|
122 |
|
123 nsCOMArray<nsWifiAccessPoint> accessPoints; |
|
124 |
|
125 for (uint32_t i = 0; i < count; i++) { |
|
126 nsRefPtr<nsWifiAccessPoint> ap = new nsWifiAccessPoint(); |
|
127 |
|
128 nsString temp; |
|
129 results[i]->GetBssid(temp); |
|
130 // 00:00:00:00:00:00 --> 00-00-00-00-00-00 |
|
131 for (int32_t x=0; x<6; x++) { |
|
132 temp.ReplaceSubstring(NS_LITERAL_STRING(":"), NS_LITERAL_STRING("-")); // would it be too much to ask for a ReplaceAll()? |
|
133 } |
|
134 |
|
135 nsCString mac; |
|
136 mac.AssignWithConversion(temp); |
|
137 |
|
138 results[i]->GetSsid(temp); |
|
139 |
|
140 nsCString ssid; |
|
141 ssid.AssignWithConversion(temp); |
|
142 |
|
143 uint32_t signal; |
|
144 results[i]->GetSignalStrength(&signal); |
|
145 |
|
146 ap->setSignal(signal); |
|
147 ap->setMacRaw(mac.get()); |
|
148 ap->setSSIDRaw(ssid.get(), ssid.Length()); |
|
149 |
|
150 accessPoints.AppendObject(ap); |
|
151 } |
|
152 |
|
153 bool accessPointsChanged = !AccessPointsEqual(accessPoints, mLastAccessPoints); |
|
154 ReplaceArray(mLastAccessPoints, accessPoints); |
|
155 |
|
156 nsTArray<nsIWifiAccessPoint*> ac; |
|
157 uint32_t resultCount = mLastAccessPoints.Count(); |
|
158 for (uint32_t i = 0; i < resultCount; i++) { |
|
159 ac.AppendElement(mLastAccessPoints[i]); |
|
160 } |
|
161 |
|
162 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
163 if (!mListeners[i].mHasSentData || accessPointsChanged) { |
|
164 mListeners[i].mHasSentData = true; |
|
165 mListeners[i].mListener->OnChange(ac.Elements(), ac.Length()); |
|
166 } |
|
167 } |
|
168 return NS_OK; |
|
169 } |
|
170 |
|
171 NS_IMETHODIMP |
|
172 nsWifiMonitor::Onfailure() |
|
173 { |
|
174 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); |
|
175 LOG(("@@@@@ About to send error to the wifi listeners\n")); |
|
176 for (uint32_t i = 0; i < mListeners.Length(); i++) { |
|
177 mListeners[i].mListener->OnError(NS_ERROR_UNEXPECTED); |
|
178 } |
|
179 |
|
180 ClearTimer(); |
|
181 return NS_OK; |
|
182 } |