Update tests

ConnectionServiceFixture now does not use Mockito when() allowing
reset() at any time. Added tests for incoming calls.

Change-Id: Ic5f5fc7b910a97d2838090713439f703d80748c6
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index bf7834e..c6e8e7a 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -27,7 +27,6 @@
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
-import android.annotation.TargetApi;
 import android.app.AppOpsManager;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -307,13 +306,6 @@
         when(mNotificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(true);
 
         when(mUserManager.getSerialNumberForUser(any(UserHandle.class))).thenReturn(-1L);
-
-        try {
-            when(mApplicationContextSpy.getFilesDir())
-                    .thenReturn(new File(File.createTempFile("foo", "bar").getParent()));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
     }
 
     @Override
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index a8841cd..7ff601a 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -20,16 +20,18 @@
 import com.android.internal.telecom.IConnectionServiceAdapter;
 import com.android.internal.telecom.IVideoProvider;
 import com.android.internal.telecom.RemoteServiceCallback;
+import com.android.server.telecom.Log;
 
 import junit.framework.TestCase;
 
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
 import android.content.ComponentName;
 import android.os.IBinder;
+import android.os.IInterface;
 import android.os.RemoteException;
+import android.telecom.AudioState;
+import android.telecom.CallAudioState;
 import android.telecom.Connection;
 import android.telecom.ConnectionRequest;
 import android.telecom.DisconnectCause;
@@ -46,9 +48,6 @@
 import java.util.Set;
 
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.when;
 
 /**
  * Controls a test {@link IConnectionService} as would be provided by a source of connectivity
@@ -56,8 +55,103 @@
  */
 public class ConnectionServiceFixture implements TestFixture<IConnectionService> {
 
-    private IConnectionService.Stub mConnectionService =
-            Mockito.mock(IConnectionService.Stub.class);
+    public class FakeConnectionService extends IConnectionService.Stub {
+
+        @Override
+        public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter)
+                throws RemoteException {
+            if (!mConnectionServiceAdapters.add(adapter)) {
+                throw new RuntimeException("Adapter already added: " + adapter);
+            }
+        }
+
+        @Override
+        public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter)
+                throws RemoteException {
+            if (!mConnectionServiceAdapters.remove(adapter)) {
+                throw new RuntimeException("Adapter never added: " + adapter);
+            }
+        }
+
+        @Override
+        public void createConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+                String id,
+                ConnectionRequest request, boolean isIncoming, boolean isUnknown)
+                throws RemoteException {
+            Log.i(ConnectionServiceFixture.this, "xoxox createConnection --> " + id);
+
+            if (mConnectionById.containsKey(id)) {
+                throw new RuntimeException("Connection already exists: " + id);
+            }
+            mLatestConnectionId = id;
+            ConnectionInfo c = new ConnectionInfo();
+            c.connectionManagerPhoneAccount = connectionManagerPhoneAccount;
+            c.id = id;
+            c.request = request;
+            c.isIncoming = isIncoming;
+            c.isUnknown = isUnknown;
+            mConnectionById.put(id, c);
+        }
+
+        @Override
+        public void abort(String callId) throws RemoteException { }
+
+        @Override
+        public void answerVideo(String callId, int videoState) throws RemoteException { }
+
+        @Override
+        public void answer(String callId) throws RemoteException { }
+
+        @Override
+        public void reject(String callId) throws RemoteException { }
+
+        @Override
+        public void disconnect(String callId) throws RemoteException { }
+
+        @Override
+        public void hold(String callId) throws RemoteException { }
+
+        @Override
+        public void unhold(String callId) throws RemoteException { }
+
+        @Override
+        public void onCallAudioStateChanged(String activeCallId, CallAudioState audioState)
+                throws RemoteException { }
+
+        @Override
+        public void playDtmfTone(String callId, char digit) throws RemoteException { }
+
+        @Override
+        public void stopDtmfTone(String callId) throws RemoteException { }
+
+        @Override
+        public void conference(String conferenceCallId, String callId) throws RemoteException { }
+
+        @Override
+        public void splitFromConference(String callId) throws RemoteException { }
+
+        @Override
+        public void mergeConference(String conferenceCallId) throws RemoteException { }
+
+        @Override
+        public void swapConference(String conferenceCallId) throws RemoteException { }
+
+        @Override
+        public void onPostDialContinue(String callId, boolean proceed) throws RemoteException { }
+
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+
+        @Override
+        public IInterface queryLocalInterface(String descriptor) {
+            return this;
+        }
+    };
+
+    private IConnectionService.Stub mConnectionService = new FakeConnectionService();
+    private IConnectionService.Stub mConnectionServiceSpy = Mockito.spy(mConnectionService);
 
     public class ConnectionInfo {
         PhoneAccountHandle connectionManagerPhoneAccount;
@@ -98,66 +192,11 @@
     public final List<ComponentName> mRemoteConnectionServiceNames = new ArrayList<>();
     public final List<IBinder> mRemoteConnectionServices = new ArrayList<>();
 
-    public ConnectionServiceFixture() throws Exception {
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable {
-                IConnectionServiceAdapter a = (IConnectionServiceAdapter)
-                        invocation.getArguments()[0];
-                if (!mConnectionServiceAdapters.add(a)) {
-                    throw new RuntimeException("Adapter already added: " + a);
-                }
-                return null;
-            }
-        }).when(mConnectionService).addConnectionServiceAdapter(
-                any(IConnectionServiceAdapter.class));
-
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable {
-                IConnectionServiceAdapter a = (IConnectionServiceAdapter)
-                        invocation.getArguments()[0];
-                if (!mConnectionServiceAdapters.remove(a)) {
-                    throw new RuntimeException("Adapter never added: " + a);
-                }
-                return null;
-            }
-        }).when(mConnectionService).removeConnectionServiceAdapter(
-                any(IConnectionServiceAdapter.class));
-
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable {
-                String id = (String) invocation.getArguments()[1];
-                if (mConnectionById.containsKey(id)) {
-                    throw new RuntimeException("Connection already exists: " + id);
-                }
-                mLatestConnectionId = id;
-                ConnectionInfo c = new ConnectionInfo();
-                c.connectionManagerPhoneAccount = (PhoneAccountHandle) invocation.getArguments()[0];
-                c.id = id;
-                c.request = (ConnectionRequest) invocation.getArguments()[2];
-                c.isIncoming = (boolean) invocation.getArguments()[3];
-                c.isUnknown = (boolean) invocation.getArguments()[4];
-                mConnectionById.put(id, c);
-                return null;
-            }
-        }).when(mConnectionService).createConnection(
-                any(PhoneAccountHandle.class),
-                any(String.class),
-                any(ConnectionRequest.class),
-                any(Boolean.TYPE),
-                any(Boolean.TYPE));
-
-        when(mConnectionService.asBinder())
-                .thenReturn(mConnectionService);
-        when(mConnectionService.queryLocalInterface(anyString()))
-                .thenReturn(mConnectionService);
-    }
+    public ConnectionServiceFixture() throws Exception { }
 
     @Override
     public IConnectionService getTestDouble() {
-        return mConnectionService;
+        return mConnectionServiceSpy;
     }
 
     public void sendHandleCreateConnectionComplete(String id) throws Exception {
diff --git a/tests/src/com/android/server/telecom/tests/TODO b/tests/src/com/android/server/telecom/tests/TODO
index f1d9acc..f412b4a 100644
--- a/tests/src/com/android/server/telecom/tests/TODO
+++ b/tests/src/com/android/server/telecom/tests/TODO
@@ -1,3 +1,14 @@
 * Implement acquireProvider("settings")
 * Implement acquireUnstableProvider("com.android.contacts")
-* ComponentContextFixture to have "setUp/tearDown" to check for things like un-released providers
\ No newline at end of file
+* ComponentContextFixture to have "setUp/tearDown" to check for things like un-released providers
+
+Bluetooth
+Speakerphone and audio modes
+Video calling
+Connection managers
+DTMF tones
+Call logging
+Ringback
+Missed calls
+Respond via SMS
+Permissions in registering PhoneAccounts
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index ad48370..a8853d3 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -117,7 +118,7 @@
     final PhoneAccount mPhoneAccountB0 =
             PhoneAccount.builder(
                     new PhoneAccountHandle(
-                            mConnectionServiceComponentNameA,
+                            mConnectionServiceComponentNameB,
                             "id B 0"),
                     "Phone account service B ID 0")
                     .addSupportedUriScheme("tel")
@@ -133,6 +134,16 @@
 
     TelecomSystem mTelecomSystem;
 
+    class IdPair {
+        final String mConnectionId;
+        final String mCallId;
+
+        public IdPair(String connectionId, String callId) {
+            this.mConnectionId = connectionId;
+            this.mCallId = callId;
+        }
+    }
+
     @Override
     public void setUp() throws Exception {
         super.setUp();
@@ -237,10 +248,26 @@
                 mInCallServiceFixtureY.getTestDouble());
     }
 
-    private String startOutgoingPhoneCall(
+    private IdPair startOutgoingPhoneCall(
             String number,
             PhoneAccountHandle phoneAccountHandle,
             ConnectionServiceFixture connectionServiceFixture) throws Exception {
+        reset(
+                connectionServiceFixture.getTestDouble(),
+                mInCallServiceFixtureX.getTestDouble(),
+                mInCallServiceFixtureY.getTestDouble());
+
+        assertEquals(
+                mInCallServiceFixtureX.mCallById.size(),
+                mInCallServiceFixtureY.mCallById.size());
+        assertEquals(
+                (mInCallServiceFixtureX.mInCallAdapter != null),
+                (mInCallServiceFixtureY.mInCallAdapter != null));
+
+        int startingNumConnections = connectionServiceFixture.mConnectionById.size();
+        int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
+        boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null;
+
         Intent actionCallIntent = new Intent();
         actionCallIntent.setData(Uri.parse("tel:" + number));
         actionCallIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
@@ -253,6 +280,15 @@
 
         mTelecomSystem.getCallIntentProcessor().processIntent(actionCallIntent);
 
+        if (!hasInCallAdapter) {
+            verify(mInCallServiceFixtureX.getTestDouble())
+                    .setInCallAdapter(
+                            any(IInCallAdapter.class));
+            verify(mInCallServiceFixtureY.getTestDouble())
+                    .setInCallAdapter(
+                            any(IInCallAdapter.class));
+        }
+
         ArgumentCaptor<Intent> newOutgoingCallIntent =
                 ArgumentCaptor.forClass(Intent.class);
         ArgumentCaptor<BroadcastReceiver> newOutgoingCallReceiver =
@@ -283,6 +319,8 @@
                 mComponentContextFixture.getTestDouble(),
                 newOutgoingCallIntent.getValue());
 
+        assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size());
+
         verify(connectionServiceFixture.getTestDouble()).createConnection(
                 eq(phoneAccountHandle),
                 anyString(),
@@ -290,17 +328,41 @@
                 anyBoolean(),
                 anyBoolean());
 
-        String id = connectionServiceFixture.mLatestConnectionId;
+        connectionServiceFixture.sendHandleCreateConnectionComplete(
+                connectionServiceFixture.mLatestConnectionId);
 
-        connectionServiceFixture.sendHandleCreateConnectionComplete(id);
+        assertEquals(startingNumCalls + 1, mInCallServiceFixtureX.mCallById.size());
+        assertEquals(startingNumCalls + 1, mInCallServiceFixtureY.mCallById.size());
 
-        return id;
+        assertEquals(
+                mInCallServiceFixtureX.mLatestCallId,
+                mInCallServiceFixtureY.mLatestCallId);
+
+        return new IdPair(
+                connectionServiceFixture.mLatestConnectionId,
+                mInCallServiceFixtureX.mLatestCallId);
     }
 
-    private String startIncomingPhoneCall(
+    private IdPair startIncomingPhoneCall(
             String number,
             PhoneAccountHandle phoneAccountHandle,
             ConnectionServiceFixture connectionServiceFixture) throws Exception {
+        reset(
+                connectionServiceFixture.getTestDouble(),
+                mInCallServiceFixtureX.getTestDouble(),
+                mInCallServiceFixtureY.getTestDouble());
+
+        assertEquals(
+                mInCallServiceFixtureX.mCallById.size(),
+                mInCallServiceFixtureY.mCallById.size());
+        assertEquals(
+                (mInCallServiceFixtureX.mInCallAdapter != null),
+                (mInCallServiceFixtureY.mInCallAdapter != null));
+
+        int startingNumConnections = connectionServiceFixture.mConnectionById.size();
+        int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
+        boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null;
+
         Bundle extras = new Bundle();
         extras.putParcelable(
                 TelephonyManager.EXTRA_INCOMING_NUMBER,
@@ -315,26 +377,31 @@
                 eq(true),
                 eq(false));
 
-        String id = connectionServiceFixture.mLatestConnectionId;
-
-        connectionServiceFixture.sendHandleCreateConnectionComplete(id);
-        connectionServiceFixture.sendSetRinging(id);
+        connectionServiceFixture.sendHandleCreateConnectionComplete(
+                connectionServiceFixture.mLatestConnectionId);
+        connectionServiceFixture.sendSetRinging(
+                connectionServiceFixture.mLatestConnectionId);
 
         // For the case of incoming calls, Telecom connecting the InCall services and adding the
         // Call is triggered by the async completion of the CallerInfoAsyncQuery. Once the Call
         // is added, future interactions as triggered by the ConnectionService, through the various
         // test fixtures, will be synchronous.
 
-        verify(
-                mInCallServiceFixtureX.getTestDouble(),
-                timeout(TEST_TIMEOUT))
-                .setInCallAdapter(
-                        any(IInCallAdapter.class));
-        verify(
-                mInCallServiceFixtureY.getTestDouble(),
-                timeout(TEST_TIMEOUT))
-                .setInCallAdapter(
-                        any(IInCallAdapter.class));
+        if (!hasInCallAdapter) {
+            verify(
+                    mInCallServiceFixtureX.getTestDouble(),
+                    timeout(TEST_TIMEOUT))
+                    .setInCallAdapter(
+                            any(IInCallAdapter.class));
+            verify(
+                    mInCallServiceFixtureY.getTestDouble(),
+                    timeout(TEST_TIMEOUT))
+                    .setInCallAdapter(
+                            any(IInCallAdapter.class));
+        }
+
+        // Give the InCallService time to respond
+        pause();
 
         assertNotNull(mInCallServiceFixtureX.mInCallAdapter);
         assertNotNull(mInCallServiceFixtureY.mInCallAdapter);
@@ -350,7 +417,20 @@
                 .addCall(
                         any(ParcelableCall.class));
 
-        return id;
+        // Give the InCallService time to respond
+        pause();
+
+        assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size());
+        assertEquals(startingNumCalls + 1, mInCallServiceFixtureX.mCallById.size());
+        assertEquals(startingNumCalls + 1, mInCallServiceFixtureY.mCallById.size());
+
+        assertEquals(
+                mInCallServiceFixtureX.mLatestCallId,
+                mInCallServiceFixtureY.mLatestCallId);
+
+        return new IdPair(
+                connectionServiceFixture.mLatestConnectionId,
+                mInCallServiceFixtureX.mLatestCallId);
     }
 
     private void rapidFire(Runnable... tasks) {
@@ -381,80 +461,95 @@
 
     // A simple outgoing call, verifying that the appropriate connection service is contacted,
     // the proper lifecycle is followed, and both In-Call Services are updated correctly.
-    public void testSingleOutgoingCall() throws Exception {
-        String connectionId = startOutgoingPhoneCall(
+    private IdPair startAndMakeActiveOutgoingCall(
+            String number,
+            PhoneAccountHandle phoneAccountHandle,
+            ConnectionServiceFixture connectionServiceFixture) throws Exception {
+        IdPair ids = startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture);
+
+        connectionServiceFixture.sendSetDialing(ids.mConnectionId);
+
+        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+        connectionServiceFixture.sendSetActive(ids.mConnectionId);
+        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+        return ids;
+    }
+
+    public void testSingleOutgoingCallLocalDisconnect() throws Exception {
+        IdPair ids = startAndMakeActiveOutgoingCall(
                 "650-555-1212",
                 mPhoneAccountA0.getAccountHandle(),
                 mConnectionServiceFixtureA);
 
-        assertEquals(1, mConnectionServiceFixtureA.mConnectionServiceAdapters.size());
-        assertEquals(1, mConnectionServiceFixtureA.mConnectionById.size());
+        mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
+        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
 
-        mConnectionServiceFixtureA.sendSetDialing(connectionId);
+        mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
+        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+    }
 
-        assertEquals(1, mInCallServiceFixtureX.mCallById.size());
-        String callId = mInCallServiceFixtureX.mLatestCallId;
+    public void testSingleOutgoingCallRemoteDisconnect() throws Exception {
+        IdPair ids = startAndMakeActiveOutgoingCall(
+                "650-555-1212",
+                mPhoneAccountA0.getAccountHandle(),
+                mConnectionServiceFixtureA);
 
-        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(callId).getState());
-        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(callId).getState());
-
-        mConnectionServiceFixtureA.sendSetActive(connectionId);
-
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(callId).getState());
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(callId).getState());
-
-        mInCallServiceFixtureX.mInCallAdapter.disconnectCall(callId);;
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(callId).getState());
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(callId).getState());
-
-        mConnectionServiceFixtureA.sendSetDisconnected(connectionId, DisconnectCause.LOCAL);
-        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(callId).getState());
-        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(callId).getState());
+        mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
+        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
     }
 
     // A simple incoming call, similar in scope to the previous test
-    public void testSingleIncomingCall() throws Exception {
-        String connectionId = startIncomingPhoneCall(
+    private IdPair startAndMakeActiveIncomingCall(
+            String number,
+            PhoneAccountHandle phoneAccountHandle,
+            ConnectionServiceFixture connectionServiceFixture) throws Exception {
+        IdPair ids = startIncomingPhoneCall(number, phoneAccountHandle, connectionServiceFixture);
+
+        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+        connectionServiceFixture.sendSetActive(ids.mConnectionId);
+        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
+
+        return ids;
+    }
+
+    public void testSingleIncomingCallLocalDisconnect() throws Exception {
+        IdPair ids = startAndMakeActiveIncomingCall(
                 "650-555-1212",
                 mPhoneAccountA0.getAccountHandle(),
                 mConnectionServiceFixtureA);
 
-        assertEquals(1, mConnectionServiceFixtureA.mConnectionServiceAdapters.size());
-        assertEquals(1, mConnectionServiceFixtureA.mConnectionById.size());
+        mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
+        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
 
-        assertEquals(1, mInCallServiceFixtureX.mCallById.size());
-        String callId = mInCallServiceFixtureX.mLatestCallId;
-
-        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(callId).getState());
-        assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(callId).getState());
-
-        mConnectionServiceFixtureA.sendSetActive(connectionId);
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(callId).getState());
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(callId).getState());
-
-        mInCallServiceFixtureX.mInCallAdapter.disconnectCall(callId);;
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(callId).getState());
-        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(callId).getState());
-
-        mConnectionServiceFixtureA.sendSetDisconnected(connectionId, DisconnectCause.LOCAL);
-        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(callId).getState());
-        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(callId).getState());
+        mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
+        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
     }
 
-    public void testDeadlockOnOutgoingCall() throws Exception {
-        for (int i = 0; i < 100; i++) {
-            TelecomSystemTest test = new TelecomSystemTest();
-            test.setContext(getContext());
-            test.setTestContext(getTestContext());
-            test.setName(getName());
-            test.setUp();
-            test.do_testDeadlockOnOutgoingCall();
-            test.tearDown();
-        }
+    public void testSingleIncomingCallRemoteDisconnect() throws Exception {
+        IdPair ids = startAndMakeActiveIncomingCall(
+                "650-555-1212",
+                mPhoneAccountA0.getAccountHandle(),
+                mConnectionServiceFixtureA);
+
+        mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
+        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
+        assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
     }
 
     public void do_testDeadlockOnOutgoingCall() throws Exception {
-        final String connectionId = startOutgoingPhoneCall(
+        final IdPair ids = startOutgoingPhoneCall(
                 "650-555-1212",
                 mPhoneAccountA0.getAccountHandle(),
                 mConnectionServiceFixtureA);
@@ -471,11 +566,55 @@
                     @Override
                     public void run() {
                         try {
-                            mConnectionServiceFixtureA.sendSetActive(connectionId);
+                            mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId);
                         } catch (Exception e) {
                             Log.e(this, e, "");
                         }
                     }
                 });
     }
+
+    public void testDeadlockOnOutgoingCall() throws Exception {
+        for (int i = 0; i < 100; i++) {
+            TelecomSystemTest test = new TelecomSystemTest();
+            test.setContext(getContext());
+            test.setTestContext(getTestContext());
+            test.setName(getName());
+            test.setUp();
+            test.do_testDeadlockOnOutgoingCall();
+            test.tearDown();
+        }
+    }
+
+    public void testIncomingThenOutgoingCalls() throws Exception {
+        // TODO: We have to use the same PhoneAccount for both; see http://b/18461539
+        IdPair incoming = startAndMakeActiveIncomingCall(
+                "650-555-2323",
+                mPhoneAccountA0.getAccountHandle(),
+                mConnectionServiceFixtureA);
+        IdPair outgoing = startAndMakeActiveOutgoingCall(
+                "650-555-1212",
+                mPhoneAccountA0.getAccountHandle(),
+                mConnectionServiceFixtureA);
+    }
+
+    public void testOutgoingThenIncomingCalls() throws Exception {
+        // TODO: We have to use the same PhoneAccount for both; see http://b/18461539
+        IdPair outgoing = startAndMakeActiveOutgoingCall(
+                "650-555-1212",
+                mPhoneAccountA0.getAccountHandle(),
+                mConnectionServiceFixtureA);
+        IdPair incoming = startAndMakeActiveIncomingCall(
+                "650-555-2323",
+                mPhoneAccountA0.getAccountHandle(),
+                mConnectionServiceFixtureA);
+    }
+
+    protected static void pause() {
+        try {
+            Thread.sleep(TEST_TIMEOUT);
+        } catch (InterruptedException e) {
+            fail(e.toString());
+        }
+    }
 }