Bug 1134821: Detect default Bluetooth backend, r=shuang
authorThomas Zimmermann <tdz@users.sourceforge.net>
Wed, 11 Mar 2015 10:11:48 +0100
changeset 233051 c854fe96a8a13db9b620750ba9e75c1c76beedcb
parent 233050 ce41227222ea06bf9aafc1264847f44c6c4627aa
child 233052 a8e070c7f67ca9c8a623c4dfd47ed9bfbe51d99f
push id28402
push userkwierso@gmail.com
push dateThu, 12 Mar 2015 02:03:45 +0000
treeherdermozilla-central@5334d2bead3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshuang
bugs1134821
milestone39.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 1134821: Detect default Bluetooth backend, r=shuang This patch adds code to select the default Bluetooth backend from a list of supported ones, by detecting the backend's availability. Some devices are missing bluetoothd support. With the patch, bluetoothd can be the default backend, but unsupportive devices fall back to in- Gecko Bluedroid.
dom/bluetooth/BluetoothInterface.cpp
--- a/dom/bluetooth/BluetoothInterface.cpp
+++ b/dom/bluetooth/BluetoothInterface.cpp
@@ -90,46 +90,66 @@ BluetoothNotificationHandler::~Bluetooth
 
 // Interface
 //
 
 BluetoothInterface*
 BluetoothInterface::GetInstance()
 {
 #if ANDROID_VERSION >= 17
-  /* We pick a default backend from the available ones. The branches
-   * are ordered by preference.
+  /* We pick a default backend from the available ones. The options are
+   * ordered by preference. If a backend is supported but not available
+   * on the current system, we pick the next one. The selected default
+   * can be overriden manually by storing the respective string in the
+   * system property 'ro.moz.bluetooth.backend'.
    */
+
+  static const char* const sDefaultBackend[] = {
+#ifdef MOZ_B2G_BT_DAEMON
+    "bluetoothd",
+#endif
 #ifdef MOZ_B2G_BT_BLUEDROID
-  static const char sDefaultBackend[] = "bluedroid";
-#else
-#ifdef MOZ_B2G_BT_DAEMON
-  static const char sDefaultBackend[] = "bluetoothd";
-#else
-  static const char* const sDefaultBackend = nullptr;
+    "bluedroid",
 #endif
-#endif
+    nullptr // no default backend; must be final element in array
+  };
+
+  const char* defaultBackend;
+
+  for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDefaultBackend); ++i) {
+
+    /* select current backend */
+    defaultBackend = sDefaultBackend[i];
+
+    if (defaultBackend) {
+      if (!strcmp(defaultBackend, "bluetoothd") &&
+          access("/init.bluetooth.rc", F_OK) == -1) {
+        continue; /* bluetoothd not available */
+      }
+    }
+    break;
+  }
+
+  char value[PROPERTY_VALUE_MAX];
+  int len;
+
+  len = property_get("ro.moz.bluetooth.backend", value, defaultBackend);
+  if (len < 0) {
+    BT_WARNING("No Bluetooth backend available.");
+    return nullptr;
+  }
+
+  const nsDependentCString backend(value, len);
 
   /* Here's where we decide which implementation to use. Currently
    * there is only Bluedroid and the Bluetooth daemon, but others are
    * possible. Having multiple interfaces built-in and selecting the
    * correct one at runtime is also an option.
    */
 
-  char value[PROPERTY_VALUE_MAX];
-  int len;
-
-  len = property_get("ro.moz.bluetooth.backend", value, sDefaultBackend);
-  if (len < 0) {
-    BT_WARNING("No Bluetooth backend available.");
-    return nullptr;
-  }
-
-  const nsDependentCString backend(value, len);
-
 #ifdef MOZ_B2G_BT_BLUEDROID
   if (backend.LowerCaseEqualsLiteral("bluedroid")) {
     return BluetoothHALInterface::GetInstance();
   } else
 #endif
 #ifdef MOZ_B2G_BT_DAEMON
   if (backend.LowerCaseEqualsLiteral("bluetoothd")) {
     return BluetoothDaemonInterface::GetInstance();