summaryrefslogtreecommitdiffstats
path: root/dom/system/gonk/SystemWorkerManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/system/gonk/SystemWorkerManager.cpp')
-rw-r--r--dom/system/gonk/SystemWorkerManager.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/dom/system/gonk/SystemWorkerManager.cpp b/dom/system/gonk/SystemWorkerManager.cpp
new file mode 100644
index 000000000..ee3fc8de3
--- /dev/null
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -0,0 +1,214 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SystemWorkerManager.h"
+
+#include "nsINetworkService.h"
+#include "nsIWifi.h"
+#include "nsIWorkerHolder.h"
+#include "nsIXPConnect.h"
+
+#include "jsfriendapi.h"
+#include "mozilla/dom/workers/Workers.h"
+#include "AutoMounter.h"
+#include "TimeZoneSettingObserver.h"
+#include "AudioManager.h"
+#include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/ipc/KeyStore.h"
+#include "nsIObserverService.h"
+#include "nsServiceManagerUtils.h"
+#include "nsThreadUtils.h"
+#include "WifiWorker.h"
+#include "mozilla/Services.h"
+
+USING_WORKERS_NAMESPACE
+
+using namespace mozilla::dom::gonk;
+using namespace mozilla::ipc;
+using namespace mozilla::system;
+
+namespace {
+
+NS_DEFINE_CID(kWifiWorkerCID, NS_WIFIWORKER_CID);
+
+// Doesn't carry a reference, we're owned by services.
+SystemWorkerManager *gInstance = nullptr;
+
+} // namespace
+
+SystemWorkerManager::SystemWorkerManager()
+ : mShutdown(false)
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ NS_ASSERTION(!gInstance, "There should only be one instance!");
+}
+
+SystemWorkerManager::~SystemWorkerManager()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ NS_ASSERTION(!gInstance || gInstance == this,
+ "There should only be one instance!");
+ gInstance = nullptr;
+}
+
+nsresult
+SystemWorkerManager::Init()
+{
+ if (!XRE_IsParentProcess()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ NS_ASSERTION(NS_IsMainThread(), "We can only initialize on the main thread");
+ NS_ASSERTION(!mShutdown, "Already shutdown!");
+
+ nsresult rv = InitWifi();
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to initialize WiFi Networking!");
+ return rv;
+ }
+
+ InitKeyStore();
+
+ InitAutoMounter();
+ InitializeTimeZoneSettingObserver();
+ nsCOMPtr<nsIAudioManager> audioManager =
+ do_GetService(NS_AUDIOMANAGER_CONTRACTID);
+
+ nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+ if (!obs) {
+ NS_WARNING("Failed to get observer service!");
+ return NS_ERROR_FAILURE;
+ }
+
+ rv = obs->AddObserver(this, WORKERS_SHUTDOWN_TOPIC, false);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to initialize worker shutdown event!");
+ return rv;
+ }
+
+ return NS_OK;
+}
+
+void
+SystemWorkerManager::Shutdown()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+ mShutdown = true;
+
+ ShutdownAutoMounter();
+
+ nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
+ if (wifi) {
+ wifi->Shutdown();
+ wifi = nullptr;
+ }
+ mWifiWorker = nullptr;
+
+ if (mKeyStore) {
+ mKeyStore->Shutdown();
+ mKeyStore = nullptr;
+ }
+
+ nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+ if (obs) {
+ obs->RemoveObserver(this, WORKERS_SHUTDOWN_TOPIC);
+ }
+}
+
+// static
+already_AddRefed<SystemWorkerManager>
+SystemWorkerManager::FactoryCreate()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+ RefPtr<SystemWorkerManager> instance(gInstance);
+
+ if (!instance) {
+ instance = new SystemWorkerManager();
+ if (NS_FAILED(instance->Init())) {
+ instance->Shutdown();
+ return nullptr;
+ }
+
+ gInstance = instance;
+ }
+
+ return instance.forget();
+}
+
+// static
+nsIInterfaceRequestor*
+SystemWorkerManager::GetInterfaceRequestor()
+{
+ return gInstance;
+}
+
+NS_IMETHODIMP
+SystemWorkerManager::GetInterface(const nsIID &aIID, void **aResult)
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+ if (aIID.Equals(NS_GET_IID(nsIWifi))) {
+ return CallQueryInterface(mWifiWorker,
+ reinterpret_cast<nsIWifi**>(aResult));
+ }
+
+ NS_WARNING("Got nothing for the requested IID!");
+ return NS_ERROR_NO_INTERFACE;
+}
+
+nsresult
+SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
+ JS::Handle<JS::Value> aWorker,
+ JSContext *aCx)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult
+SystemWorkerManager::InitWifi()
+{
+ nsCOMPtr<nsIWorkerHolder> worker = do_CreateInstance(kWifiWorkerCID);
+ NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
+
+ mWifiWorker = worker;
+ return NS_OK;
+}
+
+nsresult
+SystemWorkerManager::InitKeyStore()
+{
+ mKeyStore = new KeyStore();
+ return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS(SystemWorkerManager,
+ nsIObserver,
+ nsIInterfaceRequestor,
+ nsISystemWorkerManager)
+
+NS_IMETHODIMP
+SystemWorkerManager::Observe(nsISupports *aSubject, const char *aTopic,
+ const char16_t *aData)
+{
+ if (!strcmp(aTopic, WORKERS_SHUTDOWN_TOPIC)) {
+ Shutdown();
+ }
+
+ return NS_OK;
+}