Backed out changeset bed325ace368 (bug 1203092)
authorNigel Babu <nigelbabu@gmail.com>
Tue, 15 Sep 2015 15:17:30 +0530
changeset 262584 999be83112ddcef40d85ef4a6a9082d29b55457e
parent 262583 bed325ace3688ccf8da0a35177f76026a1bced23
child 262585 2ead1d29f1b2d8ab2458956f6181ae37609129c6
push id29377
push userkwierso@gmail.com
push dateTue, 15 Sep 2015 23:56:04 +0000
treeherdermozilla-central@bd52dfa33582 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1203092
milestone43.0a1
backs outbed325ace3688ccf8da0a35177f76026a1bced23
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
Backed out changeset bed325ace368 (bug 1203092)
dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h
dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h
dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h
dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h
dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h
ipc/hal/DaemonSocketConsumer.h
ipc/hal/DaemonSocketPDU.cpp
ipc/hal/DaemonSocketPDU.h
--- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
@@ -23,34 +23,45 @@ BluetoothA2dpNotificationHandler*
 
 void
 BluetoothDaemonA2dpModule::SetNotificationHandler(
   BluetoothA2dpNotificationHandler* aNotificationHandler)
 {
   sNotificationHandler = aNotificationHandler;
 }
 
+nsresult
+BluetoothDaemonA2dpModule::Send(DaemonSocketPDU* aPDU,
+                                BluetoothA2dpResultHandler* aRes)
+{
+  nsRefPtr<BluetoothA2dpResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
+}
+
 void
 BluetoothDaemonA2dpModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                                     DaemonSocketPDU& aPDU,
-                                     DaemonSocketResultHandler* aRes)
+                                     DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonA2dpModule::* const HandleOp[])(
-    const DaemonSocketPDUHeader&, DaemonSocketPDU&,
-    DaemonSocketResultHandler*) = {
+    const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
     [0] = &BluetoothDaemonA2dpModule::HandleRsp,
     [1] = &BluetoothDaemonA2dpModule::HandleNtf
   };
 
   MOZ_ASSERT(!NS_IsMainThread());
 
   // negate twice to map bit to 0/1
   unsigned int isNtf = !!(aHeader.mOpcode & 0x80);
 
-  (this->*(HandleOp[isNtf]))(aHeader, aPDU, aRes);
+  (this->*(HandleOp[isNtf]))(aHeader, aPDU, aUserData);
 }
 
 // Commands
 //
 
 nsresult
 BluetoothDaemonA2dpModule::ConnectCmd(
   const nsAString& aRemoteAddr, BluetoothA2dpResultHandler* aRes)
@@ -123,17 +134,17 @@ BluetoothDaemonA2dpModule::DisconnectRsp
 {
   ResultRunnable::Dispatch(
     aRes, &BluetoothA2dpResultHandler::Disconnect, UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonA2dpModule::HandleRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
   static void (BluetoothDaemonA2dpModule::* const HandleRsp[])(
     const DaemonSocketPDUHeader&,
     DaemonSocketPDU&,
     BluetoothA2dpResultHandler*) = {
     [OPCODE_ERROR] = &BluetoothDaemonA2dpModule::ErrorRsp,
     [OPCODE_CONNECT] = &BluetoothDaemonA2dpModule::ConnectRsp,
     [OPCODE_DISCONNECT] = &BluetoothDaemonA2dpModule::DisconnectRsp
@@ -142,17 +153,18 @@ BluetoothDaemonA2dpModule::HandleRsp(
   MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
   if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
       NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
     return;
   }
 
   nsRefPtr<BluetoothA2dpResultHandler> res =
-    static_cast<BluetoothA2dpResultHandler*>(aRes);
+    already_AddRefed<BluetoothA2dpResultHandler>(
+      static_cast<BluetoothA2dpResultHandler*>(aUserData));
 
   if (!res) {
     return; // Return early if no result handler has been set for response
   }
 
   (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
 }
 
@@ -298,17 +310,17 @@ BluetoothDaemonA2dpModule::AudioConfigNt
   AudioConfigNotification::Dispatch(
     &BluetoothA2dpNotificationHandler::AudioConfigNotification,
     AudioConfigInitOp(aPDU));
 }
 
 void
 BluetoothDaemonA2dpModule::HandleNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
   static void (BluetoothDaemonA2dpModule::* const HandleNtf[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
     [0] = &BluetoothDaemonA2dpModule::ConnectionStateNtf,
     [1] = &BluetoothDaemonA2dpModule::AudioStateNtf,
 #if ANDROID_VERSION >= 21
     [2] = &BluetoothDaemonA2dpModule::AudioConfigNtf
 #endif
--- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h
@@ -10,17 +10,16 @@
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothInterface.h"
 #include "mozilla/ipc/DaemonRunnables.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 using mozilla::ipc::DaemonSocketPDU;
 using mozilla::ipc::DaemonSocketPDUHeader;
-using mozilla::ipc::DaemonSocketResultHandler;
 
 class BluetoothSetupResultHandler;
 
 class BluetoothDaemonA2dpModule
 {
 public:
   enum {
     SERVICE_ID = 0x06
@@ -29,18 +28,17 @@ public:
   enum {
     OPCODE_ERROR = 0x00,
     OPCODE_CONNECT = 0x01,
     OPCODE_DISCONNECT = 0x02
   };
 
   static const int MAX_NUM_CLIENTS;
 
-  virtual nsresult Send(DaemonSocketPDU* aPDU,
-                        DaemonSocketResultHandler* aRes) = 0;
+  virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
 
   virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
                                   uint32_t aMaxNumClients,
                                   BluetoothSetupResultHandler* aRes) = 0;
 
   virtual nsresult UnregisterModule(uint8_t aId,
                                     BluetoothSetupResultHandler* aRes) = 0;
 
@@ -52,18 +50,21 @@ public:
   //
 
   nsresult ConnectCmd(const nsAString& aBdAddr,
                       BluetoothA2dpResultHandler* aRes);
   nsresult DisconnectCmd(const nsAString& aBdAddr,
                          BluetoothA2dpResultHandler* aRes);
 
 protected:
+  nsresult Send(DaemonSocketPDU* aPDU,
+                BluetoothA2dpResultHandler* aRes);
+
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
+                 DaemonSocketPDU& aPDU, void* aUserData);
 
   //
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
     BluetoothA2dpResultHandler, void>
     ResultRunnable;
@@ -81,17 +82,17 @@ protected:
                   BluetoothA2dpResultHandler* aRes);
 
   void DisconnectRsp(const DaemonSocketPDUHeader& aHeader,
                      DaemonSocketPDU& aPDU,
                      BluetoothA2dpResultHandler* aRes);
 
   void HandleRsp(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 void* aUserData);
 
   //
   // Notifications
   //
 
   class NotificationHandlerWrapper;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
@@ -119,17 +120,17 @@ protected:
   void AudioStateNtf(const DaemonSocketPDUHeader& aHeader,
                      DaemonSocketPDU& aPDU);
 
   void AudioConfigNtf(const DaemonSocketPDUHeader& aHeader,
                       DaemonSocketPDU& aPDU);
 
   void HandleNtf(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 void* aUserData);
 
   static BluetoothA2dpNotificationHandler* sNotificationHandler;
 };
 
 class BluetoothDaemonA2dpInterface final
   : public BluetoothA2dpInterface
 {
   class CleanupResultHandler;
--- a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
@@ -23,33 +23,44 @@ BluetoothAvrcpNotificationHandler*
 
 void
 BluetoothDaemonAvrcpModule::SetNotificationHandler(
   BluetoothAvrcpNotificationHandler* aNotificationHandler)
 {
   sNotificationHandler = aNotificationHandler;
 }
 
+nsresult
+BluetoothDaemonAvrcpModule::Send(DaemonSocketPDU* aPDU,
+                                 BluetoothAvrcpResultHandler* aRes)
+{
+  nsRefPtr<BluetoothAvrcpResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
+}
+
 void
 BluetoothDaemonAvrcpModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                                      DaemonSocketPDU& aPDU,
-                                      DaemonSocketResultHandler* aRes)
+                                      DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonAvrcpModule::* const HandleOp[])(
-    const DaemonSocketPDUHeader&, DaemonSocketPDU&,
-    DaemonSocketResultHandler*) = {
+    const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
     [0] = &BluetoothDaemonAvrcpModule::HandleRsp,
     [1] = &BluetoothDaemonAvrcpModule::HandleNtf
   };
 
   MOZ_ASSERT(!NS_IsMainThread());
 
   unsigned int isNtf = !!(aHeader.mOpcode & 0x80);
 
-  (this->*(HandleOp[isNtf]))(aHeader, aPDU, aRes);
+  (this->*(HandleOp[isNtf]))(aHeader, aPDU, aUserData);
 }
 
 // Commands
 //
 
 nsresult
 BluetoothDaemonAvrcpModule::GetPlayStatusRspCmd(
   ControlPlayStatus aPlayStatus, uint32_t aSongLen, uint32_t aSongPos,
@@ -405,17 +416,17 @@ BluetoothDaemonAvrcpModule::SetVolumeRsp
   ResultRunnable::Dispatch(
     aRes, &BluetoothAvrcpResultHandler::SetVolume,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonAvrcpModule::HandleRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
   static void (BluetoothDaemonAvrcpModule::* const HandleRsp[])(
     const DaemonSocketPDUHeader&,
     DaemonSocketPDU&,
     BluetoothAvrcpResultHandler*) = {
     [OPCODE_ERROR] =
       &BluetoothDaemonAvrcpModule::ErrorRsp,
     [OPCODE_GET_PLAY_STATUS_RSP] =
@@ -443,17 +454,18 @@ BluetoothDaemonAvrcpModule::HandleRsp(
   MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
   if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
       NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
     return;
   }
 
   nsRefPtr<BluetoothAvrcpResultHandler> res =
-    static_cast<BluetoothAvrcpResultHandler*>(aRes);
+    already_AddRefed<BluetoothAvrcpResultHandler>(
+      static_cast<BluetoothAvrcpResultHandler*>(aUserData));
 
   if (!res) {
     return; // Return early if no result handler has been set for response
   }
 
   (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
 }
 
@@ -775,17 +787,17 @@ BluetoothDaemonAvrcpModule::PassthroughC
     &BluetoothAvrcpNotificationHandler::PassthroughCmdNotification,
     PassthroughCmdInitOp(aPDU));
 }
 #endif
 
 void
 BluetoothDaemonAvrcpModule::HandleNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
   static void (BluetoothDaemonAvrcpModule::* const HandleNtf[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
 #if ANDROID_VERSION >= 19
     [0] = &BluetoothDaemonAvrcpModule::RemoteFeatureNtf,
     [1] = &BluetoothDaemonAvrcpModule::GetPlayStatusNtf,
     [2] = &BluetoothDaemonAvrcpModule::ListPlayerAppAttrNtf,
     [3] = &BluetoothDaemonAvrcpModule::ListPlayerAppValuesNtf,
--- a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h
@@ -10,17 +10,16 @@
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothInterface.h"
 #include "mozilla/ipc/DaemonRunnables.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 using mozilla::ipc::DaemonSocketPDU;
 using mozilla::ipc::DaemonSocketPDUHeader;
-using mozilla::ipc::DaemonSocketResultHandler;
 
 class BluetoothSetupResultHandler;
 
 class BluetoothDaemonAvrcpModule
 {
 public:
   enum {
     SERVICE_ID = 0x08
@@ -61,18 +60,17 @@ public:
     OPCODE_SET_PLAYER_APP_VALUE_NTF = 0x87,
     OPCODE_GET_ELEMENT_ATTR_NTF = 0x88,
     OPCODE_REGISTER_NOTIFICATION_NTF = 0x89
 #endif
   };
 
   static const int MAX_NUM_CLIENTS;
 
-  virtual nsresult Send(DaemonSocketPDU* aPDU,
-                        DaemonSocketResultHandler* aRes) = 0;
+  virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
 
   virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
                                   uint32_t aMaxNumClients,
                                   BluetoothSetupResultHandler* aRes) = 0;
 
   virtual nsresult UnregisterModule(uint8_t aId,
                                     BluetoothSetupResultHandler* aRes) = 0;
 
@@ -116,18 +114,21 @@ public:
   nsresult RegisterNotificationRspCmd(
     BluetoothAvrcpEvent aEvent, BluetoothAvrcpNotification aType,
     const BluetoothAvrcpNotificationParam& aParam,
     BluetoothAvrcpResultHandler* aRes);
 
   nsresult SetVolumeCmd(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes);
 
 protected:
+  nsresult Send(DaemonSocketPDU* aPDU,
+                BluetoothAvrcpResultHandler* aRes);
+
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
+                 DaemonSocketPDU& aPDU, void* aUserData);
 
   //
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
     BluetoothAvrcpResultHandler, void>
     ResultRunnable;
@@ -177,17 +178,17 @@ protected:
                                   BluetoothAvrcpResultHandler* aRes);
 
   void SetVolumeRsp(const DaemonSocketPDUHeader& aHeader,
                     DaemonSocketPDU& aPDU,
                     BluetoothAvrcpResultHandler* aRes);
 
   void HandleRsp(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 void* aUserData);
 
   //
   // Notifications
   //
 
   class NotificationHandlerWrapper;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
@@ -287,17 +288,17 @@ protected:
   void VolumeChangeNtf(const DaemonSocketPDUHeader& aHeader,
                        DaemonSocketPDU& aPDU);
 
   void PassthroughCmdNtf(const DaemonSocketPDUHeader& aHeader,
                          DaemonSocketPDU& aPDU);
 
   void HandleNtf(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 void* aUserData);
 
   static BluetoothAvrcpNotificationHandler* sNotificationHandler;
 };
 
 class BluetoothDaemonAvrcpInterface final
   : public BluetoothAvrcpInterface
 {
   class CleanupResultHandler;
--- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
@@ -23,34 +23,45 @@ BluetoothGattNotificationHandler*
 
 void
 BluetoothDaemonGattModule::SetNotificationHandler(
   BluetoothGattNotificationHandler* aNotificationHandler)
 {
   sNotificationHandler = aNotificationHandler;
 }
 
+nsresult
+BluetoothDaemonGattModule::Send(DaemonSocketPDU* aPDU,
+                                BluetoothGattResultHandler* aRes)
+{
+  nsRefPtr<BluetoothGattResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
+}
+
 void
 BluetoothDaemonGattModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                                     DaemonSocketPDU& aPDU,
-                                     DaemonSocketResultHandler* aRes)
+                                     DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonGattModule::* const HandleOp[])(
-    const DaemonSocketPDUHeader&, DaemonSocketPDU&,
-    DaemonSocketResultHandler*) = {
+    const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
     [0] = &BluetoothDaemonGattModule::HandleRsp,
     [1] = &BluetoothDaemonGattModule::HandleNtf
   };
 
   MOZ_ASSERT(!NS_IsMainThread());
 
   // Negate twice to map bit to 0/1
   unsigned long isNtf = !!(aHeader.mOpcode & 0x80);
 
-  (this->*(HandleOp[isNtf]))(aHeader, aPDU, aRes);
+  (this->*(HandleOp[isNtf]))(aHeader, aPDU, aUserData);
 }
 
 // Commands
 //
 
 nsresult
 BluetoothDaemonGattModule::ClientRegisterCmd(
   const BluetoothUuid& aUuid, BluetoothGattResultHandler* aRes)
@@ -1389,17 +1400,17 @@ BluetoothDaemonGattModule::ServerSendRes
   ResultRunnable::Dispatch(
     aRes, &BluetoothGattResultHandler::SendResponse,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::HandleRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
   static void (BluetoothDaemonGattModule::* const HandleRsp[])(
     const DaemonSocketPDUHeader&,
     DaemonSocketPDU&,
     BluetoothGattResultHandler*) = {
     [OPCODE_ERROR] =
       &BluetoothDaemonGattModule::ErrorRsp,
     [OPCODE_CLIENT_REGISTER] =
@@ -1477,17 +1488,18 @@ BluetoothDaemonGattModule::HandleRsp(
   MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
   if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
       NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
     return;
   }
 
   nsRefPtr<BluetoothGattResultHandler> res =
-    static_cast<BluetoothGattResultHandler*>(aRes);
+    already_AddRefed<BluetoothGattResultHandler>(
+      static_cast<BluetoothGattResultHandler*>(aUserData));
 
   if (!res) {
     return;
   } // Return early if no result handler has been set for response
 
   (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
 }
 
@@ -2135,17 +2147,17 @@ BluetoothDaemonGattModule::ServerRespons
   ServerResponseConfirmationNotification::Dispatch(
     &BluetoothGattNotificationHandler::ResponseConfirmationNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::HandleNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
   static void (BluetoothDaemonGattModule::* const HandleNtf[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
     [0] = &BluetoothDaemonGattModule::ClientRegisterNtf,
     [1] = &BluetoothDaemonGattModule::ClientScanResultNtf,
     [2] = &BluetoothDaemonGattModule::ClientConnectNtf,
     [3] = &BluetoothDaemonGattModule::ClientDisconnectNtf,
     [4] = &BluetoothDaemonGattModule::ClientSearchCompleteNtf,
--- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h
@@ -10,17 +10,16 @@
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothInterface.h"
 #include "mozilla/ipc/DaemonRunnables.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 using mozilla::ipc::DaemonSocketPDU;
 using mozilla::ipc::DaemonSocketPDUHeader;
-using mozilla::ipc::DaemonSocketResultHandler;
 
 class BluetoothSetupResultHandler;
 
 class BluetoothDaemonGattModule
 {
 public:
   enum {
     SERVICE_ID = 0x09
@@ -63,18 +62,17 @@ public:
     OPCODE_SERVER_DELETE_SERVICE = 0x21,
     OPCODE_SERVER_SEND_INDICATION = 0x22,
     OPCODE_SERVER_SEND_RESPONSE = 0x23
     // TODO: Add L support
   };
 
   static const int MAX_NUM_CLIENTS;
 
-  virtual nsresult Send(DaemonSocketPDU* aPDU,
-                        DaemonSocketResultHandler* aRes) = 0;
+  virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
 
   virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
                                   uint32_t aMaxNumClients,
                                   BluetoothSetupResultHandler* aRes) = 0;
 
   virtual nsresult UnregisterModule(uint8_t aId,
                                     BluetoothSetupResultHandler* aRes) = 0;
 
@@ -297,18 +295,21 @@ public:
   nsresult ServerSendResponseCmd(int aConnId,
                                  int aTransId,
                                  BluetoothGattStatus aStatus,
                                  const BluetoothGattResponse& aResponse,
                                  BluetoothGattResultHandler* aRes);
   // TODO: Add L support
 
 protected:
+  nsresult Send(DaemonSocketPDU* aPDU,
+                BluetoothGattResultHandler* aRes);
+
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
+                 DaemonSocketPDU& aPDU, void* aUserData);
 
   //
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
     BluetoothGattResultHandler, void>
     ResultRunnable;
@@ -465,17 +466,17 @@ protected:
   void ServerSendResponseRsp(const DaemonSocketPDUHeader& aHeader,
                              DaemonSocketPDU& aPDU,
                              BluetoothGattResultHandler* aRes);
 
   // TODO: Add L support
 
   void HandleRsp(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 void* aUserData);
 
   //
   // Notifications
   //
 
   class NotificationHandlerWrapper;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
@@ -764,17 +765,17 @@ protected:
 
   void ServerResponseConfirmationNtf(const DaemonSocketPDUHeader& aHeader,
                                      DaemonSocketPDU& aPDU);
 
   // TODO: Add L support
 
   void HandleNtf(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 void* aUserData);
 
   static BluetoothGattNotificationHandler* sNotificationHandler;
 };
 
 class BluetoothDaemonGattInterface final
   : public BluetoothGattInterface
 {
   class CleanupResultHandler;
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
@@ -26,34 +26,45 @@ nsString BluetoothDaemonHandsfreeModule:
 
 void
 BluetoothDaemonHandsfreeModule::SetNotificationHandler(
   BluetoothHandsfreeNotificationHandler* aNotificationHandler)
 {
   sNotificationHandler = aNotificationHandler;
 }
 
+nsresult
+BluetoothDaemonHandsfreeModule::Send(DaemonSocketPDU* aPDU,
+                                     BluetoothHandsfreeResultHandler* aRes)
+{
+  nsRefPtr<BluetoothHandsfreeResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
+}
+
 void
 BluetoothDaemonHandsfreeModule::HandleSvc(
-  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonHandsfreeModule::* const HandleOp[])(
-    const DaemonSocketPDUHeader&, DaemonSocketPDU&,
-    DaemonSocketResultHandler*) = {
+    const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
     [0] = &BluetoothDaemonHandsfreeModule::HandleRsp,
     [1] = &BluetoothDaemonHandsfreeModule::HandleNtf
   };
 
   MOZ_ASSERT(!NS_IsMainThread());
 
   // Negate twice to map bit to 0/1
   unsigned long isNtf = !!(aHeader.mOpcode & 0x80);
 
-  (this->*(HandleOp[isNtf]))(aHeader, aPDU, aRes);
+  (this->*(HandleOp[isNtf]))(aHeader, aPDU, aUserData);
 }
 
 // Commands
 //
 
 nsresult
 BluetoothDaemonHandsfreeModule::ConnectCmd(
   const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
@@ -663,17 +674,17 @@ BluetoothDaemonHandsfreeModule::Configur
   ResultRunnable::Dispatch(
     aRes, &BluetoothHandsfreeResultHandler::ConfigureWbs,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonHandsfreeModule::HandleRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
   static void (BluetoothDaemonHandsfreeModule::* const HandleRsp[])(
     const DaemonSocketPDUHeader&,
     DaemonSocketPDU&,
     BluetoothHandsfreeResultHandler*) = {
     [OPCODE_ERROR] =
       &BluetoothDaemonHandsfreeModule::ErrorRsp,
     [OPCODE_CONNECT] =
@@ -711,17 +722,18 @@ BluetoothDaemonHandsfreeModule::HandleRs
   MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
   if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
       NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
     return;
   }
 
   nsRefPtr<BluetoothHandsfreeResultHandler> res =
-    static_cast<BluetoothHandsfreeResultHandler*>(aRes);
+    already_AddRefed<BluetoothHandsfreeResultHandler>(
+      static_cast<BluetoothHandsfreeResultHandler*>(aUserData));
 
   if (!res) {
     return; // Return early if no result handler has been set for response
   }
 
   (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
 }
 
@@ -1446,17 +1458,17 @@ BluetoothDaemonHandsfreeModule::WbsNtf(
   WbsNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::WbsNotification,
     WbsInitOp(aPDU));
 }
 
 void
 BluetoothDaemonHandsfreeModule::HandleNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
   static void (BluetoothDaemonHandsfreeModule::* const HandleNtf[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
     [0] = &BluetoothDaemonHandsfreeModule::ConnectionStateNtf,
     [1] = &BluetoothDaemonHandsfreeModule::AudioStateNtf,
     [2] = &BluetoothDaemonHandsfreeModule::VoiceRecognitionNtf,
     [3] = &BluetoothDaemonHandsfreeModule::AnswerCallNtf,
     [4] = &BluetoothDaemonHandsfreeModule::HangupCallNtf,
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h
@@ -10,17 +10,16 @@
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothInterface.h"
 #include "mozilla/ipc/DaemonRunnables.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 using mozilla::ipc::DaemonSocketPDU;
 using mozilla::ipc::DaemonSocketPDUHeader;
-using mozilla::ipc::DaemonSocketResultHandler;
 
 class BluetoothSetupResultHandler;
 
 class BluetoothDaemonHandsfreeModule
 {
 public:
   enum {
     SERVICE_ID = 0x05
@@ -40,18 +39,17 @@ public:
     OPCODE_CIND_RESPONSE = 0x0a,
     OPCODE_FORMATTED_AT_RESPONSE = 0x0b,
     OPCODE_AT_RESPONSE = 0x0c,
     OPCODE_CLCC_RESPONSE = 0x0d,
     OPCODE_PHONE_STATE_CHANGE = 0x0e,
     OPCODE_CONFIGURE_WBS = 0x0f
   };
 
-  virtual nsresult Send(DaemonSocketPDU* aPDU,
-                        DaemonSocketResultHandler* aRes) = 0;
+  virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
 
   virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
                                   uint32_t aMaxNumClients,
                                   BluetoothSetupResultHandler* aRes) = 0;
 
   virtual nsresult UnregisterModule(uint8_t aId,
                                     BluetoothSetupResultHandler* aRes) = 0;
 
@@ -125,19 +123,21 @@ public:
 
   /* Wide Band Speech */
 
   nsresult ConfigureWbsCmd(const nsAString& aBdAddr,
                            BluetoothHandsfreeWbsConfig aConfig,
                            BluetoothHandsfreeResultHandler* aRes);
 
 protected:
+  nsresult Send(DaemonSocketPDU* aPDU,
+                BluetoothHandsfreeResultHandler* aRes);
+
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 DaemonSocketPDU& aPDU, void* aUserData);
 
   //
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
     BluetoothHandsfreeResultHandler, void>
     ResultRunnable;
@@ -207,17 +207,17 @@ protected:
                            BluetoothHandsfreeResultHandler* aRes);
 
   void ConfigureWbsRsp(const DaemonSocketPDUHeader& aHeader,
                        DaemonSocketPDU& aPDU,
                        BluetoothHandsfreeResultHandler* aRes);
 
   void HandleRsp(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 void* aUserData);
 
   //
   // Notifications
   //
 
   class NotificationHandlerWrapper;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
@@ -364,17 +364,17 @@ protected:
   void KeyPressedNtf(const DaemonSocketPDUHeader& aHeader,
                      DaemonSocketPDU& aPDU);
 
   void WbsNtf(const DaemonSocketPDUHeader& aHeader,
               DaemonSocketPDU& aPDU);
 
   void HandleNtf(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
-                 DaemonSocketResultHandler* aRes);
+                 void* aUserData);
 
   static BluetoothHandsfreeNotificationHandler* sNotificationHandler;
 #if ANDROID_VERSION < 21
   /* |sConnectedDeviceAddress| stores Bluetooth device address of the
    * connected device. Before BlueZ 5.25, we maintain this address by ourselves
    * through ConnectionStateNtf(); after BlueZ 5.25, every callback carries
    * this address directly so we don't have to keep it.
    */
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -29,18 +29,17 @@ static const int sRetryInterval = 100; /
 
 //
 // Protocol initialization and setup
 //
 
 class BluetoothDaemonSetupModule
 {
 public:
-  virtual nsresult Send(DaemonSocketPDU* aPDU,
-                        DaemonSocketResultHandler* aRes) = 0;
+  virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
 
   // Commands
   //
 
   nsresult RegisterModuleCmd(uint8_t aId, uint8_t aMode,
                              uint32_t aMaxNumClients,
                              BluetoothSetupResultHandler* aRes)
   {
@@ -103,17 +102,17 @@ public:
     return rv;
   }
 
 protected:
 
   // Called to handle PDUs with Service field equal to 0x00, which
   // contains internal operations for setup and configuration.
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes)
+                 DaemonSocketPDU& aPDU, void* aUserData)
   {
     static void (BluetoothDaemonSetupModule::* const HandleRsp[])(
       const DaemonSocketPDUHeader&,
       DaemonSocketPDU&,
       BluetoothSetupResultHandler*) = {
       [0x00] = &BluetoothDaemonSetupModule::ErrorRsp,
       [0x01] = &BluetoothDaemonSetupModule::RegisterModuleRsp,
       [0x02] = &BluetoothDaemonSetupModule::UnregisterModuleRsp,
@@ -121,25 +120,37 @@ protected:
     };
 
     if (NS_WARN_IF(aHeader.mOpcode >= MOZ_ARRAY_LENGTH(HandleRsp)) ||
         NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
       return;
     }
 
     nsRefPtr<BluetoothSetupResultHandler> res =
-      static_cast<BluetoothSetupResultHandler*>(aRes);
+      already_AddRefed<BluetoothSetupResultHandler>(
+        static_cast<BluetoothSetupResultHandler*>(aUserData));
 
-    if (!aRes) {
+    if (!res) {
       return; // Return early if no result handler has been set
     }
 
     (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
   }
 
+  nsresult Send(DaemonSocketPDU* aPDU, BluetoothSetupResultHandler* aRes)
+  {
+    nsRefPtr<BluetoothSetupResultHandler> res(aRes);
+    nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    unused << res.forget(); // Keep reference for response
+    return NS_OK;
+  }
+
 private:
 
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
     BluetoothSetupResultHandler, void>
     ResultRunnable;
@@ -195,18 +206,17 @@ private:
 static BluetoothNotificationHandler* sNotificationHandler;
 
 class BluetoothDaemonCoreModule
 {
 public:
 
   static const int MAX_NUM_CLIENTS;
 
-  virtual nsresult Send(DaemonSocketPDU* aPDU,
-                        DaemonSocketResultHandler* aRes) = 0;
+  virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
 
   nsresult EnableCmd(BluetoothResultHandler* aRes)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x01, 0));
 
     nsresult rv = Send(pdu, aRes);
@@ -585,28 +595,38 @@ public:
     }
     unused << pdu.forget();
     return rv;
   }
 
 protected:
 
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes)
+                 DaemonSocketPDU& aPDU, void* aUserData)
   {
     static void (BluetoothDaemonCoreModule::* const HandleOp[])(
-      const DaemonSocketPDUHeader&, DaemonSocketPDU&,
-      DaemonSocketResultHandler*) = {
+      const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
       [0] = &BluetoothDaemonCoreModule::HandleRsp,
       [1] = &BluetoothDaemonCoreModule::HandleNtf
     };
 
     MOZ_ASSERT(!NS_IsMainThread());
 
-    (this->*(HandleOp[!!(aHeader.mOpcode & 0x80)]))(aHeader, aPDU, aRes);
+    (this->*(HandleOp[!!(aHeader.mOpcode & 0x80)]))(aHeader, aPDU, aUserData);
+  }
+
+  nsresult Send(DaemonSocketPDU* aPDU, BluetoothResultHandler* aRes)
+  {
+    nsRefPtr<BluetoothResultHandler> res(aRes);
+    nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    unused << res.forget(); // Keep reference for response
+    return NS_OK;
   }
 
 private:
 
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
@@ -800,17 +820,17 @@ private:
                      BluetoothResultHandler* aRes)
   {
     ResultRunnable::Dispatch(
       aRes, &BluetoothResultHandler::LeTestMode,
       UnpackPDUInitOp(aPDU));
   }
 
   void HandleRsp(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes)
+                 DaemonSocketPDU& aPDU, void* aUserData)
   {
     static void (BluetoothDaemonCoreModule::* const HandleRsp[])(
       const DaemonSocketPDUHeader&,
       DaemonSocketPDU&,
       BluetoothResultHandler*) = {
       [0x00] = &BluetoothDaemonCoreModule::ErrorRsp,
       [0x01] = &BluetoothDaemonCoreModule::EnableRsp,
       [0x02] = &BluetoothDaemonCoreModule::DisableRsp,
@@ -837,17 +857,18 @@ private:
     MOZ_ASSERT(!NS_IsMainThread());
 
     if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
         NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
       return;
     }
 
     nsRefPtr<BluetoothResultHandler> res =
-      static_cast<BluetoothResultHandler*>(aRes);
+      already_AddRefed<BluetoothResultHandler>(
+        static_cast<BluetoothResultHandler*>(aUserData));
 
     if (!res) {
       return; // Return early if no result handler has been set for response
     }
 
     (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
   }
 
@@ -1319,17 +1340,17 @@ private:
                      DaemonSocketPDU& aPDU)
   {
     LeTestModeNotification::Dispatch(
       &BluetoothNotificationHandler::LeTestModeNotification,
       UnpackPDUInitOp(aPDU));
   }
 
   void HandleNtf(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes)
+                 DaemonSocketPDU& aPDU, void* aUserData)
   {
     static void (BluetoothDaemonCoreModule::* const HandleNtf[])(
       const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
       [0] = &BluetoothDaemonCoreModule::AdapterStateChangedNtf,
       [1] = &BluetoothDaemonCoreModule::AdapterPropertiesNtf,
       [2] = &BluetoothDaemonCoreModule::RemoteDevicePropertiesNtf,
       [3] = &BluetoothDaemonCoreModule::DeviceFoundNtf,
       [4] = &BluetoothDaemonCoreModule::DiscoveryStateChangedNtf,
@@ -1427,54 +1448,45 @@ public:
                           BluetoothSetupResultHandler* aRes) override;
 
   nsresult UnregisterModule(uint8_t aId,
                             BluetoothSetupResultHandler* aRes) override;
 
   // Outgoing PDUs
   //
 
-  nsresult Send(DaemonSocketPDU* aPDU,
-                DaemonSocketResultHandler* aRes) override;
+  nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) override;
 
-  void StoreResultHandler(const DaemonSocketPDU& aPDU) override;
+  void StoreUserData(const DaemonSocketPDU& aPDU) override;
 
   // Incoming PUDs
   //
 
   void Handle(DaemonSocketPDU& aPDU) override;
 
-  already_AddRefed<DaemonSocketResultHandler> FetchResultHandler(
-    const DaemonSocketPDUHeader& aHeader);
+  void* FetchUserData(const DaemonSocketPDUHeader& aHeader);
 
 private:
   void HandleSetupSvc(const DaemonSocketPDUHeader& aHeader,
-                      DaemonSocketPDU& aPDU,
-                      DaemonSocketResultHandler* aRes);
+                      DaemonSocketPDU& aPDU, void* aUserData);
   void HandleCoreSvc(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU,
-                     DaemonSocketResultHandler* aRes);
+                     DaemonSocketPDU& aPDU, void* aUserData);
   void HandleSocketSvc(const DaemonSocketPDUHeader& aHeader,
-                       DaemonSocketPDU& aPDU,
-                       DaemonSocketResultHandler* aRes);
+                       DaemonSocketPDU& aPDU, void* aUserData);
   void HandleHandsfreeSvc(const DaemonSocketPDUHeader& aHeader,
-                          DaemonSocketPDU& aPDU,
-                          DaemonSocketResultHandler* aRes);
+                          DaemonSocketPDU& aPDU, void* aUserData);
   void HandleA2dpSvc(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU,
-                     DaemonSocketResultHandler* aUserData);
+                     DaemonSocketPDU& aPDU, void* aUserData);
   void HandleAvrcpSvc(const DaemonSocketPDUHeader& aHeader,
-                      DaemonSocketPDU& aPDU,
-                      DaemonSocketResultHandler* aRes);
+                      DaemonSocketPDU& aPDU, void* aUserData);
   void HandleGattSvc(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU,
-                     DaemonSocketResultHandler* aRes);
+                     DaemonSocketPDU& aPDU, void* aUserData);
 
   DaemonSocket* mConnection;
-  nsTArray<nsRefPtr<DaemonSocketResultHandler>> mResQ;
+  nsTArray<void*> mUserDataQ;
 };
 
 BluetoothDaemonProtocol::BluetoothDaemonProtocol()
 { }
 
 void
 BluetoothDaemonProtocol::SetConnection(DaemonSocket* aConnection)
 {
@@ -1493,98 +1505,96 @@ BluetoothDaemonProtocol::RegisterModule(
 nsresult
 BluetoothDaemonProtocol::UnregisterModule(uint8_t aId,
                                           BluetoothSetupResultHandler* aRes)
 {
   return BluetoothDaemonSetupModule::UnregisterModuleCmd(aId, aRes);
 }
 
 nsresult
-BluetoothDaemonProtocol::Send(DaemonSocketPDU* aPDU,
-                              DaemonSocketResultHandler* aRes)
+BluetoothDaemonProtocol::Send(DaemonSocketPDU* aPDU, void* aUserData)
 {
   MOZ_ASSERT(mConnection);
   MOZ_ASSERT(aPDU);
 
   aPDU->SetConsumer(this);
-  aPDU->SetResultHandler(aRes);
+  aPDU->SetUserData(aUserData);
   aPDU->UpdateHeader();
 
   if (mConnection->GetConnectionStatus() == SOCKET_DISCONNECTED) {
     BT_LOGR("Connection to Bluetooth daemon is closed.");
     return NS_ERROR_FAILURE;
   }
 
   mConnection->SendSocketData(aPDU); // Forward PDU to command channel
 
   return NS_OK;
 }
 
 void
 BluetoothDaemonProtocol::HandleSetupSvc(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
-  BluetoothDaemonSetupModule::HandleSvc(aHeader, aPDU, aRes);
+  BluetoothDaemonSetupModule::HandleSvc(aHeader, aPDU, aUserData);
 }
 
 void
 BluetoothDaemonProtocol::HandleCoreSvc(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
-  BluetoothDaemonCoreModule::HandleSvc(aHeader, aPDU, aRes);
+  BluetoothDaemonCoreModule::HandleSvc(aHeader, aPDU, aUserData);
 }
 
 void
 BluetoothDaemonProtocol::HandleSocketSvc(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
-  BluetoothDaemonSocketModule::HandleSvc(aHeader, aPDU, aRes);
+  BluetoothDaemonSocketModule::HandleSvc(aHeader, aPDU, aUserData);
 }
 
 void
 BluetoothDaemonProtocol::HandleHandsfreeSvc(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
-  BluetoothDaemonHandsfreeModule::HandleSvc(aHeader, aPDU, aRes);
+  BluetoothDaemonHandsfreeModule::HandleSvc(aHeader, aPDU, aUserData);
 }
 
 void
 BluetoothDaemonProtocol::HandleA2dpSvc(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
-  BluetoothDaemonA2dpModule::HandleSvc(aHeader, aPDU, aRes);
+  BluetoothDaemonA2dpModule::HandleSvc(aHeader, aPDU, aUserData);
 }
 
 void
 BluetoothDaemonProtocol::HandleAvrcpSvc(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
-  BluetoothDaemonAvrcpModule::HandleSvc(aHeader, aPDU, aRes);
+  BluetoothDaemonAvrcpModule::HandleSvc(aHeader, aPDU, aUserData);
 }
 
 void
 BluetoothDaemonProtocol::HandleGattSvc(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  DaemonSocketResultHandler* aRes)
+  void* aUserData)
 {
-  BluetoothDaemonGattModule::HandleSvc(aHeader, aPDU, aRes);
+  BluetoothDaemonGattModule::HandleSvc(aHeader, aPDU, aUserData);
 }
 
 void
 BluetoothDaemonProtocol::Handle(DaemonSocketPDU& aPDU)
 {
   static void (BluetoothDaemonProtocol::* const HandleSvc[])(
-    const DaemonSocketPDUHeader&, DaemonSocketPDU&,
-    DaemonSocketResultHandler*) = {
+    const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
     [0x00] = &BluetoothDaemonProtocol::HandleSetupSvc,
     [0x01] = &BluetoothDaemonProtocol::HandleCoreSvc,
     [0x02] = &BluetoothDaemonProtocol::HandleSocketSvc,
     [0x03] = nullptr, // HID host
     [0x04] = nullptr, // PAN
     [BluetoothDaemonHandsfreeModule::SERVICE_ID] =
       &BluetoothDaemonProtocol::HandleHandsfreeSvc,
     [BluetoothDaemonA2dpModule::SERVICE_ID] =
@@ -1599,43 +1609,40 @@ BluetoothDaemonProtocol::Handle(DaemonSo
   DaemonSocketPDUHeader header;
 
   if (NS_FAILED(UnpackPDU(aPDU, header)) ||
       NS_WARN_IF(!(header.mService < MOZ_ARRAY_LENGTH(HandleSvc))) ||
       NS_WARN_IF(!(HandleSvc[header.mService]))) {
     return;
   }
 
-  nsRefPtr<DaemonSocketResultHandler> res = FetchResultHandler(header);
-
-  (this->*(HandleSvc[header.mService]))(header, aPDU, res);
+  (this->*(HandleSvc[header.mService]))(header, aPDU, FetchUserData(header));
 }
 
 void
-BluetoothDaemonProtocol::StoreResultHandler(const DaemonSocketPDU& aPDU)
+BluetoothDaemonProtocol::StoreUserData(const DaemonSocketPDU& aPDU)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
-  mResQ.AppendElement(aPDU.GetResultHandler());
+  mUserDataQ.AppendElement(aPDU.GetUserData());
 }
 
-already_AddRefed<DaemonSocketResultHandler>
-BluetoothDaemonProtocol::FetchResultHandler(
-  const DaemonSocketPDUHeader& aHeader)
+void*
+BluetoothDaemonProtocol::FetchUserData(const DaemonSocketPDUHeader& aHeader)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   if (aHeader.mOpcode & 0x80) {
     return nullptr; // Ignore notifications
   }
 
-  nsRefPtr<DaemonSocketResultHandler> userData = mResQ.ElementAt(0);
-  mResQ.RemoveElementAt(0);
+  void* userData = mUserDataQ.ElementAt(0);
+  mUserDataQ.RemoveElementAt(0);
 
-  return userData.forget();
+  return userData;
 }
 
 //
 // Interface
 //
 
 /* returns the container structure of a variable; _t is the container's
  * type, _v the name of the variable, and _m is _v's field within _t
--- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
@@ -155,42 +155,56 @@ BluetoothDaemonSocketModule::CloseCmd(Bl
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
 
   return NS_OK;
 }
 
 void
 BluetoothDaemonSocketModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
                                        DaemonSocketPDU& aPDU,
-                                       DaemonSocketResultHandler* aRes)
+                                       void* aUserData)
 {
   static void (BluetoothDaemonSocketModule::* const HandleRsp[])(
     const DaemonSocketPDUHeader&,
     DaemonSocketPDU&,
     BluetoothSocketResultHandler*) = {
     [0x00] = &BluetoothDaemonSocketModule::ErrorRsp,
     [0x01] = &BluetoothDaemonSocketModule::ListenRsp,
     [0x02] = &BluetoothDaemonSocketModule::ConnectRsp
   };
 
   if (NS_WARN_IF(MOZ_ARRAY_LENGTH(HandleRsp) <= aHeader.mOpcode) ||
       NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
     return;
   }
 
   nsRefPtr<BluetoothSocketResultHandler> res =
-    static_cast<BluetoothSocketResultHandler*>(aRes);
+    already_AddRefed<BluetoothSocketResultHandler>(
+      static_cast<BluetoothSocketResultHandler*>(aUserData));
 
   if (!res) {
     return; // Return early if no result handler has been set
   }
 
   (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
 }
 
+nsresult
+BluetoothDaemonSocketModule::Send(DaemonSocketPDU* aPDU,
+                                  BluetoothSocketResultHandler* aRes)
+{
+  nsRefPtr<BluetoothSocketResultHandler> res(aRes);
+  nsresult rv = Send(aPDU, static_cast<void*>(res.get()));
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << res.forget(); // Keep reference for response
+  return NS_OK;
+}
+
 uint8_t
 BluetoothDaemonSocketModule::SocketFlags(bool aEncrypt, bool aAuth)
 {
   return (0x01 * aEncrypt) | (0x02 * aAuth);
 }
 
 // Responses
 //
--- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h
@@ -10,25 +10,23 @@
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothInterface.h"
 #include "mozilla/ipc/DaemonRunnables.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 using mozilla::ipc::DaemonSocketPDU;
 using mozilla::ipc::DaemonSocketPDUHeader;
-using mozilla::ipc::DaemonSocketResultHandler;
 
 class BluetoothDaemonSocketModule
 {
 public:
   static const int MAX_NUM_CLIENTS;
 
-  virtual nsresult Send(DaemonSocketPDU* aPDU,
-                        DaemonSocketResultHandler* aRes) = 0;
+  virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
 
   // Commands
   //
 
   nsresult ListenCmd(BluetoothSocketType aType,
                      const nsAString& aServiceName,
                      const uint8_t aServiceUuid[16],
                      int aChannel, bool aEncrypt, bool aAuth,
@@ -42,17 +40,19 @@ public:
 
   nsresult AcceptCmd(int aFd, BluetoothSocketResultHandler* aRes);
 
   nsresult CloseCmd(BluetoothSocketResultHandler* aRes);
 
 protected:
 
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
+                 DaemonSocketPDU& aPDU, void* aUserData);
+
+  nsresult Send(DaemonSocketPDU* aPDU, BluetoothSocketResultHandler* aRes);
 
 private:
   class AcceptWatcher;
   class ConnectWatcher;
   class ListenInitOp;
 
   uint8_t SocketFlags(bool aEncrypt, bool aAuth);
 
--- a/ipc/hal/DaemonSocketConsumer.h
+++ b/ipc/hal/DaemonSocketConsumer.h
@@ -18,17 +18,17 @@ class DaemonSocketPDU;
  * different than the  consumer thread.
  */
 class DaemonSocketIOConsumer
 {
 public:
   virtual ~DaemonSocketIOConsumer();
 
   virtual void Handle(DaemonSocketPDU& aPDU) = 0;
-  virtual void StoreResultHandler(const DaemonSocketPDU& aPDU) = 0;
+  virtual void StoreUserData(const DaemonSocketPDU& aPDU) = 0;
 
 protected:
   DaemonSocketIOConsumer();
 };
 
 /**
  * |DaemonSocketConsumer| handles socket events.
  */
--- a/ipc/hal/DaemonSocketPDU.cpp
+++ b/ipc/hal/DaemonSocketPDU.cpp
@@ -24,18 +24,19 @@
 namespace mozilla {
 namespace ipc {
 
 //
 // DaemonSocketPDU
 //
 
 DaemonSocketPDU::DaemonSocketPDU(uint8_t aService, uint8_t aOpcode,
-                                 uint16_t aPayloadSize)
+                                       uint16_t aPayloadSize)
   : mConsumer(nullptr)
+  , mUserData(nullptr)
 {
   MOZ_COUNT_CTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer);
 
   // Allocate memory
   size_t availableSpace = HEADER_SIZE + aPayloadSize;
   ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
 
   // Reserve PDU header
@@ -45,16 +46,17 @@ DaemonSocketPDU::DaemonSocketPDU(uint8_t
   // Setup PDU header
   data[OFF_SERVICE] = aService;
   data[OFF_OPCODE] = aOpcode;
   memcpy(data + OFF_LENGTH, &aPayloadSize, sizeof(aPayloadSize));
 }
 
 DaemonSocketPDU::DaemonSocketPDU(size_t aPayloadSize)
   : mConsumer(nullptr)
+  , mUserData(nullptr)
 {
   MOZ_COUNT_CTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer);
 
   size_t availableSpace = HEADER_SIZE + aPayloadSize;
   ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
 }
 
 DaemonSocketPDU::~DaemonSocketPDU()
@@ -95,18 +97,18 @@ DaemonSocketPDU::Send(int aFd)
     OnError("sendmsg", errno);
     return -1;
   }
 
   Consume(res);
 
   if (mConsumer) {
     // We successfully sent a PDU, now store the
-    // result handler in the consumer.
-    mConsumer->StoreResultHandler(*this);
+    // result runnable in the consumer.
+    mConsumer->StoreUserData(*this);
   }
 
   return res;
 }
 
 #define CMSGHDR_CONTAINS_FD(_cmsghdr) \
     ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
       ((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
--- a/ipc/hal/DaemonSocketPDU.h
+++ b/ipc/hal/DaemonSocketPDU.h
@@ -4,17 +4,16 @@
  * 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_ipc_DaemonSocketPDU_h
 #define mozilla_ipc_DaemonSocketPDU_h
 
 #include "mozilla/FileUtils.h"
 #include "mozilla/ipc/SocketBase.h"
-#include "mozilla/ipc/DaemonSocketMessageHandlers.h"
 
 namespace mozilla {
 namespace ipc {
 
 class DaemonSocketIOConsumer;
 
 /**
  * |DaemonSocketPDU| represents a single PDU that is transfered from or to
@@ -51,24 +50,24 @@ public:
   DaemonSocketPDU(size_t aPayloadSize);
   ~DaemonSocketPDU();
 
   void SetConsumer(DaemonSocketIOConsumer* aConsumer)
   {
     mConsumer = aConsumer;
   }
 
-  void SetResultHandler(DaemonSocketResultHandler* aRes)
+  void SetUserData(void* aUserData)
   {
-    mRes = aRes;
+    mUserData = aUserData;
   }
 
-  DaemonSocketResultHandler* GetResultHandler() const
+  void* GetUserData() const
   {
-    return mRes;
+    return mUserData;
   }
 
   void GetHeader(uint8_t& aService, uint8_t& aOpcode,
                  uint16_t& aPayloadSize);
 
   ssize_t Send(int aFd) override;
   ssize_t Receive(int aFd) override;
 
@@ -76,17 +75,17 @@ public:
 
   nsresult UpdateHeader();
 
 private:
   size_t GetPayloadSize() const;
   void OnError(const char* aFunction, int aErrno);
 
   DaemonSocketIOConsumer* mConsumer;
-  nsRefPtr<DaemonSocketResultHandler> mRes;
+  void* mUserData;
   ScopedClose mReceivedFd;
 };
 
 }
 }
 
 #endif