From e17f8ea8c00b49fbaee015d01372214c541fbdc6 Mon Sep 17 00:00:00 2001 From: Gina Yeh Date: Mon, 3 Sep 2012 14:38:44 +0800 Subject: [PATCH] Bug 764559 - Final version: add eventlistener for adapteradded in BluetoothManager, r=qdot, sr=jst --- content/base/src/nsGkAtomList.h | 1 + dom/bluetooth/BluetoothManager.cpp | 51 ++++++++++++++++---- dom/bluetooth/BluetoothService.h | 1 + dom/bluetooth/gonk/BluetoothGonkService.cpp | 10 ++++ dom/bluetooth/gonk/BluetoothGonkService.h | 5 ++ dom/bluetooth/linux/BluetoothDBusService.cpp | 19 +++++++- dom/bluetooth/linux/BluetoothDBusService.h | 2 + dom/bluetooth/nsIDOMBluetoothManager.idl | 3 +- 8 files changed, 80 insertions(+), 12 deletions(-) diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 392037f64d9..5fcc795ac98 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -614,6 +614,7 @@ GK_ATOM(OFF, "OFF") GK_ATOM(ol, "ol") GK_ATOM(omitXmlDeclaration, "omit-xml-declaration") GK_ATOM(onabort, "onabort") +GK_ATOM(onadapteradded, "onadapteradded") GK_ATOM(onafterprint, "onafterprint") GK_ATOM(onafterscriptexecute, "onafterscriptexecute") GK_ATOM(onalerting, "onalerting") diff --git a/dom/bluetooth/BluetoothManager.cpp b/dom/bluetooth/BluetoothManager.cpp index 5d22e45e3ee..703af6e01fd 100644 --- a/dom/bluetooth/BluetoothManager.cpp +++ b/dom/bluetooth/BluetoothManager.cpp @@ -83,7 +83,7 @@ public: sc->GetNativeGlobal(), adapter, aValue); - bool result = NS_SUCCEEDED(rv) ? true : false; + bool result = NS_SUCCEEDED(rv); if (!result) { NS_WARNING("Cannot create native object!"); SetError(NS_LITERAL_STRING("BluetoothNativeObjectError")); @@ -247,6 +247,20 @@ BluetoothManager::HandleMozsettingChanged(const PRUnichar* aData) } bool enabled = value.toBoolean(); + bool isEnabled = (bs->IsEnabledInternal() > 0); + if (!isEnabled && enabled) { + if (NS_FAILED(bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING("/"), this))) { + NS_ERROR("Failed to register object with observer!"); + return NS_ERROR_FAILURE; + } + } else if (isEnabled && !enabled){ + if (NS_FAILED(bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING("/"), this))) { + NS_WARNING("Failed to unregister object with observer!"); + } + } else { + return NS_OK; + } + nsCOMPtr resultTask = new ToggleBtResultTask(this, enabled); if (enabled) { @@ -330,17 +344,19 @@ BluetoothManager::GetDefaultAdapter(nsIDOMDOMRequest** aAdapter) // static already_AddRefed BluetoothManager::Create(nsPIDOMWindow* aWindow) { - nsRefPtr manager = new BluetoothManager(aWindow); BluetoothService* bs = BluetoothService::Get(); if (!bs) { NS_WARNING("BluetoothService not available!"); return nullptr; } - - if (NS_FAILED(bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING("/"), manager))) { - NS_ERROR("Failed to register object with observer!"); - return nullptr; + + bool isEnabled = (bs->IsEnabledInternal() > 0); + if (isEnabled) { + if (NS_FAILED(bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING("/"), manager))) { + NS_ERROR("Failed to register object with observer!"); + return nullptr; + } } return manager.forget(); @@ -390,13 +406,28 @@ NS_NewBluetoothManager(nsPIDOMWindow* aWindow, void BluetoothManager::Notify(const BluetoothSignal& aData) { + if (aData.name().EqualsLiteral("AdapterAdded")) { + nsRefPtr event = new nsDOMEvent(nullptr, nullptr); + nsresult rv = event->InitEvent(NS_LITERAL_STRING("adapteradded"), false, false); + + if (NS_FAILED(rv)) { + NS_WARNING("Failed to init the adapteradded event!!!"); + return; + } + + event->SetTrusted(true); + bool dummy; + DispatchEvent(event, &dummy); + } else { #ifdef DEBUG - nsCString warningMsg; - warningMsg.AssignLiteral("Not handling manager signal: "); - warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name())); - NS_WARNING(warningMsg.get()); + nsCString warningMsg; + warningMsg.AssignLiteral("Not handling manager signal: "); + warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name())); + NS_WARNING(warningMsg.get()); #endif + } } NS_IMPL_EVENT_HANDLER(BluetoothManager, enabled) NS_IMPL_EVENT_HANDLER(BluetoothManager, disabled) +NS_IMPL_EVENT_HANDLER(BluetoothManager, adapteradded) diff --git a/dom/bluetooth/BluetoothService.h b/dom/bluetooth/BluetoothService.h index 43aed9e9429..f84d44c92b8 100644 --- a/dom/bluetooth/BluetoothService.h +++ b/dom/bluetooth/BluetoothService.h @@ -225,6 +225,7 @@ public: virtual bool SetPasskeyInternal(const nsAString& aDeviceAddress, uint32_t aPasskey) = 0; virtual bool SetPairingConfirmationInternal(const nsAString& aDeviceAddress, bool aConfirm) = 0; virtual bool SetAuthorizationInternal(const nsAString& aDeviceAddress, bool aAllow) = 0; + virtual int IsEnabledInternal() = 0; /** * Due to the fact that some operations require multiple calls, a diff --git a/dom/bluetooth/gonk/BluetoothGonkService.cpp b/dom/bluetooth/gonk/BluetoothGonkService.cpp index 1e9ca5768e7..634c5e39e4a 100644 --- a/dom/bluetooth/gonk/BluetoothGonkService.cpp +++ b/dom/bluetooth/gonk/BluetoothGonkService.cpp @@ -128,6 +128,16 @@ StartStopGonkBluetooth(bool aShouldEnable) return NS_OK; } +int +BluetoothGonkService::IsEnabledInternal() +{ + if (!EnsureBluetoothInit()) { + NS_ERROR("Failed to load bluedroid library.\n"); + return false; + } + return IsBluetoothEnabled(); +} + nsresult BluetoothGonkService::StartInternal() { diff --git a/dom/bluetooth/gonk/BluetoothGonkService.h b/dom/bluetooth/gonk/BluetoothGonkService.h index afeb53d4529..308d9b8608d 100644 --- a/dom/bluetooth/gonk/BluetoothGonkService.h +++ b/dom/bluetooth/gonk/BluetoothGonkService.h @@ -52,6 +52,11 @@ public: * otherwise */ virtual nsresult StopInternal(); + + /** + * @return true if bluetooth daemon is enabled, false otherwise + */ + virtual int IsEnabledInternal(); }; END_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/linux/BluetoothDBusService.cpp b/dom/bluetooth/linux/BluetoothDBusService.cpp index 95106803096..8ab2ab2bb00 100644 --- a/dom/bluetooth/linux/BluetoothDBusService.cpp +++ b/dom/bluetooth/linux/BluetoothDBusService.cpp @@ -831,7 +831,6 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData) BluetoothValue v; if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "DeviceFound")) { - DBusMessageIter iter; if (!dbus_message_iter_init(aMsg, &iter)) { @@ -892,6 +891,16 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData) errorStr, sDeviceProperties, ArrayLength(sDeviceProperties)); + } else if (dbus_message_is_signal(aMsg, DBUS_MANAGER_IFACE, "AdapterAdded")) { + const char* str; + if (!dbus_message_get_args(aMsg, &err, + DBUS_TYPE_OBJECT_PATH, &str, + DBUS_TYPE_INVALID)) { + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg); + errorStr.AssignLiteral("Cannot parse manager path!"); + } else { + v = NS_ConvertUTF8toUTF16(str); + } } else if (dbus_message_is_signal(aMsg, DBUS_MANAGER_IFACE, "PropertyChanged")) { ParsePropertyChange(aMsg, v, @@ -1028,6 +1037,14 @@ BluetoothDBusService::StopInternal() return NS_OK; } + +int +BluetoothDBusService::IsEnabledInternal() +{ + // assume bluetooth is always enabled on desktop + return true; +} + class DefaultAdapterPropertiesRunnable : public nsRunnable { public: diff --git a/dom/bluetooth/linux/BluetoothDBusService.h b/dom/bluetooth/linux/BluetoothDBusService.h index 470c06d170b..391e6e9e4c7 100644 --- a/dom/bluetooth/linux/BluetoothDBusService.h +++ b/dom/bluetooth/linux/BluetoothDBusService.h @@ -82,6 +82,8 @@ public: virtual bool SetAuthorizationInternal(const nsAString& aDeviceAddress, bool aAllow); + virtual int IsEnabledInternal(); + private: nsresult SendGetPropertyMessage(const nsAString& aPath, const char* aInterface, diff --git a/dom/bluetooth/nsIDOMBluetoothManager.idl b/dom/bluetooth/nsIDOMBluetoothManager.idl index 82ca02ac129..50b53ad4f2c 100644 --- a/dom/bluetooth/nsIDOMBluetoothManager.idl +++ b/dom/bluetooth/nsIDOMBluetoothManager.idl @@ -9,7 +9,7 @@ interface nsIDOMDOMRequest; interface nsIDOMBluetoothAdapter; -[scriptable, builtinclass, uuid(b9e0a4a2-fa84-402d-8830-d0f3625f120a)] +[scriptable, builtinclass, uuid(d27ec867-949f-4585-b718-d2352e420ec6)] interface nsIDOMBluetoothManager : nsIDOMEventTarget { readonly attribute bool enabled; @@ -18,4 +18,5 @@ interface nsIDOMBluetoothManager : nsIDOMEventTarget [implicit_jscontext] attribute jsval onenabled; [implicit_jscontext] attribute jsval ondisabled; + [implicit_jscontext] attribute jsval onadapteradded; };