Merge "Ensure DISCONNECTING state is passed to the InCallService on local disc." into rvc-dev
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index c170599..491aed3 100755
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -821,7 +821,7 @@
         return String.format(Locale.US, "[Call id=%s, state=%s, tpac=%s, cmgr=%s, handle=%s, "
                         + "vidst=%s, childs(%d), has_parent(%b), cap=%s, prop=%s]",
                 mId,
-                CallState.toString(mState),
+                CallState.toString(getParcelableCallState()),
                 getTargetPhoneAccount(),
                 getConnectionManagerPhoneAccount(),
                 Log.piiHandle(mHandle),
@@ -964,6 +964,20 @@
     }
 
     /**
+     * Similar to {@link #getState()}, except will return {@link CallState#DISCONNECTING} if the
+     * call is locally disconnecting.  This is the call state which is reported to the
+     * {@link android.telecom.InCallService}s when a call is parcelled.
+     * @return The parcelable call state.
+     */
+    public int getParcelableCallState() {
+        if (isLocallyDisconnecting() &&
+                (mState != android.telecom.Call.STATE_DISCONNECTED)) {
+            return CallState.DISCONNECTING;
+        }
+        return mState;
+    }
+
+    /**
      * Determines if this {@link Call} can receive call focus via the
      * {@link ConnectionServiceFocusManager}.
      * Only top-level calls and non-external calls are eligible.
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index b370815..dac5b4e 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -423,7 +423,7 @@
                         CallAudioRouteStateMachine.NO_INCLUDE_BLUETOOTH_IN_BASELINE);
                 return;
             default:
-                Log.wtf(this, "Invalid route specified: %d", route);
+                Log.w(this, "InCallService requested an invalid audio route: %d", route);
         }
     }
 
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index f2e8bc3..8fac4db 100755
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -2549,7 +2549,11 @@
             Log.w(this, "Unknown call (%s) asked to disconnect", call);
         } else {
             mLocallyDisconnectingCalls.add(call);
+            int previousState = call.getState();
             call.disconnect();
+            for (CallsManagerListener listener : mListeners) {
+                listener.onCallStateChanged(call, previousState, call.getState());
+            }
             // Cancel any of the outgoing call futures if they're still around.
             if (mPendingCallConfirm != null && !mPendingCallConfirm.isDone()) {
                 mPendingCallConfirm.complete(null);
@@ -3524,7 +3528,8 @@
             return;
         }
         int oldState = call.getState();
-        Log.i(this, "setCallState %s -> %s, call: %s", CallState.toString(oldState),
+        Log.i(this, "setCallState %s -> %s, call: %s",
+                CallState.toString(call.getParcelableCallState()),
                 CallState.toString(newState), call);
         if (newState != oldState) {
             // If the call switches to held state while a DTMF tone is playing, stop the tone to
diff --git a/src/com/android/server/telecom/ParcelableCallUtils.java b/src/com/android/server/telecom/ParcelableCallUtils.java
index 9638fee..5c821a4 100644
--- a/src/com/android/server/telecom/ParcelableCallUtils.java
+++ b/src/com/android/server/telecom/ParcelableCallUtils.java
@@ -381,7 +381,7 @@
 
     private static int getParcelableState(Call call, boolean supportsExternalCalls) {
         int state = CallState.NEW;
-        switch (call.getState()) {
+        switch (call.getParcelableCallState()) {
             case CallState.ABORTED:
             case CallState.DISCONNECTED:
                 state = android.telecom.Call.STATE_DISCONNECTED;
@@ -433,12 +433,6 @@
                 break;
         }
 
-        // If we are marked as 'locally disconnecting' then mark ourselves as disconnecting instead.
-        // Unless we're disconnect*ED*, in which case leave it at that.
-        if (call.isLocallyDisconnecting() &&
-                (state != android.telecom.Call.STATE_DISCONNECTED)) {
-            state = android.telecom.Call.STATE_DISCONNECTING;
-        }
         return state;
     }
 
diff --git a/tests/src/com/android/server/telecom/tests/BasicCallTests.java b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
index 8364869..6fd53eb 100644
--- a/tests/src/com/android/server/telecom/tests/BasicCallTests.java
+++ b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
@@ -103,8 +103,10 @@
                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
 
         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DISCONNECTING,
+                mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DISCONNECTING,
+                mInCallServiceFixtureY.getCall(ids.mCallId).getState());
 
         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
@@ -259,12 +261,15 @@
         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DISCONNECTING,
+                mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DISCONNECTING,
+                mInCallServiceFixtureY.getCall(ids.mCallId).getState());
 
         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
         mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
+
         assertEquals(Call.STATE_DISCONNECTED,
                 mInCallServiceFixtureX.getCall(ids.mCallId).getState());
         assertEquals(Call.STATE_DISCONNECTED,
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index e9794e3..9e7680a 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -66,6 +66,7 @@
 import com.android.server.telecom.CallState;
 import com.android.server.telecom.CallerInfoLookupHelper;
 import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.CallsManagerListenerBase;
 import com.android.server.telecom.ClockProxy;
 import com.android.server.telecom.ConnectionServiceFocusManager;
 import com.android.server.telecom.ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory;
@@ -1390,6 +1391,26 @@
         verify(heldCall).unhold(any());
     }
 
+    /**
+     * Verifies we inform the InCallService on local disconnect.
+     * @throws Exception
+     */
+    @SmallTest
+    @Test
+    public void testRequestDisconnect() throws Exception {
+        CallsManager.CallsManagerListener listener = mock(CallsManager.CallsManagerListener.class);
+        mCallsManager.addListener(listener);
+
+        Call ongoingCall = addSpyCall(CallState.ACTIVE);
+        mCallsManager.addCall(ongoingCall);
+
+        mCallsManager.disconnectCall(ongoingCall);
+        // Seems odd, but ultimately the call state is still active even though it is locally
+        // disconnecting.
+        verify(listener).onCallStateChanged(eq(ongoingCall), eq(CallState.ACTIVE),
+                eq(CallState.ACTIVE));
+    }
+
     private Call addSpyCall() {
         return addSpyCall(SIM_2_HANDLE, CallState.ACTIVE);
     }