summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt12
-rw-r--r--api/system-current.txt12
-rw-r--r--api/test-current.txt12
-rw-r--r--telecomm/java/android/telecom/Call.java84
-rw-r--r--telecomm/java/android/telecom/Conference.java164
-rw-r--r--telecomm/java/android/telecom/Connection.java162
-rw-r--r--telecomm/java/android/telecom/ConnectionService.java75
-rw-r--r--telecomm/java/android/telecom/ConnectionServiceAdapter.java82
-rw-r--r--telecomm/java/android/telecom/ConnectionServiceAdapterServant.java30
-rw-r--r--telecomm/java/android/telecom/InCallAdapter.java75
-rw-r--r--telecomm/java/android/telecom/RemoteConference.java26
-rw-r--r--telecomm/java/android/telecom/RemoteConnection.java26
-rw-r--r--telecomm/java/android/telecom/RemoteConnectionService.java19
-rw-r--r--telecomm/java/com/android/internal/telecom/IConnectionService.aidl2
-rw-r--r--telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl4
-rw-r--r--telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl4
16 files changed, 743 insertions, 46 deletions
diff --git a/api/current.txt b/api/current.txt
index 3fc1673fc959..690fec7fdbb2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -36008,9 +36008,11 @@ package android.telecom {
method public void playDtmfTone(char);
method public void postDialContinue(boolean);
method public void pullExternalCall();
+ method public final void putExtras(android.os.Bundle);
method public void registerCallback(android.telecom.Call.Callback);
method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
method public void reject(boolean, java.lang.String);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public void sendCallEvent(java.lang.String, android.os.Bundle);
method public void splitFromConference();
method public void stopDtmfTone();
@@ -36151,6 +36153,7 @@ package android.telecom {
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onConnectionAdded(android.telecom.Connection);
method public void onDisconnect();
+ method public void onExtrasChanged(android.os.Bundle);
method public void onHold();
method public void onMerge(android.telecom.Connection);
method public void onMerge();
@@ -36159,14 +36162,16 @@ package android.telecom {
method public void onStopDtmfTone();
method public void onSwap();
method public void onUnhold();
+ method public final void putExtras(android.os.Bundle);
method public final void removeConnection(android.telecom.Connection);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public final void setActive();
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
method public final void setConnectionCapabilities(int);
method public final void setConnectionTime(long);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
- method public final void setExtras(android.os.Bundle);
+ method public final deprecated void setExtras(android.os.Bundle);
method public final void setOnHold();
method public final void setStatusHints(android.telecom.StatusHints);
method public final void setVideoProvider(android.telecom.Connection, android.telecom.Connection.VideoProvider);
@@ -36204,6 +36209,7 @@ package android.telecom {
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onCallEvent(java.lang.String, android.os.Bundle);
method public void onDisconnect();
+ method public void onExtrasChanged(android.os.Bundle);
method public void onHold();
method public void onPlayDtmfTone(char);
method public void onPostDialContinue(boolean);
@@ -36214,6 +36220,8 @@ package android.telecom {
method public void onStateChanged(int);
method public void onStopDtmfTone();
method public void onUnhold();
+ method public final void putExtras(android.os.Bundle);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
method public final void setActive();
method public final void setAddress(android.net.Uri, int);
@@ -36224,7 +36232,7 @@ package android.telecom {
method public final void setConnectionCapabilities(int);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
- method public final void setExtras(android.os.Bundle);
+ method public final deprecated void setExtras(android.os.Bundle);
method public final void setInitialized();
method public final void setInitializing();
method public final void setNextPostDialChar(char);
diff --git a/api/system-current.txt b/api/system-current.txt
index 48e1bd06d6a7..f06e54562867 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -38571,9 +38571,11 @@ package android.telecom {
method public void playDtmfTone(char);
method public void postDialContinue(boolean);
method public void pullExternalCall();
+ method public final void putExtras(android.os.Bundle);
method public void registerCallback(android.telecom.Call.Callback);
method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
method public void reject(boolean, java.lang.String);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public deprecated void removeListener(android.telecom.Call.Listener);
method public void sendCallEvent(java.lang.String, android.os.Bundle);
method public void splitFromConference();
@@ -38724,6 +38726,7 @@ package android.telecom {
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onConnectionAdded(android.telecom.Connection);
method public void onDisconnect();
+ method public void onExtrasChanged(android.os.Bundle);
method public void onHold();
method public void onMerge(android.telecom.Connection);
method public void onMerge();
@@ -38732,7 +38735,9 @@ package android.telecom {
method public void onStopDtmfTone();
method public void onSwap();
method public void onUnhold();
+ method public final void putExtras(android.os.Bundle);
method public final void removeConnection(android.telecom.Connection);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public final void setActive();
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
method public final deprecated void setConnectTimeMillis(long);
@@ -38740,7 +38745,7 @@ package android.telecom {
method public final void setConnectionTime(long);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
- method public final void setExtras(android.os.Bundle);
+ method public final deprecated void setExtras(android.os.Bundle);
method public final void setOnHold();
method public final void setStatusHints(android.telecom.StatusHints);
method public final void setVideoProvider(android.telecom.Connection, android.telecom.Connection.VideoProvider);
@@ -38780,6 +38785,7 @@ package android.telecom {
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onCallEvent(java.lang.String, android.os.Bundle);
method public void onDisconnect();
+ method public void onExtrasChanged(android.os.Bundle);
method public void onHold();
method public void onPlayDtmfTone(char);
method public void onPostDialContinue(boolean);
@@ -38790,6 +38796,8 @@ package android.telecom {
method public void onStateChanged(int);
method public void onStopDtmfTone();
method public void onUnhold();
+ method public final void putExtras(android.os.Bundle);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
method public final void setActive();
method public final void setAddress(android.net.Uri, int);
@@ -38800,7 +38808,7 @@ package android.telecom {
method public final void setConnectionCapabilities(int);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
- method public final void setExtras(android.os.Bundle);
+ method public final deprecated void setExtras(android.os.Bundle);
method public final void setInitialized();
method public final void setInitializing();
method public final void setNextPostDialChar(char);
diff --git a/api/test-current.txt b/api/test-current.txt
index c1035afc9a64..4afda9cfe65e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -36079,9 +36079,11 @@ package android.telecom {
method public void playDtmfTone(char);
method public void postDialContinue(boolean);
method public void pullExternalCall();
+ method public final void putExtras(android.os.Bundle);
method public void registerCallback(android.telecom.Call.Callback);
method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
method public void reject(boolean, java.lang.String);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public void sendCallEvent(java.lang.String, android.os.Bundle);
method public void splitFromConference();
method public void stopDtmfTone();
@@ -36222,6 +36224,7 @@ package android.telecom {
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onConnectionAdded(android.telecom.Connection);
method public void onDisconnect();
+ method public void onExtrasChanged(android.os.Bundle);
method public void onHold();
method public void onMerge(android.telecom.Connection);
method public void onMerge();
@@ -36230,14 +36233,16 @@ package android.telecom {
method public void onStopDtmfTone();
method public void onSwap();
method public void onUnhold();
+ method public final void putExtras(android.os.Bundle);
method public final void removeConnection(android.telecom.Connection);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public final void setActive();
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
method public final void setConnectionCapabilities(int);
method public final void setConnectionTime(long);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
- method public final void setExtras(android.os.Bundle);
+ method public final deprecated void setExtras(android.os.Bundle);
method public final void setOnHold();
method public final void setStatusHints(android.telecom.StatusHints);
method public final void setVideoProvider(android.telecom.Connection, android.telecom.Connection.VideoProvider);
@@ -36275,6 +36280,7 @@ package android.telecom {
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onCallEvent(java.lang.String, android.os.Bundle);
method public void onDisconnect();
+ method public void onExtrasChanged(android.os.Bundle);
method public void onHold();
method public void onPlayDtmfTone(char);
method public void onPostDialContinue(boolean);
@@ -36285,6 +36291,8 @@ package android.telecom {
method public void onStateChanged(int);
method public void onStopDtmfTone();
method public void onUnhold();
+ method public final void putExtras(android.os.Bundle);
+ method public final void removeExtras(java.util.List<java.lang.String>);
method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
method public final void setActive();
method public final void setAddress(android.net.Uri, int);
@@ -36295,7 +36303,7 @@ package android.telecom {
method public final void setConnectionCapabilities(int);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
- method public final void setExtras(android.os.Bundle);
+ method public final deprecated void setExtras(android.os.Bundle);
method public final void setInitialized();
method public final void setInitializing();
method public final void setNextPostDialChar(char);
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index afb7d9394679..e26e54b058f5 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -813,6 +813,7 @@ public final class Call {
private String mRemainingPostDialSequence;
private VideoCallImpl mVideoCallImpl;
private Details mDetails;
+ private Bundle mExtras;
/**
* Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
@@ -988,6 +989,89 @@ public final class Call {
}
/**
+ * Adds some extras to this {@link Call}. Existing keys are replaced and new ones are
+ * added.
+ * <p>
+ * No assumptions should be made as to how an In-Call UI or service will handle these
+ * extras. Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
+ *
+ * @param extras The extras to add.
+ */
+ public final void putExtras(Bundle extras) {
+ if (extras == null) {
+ return;
+ }
+
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putAll(extras);
+ mInCallAdapter.putExtras(mTelecomCallId, extras);
+ }
+
+ /**
+ * Adds a boolean extra to this {@link Call}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, boolean value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putBoolean(key, value);
+ mInCallAdapter.putExtra(mTelecomCallId, key, value);
+ }
+
+ /**
+ * Adds an integer extra to this {@code Connection}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, int value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putInt(key, value);
+ mInCallAdapter.putExtra(mTelecomCallId, key, value);
+ }
+
+ /**
+ * Adds a string extra to this {@code Connection}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, String value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putString(key, value);
+ mInCallAdapter.putExtra(mTelecomCallId, key, value);
+ }
+
+ /**
+ * Removes extras from this {@code Connection}.
+ *
+ * @param keys The keys of the extras to remove.
+ */
+ public final void removeExtras(List<String> keys) {
+ if (mExtras != null) {
+ for (String key : keys) {
+ mExtras.remove(key);
+ }
+ if (mExtras.size() == 0) {
+ mExtras = null;
+ }
+ }
+ mInCallAdapter.removeExtras(mTelecomCallId, keys);
+ }
+
+ /**
* Obtains the parent of this {@code Call} in a conference, if any.
*
* @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 1b70d651aabc..00e07afda4b1 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -16,10 +16,12 @@
package android.telecom;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Bundle;
import android.telecom.Connection.VideoProvider;
+import android.util.ArraySet;
import java.util.ArrayList;
import java.util.Collections;
@@ -54,7 +56,8 @@ public abstract class Conference extends Conferenceable {
public void onVideoStateChanged(Conference c, int videoState) { }
public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {}
public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {}
- public void onExtrasChanged(Conference conference, Bundle extras) {}
+ public void onExtrasChanged(Conference c, Bundle extras) {}
+ public void onExtrasRemoved(Conference c, List<String> keys) {}
}
private final Set<Listener> mListeners = new CopyOnWriteArraySet<>();
@@ -75,6 +78,7 @@ public abstract class Conference extends Conferenceable {
private long mConnectTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
private StatusHints mStatusHints;
private Bundle mExtras;
+ private Set<String> mPreviousExtraKeys;
private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
@Override
@@ -640,23 +644,171 @@ public abstract class Conference extends Conferenceable {
}
/**
- * Set some extras that can be associated with this {@code Conference}. No assumptions should
- * be made as to how an In-Call UI or service will handle these extras.
+ * Replaces all the extras associated with this {@code Conference}.
+ * <p>
+ * New or existing keys are replaced in the {@code Conference} extras. Keys which are no longer
+ * in the new extras, but were present the last time {@code setExtras} was called are removed.
+ * <p>
+ * No assumptions should be made as to how an In-Call UI or service will handle these extras.
* Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
*
- * @param extras The extras associated with this {@code Connection}.
+ * @param extras The extras associated with this {@code Conference}.
+ * @deprecated Use {@link #putExtras(Bundle)} to add extras. Use {@link #removeExtras(List)}
+ * to remove extras.
*/
public final void setExtras(@Nullable Bundle extras) {
- mExtras = extras;
+ // Add/replace any new or changed extras values.
+ putExtras(extras);
+
+ // If we have used "setExtras" in the past, compare the key set from the last invocation to
+ // the current one and remove any keys that went away.
+ if (mPreviousExtraKeys != null) {
+ List<String> toRemove = new ArrayList<String>();
+ for (String oldKey : mPreviousExtraKeys) {
+ if (!extras.containsKey(oldKey)) {
+ toRemove.add(oldKey);
+ }
+ }
+
+ if (!toRemove.isEmpty()) {
+ removeExtras(toRemove);
+ }
+ }
+
+ // Track the keys the last time set called setExtras. This way, the next time setExtras is
+ // called we can see if the caller has removed any extras values.
+ if (mPreviousExtraKeys == null) {
+ mPreviousExtraKeys = new ArraySet<String>();
+ }
+ mPreviousExtraKeys.clear();
+ mPreviousExtraKeys.addAll(extras.keySet());
+ }
+
+ /**
+ * Adds some extras to this {@link Conference}. Existing keys are replaced and new ones are
+ * added.
+ * <p>
+ * No assumptions should be made as to how an In-Call UI or service will handle these extras.
+ * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
+ *
+ * @param extras The extras to add.
+ */
+ public final void putExtras(@NonNull Bundle extras) {
+ if (extras == null) {
+ return;
+ }
+
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putAll(extras);
+
for (Listener l : mListeners) {
l.onExtrasChanged(this, extras);
}
}
/**
- * @return The extras associated with this conference.
+ * Adds a boolean extra to this {@link Conference}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, boolean value) {
+ Bundle newExtras = new Bundle();
+ newExtras.putBoolean(key, value);
+ putExtras(newExtras);
+ }
+
+ /**
+ * Adds an integer extra to this {@link Conference}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, int value) {
+ Bundle newExtras = new Bundle();
+ newExtras.putInt(key, value);
+ putExtras(newExtras);
+ }
+
+ /**
+ * Adds a string extra to this {@link Conference}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, String value) {
+ Bundle newExtras = new Bundle();
+ newExtras.putString(key, value);
+ putExtras(newExtras);
+ }
+
+ /**
+ * Removes an extra from this {@link Conference}.
+ *
+ * @param keys The key of the extra key to remove.
+ */
+ public final void removeExtras(List<String> keys) {
+ if (keys == null || keys.isEmpty()) {
+ return;
+ }
+
+ if (mExtras != null) {
+ for (String key : keys) {
+ mExtras.remove(key);
+ }
+ if (mExtras.size() == 0) {
+ mExtras = null;
+ }
+ }
+
+ for (Listener l : mListeners) {
+ l.onExtrasRemoved(this, keys);
+ }
+ }
+
+ /**
+ * Returns the extras associated with this conference.
+ * <p>
+ * Extras should be updated using {@link #putExtras(Bundle)} and {@link #removeExtras(List)}.
+ * <p>
+ * Telecom or an {@link InCallService} can also update the extras via
+ * {@link android.telecom.Call#putExtras(Bundle)}, and
+ * {@link Call#removeExtras(List)}.
+ * <p>
+ * The conference is notified of changes to the extras made by Telecom or an
+ * {@link InCallService} by {@link #onExtrasChanged(Bundle)}.
+ *
+ * @return The extras associated with this connection.
*/
public final Bundle getExtras() {
return mExtras;
}
+
+ /**
+ * Notifies this {@link Conference} of a change to the extras made outside the
+ * {@link ConnectionService}.
+ * <p>
+ * These extras changes can originate from Telecom itself, or from an {@link InCallService} via
+ * {@link android.telecom.Call#putExtras(Bundle)}, and
+ * {@link Call#removeExtras(List)}.
+ *
+ * @param extras The new extras bundle.
+ */
+ public void onExtrasChanged(Bundle extras) {}
+
+ /**
+ * Handles a change to extras received from Telecom.
+ *
+ * @param extras The new extras.
+ * @hide
+ */
+ final void handleExtrasChanged(Bundle extras) {
+ mExtras = extras;
+ onExtrasChanged(mExtras);
+ }
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 51a65882b802..3ea1c6a7663b 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -20,6 +20,7 @@ import com.android.internal.os.SomeArgs;
import com.android.internal.telecom.IVideoCallback;
import com.android.internal.telecom.IVideoProvider;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.hardware.camera2.CameraManager;
@@ -30,6 +31,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.util.ArraySet;
import android.view.Surface;
import java.util.ArrayList;
@@ -516,6 +518,7 @@ public abstract class Connection extends Conferenceable {
public void onConferenceStarted() {}
public void onConferenceMergeFailed(Connection c) {}
public void onExtrasChanged(Connection c, Bundle extras) {}
+ public void onExtrasRemoved(Connection c, List<String> keys) {}
public void onConnectionEvent(Connection c, String event, Bundle extras) {}
}
@@ -1183,6 +1186,13 @@ public abstract class Connection extends Conferenceable {
private Bundle mExtras;
/**
+ * Tracks the key set for the extras bundle provided on the last invocation of
+ * {@link #setExtras(Bundle)}. Used so that on subsequent invocations we can remove any extras
+ * keys which were set previously but are no longer present in the replacement Bundle.
+ */
+ private Set<String> mPreviousExtraKeys;
+
+ /**
* Create a new Connection.
*/
public Connection() {}
@@ -1318,6 +1328,17 @@ public abstract class Connection extends Conferenceable {
}
/**
+ * Returns the extras associated with this connection.
+ * <p>
+ * Extras should be updated using {@link #putExtras(Bundle)}.
+ * <p>
+ * Telecom or an {@link InCallService} can also update the extras via
+ * {@link android.telecom.Call#putExtras(Bundle)}, and
+ * {@link Call#removeExtras(List)}.
+ * <p>
+ * The connection is notified of changes to the extras made by Telecom or an
+ * {@link InCallService} by {@link #onExtrasChanged(Bundle)}.
+ *
* @return The extras associated with this connection.
*/
public final Bundle getExtras() {
@@ -1777,21 +1798,133 @@ public abstract class Connection extends Conferenceable {
}
/**
- * Set some extras that can be associated with this {@code Connection}. No assumptions should
- * be made as to how an In-Call UI or service will handle these extras.
+ * Set some extras that can be associated with this {@code Connection}.
+ * <p>
+ * New or existing keys are replaced in the {@code Connection} extras. Keys which are no longer
+ * in the new extras, but were present the last time {@code setExtras} was called are removed.
+ * <p>
+ * No assumptions should be made as to how an In-Call UI or service will handle these extras.
* Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
*
* @param extras The extras associated with this {@code Connection}.
+ * @deprecated Use {@link #putExtras(Bundle)} to add extras. Use {@link #removeExtras(List)}
+ * to remove extras.
*/
public final void setExtras(@Nullable Bundle extras) {
checkImmutable();
- mExtras = extras;
+
+ // Add/replace any new or changed extras values.
+ putExtras(extras);
+
+ // If we have used "setExtras" in the past, compare the key set from the last invocation to
+ // the current one and remove any keys that went away.
+ if (mPreviousExtraKeys != null) {
+ List<String> toRemove = new ArrayList<String>();
+ for (String oldKey : mPreviousExtraKeys) {
+ if (!extras.containsKey(oldKey)) {
+ toRemove.add(oldKey);
+ }
+ }
+ if (!toRemove.isEmpty()) {
+ removeExtras(toRemove);
+ }
+ }
+
+ // Track the keys the last time set called setExtras. This way, the next time setExtras is
+ // called we can see if the caller has removed any extras values.
+ if (mPreviousExtraKeys == null) {
+ mPreviousExtraKeys = new ArraySet<String>();
+ }
+ mPreviousExtraKeys.clear();
+ mPreviousExtraKeys.addAll(extras.keySet());
+ }
+
+ /**
+ * Adds some extras to this {@code Connection}. Existing keys are replaced and new ones are
+ * added.
+ * <p>
+ * No assumptions should be made as to how an In-Call UI or service will handle these extras.
+ * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
+ *
+ * @param extras The extras to add.
+ */
+ public final void putExtras(@NonNull Bundle extras) {
+ checkImmutable();
+ if (extras == null) {
+ return;
+ }
+
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putAll(extras);
+
for (Listener l : mListeners) {
l.onExtrasChanged(this, extras);
}
}
/**
+ * Adds a boolean extra to this {@code Connection}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, boolean value) {
+ Bundle newExtras = new Bundle();
+ newExtras.putBoolean(key, value);
+ putExtras(newExtras);
+ }
+
+ /**
+ * Adds an integer extra to this {@code Connection}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, int value) {
+ Bundle newExtras = new Bundle();
+ newExtras.putInt(key, value);
+ putExtras(newExtras);
+ }
+
+ /**
+ * Adds a string extra to this {@code Connection}.
+ *
+ * @param key The extra key.
+ * @param value The value.
+ * @hide
+ */
+ public final void putExtra(String key, String value) {
+ Bundle newExtras = new Bundle();
+ newExtras.putString(key, value);
+ putExtras(newExtras);
+ }
+
+ /**
+ * Removes an extra from this {@code Connection}.
+ *
+ * @param keys The key of the extra key to remove.
+ */
+ public final void removeExtras(List<String> keys) {
+ if (mExtras != null) {
+ for (String key : keys) {
+ mExtras.remove(key);
+ }
+
+ if (mExtras.size() == 0) {
+ mExtras = null;
+ }
+ }
+
+ for (Listener l : mListeners) {
+ l.onExtrasRemoved(this, keys);
+ }
+ }
+
+ /**
* Notifies this Connection that the {@link #getAudioState()} property has a new value.
*
* @param state The new connection audio state.
@@ -1928,6 +2061,18 @@ public abstract class Connection extends Conferenceable {
*/
public void onCallEvent(String event, Bundle extras) {}
+ /**
+ * Notifies this {@link Connection} of a change to the extras made outside the
+ * {@link ConnectionService}.
+ * <p>
+ * These extras changes can originate from Telecom itself, or from an {@link InCallService} via
+ * the {@link android.telecom.Call#putExtras(Bundle)} and
+ * {@link Call#removeExtras(List)}.
+ *
+ * @param extras The new extras bundle.
+ */
+ public void onExtrasChanged(Bundle extras) {}
+
static String toLogSafePhoneNumber(String number) {
// For unknown number, log empty string.
if (number == null) {
@@ -2048,6 +2193,17 @@ public abstract class Connection extends Conferenceable {
}
/**
+ * Handles a change to extras received from Telecom.
+ *
+ * @param extras The new extras.
+ * @hide
+ */
+ final void handleExtrasChanged(Bundle extras) {
+ mExtras = extras;
+ onExtrasChanged(mExtras);
+ }
+
+ /**
* Notifies listeners that the merge request failed.
*
* @hide
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index d18b31725aaa..e092095eaed3 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -105,6 +105,7 @@ public abstract class ConnectionService extends Service {
private static final int MSG_SILENCE = 21;
private static final int MSG_PULL_EXTERNAL_CALL = 22;
private static final int MSG_SEND_CALL_EVENT = 23;
+ private static final int MSG_ON_EXTRAS_CHANGED = 24;
private static Connection sNullConnection;
@@ -261,6 +262,14 @@ public abstract class ConnectionService extends Service {
args.arg3 = extras;
mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
}
+
+ @Override
+ public void onExtrasChanged(String callId, Bundle extras) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = extras;
+ mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
+ }
};
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -414,6 +423,17 @@ public abstract class ConnectionService extends Service {
}
break;
}
+ case MSG_ON_EXTRAS_CHANGED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ String callId = (String) args.arg1;
+ Bundle extras = (Bundle) args.arg2;
+ handleExtrasChanged(callId, extras);
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
default:
break;
}
@@ -492,13 +512,25 @@ public abstract class ConnectionService extends Service {
@Override
public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
String id = mIdByConference.get(conference);
- mAdapter.setStatusHints(id, statusHints);
+ if (id != null) {
+ mAdapter.setStatusHints(id, statusHints);
+ }
}
@Override
- public void onExtrasChanged(Conference conference, Bundle extras) {
- String id = mIdByConference.get(conference);
- mAdapter.setExtras(id, extras);
+ public void onExtrasChanged(Conference c, Bundle extras) {
+ String id = mIdByConference.get(c);
+ if (id != null) {
+ mAdapter.putExtras(id, extras);
+ }
+ }
+
+ @Override
+ public void onExtrasRemoved(Conference c, List<String> keys) {
+ String id = mIdByConference.get(c);
+ if (id != null) {
+ mAdapter.removeExtras(id, keys);
+ }
}
};
@@ -639,13 +671,21 @@ public abstract class ConnectionService extends Service {
}
@Override
- public void onExtrasChanged(Connection connection, Bundle extras) {
- String id = mIdByConnection.get(connection);
+ public void onExtrasChanged(Connection c, Bundle extras) {
+ String id = mIdByConnection.get(c);
+ if (id != null) {
+ mAdapter.putExtras(id, extras);
+ }
+ }
+
+ public void onExtrasRemoved(Connection c, List<String> keys) {
+ String id = mIdByConnection.get(c);
if (id != null) {
- mAdapter.setExtras(id, extras);
+ mAdapter.removeExtras(id, keys);
}
}
+
@Override
public void onConnectionEvent(Connection connection, String event, Bundle extras) {
String id = mIdByConnection.get(connection);
@@ -929,6 +969,27 @@ public abstract class ConnectionService extends Service {
}
+ /**
+ * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
+ * <p>
+ * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
+ * the {@link android.telecom.Call#putExtra(String, boolean)},
+ * {@link android.telecom.Call#putExtra(String, int)},
+ * {@link android.telecom.Call#putExtra(String, String)},
+ * {@link Call#removeExtras(List)}.
+ *
+ * @param callId The ID of the call receiving the event.
+ * @param extras The new extras bundle.
+ */
+ private void handleExtrasChanged(String callId, Bundle extras) {
+ Log.d(this, "handleExtrasChanged(%s, %s)", callId, extras);
+ if (mConnectionById.containsKey(callId)) {
+ findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
+ } else if (mConferenceById.containsKey(callId)) {
+ findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
+ }
+ }
+
private void onPostDialContinue(String callId, boolean proceed) {
Log.d(this, "onPostDialContinue(%s)", callId);
findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index e91128f1f7bc..81e4c2271c14 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -398,16 +398,88 @@ final class ConnectionServiceAdapter implements DeathRecipient {
}
/**
- * Sets extras associated with a connection.
+ * Adds some extras associated with a {@code Connection}.
*
* @param callId The unique ID of the call.
- * @param extras The extras to associate with this call.
+ * @param extras The extras to add.
*/
- void setExtras(String callId, Bundle extras) {
- Log.v(this, "setExtras: %s", extras);
+ void putExtras(String callId, Bundle extras) {
+ Log.v(this, "putExtras: %s", callId);
for (IConnectionServiceAdapter adapter : mAdapters) {
try {
- adapter.setExtras(callId, extras);
+ adapter.putExtras(callId, extras);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ /**
+ * Adds an extra associated with a {@code Connection}.
+ *
+ * @param callId The unique ID of the call.
+ * @param key The extra key.
+ * @param value The extra value.
+ */
+ void putExtra(String callId, String key, boolean value) {
+ Log.v(this, "putExtra: %s %s=%b", callId, key, value);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(key, value);
+ adapter.putExtras(callId, bundle);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ /**
+ * Adds an extra associated with a {@code Connection}.
+ *
+ * @param callId The unique ID of the call.
+ * @param key The extra key.
+ * @param value The extra value.
+ */
+ void putExtra(String callId, String key, int value) {
+ Log.v(this, "putExtra: %s %s=%d", callId, key, value);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ Bundle bundle = new Bundle();
+ bundle.putInt(key, value);
+ adapter.putExtras(callId, bundle);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ /**
+ * Adds an extra associated with a {@code Connection}.
+ *
+ * @param callId The unique ID of the call.
+ * @param key The extra key.
+ * @param value The extra value.
+ */
+ void putExtra(String callId, String key, String value) {
+ Log.v(this, "putExtra: %s %s=%s", callId, key, value);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ adapter.putExtras(callId, bundle);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ /**
+ * Removes extras associated with a {@code Connection}.
+ * @param callId The unique ID of the call.
+ * @param keys The extra keys to remove.
+ */
+ void removeExtras(String callId, List<String> keys) {
+ Log.v(this, "removeExtras: %s %s", callId, keys);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.removeExtras(callId, keys);
} catch (RemoteException ignored) {
}
}
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 4b15e541d0dc..3e465577e2f3 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -61,8 +61,9 @@ final class ConnectionServiceAdapterServant {
private static final int MSG_ADD_EXISTING_CONNECTION = 21;
private static final int MSG_ON_POST_DIAL_CHAR = 22;
private static final int MSG_SET_CONFERENCE_MERGE_FAILED = 23;
- private static final int MSG_SET_EXTRAS = 24;
- private static final int MSG_ON_CONNECTION_EVENT = 25;
+ private static final int MSG_PUT_EXTRAS = 24;
+ private static final int MSG_REMOVE_EXTRAS = 25;
+ private static final int MSG_ON_CONNECTION_EVENT = 26;
private final IConnectionServiceAdapter mDelegate;
@@ -233,10 +234,19 @@ final class ConnectionServiceAdapterServant {
}
break;
}
- case MSG_SET_EXTRAS: {
+ case MSG_PUT_EXTRAS: {
SomeArgs args = (SomeArgs) msg.obj;
try {
- mDelegate.setExtras((String) args.arg1, (Bundle) args.arg2);
+ mDelegate.putExtras((String) args.arg1, (Bundle) args.arg2);
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_REMOVE_EXTRAS: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ mDelegate.removeExtras((String) args.arg1, (List<String>) args.arg2);
} finally {
args.recycle();
}
@@ -425,11 +435,19 @@ final class ConnectionServiceAdapterServant {
}
@Override
- public final void setExtras(String connectionId, Bundle extras) {
+ public final void putExtras(String connectionId, Bundle extras) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = connectionId;
args.arg2 = extras;
- mHandler.obtainMessage(MSG_SET_EXTRAS, args).sendToTarget();
+ mHandler.obtainMessage(MSG_PUT_EXTRAS, args).sendToTarget();
+ }
+
+ @Override
+ public final void removeExtras(String connectionId, List<String> keys) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = connectionId;
+ args.arg2 = keys;
+ mHandler.obtainMessage(MSG_REMOVE_EXTRAS, args).sendToTarget();
}
@Override
diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java
index 52ef4a705e05..3f270d9c5829 100644
--- a/telecomm/java/android/telecom/InCallAdapter.java
+++ b/telecomm/java/android/telecom/InCallAdapter.java
@@ -21,6 +21,8 @@ import android.os.RemoteException;
import com.android.internal.telecom.IInCallAdapter;
+import java.util.List;
+
/**
* Receives commands from {@link InCallService} implementations which should be executed by
* Telecom. When Telecom binds to a {@link InCallService}, an instance of this class is given to
@@ -278,6 +280,79 @@ public final class InCallAdapter {
}
/**
+ * Intructs Telecom to add extras to a call.
+ *
+ * @param callId The callId to add the extras to.
+ * @param extras The extras.
+ */
+ public void putExtras(String callId, Bundle extras) {
+ try {
+ mAdapter.putExtras(callId, extras);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
+ * Intructs Telecom to add an extra to a call.
+ *
+ * @param callId The callId to add the extras to.
+ * @param key The extra key.
+ * @param value The extra value.
+ */
+ public void putExtra(String callId, String key, boolean value) {
+ try {
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(key, value);
+ mAdapter.putExtras(callId, bundle);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
+ * Intructs Telecom to add an extra to a call.
+ *
+ * @param callId The callId to add the extras to.
+ * @param key The extra key.
+ * @param value The extra value.
+ */
+ public void putExtra(String callId, String key, int value) {
+ try {
+ Bundle bundle = new Bundle();
+ bundle.putInt(key, value);
+ mAdapter.putExtras(callId, bundle);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
+ * Intructs Telecom to add an extra to a call.
+ *
+ * @param callId The callId to add the extras to.
+ * @param key The extra key.
+ * @param value The extra value.
+ */
+ public void putExtra(String callId, String key, String value) {
+ try {
+ Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ mAdapter.putExtras(callId, bundle);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
+ * Intructs Telecom to remove extras from a call.
+ * @param callId The callId to remove the extras from.
+ * @param keys The extra keys to remove.
+ */
+ public void removeExtras(String callId, List<String> keys) {
+ try {
+ mAdapter.removeExtras(callId, keys);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
* Instructs Telecom to turn the proximity sensor on.
*/
public void turnProximitySensorOn() {
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index ae5cd464d72c..b03cb51277b5 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -279,15 +279,35 @@ public final class RemoteConference {
}
/** @hide */
- void setExtras(final Bundle extras) {
- mExtras = extras;
+ void putExtras(final Bundle extras) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putAll(extras);
+
+ notifyExtrasChanged();
+ }
+
+ /** @hide */
+ void removeExtras(List<String> keys) {
+ if (mExtras == null || keys == null || keys.isEmpty()) {
+ return;
+ }
+ for (String key : keys) {
+ mExtras.remove(key);
+ }
+
+ notifyExtrasChanged();
+ }
+
+ private void notifyExtrasChanged() {
for (CallbackRecord<Callback> record : mCallbackRecords) {
final RemoteConference conference = this;
final Callback callback = record.getCallback();
record.getHandler().post(new Runnable() {
@Override
public void run() {
- callback.onExtrasChanged(conference, extras);
+ callback.onExtrasChanged(conference, mExtras);
}
});
}
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 5b602eb49dca..7df6678bd5d3 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -1302,15 +1302,35 @@ public final class RemoteConnection {
}
/** @hide */
- void setExtras(final Bundle extras) {
- mExtras = extras;
+ void putExtras(final Bundle extras) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putAll(extras);
+
+ notifyExtrasChanged();
+ }
+
+ /** @hide */
+ void removeExtras(List<String> keys) {
+ if (mExtras == null || keys == null || keys.isEmpty()) {
+ return;
+ }
+ for (String key : keys) {
+ mExtras.remove(key);
+ }
+
+ notifyExtrasChanged();
+ }
+
+ private void notifyExtrasChanged() {
for (CallbackRecord record : mCallbackRecords) {
final RemoteConnection connection = this;
final Callback callback = record.getCallback();
record.getHandler().post(new Runnable() {
@Override
public void run() {
- callback.onExtrasChanged(connection, extras);
+ callback.onExtrasChanged(connection, mExtras);
}
});
}
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index fa7183acc350..d88d007e532e 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -321,13 +321,20 @@ final class RemoteConnectionService {
}
@Override
- public void setExtras(String callId, Bundle extras) {
- if (mConnectionById.containsKey(callId)) {
- findConnectionForAction(callId, "setExtras")
- .setExtras(extras);
+ public void putExtras(String callId, Bundle extras) {
+ if (hasConnection(callId)) {
+ findConnectionForAction(callId, "putExtras").putExtras(extras);
+ } else {
+ findConferenceForAction(callId, "putExtras").putExtras(extras);
+ }
+ }
+
+ @Override
+ public void removeExtras(String callId, List<String> keys) {
+ if (hasConnection(callId)) {
+ findConnectionForAction(callId, "removeExtra").removeExtras(keys);
} else {
- findConferenceForAction(callId, "setExtras")
- .setExtras(extras);
+ findConferenceForAction(callId, "removeExtra").removeExtras(keys);
}
}
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index 3ee0e9f94443..a4c179820331 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -79,4 +79,6 @@ oneway interface IConnectionService {
void pullExternalCall(String callId);
void sendCallEvent(String callId, String event, in Bundle extras);
+
+ void onExtrasChanged(String callId, in Bundle extras);
}
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index dff1b1138741..680480500eea 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -85,7 +85,9 @@ oneway interface IConnectionServiceAdapter {
void addExistingConnection(String callId, in ParcelableConnection connection);
- void setExtras(String callId, in Bundle extras);
+ void putExtras(String callId, in Bundle extras);
+
+ void removeExtras(String callId, in List<String> keys);
void onConnectionEvent(String callId, String event, in Bundle extras);
}
diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
index 0678fe2c0aa4..49f9b3b8af73 100644
--- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
@@ -65,4 +65,8 @@ oneway interface IInCallAdapter {
void pullExternalCall(String callId);
void sendCallEvent(String callId, String event, in Bundle extras);
+
+ void putExtras(String callId, in Bundle extras);
+
+ void removeExtras(String callId, in List<String> keys);
}