Bug 861085 - Enable/Disable Bluetooth based on mozSettings value at startup. r=gyeh, r=qdot, a=tef+
authorEric Chou <echou@mozilla.com>
Tue, 16 Apr 2013 11:02:23 +0800
changeset 118744 6bac24e14538abe16f6788af1ee8aad0f98f67d0
parent 118743 04de87e63992d6b9b1ac50d9b1974708535ffa77
child 118745 15c72c3c30d1af3f34e2a418643243a0d64bdd63
push id106
push userryanvm@gmail.com
push dateTue, 16 Apr 2013 12:40:16 +0000
reviewersgyeh, qdot, tef
bugs861085
milestone18.0
Bug 861085 - Enable/Disable Bluetooth based on mozSettings value at startup. r=gyeh, r=qdot, a=tef+
dom/bluetooth/BluetoothService.cpp
dom/bluetooth/BluetoothService.h
dom/bluetooth/gonk/BluetoothGonkService.cpp
dom/bluetooth/gonk/BluetoothGonkService.h
dom/bluetooth/ipc/BluetoothServiceChildProcess.cpp
dom/bluetooth/ipc/BluetoothServiceChildProcess.h
dom/bluetooth/linux/BluetoothDBusService.cpp
dom/bluetooth/linux/BluetoothDBusService.h
--- a/dom/bluetooth/BluetoothService.cpp
+++ b/dom/bluetooth/BluetoothService.cpp
@@ -175,17 +175,17 @@ public:
 
     /*
      * mEnabled: expected status of bluetooth
      * gBluetoothService->IsEnabled(): real status of bluetooth
      *
      * When two values are the same, we don't switch on/off bluetooth,
      * but we still do ToggleBtAck task.
      */
-    if (mEnabled == gBluetoothService->IsEnabled()) {
+    if (mEnabled == gBluetoothService->IsEnabledInternal()) {
       NS_WARNING("Bluetooth has already been enabled/disabled before.");
     } else {
       // Switch on/off bluetooth
       if (mEnabled) {
         if (NS_FAILED(gBluetoothService->StartInternal())) {
           NS_WARNING("Bluetooth service failed to start!");
           mEnabled = !mEnabled;
         }
@@ -512,28 +512,17 @@ BluetoothService::HandleStartup()
   gToggleInProgress = true;
   return NS_OK;
 }
 
 nsresult
 BluetoothService::HandleStartupSettingsCheck(bool aEnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
-
-  if (aEnable) {
-    return StartStopBluetooth(true);
-  }
-
-  /*
-   * Since BLUETOOTH_ENABLED_SETTING is false, we don't have to turn on
-   * bluetooth here, and set gToggleInProgress back to false.
-   */
-  gToggleInProgress = false;
-
-  return NS_OK;
+  return StartStopBluetooth(aEnable);
 }
 
 nsresult
 BluetoothService::HandleSettingsChanged(const nsAString& aData)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // The string that we're interested in will be a JSON string that looks like:
--- a/dom/bluetooth/BluetoothService.h
+++ b/dom/bluetooth/BluetoothService.h
@@ -315,26 +315,35 @@ protected:
    * Platform specific startup functions go here. Usually deals with member
    * variables, so not static. Guaranteed to be called outside of main thread.
    *
    * @return NS_OK on correct startup, NS_ERROR_FAILURE otherwise
    */
   virtual nsresult
   StartInternal() = 0;
 
-  /** 
+  /**
    * Platform specific startup functions go here. Usually deals with member
    * variables, so not static. Guaranteed to be called outside of main thread.
    *
    * @return NS_OK on correct startup, NS_ERROR_FAILURE otherwise
    */
   virtual nsresult
   StopInternal() = 0;
 
   /**
+   * Platform specific startup functions go here. Usually deals with member
+   * variables, so not static. Guaranteed to be called outside of main thread.
+   *
+   * @return true if Bluetooth is enabled, false otherwise
+   */
+  virtual bool
+  IsEnabledInternal() = 0;
+
+  /**
    * Called when XPCOM first creates this service.
    */
   virtual nsresult
   HandleStartup();
 
   /**
    * Called when the startup settings check has completed.
    */
--- a/dom/bluetooth/gonk/BluetoothGonkService.cpp
+++ b/dom/bluetooth/gonk/BluetoothGonkService.cpp
@@ -115,37 +115,50 @@ StartStopGonkBluetooth(bool aShouldEnabl
   }
   
   return NS_OK;
 }
 
 nsresult
 BluetoothGonkService::StartInternal()
 {
-  NS_ASSERTION(!NS_IsMainThread(), "This should not run on the main thread!");
+  MOZ_ASSERT(!NS_IsMainThread());
 
   nsresult ret;
 
   ret = StartStopGonkBluetooth(true);
 
   if (NS_FAILED(ret)) {
     return ret;
   }
 
   return BluetoothDBusService::StartInternal();
 }
 
 nsresult
 BluetoothGonkService::StopInternal()
 {
-  NS_ASSERTION(!NS_IsMainThread(), "This should not run on the main thread!");
+  MOZ_ASSERT(!NS_IsMainThread());
 
   nsresult ret;
 
   ret = BluetoothDBusService::StopInternal();
 
   if (NS_FAILED(ret)) {
     return ret;
   }
 
   return StartStopGonkBluetooth(false);
 }
 
+bool
+BluetoothGonkService::IsEnabledInternal()
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  if (!EnsureBluetoothInit()) {
+    NS_ERROR("Failed to load bluedroid library.\n");
+    return false;
+  }
+
+  return (sBluedroidFunctions.bt_is_enabled() == 1);
+}
+
--- a/dom/bluetooth/gonk/BluetoothGonkService.h
+++ b/dom/bluetooth/gonk/BluetoothGonkService.h
@@ -30,30 +30,34 @@ BEGIN_BLUETOOTH_NAMESPACE
  * happen on the IO Thread (see ipc/dbus for instance), and these messages will
  * be encased in runnables that will then be distributed via observers managed
  * here.
  */
 
 class BluetoothGonkService : public BluetoothDBusService
 {
 public:
-  /** 
+  /**
    * Set up variables and start the platform specific connection. Must
-   * be called from main thread.
+   * be called from non-main thread.
    *
-   * @return NS_OK if connection starts successfully, NS_ERROR_FAILURE
-   * otherwise
+   * @return NS_OK if connection starts successfully, NS_ERROR_FAILURE otherwise
    */
   virtual nsresult StartInternal();
 
-  /** 
-   * Stop the platform specific connection. Must be called from main
-   * thread.
+  /**
+   * Stop the platform specific connection. Must be called from non-main thread.
    *
-   * @return NS_OK if connection starts successfully, NS_ERROR_FAILURE
-   * otherwise
+   * @return NS_OK if connection starts successfully, NS_ERROR_FAILURE otherwise
    */
   virtual nsresult StopInternal();
+
+  /**
+   * Get status of Bluetooth. Must be called from non-main thread.
+   *
+   * @return true if Bluetooth is enabled, false otherwise
+   */
+  virtual bool IsEnabledInternal();
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/ipc/BluetoothServiceChildProcess.cpp
+++ b/dom/bluetooth/ipc/BluetoothServiceChildProcess.cpp
@@ -373,13 +373,20 @@ BluetoothServiceChildProcess::StartInter
 nsresult
 BluetoothServiceChildProcess::StopInternal()
 {
   MOZ_NOT_REACHED("This should never be called!");
   return NS_ERROR_FAILURE;
 }
 
 bool
+BluetoothServiceChildProcess::IsEnabledInternal()
+{
+  MOZ_NOT_REACHED("This should never be called!");
+  return false;
+}
+
+bool
 BluetoothServiceChildProcess::IsConnected(uint16_t aProfileId)
 {
   MOZ_NOT_REACHED("This should never be called!");
   return false;
 }
--- a/dom/bluetooth/ipc/BluetoothServiceChildProcess.h
+++ b/dom/bluetooth/ipc/BluetoothServiceChildProcess.h
@@ -169,16 +169,20 @@ private:
   // This method should never be called.
   virtual nsresult
   StartInternal() MOZ_OVERRIDE;
 
   // This method should never be called.
   virtual nsresult
   StopInternal() MOZ_OVERRIDE;
 
+  // This method should never be called.
+  virtual bool
+  IsEnabledInternal() MOZ_OVERRIDE;
+
   // Should never be called from the child
   virtual nsresult
   GetDevicePropertiesInternal(const BluetoothSignal& aSignal) MOZ_OVERRIDE;
 
   // This method should never be called from the child.
   virtual nsresult
   PrepareAdapterInternal(const nsAString& aPath) MOZ_OVERRIDE;
 };
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -1637,17 +1637,19 @@ nsresult
 BluetoothDBusService::StopInternal()
 {
   // This could block. It should never be run on the main thread.
   MOZ_ASSERT(!NS_IsMainThread());
 
   // If Bluetooth is turned off while connections exist, in order not to only
   // disconnect with profile connections with low level ACL connections alive,
   // we disconnect ACLs directly instead of closing each socket.
-  DisconnectAllAcls(sAdapterPath);
+  if (!sAdapterPath.IsEmpty()) {
+    DisconnectAllAcls(sAdapterPath);
+  }
 
   if (!mConnection) {
     StopDBus();
     return NS_OK;
   }
 
   DBusError err;
   dbus_error_init(&err);
@@ -1685,16 +1687,22 @@ BluetoothDBusService::StopInternal()
   sAuthorizeReqTable.Clear();
 
   PR_AtomicSet(&sIsPairing, 0);
 
   StopDBus();
   return NS_OK;
 }
 
+bool
+BluetoothDBusService::IsEnabledInternal()
+{
+  return mEnabled;
+}
+
 class DefaultAdapterPropertiesRunnable : public nsRunnable
 {
 public:
   DefaultAdapterPropertiesRunnable(BluetoothReplyRunnable* aRunnable)
     : mRunnable(dont_AddRef(aRunnable))
   {
   }
 
--- a/dom/bluetooth/linux/BluetoothDBusService.h
+++ b/dom/bluetooth/linux/BluetoothDBusService.h
@@ -25,16 +25,18 @@ class BluetoothDBusService : public Blue
 {
 public:
   bool IsReady();
 
   virtual nsresult StartInternal();
 
   virtual nsresult StopInternal();
 
+  virtual bool IsEnabledInternal();
+
   virtual nsresult GetDefaultAdapterPathInternal(BluetoothReplyRunnable* aRunnable);
 
   virtual nsresult GetPairedDevicePropertiesInternal(const nsTArray<nsString>& aDeviceAddresses,
                                                      BluetoothReplyRunnable* aRunnable);
 
   virtual nsresult StartDiscoveryInternal(const nsAString& aAdapterPath,
                                           BluetoothReplyRunnable* aRunnable);