diff options
author | Justin Klaassen <justinklaassen@google.com> | 2018-04-03 23:21:57 -0400 |
---|---|---|
committer | Justin Klaassen <justinklaassen@google.com> | 2018-04-03 23:21:57 -0400 |
commit | 4d01eeaffaa720e4458a118baa137a11614f00f7 (patch) | |
tree | 66751893566986236788e3c796a7cc5e90d05f52 /android/telecom | |
parent | a192cc2a132cb0ee8588e2df755563ec7008c179 (diff) | |
download | android-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.java | 185 | ||||
-rw-r--r-- | android/telecom/Conference.java | 33 | ||||
-rw-r--r-- | android/telecom/Connection.java | 116 | ||||
-rw-r--r-- | android/telecom/ConnectionRequest.java | 7 | ||||
-rw-r--r-- | android/telecom/ConnectionService.java | 135 | ||||
-rw-r--r-- | android/telecom/DisconnectCause.java | 27 | ||||
-rw-r--r-- | android/telecom/InCallAdapter.java | 14 | ||||
-rw-r--r-- | android/telecom/InCallService.java | 20 | ||||
-rw-r--r-- | android/telecom/Logging/EventManager.java | 31 | ||||
-rw-r--r-- | android/telecom/PhoneAccount.java | 19 | ||||
-rw-r--r-- | android/telecom/RemoteConnectionService.java | 4 | ||||
-rw-r--r-- | android/telecom/TelecomManager.java | 39 | ||||
-rw-r--r-- | android/telecom/TransformationInfo.java | 127 | ||||
-rw-r--r-- | android/telecom/VideoProfile.java | 1 |
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 {} |