From 2ab88cc313fc4af7fb9436e236cd3a5d1ac58478 Mon Sep 17 00:00:00 2001 From: Sailesh Nepal Date: Fri, 18 Jul 2014 14:49:18 -0700 Subject: [PATCH] Add Connection.startActivityFromInCall This CL adds a new public API to allow Connections to start an activity on top of the in-call UI. The Connection passes a PendingIntent to Telecomm which then forwards it on to InCallUI. The Connection can cancel the operation by calling PendingIntent.cancel(). This allows services like SIP and Hangouts to show dialogs to the user when making a call. Change-Id: I65119a89c925a93467d1b27304ffec9b088b172f --- api/current.txt | 3 +++ telecomm/java/android/telecomm/Call.java | 21 +++++++++++++++++ .../java/android/telecomm/Connection.java | 16 +++++++++++++ .../android/telecomm/ConnectionService.java | 7 ++++++ .../telecomm/ConnectionServiceAdapter.java | 10 ++++++++ .../java/android/telecomm/InCallService.java | 20 ++++++++++++++++ telecomm/java/android/telecomm/Phone.java | 17 ++++++++++---- .../telecomm/RemoteCallVideoClient.java | 4 ++-- .../android/telecomm/RemoteConnection.java | 10 +++++++- .../telecomm/RemoteConnectionService.java | 23 +++++++++++++++++++ .../telecomm/IConnectionServiceAdapter.aidl | 3 +++ .../internal/telecomm/IInCallService.aidl | 3 +++ 12 files changed, 130 insertions(+), 7 deletions(-) diff --git a/api/current.txt b/api/current.txt index 6f7f9ee38cfcd..acbc84ce407ba 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28174,6 +28174,7 @@ package android.telecomm { method public void onParentChanged(android.telecomm.Call, android.telecomm.Call); method public void onPostDial(android.telecomm.Call, java.lang.String); method public void onPostDialWait(android.telecomm.Call, java.lang.String); + method public void onStartActivity(android.telecomm.Call, android.app.PendingIntent); method public void onStateChanged(android.telecomm.Call, int); } @@ -28319,6 +28320,7 @@ package android.telecomm { method public final void setSignal(android.os.Bundle); method public final void setStatusHints(android.telecomm.StatusHints); method public final void setVideoState(int); + method public final void startActivityFromInCall(android.app.PendingIntent); method public static java.lang.String stateToString(int); } @@ -28525,6 +28527,7 @@ package android.telecomm { method public abstract void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int); method public abstract void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String); method public abstract void onRequestingRingback(android.telecomm.RemoteConnection, boolean); + method public abstract void onStartActivityFromInCall(android.telecomm.RemoteConnection, android.app.PendingIntent); method public abstract void onStateChanged(android.telecomm.RemoteConnection, int); method public abstract void onStatusHintsChanged(android.telecomm.RemoteConnection, android.telecomm.StatusHints); method public abstract void onVideoStateChanged(android.telecomm.RemoteConnection, int); diff --git a/telecomm/java/android/telecomm/Call.java b/telecomm/java/android/telecomm/Call.java index 930336f99124c..1398ad36374ae 100644 --- a/telecomm/java/android/telecomm/Call.java +++ b/telecomm/java/android/telecomm/Call.java @@ -16,6 +16,7 @@ package android.telecomm; +import android.app.PendingIntent; import android.net.Uri; import android.os.RemoteException; import android.telephony.DisconnectCause; @@ -317,6 +318,14 @@ public final class Call { public void onCallVideoProviderChanged(Call call, RemoteCallVideoProvider callVideoProvider) {} + /** + * Launches an activity for this connection on top of the in-call UI. + * + * @param call The {@code Call} invoking this method. + * @param intent The intent to use to start the activity. + */ + public void onStartActivity(Call call, PendingIntent intent) {} + /** * Invoked when the {@code Call} is destroyed. Clients should refrain from cleaning * up their UI for the {@code Call} in response to state transitions. Specifically, @@ -664,6 +673,11 @@ public final class Call { firePostDialWait(mRemainingPostDialSequence); } + /** {@hide} */ + final void internalStartActivity(PendingIntent intent) { + fireStartActivity(intent); + } + private void fireStateChanged(int newState) { Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]); for (int i = 0; i < listeners.length; i++) { @@ -720,6 +734,13 @@ public final class Call { } } + private void fireStartActivity(PendingIntent intent) { + Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].onStartActivity(this, intent); + } + } + private void fireCallDestroyed() { Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]); for (int i = 0; i < listeners.length; i++) { diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java index c050f30b0176c..d4af50c3d490d 100644 --- a/telecomm/java/android/telecomm/Connection.java +++ b/telecomm/java/android/telecomm/Connection.java @@ -16,6 +16,7 @@ package android.telecomm; +import android.app.PendingIntent; import android.net.Uri; import android.os.Bundle; import android.telecomm.CallVideoProvider; @@ -48,6 +49,7 @@ public abstract class Connection { public void onCallVideoProviderChanged(Connection c, CallVideoProvider callVideoProvider) {} public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {} public void onStatusHintsChanged(Connection c, StatusHints statusHints) {} + public void onStartActivityFromInCall(Connection c, PendingIntent intent) {} } public final class State { @@ -463,6 +465,20 @@ public abstract class Connection { } } + /** + * Launches an activity for this connection on top of the in-call UI. + * + * @param intent The intent to use to start the activity. + */ + public final void startActivityFromInCall(PendingIntent intent) { + if (!intent.isActivity()) { + throw new IllegalArgumentException("Activity intent required."); + } + for (Listener l : mListeners) { + l.onStartActivityFromInCall(this, intent); + } + } + /** * Notifies this Connection that the {@link #getCallAudioState()} property has a new value. * diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java index 9e04c6e6cdae8..5bf6124bcdbb7 100644 --- a/telecomm/java/android/telecomm/ConnectionService.java +++ b/telecomm/java/android/telecomm/ConnectionService.java @@ -16,6 +16,7 @@ package android.telecomm; +import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.content.ComponentName; @@ -398,6 +399,12 @@ public abstract class ConnectionService extends Service { String id = mIdByConnection.get(c); mAdapter.setStatusHints(id, statusHints); } + + @Override + public void onStartActivityFromInCall(Connection c, PendingIntent intent) { + String id = mIdByConnection.get(c); + mAdapter.startActivityFromInCall(id, intent); + } }; /** {@inheritDoc} */ diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java index 63546d3b79199..0b8d93d29c6a6 100644 --- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java +++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java @@ -16,6 +16,7 @@ package android.telecomm; +import android.app.PendingIntent; import android.content.ComponentName; import android.net.Uri; import android.os.IBinder; @@ -344,4 +345,13 @@ final class ConnectionServiceAdapter implements DeathRecipient { } } } + + void startActivityFromInCall(String callId, PendingIntent intent) { + for (IConnectionServiceAdapter adapter : mAdapters) { + try { + adapter.startActivityFromInCall(callId, intent); + } catch (RemoteException e) { + } + } + } } diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java index 27d92b2a7d695..367ef80a18e85 100644 --- a/telecomm/java/android/telecomm/InCallService.java +++ b/telecomm/java/android/telecomm/InCallService.java @@ -16,6 +16,7 @@ package android.telecomm; +import android.app.PendingIntent; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -40,6 +41,7 @@ public abstract class InCallService { private static final int MSG_SET_POST_DIAL_WAIT = 5; private static final int MSG_ON_AUDIO_STATE_CHANGED = 6; private static final int MSG_BRING_TO_FOREGROUND = 7; + private static final int MSG_START_ACTIVITY = 8; /** Default Handler used to consolidate binder method calls onto a single thread. */ private final Handler mHandler = new Handler(Looper.getMainLooper()) { @@ -84,6 +86,15 @@ public abstract class InCallService { case MSG_BRING_TO_FOREGROUND: mPhone.internalBringToForeground(msg.arg1 == 1); break; + case MSG_START_ACTIVITY: + SomeArgs args = (SomeArgs) msg.obj; + try { + mPhone.internalStartActivity( + (String) args.arg1, (PendingIntent) args.arg2); + } finally { + args.recycle(); + } + break; default: break; } @@ -137,6 +148,15 @@ public abstract class InCallService { public void bringToForeground(boolean showDialpad) { mHandler.obtainMessage(MSG_BRING_TO_FOREGROUND, showDialpad ? 1 : 0, 0).sendToTarget(); } + + /** {@inheritDoc} */ + @Override + public void startActivity(String callId, PendingIntent intent) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = callId; + args.arg2 = intent; + mHandler.obtainMessage(MSG_START_ACTIVITY, args).sendToTarget(); + } } private Phone mPhone; diff --git a/telecomm/java/android/telecomm/Phone.java b/telecomm/java/android/telecomm/Phone.java index 9c97b45891b45..0f271c31e849b 100644 --- a/telecomm/java/android/telecomm/Phone.java +++ b/telecomm/java/android/telecomm/Phone.java @@ -16,6 +16,7 @@ package android.telecomm; +import android.app.PendingIntent; import android.util.ArrayMap; import java.util.ArrayList; @@ -120,16 +121,16 @@ public final class Phone { } /** {@hide} */ - final void internalSetPostDial(String callId, String remaining) { - Call call = mCallByTelecommCallId.get(callId); + final void internalSetPostDial(String telecommId, String remaining) { + Call call = mCallByTelecommCallId.get(telecommId); if (call != null) { call.internalSetPostDial(remaining); } } /** {@hide} */ - final void internalSetPostDialWait(String callId, String remaining) { - Call call = mCallByTelecommCallId.get(callId); + final void internalSetPostDialWait(String telecommId, String remaining) { + Call call = mCallByTelecommCallId.get(telecommId); if (call != null) { call.internalSetPostDialWait(remaining); } @@ -153,6 +154,14 @@ public final class Phone { fireBringToForeground(showDialpad); } + /** {@hide} */ + final void internalStartActivity(String telecommId, PendingIntent intent) { + Call call = mCallByTelecommCallId.get(telecommId); + if (call != null) { + call.internalStartActivity(intent); + } + } + /** * Adds a listener to this {@code Phone}. * diff --git a/telecomm/java/android/telecomm/RemoteCallVideoClient.java b/telecomm/java/android/telecomm/RemoteCallVideoClient.java index aceba4de5affd..80248318b7ff9 100644 --- a/telecomm/java/android/telecomm/RemoteCallVideoClient.java +++ b/telecomm/java/android/telecomm/RemoteCallVideoClient.java @@ -63,7 +63,7 @@ public class RemoteCallVideoClient implements IBinder.DeathRecipient { * {@link CallVideoClient#SESSION_MODIFY_REQUEST_SUCCESS}, * {@link CallVideoClient#SESSION_MODIFY_REQUEST_FAIL}, * {@link CallVideoClient#SESSION_MODIFY_REQUEST_INVALID} - * @param requestProfile The original request which was sent to the remote device. + * @param requestedProfile The original request which was sent to the remote device. * @param responseProfile The actual profile changes made by the remote device. */ public void receiveSessionModifyResponse(int status, VideoCallProfile requestedProfile, @@ -114,4 +114,4 @@ public class RemoteCallVideoClient implements IBinder.DeathRecipient { throws RemoteException { mCallVideoClient.handleCameraCapabilitiesChange(callCameraCapabilities); } -} \ No newline at end of file +} diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java index d17e62affbf23..ddad58f8b12aa 100644 --- a/telecomm/java/android/telecomm/RemoteConnection.java +++ b/telecomm/java/android/telecomm/RemoteConnection.java @@ -16,8 +16,8 @@ package android.telecomm; +import android.app.PendingIntent; import android.net.Uri; - import android.os.Bundle; import android.os.RemoteException; import android.telephony.DisconnectCause; @@ -43,6 +43,7 @@ public final class RemoteConnection { void onCallerDisplayNameChanged( RemoteConnection connection, String callerDisplayName, int presentation); void onVideoStateChanged(RemoteConnection connection, int videoState); + void onStartActivityFromInCall(RemoteConnection connection, PendingIntent intent); void onDestroyed(RemoteConnection connection); } @@ -346,4 +347,11 @@ public final class RemoteConnection { l.onCallerDisplayNameChanged(this, callerDisplayName, presentation); } } + + /** @hide */ + void startActivityFromInCall(PendingIntent intent) { + for (Listener l : mListeners) { + l.onStartActivityFromInCall(this, intent); + } + } } diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java index ed76a48c67f87..6c024c6de68c4 100644 --- a/telecomm/java/android/telecomm/RemoteConnectionService.java +++ b/telecomm/java/android/telecomm/RemoteConnectionService.java @@ -16,6 +16,7 @@ package android.telecomm; +import android.app.PendingIntent; import android.content.ComponentName; import android.net.Uri; import android.os.IBinder.DeathRecipient; @@ -63,6 +64,7 @@ final class RemoteConnectionService implements DeathRecipient { private static final int MSG_SET_STATUS_HINTS = 19; private static final int MSG_SET_HANDLE = 20; private static final int MSG_SET_CALLER_DISPLAY_NAME = 21; + private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 22; private final IConnectionService mConnectionService; private final ComponentName mComponentName; @@ -221,8 +223,21 @@ final class RemoteConnectionService implements DeathRecipient { } break; } + case MSG_START_ACTIVITY_FROM_IN_CALL: { + SomeArgs args = (SomeArgs) msg.obj; + try { + if (isCurrentConnection(msg.arg1)) { + mConnection.startActivityFromInCall((PendingIntent) args.arg2); + } + } finally { + args.recycle(); + } + break; + } } } + + }; private final IConnectionServiceAdapter mAdapter = new IConnectionServiceAdapter.Stub() { @@ -363,6 +378,14 @@ final class RemoteConnectionService implements DeathRecipient { args.argi1 = presentation; mHandler.obtainMessage(MSG_SET_CALLER_DISPLAY_NAME, args).sendToTarget(); } + + @Override + public final void startActivityFromInCall(String connectionId, PendingIntent intent) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = connectionId; + args.arg2 = intent; + mHandler.obtainMessage(MSG_START_ACTIVITY_FROM_IN_CALL, args).sendToTarget(); + } }; RemoteConnectionService(ComponentName componentName, IConnectionService connectionService) diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl index e12cfca6d1050..1abdf7c51f01a 100644 --- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl +++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl @@ -16,6 +16,7 @@ package com.android.internal.telecomm; +import android.app.PendingIntent; import android.net.Uri; import android.telecomm.ConnectionRequest; import android.telecomm.StatusHints; @@ -73,4 +74,6 @@ oneway interface IConnectionServiceAdapter { void setHandle(String callId, in Uri handle, int presentation); void setCallerDisplayName(String callId, String callerDisplayName, int presentation); + + void startActivityFromInCall(String callId, in PendingIntent intent); } diff --git a/telecomm/java/com/android/internal/telecomm/IInCallService.aidl b/telecomm/java/com/android/internal/telecomm/IInCallService.aidl index 16350539512c5..fc28ed541eadc 100644 --- a/telecomm/java/com/android/internal/telecomm/IInCallService.aidl +++ b/telecomm/java/com/android/internal/telecomm/IInCallService.aidl @@ -16,6 +16,7 @@ package com.android.internal.telecomm; +import android.app.PendingIntent; import android.telecomm.CallAudioState; import android.telecomm.InCallCall; @@ -42,4 +43,6 @@ oneway interface IInCallService { void onAudioStateChanged(in CallAudioState audioState); void bringToForeground(boolean showDialpad); + + void startActivity(String callId, in PendingIntent intent); }