Use mapped IDs for calls

With this CL each client gets a unique ID to represent calls.
This has a couple of benefits:
  - avoids one client from modifying another clients call
  - allows for stricter validation of input
  - allows a call to handed off to a different call service
    (with a different call ID)

Bug: 13643568
Change-Id: I6e2039aead5723d01f9442a4e54f5e616711a3b3
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index 5fbf1f8..d975b0b 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -32,16 +32,12 @@
 /**
  * Binds to {@link IInCallService} and provides the service to {@link CallsManager} through which it
  * can send updates to the in-call app. This class is created and owned by CallsManager and retains
- * a binding to the {@link IInCallService} (implemented by the in-call app) until CallsManager
- * explicitly disconnects it. CallsManager starts the connection by calling {@link #connect} and
- * retains the connection as long as it has calls which need UI. When all calls are disconnected,
- * CallsManager will invoke {@link #disconnect} to sever the binding until the in-call UI is needed
- * again.
+ * a binding to the {@link IInCallService} (implemented by the in-call app).
  */
 public final class InCallController extends CallsManagerListenerBase {
     /**
      * Used to bind to the in-call app and triggers the start of communication between
-     * CallsManager and in-call app.
+     * this class and in-call app.
      */
     private class InCallServiceConnection implements ServiceConnection {
         /** {@inheritDoc} */
@@ -75,8 +71,8 @@
     /** The in-call app implementation, see {@link IInCallService}. */
     private IInCallService mInCallService;
 
-    // TODO(santoscordon): May be better to expose the IInCallService methods directly from this
-    // class as its own method to make the CallsManager code easier to read.
+    private final CallIdMapper mCallIdMapper = new CallIdMapper("InCall");
+
     IInCallService getService() {
         return mInCallService;
     }
@@ -87,10 +83,11 @@
             bind();
         } else {
             Log.i(this, "Adding call: %s", call);
+            mCallIdMapper.addCall(call);
+            CallInfo callInfo = call.toCallInfo(mCallIdMapper.getCallId(call));
             try {
-                mInCallService.addCall(call.toCallInfo());
+                mInCallService.addCall(callInfo);
             } catch (RemoteException e) {
-                Log.e(this, e, "Exception attempting to addCall.");
             }
         }
     }
@@ -101,6 +98,7 @@
             // TODO(sail): Wait for all messages to be delivered to the service before unbinding.
             unbind();
         }
+        mCallIdMapper.removeCall(call);
     }
 
     @Override
@@ -109,29 +107,27 @@
             return;
         }
 
+        String callId = mCallIdMapper.getCallId(call);
         switch (newState) {
             case ACTIVE:
-                Log.i(this, "Mark call as ACTIVE: %s", call.getId());
+                Log.i(this, "Mark call as ACTIVE: %s", callId);
                 try {
-                    mInCallService.setActive(call.getId());
+                    mInCallService.setActive(callId);
                 } catch (RemoteException e) {
-                    Log.e(this, e, "Exception attempting to call setActive.");
                 }
                 break;
             case ON_HOLD:
-                Log.i(this, "Mark call as HOLD: %s", call.getId());
+                Log.i(this, "Mark call as HOLD: %s", callId);
                 try {
-                    mInCallService.setOnHold(call.getId());
+                    mInCallService.setOnHold(callId);
                 } catch (RemoteException e) {
-                    Log.e(this, e, "Exception attempting to call setOnHold.");
                 }
                 break;
             case DISCONNECTED:
-                Log.i(this, "Mark call as DISCONNECTED: %s", call.getId());
+                Log.i(this, "Mark call as DISCONNECTED: %s", callId);
                 try {
-                    mInCallService.setDisconnected(call.getId(), call.getDisconnectCause());
+                    mInCallService.setDisconnected(callId, call.getDisconnectCause());
                 } catch (RemoteException e) {
-                    Log.e(this, e, "Exception attempting to call setDisconnected.");
                 }
                 break;
             default:
@@ -147,7 +143,6 @@
             try {
                 mInCallService.onAudioStateChanged(newAudioState);
             } catch (RemoteException e) {
-                Log.e(this, e, "Exception attempting to update audio state.");
             }
         }
     }
@@ -189,7 +184,7 @@
 
     /**
      * Persists the {@link IInCallService} instance and starts the communication between
-     * CallsManager and in-call app by sending the first update to in-call app. This method is
+     * this class and in-call app by sending the first update to in-call app. This method is
      * called after a successful binding connection is established.
      *
      * @param service The {@link IInCallService} implementation.
@@ -199,7 +194,8 @@
         mInCallService = IInCallService.Stub.asInterface(service);
 
         try {
-            mInCallService.setInCallAdapter(new InCallAdapter(CallsManager.getInstance()));
+            mInCallService.setInCallAdapter(new InCallAdapter(CallsManager.getInstance(),
+                    mCallIdMapper));
         } catch (RemoteException e) {
             Log.e(this, e, "Failed to set the in-call adapter.");
             mInCallService = null;