DTMF dialing support in packages/services/Telecomm

Change-Id: I86522cedea9617dd420a568aad44c220fc3ef49b
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 88ec312..3e4895b 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -303,6 +303,30 @@
     }
 
     /**
+     * Plays the specified DTMF tone.
+     */
+    void playDtmfTone(char digit) {
+        if (mCallService == null) {
+            Log.w(this, "playDtmfTone() request on a call without a call service.");
+        } else {
+            Log.i(this, "Send playDtmfTone to call service for call with id %s", mId);
+            mCallService.playDtmfTone(mId, digit);
+        }
+    }
+
+    /**
+     * Stops playing any currently playing DTMF tone.
+     */
+    void stopDtmfTone() {
+        if (mCallService == null) {
+            Log.w(this, "stopDtmfTone() request on a call without a call service.");
+        } else {
+            Log.i(this, "Send stopDtmfTone to call service for call with id %s", mId);
+            mCallService.stopDtmfTone(mId);
+        }
+    }
+
+    /**
      * Attempts to disconnect the call through the call service.
      */
     void disconnect() {
diff --git a/src/com/android/telecomm/CallServiceWrapper.java b/src/com/android/telecomm/CallServiceWrapper.java
index 0722ec6..4475b2d 100644
--- a/src/com/android/telecomm/CallServiceWrapper.java
+++ b/src/com/android/telecomm/CallServiceWrapper.java
@@ -135,7 +135,7 @@
          mBinder.bind(callback);
     }
 
-    /** See {@link ICallService#abort}. */
+    /** @see CallService#abort(String) */
     void abort(String callId) {
         mAdapter.removePendingOutgoingCallId(callId);
         if (isServiceValid("abort")) {
@@ -147,7 +147,7 @@
         }
     }
 
-    /** See {@link ICallService#hold}. */
+    /** @see CallService#hold(String) */
     void hold(String callId) {
         if (isServiceValid("hold")) {
             try {
@@ -158,7 +158,7 @@
         }
     }
 
-    /** See {@link ICallService#unhold}. */
+    /** @see CallService#unhold(String) */
     void unhold(String callId) {
         if (isServiceValid("unhold")) {
             try {
@@ -169,7 +169,7 @@
         }
     }
 
-    /** See {@link ICallService#onAudioStateChanged}. */
+    /** @see CallService#onAudioStateChanged(String,CallAudioState) */
     void onAudioStateChanged(String activeCallId, CallAudioState audioState) {
         if (isServiceValid("onAudioStateChanged")) {
             try {
@@ -217,7 +217,7 @@
         mBinder.bind(callback);
     }
 
-    /** See {@link ICallService#disconnect}. */
+    /** @see CallService#disconnect(String) */
     void disconnect(String callId) {
         if (isServiceValid("disconnect")) {
             try {
@@ -228,7 +228,7 @@
         }
     }
 
-    /** See {@link ICallService#answer}. */
+    /** @see CallService#answer(String) */
     void answer(String callId) {
         if (isServiceValid("answer")) {
             try {
@@ -239,13 +239,35 @@
         }
     }
 
-    /** See {@link ICallService#reject}. */
+    /** @see CallService#reject(String) */
     void reject(String callId) {
         if (isServiceValid("reject")) {
             try {
                 mServiceInterface.reject(callId);
             } catch (RemoteException e) {
-                Log.e(this, e, "Failed to reject call %s");
+                Log.e(this, e, "Failed to reject call %s", callId);
+            }
+        }
+    }
+
+    /** @see CallService#playDtmfTone(String,char) */
+    void playDtmfTone(String callId, char digit) {
+        if (isServiceValid("playDtmfTone")) {
+            try {
+                mServiceInterface.playDtmfTone(callId, digit);
+            } catch (RemoteException e) {
+                Log.e(this, e, "Failed to play DTMF tone for call %s", callId);
+            }
+        }
+    }
+
+    /** @see CallService#stopDtmfTone(String) */
+    void stopDtmfTone(String callId) {
+        if (isServiceValid("stopDtmfTone")) {
+            try {
+                mServiceInterface.stopDtmfTone(callId);
+            } catch (RemoteException e) {
+                Log.e(this, e, "Failed to stop DTMF tone for call %s", callId);
             }
         }
     }
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 6daaba0..3821426 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -287,6 +287,51 @@
     }
 
     /**
+     * Instructs Telecomm to play the specified DTMF tone within the specified call.
+     *
+     * @param callId The ID of the call.
+     * @param digit The DTMF digit to play.
+     */
+    void playDtmfTone(String callId, char digit) {
+        Call call = mCalls.get(callId);
+        if (call == null) {
+            Log.i(this, "Request to play DTMF in a non-existent call %s", callId);
+        } else {
+            call.playDtmfTone(digit);
+        }
+    }
+
+    /**
+     * Instructs Telecomm to stop the currently playing DTMF tone, if any.
+     *
+     * @param callId The ID of the call.
+     */
+    void stopDtmfTone(String callId) {
+        Call call = mCalls.get(callId);
+        if (call == null) {
+            Log.i(this, "Request to stop DTMF in a non-existent call %s", callId);
+        } else {
+            call.stopDtmfTone();
+        }
+    }
+
+    /**
+     * Instructs Telecomm to continue the current post-dial DTMF string, if any.
+     *
+     * @param callId The ID of the call.
+     */
+    void postDialContinue(String callId) {
+        Call call = mCalls.get(callId);
+        if (call == null) {
+            Log.i(this, "Request to continue post-dial string in a non-existent call %s", callId);
+        } else {
+            // TODO(ihab): Implement this from this level on downwards
+            // call.postDialContinue();
+            // Must play tones locally -- see DTMFTonePlayer.java in Telephony
+        }
+    }
+
+    /**
      * Instructs Telecomm to disconnect the specified call. Intended to be invoked by the
      * in-call app through {@link InCallAdapter} for an ongoing call. This is usually triggered by
      * the user hitting the end-call button.
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index e61c919..fec3080 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -60,6 +60,36 @@
     }
 
     /** {@inheritDoc} */
+    public void playDtmfTone(final String callId, final char digit) {
+        Log.d(this, "playDtmfTone(%s,%c)", callId, digit);
+        mHandler.post(new Runnable() {
+            @Override public void run() {
+                mCallsManager.playDtmfTone(callId, digit);
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
+    public void stopDtmfTone(final String callId) {
+        Log.d(this, "stopDtmfTone(%s)", callId);
+        mHandler.post(new Runnable() {
+            @Override public void run() {
+                mCallsManager.stopDtmfTone(callId);
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
+    public void postDialContinue(final String callId) {
+        Log.d(this, "postDialContinue(%s)", callId);
+        mHandler.post(new Runnable() {
+            @Override public void run() {
+                mCallsManager.postDialContinue(callId);
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
     @Override
     public void disconnectCall(final String callId) {
         mHandler.post(new Runnable() {