Implement Connection.startActivityFromInCall in Telecomm

This CL adds plumbing to send the startActivityFromInCall
request from Connection to InCallUI.

Change-Id: I65119a89c925a93467d1b27304ffec9b088b172f
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 27a995a..2a10558 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -16,6 +16,7 @@
 
 package com.android.telecomm;
 
+import android.app.PendingIntent;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
@@ -78,6 +79,7 @@
         void onHandleChanged(Call call);
         void onCallerDisplayNameChanged(Call call);
         void onVideoStateChanged(Call call);
+        void onStartActivityFromInCall(Call call, PendingIntent intent);
     }
 
     abstract static class ListenerBase implements Listener {
@@ -121,6 +123,8 @@
         public void onCallerDisplayNameChanged(Call call) {}
         @Override
         public void onVideoStateChanged(Call call) {}
+        @Override
+        public void onStartActivityFromInCall(Call call, PendingIntent intent) {}
     }
 
     private static final OnQueryCompleteListener sCallerInfoQueryListener =
@@ -1122,4 +1126,14 @@
             l.onStatusHintsChanged(this);
         }
     }
+
+    public void startActivityFromInCall(PendingIntent intent) {
+        if (intent.isActivity()) {
+            for (Listener l : mListeners) {
+                l.onStartActivityFromInCall(this, intent);
+            }
+        } else {
+            Log.w(this, "startActivityFromInCall, activity intent required");
+        }
+    }
 }
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index fb9d34c..eb2e0ac 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -16,6 +16,7 @@
 
 package com.android.telecomm;
 
+import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.net.Uri;
 import android.os.Bundle;
@@ -77,6 +78,7 @@
     private static final int MSG_SET_HANDLE = 19;
     private static final int MSG_SET_CALLER_DISPLAY_NAME = 20;
     private static final int MSG_SET_VIDEO_STATE = 21;
+    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 22;
 
     private final Handler mHandler = new Handler() {
         @Override
@@ -171,17 +173,11 @@
                     }
                     break;
                 case MSG_SET_REQUESTING_RINGBACK: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        call = mCallIdMapper.getCall(args.arg1);
-                        boolean ringback = (boolean) args.arg2;
-                        if (call != null) {
-                            call.setRequestingRingback(ringback);
-                        } else {
-                            //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
-                        }
-                    } finally {
-                        args.recycle();
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.setRequestingRingback(msg.arg1 == 1);
+                    } else {
+                        //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
                     }
                     break;
                 }
@@ -315,6 +311,18 @@
                         call.setVideoState(msg.arg1);
                     }
                 }
+                case MSG_START_ACTIVITY_FROM_IN_CALL: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            call.startActivityFromInCall((PendingIntent) args.arg2);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
             }
         }
     };
@@ -400,10 +408,8 @@
         public void setRequestingRingback(String callId, boolean ringback) {
             logIncoming("setRequestingRingback %s %b", callId, ringback);
             mCallIdMapper.checkValidCallId(callId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = ringback;
-            mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, args).sendToTarget();
+            mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, ringback ? 1 : 0, 0, callId)
+                    .sendToTarget();
         }
 
         @Override
@@ -497,6 +503,16 @@
             args.argi1 = presentation;
             mHandler.obtainMessage(MSG_SET_CALLER_DISPLAY_NAME, args).sendToTarget();
         }
+
+        @Override
+        public void startActivityFromInCall(String callId, PendingIntent intent) {
+            logIncoming("startActivityFromInCall %s %s", callId, intent);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = intent;
+            mHandler.obtainMessage(MSG_START_ACTIVITY_FROM_IN_CALL, args).sendToTarget();
+        }
     }
 
     private final Adapter mAdapter = new Adapter();
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index 7081dc9..08025a9 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -16,6 +16,7 @@
 
 package com.android.telecomm;
 
+import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -95,6 +96,17 @@
         public void onVideoStateChanged(Call call) {
             updateCall(call);
         }
+
+        @Override
+        public void onStartActivityFromInCall(Call call, PendingIntent intent) {
+            if (mInCallService != null) {
+                Log.i(this, "Calling startActivity, intent: %s", intent);
+                try {
+                    mInCallService.startActivity(mCallIdMapper.getCallId(call), intent);
+                } catch (RemoteException ignored) {
+                }
+            }
+        }
     };
 
     /** Maintains a binding connection to the in-call app. */
diff --git a/src/com/android/telecomm/TtyManager.java b/src/com/android/telecomm/TtyManager.java
index c94cd30..61cd6d0 100644
--- a/src/com/android/telecomm/TtyManager.java
+++ b/src/com/android/telecomm/TtyManager.java
@@ -51,7 +51,7 @@
 
     boolean isTtySupported() {
         boolean isEnabled = mContext.getResources().getBoolean(R.bool.tty_enabled);
-        Log.v(this, "isTtySupported: " + isEnabled);
+        Log.v(this, "isTtySupported: %b", isEnabled);
         return isEnabled;
     }
 
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionService.java b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
index 7e2ee68..2178af0 100644
--- a/tests/src/com/android/telecomm/testapps/TestConnectionService.java
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
@@ -16,6 +16,7 @@
 
 package com.android.telecomm.testapps;
 
+import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.media.MediaPlayer;
@@ -123,6 +124,12 @@
             }
 
             @Override
+            public void onStartActivityFromInCall(
+                    RemoteConnection connection, PendingIntent intent) {
+                startActivityFromInCall(intent);
+            }
+
+            @Override
             public void onDestroyed(RemoteConnection connection) {
                 setDestroyed();
             }