Bug 1180555 - Handle PBAP replies and pass the results through IPC to PbapManager. r=btian
☠☠ backed out by fda36c6f4825 ☠ ☠
authorJamin Liu <jaliu@mozilla.com>
Wed, 19 Aug 2015 11:41:01 +0800
changeset 258392 d08f41259fb9f8146684d7e371233fc468a1ef87
parent 258391 ad74716bf6e7077cf5a5636f416a1901ce880263
child 258393 3210b4a21f50f10d0b9c125402fa64fc503da9cc
push id63898
push userryanvm@gmail.com
push dateWed, 19 Aug 2015 12:17:13 +0000
treeherdermozilla-inbound@cb6c34882e41 [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