1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/system/gonk/SystemWorkerManager.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,263 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* Copyright 2012 Mozilla Foundation and Mozilla contributors 1.7 + * 1.8 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.9 + * you may not use this file except in compliance with the License. 1.10 + * You may obtain a copy of the License at 1.11 + * 1.12 + * http://www.apache.org/licenses/LICENSE-2.0 1.13 + * 1.14 + * Unless required by applicable law or agreed to in writing, software 1.15 + * distributed under the License is distributed on an "AS IS" BASIS, 1.16 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.17 + * See the License for the specific language governing permissions and 1.18 + * limitations under the License. 1.19 + */ 1.20 + 1.21 +#include "SystemWorkerManager.h" 1.22 + 1.23 +#include "nsINetworkService.h" 1.24 +#include "nsIWifi.h" 1.25 +#include "nsIWorkerHolder.h" 1.26 +#include "nsIXPConnect.h" 1.27 + 1.28 +#include "jsfriendapi.h" 1.29 +#include "mozilla/dom/workers/Workers.h" 1.30 +#include "AutoMounter.h" 1.31 +#include "TimeZoneSettingObserver.h" 1.32 +#include "AudioManager.h" 1.33 +#ifdef MOZ_B2G_RIL 1.34 +#include "mozilla/ipc/Ril.h" 1.35 +#endif 1.36 +#ifdef MOZ_NFC 1.37 +#include "mozilla/ipc/Nfc.h" 1.38 +#endif 1.39 +#include "mozilla/ipc/KeyStore.h" 1.40 +#include "nsIObserverService.h" 1.41 +#include "nsCxPusher.h" 1.42 +#include "nsServiceManagerUtils.h" 1.43 +#include "nsThreadUtils.h" 1.44 +#include "nsRadioInterfaceLayer.h" 1.45 +#include "WifiWorker.h" 1.46 +#include "mozilla/Services.h" 1.47 + 1.48 +USING_WORKERS_NAMESPACE 1.49 + 1.50 +using namespace mozilla::dom::gonk; 1.51 +using namespace mozilla::ipc; 1.52 +using namespace mozilla::system; 1.53 + 1.54 +namespace { 1.55 + 1.56 +NS_DEFINE_CID(kWifiWorkerCID, NS_WIFIWORKER_CID); 1.57 + 1.58 +// Doesn't carry a reference, we're owned by services. 1.59 +SystemWorkerManager *gInstance = nullptr; 1.60 + 1.61 +} // anonymous namespace 1.62 + 1.63 +SystemWorkerManager::SystemWorkerManager() 1.64 + : mShutdown(false) 1.65 +{ 1.66 + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); 1.67 + NS_ASSERTION(!gInstance, "There should only be one instance!"); 1.68 +} 1.69 + 1.70 +SystemWorkerManager::~SystemWorkerManager() 1.71 +{ 1.72 + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); 1.73 + NS_ASSERTION(!gInstance || gInstance == this, 1.74 + "There should only be one instance!"); 1.75 + gInstance = nullptr; 1.76 +} 1.77 + 1.78 +nsresult 1.79 +SystemWorkerManager::Init() 1.80 +{ 1.81 + if (XRE_GetProcessType() != GeckoProcessType_Default) { 1.82 + return NS_ERROR_NOT_AVAILABLE; 1.83 + } 1.84 + 1.85 + NS_ASSERTION(NS_IsMainThread(), "We can only initialize on the main thread"); 1.86 + NS_ASSERTION(!mShutdown, "Already shutdown!"); 1.87 + 1.88 + mozilla::AutoSafeJSContext cx; 1.89 + 1.90 + nsresult rv = InitWifi(cx); 1.91 + if (NS_FAILED(rv)) { 1.92 + NS_WARNING("Failed to initialize WiFi Networking!"); 1.93 + return rv; 1.94 + } 1.95 + 1.96 + InitKeyStore(cx); 1.97 + 1.98 + InitAutoMounter(); 1.99 + InitializeTimeZoneSettingObserver(); 1.100 + nsCOMPtr<nsIAudioManager> audioManager = 1.101 + do_GetService(NS_AUDIOMANAGER_CONTRACTID); 1.102 + 1.103 + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); 1.104 + if (!obs) { 1.105 + NS_WARNING("Failed to get observer service!"); 1.106 + return NS_ERROR_FAILURE; 1.107 + } 1.108 + 1.109 + rv = obs->AddObserver(this, WORKERS_SHUTDOWN_TOPIC, false); 1.110 + if (NS_FAILED(rv)) { 1.111 + NS_WARNING("Failed to initialize worker shutdown event!"); 1.112 + return rv; 1.113 + } 1.114 + 1.115 + return NS_OK; 1.116 +} 1.117 + 1.118 +void 1.119 +SystemWorkerManager::Shutdown() 1.120 +{ 1.121 + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); 1.122 + 1.123 + mShutdown = true; 1.124 + 1.125 + ShutdownAutoMounter(); 1.126 + 1.127 +#ifdef MOZ_B2G_RIL 1.128 + RilConsumer::Shutdown(); 1.129 +#endif 1.130 + 1.131 +#ifdef MOZ_NFC 1.132 + NfcConsumer::Shutdown(); 1.133 +#endif 1.134 + 1.135 + nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker)); 1.136 + if (wifi) { 1.137 + wifi->Shutdown(); 1.138 + wifi = nullptr; 1.139 + } 1.140 + mWifiWorker = nullptr; 1.141 + 1.142 + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); 1.143 + if (obs) { 1.144 + obs->RemoveObserver(this, WORKERS_SHUTDOWN_TOPIC); 1.145 + } 1.146 +} 1.147 + 1.148 +// static 1.149 +already_AddRefed<SystemWorkerManager> 1.150 +SystemWorkerManager::FactoryCreate() 1.151 +{ 1.152 + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); 1.153 + 1.154 + nsRefPtr<SystemWorkerManager> instance(gInstance); 1.155 + 1.156 + if (!instance) { 1.157 + instance = new SystemWorkerManager(); 1.158 + if (NS_FAILED(instance->Init())) { 1.159 + instance->Shutdown(); 1.160 + return nullptr; 1.161 + } 1.162 + 1.163 + gInstance = instance; 1.164 + } 1.165 + 1.166 + return instance.forget(); 1.167 +} 1.168 + 1.169 +// static 1.170 +nsIInterfaceRequestor* 1.171 +SystemWorkerManager::GetInterfaceRequestor() 1.172 +{ 1.173 + return gInstance; 1.174 +} 1.175 + 1.176 +NS_IMETHODIMP 1.177 +SystemWorkerManager::GetInterface(const nsIID &aIID, void **aResult) 1.178 +{ 1.179 + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); 1.180 + 1.181 + if (aIID.Equals(NS_GET_IID(nsIWifi))) { 1.182 + return CallQueryInterface(mWifiWorker, 1.183 + reinterpret_cast<nsIWifi**>(aResult)); 1.184 + } 1.185 + 1.186 + NS_WARNING("Got nothing for the requested IID!"); 1.187 + return NS_ERROR_NO_INTERFACE; 1.188 +} 1.189 + 1.190 +nsresult 1.191 +SystemWorkerManager::RegisterRilWorker(unsigned int aClientId, 1.192 + JS::Handle<JS::Value> aWorker, 1.193 + JSContext *aCx) 1.194 +{ 1.195 +#ifndef MOZ_B2G_RIL 1.196 + return NS_ERROR_NOT_IMPLEMENTED; 1.197 +#else 1.198 + NS_ENSURE_TRUE(aWorker.isObject(), NS_ERROR_UNEXPECTED); 1.199 + 1.200 + JSAutoCompartment ac(aCx, &aWorker.toObject()); 1.201 + 1.202 + WorkerCrossThreadDispatcher *wctd = 1.203 + GetWorkerCrossThreadDispatcher(aCx, aWorker); 1.204 + if (!wctd) { 1.205 + NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for ril"); 1.206 + return NS_ERROR_FAILURE; 1.207 + } 1.208 + 1.209 + return RilConsumer::Register(aClientId, wctd); 1.210 +#endif // MOZ_B2G_RIL 1.211 +} 1.212 + 1.213 +nsresult 1.214 +SystemWorkerManager::RegisterNfcWorker(JS::Handle<JS::Value> aWorker, 1.215 + JSContext* aCx) 1.216 +{ 1.217 +#ifndef MOZ_NFC 1.218 + return NS_ERROR_NOT_IMPLEMENTED; 1.219 +#else 1.220 + NS_ENSURE_TRUE(aWorker.isObject(), NS_ERROR_UNEXPECTED); 1.221 + 1.222 + JSAutoCompartment ac(aCx, &aWorker.toObject()); 1.223 + 1.224 + WorkerCrossThreadDispatcher* wctd = 1.225 + GetWorkerCrossThreadDispatcher(aCx, aWorker); 1.226 + if (!wctd) { 1.227 + NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for nfc"); 1.228 + return NS_ERROR_FAILURE; 1.229 + } 1.230 + 1.231 + return NfcConsumer::Register(wctd); 1.232 +#endif // MOZ_NFC 1.233 +} 1.234 + 1.235 +nsresult 1.236 +SystemWorkerManager::InitWifi(JSContext *cx) 1.237 +{ 1.238 + nsCOMPtr<nsIWorkerHolder> worker = do_CreateInstance(kWifiWorkerCID); 1.239 + NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE); 1.240 + 1.241 + mWifiWorker = worker; 1.242 + return NS_OK; 1.243 +} 1.244 + 1.245 +nsresult 1.246 +SystemWorkerManager::InitKeyStore(JSContext *cx) 1.247 +{ 1.248 + mKeyStore = new KeyStore(); 1.249 + return NS_OK; 1.250 +} 1.251 + 1.252 +NS_IMPL_ISUPPORTS(SystemWorkerManager, 1.253 + nsIObserver, 1.254 + nsIInterfaceRequestor, 1.255 + nsISystemWorkerManager) 1.256 + 1.257 +NS_IMETHODIMP 1.258 +SystemWorkerManager::Observe(nsISupports *aSubject, const char *aTopic, 1.259 + const char16_t *aData) 1.260 +{ 1.261 + if (!strcmp(aTopic, WORKERS_SHUTDOWN_TOPIC)) { 1.262 + Shutdown(); 1.263 + } 1.264 + 1.265 + return NS_OK; 1.266 +}