summaryrefslogtreecommitdiff
path: root/android/telecom
diff options
context:
space:
mode:
authorJustin Klaassen <justinklaassen@google.com>2018-04-03 23:21:57 -0400
committerJustin Klaassen <justinklaassen@google.com>2018-04-03 23:21:57 -0400
commit4d01eeaffaa720e4458a118baa137a11614f00f7 (patch)
tree66751893566986236788e3c796a7cc5e90d05f52 /android/telecom
parenta192cc2a132cb0ee8588e2df755563ec7008c179 (diff)
downloadandroid-28-4d01eeaffaa720e4458a118baa137a11614f00f7.tar.gz
Import Android SDK Platform P [4697573]
/google/data/ro/projects/android/fetch_artifact \ --bid 4697573 \ --target sdk_phone_armv7-win_sdk \ sdk-repo-linux-sources-4697573.zip AndroidVersion.ApiLevel has been modified to appear as 28 Change-Id: If80578c3c657366cc9cf75f8db13d46e2dd4e077
Diffstat (limited to 'android/telecom')
-rw-r--r--android/telecom/Call.java185
-rw-r--r--android/telecom/Conference.java33
-rw-r--r--android/telecom/Connection.java116
-rw-r--r--android/telecom/ConnectionRequest.java7
-rw-r--r--android/telecom/ConnectionService.java135
-rw-r--r--android/telecom/DisconnectCause.java27
-rw-r--r--android/telecom/InCallAdapter.java14
-rw-r--r--android/telecom/InCallService.java20
-rw-r--r--android/telecom/Logging/EventManager.java31
-rw-r--r--android/telecom/PhoneAccount.java19
-rw-r--r--android/telecom/RemoteConnectionService.java4
-rw-r--r--android/telecom/TelecomManager.java39
-rw-r--r--android/telecom/TransformationInfo.java127
-rw-r--r--android/telecom/VideoProfile.java1
14 files changed, 491 insertions, 267 deletions
diff --git a/android/telecom/Call.java b/android/telecom/Call.java
index 67994179..1c0e260b 100644
--- a/android/telecom/Call.java
+++ b/android/telecom/Call.java
@@ -352,8 +352,11 @@ public final class Call {
*/
public static final int CAPABILITY_CAN_PULL_CALL = 0x00800000;
+ /** Call supports the deflect feature. */
+ public static final int CAPABILITY_SUPPORT_DEFLECT = 0x01000000;
+
//******************************************************************************************
- // Next CAPABILITY value: 0x01000000
+ // Next CAPABILITY value: 0x02000000
//******************************************************************************************
/**
@@ -419,11 +422,18 @@ public final class Call {
/**
* Indicates the call used Assisted Dialing.
* See also {@link Connection#PROPERTY_ASSISTED_DIALING_USED}
+ * @hide
*/
public static final int PROPERTY_ASSISTED_DIALING_USED = 0x00000200;
+ /**
+ * Indicates that the call is an RTT call. Use {@link #getRttCall()} to get the
+ * {@link RttCall} object that is used to send and receive text.
+ */
+ public static final int PROPERTY_RTT = 0x00000400;
+
//******************************************************************************************
- // Next PROPERTY value: 0x00000400
+ // Next PROPERTY value: 0x00000800
//******************************************************************************************
private final String mTelecomCallId;
@@ -528,6 +538,9 @@ public final class Call {
if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
builder.append(" CAPABILITY_CAN_PULL_CALL");
}
+ if (can(capabilities, CAPABILITY_SUPPORT_DEFLECT)) {
+ builder.append(" CAPABILITY_SUPPORT_DEFLECT");
+ }
builder.append("]");
return builder.toString();
}
@@ -866,42 +879,76 @@ public final class Call {
/**
* @hide
*/
- @IntDef({HANDOVER_FAILURE_DEST_APP_REJECTED, HANDOVER_FAILURE_DEST_NOT_SUPPORTED,
- HANDOVER_FAILURE_DEST_INVALID_PERM, HANDOVER_FAILURE_DEST_USER_REJECTED,
- HANDOVER_FAILURE_ONGOING_EMERG_CALL})
+ @IntDef(prefix = { "HANDOVER_" },
+ value = {HANDOVER_FAILURE_DEST_APP_REJECTED, HANDOVER_FAILURE_NOT_SUPPORTED,
+ HANDOVER_FAILURE_USER_REJECTED, HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL,
+ HANDOVER_FAILURE_UNKNOWN})
@Retention(RetentionPolicy.SOURCE)
public @interface HandoverFailureErrors {}
/**
* Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the app
- * to handover the call rejects handover.
+ * to handover the call to rejects the handover request.
+ * <p>
+ * Will be returned when {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} is called
+ * and the destination {@link PhoneAccountHandle}'s {@link ConnectionService} returns a
+ * {@code null} {@link Connection} from
+ * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle,
+ * ConnectionRequest)}.
+ * <p>
+ * For more information on call handovers, see
+ * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
*/
public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1;
/**
- * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there is
- * an error associated with unsupported handover.
- */
- public static final int HANDOVER_FAILURE_DEST_NOT_SUPPORTED = 2;
-
- /**
- * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there
- * are some permission errors associated with APIs doing handover.
+ * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover
+ * is initiated but the source or destination app does not support handover.
+ * <p>
+ * Will be returned when a handover is requested via
+ * {@link #handoverTo(PhoneAccountHandle, int, Bundle)} and the destination
+ * {@link PhoneAccountHandle} does not declare
+ * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}. May also be returned when a handover is
+ * requested at the {@link PhoneAccountHandle} for the current call (i.e. the source call's
+ * {@link Details#getAccountHandle()}) does not declare
+ * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
+ * <p>
+ * For more information on call handovers, see
+ * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
*/
- public static final int HANDOVER_FAILURE_DEST_INVALID_PERM = 3;
+ public static final int HANDOVER_FAILURE_NOT_SUPPORTED = 2;
/**
- * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when user
- * rejects handover.
+ * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when the remote
+ * user rejects the handover request.
+ * <p>
+ * For more information on call handovers, see
+ * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
*/
- public static final int HANDOVER_FAILURE_DEST_USER_REJECTED = 4;
+ public static final int HANDOVER_FAILURE_USER_REJECTED = 3;
/**
* Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when there
* is ongoing emergency call.
+ * <p>
+ * This error code is returned when {@link #handoverTo(PhoneAccountHandle, int, Bundle)} is
+ * called on an emergency call, or if any other call is an emergency call.
+ * <p>
+ * Handovers are not permitted while there are ongoing emergency calls.
+ * <p>
+ * For more information on call handovers, see
+ * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
*/
- public static final int HANDOVER_FAILURE_ONGOING_EMERG_CALL = 5;
+ public static final int HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL = 4;
+ /**
+ * Handover failure reason returned via {@link #onHandoverFailed(Call, int)} when a handover
+ * fails for an unknown reason.
+ * <p>
+ * For more information on call handovers, see
+ * {@link #handoverTo(PhoneAccountHandle, int, Bundle)}.
+ */
+ public static final int HANDOVER_FAILURE_UNKNOWN = 5;
/**
* Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
@@ -1042,6 +1089,10 @@ public final class Call {
/**
* Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
* has completed successfully.
+ * <p>
+ * For a full discussion of the handover process and the APIs involved, see
+ * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
+ *
* @param call The call which had initiated handover.
*/
public void onHandoverComplete(Call call) {}
@@ -1049,8 +1100,12 @@ public final class Call {
/**
* Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
* has failed.
+ * <p>
+ * For a full discussion of the handover process and the APIs involved, see
+ * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
+ *
* @param call The call which had initiated handover.
- * @param failureReason Error reason for failure
+ * @param failureReason Error reason for failure.
*/
public void onHandoverFailed(Call call, @HandoverFailureErrors int failureReason) {}
}
@@ -1183,6 +1238,23 @@ public final class Call {
return null;
}
}
+
+ /**
+ * Closes the underlying file descriptors
+ * @hide
+ */
+ public void close() {
+ try {
+ mReceiveStream.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ try {
+ mTransmitStream.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
}
/**
@@ -1230,11 +1302,20 @@ public final class Call {
* Instructs this {@link #STATE_RINGING} {@code Call} to answer.
* @param videoState The video state in which to answer the call.
*/
- public void answer(int videoState) {
+ public void answer(@VideoProfile.VideoState int videoState) {
mInCallAdapter.answerCall(mTelecomCallId, videoState);
}
/**
+ * Instructs this {@link #STATE_RINGING} {@code Call} to deflect.
+ *
+ * @param address The address to which the call will be deflected.
+ */
+ public void deflect(Uri address) {
+ mInCallAdapter.deflectCall(mTelecomCallId, address);
+ }
+
+ /**
* Instructs this {@link #STATE_RINGING} {@code Call} to reject.
*
* @param rejectWithMessage Whether to reject with a text message.
@@ -1435,16 +1516,65 @@ public final class Call {
* by {@code toHandle}. The videoState specified indicates the desired video state after the
* handover.
* <p>
- * A handover request is initiated by the user from one app to indicate a desire
- * to handover a call to another.
+ * A call handover is the process where an ongoing call is transferred from one app (i.e.
+ * {@link ConnectionService} to another app. The user could, for example, choose to continue a
+ * mobile network call in a video calling app. The mobile network call via the Telephony stack
+ * is referred to as the source of the handover, and the video calling app is referred to as the
+ * destination.
+ * <p>
+ * When considering a handover scenario the device this method is called on is considered the
+ * <em>initiating</em> device (since the user initiates the handover from this device), and the
+ * other device is considered the <em>receiving</em> device.
+ * <p>
+ * When this method is called on the <em>initiating</em> device, the Telecom framework will bind
+ * to the {@link ConnectionService} defined by the {@code toHandle} {@link PhoneAccountHandle}
+ * and invoke
+ * {@link ConnectionService#onCreateOutgoingHandoverConnection(PhoneAccountHandle,
+ * ConnectionRequest)} to inform the destination app that a request has been made to handover a
+ * call to it. The app returns an instance of {@link Connection} to represent the handover call
+ * At this point the app should display UI to indicate to the user that a call
+ * handover is in process.
+ * <p>
+ * The destination app is responsible for communicating the handover request from the
+ * <em>initiating</em> device to the <em>receiving</em> device.
+ * <p>
+ * When the app on the <em>receiving</em> device receives the handover request, it calls
+ * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to continue the handover
+ * process from the <em>initiating</em> device to the <em>receiving</em> device. At this point
+ * the destination app on the <em>receiving</em> device should show UI to allow the user to
+ * choose whether they want to continue their call in the destination app.
+ * <p>
+ * When the destination app on the <em>receiving</em> device calls
+ * {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)}, Telecom will bind to its
+ * {@link ConnectionService} and call
+ * {@link ConnectionService#onCreateIncomingHandoverConnection(PhoneAccountHandle,
+ * ConnectionRequest)} to inform it of the handover request. The app returns an instance of
+ * {@link Connection} to represent the handover call.
+ * <p>
+ * If the user of the <em>receiving</em> device accepts the handover, the app calls
+ * {@link Connection#setActive()} to complete the handover process; Telecom will disconnect the
+ * original call. If the user rejects the handover, the app calls
+ * {@link Connection#setDisconnected(DisconnectCause)} and specifies a {@link DisconnectCause}
+ * of {@link DisconnectCause#CANCELED} to indicate that the handover has been cancelled.
+ * <p>
+ * Telecom will only allow handovers from {@link PhoneAccount}s which declare
+ * {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}. Similarly, the {@link PhoneAccount}
+ * specified by {@code toHandle} must declare {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_TO}.
+ * <p>
+ * Errors in the handover process are reported to the {@link InCallService} via
+ * {@link Callback#onHandoverFailed(Call, int)}. Errors in the handover process are reported to
+ * the involved {@link ConnectionService}s via
+ * {@link ConnectionService#onHandoverFailed(ConnectionRequest, int)}.
*
* @param toHandle {@link PhoneAccountHandle} of the {@link ConnectionService} to handover
* this call to.
- * @param videoState Indicates the video state desired after the handover.
+ * @param videoState Indicates the video state desired after the handover (see the
+ * {@code STATE_*} constants defined in {@link VideoProfile}).
* @param extras Bundle containing extra information to be passed to the
* {@link ConnectionService}
*/
- public void handoverTo(PhoneAccountHandle toHandle, int videoState, Bundle extras) {
+ public void handoverTo(PhoneAccountHandle toHandle, @VideoProfile.VideoState int videoState,
+ Bundle extras) {
mInCallAdapter.handoverTo(mTelecomCallId, toHandle, videoState, extras);
}
@@ -1649,7 +1779,7 @@ public final class Call {
* @return true if there is a connection, false otherwise.
*/
public boolean isRttActive() {
- return mRttCall != null;
+ return mRttCall != null && mDetails.hasProperty(Details.PROPERTY_RTT);
}
/**
@@ -1852,7 +1982,8 @@ public final class Call {
boolean isRttChanged = false;
boolean rttModeChanged = false;
- if (parcelableCall.getParcelableRttCall() != null && parcelableCall.getIsRttCallChanged()) {
+ if (parcelableCall.getIsRttCallChanged()
+ && mDetails.hasProperty(Details.PROPERTY_RTT)) {
ParcelableRttCall parcelableRttCall = parcelableCall.getParcelableRttCall();
InputStreamReader receiveStream = new InputStreamReader(
new ParcelFileDescriptor.AutoCloseInputStream(
diff --git a/android/telecom/Conference.java b/android/telecom/Conference.java
index 5fcff18a..024bd303 100644
--- a/android/telecom/Conference.java
+++ b/android/telecom/Conference.java
@@ -29,7 +29,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
-import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -82,7 +81,7 @@ public abstract class Conference extends Conferenceable {
private int mConnectionProperties;
private String mDisconnectMessage;
private long mConnectTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
- private long mConnectElapsedTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
+ private long mConnectionStartElapsedRealTime = CONNECT_TIME_NOT_SPECIFIED;
private StatusHints mStatusHints;
private Bundle mExtras;
private Set<String> mPreviousExtraKeys;
@@ -584,30 +583,36 @@ public abstract class Conference extends Conferenceable {
}
/**
- * Sets the connection start time of the {@code Conference}. Should be specified in wall-clock
- * time returned by {@link System#currentTimeMillis()}.
+ * Sets the connection start time of the {@code Conference}. This is used in the call log to
+ * indicate the date and time when the conference took place.
+ * <p>
+ * Should be specified in wall-clock time returned by {@link System#currentTimeMillis()}.
* <p>
* When setting the connection time, you should always set the connection elapsed time via
- * {@link #setConnectionElapsedTime(long)}.
+ * {@link #setConnectionStartElapsedRealTime(long)} to ensure the duration is reflected.
*
- * @param connectionTimeMillis The connection time, in milliseconds.
+ * @param connectionTimeMillis The connection time, in milliseconds, as returned by
+ * {@link System#currentTimeMillis()}.
*/
public final void setConnectionTime(long connectionTimeMillis) {
mConnectTimeMillis = connectionTimeMillis;
}
/**
- * Sets the elapsed time since system boot when the {@link Conference} was connected.
- * This is used to determine the duration of the {@link Conference}.
+ * Sets the start time of the {@link Conference} which is the basis for the determining the
+ * duration of the {@link Conference}.
+ * <p>
+ * You should use a value returned by {@link SystemClock#elapsedRealtime()} to ensure that time
+ * zone changes do not impact the conference duration.
* <p>
- * When setting the connection elapsed time, you should always set the connection time via
+ * When setting this, you should also set the connection time via
* {@link #setConnectionTime(long)}.
*
- * @param connectionElapsedTime The connection time, as measured by
+ * @param connectionStartElapsedRealTime The connection time, as measured by
* {@link SystemClock#elapsedRealtime()}.
*/
- public final void setConnectionElapsedTime(long connectionElapsedTime) {
- mConnectElapsedTimeMillis = connectionElapsedTime;
+ public final void setConnectionStartElapsedRealTime(long connectionStartElapsedRealTime) {
+ mConnectionStartElapsedRealTime = connectionStartElapsedRealTime;
}
/**
@@ -642,8 +647,8 @@ public abstract class Conference extends Conferenceable {
* @return The elapsed time at which the {@link Conference} was connected.
* @hide
*/
- public final long getConnectElapsedTime() {
- return mConnectElapsedTimeMillis;
+ public final long getConnectionStartElapsedRealTime() {
+ return mConnectionStartElapsedRealTime;
}
/**
diff --git a/android/telecom/Connection.java b/android/telecom/Connection.java
index 63f970a4..36333e44 100644
--- a/android/telecom/Connection.java
+++ b/android/telecom/Connection.java
@@ -35,12 +35,13 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.ArraySet;
import android.view.Surface;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
@@ -328,8 +329,11 @@ public abstract class Connection extends Conferenceable {
*/
public static final int CAPABILITY_CAN_PULL_CALL = 0x01000000;
+ /** Call supports the deflect feature. */
+ public static final int CAPABILITY_SUPPORT_DEFLECT = 0x02000000;
+
//**********************************************************************************************
- // Next CAPABILITY value: 0x02000000
+ // Next CAPABILITY value: 0x04000000
//**********************************************************************************************
/**
@@ -402,6 +406,7 @@ public abstract class Connection extends Conferenceable {
/**
* Set by the framework to indicate that a connection is using assisted dialing.
+ * @hide
*/
public static final int PROPERTY_ASSISTED_DIALING_USED = 1 << 9;
@@ -726,6 +731,9 @@ public abstract class Connection extends Conferenceable {
if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
builder.append(isLong ? " CAPABILITY_CAN_PULL_CALL" : " pull");
}
+ if (can(capabilities, CAPABILITY_SUPPORT_DEFLECT)) {
+ builder.append(isLong ? " CAPABILITY_SUPPORT_DEFLECT" : " sup_def");
+ }
builder.append("]");
return builder.toString();
@@ -787,6 +795,10 @@ public abstract class Connection extends Conferenceable {
builder.append(isLong ? " PROPERTY_HAS_CDMA_VOICE_PRIVACY" : " priv");
}
+ if (can(properties, PROPERTY_IS_RTT)) {
+ builder.append(isLong ? " PROPERTY_IS_RTT" : " rtt");
+ }
+
builder.append("]");
return builder.toString();
}
@@ -850,18 +862,19 @@ public abstract class Connection extends Conferenceable {
mFdFromInCall = fromInCall;
mFdToInCall = toInCall;
mPipeFromInCall = new InputStreamReader(
- new ParcelFileDescriptor.AutoCloseInputStream(fromInCall));
+ new FileInputStream(fromInCall.getFileDescriptor()));
mPipeToInCall = new OutputStreamWriter(
- new ParcelFileDescriptor.AutoCloseOutputStream(toInCall));
+ new FileOutputStream(toInCall.getFileDescriptor()));
}
/**
* Writes the string {@param input} into the text stream to the UI for this RTT call. Since
* RTT transmits text in real-time, this method should be called as often as text snippets
* are received from the remote user, even if it is only one character.
- *
+ * <p>
* This method is not thread-safe -- calling it from multiple threads simultaneously may
* lead to interleaved text.
+ *
* @param input The message to send to the in-call app.
*/
public void write(String input) throws IOException {
@@ -874,9 +887,10 @@ public abstract class Connection extends Conferenceable {
* Reads a string from the in-call app, blocking if there is no data available. Returns
* {@code null} if the RTT conversation has been terminated and there is no further data
* to read.
- *
+ * <p>
* This method is not thread-safe -- calling it from multiple threads simultaneously may
* lead to interleaved text.
+ *
* @return A string containing text entered by the user, or {@code null} if the
* conversation has been terminated or if there was an error while reading.
*/
@@ -891,6 +905,7 @@ public abstract class Connection extends Conferenceable {
/**
* Non-blocking version of {@link #read()}. Returns {@code null} if there is nothing to
* be read.
+ *
* @return A string containing text entered by the user, or {@code null} if the user has
* not entered any new text yet.
*/
@@ -2289,7 +2304,7 @@ public abstract class Connection extends Conferenceable {
*
* @hide
*/
- public final void setConnectElapsedTimeMillis(long connectElapsedTimeMillis) {
+ public final void setConnectionStartElapsedRealTime(long connectElapsedTimeMillis) {
mConnectElapsedTimeMillis = connectElapsedTimeMillis;
}
@@ -2538,19 +2553,6 @@ public abstract class Connection extends Conferenceable {
}
/**
- * Adds a parcelable extra to this {@code Connection}.
- *
- * @param key The extra key.
- * @param value The value.
- * @hide
- */
- public final void putExtra(@NonNull String key, @NonNull Parcelable value) {
- Bundle newExtras = new Bundle();
- newExtras.putParcelable(key, value);
- putExtras(newExtras);
- }
-
- /**
* Removes extras from this {@code Connection}.
*
* @param keys The keys of the extras to remove.
@@ -2625,7 +2627,6 @@ public abstract class Connection extends Conferenceable {
* {@link #onStartRtt(RttTextStream)} has succeeded.
*/
public final void sendRttInitiationSuccess() {
- setRttProperty();
mListeners.forEach((l) -> l.onRttInitiationSuccess(Connection.this));
}
@@ -2637,7 +2638,6 @@ public abstract class Connection extends Conferenceable {
* exception of {@link RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
*/
public final void sendRttInitiationFailure(int reason) {
- unsetRttProperty();
mListeners.forEach((l) -> l.onRttInitiationFailure(Connection.this, reason));
}
@@ -2732,7 +2732,20 @@ public abstract class Connection extends Conferenceable {
/**
* Notifies this Connection, which is in {@link #STATE_RINGING}, of
* a request to accept.
- *
+ * <p>
+ * For managed {@link ConnectionService}s, this will be called when the user answers a call via
+ * the default dialer's {@link InCallService}.
+ * <p>
+ * Although a self-managed {@link ConnectionService} provides its own incoming call UI, the
+ * Telecom framework may request that the call is answered in the following circumstances:
+ * <ul>
+ * <li>The user chooses to answer an incoming call via a Bluetooth device.</li>
+ * <li>A car mode {@link InCallService} is in use which has declared
+ * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS} in its manifest. Such an
+ * {@link InCallService} will be able to see calls from self-managed
+ * {@link ConnectionService}s, and will be able to display an incoming call UI on their
+ * behalf.</li>
+ * </ul>
* @param videoState The video state in which to answer the connection.
*/
public void onAnswer(int videoState) {}
@@ -2740,6 +2753,20 @@ public abstract class Connection extends Conferenceable {
/**
* Notifies this Connection, which is in {@link #STATE_RINGING}, of
* a request to accept.
+ * <p>
+ * For managed {@link ConnectionService}s, this will be called when the user answers a call via
+ * the default dialer's {@link InCallService}.
+ * <p>
+ * Although a self-managed {@link ConnectionService} provides its own incoming call UI, the
+ * Telecom framework may request that the call is answered in the following circumstances:
+ * <ul>
+ * <li>The user chooses to answer an incoming call via a Bluetooth device.</li>
+ * <li>A car mode {@link InCallService} is in use which has declared
+ * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS} in its manifest. Such an
+ * {@link InCallService} will be able to see calls from self-managed
+ * {@link ConnectionService}s, and will be able to display an incoming call UI on their
+ * behalf.</li>
+ * </ul>
*/
public void onAnswer() {
onAnswer(VideoProfile.STATE_AUDIO_ONLY);
@@ -2747,7 +2774,27 @@ public abstract class Connection extends Conferenceable {
/**
* Notifies this Connection, which is in {@link #STATE_RINGING}, of
+ * a request to deflect.
+ */
+ public void onDeflect(Uri address) {}
+
+ /**
+ * Notifies this Connection, which is in {@link #STATE_RINGING}, of
* a request to reject.
+ * <p>
+ * For managed {@link ConnectionService}s, this will be called when the user rejects a call via
+ * the default dialer's {@link InCallService}.
+ * <p>
+ * Although a self-managed {@link ConnectionService} provides its own incoming call UI, the
+ * Telecom framework may request that the call is rejected in the following circumstances:
+ * <ul>
+ * <li>The user chooses to reject an incoming call via a Bluetooth device.</li>
+ * <li>A car mode {@link InCallService} is in use which has declared
+ * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS} in its manifest. Such an
+ * {@link InCallService} will be able to see calls from self-managed
+ * {@link ConnectionService}s, and will be able to display an incoming call UI on their
+ * behalf.</li>
+ * </ul>
*/
public void onReject() {}
@@ -2830,9 +2877,10 @@ public abstract class Connection extends Conferenceable {
* should show its own incoming call user interface.
* <p>
* Where there are ongoing calls in other self-managed {@link ConnectionService}s, or in a
- * regular {@link ConnectionService}, the Telecom framework will display its own incoming call
- * user interface to allow the user to choose whether to answer the new incoming call and
- * disconnect other ongoing calls, or to reject the new incoming call.
+ * regular {@link ConnectionService}, and it is not possible to hold these other calls, the
+ * Telecom framework will display its own incoming call user interface to allow the user to
+ * choose whether to answer the new incoming call and disconnect other ongoing calls, or to
+ * reject the new incoming call.
* <p>
* You should trigger the display of the incoming call user interface for your application by
* showing a {@link Notification} with a full-screen {@link Intent} specified.
@@ -2897,22 +2945,6 @@ public abstract class Connection extends Conferenceable {
*/
public void handleRttUpgradeResponse(@Nullable RttTextStream rttTextStream) {}
- /**
- * Internal method to set {@link #PROPERTY_IS_RTT}.
- * @hide
- */
- void setRttProperty() {
- setConnectionProperties(getConnectionProperties() | PROPERTY_IS_RTT);
- }
-
- /**
- * Internal method to un-set {@link #PROPERTY_IS_RTT}.
- * @hide
- */
- void unsetRttProperty() {
- setConnectionProperties(getConnectionProperties() & (~PROPERTY_IS_RTT));
- }
-
static String toLogSafePhoneNumber(String number) {
// For unknown number, log empty string.
if (number == null) {
diff --git a/android/telecom/ConnectionRequest.java b/android/telecom/ConnectionRequest.java
index 658b4734..b6e6b0ed 100644
--- a/android/telecom/ConnectionRequest.java
+++ b/android/telecom/ConnectionRequest.java
@@ -143,6 +143,8 @@ public final class ConnectionRequest implements Parcelable {
private final boolean mShouldShowIncomingCallUi;
private final ParcelFileDescriptor mRttPipeToInCall;
private final ParcelFileDescriptor mRttPipeFromInCall;
+ // Cached return value of getRttTextStream -- we don't want to wrap it more than once.
+ private Connection.RttTextStream mRttTextStream;
/**
* @param accountHandle The accountHandle which should be used to place the call.
@@ -312,7 +314,10 @@ public final class ConnectionRequest implements Parcelable {
*/
public Connection.RttTextStream getRttTextStream() {
if (isRequestingRtt()) {
- return new Connection.RttTextStream(mRttPipeToInCall, mRttPipeFromInCall);
+ if (mRttTextStream == null) {
+ mRttTextStream = new Connection.RttTextStream(mRttPipeToInCall, mRttPipeFromInCall);
+ }
+ return mRttTextStream;
} else {
return null;
}
diff --git a/android/telecom/ConnectionService.java b/android/telecom/ConnectionService.java
index c1040adc..fc32b177 100644
--- a/android/telecom/ConnectionService.java
+++ b/android/telecom/ConnectionService.java
@@ -21,7 +21,6 @@ import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -124,6 +123,7 @@ public abstract class ConnectionService extends Service {
private static final String SESSION_ABORT = "CS.ab";
private static final String SESSION_ANSWER = "CS.an";
private static final String SESSION_ANSWER_VIDEO = "CS.anV";
+ private static final String SESSION_DEFLECT = "CS.def";
private static final String SESSION_REJECT = "CS.r";
private static final String SESSION_REJECT_MESSAGE = "CS.rWM";
private static final String SESSION_SILENCE = "CS.s";
@@ -143,6 +143,7 @@ public abstract class ConnectionService extends Service {
private static final String SESSION_HANDOVER_COMPLETE = "CS.hC";
private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
private static final String SESSION_START_RTT = "CS.+RTT";
+ private static final String SESSION_UPDATE_RTT_PIPES = "CS.uRTT";
private static final String SESSION_STOP_RTT = "CS.-RTT";
private static final String SESSION_RTT_UPGRADE_RESPONSE = "CS.rTRUR";
private static final String SESSION_CONNECTION_SERVICE_FOCUS_LOST = "CS.cSFL";
@@ -181,6 +182,7 @@ public abstract class ConnectionService extends Service {
private static final int MSG_CONNECTION_SERVICE_FOCUS_GAINED = 31;
private static final int MSG_HANDOVER_FAILED = 32;
private static final int MSG_HANDOVER_COMPLETE = 33;
+ private static final int MSG_DEFLECT = 34;
private static Connection sNullConnection;
@@ -353,6 +355,20 @@ public abstract class ConnectionService extends Service {
}
@Override
+ public void deflect(String callId, Uri address, Session.Info sessionInfo) {
+ Log.startSession(sessionInfo, SESSION_DEFLECT);
+ try {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = address;
+ args.arg3 = Log.createSubsession();
+ mHandler.obtainMessage(MSG_DEFLECT, args).sendToTarget();
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
public void reject(String callId, Session.Info sessionInfo) {
Log.startSession(sessionInfo, SESSION_REJECT);
try {
@@ -847,6 +863,17 @@ public abstract class ConnectionService extends Service {
}
break;
}
+ case MSG_DEFLECT: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT);
+ try {
+ deflect((String) args.arg1, (Uri) args.arg2);
+ } finally {
+ args.recycle();
+ Log.endSession();
+ }
+ break;
+ }
case MSG_REJECT: {
SomeArgs args = (SomeArgs) msg.obj;
Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
@@ -1605,6 +1632,11 @@ public abstract class ConnectionService extends Service {
findConnectionForAction(callId, "answer").onAnswer();
}
+ private void deflect(String callId, Uri address) {
+ Log.d(this, "deflect %s", callId);
+ findConnectionForAction(callId, "deflect").onDeflect(address);
+ }
+
private void reject(String callId) {
Log.d(this, "reject %s", callId);
findConnectionForAction(callId, "reject").onReject();
@@ -1833,7 +1865,6 @@ public abstract class ConnectionService extends Service {
Log.d(this, "stopRtt(%s)", callId);
if (mConnectionById.containsKey(callId)) {
findConnectionForAction(callId, "stopRtt").onStopRtt();
- findConnectionForAction(callId, "stopRtt").unsetRttProperty();
} else if (mConferenceById.containsKey(callId)) {
Log.w(this, "stopRtt called on a conference.");
}
@@ -1975,7 +2006,7 @@ public abstract class ConnectionService extends Service {
null : conference.getVideoProvider().getInterface(),
conference.getVideoState(),
conference.getConnectTimeMillis(),
- conference.getConnectElapsedTime(),
+ conference.getConnectionStartElapsedRealTime(),
conference.getStatusHints(),
conference.getExtras());
@@ -2188,12 +2219,50 @@ public abstract class ConnectionService extends Service {
}
/**
- * Called by Telecom on the initiating side of the handover to create an instance of a
- * handover connection.
+ * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
+ * outgoing handover {@link Connection}.
+ * <p>
+ * A call handover is the process where an ongoing call is transferred from one app (i.e.
+ * {@link ConnectionService} to another app. The user could, for example, choose to continue a
+ * mobile network call in a video calling app. The mobile network call via the Telephony stack
+ * is referred to as the source of the handover, and the video calling app is referred to as the
+ * destination.
+ * <p>
+ * When considering a handover scenario the <em>initiating</em> device is where a user initiated
+ * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
+ * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
+ * device.
+ * <p>
+ * This method is called on the destination {@link ConnectionService} on <em>initiating</em>
+ * device when the user initiates a handover request from one app to another. The user request
+ * originates in the {@link InCallService} via
+ * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
+ * <p>
+ * For a full discussion of the handover process and the APIs involved, see
+ * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
+ * <p>
+ * Implementations of this method should return an instance of {@link Connection} which
+ * represents the handover. If your app does not wish to accept a handover to it at this time,
+ * you can return {@code null}. The code below shows an example of how this is done.
+ * <pre>
+ * {@code
+ * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
+ * fromPhoneAccountHandle, ConnectionRequest request) {
+ * if (!isHandoverAvailable()) {
+ * return null;
+ * }
+ * MyConnection connection = new MyConnection();
+ * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
+ * connection.setVideoState(request.getVideoState());
+ * return connection;
+ * }
+ * }
+ * </pre>
+ *
* @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
* ConnectionService which needs to handover the call.
- * @param request Details about the call which needs to be handover.
- * @return Connection object corresponding to the handover call.
+ * @param request Details about the call to handover.
+ * @return {@link Connection} instance corresponding to the handover call.
*/
public Connection onCreateOutgoingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
ConnectionRequest request) {
@@ -2201,12 +2270,46 @@ public abstract class ConnectionService extends Service {
}
/**
- * Called by Telecom on the receiving side of the handover to request the
- * {@link ConnectionService} to create an instance of a handover connection.
+ * Called by Telecom to request that a {@link ConnectionService} creates an instance of an
+ * incoming handover {@link Connection}.
+ * <p>
+ * A call handover is the process where an ongoing call is transferred from one app (i.e.
+ * {@link ConnectionService} to another app. The user could, for example, choose to continue a
+ * mobile network call in a video calling app. The mobile network call via the Telephony stack
+ * is referred to as the source of the handover, and the video calling app is referred to as the
+ * destination.
+ * <p>
+ * When considering a handover scenario the <em>initiating</em> device is where a user initiated
+ * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
+ * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
+ * device.
+ * <p>
+ * This method is called on the destination app on the <em>receiving</em> device when the
+ * destination app calls {@link TelecomManager#acceptHandover(Uri, int, PhoneAccountHandle)} to
+ * accept an incoming handover from the <em>initiating</em> device.
+ * <p>
+ * For a full discussion of the handover process and the APIs involved, see
+ * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
+ * <p>
+ * Implementations of this method should return an instance of {@link Connection} which
+ * represents the handover. The code below shows an example of how this is done.
+ * <pre>
+ * {@code
+ * public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle
+ * fromPhoneAccountHandle, ConnectionRequest request) {
+ * // Given that your app requested to accept the handover, you should not return null here.
+ * MyConnection connection = new MyConnection();
+ * connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
+ * connection.setVideoState(request.getVideoState());
+ * return connection;
+ * }
+ * }
+ * </pre>
+ *
* @param fromPhoneAccountHandle {@link PhoneAccountHandle} associated with the
* ConnectionService which needs to handover the call.
* @param request Details about the call which needs to be handover.
- * @return {@link Connection} object corresponding to the handover call.
+ * @return {@link Connection} instance corresponding to the handover call.
*/
public Connection onCreateIncomingHandoverConnection(PhoneAccountHandle fromPhoneAccountHandle,
ConnectionRequest request) {
@@ -2216,11 +2319,15 @@ public abstract class ConnectionService extends Service {
/**
* Called by Telecom in response to a {@code TelecomManager#acceptHandover()}
* invocation which failed.
- * @param request Details about the call which needs to be handover.
- * @param error Reason for handover failure as defined in
- * {@link android.telecom.Call.Callback#HANDOVER_FAILURE_DEST_INVALID_PERM}
+ * <p>
+ * For a full discussion of the handover process and the APIs involved, see
+ * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}
+ *
+ * @param request Details about the call which failed to handover.
+ * @param error Reason for handover failure. Will be one of the
*/
- public void onHandoverFailed(ConnectionRequest request, int error) {
+ public void onHandoverFailed(ConnectionRequest request,
+ @Call.Callback.HandoverFailureErrors int error) {
return;
}
diff --git a/android/telecom/DisconnectCause.java b/android/telecom/DisconnectCause.java
index dcf5c271..1de67a58 100644
--- a/android/telecom/DisconnectCause.java
+++ b/android/telecom/DisconnectCause.java
@@ -33,47 +33,48 @@ import java.util.Objects;
public final class DisconnectCause implements Parcelable {
/** Disconnected because of an unknown or unspecified reason. */
- public static final int UNKNOWN = 0;
+ public static final int UNKNOWN = TelecomProtoEnums.UNKNOWN; // = 0
/** Disconnected because there was an error, such as a problem with the network. */
- public static final int ERROR = 1;
+ public static final int ERROR = TelecomProtoEnums.ERROR; // = 1
/** Disconnected because of a local user-initiated action, such as hanging up. */
- public static final int LOCAL = 2;
+ public static final int LOCAL = TelecomProtoEnums.LOCAL; // = 2
/**
* Disconnected because of a remote user-initiated action, such as the other party hanging up
* up.
*/
- public static final int REMOTE = 3;
+ public static final int REMOTE = TelecomProtoEnums.REMOTE; // = 3
/** Disconnected because it has been canceled. */
- public static final int CANCELED = 4;
+ public static final int CANCELED = TelecomProtoEnums.CANCELED; // = 4
/** Disconnected because there was no response to an incoming call. */
- public static final int MISSED = 5;
+ public static final int MISSED = TelecomProtoEnums.MISSED; // = 5
/** Disconnected because the user rejected an incoming call. */
- public static final int REJECTED = 6;
+ public static final int REJECTED = TelecomProtoEnums.REJECTED; // = 6
/** Disconnected because the other party was busy. */
- public static final int BUSY = 7;
+ public static final int BUSY = TelecomProtoEnums.BUSY; // = 7
/**
* Disconnected because of a restriction on placing the call, such as dialing in airplane
* mode.
*/
- public static final int RESTRICTED = 8;
+ public static final int RESTRICTED = TelecomProtoEnums.RESTRICTED; // = 8
/** Disconnected for reason not described by other disconnect codes. */
- public static final int OTHER = 9;
+ public static final int OTHER = TelecomProtoEnums.OTHER; // = 9
/**
* Disconnected because the connection manager did not support the call. The call will be tried
* again without a connection manager. See {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
*/
- public static final int CONNECTION_MANAGER_NOT_SUPPORTED = 10;
+ public static final int CONNECTION_MANAGER_NOT_SUPPORTED =
+ TelecomProtoEnums.CONNECTION_MANAGER_NOT_SUPPORTED; // = 10
/**
* Disconnected because the user did not locally answer the incoming call, but it was answered
* on another device where the call was ringing.
*/
- public static final int ANSWERED_ELSEWHERE = 11;
+ public static final int ANSWERED_ELSEWHERE = TelecomProtoEnums.ANSWERED_ELSEWHERE; // = 11
/**
* Disconnected because the call was pulled from the current device to another device.
*/
- public static final int CALL_PULLED = 12;
+ public static final int CALL_PULLED = TelecomProtoEnums.CALL_PULLED; // = 12
/**
* Reason code (returned via {@link #getReason()}) which indicates that a call could not be
diff --git a/android/telecom/InCallAdapter.java b/android/telecom/InCallAdapter.java
index 658685fe..8678e33f 100644
--- a/android/telecom/InCallAdapter.java
+++ b/android/telecom/InCallAdapter.java
@@ -16,6 +16,7 @@
package android.telecom;
+import android.net.Uri;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
import android.os.RemoteException;
@@ -61,6 +62,19 @@ public final class InCallAdapter {
}
/**
+ * Instructs Telecom to deflect the specified call.
+ *
+ * @param callId The identifier of the call to deflect.
+ * @param address The address to deflect.
+ */
+ public void deflectCall(String callId, Uri address) {
+ try {
+ mAdapter.deflectCall(callId, address);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
* Instructs Telecom to reject the specified call.
*
* @param callId The identifier of the call to reject.
diff --git a/android/telecom/InCallService.java b/android/telecom/InCallService.java
index fcf04c9a..af65c65a 100644
--- a/android/telecom/InCallService.java
+++ b/android/telecom/InCallService.java
@@ -60,6 +60,26 @@ import java.util.List;
* </service>
* }
* </pre>
+ * <p>
+ * In addition to implementing the {@link InCallService} API, you must also declare an activity in
+ * your manifest which handles the {@link Intent#ACTION_DIAL} intent. The example below illustrates
+ * how this is done:
+ * <pre>
+ * {@code
+ * <activity android:name="your.package.YourDialerActivity"
+ * android:label="@string/yourDialerActivityLabel">
+ * <intent-filter>
+ * <action android:name="android.intent.action.DIAL" />
+ * <category android:name="android.intent.category.DEFAULT" />
+ * </intent-filter>
+ * </activity>
+ * }
+ * </pre>
+ * <p>
+ * When a user installs your application and runs it for the first time, you should prompt the user
+ * to see if they would like your application to be the new default phone app. See the
+ * {@link TelecomManager#ACTION_CHANGE_DEFAULT_DIALER} intent documentation for more information on
+ * how to do this.
*/
public abstract class InCallService extends Service {
diff --git a/android/telecom/Logging/EventManager.java b/android/telecom/Logging/EventManager.java
index 4fc33853..2bda6480 100644
--- a/android/telecom/Logging/EventManager.java
+++ b/android/telecom/Logging/EventManager.java
@@ -24,21 +24,20 @@ import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Date;
import java.util.HashMap;
import java.util.IllegalFormatException;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.TimeZone;
import java.util.concurrent.LinkedBlockingQueue;
-import java.util.stream.Collectors;
/**
* A utility class that provides the ability to define Events that a subsystem deems important, and
@@ -53,7 +52,8 @@ public class EventManager {
public static final String TAG = "Logging.Events";
@VisibleForTesting
public static final int DEFAULT_EVENTS_TO_CACHE = 10; // Arbitrarily chosen.
- private final DateFormat sDateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
+ public static final DateTimeFormatter DATE_TIME_FORMATTER =
+ DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
public interface Loggable {
/**
@@ -131,11 +131,17 @@ public class EventManager {
public String sessionId;
public long time;
public Object data;
+ // String storing the date for display. This will be computed at the time/timezone when
+ // the event is recorded.
+ public final String timestampString;
public Event(String eventId, String sessionId, long time, Object data) {
this.eventId = eventId;
this.sessionId = sessionId;
this.time = time;
+ timestampString =
+ ZonedDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault())
+ .format(DATE_TIME_FORMATTER);
this.data = data;
}
}
@@ -228,7 +234,7 @@ public class EventManager {
pw.increaseIndent();
for (Event event : mEvents) {
- pw.print(sDateFormat.format(new Date(event.time)));
+ pw.print(event.timestampString);
pw.print(" - ");
pw.print(event.eventId);
if (event.data != null) {
@@ -269,7 +275,6 @@ public class EventManager {
public EventManager(@NonNull SessionManager.ISessionIdQueryHandler l) {
mSessionIdHandler = l;
- sDateFormat.setTimeZone(TimeZone.getDefault());
}
public void event(Loggable recordEntry, String event, Object data) {
@@ -329,15 +334,15 @@ public class EventManager {
}
}
- // Sort by event time.
- Comparator<Pair<Loggable, Event>> byEventTime = (e1, e2) -> {
- return Long.compare(e1.second.time, e2.second.time);
- };
+ // Sort by event time. This might result in out-of-order seeming events if the timezone
+ // changes somewhere in the middle.
+ Comparator<Pair<Loggable, Event>> byEventTime =
+ Comparator.comparingLong(e -> e.second.time);
events.sort(byEventTime);
pw.increaseIndent();
for (Pair<Loggable, Event> event : events) {
- pw.print(sDateFormat.format(new Date(event.second.time)));
+ pw.print(event.second.timestampString);
pw.print(",");
pw.print(event.first.getId());
pw.print(",");
diff --git a/android/telecom/PhoneAccount.java b/android/telecom/PhoneAccount.java
index fcfc5931..95eb14ad 100644
--- a/android/telecom/PhoneAccount.java
+++ b/android/telecom/PhoneAccount.java
@@ -134,6 +134,25 @@ public final class PhoneAccount implements Parcelable {
"android.telecom.extra.LOG_SELF_MANAGED_CALLS";
/**
+ * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+ * indicates whether calls for a {@link PhoneAccount} should generate a "call recording tone"
+ * when the user is recording audio on the device.
+ * <p>
+ * The call recording tone is played over the telephony audio stream so that the remote party
+ * has an audible indication that it is possible their call is being recorded using a call
+ * recording app on the device.
+ * <p>
+ * This extra only has an effect for calls placed via Telephony (e.g.
+ * {@link #CAPABILITY_SIM_SUBSCRIPTION}).
+ * <p>
+ * The call recording tone is a 1400 hz tone which repeats every 15 seconds while recording is
+ * in progress.
+ * @hide
+ */
+ public static final String EXTRA_PLAY_CALL_RECORDING_TONE =
+ "android.telecom.extra.PLAY_CALL_RECORDING_TONE";
+
+ /**
* Flag indicating that this {@code PhoneAccount} can act as a connection manager for
* other connections. The {@link ConnectionService} associated with this {@code PhoneAccount}
* will be allowed to manage phone calls including using its own proprietary phone-call
diff --git a/android/telecom/RemoteConnectionService.java b/android/telecom/RemoteConnectionService.java
index 59ce5908..bb4b483d 100644
--- a/android/telecom/RemoteConnectionService.java
+++ b/android/telecom/RemoteConnectionService.java
@@ -93,6 +93,10 @@ final class RemoteConnectionService {
// failure on the providing end, so immediately mark it destroyed
connection.setDestroyed();
}
+ connection.setStatusHints(parcel.getStatusHints());
+ connection.setIsVoipAudioMode(parcel.getIsVoipAudioMode());
+ connection.setRingbackRequested(parcel.isRingbackRequested());
+ connection.putExtras(parcel.getExtras());
}
}
diff --git a/android/telecom/TelecomManager.java b/android/telecom/TelecomManager.java
index 1fe5db5d..72c67d37 100644
--- a/android/telecom/TelecomManager.java
+++ b/android/telecom/TelecomManager.java
@@ -111,12 +111,6 @@ public class TelecomManager {
"android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS";
/**
- * The {@link android.content.Intent} action used to show the assisted dialing settings.
- */
- public static final String ACTION_SHOW_ASSISTED_DIALING_SETTINGS =
- "android.telecom.action.SHOW_ASSISTED_DIALING_SETTINGS";
-
- /**
* The {@link android.content.Intent} action used to show the settings page used to configure
* {@link PhoneAccount} preferences.
*/
@@ -619,17 +613,12 @@ public class TelecomManager {
/**
* The boolean indicated by this extra controls whether or not a call is eligible to undergo
* assisted dialing. This extra is stored under {@link #EXTRA_OUTGOING_CALL_EXTRAS}.
+ * @hide
*/
public static final String EXTRA_USE_ASSISTED_DIALING =
"android.telecom.extra.USE_ASSISTED_DIALING";
/**
- * The bundle indicated by this extra store information related to the assisted dialing action.
- */
- public static final String EXTRA_ASSISTED_DIALING_TRANSFORMATION_INFO =
- "android.telecom.extra.ASSISTED_DIALING_TRANSFORMATION_INFO";
-
- /**
* The following 4 constants define how properties such as phone numbers and names are
* displayed to the user.
*/
@@ -1320,7 +1309,7 @@ public class TelecomManager {
public boolean endCall() {
try {
if (isServiceConnected()) {
- return getTelecomService().endCall();
+ return getTelecomService().endCall(mContext.getPackageName());
}
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#endCall", e);
@@ -1805,8 +1794,25 @@ public class TelecomManager {
}
/**
- * Called from the recipient side of a handover to indicate a desire to accept the handover
- * of an ongoing call to another {@link ConnectionService} identified by
+ * Called by an app to indicate that it wishes to accept the handover of an ongoing call to a
+ * {@link PhoneAccountHandle} it defines.
+ * <p>
+ * A call handover is the process where an ongoing call is transferred from one app (i.e.
+ * {@link ConnectionService} to another app. The user could, for example, choose to continue a
+ * mobile network call in a video calling app. The mobile network call via the Telephony stack
+ * is referred to as the source of the handover, and the video calling app is referred to as the
+ * destination.
+ * <p>
+ * When considering a handover scenario the <em>initiating</em> device is where a user initiated
+ * the handover process (e.g. by calling {@link android.telecom.Call#handoverTo(
+ * PhoneAccountHandle, int, Bundle)}, and the other device is considered the <em>receiving</em>
+ * device.
+ * <p>
+ * For a full discussion of the handover process and the APIs involved, see
+ * {@link android.telecom.Call#handoverTo(PhoneAccountHandle, int, Bundle)}.
+ * <p>
+ * This method is called from the <em>receiving</em> side of a handover to indicate a desire to
+ * accept the handover of an ongoing call to another {@link ConnectionService} identified by
* {@link PhoneAccountHandle} destAcct. For managed {@link ConnectionService}s, the specified
* {@link PhoneAccountHandle} must have been registered with {@link #registerPhoneAccount} and
* the user must have enabled the corresponding {@link PhoneAccount}. This can be checked using
@@ -1830,7 +1836,8 @@ public class TelecomManager {
* @param videoState Video state after the handover.
* @param destAcct The {@link PhoneAccountHandle} registered to the calling package.
*/
- public void acceptHandover(Uri srcAddr, int videoState, PhoneAccountHandle destAcct) {
+ public void acceptHandover(Uri srcAddr, @VideoProfile.VideoState int videoState,
+ PhoneAccountHandle destAcct) {
try {
if (isServiceConnected()) {
getTelecomService().acceptHandover(srcAddr, videoState, destAcct);
diff --git a/android/telecom/TransformationInfo.java b/android/telecom/TransformationInfo.java
deleted file mode 100644
index 3e848c6f..00000000
--- a/android/telecom/TransformationInfo.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telecom;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * A container class to hold information related to the Assisted Dialing operation. All member
- * variables must be set when constructing a new instance of this class.
- */
-public final class TransformationInfo implements Parcelable {
- private String mOriginalNumber;
- private String mTransformedNumber;
- private String mUserHomeCountryCode;
- private String mUserRoamingCountryCode;
- private int mTransformedNumberCountryCallingCode;
-
- public TransformationInfo(String originalNumber,
- String transformedNumber,
- String userHomeCountryCode,
- String userRoamingCountryCode,
- int transformedNumberCountryCallingCode) {
- String missing = "";
- if (originalNumber == null) {
- missing += " mOriginalNumber";
- }
- if (transformedNumber == null) {
- missing += " mTransformedNumber";
- }
- if (userHomeCountryCode == null) {
- missing += " mUserHomeCountryCode";
- }
- if (userRoamingCountryCode == null) {
- missing += " mUserRoamingCountryCode";
- }
-
- if (!missing.isEmpty()) {
- throw new IllegalStateException("Missing required properties:" + missing);
- }
- this.mOriginalNumber = originalNumber;
- this.mTransformedNumber = transformedNumber;
- this.mUserHomeCountryCode = userHomeCountryCode;
- this.mUserRoamingCountryCode = userRoamingCountryCode;
- this.mTransformedNumberCountryCallingCode = transformedNumberCountryCallingCode;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(mOriginalNumber);
- out.writeString(mTransformedNumber);
- out.writeString(mUserHomeCountryCode);
- out.writeString(mUserRoamingCountryCode);
- out.writeInt(mTransformedNumberCountryCallingCode);
- }
-
- public static final Parcelable.Creator<TransformationInfo> CREATOR
- = new Parcelable.Creator<TransformationInfo>() {
- public TransformationInfo createFromParcel(Parcel in) {
- return new TransformationInfo(in);
- }
-
- public TransformationInfo[] newArray(int size) {
- return new TransformationInfo[size];
- }
- };
-
- private TransformationInfo(Parcel in) {
- mOriginalNumber = in.readString();
- mTransformedNumber = in.readString();
- mUserHomeCountryCode = in.readString();
- mUserRoamingCountryCode = in.readString();
- mTransformedNumberCountryCallingCode = in.readInt();
- }
-
- /**
- * The original number that underwent Assisted Dialing.
- */
- public String getOriginalNumber() {
- return mOriginalNumber;
- }
-
- /**
- * The number after it underwent Assisted Dialing.
- */
- public String getTransformedNumber() {
- return mTransformedNumber;
- }
-
- /**
- * The user's home country code that was used when attempting to transform the number.
- */
- public String getUserHomeCountryCode() {
- return mUserHomeCountryCode;
- }
-
- /**
- * The users's roaming country code that was used when attempting to transform the number.
- */
- public String getUserRoamingCountryCode() {
- return mUserRoamingCountryCode;
- }
-
- /**
- * The country calling code that was used in the transformation.
- */
- public int getTransformedNumberCountryCallingCode() {
- return mTransformedNumberCountryCallingCode;
- }
-}
diff --git a/android/telecom/VideoProfile.java b/android/telecom/VideoProfile.java
index e0e3a085..90ed36f1 100644
--- a/android/telecom/VideoProfile.java
+++ b/android/telecom/VideoProfile.java
@@ -62,6 +62,7 @@ public class VideoProfile implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
@IntDef(
flag = true,
+ prefix = { "STATE_" },
value = {STATE_AUDIO_ONLY, STATE_TX_ENABLED, STATE_RX_ENABLED, STATE_BIDIRECTIONAL,
STATE_PAUSED})
public @interface VideoState {}