Bug 791268 - Make dylib symbol binding retry, let bluetooth firmware shutdown still work even on error. r=echou, a=blocking-basecamp
authorKyle Machulis <kyle@nonpolynomial.com>
Fri, 02 Nov 2012 13:16:45 -0700
changeset 116631 1ad4fc08462dd7321a2a2a44a70ef7b1f966b658
parent 116630 ea28d6b8dbd80496ca342573a4c2cb410a25e5b3
child 116632 1240dc686edbce5c99b255f7fbe3dffb77f7dba5
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersechou, blocking-basecamp
bugs791268
milestone18.0a2
Bug 791268 - Make dylib symbol binding retry, let bluetooth firmware shutdown still work even on error. r=echou, a=blocking-basecamp
dom/bluetooth/gonk/BluetoothGonkService.cpp
--- a/dom/bluetooth/gonk/BluetoothGonkService.cpp
+++ b/dom/bluetooth/gonk/BluetoothGonkService.cpp
@@ -24,40 +24,34 @@
 #include "nsThreadUtils.h"
 #include <dlfcn.h>
 
 USING_BLUETOOTH_NAMESPACE
 
 static struct BluedroidFunctions
 {
   bool initialized;
-  bool tried_initialization;
 
   BluedroidFunctions() :
-    initialized(false),
-    tried_initialization(false)
+    initialized(false)
   {
   }
 
   int (* bt_enable)();
   int (* bt_disable)();
   int (* bt_is_enabled)();
 } sBluedroidFunctions;
 
-bool
+static bool
 EnsureBluetoothInit()
 {
-  if (sBluedroidFunctions.tried_initialization)
-  {
-    return sBluedroidFunctions.initialized;
+  if (sBluedroidFunctions.initialized) {
+    return true;
   }
 
-  sBluedroidFunctions.initialized = false;
-  sBluedroidFunctions.tried_initialization = true;
-  
   void* handle = dlopen("libbluedroid.so", RTLD_LAZY);
 
   if (!handle) {
     NS_ERROR("Failed to open libbluedroid.so, bluetooth cannot run");
     return false;
   }
 
   sBluedroidFunctions.bt_enable = (int (*)())dlsym(handle, "bt_enable");
@@ -70,62 +64,55 @@ EnsureBluetoothInit()
     NS_ERROR("Failed to attach bt_disable function");
     return false;
   }
   sBluedroidFunctions.bt_is_enabled = (int (*)())dlsym(handle, "bt_is_enabled");
   if (!sBluedroidFunctions.bt_is_enabled) {
     NS_ERROR("Failed to attach bt_is_enabled function");
     return false;
   }
+
   sBluedroidFunctions.initialized = true;
   return true;
 }
 
-int
-IsBluetoothEnabled()
-{
-  return sBluedroidFunctions.bt_is_enabled();
-}
-
-int
-EnableBluetooth()
-{
-  return sBluedroidFunctions.bt_enable();
-}
-
-int
-DisableBluetooth()
-{
-  return sBluedroidFunctions.bt_disable();
-}
-
-nsresult
+static nsresult
 StartStopGonkBluetooth(bool aShouldEnable)
 {
   bool result;
   
   // Platform specific check for gonk until object is divided in
   // different implementations per platform. Linux doesn't require
   // bluetooth firmware loading, but code should work otherwise.
   if (!EnsureBluetoothInit()) {
     NS_ERROR("Failed to load bluedroid library.\n");
     return NS_ERROR_FAILURE;
   }
 
   // return 1 if it's enabled, 0 if it's disabled, and -1 on error
-  int isEnabled = IsBluetoothEnabled();
+  int isEnabled = sBluedroidFunctions.bt_is_enabled();
 
   if ((isEnabled == 1 && aShouldEnable) || (isEnabled == 0 && !aShouldEnable)) {
-    result = true;
-  } else if (isEnabled < 0) {
-    result = false;
-  } else if (aShouldEnable) {
-    result = (EnableBluetooth() == 0) ? true : false;
+    return NS_OK;
+  }
+  if (aShouldEnable) {
+    result = (sBluedroidFunctions.bt_enable() == 0) ? true : false;
+    if (sBluedroidFunctions.bt_is_enabled() < 0) {
+      // if isEnabled < 0, this means we brought up the firmware, but something
+      // went wrong with bluetoothd. Post a warning message, but try to proceed
+      // with firmware unloading if that was requested, so we can retry later.
+      NS_WARNING("Bluetooth firmware up, but cannot connect to HCI socket! Check bluetoothd and try stopping/starting bluetooth again.");
+      // Just disable now, return an error.
+      if (sBluedroidFunctions.bt_disable() != 0) {
+        NS_WARNING("Problem shutting down bluetooth after error in bringup!");
+      }
+      return NS_ERROR_FAILURE;
+    }
   } else {
-    result = (DisableBluetooth() == 0) ? true : false;
+    result = (sBluedroidFunctions.bt_disable() == 0) ? true : false;
   }
   if (!result) {
     NS_WARNING("Could not set gonk bluetooth firmware!");
     return NS_ERROR_FAILURE;
   }
   
   return NS_OK;
 }