Bug 969218 - Part 6: Use promise for dial and dialEmergency - ipc. r=khuey
authorSzu-Yu Chen [:aknow] <szchen@mozilla.com>
Thu, 27 Feb 2014 14:12:30 +0800
changeset 171314 5838091659a736a4162919600f5a45a2f7e4b252
parent 171313 a381a07fffb436bd8c32a18707498b7961d76c7a
child 171315 bfc87261fa2a87a1963f9aa32acc16ac29bf3607
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewerskhuey
bugs969218
milestone30.0a1
Bug 969218 - Part 6: Use promise for dial and dialEmergency - ipc. r=khuey
dom/telephony/ipc/PTelephony.ipdl
dom/telephony/ipc/PTelephonyRequest.ipdl
dom/telephony/ipc/TelephonyChild.cpp
dom/telephony/ipc/TelephonyChild.h
dom/telephony/ipc/TelephonyIPCProvider.cpp
dom/telephony/ipc/TelephonyIPCProvider.h
dom/telephony/ipc/TelephonyParent.cpp
dom/telephony/ipc/TelephonyParent.h
--- a/dom/telephony/ipc/PTelephony.ipdl
+++ b/dom/telephony/ipc/PTelephony.ipdl
@@ -7,16 +7,34 @@
 include protocol PContent;
 include protocol PTelephonyRequest;
 include TelephonyTypes;
 
 namespace mozilla {
 namespace dom {
 namespace telephony {
 
+struct EnumerateCallsRequest
+{
+  // empty.
+};
+
+struct DialRequest
+{
+  uint32_t clientId;
+  nsString number;
+  bool isEmergency;
+};
+
+union IPCTelephonyRequest
+{
+  EnumerateCallsRequest;
+  DialRequest;
+};
+
 sync protocol PTelephony {
   manager PContent;
   manages PTelephonyRequest;
 
 child:
   NotifyCallError(uint32_t aClientId, int32_t aCallIndex, nsString aError);
 
   NotifyCallStateChanged(uint32_t aClientId, IPCCallStateData aData);
@@ -32,27 +50,24 @@ child:
 
 parent:
   /**
    * Sent when the child no longer needs to use PTelephony.
    */
   __delete__();
 
   /**
-   * Sent when the child makes an asynchronous request to the parent.  It's
-   * currently only for request call enumeration.
+   * Sent when the child makes an asynchronous request to the parent.
    */
-  PTelephonyRequest();
+  PTelephonyRequest(IPCTelephonyRequest request);
 
   RegisterListener();
 
   UnregisterListener();
 
-  DialCall(uint32_t aClientId, nsString aNumber, bool aIsEmergency);
-
   HangUpCall(uint32_t aClientId, uint32_t aCallIndex);
 
   AnswerCall(uint32_t aClientId, uint32_t aCallIndex);
 
   RejectCall(uint32_t aClientId, uint32_t aCallIndex);
 
   HoldCall(uint32_t aClientId, uint32_t aCallIndex);
 
--- a/dom/telephony/ipc/PTelephonyRequest.ipdl
+++ b/dom/telephony/ipc/PTelephonyRequest.ipdl
@@ -6,25 +6,44 @@
 
 include protocol PTelephony;
 include TelephonyTypes;
 
 namespace mozilla {
 namespace dom {
 namespace telephony {
 
+struct EnumerateCallsResponse
+{
+  // empty.
+};
+
+struct DialResponse
+{
+  // empty.
+};
+
+union IPCTelephonyResponse
+{
+  EnumerateCallsResponse;
+  DialResponse;
+};
+
 protocol PTelephonyRequest
 {
   manager PTelephony;
 
 child:
   NotifyEnumerateCallState(uint32_t aClientId, IPCCallStateData aData);
 
+  NotifyDialError(nsString aError);
+
+  NotifyDialSuccess();
+
   /**
-   * Sent when the asynchronous request has completed. It's currently only for
-   * request call enumeration.
+   * Sent when the asynchronous request has completed.
    */
-  __delete__();
+  __delete__(IPCTelephonyResponse aResponse);
 };
 
 } /* namespace telephony */
 } /* namespace dom */
 } /* namespace mozilla */
--- a/dom/telephony/ipc/TelephonyChild.cpp
+++ b/dom/telephony/ipc/TelephonyChild.cpp
@@ -19,17 +19,17 @@ TelephonyChild::TelephonyChild(nsITeleph
 
 void
 TelephonyChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   mListener = nullptr;
 }
 
 PTelephonyRequestChild*
-TelephonyChild::AllocPTelephonyRequestChild()
+TelephonyChild::AllocPTelephonyRequestChild(const IPCTelephonyRequest& aRequest)
 {
   MOZ_CRASH("Caller is supposed to manually construct a request!");
 }
 
 bool
 TelephonyChild::DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor)
 {
   delete aActor;
@@ -104,34 +104,43 @@ TelephonyChild::RecvNotifySupplementaryS
                                               aNotification);
   return true;
 }
 
 /*******************************************************************************
  * TelephonyRequestChild
  ******************************************************************************/
 
-TelephonyRequestChild::TelephonyRequestChild(nsITelephonyListener* aListener)
-  : mListener(aListener)
+TelephonyRequestChild::TelephonyRequestChild(nsITelephonyListener* aListener,
+                                             nsITelephonyCallback* aCallback)
+  : mListener(aListener), mCallback(aCallback)
 {
-  MOZ_ASSERT(aListener);
 }
 
 void
 TelephonyRequestChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   mListener = nullptr;
+  mCallback = nullptr;
 }
 
 bool
-TelephonyRequestChild::Recv__delete__()
+TelephonyRequestChild::Recv__delete__(const IPCTelephonyResponse& aResponse)
 {
-  MOZ_ASSERT(mListener);
+  switch (aResponse.type()) {
+    case IPCTelephonyResponse::TEnumerateCallsResponse:
+      mListener->EnumerateCallStateComplete();
+      break;
+    case IPCTelephonyResponse::TDialResponse:
+      // Do nothing.
+      break;
+    default:
+      MOZ_CRASH("Unknown type!");
+  }
 
-  mListener->EnumerateCallStateComplete();
   return true;
 }
 
 bool
 TelephonyRequestChild::RecvNotifyEnumerateCallState(const uint32_t& aClientId,
                                                     const IPCCallStateData& aData)
 {
   MOZ_ASSERT(mListener);
@@ -141,8 +150,26 @@ TelephonyRequestChild::RecvNotifyEnumera
                                 aData.callState(),
                                 aData.number(),
                                 aData.isActive(),
                                 aData.isOutGoing(),
                                 aData.isEmergency(),
                                 aData.isConference());
   return true;
 }
+
+bool
+TelephonyRequestChild::RecvNotifyDialError(const nsString& aError)
+{
+  MOZ_ASSERT(mCallback);
+
+  mCallback->NotifyDialError(aError);
+  return true;
+}
+
+bool
+TelephonyRequestChild::RecvNotifyDialSuccess()
+{
+  MOZ_ASSERT(mCallback);
+
+  mCallback->NotifyDialSuccess();
+  return true;
+}
--- a/dom/telephony/ipc/TelephonyChild.h
+++ b/dom/telephony/ipc/TelephonyChild.h
@@ -20,17 +20,17 @@ public:
 
 protected:
   virtual ~TelephonyChild() {}
 
   virtual void
   ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   virtual PTelephonyRequestChild*
-  AllocPTelephonyRequestChild() MOZ_OVERRIDE;
+  AllocPTelephonyRequestChild(const IPCTelephonyRequest& aRequest) MOZ_OVERRIDE;
 
   virtual bool
   DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor) MOZ_OVERRIDE;
 
   virtual bool
   RecvNotifyCallError(const uint32_t& aClientId, const int32_t& aCallIndex,
                       const nsString& aError) MOZ_OVERRIDE;
 
@@ -56,30 +56,38 @@ protected:
 
 private:
   nsCOMPtr<nsITelephonyListener> mListener;
 };
 
 class TelephonyRequestChild : public PTelephonyRequestChild
 {
 public:
-  TelephonyRequestChild(nsITelephonyListener* aListener);
+  TelephonyRequestChild(nsITelephonyListener* aListener,
+                        nsITelephonyCallback* aCallback);
 
 protected:
   virtual ~TelephonyRequestChild() {}
 
   virtual void
   ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   virtual bool
-  Recv__delete__() MOZ_OVERRIDE;
+  Recv__delete__(const IPCTelephonyResponse& aResponse) MOZ_OVERRIDE;
 
   virtual bool
   RecvNotifyEnumerateCallState(const uint32_t& aClientId,
                                const IPCCallStateData& aData) MOZ_OVERRIDE;
 
+  virtual bool
+  RecvNotifyDialError(const nsString& aError) MOZ_OVERRIDE;
+
+  virtual bool
+  RecvNotifyDialSuccess() MOZ_OVERRIDE;
+
 private:
   nsCOMPtr<nsITelephonyListener> mListener;
+  nsCOMPtr<nsITelephonyCallback> mCallback;
 };
 
 END_TELEPHONY_NAMESPACE
 
 #endif // mozilla_dom_telephony_TelephonyChild_h
--- a/dom/telephony/ipc/TelephonyIPCProvider.cpp
+++ b/dom/telephony/ipc/TelephonyIPCProvider.cpp
@@ -112,32 +112,40 @@ TelephonyIPCProvider::UnregisterListener
   mListeners.RemoveElement(aListener);
 
   if (!mListeners.Length()) {
     mPTelephonyChild->SendUnregisterListener();
   }
   return NS_OK;
 }
 
-NS_IMETHODIMP
-TelephonyIPCProvider::EnumerateCalls(nsITelephonyListener *aListener)
+nsresult
+TelephonyIPCProvider::SendRequest(nsITelephonyListener *aListener,
+                                  nsITelephonyCallback *aCallback,
+                                  const IPCTelephonyRequest& aRequest)
 {
   // Life time of newly allocated TelephonyRequestChild instance is managed by
   // IPDL itself.
-  TelephonyRequestChild* actor = new TelephonyRequestChild(aListener);
-  mPTelephonyChild->SendPTelephonyRequestConstructor(actor);
+  TelephonyRequestChild* actor = new TelephonyRequestChild(aListener, aCallback);
+  mPTelephonyChild->SendPTelephonyRequestConstructor(actor, aRequest);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TelephonyIPCProvider::Dial(uint32_t aClientId, const nsAString& aNumber,
-                           bool aIsEmergency)
+TelephonyIPCProvider::EnumerateCalls(nsITelephonyListener *aListener)
 {
-  mPTelephonyChild->SendDialCall(aClientId, nsString(aNumber), aIsEmergency);
-  return NS_OK;
+  return SendRequest(aListener, nullptr, EnumerateCallsRequest());
+}
+
+NS_IMETHODIMP
+TelephonyIPCProvider::Dial(uint32_t aClientId, const nsAString& aNumber,
+                           bool aIsEmergency, nsITelephonyCallback *aCallback)
+{
+  return SendRequest(nullptr, aCallback,
+                     DialRequest(aClientId, nsString(aNumber), aIsEmergency));
 }
 
 NS_IMETHODIMP
 TelephonyIPCProvider::HangUp(uint32_t aClientId, uint32_t aCallIndex)
 {
   mPTelephonyChild->SendHangUpCall(aClientId, aCallIndex);
   return NS_OK;
 }
--- a/dom/telephony/ipc/TelephonyIPCProvider.h
+++ b/dom/telephony/ipc/TelephonyIPCProvider.h
@@ -8,16 +8,17 @@
 
 #include "mozilla/dom/telephony/TelephonyCommon.h"
 #include "mozilla/Attributes.h"
 #include "nsIObserver.h"
 #include "nsITelephonyProvider.h"
 
 BEGIN_TELEPHONY_NAMESPACE
 
+struct IPCTelephonyRequest;
 class PTelephonyChild;
 
 class TelephonyIPCProvider MOZ_FINAL : public nsITelephonyProvider
                                      , public nsITelephonyListener
                                      , public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
@@ -29,13 +30,17 @@ public:
 
 protected:
   virtual ~TelephonyIPCProvider();
 
 private:
   nsTArray<nsCOMPtr<nsITelephonyListener> > mListeners;
   PTelephonyChild* mPTelephonyChild;
   uint32_t mDefaultServiceId;
+
+  nsresult SendRequest(nsITelephonyListener *aListener,
+                       nsITelephonyCallback *aCallback,
+                       const IPCTelephonyRequest& aRequest);
 };
 
 END_TELEPHONY_NAMESPACE
 
 #endif // mozilla_dom_telephony_TelephonyIPCProvider_h
--- a/dom/telephony/ipc/TelephonyParent.cpp
+++ b/dom/telephony/ipc/TelephonyParent.cpp
@@ -28,25 +28,35 @@ TelephonyParent::ActorDestroy(ActorDestr
   // an error here to avoid sending a message to the dead process.
   mActorDestroyed = true;
 
   // Try to unregister listener if we're still registered.
   RecvUnregisterListener();
 }
 
 bool
-TelephonyParent::RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor)
+TelephonyParent::RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor,
+                                                  const IPCTelephonyRequest& aRequest)
 {
   TelephonyRequestParent* actor = static_cast<TelephonyRequestParent*>(aActor);
 
-  return actor->DoRequest();
+  switch (aRequest.type()) {
+    case IPCTelephonyRequest::TEnumerateCallsRequest:
+      return actor->DoRequest(aRequest.get_EnumerateCallsRequest());
+    case IPCTelephonyRequest::TDialRequest:
+      return actor->DoRequest(aRequest.get_DialRequest());
+    default:
+      MOZ_CRASH("Unknown type!");
+  }
+
+  return false;
 }
 
 PTelephonyRequestParent*
-TelephonyParent::AllocPTelephonyRequestParent()
+TelephonyParent::AllocPTelephonyRequestParent(const IPCTelephonyRequest& aRequest)
 {
   TelephonyRequestParent* actor = new TelephonyRequestParent();
   // Add an extra ref for IPDL. Will be released in
   // TelephonyParent::DeallocPTelephonyRequestParent().
   NS_ADDREF(actor);
 
   return actor;
 }
@@ -87,29 +97,16 @@ TelephonyParent::RecvUnregisterListener(
     do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
   NS_ENSURE_TRUE(provider, true);
 
   mRegistered = !NS_SUCCEEDED(provider->UnregisterListener(this));
   return true;
 }
 
 bool
-TelephonyParent::RecvDialCall(const uint32_t& aClientId,
-                              const nsString& aNumber,
-                              const bool& aIsEmergency)
-{
-  nsCOMPtr<nsITelephonyProvider> provider =
-    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, true);
-
-  provider->Dial(aClientId, aNumber, aIsEmergency);
-  return true;
-}
-
-bool
 TelephonyParent::RecvHangUpCall(const uint32_t& aClientId,
                                 const uint32_t& aCallIndex)
 {
   nsCOMPtr<nsITelephonyProvider> provider =
     do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
   NS_ENSURE_TRUE(provider, true);
 
   provider->HangUp(aClientId, aCallIndex);
@@ -367,50 +364,67 @@ TelephonyParent::SupplementaryServiceNot
   return SendNotifySupplementaryService(aClientId, aCallIndex, aNotification)
       ? NS_OK : NS_ERROR_FAILURE;
 }
 
 /*******************************************************************************
  * TelephonyRequestParent
  ******************************************************************************/
 
-NS_IMPL_ISUPPORTS1(TelephonyRequestParent, nsITelephonyListener)
+NS_IMPL_ISUPPORTS2(TelephonyRequestParent,
+                   nsITelephonyListener,
+                   nsITelephonyCallback)
 
 TelephonyRequestParent::TelephonyRequestParent()
   : mActorDestroyed(false)
 {
 }
 
 void
 TelephonyRequestParent::ActorDestroy(ActorDestroyReason why)
 {
   // The child process could die before this asynchronous notification, in which
   // case ActorDestroy() was called and mActorDestroyed is set to true. Return
   // an error here to avoid sending a message to the dead process.
   mActorDestroyed = true;
 }
 
 bool
-TelephonyRequestParent::DoRequest()
+TelephonyRequestParent::DoRequest(const EnumerateCallsRequest& aRequest)
 {
   nsresult rv = NS_ERROR_FAILURE;
 
   nsCOMPtr<nsITelephonyProvider> provider =
     do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
   if (provider) {
     rv = provider->EnumerateCalls(this);
   }
 
   if (NS_FAILED(rv)) {
     return NS_SUCCEEDED(EnumerateCallStateComplete());
   }
 
   return true;
 }
 
+bool
+TelephonyRequestParent::DoRequest(const DialRequest& aRequest)
+{
+  nsCOMPtr<nsITelephonyProvider> provider =
+    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
+  if (provider) {
+    provider->Dial(aRequest.clientId(), aRequest.number(),
+                   aRequest.isEmergency(), this);
+  } else {
+    return NS_SUCCEEDED(NotifyDialError(NS_LITERAL_STRING("InvalidStateError")));
+  }
+
+  return true;
+}
+
 // nsITelephonyListener
 
 NS_IMETHODIMP
 TelephonyRequestParent::CallStateChanged(uint32_t aClientId,
                                          uint32_t aCallIndex,
                                          uint16_t aCallState,
                                          const nsAString& aNumber,
                                          bool aIsActive,
@@ -427,17 +441,17 @@ TelephonyRequestParent::ConferenceCallSt
   MOZ_CRASH("Not a TelephonyParent!");
 }
 
 NS_IMETHODIMP
 TelephonyRequestParent::EnumerateCallStateComplete()
 {
   NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
 
-  return Send__delete__(this) ? NS_OK : NS_ERROR_FAILURE;
+  return Send__delete__(this, EnumerateCallsResponse()) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 TelephonyRequestParent::EnumerateCallState(uint32_t aClientId,
                                            uint32_t aCallIndex,
                                            uint16_t aCallState,
                                            const nsAString& aNumber,
                                            bool aIsActive,
@@ -477,8 +491,28 @@ TelephonyRequestParent::NotifyError(uint
 
 NS_IMETHODIMP
 TelephonyRequestParent::SupplementaryServiceNotification(uint32_t aClientId,
                                                          int32_t aCallIndex,
                                                          uint16_t aNotification)
 {
   MOZ_CRASH("Not a TelephonyParent!");
 }
+
+// nsITelephonyCallback
+
+NS_IMETHODIMP
+TelephonyRequestParent::NotifyDialError(const nsAString& aError)
+{
+  NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
+
+  return (SendNotifyDialError(nsString(aError)) &&
+          Send__delete__(this, DialResponse())) ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+TelephonyRequestParent::NotifyDialSuccess()
+{
+  NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
+
+  return (SendNotifyDialSuccess() &&
+          Send__delete__(this, DialResponse())) ? NS_OK : NS_ERROR_FAILURE;
+}
--- a/dom/telephony/ipc/TelephonyParent.h
+++ b/dom/telephony/ipc/TelephonyParent.h
@@ -24,37 +24,34 @@ public:
 
 protected:
   virtual ~TelephonyParent() {}
 
   virtual void
   ActorDestroy(ActorDestroyReason why);
 
   virtual bool
-  RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor) MOZ_OVERRIDE;
+  RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor, const IPCTelephonyRequest& aRequest) MOZ_OVERRIDE;
 
   virtual PTelephonyRequestParent*
-  AllocPTelephonyRequestParent() MOZ_OVERRIDE;
+  AllocPTelephonyRequestParent(const IPCTelephonyRequest& aRequest) MOZ_OVERRIDE;
 
   virtual bool
   DeallocPTelephonyRequestParent(PTelephonyRequestParent* aActor) MOZ_OVERRIDE;
 
   virtual bool
   Recv__delete__() MOZ_OVERRIDE;
 
   virtual bool
   RecvRegisterListener() MOZ_OVERRIDE;
 
   virtual bool
   RecvUnregisterListener() MOZ_OVERRIDE;
 
   virtual bool
-  RecvDialCall(const uint32_t& aClientId, const nsString& aNumber, const bool& aIsEmergency) MOZ_OVERRIDE;
-
-  virtual bool
   RecvHangUpCall(const uint32_t& aClientId, const uint32_t& aCallIndex) MOZ_OVERRIDE;
 
   virtual bool
   RecvAnswerCall(const uint32_t& aClientId, const uint32_t& aCallIndex) MOZ_OVERRIDE;
 
   virtual bool
   RecvRejectCall(const uint32_t& aClientId, const uint32_t& aCallIndex) MOZ_OVERRIDE;
 
@@ -96,32 +93,37 @@ protected:
 
 private:
   bool mActorDestroyed;
   bool mRegistered;
 };
 
 class TelephonyRequestParent : public PTelephonyRequestParent
                              , public nsITelephonyListener
+                             , public nsITelephonyCallback
 {
   friend class TelephonyParent;
 
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSITELEPHONYLISTENER
+  NS_DECL_NSITELEPHONYCALLBACK
 
 protected:
   TelephonyRequestParent();
   virtual ~TelephonyRequestParent() {}
 
   virtual void
   ActorDestroy(ActorDestroyReason why);
 
 private:
   bool mActorDestroyed;
 
   bool
-  DoRequest();
+  DoRequest(const EnumerateCallsRequest& aRequest);
+
+  bool
+  DoRequest(const DialRequest& aRequest);
 };
 
 END_TELEPHONY_NAMESPACE
 
 #endif /* mozilla_dom_telephony_TelephonyParent_h */