Merge "Modify Telecom to have "one call ID to rule them all"."
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 8fe6fc1..6000807 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -65,6 +65,8 @@
  */
 @VisibleForTesting
 public class Call implements CreateConnectionResponse {
+    public final static String CALL_ID_UNKNOWN = "-1";
+
     /**
      * Listener for events on the call.
      */
@@ -320,6 +322,7 @@
     private final CallsManager mCallsManager;
     private final TelecomSystem.SyncRoot mLock;
     private final CallerInfoAsyncQueryFactory mCallerInfoAsyncQueryFactory;
+    private final String mId;
 
     private boolean mWasConferencePreviouslyMerged = false;
 
@@ -346,6 +349,7 @@
      * @param isIncoming True if this is an incoming call.
      */
     public Call(
+            String callId,
             Context context,
             CallsManager callsManager,
             TelecomSystem.SyncRoot lock,
@@ -358,6 +362,7 @@
             PhoneAccountHandle targetPhoneAccountHandle,
             boolean isIncoming,
             boolean isConference) {
+        mId = callId;
         mState = isConference ? CallState.ACTIVE : CallState.NEW;
         mContext = context;
         mCallsManager = callsManager;
@@ -392,6 +397,7 @@
      * @param connectTimeMillis The connection time of the call.
      */
     Call(
+            String callId,
             Context context,
             CallsManager callsManager,
             TelecomSystem.SyncRoot lock,
@@ -405,7 +411,7 @@
             boolean isIncoming,
             boolean isConference,
             long connectTimeMillis) {
-        this(context, callsManager, lock, repository, contactsAsyncHelper,
+        this(callId, context, callsManager, lock, repository, contactsAsyncHelper,
                 callerInfoAsyncQueryFactory, handle, gatewayInfo,
                 connectionManagerPhoneAccountHandle, targetPhoneAccountHandle, isIncoming,
                 isConference);
@@ -438,7 +444,7 @@
 
 
         return String.format(Locale.US, "[%s, %s, %s, %s, %s, childs(%d), has_parent(%b), [%s]]",
-                System.identityHashCode(this),
+                mId,
                 CallState.toString(mState),
                 component,
                 Log.piiHandle(mHandle),
@@ -503,6 +509,14 @@
     }
 
     /**
+     * Returns the unique ID for this call as it exists in Telecom.
+     * @return The call ID.
+     */
+    public String getId() {
+        return mId;
+    }
+
+    /**
      * Sets the call state. Although there exists the notion of appropriate state transitions
      * (see {@link CallState}), in practice those expectations break down when cellular systems
      * misbehave and they do this very often. The result is that we do not enforce state transitions
diff --git a/src/com/android/server/telecom/CallIdMapper.java b/src/com/android/server/telecom/CallIdMapper.java
index 8199dfa..f3a3a44 100644
--- a/src/com/android/server/telecom/CallIdMapper.java
+++ b/src/com/android/server/telecom/CallIdMapper.java
@@ -75,12 +75,6 @@
     }
 
     private final BiMap<String, Call> mCalls = new BiMap<>();
-    private final String mCallIdPrefix;
-    private static int sIdCount;
-
-    CallIdMapper(String callIdPrefix) {
-        mCallIdPrefix = callIdPrefix + "@";
-    }
 
     void replaceCall(Call newCall, Call callToReplace) {
         // Use the old call's ID for the new call.
@@ -96,7 +90,7 @@
     }
 
     void addCall(Call call) {
-        addCall(call, getNewId());
+        addCall(call, call.getId());
     }
 
     void removeCall(Call call) {
@@ -111,10 +105,10 @@
     }
 
     String getCallId(Call call) {
-        if (call == null) {
+        if (call == null || mCalls.getKey(call) == null) {
             return null;
         }
-        return mCalls.getKey(call);
+        return call.getId();
     }
 
     Call getCall(Object objId) {
@@ -122,9 +116,6 @@
         if (objId instanceof String) {
             callId = (String) objId;
         }
-        if (!isValidCallId(callId) && !isValidConferenceId(callId)) {
-            return null;
-        }
 
         return mCalls.getValue(callId);
     }
@@ -132,18 +123,4 @@
     void clear() {
         mCalls.clear();
     }
-
-    boolean isValidCallId(String callId) {
-        // Note, no need for thread check, this method is thread safe.
-        return callId != null && callId.startsWith(mCallIdPrefix);
-    }
-
-    boolean isValidConferenceId(String callId) {
-        return callId != null;
-    }
-
-    String getNewId() {
-        sIdCount++;
-        return mCallIdPrefix + sIdCount;
-    }
 }
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index fd78b94..295f5cf 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -97,6 +97,7 @@
 
     private static final int[] LIVE_CALL_STATES =
             {CallState.CONNECTING, CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING, CallState.ACTIVE};
+    public static final String TELECOM_CALL_ID_PREFIX = "TC@";
 
     /**
      * The main call repository. Keeps an instance of all live calls. New incoming and outgoing
@@ -109,6 +110,13 @@
     private final Set<Call> mCalls = Collections.newSetFromMap(
             new ConcurrentHashMap<Call, Boolean>(8, 0.9f, 1));
 
+    /**
+     * The current telecom call ID.  Used when creating new instances of {@link Call}.  Should
+     * only be accessed using the {@link #getNextCallId()} method which synchronizes on the
+     * {@link #mLock} sync root.
+     */
+    private int mCallId = 0;
+
     private final ConnectionServiceRepository mConnectionServiceRepository;
     private final DtmfLocalTonePlayer mDtmfLocalTonePlayer;
     private final InCallController mInCallController;
@@ -492,6 +500,7 @@
             handle = extras.getParcelable(TelephonyManager.EXTRA_INCOMING_NUMBER);
         }
         Call call = new Call(
+                getNextCallId(),
                 mContext,
                 this,
                 mLock,
@@ -515,6 +524,7 @@
         Uri handle = extras.getParcelable(TelecomManager.EXTRA_UNKNOWN_CALL_HANDLE);
         Log.i(this, "addNewUnknownCall with handle: %s", Log.pii(handle));
         Call call = new Call(
+                getNextCallId(),
                 mContext,
                 this,
                 mLock,
@@ -570,6 +580,7 @@
         // Create a call with original handle. The handle may be changed when the call is attached
         // to a connection service, but in most cases will remain the same.
         return new Call(
+                getNextCallId(),
                 mContext,
                 this,
                 mLock,
@@ -1178,6 +1189,7 @@
     }
 
     Call createConferenceCall(
+            String callId,
             PhoneAccountHandle phoneAccount,
             ParcelableConference parcelableConference) {
 
@@ -1189,6 +1201,7 @@
                         parcelableConference.getConnectTimeMillis();
 
         Call call = new Call(
+                callId,
                 mContext,
                 this,
                 mLock,
@@ -1597,6 +1610,7 @@
      */
     Call createCallForExistingConnection(String callId, ParcelableConnection connection) {
         Call call = new Call(
+                getNextCallId(),
                 mContext,
                 this,
                 mLock,
@@ -1624,6 +1638,15 @@
     }
 
     /**
+     * @return A new unique telecom call Id.
+     */
+    private String getNextCallId() {
+        synchronized(mLock) {
+            return TELECOM_CALL_ID_PREFIX + (++mCallId);
+        }
+    }
+
+    /**
      * Dumps the state of the {@link CallsManager}.
      *
      * @param pw The {@code IndentingPrintWriter} to write the state to.
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index b80134e..619fe01 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -70,10 +70,8 @@
             try {
                 synchronized (mLock) {
                     logIncoming("handleCreateConnectionComplete %s", callId);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        ConnectionServiceWrapper.this
-                                .handleCreateConnectionComplete(callId, request, connection);
-                    }
+                    ConnectionServiceWrapper.this
+                            .handleCreateConnectionComplete(callId, request, connection);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -86,14 +84,11 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setActive %s", callId);
-                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                            .isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            mCallsManager.markCallAsActive(call);
-                        } else {
-                            // Log.w(this, "setActive, unknown call id: %s", msg.obj);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.markCallAsActive(call);
+                    } else {
+                        // Log.w(this, "setActive, unknown call id: %s", msg.obj);
                     }
                 }
             } finally {
@@ -107,13 +102,11 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setRinging %s", callId);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            mCallsManager.markCallAsRinging(call);
-                        } else {
-                            // Log.w(this, "setRinging, unknown call id: %s", msg.obj);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.markCallAsRinging(call);
+                    } else {
+                        // Log.w(this, "setRinging, unknown call id: %s", msg.obj);
                     }
                 }
             } finally {
@@ -127,12 +120,9 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setVideoProvider %s", callId);
-                    if (mCallIdMapper.isValidCallId(callId)
-                            || mCallIdMapper.isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setVideoProvider(videoProvider);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setVideoProvider(videoProvider);
                     }
                 }
             } finally {
@@ -146,13 +136,11 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setDialing %s", callId);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            mCallsManager.markCallAsDialing(call);
-                        } else {
-                            // Log.w(this, "setDialing, unknown call id: %s", msg.obj);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.markCallAsDialing(call);
+                    } else {
+                        // Log.w(this, "setDialing, unknown call id: %s", msg.obj);
                     }
                 }
             } finally {
@@ -166,15 +154,12 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setDisconnected %s %s", callId, disconnectCause);
-                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                            .isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        Log.d(this, "disconnect call %s %s", disconnectCause, call);
-                        if (call != null) {
-                            mCallsManager.markCallAsDisconnected(call, disconnectCause);
-                        } else {
-                            // Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    Log.d(this, "disconnect call %s %s", disconnectCause, call);
+                    if (call != null) {
+                        mCallsManager.markCallAsDisconnected(call, disconnectCause);
+                    } else {
+                        // Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
                     }
                 }
             } finally {
@@ -188,14 +173,11 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setOnHold %s", callId);
-                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                            .isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            mCallsManager.markCallAsOnHold(call);
-                        } else {
-                            // Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.markCallAsOnHold(call);
+                    } else {
+                        // Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
                     }
                 }
             } finally {
@@ -209,13 +191,11 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setRingbackRequested %s %b", callId, ringback);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setRingbackRequested(ringback);
-                        } else {
-                            // Log.w(this, "setRingback, unknown call id: %s", args.arg1);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setRingbackRequested(ringback);
+                    } else {
+                        // Log.w(this, "setRingback, unknown call id: %s", args.arg1);
                     }
                 }
             } finally {
@@ -229,16 +209,13 @@
             try {
                 synchronized (mLock) {
                     logIncoming("removeCall %s", callId);
-                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                            .isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            if (call.isAlive()) {
-                                mCallsManager.markCallAsDisconnected(
-                                        call, new DisconnectCause(DisconnectCause.REMOTE));
-                            } else {
-                                mCallsManager.markCallAsRemoved(call);
-                            }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        if (call.isAlive()) {
+                            mCallsManager.markCallAsDisconnected(
+                                    call, new DisconnectCause(DisconnectCause.REMOTE));
+                        } else {
+                            mCallsManager.markCallAsRemoved(call);
                         }
                     }
                 }
@@ -253,15 +230,12 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setConnectionCapabilities %s %d", callId, connectionCapabilities);
-                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                            .isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setConnectionCapabilities(connectionCapabilities);
-                        } else {
-                            // Log.w(ConnectionServiceWrapper.this,
-                            // "setConnectionCapabilities, unknown call id: %s", msg.obj);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setConnectionCapabilities(connectionCapabilities);
+                    } else {
+                        // Log.w(ConnectionServiceWrapper.this,
+                        // "setConnectionCapabilities, unknown call id: %s", msg.obj);
                     }
                 }
             } finally {
@@ -299,26 +273,23 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setConferenceMergeFailed %s", callId);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        // TODO: we should move the UI for indication a merge failure here
-                        // from CallNotifier.onSuppServiceFailed(). This way the InCallUI can
-                        // deliver the message anyway that they want. b/20530631.
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            // Just refresh the connection capabilities so that the UI
-                            // is forced to reenable the merge button as the capability
-                            // is still on the connection. Note when b/20530631 is fixed, we need
-                            // to revisit this fix to remove this hacky way of unhiding the merge
-                            // button (side effect of reprocessing the capabilities) and plumb
-                            // the failure event all the way to InCallUI instead of stopping
-                            // it here. That way we can also handle the UI of notifying that
-                            // the merged has failed.
-                            call.setConnectionCapabilities(call.getConnectionCapabilities(), true);
-                        } else {
-                            Log.w(this, "setConferenceMergeFailed, unknown call id: %s", callId);
-                        }
+                    // TODO: we should move the UI for indication a merge failure here
+                    // from CallNotifier.onSuppServiceFailed(). This way the InCallUI can
+                    // deliver the message anyway that they want. b/20530631.
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        // Just refresh the connection capabilities so that the UI
+                        // is forced to reenable the merge button as the capability
+                        // is still on the connection. Note when b/20530631 is fixed, we need
+                        // to revisit this fix to remove this hacky way of unhiding the merge
+                        // button (side effect of reprocessing the capabilities) and plumb
+                        // the failure event all the way to InCallUI instead of stopping
+                        // it here. That way we can also handle the UI of notifying that
+                        // the merged has failed.
+                        call.setConnectionCapabilities(call.getConnectionCapabilities(), true);
+                    } else {
+                        Log.w(this, "setConferenceMergeFailed, unknown call id: %s", callId);
                     }
-
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -358,7 +329,7 @@
                             parcelableConference.getPhoneAccount() != null) {
                         phAcc = parcelableConference.getPhoneAccount();
                     }
-                    Call conferenceCall = mCallsManager.createConferenceCall(
+                    Call conferenceCall = mCallsManager.createConferenceCall(callId,
                             phAcc, parcelableConference);
                     mCallIdMapper.addCall(conferenceCall, callId);
                     conferenceCall.setConnectionService(ConnectionServiceWrapper.this);
@@ -384,13 +355,11 @@
             try {
                 synchronized (mLock) {
                     logIncoming("onPostDialWait %s %s", callId, remaining);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.onPostDialWait(remaining);
-                        } else {
-                            // Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.onPostDialWait(remaining);
+                    } else {
+                        // Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
                     }
                 }
             } finally {
@@ -404,13 +373,11 @@
             try {
                 synchronized (mLock) {
                     logIncoming("onPostDialChar %s %s", callId, nextChar);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.onPostDialChar(nextChar);
-                        } else {
-                            // Log.w(this, "onPostDialChar, unknown call id: %s", args.arg1);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.onPostDialChar(nextChar);
+                    } else {
+                        // Log.w(this, "onPostDialChar, unknown call id: %s", args.arg1);
                     }
                 }
             } finally {
@@ -437,12 +404,9 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setVideoState %s %d", callId, videoState);
-                    if (mCallIdMapper.isValidCallId(callId)
-                            || mCallIdMapper.isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setVideoState(videoState);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setVideoState(videoState);
                     }
                 }
             } finally {
@@ -456,11 +420,9 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setIsVoipAudioMode %s %b", callId, isVoip);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setIsVoipAudioMode(isVoip);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setIsVoipAudioMode(isVoip);
                     }
                 }
             } finally {
@@ -474,12 +436,9 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setStatusHints %s %s", callId, statusHints);
-                    if (mCallIdMapper.isValidCallId(callId)
-                            || mCallIdMapper.isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setStatusHints(statusHints);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setStatusHints(statusHints);
                     }
                 }
             } finally {
@@ -493,12 +452,9 @@
             try {
                 synchronized(mLock) {
                     logIncoming("setExtras %s %s", callId, extras);
-                    if (mCallIdMapper.isValidCallId(callId)
-                            || mCallIdMapper.isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setExtras(extras);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setExtras(extras);
                     }
                 }
             } finally {
@@ -512,11 +468,9 @@
             try {
                 synchronized (mLock) {
                     logIncoming("setAddress %s %s %d", callId, address, presentation);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setHandle(address, presentation);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setHandle(address, presentation);
                     }
                 }
             } finally {
@@ -532,11 +486,9 @@
                 synchronized (mLock) {
                     logIncoming("setCallerDisplayName %s %s %d", callId, callerDisplayName,
                             presentation);
-                    if (mCallIdMapper.isValidCallId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            call.setCallerDisplayName(callerDisplayName, presentation);
-                        }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.setCallerDisplayName(callerDisplayName, presentation);
                     }
                 }
             } finally {
@@ -552,20 +504,17 @@
                 synchronized (mLock) {
                     logIncoming("setConferenceableConnections %s %s", callId,
                             conferenceableCallIds);
-                    if (mCallIdMapper.isValidCallId(callId) ||
-                            mCallIdMapper.isValidConferenceId(callId)) {
-                        Call call = mCallIdMapper.getCall(callId);
-                        if (call != null) {
-                            List<Call> conferenceableCalls =
-                                    new ArrayList<>(conferenceableCallIds.size());
-                            for (String otherId : conferenceableCallIds) {
-                                Call otherCall = mCallIdMapper.getCall(otherId);
-                                if (otherCall != null && otherCall != call) {
-                                    conferenceableCalls.add(otherCall);
-                                }
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        List<Call> conferenceableCalls =
+                                new ArrayList<>(conferenceableCallIds.size());
+                        for (String otherId : conferenceableCallIds) {
+                            Call otherCall = mCallIdMapper.getCall(otherId);
+                            if (otherCall != null && otherCall != call) {
+                                conferenceableCalls.add(otherCall);
                             }
-                            call.setConferenceableCalls(conferenceableCalls);
                         }
+                        call.setConferenceableCalls(conferenceableCalls);
                     }
                 }
             } finally {
@@ -591,7 +540,7 @@
     }
 
     private final Adapter mAdapter = new Adapter();
-    private final CallIdMapper mCallIdMapper = new CallIdMapper("ConnectionService");
+    private final CallIdMapper mCallIdMapper = new CallIdMapper();
     private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();
 
     private Binder2 mBinder = new Binder2();
@@ -672,7 +621,8 @@
                                     call.getTargetPhoneAccount(),
                                     call.getHandle(),
                                     extras,
-                                    call.getVideoState()),
+                                    call.getVideoState(),
+                                    callId),
                             call.isIncoming(),
                             call.isUnknown());
                 } catch (RemoteException e) {
diff --git a/src/com/android/server/telecom/InCallAdapter.java b/src/com/android/server/telecom/InCallAdapter.java
index 9239288..1fd4855 100644
--- a/src/com/android/server/telecom/InCallAdapter.java
+++ b/src/com/android/server/telecom/InCallAdapter.java
@@ -45,13 +45,11 @@
         try {
             synchronized (mLock) {
                 Log.d(this, "answerCall(%s,%d)", callId, videoState);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.answerCall(call, videoState);
-                    } else {
-                        Log.w(this, "answerCall, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.answerCall(call, videoState);
+                } else {
+                    Log.w(this, "answerCall, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -65,13 +63,11 @@
         try {
             synchronized (mLock) {
                 Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.rejectCall(call, rejectWithMessage, textMessage);
-                    } else {
-                        Log.w(this, "setRingback, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.rejectCall(call, rejectWithMessage, textMessage);
+                } else {
+                    Log.w(this, "setRingback, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -85,13 +81,11 @@
         try {
             synchronized (mLock) {
                 Log.d(this, "playDtmfTone(%s,%c)", callId, digit);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.playDtmfTone(call, digit);
-                    } else {
-                        Log.w(this, "playDtmfTone, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.playDtmfTone(call, digit);
+                } else {
+                    Log.w(this, "playDtmfTone, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -105,13 +99,11 @@
         try {
             synchronized (mLock) {
                 Log.d(this, "stopDtmfTone(%s)", callId);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.stopDtmfTone(call);
-                    } else {
-                        Log.w(this, "stopDtmfTone, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.stopDtmfTone(call);
+                } else {
+                    Log.w(this, "stopDtmfTone, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -125,13 +117,11 @@
         try {
             synchronized (mLock) {
                 Log.d(this, "postDialContinue(%s)", callId);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.postDialContinue(call, proceed);
-                    } else {
-                        Log.w(this, "postDialContinue, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.postDialContinue(call, proceed);
+                } else {
+                    Log.w(this, "postDialContinue, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -145,13 +135,11 @@
         try {
             synchronized (mLock) {
                 Log.v(this, "disconnectCall: %s", callId);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.disconnectCall(call);
-                    } else {
-                        Log.w(this, "disconnectCall, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.disconnectCall(call);
+                } else {
+                    Log.w(this, "disconnectCall, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -164,13 +152,11 @@
         long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.holdCall(call);
-                    } else {
-                        Log.w(this, "holdCall, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.holdCall(call);
+                } else {
+                    Log.w(this, "holdCall, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -183,13 +169,11 @@
         long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.unholdCall(call);
-                    } else {
-                        Log.w(this, "unholdCall, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.unholdCall(call);
+                } else {
+                    Log.w(this, "unholdCall, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -203,13 +187,11 @@
         long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.phoneAccountSelected(call, accountHandle, setDefault);
-                    } else {
-                        Log.w(this, "phoneAccountSelected, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    mCallsManager.phoneAccountSelected(call, accountHandle, setDefault);
+                } else {
+                    Log.w(this, "phoneAccountSelected, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -246,16 +228,12 @@
         long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                if (mCallIdMapper.isValidCallId(callId) &&
-                        mCallIdMapper.isValidCallId(otherCallId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    Call otherCall = mCallIdMapper.getCall(otherCallId);
-                    if (call != null && otherCall != null) {
-                        mCallsManager.conference(call, otherCall);
-                    } else {
-                        Log.w(this, "conference, unknown call id: %s or %s", callId, otherCallId);
-                    }
-
+                Call call = mCallIdMapper.getCall(callId);
+                Call otherCall = mCallIdMapper.getCall(otherCallId);
+                if (call != null && otherCall != null) {
+                    mCallsManager.conference(call, otherCall);
+                } else {
+                    Log.w(this, "conference, unknown call id: %s or %s", callId, otherCallId);
                 }
             }
         } finally {
@@ -268,13 +246,11 @@
         long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.splitFromConference();
-                    } else {
-                        Log.w(this, "splitFromConference, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    call.splitFromConference();
+                } else {
+                    Log.w(this, "splitFromConference, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -287,13 +263,11 @@
         long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.mergeConference();
-                    } else {
-                        Log.w(this, "mergeConference, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    call.mergeConference();
+                } else {
+                    Log.w(this, "mergeConference, unknown call id: %s", callId);
                 }
             }
         } finally {
@@ -306,13 +280,11 @@
         long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.swapConference();
-                    } else {
-                        Log.w(this, "swapConference, unknown call id: %s", callId);
-                    }
+                Call call = mCallIdMapper.getCall(callId);
+                if (call != null) {
+                    call.swapConference();
+                } else {
+                    Log.w(this, "swapConference, unknown call id: %s", callId);
                 }
             }
         } finally {
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 9562ea7..5116807 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -146,7 +146,7 @@
      */
     private ComponentName mInCallUIComponentName;
 
-    private final CallIdMapper mCallIdMapper = new CallIdMapper("InCall");
+    private final CallIdMapper mCallIdMapper = new CallIdMapper();
 
     /** The {@link ComponentName} of the default InCall UI. */
     private final ComponentName mSystemInCallComponentName;
diff --git a/src/com/android/server/telecom/Log.java b/src/com/android/server/telecom/Log.java
index f0ee3fe..31728eb 100644
--- a/src/com/android/server/telecom/Log.java
+++ b/src/com/android/server/telecom/Log.java
@@ -118,11 +118,9 @@
         private static int sNextId = 1;
         private final List<CallEvent> mEvents = new LinkedList<>();
         private final Call mCall;
-        private final int mId;
 
         public CallEventRecord(Call call) {
             mCall = call;
-            mId = ++sNextId;
         }
 
         public Call getCall() {
@@ -131,14 +129,14 @@
 
         public void addEvent(String event, Object data) {
             mEvents.add(new CallEvent(event, System.currentTimeMillis(), data));
-            Log.i("Event", "Call %d: %s, %s", mId, event, data);
+            Log.i("Event", "Call %s: %s, %s", mCall.getId(), event, data);
         }
 
         public void dump(IndentingPrintWriter pw) {
             Map<String, CallEvent> pendingResponses = new HashMap<>();
 
             pw.print("Call ");
-            pw.print(mId);
+            pw.print(mCall.getId());
             pw.print(" [");
             pw.print(sDateFormat.format(new Date(mCall.getCreationTimeMillis())));
             pw.print("]");
@@ -174,7 +172,7 @@
                         // ID instead.
                         CallEventRecord record = mCallEventRecordMap.get(data);
                         if (record != null) {
-                            data = "Call " + record.mId;
+                            data = "Call " + record.mCall.getId();
                         }
                     }
 
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index ef16e59..30100d1 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -409,9 +409,10 @@
                             synchronized (lock) {
 
                                 // Convert the data to a call object
-                                Call call = new Call(mContext, callsManager, lock,
-                                        null, contactsAsyncHelper, callerInfoAsyncQueryFactory,
-                                        null, null, null, null, true, false);
+                                Call call = new Call(Call.CALL_ID_UNKNOWN, mContext, callsManager,
+                                        lock, null, contactsAsyncHelper,
+                                        callerInfoAsyncQueryFactory, null, null, null, null, true,
+                                        false);
                                 call.setDisconnectCause(
                                         new DisconnectCause(DisconnectCause.MISSED));
                                 call.setState(CallState.DISCONNECTED, "throw away call");