Plumb through the post-dial DTMF wait/response

Connect the CallServices with the InCallService for post-dial DTMF
call flows (and the reverse path, for the wait dialog response).

Bug: 13734588
Change-Id: I5cc06268590c3c424ea6daf216cb205b9c470dac
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index cd64ff8..8f94e1e 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -59,6 +59,7 @@
         void onSuccessfulIncomingCall(Call call, CallInfo callInfo);
         void onFailedIncomingCall(Call call);
         void onRequestingRingback(Call call, boolean requestingRingback);
+        void onPostDialWait(Call call, String remaining);
     }
 
     private static final OnQueryCompleteListener sCallerInfoQueryListener =
@@ -728,6 +729,16 @@
         return mCallerInfo == null ? null : mCallerInfo.contactRingtoneUri;
     }
 
+    void onPostDialWait(String remaining) {
+        for (Listener l : mListeners) {
+            l.onPostDialWait(this, remaining);
+        }
+    }
+
+    void postDialContinue(boolean proceed) {
+        getCallService().onPostDialContinue(this, proceed);
+    }
+
     /**
      * @return True if the call is ringing, else logs the action name.
      */
diff --git a/src/com/android/telecomm/CallServiceWrapper.java b/src/com/android/telecomm/CallServiceWrapper.java
index 41a80e5..945f354 100644
--- a/src/com/android/telecomm/CallServiceWrapper.java
+++ b/src/com/android/telecomm/CallServiceWrapper.java
@@ -57,6 +57,7 @@
         private static final int MSG_SET_DISCONNECTED = 7;
         private static final int MSG_SET_ON_HOLD = 8;
         private static final int MSG_SET_REQUESTING_RINGBACK = 9;
+        private static final int MSG_ON_POST_DIAL_WAIT = 10;
 
         private final Handler mHandler = new Handler() {
             @Override
@@ -153,7 +154,7 @@
                             Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
                         }
                         break;
-                    case MSG_SET_REQUESTING_RINGBACK:
+                    case MSG_SET_REQUESTING_RINGBACK: {
                         SomeArgs args = (SomeArgs) msg.obj;
                         try {
                             call = mCallIdMapper.getCall(args.arg1);
@@ -167,6 +168,20 @@
                             args.recycle();
                         }
                         break;
+                    }
+                    case MSG_ON_POST_DIAL_WAIT:
+                        SomeArgs args = (SomeArgs) msg.obj;
+                        try {
+                            call = mCallIdMapper.getCall(args.arg1);
+                            if (call != null) {
+                                String remaining = (String) args.arg2;
+                                call.onPostDialWait(remaining);
+                            } else {
+                                Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
+                            }
+                        } finally {
+                            args.recycle();
+                        }
                 }
             }
         };
@@ -267,6 +282,15 @@
         @Override
         public void setIsConferenced(String conferenceCallId, String callId, boolean isConferenced) {
         }
+
+        @Override
+        public void onPostDialWait(String callId, String remaining) throws RemoteException {
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = remaining;
+            mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
+        }
     }
 
     private final Adapter mAdapter = new Adapter();
@@ -493,6 +517,15 @@
         mCallIdMapper.removeCall(call);
     }
 
+    void onPostDialContinue(Call call, boolean proceed) {
+        if (isServiceValid("onPostDialContinue")) {
+            try {
+                mServiceInterface.onPostDialContinue(mCallIdMapper.getCallId(call), proceed);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     protected void setServiceInterface(IBinder binder) {
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 727e44d..5433467 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -171,6 +171,11 @@
         }
     }
 
+    @Override
+    public void onPostDialWait(Call call, String remaining) {
+        mInCallController.onPostDialWait(call, remaining);
+    }
+
     ImmutableCollection<Call> getCalls() {
         return ImmutableList.copyOf(mCalls);
     }
@@ -322,15 +327,13 @@
     }
 
     /**
-     * Instructs Telecomm to continue the current post-dial DTMF string, if any.
+     * Instructs Telecomm to continue (or not) the current post-dial DTMF string, if any.
      */
-    void postDialContinue(Call call) {
+    void postDialContinue(Call call, boolean proceed) {
         if (!mCalls.contains(call)) {
             Log.i(this, "Request to continue post-dial string in a non-existent call %s", call);
         } else {
-            // TODO(ihab): Implement this from this level on downwards
-            // call.postDialContinue();
-            // Must play tones locally -- see DTMFTonePlayer.java in Telephony
+            call.postDialContinue(proceed);
         }
     }
 
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index b4ebb07..0dfcae8 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -19,6 +19,7 @@
 import android.os.Handler;
 import android.os.Message;
 
+import com.android.internal.os.SomeArgs;
 import com.android.internal.telecomm.IInCallAdapter;
 
 /**
@@ -65,7 +66,7 @@
                     mCallsManager.stopDtmfTone(call);
                     break;
                 case MSG_POST_DIAL_CONTINUE:
-                    mCallsManager.postDialContinue(call);
+                    mCallsManager.postDialContinue(call, msg.arg1 == 1);
                     break;
                 case MSG_DISCONNECT_CALL:
                     mCallsManager.disconnectCall(call);
@@ -134,10 +135,10 @@
 
     /** {@inheritDoc} */
     @Override
-    public void postDialContinue(String callId) {
+    public void postDialContinue(String callId, boolean proceed) {
         Log.d(this, "postDialContinue(%s)", callId);
         mCallIdMapper.checkValidCallId(callId);
-        mHandler.obtainMessage(MSG_POST_DIAL_CONTINUE, callId).sendToTarget();
+        mHandler.obtainMessage(MSG_POST_DIAL_CONTINUE, proceed ? 1 : 0, 0, callId).sendToTarget();
     }
 
     /** {@inheritDoc} */
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index 4bba241..6078186 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -142,6 +142,16 @@
         }
     }
 
+    void onPostDialWait(Call call, String remaining) {
+        if (mInCallService != null) {
+            Log.i(this, "Calling onPostDialWait, remaining = %s", remaining);
+            try {
+                mInCallService.setPostDialWait(mCallIdMapper.getCallId(call), remaining);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     void bringToForeground(boolean showDialpad) {
         if (mInCallService != null) {
             try {