Merge "Fixes bug of voicemail check for waiting call" into klp-dev
diff --git a/common/src/com/android/services/telephony/common/Call.java b/common/src/com/android/services/telephony/common/Call.java
index 0aaf12d..f5cc904 100644
--- a/common/src/com/android/services/telephony/common/Call.java
+++ b/common/src/com/android/services/telephony/common/Call.java
@@ -48,8 +48,9 @@
         public static final int CALL_WAITING = 4;   /* Incoming call while another is active */
         public static final int DIALING = 5;        /* An outgoing call during dial phase */
         public static final int ONHOLD = 6;         /* An active phone call placed on hold */
-        public static final int DISCONNECTED = 7;   /* State after a call disconnects */
-        public static final int CONFERENCED = 8;    /* Call part of a conference call */
+        public static final int DISCONNECTING = 7;  /* A call is being ended. */
+        public static final int DISCONNECTED = 8;   /* State after a call disconnects */
+        public static final int CONFERENCED = 9;    /* Call part of a conference call */
 
         public static boolean isConnected(int state) {
             switch(state) {
@@ -142,6 +143,7 @@
             .put(Call.State.INCOMING, "INCOMING")
             .put(Call.State.ONHOLD, "ONHOLD")
             .put(Call.State.INVALID, "INVALID")
+            .put(Call.State.DISCONNECTING, "DISCONNECTING")
             .put(Call.State.DISCONNECTED, "DISCONNECTED")
             .put(Call.State.CONFERENCED, "CONFERENCED")
             .build();
diff --git a/src/com/android/phone/BluetoothManager.java b/src/com/android/phone/BluetoothManager.java
index ffce465..443c950 100644
--- a/src/com/android/phone/BluetoothManager.java
+++ b/src/com/android/phone/BluetoothManager.java
@@ -32,6 +32,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Connection;
 import com.android.services.telephony.common.Call;
 
 import java.util.List;
@@ -416,7 +417,7 @@
     }
 
     @Override
-    public void onPostDialWait(int callId, String chars) {
+    public void onPostDialAction(Connection.PostDialState state, int callId, String chars, char c) {
         // no-op
     }
 
diff --git a/src/com/android/phone/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index 2f71457..1b05214 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -31,8 +31,11 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Connection.PostDialState;
 import com.android.phone.AudioRouter.AudioModeListener;
 import com.android.phone.NotificationMgr.StatusBarHelper;
 import com.android.services.telephony.common.AudioMode;
@@ -154,7 +157,7 @@
             Log.d(TAG, "onIncoming: " + call);
         }
         try {
-            // TODO(klp): check RespondViaSmsManager.allowRespondViaSmsForCall()
+            // TODO: check RespondViaSmsManager.allowRespondViaSmsForCall()
             // must refactor call method to accept proper call object.
             synchronized (mServiceAndQueueLock) {
                 if (mCallHandlerServiceGuarded != null) {
@@ -207,7 +210,9 @@
 
 
     @Override
-    public void onPostDialWait(int callId, String remainingChars) {
+    public void onPostDialAction(Connection.PostDialState state, int callId, String remainingChars,
+            char currentChar) {
+        if (state != PostDialState.WAIT) return;
         try {
             synchronized (mServiceAndQueueLock) {
                 if (mCallHandlerServiceGuarded == null) {
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index 75da0be..02f0809 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -224,7 +224,8 @@
                     state == Call.State.CONFERENCED ||
                     state == Call.State.DIALING ||
                     state == Call.State.INCOMING ||
-                    state == Call.State.ONHOLD) {
+                    state == Call.State.ONHOLD ||
+                    state == Call.State.DISCONNECTING) {
                 return true;
             }
         }
@@ -265,20 +266,23 @@
             final Connection.PostDialState state = (Connection.PostDialState) r.userObj;
 
             switch (state) {
-                // TODO(klp): add other post dial related functions
                 case WAIT:
                     final Call call = getCallFromMap(mCallMap, c, false);
                     if (call == null) {
                         Log.i(TAG, "Call no longer exists. Skipping onPostDialWait().");
                     } else {
                         for (Listener mListener : mListeners) {
-                            mListener.onPostDialWait(call.getCallId(),
-                                    c.getRemainingPostDialString());
+                            mListener.onPostDialAction(state, call.getCallId(),
+                                    c.getRemainingPostDialString(), ch);
                         }
                     }
                     break;
-
                 default:
+                    // This is primarily to cause the DTMFTonePlayer to play local tones.
+                    // Other listeners simply perform no-ops.
+                    for (Listener mListener : mListeners) {
+                        mListener.onPostDialAction(state, 0, "", ch);
+                    }
                     break;
             }
         }
@@ -353,12 +357,16 @@
         for (com.android.internal.telephony.Call telephonyCall : telephonyCalls) {
 
             for (Connection connection : telephonyCall.getConnections()) {
-                if (DBG) Log.d(TAG, "connection: " + connection);
+                if (DBG) Log.d(TAG, "connection: " + connection + connection.getState());
 
                 // We only send updates for live calls which are not incoming (ringing).
                 // Disconnected and incoming calls are handled by onDisconnect and
                 // onNewRingingConnection.
-                boolean shouldUpdate = connection.getState().isAlive() &&
+                boolean shouldUpdate =
+                        connection.getState() !=
+                                com.android.internal.telephony.Call.State.DISCONNECTED &&
+                        connection.getState() !=
+                                com.android.internal.telephony.Call.State.IDLE &&
                         !connection.getState().isRinging();
 
                 // New connections return a Call with INVALID state, which does not translate to
@@ -705,8 +713,10 @@
             case HOLDING:
                 retval = State.ONHOLD;
                 break;
-            case DISCONNECTED:
             case DISCONNECTING:
+                retval = State.DISCONNECTING;
+                break;
+            case DISCONNECTED:
                 retval = State.DISCONNECTED;
             default:
         }
@@ -840,7 +850,8 @@
         void onDisconnect(Call call);
         void onIncoming(Call call);
         void onUpdate(List<Call> calls);
-        void onPostDialWait(int callId, String remainingChars);
+        void onPostDialAction(Connection.PostDialState state, int callId, String remainingChars,
+                char c);
     }
 
     /**
diff --git a/src/com/android/phone/DTMFTonePlayer.java b/src/com/android/phone/DTMFTonePlayer.java
index 0acd114..b8adaf1 100644
--- a/src/com/android/phone/DTMFTonePlayer.java
+++ b/src/com/android/phone/DTMFTonePlayer.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Connection.PostDialState;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.services.telephony.common.Call;
@@ -124,8 +125,25 @@
     }
 
     @Override
-    public void onPostDialWait(int callId, String chars) {
-        // no-op
+    public void onPostDialAction(PostDialState state, int callId, String remainingChars,
+            char currentChar) {
+        switch (state) {
+            case STARTED:
+                stopLocalToneIfNeeded();
+                if (!mToneMap.containsKey(currentChar)) {
+                    return;
+                }
+                startLocalToneIfNeeded(currentChar);
+                break;
+            case PAUSE:
+            case WAIT:
+            case WILD:
+            case COMPLETE:
+                stopLocalToneIfNeeded();
+                break;
+            default:
+                break;
+        }
     }
 
     /**
@@ -387,5 +405,4 @@
             Log.d(LOG_TAG, msg);
         }
     }
-
 }
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 06b8969..6744d33 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -922,9 +922,8 @@
                     mUpdateLock.acquire();
                 }
             } else {
-                if (!mUpdateLock.isHeld()) {
+                if (mUpdateLock.isHeld()) {
                     mUpdateLock.release();
-                } else {
                 }
             }
         }
@@ -934,13 +933,6 @@
         return mLastPhoneState;
     }
 
-    /**
-     * Returns UpdateLock object.
-     */
-    /* package */ UpdateLock getUpdateLock() {
-        return mUpdateLock;
-    }
-
     KeyguardManager getKeyguardManager() {
         return mKeyguardManager;
     }
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index c3abd9f..6e8abfd 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -2415,7 +2415,7 @@
             if (DBG) log("activateSpeakerIfDocked(): In a dock -> may need to turn on speaker.");
             final PhoneGlobals app = PhoneGlobals.getInstance();
 
-            // TODO(klp): This function should move to AudioRouter
+            // TODO: This function should move to AudioRouter
             final BluetoothManager btManager = app.getBluetoothManager();
             final WiredHeadsetManager wiredHeadset = app.getWiredHeadsetManager();
             final AudioRouter audioRouter = app.getAudioRouter();