Bug 713116 - B2G Bluetooth: Turn bluetooth adapter on/off - r=qDot
authorEric Chou <echou@mozilla.com>
Thu, 23 Feb 2012 16:55:48 +0100
changeset 87541 ec8b8731343b513398222c2dc569199ddb3c7829
parent 87540 1de300d294f061afcd7bf1a195c2e08aee5cab17
child 87542 307abe0852487a89d1d1edc2f4c9496c3a5d87f0
push idunknown
push userunknown
push dateunknown
reviewersqDot
bugs713116
milestone13.0a1
Bug 713116 - B2G Bluetooth: Turn bluetooth adapter on/off - r=qDot
dom/bluetooth/BluetoothAdapter.cpp
dom/bluetooth/BluetoothAdapter.h
dom/bluetooth/nsIDOMBluetoothAdapter.idl
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -1,39 +1,163 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=40: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "nsDOMClassInfo.h"
+#include "nsDOMEvent.h"
+#include "nsThreadUtils.h"
+#include "nsXPCOMCIDInternal.h"
+#include "mozilla/LazyIdleThread.h"
+
 #include "BluetoothAdapter.h"
-#include "nsDOMClassInfo.h"
+
+#if defined(MOZ_WIDGET_GONK)
+#include <bluedroid/bluetooth.h>
+#endif
+
+#define POWERED_EVENT_NAME NS_LITERAL_STRING("powered")
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+class ToggleBtResultTask : public nsRunnable
+{
+  public:
+    ToggleBtResultTask(bool result, nsRefPtr<BluetoothAdapter>& adapterPtr)
+      : mResult(result)
+    {
+      MOZ_ASSERT(!NS_IsMainThread()); // This should be running on the worker thread
+
+      mAdapterPtr.swap(adapterPtr);
+    }
+
+    NS_IMETHOD Run() {
+      MOZ_ASSERT(NS_IsMainThread()); // This method is supposed to run on the main thread!
+      mAdapterPtr->FirePowered();
+
+      return NS_OK;
+    }
+
+  private:
+    bool mResult;
+    nsRefPtr<BluetoothAdapter> mAdapterPtr;
+};
+
+class ToggleBtTask : public nsRunnable
+{
+  public:
+    ToggleBtTask(bool onOff, BluetoothAdapter* adapterPtr)
+      : mOnOff(onOff),
+      mAdapterPtr(adapterPtr)
+    {
+      MOZ_ASSERT(NS_IsMainThread()); // The constructor should be running on the main thread.
+    }
+
+    NS_IMETHOD Run() {
+      bool result;
+
+      MOZ_ASSERT(!NS_IsMainThread()); // This should be running on the worker thread.
+
+      //Toggle BT here
+#if defined(MOZ_WIDGET_GONK)  
+      if (mOnOff) {
+        result = bt_enable();
+      } else {
+        result = bt_disable();
+      }
+#else
+      result = true;
+#endif
+
+      // Create a result thread and pass it to Main Thread, 
+      nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(result, mAdapterPtr);
+      NS_DispatchToMainThread(resultRunnable);
+
+      return NS_OK;
+    }
+
+  private:
+    nsRefPtr<BluetoothAdapter> mAdapterPtr;
+    bool mOnOff;
+};
+
+END_BLUETOOTH_NAMESPACE
+
+DOMCI_DATA(BluetoothAdapter, mozilla::dom::bluetooth::BluetoothAdapter)
 
 USING_BLUETOOTH_NAMESPACE
 
+NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
+    nsDOMEventTargetHelper)
+NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(powered)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
+    nsDOMEventTargetHelper)
+NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(powered)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+  NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothAdapter)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothAdapter)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
+
+NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
+
 BluetoothAdapter::BluetoothAdapter() : mPower(false)
 {
 }
 
-NS_INTERFACE_MAP_BEGIN(BluetoothAdapter)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothAdapter)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothAdapter)
-NS_INTERFACE_MAP_END
-  
-NS_IMPL_ADDREF(BluetoothAdapter)
-NS_IMPL_RELEASE(BluetoothAdapter)
-
-DOMCI_DATA(BluetoothAdapter, BluetoothAdapter)
-  
 NS_IMETHODIMP
 BluetoothAdapter::GetPower(bool* aPower)
 {
+#if defined(MOZ_WIDGET_GONK)  
+  *aPower = bt_is_enabled();
+#else
   *aPower = mPower;
+#endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BluetoothAdapter::SetPower(bool aPower)
 {
-  mPower = aPower;
+  if (mPower != aPower) {
+    mPower = aPower;
+
+    ToggleBluetoothAsync();
+  }
+
   return NS_OK;
 }
+
+void 
+BluetoothAdapter::ToggleBluetoothAsync()
+{
+  if (!mToggleBtThread) {
+    mToggleBtThread = new LazyIdleThread(15000);
+  }
+
+  nsCOMPtr<nsIRunnable> r = new ToggleBtTask(mPower, this);
+
+  mToggleBtThread->Dispatch(r, 0);
+}
+
+nsresult
+BluetoothAdapter::FirePowered()
+{
+  nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
+  nsresult rv = event->InitEvent(POWERED_EVENT_NAME, false, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool dummy;
+  rv = DispatchEvent(event, &dummy);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+NS_IMPL_EVENT_HANDLER(BluetoothAdapter, powered)
--- a/dom/bluetooth/BluetoothAdapter.h
+++ b/dom/bluetooth/BluetoothAdapter.h
@@ -3,26 +3,41 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_bluetooth_bluetoothadapter_h__
 #define mozilla_dom_bluetooth_bluetoothadapter_h__
 
 #include "BluetoothCommon.h"
+#include "nsDOMEventTargetHelper.h"
 #include "nsIDOMBluetoothAdapter.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothAdapter : public nsIDOMBluetoothAdapter
+                        ,public nsDOMEventTargetHelper
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMBLUETOOTHADAPTER
 
+  NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
+
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothAdapter,
+                                           nsDOMEventTargetHelper)
+
   BluetoothAdapter();
 
+  nsresult FirePowered();
+
 protected:
   bool mPower;
+
+  NS_DECL_EVENT_HANDLER(powered)
+
+private:
+  nsCOMPtr<nsIEventTarget> mToggleBtThread;
+  void ToggleBluetoothAsync();
 };
 
 END_BLUETOOTH_NAMESPACE
 #endif
--- a/dom/bluetooth/nsIDOMBluetoothAdapter.idl
+++ b/dom/bluetooth/nsIDOMBluetoothAdapter.idl
@@ -1,13 +1,17 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=40: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
+#include "nsIDOMEventTarget.idl"
 
-[scriptable, builtinclass, uuid(29689a22-45ff-4ccf-b552-5364ce3a3642)]
-interface nsIDOMBluetoothAdapter : nsISupports
+interface nsIDOMEventListener;
+
+[scriptable, builtinclass, uuid(3dbaa9f4-5c93-11e1-8592-ff9bfcc3ab4b)]
+interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
 {
   attribute boolean power;
+
+  attribute nsIDOMEventListener onpowered;
 };