Bug 1180555 - Handle PBAP replies and pass the results through IPC to PbapManager. r=btian
☠☠ backed out by 00b847293e70 ☠ ☠
authorJamin Liu <jaliu@mozilla.com>
Fri, 21 Aug 2015 09:51:50 +0800
changeset 291243 5bdcc058e6d6ab6b29cf70754be30100dccb543e
parent 291242 f7e0cd74c082d5bee3493e39dea048a58af2dd59
child 291244 131251625ee858d5281b20b356cab8518037d599
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbtian
bugs1180555
milestone43.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 1180555 - Handle PBAP replies and pass the results through IPC to PbapManager. r=btian
dom/bluetooth/BluetoothPbapRequestHandle.cpp
dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
dom/bluetooth/bluedroid/BluetoothPbapManager.h
dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
dom/bluetooth/bluetooth2/BluetoothAdapter.cpp
dom/bluetooth/bluetooth2/BluetoothService.h
dom/bluetooth/bluetooth2/ipc/BluetoothParent.cpp
dom/bluetooth/bluetooth2/ipc/BluetoothParent.h
dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.cpp
dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h
dom/bluetooth/bluetooth2/ipc/PBluetooth.ipdl
dom/bluetooth/bluez/BluetoothDBusService.cpp
dom/bluetooth/bluez/BluetoothDBusService.h
--- a/dom/bluetooth/BluetoothPbapRequestHandle.cpp
+++ b/dom/bluetooth/BluetoothPbapRequestHandle.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BluetoothCommon.h"
 #include "BluetoothPbapRequestHandle.h"
 #include "BluetoothReplyRunnable.h"
 #include "BluetoothService.h"
 
 #include "mozilla/dom/BluetoothPbapRequestHandleBinding.h"
+#include "mozilla/dom/ContentChild.h"
 
 using namespace mozilla;
 using namespace dom;
 
 USING_BLUETOOTH_NAMESPACE
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BluetoothPbapRequestHandle, mOwner)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(BluetoothPbapRequestHandle)
@@ -44,36 +45,138 @@ BluetoothPbapRequestHandle::Create(nsPID
 
   return handle.forget();
 }
 
 already_AddRefed<DOMRequest>
 BluetoothPbapRequestHandle::ReplyTovCardPulling(Blob& aBlob,
                                                 ErrorResult& aRv)
 {
-  // TODO: Implement this function (Bug 1180555)
-  return nullptr;
+  nsCOMPtr<nsPIDOMWindow> win = GetParentObject();
+  if (!win) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  nsRefPtr<DOMRequest> request = new DOMRequest(win);
+  nsRefPtr<BluetoothVoidReplyRunnable> result =
+    new BluetoothVoidReplyRunnable(request);
+
+  BluetoothService* bs = BluetoothService::Get();
+  if (!bs) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    // In-process reply
+    bs->ReplyTovCardPulling(&aBlob, result);
+  } else {
+    ContentChild *cc = ContentChild::GetSingleton();
+    if (!cc) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return nullptr;
+    }
+
+    BlobChild* actor = cc->GetOrCreateActorForBlob(&aBlob);
+    if (!actor) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return nullptr;
+    }
+
+    bs->ReplyTovCardPulling(nullptr, actor, result);
+  }
+
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 BluetoothPbapRequestHandle::ReplyToPhonebookPulling(Blob& aBlob,
                                                     uint16_t phonebookSize,
                                                     ErrorResult& aRv)
 {
-  // TODO: Implement this function (Bug 1180555)
-  return nullptr;
+  nsCOMPtr<nsPIDOMWindow> win = GetParentObject();
+  if (!win) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  nsRefPtr<DOMRequest> request = new DOMRequest(win);
+  nsRefPtr<BluetoothVoidReplyRunnable> result =
+    new BluetoothVoidReplyRunnable(request);
+
+  BluetoothService* bs = BluetoothService::Get();
+  if (!bs) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    // In-process reply
+    bs->ReplyToPhonebookPulling(&aBlob, phonebookSize, result);
+  } else {
+    ContentChild *cc = ContentChild::GetSingleton();
+    if (!cc) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return nullptr;
+    }
+
+    BlobChild* actor = cc->GetOrCreateActorForBlob(&aBlob);
+    if (!actor) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return nullptr;
+    }
+
+    bs->ReplyToPhonebookPulling(nullptr, actor, phonebookSize, result);
+  }
+
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 BluetoothPbapRequestHandle::ReplyTovCardListing(Blob& aBlob,
                                                 uint16_t phonebookSize,
                                                 ErrorResult& aRv)
 {
-  // TODO: Implement this function (Bug 1180555)
-  return nullptr;
+  nsCOMPtr<nsPIDOMWindow> win = GetParentObject();
+  if (!win) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  nsRefPtr<DOMRequest> request = new DOMRequest(win);
+  nsRefPtr<BluetoothVoidReplyRunnable> result =
+    new BluetoothVoidReplyRunnable(request);
+
+  BluetoothService* bs = BluetoothService::Get();
+  if (!bs) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    // In-process reply
+    bs->ReplyTovCardListing(&aBlob, phonebookSize, result);
+  } else {
+    ContentChild *cc = ContentChild::GetSingleton();
+    if (!cc) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return nullptr;
+    }
+
+    BlobChild* actor = cc->GetOrCreateActorForBlob(&aBlob);
+    if (!actor) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return nullptr;
+    }
+
+    bs->ReplyTovCardListing(nullptr, actor, phonebookSize, result);
+  }
+
+  return request.forget();
 }
 
 JSObject*
 BluetoothPbapRequestHandle::WrapObject(JSContext* aCx,
                                    JS::Handle<JSObject*> aGivenProto)
 {
   return BluetoothPbapRequestHandleBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
@@ -7,16 +7,17 @@
 #include "base/basictypes.h"
 #include "BluetoothPbapManager.h"
 
 #include "BluetoothService.h"
 #include "BluetoothSocket.h"
 #include "BluetoothUuid.h"
 #include "ObexBase.h"
 
+#include "mozilla/dom/ipc/BlobParent.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 
 USING_BLUETOOTH_NAMESPACE
@@ -748,30 +749,58 @@ BluetoothPbapManager::PackPropertiesMask
     ++count;
     x >>= 1;
   }
 
   return propSelector;
 }
 
 void
+BluetoothPbapManager::ReplyToPullPhonebook(BlobParent* aActor,
+                                           uint16_t aPhonebookSize)
+{
+  nsRefPtr<BlobImpl> impl = aActor->GetBlobImpl();
+  nsRefPtr<Blob> blob = Blob::Create(nullptr, impl);
+
+  ReplyToPullPhonebook(blob.get(), aPhonebookSize);
+}
+
+void
 BluetoothPbapManager::ReplyToPullPhonebook(Blob* aBlob, uint16_t aPhonebookSize)
 {
   // TODO: Implement this function (Bug 1180556)
 }
 
 void
-BluetoothPbapManager::ReplyToPullvCardListing(
-  Blob* aBlob,
-  uint16_t aPhonebookSize)
+BluetoothPbapManager::ReplyToPullvCardListing(BlobParent* aActor,
+                                              uint16_t aPhonebookSize)
+{
+  nsRefPtr<BlobImpl> impl = aActor->GetBlobImpl();
+  nsRefPtr<Blob> blob = Blob::Create(nullptr, impl);
+
+  ReplyToPullvCardListing(blob.get(), aPhonebookSize);
+}
+
+void
+BluetoothPbapManager::ReplyToPullvCardListing(Blob* aBlob,
+                                              uint16_t aPhonebookSize)
 {
   // TODO: Implement this function (Bug 1180556)
 }
 
 void
+BluetoothPbapManager::ReplyToPullvCardEntry(BlobParent* aActor)
+{
+  nsRefPtr<BlobImpl> impl = aActor->GetBlobImpl();
+  nsRefPtr<Blob> blob = Blob::Create(nullptr, impl);
+
+  ReplyToPullvCardEntry(blob.get());
+}
+
+void
 BluetoothPbapManager::ReplyToPullvCardEntry(Blob* aBlob)
 {
   // TODO: Implement this function (Bug 1180556)
 }
 
 void
 BluetoothPbapManager::ReplyError(uint8_t aError)
 {
--- a/dom/bluetooth/bluedroid/BluetoothPbapManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.h
@@ -11,16 +11,17 @@
 #include "BluetoothProfileManagerBase.h"
 #include "BluetoothSocketObserver.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/ipc/SocketBase.h"
 
 namespace mozilla {
   namespace dom {
     class Blob;
+    class BlobParent;
   }
 }
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 /*
  * Defined in section 6.2.1 "Application Parameters Header", PBAP ver 1.2
  */
@@ -57,18 +58,61 @@ public:
   {
     aName.AssignLiteral("PBAP");
   }
 
   static const int MAX_PACKET_LENGTH = 0xFFFE;
 
   static BluetoothPbapManager* Get();
   bool Listen();
+
+  /**
+   * Reply vCard object to the *IPC* 'pullphonebook' request.
+   *
+   * @param aActor [in]          a blob actor containing the vCard objects
+   * @param aPhonebookSize [in]  the number of vCard indexes in the blob
+   */
+  void ReplyToPullPhonebook(BlobParent* aActor, uint16_t aPhonebookSize);
+
+  /**
+   * Reply vCard object to the *in-process* 'pullphonebook' request.
+   *
+   * @param aBlob [in]           a blob contained the vCard objects
+   * @param aPhonebookSize [in]  the number of vCard indexes in the blob
+   */
   void ReplyToPullPhonebook(Blob* aBlob, uint16_t aPhonebookSize);
+
+  /**
+   * Reply vCard object to the *IPC* 'pullvcardlisting' request.
+   *
+   * @param aActor [in]          a blob actor containing the vCard objects
+   * @param aPhonebookSize [in]  the number of vCard indexes in the blob
+   */
+  void ReplyToPullvCardListing(BlobParent* aActor, uint16_t aPhonebookSize);
+
+  /**
+   * Reply vCard object to the *in-process* 'pullvcardlisting' request.
+   *
+   * @param aBlob [in]           a blob contained the vCard objects
+   * @param aPhonebookSize [in]  the number of vCard indexes in the blob
+   */
   void ReplyToPullvCardListing(Blob* aBlob, uint16_t aPhonebookSize);
+
+  /**
+   * Reply vCard object to the *IPC* 'pullvcardentry' request.
+   *
+   * @param aActor [in]  a blob actor containing the vCard objects
+   */
+  void ReplyToPullvCardEntry(BlobParent* aActor);
+
+  /**
+   * Reply vCard object to the *in-process* 'pullvcardentry' request.
+   *
+   * @param aBlob [in]  a blob contained the vCard objects
+   */
   void ReplyToPullvCardEntry(Blob* aBlob);
 
 protected:
   virtual ~BluetoothPbapManager();
 
 private:
   BluetoothPbapManager();
   bool Init();
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
@@ -1121,16 +1121,119 @@ BluetoothServiceBluedroid::IsScoConnecte
     DispatchReplyError(aRunnable, NS_LITERAL_STRING("IsScoConnected failed"));
     return;
   }
 
   DispatchReplySuccess(aRunnable, BluetoothValue(hfp->IsScoConnected()));
 }
 
 void
+BluetoothServiceBluedroid::ReplyTovCardPulling(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  BluetoothReplyRunnable* aRunnable)
+{
+  BluetoothPbapManager* pbap = BluetoothPbapManager::Get();
+  if (!pbap) {
+    DispatchReplyError(aRunnable,
+                       NS_LITERAL_STRING("Reply to vCardPulling failed"));
+    return;
+  }
+
+  pbap->ReplyToPullvCardEntry(aBlobParent);
+  DispatchReplySuccess(aRunnable);
+}
+
+void
+BluetoothServiceBluedroid::ReplyTovCardPulling(
+  Blob* aBlob,
+  BluetoothReplyRunnable* aRunnable)
+{
+  BluetoothPbapManager* pbap = BluetoothPbapManager::Get();
+  if (!pbap) {
+    DispatchReplyError(aRunnable,
+                       NS_LITERAL_STRING("Reply to vCardPulling failed"));
+    return;
+  }
+
+  pbap->ReplyToPullvCardEntry(aBlob);
+  DispatchReplySuccess(aRunnable);
+}
+
+void
+BluetoothServiceBluedroid::ReplyToPhonebookPulling(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+  BluetoothPbapManager* pbap = BluetoothPbapManager::Get();
+  if (!pbap) {
+    DispatchReplyError(aRunnable,
+                       NS_LITERAL_STRING("Reply to Phonebook Pulling failed"));
+    return;
+  }
+
+  pbap->ReplyToPullPhonebook(aBlobParent, aPhonebookSize);
+  DispatchReplySuccess(aRunnable);
+}
+
+void
+BluetoothServiceBluedroid::ReplyToPhonebookPulling(
+  Blob* aBlob,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+  BluetoothPbapManager* pbap = BluetoothPbapManager::Get();
+  if (!pbap) {
+    DispatchReplyError(aRunnable,
+                       NS_LITERAL_STRING("Reply to Phonebook Pulling failed"));
+    return;
+  }
+
+  pbap->ReplyToPullPhonebook(aBlob, aPhonebookSize);
+  DispatchReplySuccess(aRunnable);
+}
+
+void
+BluetoothServiceBluedroid::ReplyTovCardListing(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+  BluetoothPbapManager* pbap = BluetoothPbapManager::Get();
+  if (!pbap) {
+    DispatchReplyError(aRunnable,
+                       NS_LITERAL_STRING("Reply to vCard Listing failed"));
+    return;
+  }
+
+  pbap->ReplyToPullvCardListing(aBlobParent, aPhonebookSize);
+  DispatchReplySuccess(aRunnable);
+}
+
+void
+BluetoothServiceBluedroid::ReplyTovCardListing(
+  Blob* aBlob,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+  BluetoothPbapManager* pbap = BluetoothPbapManager::Get();
+  if (!pbap) {
+    DispatchReplyError(aRunnable,
+                       NS_LITERAL_STRING("Reply to vCard Listing failed"));
+    return;
+  }
+
+  pbap->ReplyToPullvCardListing(aBlob, aPhonebookSize);
+  DispatchReplySuccess(aRunnable);
+}
+
+void
 BluetoothServiceBluedroid::SendMetaData(const nsAString& aTitle,
                                         const nsAString& aArtist,
                                         const nsAString& aAlbum,
                                         int64_t aMediaNumber,
                                         int64_t aTotalMediaCount,
                                         int64_t aDuration,
                                         BluetoothReplyRunnable* aRunnable)
 {
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
@@ -138,16 +138,47 @@ public:
 
   virtual void
   DisconnectSco(BluetoothReplyRunnable* aRunnable);
 
   virtual void
   IsScoConnected(BluetoothReplyRunnable* aRunnable);
 
   virtual void
+  ReplyTovCardPulling(BlobParent* aBlobParent,
+                      BlobChild* aBlobChild,
+                      BluetoothReplyRunnable* aRunnable);
+
+  virtual void
+  ReplyTovCardPulling(Blob* aBlob,
+                      BluetoothReplyRunnable* aRunnable);
+
+  virtual void
+  ReplyToPhonebookPulling(BlobParent* aBlobParent,
+                          BlobChild* aBlobChild,
+                          uint16_t aPhonebookSize,
+                          BluetoothReplyRunnable* aRunnable);
+
+  virtual void
+  ReplyToPhonebookPulling(Blob* aBlob,
+                          uint16_t aPhonebookSize,
+                          BluetoothReplyRunnable* aRunnable);
+
+  virtual void
+  ReplyTovCardListing(BlobParent* aBlobParent,
+                      BlobChild* aBlobChild,
+                      uint16_t aPhonebookSize,
+                      BluetoothReplyRunnable* aRunnable);
+
+  virtual void
+  ReplyTovCardListing(Blob* aBlob,
+                      uint16_t aPhonebookSize,
+                      BluetoothReplyRunnable* aRunnable);
+
+  virtual void
   AnswerWaitingCall(BluetoothReplyRunnable* aRunnable);
 
   virtual void
   IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable);
 
   virtual void
   ToggleCalls(BluetoothReplyRunnable* aRunnable);
 
--- a/dom/bluetooth/bluetooth2/BluetoothAdapter.cpp
+++ b/dom/bluetooth/bluetooth2/BluetoothAdapter.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/dom/File.h"
 
 #include "mozilla/dom/bluetooth/BluetoothAdapter.h"
 #include "mozilla/dom/bluetooth/BluetoothClassOfDevice.h"
 #include "mozilla/dom/bluetooth/BluetoothDevice.h"
 #include "mozilla/dom/bluetooth/BluetoothDiscoveryHandle.h"
 #include "mozilla/dom/bluetooth/BluetoothGattServer.h"
 #include "mozilla/dom/bluetooth/BluetoothPairingListener.h"
+#include "mozilla/dom/bluetooth/BluetoothPbapRequestHandle.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 USING_BLUETOOTH_NAMESPACE
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
@@ -1229,16 +1230,18 @@ BluetoothAdapter::HandlePullPhonebookReq
       init.mVcardSelector = getVCardProperties(value);
       init.mVcardSelectorOperator = vCardSelectorOp::AND;
     } else if (name.EqualsLiteral("vCardSelector_OR")) {
       init.mVcardSelector = getVCardProperties(value);
       init.mVcardSelectorOperator = vCardSelectorOp::OR;
     }
   }
 
+  init.mHandle = BluetoothPbapRequestHandle::Create(GetOwner());
+
   nsRefPtr<BluetoothPhonebookPullingEvent> event =
     BluetoothPhonebookPullingEvent::Constructor(this,
       NS_LITERAL_STRING(PULL_PHONEBOOK_REQ_ID), init);
   DispatchTrustedEvent(event);
 }
 
 void
 BluetoothAdapter::HandlePullVCardEntryReq(const BluetoothValue& aValue)
@@ -1261,16 +1264,18 @@ BluetoothAdapter::HandlePullVCardEntryRe
     } else if (name.EqualsLiteral("format")) {
       init.mFormat = value.get_bool() ? vCardVersion::VCard30
                                       : vCardVersion::VCard21;
     } else if (name.EqualsLiteral("propSelector")) {
       init.mPropSelector = getVCardProperties(value);
     }
   }
 
+  init.mHandle = BluetoothPbapRequestHandle::Create(GetOwner());
+
   nsRefPtr<BluetoothVCardPullingEvent> event =
     BluetoothVCardPullingEvent::Constructor(this,
       NS_LITERAL_STRING(PULL_VCARD_ENTRY_REQ_ID), init);
   DispatchTrustedEvent(event);
 }
 
 void
 BluetoothAdapter::HandlePullVCardListingReq(const BluetoothValue& aValue)
@@ -1303,16 +1308,18 @@ BluetoothAdapter::HandlePullVCardListing
       init.mVcardSelector = getVCardProperties(value);
       init.mVcardSelectorOperator = vCardSelectorOp::AND;
     } else if (name.EqualsLiteral("vCardSelector_OR")) {
       init.mVcardSelector = getVCardProperties(value);
       init.mVcardSelectorOperator = vCardSelectorOp::OR;
     }
   }
 
+  init.mHandle = BluetoothPbapRequestHandle::Create(GetOwner());
+
   nsRefPtr<BluetoothVCardListingEvent> event =
     BluetoothVCardListingEvent::Constructor(this,
       NS_LITERAL_STRING(PULL_VCARD_LISTING_REQ_ID), init);
   DispatchTrustedEvent(event);
 }
 
 Sequence<vCardProperties>
 BluetoothAdapter::getVCardProperties(const BluetoothValue &aValue)
--- a/dom/bluetooth/bluetooth2/BluetoothService.h
+++ b/dom/bluetooth/bluetooth2/BluetoothService.h
@@ -4,16 +4,17 @@
  * 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_BluetoothService_h
 #define mozilla_dom_bluetooth_BluetoothService_h
 
 #include "BluetoothCommon.h"
 #include "BluetoothInterface.h"
+#include "BluetoothPbapRequestHandle.h"
 #include "BluetoothProfileManagerBase.h"
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
 #include "nsIObserver.h"
 #include "nsTObserverArray.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
@@ -305,16 +306,47 @@ public:
   ConnectSco(BluetoothReplyRunnable* aRunnable) = 0;
 
   virtual void
   DisconnectSco(BluetoothReplyRunnable* aRunnable) = 0;
 
   virtual void
   IsScoConnected(BluetoothReplyRunnable* aRunnable) = 0;
 
+  virtual void
+  ReplyTovCardPulling(BlobParent* aBlobParent,
+                      BlobChild* aBlobChild,
+                      BluetoothReplyRunnable* aRunnable) = 0;
+
+  virtual void
+  ReplyTovCardPulling(Blob* aBlob,
+                      BluetoothReplyRunnable* aRunnable) = 0;
+
+  virtual void
+  ReplyToPhonebookPulling(BlobParent* aBlobParent,
+                          BlobChild* aBlobChild,
+                          uint16_t aPhonebookSize,
+                          BluetoothReplyRunnable* aRunnable) = 0;
+
+  virtual void
+  ReplyToPhonebookPulling(Blob* aBlob,
+                          uint16_t aPhonebookSize,
+                          BluetoothReplyRunnable* aRunnable) = 0;
+
+  virtual void
+  ReplyTovCardListing(BlobParent* aBlobParent,
+                      BlobChild* aBlobChild,
+                      uint16_t aPhonebookSize,
+                      BluetoothReplyRunnable* aRunnable) = 0;
+
+  virtual void
+  ReplyTovCardListing(Blob* aBlob,
+                      uint16_t aPhonebookSize,
+                      BluetoothReplyRunnable* aRunnable) = 0;
+
 #ifdef MOZ_B2G_RIL
   virtual void
   AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) = 0;
 
   virtual void
   IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable) = 0;
 
   virtual void
--- a/dom/bluetooth/bluetooth2/ipc/BluetoothParent.cpp
+++ b/dom/bluetooth/bluetooth2/ipc/BluetoothParent.cpp
@@ -241,16 +241,22 @@ BluetoothParent::RecvPBluetoothRequestCo
     case Request::TDenyReceivingFileRequest:
       return actor->DoRequest(aRequest.get_DenyReceivingFileRequest());
     case Request::TConnectScoRequest:
       return actor->DoRequest(aRequest.get_ConnectScoRequest());
     case Request::TDisconnectScoRequest:
       return actor->DoRequest(aRequest.get_DisconnectScoRequest());
     case Request::TIsScoConnectedRequest:
       return actor->DoRequest(aRequest.get_IsScoConnectedRequest());
+    case Request::TReplyTovCardPullingRequest:
+      return actor->DoRequest(aRequest.get_ReplyTovCardPullingRequest());
+    case Request::TReplyToPhonebookPullingRequest:
+      return actor->DoRequest(aRequest.get_ReplyToPhonebookPullingRequest());
+    case Request::TReplyTovCardListingRequest:
+      return actor->DoRequest(aRequest.get_ReplyTovCardListingRequest());
 #ifdef MOZ_B2G_RIL
     case Request::TAnswerWaitingCallRequest:
       return actor->DoRequest(aRequest.get_AnswerWaitingCallRequest());
     case Request::TIgnoreWaitingCallRequest:
       return actor->DoRequest(aRequest.get_IgnoreWaitingCallRequest());
     case Request::TToggleCallsRequest:
       return actor->DoRequest(aRequest.get_ToggleCallsRequest());
 #endif
@@ -698,16 +704,54 @@ BluetoothRequestParent::DoRequest(const 
 {
   MOZ_ASSERT(mService);
   MOZ_ASSERT(mRequestType == Request::TIsScoConnectedRequest);
 
   mService->IsScoConnected(mReplyRunnable.get());
   return true;
 }
 
+bool
+BluetoothRequestParent::DoRequest(const ReplyTovCardPullingRequest& aRequest)
+{
+  MOZ_ASSERT(mService);
+  MOZ_ASSERT(mRequestType == Request::TReplyTovCardPullingRequest);
+
+  mService->ReplyTovCardPulling((BlobParent*)aRequest.blobParent(),
+                                (BlobChild*)aRequest.blobChild(),
+                                mReplyRunnable.get());
+  return true;
+}
+
+bool
+BluetoothRequestParent::DoRequest(const ReplyToPhonebookPullingRequest& aRequest)
+{
+  MOZ_ASSERT(mService);
+  MOZ_ASSERT(mRequestType == Request::TReplyToPhonebookPullingRequest);
+
+  mService->ReplyToPhonebookPulling((BlobParent*)aRequest.blobParent(),
+                                    (BlobChild*)aRequest.blobChild(),
+                                    aRequest.phonebookSize(),
+                                    mReplyRunnable.get());
+  return true;
+}
+
+bool
+BluetoothRequestParent::DoRequest(const ReplyTovCardListingRequest& aRequest)
+{
+  MOZ_ASSERT(mService);
+  MOZ_ASSERT(mRequestType == Request::TReplyTovCardListingRequest);
+
+  mService->ReplyTovCardListing((BlobParent*)aRequest.blobParent(),
+                                (BlobChild*)aRequest.blobChild(),
+                                aRequest.phonebookSize(),
+                                mReplyRunnable.get());
+  return true;
+}
+
 #ifdef MOZ_B2G_RIL
 bool
 BluetoothRequestParent::DoRequest(const AnswerWaitingCallRequest& aRequest)
 {
   MOZ_ASSERT(mService);
   MOZ_ASSERT(mRequestType == Request::TAnswerWaitingCallRequest);
 
   mService->AnswerWaitingCall(mReplyRunnable.get());
--- a/dom/bluetooth/bluetooth2/ipc/BluetoothParent.h
+++ b/dom/bluetooth/bluetooth2/ipc/BluetoothParent.h
@@ -207,16 +207,25 @@ protected:
   DoRequest(const ConnectScoRequest& aRequest);
 
   bool
   DoRequest(const DisconnectScoRequest& aRequest);
 
   bool
   DoRequest(const IsScoConnectedRequest& aRequest);
 
+  bool
+  DoRequest(const ReplyTovCardPullingRequest& aRequest);
+
+  bool
+  DoRequest(const ReplyToPhonebookPullingRequest& aRequest);
+
+  bool
+  DoRequest(const ReplyTovCardListingRequest& aRequest);
+
 #ifdef MOZ_B2G_RIL
   bool
   DoRequest(const AnswerWaitingCallRequest& aRequest);
 
   bool
   DoRequest(const IgnoreWaitingCallRequest& aRequest);
 
   bool
--- a/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.cpp
+++ b/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.cpp
@@ -361,16 +361,76 @@ BluetoothServiceChildProcess::Disconnect
 }
 
 void
 BluetoothServiceChildProcess::IsScoConnected(BluetoothReplyRunnable* aRunnable)
 {
   SendRequest(aRunnable, IsScoConnectedRequest());
 }
 
+void
+BluetoothServiceChildProcess::ReplyTovCardPulling(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  BluetoothReplyRunnable* aRunnable)
+{
+  SendRequest(aRunnable, ReplyTovCardPullingRequest(nullptr, aBlobChild));
+}
+
+void
+BluetoothServiceChildProcess::ReplyTovCardPulling(
+  Blob* aBlobChild,
+  BluetoothReplyRunnable* aRunnable)
+{
+  // Parent-process-only method
+  MOZ_CRASH("This should never be called!");
+}
+
+void
+BluetoothServiceChildProcess::ReplyToPhonebookPulling(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+  SendRequest(aRunnable,
+    ReplyToPhonebookPullingRequest(nullptr, aBlobChild, aPhonebookSize));
+}
+
+void
+BluetoothServiceChildProcess::ReplyToPhonebookPulling(
+  Blob* aBlobChild,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+  // Parent-process-only method
+  MOZ_CRASH("This should never be called!");
+}
+
+void
+BluetoothServiceChildProcess::ReplyTovCardListing(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+  SendRequest(aRunnable,
+    ReplyTovCardListingRequest(nullptr, aBlobChild, aPhonebookSize));
+}
+
+void
+BluetoothServiceChildProcess::ReplyTovCardListing(
+  Blob* aBlobChild,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+  // Parent-process-only method
+  MOZ_CRASH("This should never be called!");
+}
+
 #ifdef MOZ_B2G_RIL
 void
 BluetoothServiceChildProcess::AnswerWaitingCall(
   BluetoothReplyRunnable* aRunnable)
 {
   SendRequest(aRunnable, AnswerWaitingCallRequest());
 }
 
--- a/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h
+++ b/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h
@@ -153,16 +153,47 @@ public:
   ConnectSco(BluetoothReplyRunnable* aRunnable) override;
 
   virtual void
   DisconnectSco(BluetoothReplyRunnable* aRunnable) override;
 
   virtual void
   IsScoConnected(BluetoothReplyRunnable* aRunnable) override;
 
+  virtual void
+  ReplyTovCardPulling(BlobParent* aBlobParent,
+                      BlobChild* aBlobChild,
+                      BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyTovCardPulling(Blob* aBlob,
+                      BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyToPhonebookPulling(BlobParent* aBlobParent,
+                          BlobChild* aBlobChild,
+                          uint16_t aPhonebookSize,
+                          BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyToPhonebookPulling(Blob* aBlob,
+                          uint16_t aPhonebookSize,
+                          BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyTovCardListing(BlobParent* aBlobParent,
+                      BlobChild* aBlobChild,
+                      uint16_t aPhonebookSize,
+                      BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyTovCardListing(Blob* aBlob,
+                      uint16_t aPhonebookSize,
+                      BluetoothReplyRunnable* aRunnable) override;
+
 #ifdef MOZ_B2G_RIL
   virtual void
   AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) override;
 
   virtual void
   IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable) override;
 
   virtual void
--- a/dom/bluetooth/bluetooth2/ipc/PBluetooth.ipdl
+++ b/dom/bluetooth/bluetooth2/ipc/PBluetooth.ipdl
@@ -166,16 +166,33 @@ struct ConnectScoRequest
 struct DisconnectScoRequest
 {
 };
 
 struct IsScoConnectedRequest
 {
 };
 
+struct ReplyTovCardPullingRequest
+{
+  PBlob blob;
+};
+
+struct ReplyToPhonebookPullingRequest
+{
+  PBlob blob;
+  uint16_t phonebookSize;
+};
+
+struct ReplyTovCardListingRequest
+{
+  PBlob blob;
+  uint16_t phonebookSize;
+};
+
 struct AnswerWaitingCallRequest
 {
 };
 
 struct IgnoreWaitingCallRequest
 {
 };
 
@@ -301,16 +318,19 @@ union Request
   DisconnectRequest;
   SendFileRequest;
   StopSendingFileRequest;
   ConfirmReceivingFileRequest;
   DenyReceivingFileRequest;
   ConnectScoRequest;
   DisconnectScoRequest;
   IsScoConnectedRequest;
+  ReplyTovCardPullingRequest;
+  ReplyToPhonebookPullingRequest;
+  ReplyTovCardListingRequest;
   AnswerWaitingCallRequest;
   IgnoreWaitingCallRequest;
   ToggleCallsRequest;
   SendMetaDataRequest;
   SendPlayStatusRequest;
   ConnectGattClientRequest;
   DisconnectGattClientRequest;
   DiscoverGattServicesRequest;
--- a/dom/bluetooth/bluez/BluetoothDBusService.cpp
+++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp
@@ -4373,8 +4373,57 @@ BluetoothDBusService::GattClientWriteDes
   const nsAString& aAppUuid,
   const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharacteristicId,
   const BluetoothGattId& aDescriptorId,
   const nsTArray<uint8_t>& aValue,
   BluetoothReplyRunnable* aRunnable)
 {
 }
+
+void
+BluetoothDBusService::ReplyTovCardPulling(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  BluetoothReplyRunnable* aRunnable)
+{
+}
+
+void
+BluetoothDBusService::ReplyTovCardPulling(
+  Blob* aBlob,
+  BluetoothReplyRunnable* aRunnable)
+{
+}
+
+void
+BluetoothDBusService::ReplyToPhonebookPulling(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+}
+
+void
+BluetoothDBusService::ReplyToPhonebookPulling(
+  Blob* aBlob,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+}
+
+void
+BluetoothDBusService::ReplyTovCardListing(
+  BlobParent* aBlobParent,
+  BlobChild* aBlobChild,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+}
+
+void
+BluetoothDBusService::ReplyTovCardListing(
+  Blob* aBlob,
+  uint16_t aPhonebookSize,
+  BluetoothReplyRunnable* aRunnable)
+{
+}
--- a/dom/bluetooth/bluez/BluetoothDBusService.h
+++ b/dom/bluetooth/bluez/BluetoothDBusService.h
@@ -152,16 +152,47 @@ public:
   ConnectSco(BluetoothReplyRunnable* aRunnable) override;
 
   virtual void
   DisconnectSco(BluetoothReplyRunnable* aRunnable) override;
 
   virtual void
   IsScoConnected(BluetoothReplyRunnable* aRunnable) override;
 
+  virtual void
+  ReplyTovCardPulling(BlobParent* aBlobParent,
+                      BlobChild* aBlobChild,
+                      BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyTovCardPulling(Blob* aBlob,
+                      BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyToPhonebookPulling(BlobParent* aBlobParent,
+                          BlobChild* aBlobChild,
+                          uint16_t aPhonebookSize,
+                          BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyToPhonebookPulling(Blob* aBlob,
+                          uint16_t aPhonebookSize,
+                          BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyTovCardListing(BlobParent* aBlobParent,
+                      BlobChild* aBlobChild,
+                      uint16_t aPhonebookSize,
+                      BluetoothReplyRunnable* aRunnable) override;
+
+  virtual void
+  ReplyTovCardListing(Blob* aBlob,
+                      uint16_t aPhonebookSize,
+                      BluetoothReplyRunnable* aRunnable);
+
 #ifdef MOZ_B2G_RIL
   virtual void
   AnswerWaitingCall(BluetoothReplyRunnable* aRunnable);
 
   virtual void
   IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable);
 
   virtual void