Bug 929891 - [Bluetooth][bluedroid] Enable/Disable Bluetooth, r=echou
authorShawn Huang <shuang@mozilla.com>
Mon, 28 Oct 2013 12:05:17 +0800
changeset 167219 80734c181020ddd859cbdfbd89034595d96c7ad4
parent 167218 c3fd1d0ebb9b7e888c0470beff82dc04ceb37bc2
child 167220 a11f3d159ce7ea488b8ba608249e083f8307c823
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechou
bugs929891
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 929891 - [Bluetooth][bluedroid] Enable/Disable Bluetooth, r=echou
dom/bluetooth/BluetoothServiceBluedroid.cpp
dom/bluetooth/BluetoothServiceBluedroid.h
--- a/dom/bluetooth/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/BluetoothServiceBluedroid.cpp
@@ -12,42 +12,184 @@
 ** 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 "BluetoothServiceBluedroid.h"
+
+#include <hardware/bluetooth.h>
+#include <hardware/hardware.h>
+
 #include "BluetoothReplyRunnable.h"
 #include "BluetoothUtils.h"
 #include "BluetoothUuid.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/ipc/UnixSocket.h"
 
 using namespace mozilla;
 using namespace mozilla::ipc;
 USING_BLUETOOTH_NAMESPACE
 
+/**
+ *  Classes only used in this file
+ */
+class DistributeBluetoothSignalTask : public nsRunnable {
+public:
+  DistributeBluetoothSignalTask(const BluetoothSignal& aSignal) :
+    mSignal(aSignal)
+  {
+  }
+
+  NS_IMETHOD
+  Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    BluetoothService* bs = BluetoothService::Get();
+    bs->DistributeSignal(mSignal);
+
+    return NS_OK;
+  }
+
+private:
+  BluetoothSignal mSignal;
+};
+
+/**
+ *  Static variables
+ */
+
+static bluetooth_device_t* sBtDevice;
+static const bt_interface_t* sBtInterface;
+static bool sIsBtEnabled = false;
+
+/**
+ *  Static callback functions
+ */
+static void
+AdapterStateChangeCallback(bt_state_t aStatus)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  BT_LOGD("Enter: %s, BT_STATE:%d", __FUNCTION__, aStatus);
+  nsAutoString signalName;
+  if (aStatus == BT_STATE_ON) {
+    sIsBtEnabled = true;
+    signalName = NS_LITERAL_STRING("AdapterAdded");
+  } else {
+    sIsBtEnabled = false;
+    signalName = NS_LITERAL_STRING("Disabled");
+  }
+
+  BluetoothSignal signal(signalName, NS_LITERAL_STRING(KEY_MANAGER), BluetoothValue(true));
+  nsRefPtr<DistributeBluetoothSignalTask>
+    t = new DistributeBluetoothSignalTask(signal);
+  if (NS_FAILED(NS_DispatchToMainThread(t))) {
+    NS_WARNING("Failed to dispatch to main thread!");
+  }
+}
+
+bt_callbacks_t sBluetoothCallbacks = {
+  sizeof(sBluetoothCallbacks),
+  AdapterStateChangeCallback
+};
+
+/**
+ *  Static functions
+ */
+static bool
+EnsureBluetoothHalLoad()
+{
+  hw_module_t* module;
+  hw_device_t* device;
+  int err = hw_get_module(BT_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+  if (err != 0) {
+    BT_LOGR("Error: %s ", strerror(err));
+    return false;
+  }
+  module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
+  sBtDevice = (bluetooth_device_t *)device;
+  sBtInterface = sBtDevice->get_bluetooth_interface();
+  BT_LOGD("Bluetooth HAL loaded");
+
+  return true;
+}
+
+static nsresult
+StartStopGonkBluetooth(bool aShouldEnable)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  static bool sIsBtInterfaceInitialized = false;
+
+  if (!EnsureBluetoothHalLoad()) {
+    BT_LOGR("Failed to load bluedroid library.\n");
+    return NS_ERROR_FAILURE;
+  }
+
+  if (sIsBtEnabled == aShouldEnable)
+    return NS_OK;
+
+  if (sBtInterface && !sIsBtInterfaceInitialized) {
+    int ret = sBtInterface->init(&sBluetoothCallbacks);
+    if (ret != BT_STATUS_SUCCESS) {
+      BT_LOGR("Error while setting the callbacks %s", __FUNCTION__);
+      sBtInterface = nullptr;
+      return NS_ERROR_FAILURE;
+    }
+    sIsBtInterfaceInitialized = true;
+  }
+  int ret = aShouldEnable ? sBtInterface->enable() : sBtInterface->disable();
+
+  return (ret == BT_STATUS_SUCCESS) ? NS_OK : NS_ERROR_FAILURE;
+}
+
+/**
+ *  Member functions
+ */
 nsresult
 BluetoothServiceBluedroid::StartInternal()
 {
-  return NS_OK;
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  nsresult ret = StartStopGonkBluetooth(true);
+  if (NS_FAILED(ret)) {
+    BT_LOGR("Error: %s", __FUNCTION__);
+  }
+
+  return ret;
 }
 
 nsresult
 BluetoothServiceBluedroid::StopInternal()
 {
-  return NS_OK;
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  nsresult ret = StartStopGonkBluetooth(false);
+  if (NS_FAILED(ret)) {
+    BT_LOGR("Error: %s", __FUNCTION__);
+  }
+
+  return ret;
 }
 
 bool
 BluetoothServiceBluedroid::IsEnabledInternal()
 {
-  return true;
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  if (!EnsureBluetoothHalLoad()) {
+    NS_ERROR("Failed to load bluedroid library.\n");
+    return false;
+  }
+
+  return sIsBtEnabled;
 }
 
 nsresult
 BluetoothServiceBluedroid::GetDefaultAdapterPathInternal(
   BluetoothReplyRunnable* aRunnable)
 {
   return NS_OK;
 }
--- a/dom/bluetooth/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth/BluetoothServiceBluedroid.h
@@ -1,9 +1,9 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*-
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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_bluetoothservicebluedroid_h__
 #define mozilla_dom_bluetooth_bluetoothservicebluedroid_h__