dom/system/gonk/SystemWorkerManager.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:cedfa9b637b1
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* Copyright 2012 Mozilla Foundation and Mozilla contributors
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "SystemWorkerManager.h"
19
20 #include "nsINetworkService.h"
21 #include "nsIWifi.h"
22 #include "nsIWorkerHolder.h"
23 #include "nsIXPConnect.h"
24
25 #include "jsfriendapi.h"
26 #include "mozilla/dom/workers/Workers.h"
27 #include "AutoMounter.h"
28 #include "TimeZoneSettingObserver.h"
29 #include "AudioManager.h"
30 #ifdef MOZ_B2G_RIL
31 #include "mozilla/ipc/Ril.h"
32 #endif
33 #ifdef MOZ_NFC
34 #include "mozilla/ipc/Nfc.h"
35 #endif
36 #include "mozilla/ipc/KeyStore.h"
37 #include "nsIObserverService.h"
38 #include "nsCxPusher.h"
39 #include "nsServiceManagerUtils.h"
40 #include "nsThreadUtils.h"
41 #include "nsRadioInterfaceLayer.h"
42 #include "WifiWorker.h"
43 #include "mozilla/Services.h"
44
45 USING_WORKERS_NAMESPACE
46
47 using namespace mozilla::dom::gonk;
48 using namespace mozilla::ipc;
49 using namespace mozilla::system;
50
51 namespace {
52
53 NS_DEFINE_CID(kWifiWorkerCID, NS_WIFIWORKER_CID);
54
55 // Doesn't carry a reference, we're owned by services.
56 SystemWorkerManager *gInstance = nullptr;
57
58 } // anonymous namespace
59
60 SystemWorkerManager::SystemWorkerManager()
61 : mShutdown(false)
62 {
63 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
64 NS_ASSERTION(!gInstance, "There should only be one instance!");
65 }
66
67 SystemWorkerManager::~SystemWorkerManager()
68 {
69 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
70 NS_ASSERTION(!gInstance || gInstance == this,
71 "There should only be one instance!");
72 gInstance = nullptr;
73 }
74
75 nsresult
76 SystemWorkerManager::Init()
77 {
78 if (XRE_GetProcessType() != GeckoProcessType_Default) {
79 return NS_ERROR_NOT_AVAILABLE;
80 }
81
82 NS_ASSERTION(NS_IsMainThread(), "We can only initialize on the main thread");
83 NS_ASSERTION(!mShutdown, "Already shutdown!");
84
85 mozilla::AutoSafeJSContext cx;
86
87 nsresult rv = InitWifi(cx);
88 if (NS_FAILED(rv)) {
89 NS_WARNING("Failed to initialize WiFi Networking!");
90 return rv;
91 }
92
93 InitKeyStore(cx);
94
95 InitAutoMounter();
96 InitializeTimeZoneSettingObserver();
97 nsCOMPtr<nsIAudioManager> audioManager =
98 do_GetService(NS_AUDIOMANAGER_CONTRACTID);
99
100 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
101 if (!obs) {
102 NS_WARNING("Failed to get observer service!");
103 return NS_ERROR_FAILURE;
104 }
105
106 rv = obs->AddObserver(this, WORKERS_SHUTDOWN_TOPIC, false);
107 if (NS_FAILED(rv)) {
108 NS_WARNING("Failed to initialize worker shutdown event!");
109 return rv;
110 }
111
112 return NS_OK;
113 }
114
115 void
116 SystemWorkerManager::Shutdown()
117 {
118 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
119
120 mShutdown = true;
121
122 ShutdownAutoMounter();
123
124 #ifdef MOZ_B2G_RIL
125 RilConsumer::Shutdown();
126 #endif
127
128 #ifdef MOZ_NFC
129 NfcConsumer::Shutdown();
130 #endif
131
132 nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
133 if (wifi) {
134 wifi->Shutdown();
135 wifi = nullptr;
136 }
137 mWifiWorker = nullptr;
138
139 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
140 if (obs) {
141 obs->RemoveObserver(this, WORKERS_SHUTDOWN_TOPIC);
142 }
143 }
144
145 // static
146 already_AddRefed<SystemWorkerManager>
147 SystemWorkerManager::FactoryCreate()
148 {
149 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
150
151 nsRefPtr<SystemWorkerManager> instance(gInstance);
152
153 if (!instance) {
154 instance = new SystemWorkerManager();
155 if (NS_FAILED(instance->Init())) {
156 instance->Shutdown();
157 return nullptr;
158 }
159
160 gInstance = instance;
161 }
162
163 return instance.forget();
164 }
165
166 // static
167 nsIInterfaceRequestor*
168 SystemWorkerManager::GetInterfaceRequestor()
169 {
170 return gInstance;
171 }
172
173 NS_IMETHODIMP
174 SystemWorkerManager::GetInterface(const nsIID &aIID, void **aResult)
175 {
176 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
177
178 if (aIID.Equals(NS_GET_IID(nsIWifi))) {
179 return CallQueryInterface(mWifiWorker,
180 reinterpret_cast<nsIWifi**>(aResult));
181 }
182
183 NS_WARNING("Got nothing for the requested IID!");
184 return NS_ERROR_NO_INTERFACE;
185 }
186
187 nsresult
188 SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
189 JS::Handle<JS::Value> aWorker,
190 JSContext *aCx)
191 {
192 #ifndef MOZ_B2G_RIL
193 return NS_ERROR_NOT_IMPLEMENTED;
194 #else
195 NS_ENSURE_TRUE(aWorker.isObject(), NS_ERROR_UNEXPECTED);
196
197 JSAutoCompartment ac(aCx, &aWorker.toObject());
198
199 WorkerCrossThreadDispatcher *wctd =
200 GetWorkerCrossThreadDispatcher(aCx, aWorker);
201 if (!wctd) {
202 NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for ril");
203 return NS_ERROR_FAILURE;
204 }
205
206 return RilConsumer::Register(aClientId, wctd);
207 #endif // MOZ_B2G_RIL
208 }
209
210 nsresult
211 SystemWorkerManager::RegisterNfcWorker(JS::Handle<JS::Value> aWorker,
212 JSContext* aCx)
213 {
214 #ifndef MOZ_NFC
215 return NS_ERROR_NOT_IMPLEMENTED;
216 #else
217 NS_ENSURE_TRUE(aWorker.isObject(), NS_ERROR_UNEXPECTED);
218
219 JSAutoCompartment ac(aCx, &aWorker.toObject());
220
221 WorkerCrossThreadDispatcher* wctd =
222 GetWorkerCrossThreadDispatcher(aCx, aWorker);
223 if (!wctd) {
224 NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for nfc");
225 return NS_ERROR_FAILURE;
226 }
227
228 return NfcConsumer::Register(wctd);
229 #endif // MOZ_NFC
230 }
231
232 nsresult
233 SystemWorkerManager::InitWifi(JSContext *cx)
234 {
235 nsCOMPtr<nsIWorkerHolder> worker = do_CreateInstance(kWifiWorkerCID);
236 NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
237
238 mWifiWorker = worker;
239 return NS_OK;
240 }
241
242 nsresult
243 SystemWorkerManager::InitKeyStore(JSContext *cx)
244 {
245 mKeyStore = new KeyStore();
246 return NS_OK;
247 }
248
249 NS_IMPL_ISUPPORTS(SystemWorkerManager,
250 nsIObserver,
251 nsIInterfaceRequestor,
252 nsISystemWorkerManager)
253
254 NS_IMETHODIMP
255 SystemWorkerManager::Observe(nsISupports *aSubject, const char *aTopic,
256 const char16_t *aData)
257 {
258 if (!strcmp(aTopic, WORKERS_SHUTDOWN_TOPIC)) {
259 Shutdown();
260 }
261
262 return NS_OK;
263 }

mercurial