Bug 729991: fix followup problems of bug 713116, r=ben
authorEric Chou <echou@mozilla.com>
Sun, 04 Mar 2012 19:54:01 -0800
changeset 88447 4dd463134071c9de38fc4f5b32e6a4d267ae4f1d
parent 88446 9d1489e6521818c8dfe75fd894d97bd215e80af8
child 88448 2893c5e0be5de24947b35923078ee2ba3e6fbf3e
push id157
push userMs2ger@gmail.com
push dateWed, 07 Mar 2012 19:27:10 +0000
reviewersben
bugs729991, 713116
milestone13.0a1
Bug 729991: fix followup problems of bug 713116, r=ben
dom/base/nsDOMClassInfo.cpp
dom/bluetooth/BluetoothAdapter.cpp
dom/bluetooth/BluetoothAdapter.h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1612,18 +1612,18 @@ static nsDOMClassInfoData sClassInfoData
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TelephonyCall, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CallEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
 #ifdef MOZ_B2G_BT
-  NS_DEFINE_CLASSINFO_DATA(BluetoothAdapter, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(BluetoothAdapter, nsEventTargetSH,
+                           EVENTTARGET_SCRIPTABLE_FLAGS)
 #endif
 
   NS_DEFINE_CLASSINFO_DATA(DOMError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DOMRequest, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
 };
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -11,151 +11,160 @@
 #include "mozilla/LazyIdleThread.h"
 
 #include "BluetoothAdapter.h"
 
 #if defined(MOZ_WIDGET_GONK)
 #include <bluedroid/bluetooth.h>
 #endif
 
-#define POWERED_EVENT_NAME NS_LITERAL_STRING("powered")
-
-BEGIN_BLUETOOTH_NAMESPACE
+USING_BLUETOOTH_NAMESPACE
 
 class ToggleBtResultTask : public nsRunnable
 {
   public:
-    ToggleBtResultTask(bool result, nsRefPtr<BluetoothAdapter>& adapterPtr)
+    ToggleBtResultTask(nsRefPtr<BluetoothAdapter>& adapterPtr, bool result)
       : mResult(result)
     {
-      MOZ_ASSERT(!NS_IsMainThread()); // This should be running on the worker thread
+      MOZ_ASSERT(!NS_IsMainThread());
 
       mAdapterPtr.swap(adapterPtr);
     }
 
-    NS_IMETHOD Run() {
-      MOZ_ASSERT(NS_IsMainThread()); // This method is supposed to run on the main thread!
+    NS_IMETHOD Run() 
+    {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      if (!mResult) {
+        //TODO:Bug-731361
+        NS_WARNING("BT firmware loading fails.\n");
+      }
+ 
+      //mAdapterPtr must be null before returning to prevent the background 
+      //thread from racing to release it during the destruction of this runnable.
       mAdapterPtr->FirePowered();
+      mAdapterPtr = nsnull;
 
       return NS_OK;
     }
 
   private:
+    nsRefPtr<BluetoothAdapter> mAdapterPtr;
     bool mResult;
-    nsRefPtr<BluetoothAdapter> mAdapterPtr;
 };
 
 class ToggleBtTask : public nsRunnable
 {
   public:
-    ToggleBtTask(bool onOff, BluetoothAdapter* adapterPtr)
+    ToggleBtTask(bool onOff, BluetoothAdapter* adapterPtr) 
       : mOnOff(onOff),
-      mAdapterPtr(adapterPtr)
+        mAdapterPtr(adapterPtr) 
     {
-      MOZ_ASSERT(NS_IsMainThread()); // The constructor should be running on the main thread.
+      MOZ_ASSERT(NS_IsMainThread());
     }
 
-    NS_IMETHOD Run() {
+    NS_IMETHOD Run() 
+    {
+      MOZ_ASSERT(!NS_IsMainThread());
+
       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
+#else 
       result = true;
 #endif
 
       // Create a result thread and pass it to Main Thread, 
-      nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(result, mAdapterPtr);
-      NS_DispatchToMainThread(resultRunnable);
+      nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(mAdapterPtr, result);
+
+      if (NS_FAILED(NS_DispatchToMainThread(resultRunnable))) {
+        NS_WARNING("Failed to dispatch to main thread!");
+      }
 
       return NS_OK;
     }
 
   private:
     nsRefPtr<BluetoothAdapter> mAdapterPtr;
     bool mOnOff;
 };
 
-END_BLUETOOTH_NAMESPACE
-
-DOMCI_DATA(BluetoothAdapter, mozilla::dom::bluetooth::BluetoothAdapter)
-
-USING_BLUETOOTH_NAMESPACE
+DOMCI_DATA(BluetoothAdapter, BluetoothAdapter)
 
 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_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_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_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)
+BluetoothAdapter::BluetoothAdapter() 
+  : mPower(false)
 {
 }
 
 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)
 {
   if (mPower != aPower) {
     mPower = aPower;
 
-    ToggleBluetoothAsync();
+    return ToggleBluetoothAsync();
   }
 
   return NS_OK;
 }
 
-void 
+nsresult
 BluetoothAdapter::ToggleBluetoothAsync()
 {
   if (!mToggleBtThread) {
     mToggleBtThread = new LazyIdleThread(15000);
   }
 
   nsCOMPtr<nsIRunnable> r = new ToggleBtTask(mPower, this);
 
-  mToggleBtThread->Dispatch(r, 0);
+  return mToggleBtThread->Dispatch(r, NS_DISPATCH_NORMAL);
 }
 
 nsresult
 BluetoothAdapter::FirePowered()
 {
   nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
-  nsresult rv = event->InitEvent(POWERED_EVENT_NAME, false, false);
+  nsresult rv = event->InitEvent(NS_LITERAL_STRING("powered"), false, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = event->SetTrusted(true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool dummy;
   rv = DispatchEvent(event, &dummy);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
--- a/dom/bluetooth/BluetoothAdapter.h
+++ b/dom/bluetooth/BluetoothAdapter.h
@@ -6,20 +6,22 @@
 
 #ifndef mozilla_dom_bluetooth_bluetoothadapter_h__
 #define mozilla_dom_bluetooth_bluetoothadapter_h__
 
 #include "BluetoothCommon.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsIDOMBluetoothAdapter.h"
 
+class nsIEventTarget;
+
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothAdapter : public nsIDOMBluetoothAdapter
-                        ,public nsDOMEventTargetHelper
+                       , public nsDOMEventTargetHelper
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMBLUETOOTHADAPTER
 
   NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothAdapter,
@@ -31,13 +33,13 @@ public:
 
 protected:
   bool mPower;
 
   NS_DECL_EVENT_HANDLER(powered)
 
 private:
   nsCOMPtr<nsIEventTarget> mToggleBtThread;
-  void ToggleBluetoothAsync();
+  nsresult ToggleBluetoothAsync();
 };
 
 END_BLUETOOTH_NAMESPACE
 #endif