| /* | |
| * Copyright (C) 2014 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.annotation.NonNull; | |
| import android.annotation.Nullable; | |
| import android.annotation.SuppressLint; | |
| import android.annotation.SystemApi; | |
| import android.annotation.TestApi; | |
| import android.net.Uri; | |
| import android.os.Bundle; | |
| import android.os.Parcel; | |
| import android.os.ParcelFileDescriptor; | |
| import android.os.Parcelable; | |
| import java.util.ArrayList; | |
| import java.util.List; | |
| /** | |
| * Simple data container encapsulating a request to some entity to | |
| * create a new {@link Connection}. | |
| */ | |
| public final class ConnectionRequest implements Parcelable { | |
| /** | |
| * Builder class for {@link ConnectionRequest} | |
| * @hide | |
| */ | |
| @TestApi // For convenience in CTS tests | |
| public static final class Builder { | |
| private PhoneAccountHandle mAccountHandle; | |
| private Uri mAddress; | |
| private Bundle mExtras; | |
| private int mVideoState = VideoProfile.STATE_AUDIO_ONLY; | |
| private String mTelecomCallId; | |
| private boolean mShouldShowIncomingCallUi = false; | |
| private ParcelFileDescriptor mRttPipeToInCall; | |
| private ParcelFileDescriptor mRttPipeFromInCall; | |
| private List<Uri> mParticipants; | |
| private boolean mIsAdhocConference = false; | |
| public Builder() { } | |
| /** | |
| * Sets the phone account handle for the resulting {@link ConnectionRequest} | |
| * @param accountHandle The accountHandle which should be used to place the call. | |
| */ | |
| public @NonNull Builder setAccountHandle(@NonNull PhoneAccountHandle accountHandle) { | |
| this.mAccountHandle = accountHandle; | |
| return this; | |
| } | |
| /** | |
| * Sets the participants for the resulting {@link ConnectionRequest} | |
| * @param participants The participants to which the {@link Connection} is to connect. | |
| */ | |
| public @NonNull Builder setParticipants( | |
| @SuppressLint("NullableCollection") @Nullable List<Uri> participants) { | |
| this.mParticipants = participants; | |
| return this; | |
| } | |
| /** | |
| * Sets the address for the resulting {@link ConnectionRequest} | |
| * @param address The address(e.g., phone number) to which the {@link Connection} is to | |
| * connect. | |
| */ | |
| public @NonNull Builder setAddress(@NonNull Uri address) { | |
| this.mAddress = address; | |
| return this; | |
| } | |
| /** | |
| * Sets the extras bundle for the resulting {@link ConnectionRequest} | |
| * @param extras Application-specific extra data. | |
| */ | |
| public @NonNull Builder setExtras(@NonNull Bundle extras) { | |
| this.mExtras = extras; | |
| return this; | |
| } | |
| /** | |
| * Sets the video state for the resulting {@link ConnectionRequest} | |
| * @param videoState Determines the video state for the connection. | |
| */ | |
| public @NonNull Builder setVideoState(int videoState) { | |
| this.mVideoState = videoState; | |
| return this; | |
| } | |
| /** | |
| * Sets the Telecom call ID for the resulting {@link ConnectionRequest} | |
| * @param telecomCallId The telecom call ID. | |
| */ | |
| public @NonNull Builder setTelecomCallId(@NonNull String telecomCallId) { | |
| this.mTelecomCallId = telecomCallId; | |
| return this; | |
| } | |
| /** | |
| * Sets shouldShowIncomingUi for the resulting {@link ConnectionRequest} | |
| * @param shouldShowIncomingCallUi For a self-managed {@link ConnectionService}, will be | |
| * {@code true} if the {@link ConnectionService} should show | |
| * its own incoming call UI for an incoming call. When | |
| * {@code false}, Telecom shows the incoming call UI. | |
| */ | |
| public @NonNull Builder setShouldShowIncomingCallUi(boolean shouldShowIncomingCallUi) { | |
| this.mShouldShowIncomingCallUi = shouldShowIncomingCallUi; | |
| return this; | |
| } | |
| /** | |
| * Sets isAdhocConference for the resulting {@link ConnectionRequest} | |
| * @param isAdhocConference {@code true} if it is a adhoc conference call | |
| * {@code false}, if not a adhoc conference call | |
| */ | |
| public @NonNull Builder setIsAdhocConferenceCall(boolean isAdhocConference) { | |
| this.mIsAdhocConference = isAdhocConference; | |
| return this; | |
| } | |
| /** | |
| * Sets the RTT pipe for transferring text into the {@link ConnectionService} for the | |
| * resulting {@link ConnectionRequest} | |
| * @param rttPipeFromInCall The data pipe to read from. | |
| */ | |
| public @NonNull Builder setRttPipeFromInCall( | |
| @NonNull ParcelFileDescriptor rttPipeFromInCall) { | |
| this.mRttPipeFromInCall = rttPipeFromInCall; | |
| return this; | |
| } | |
| /** | |
| * Sets the RTT pipe for transferring text out of {@link ConnectionService} for the | |
| * resulting {@link ConnectionRequest} | |
| * @param rttPipeToInCall The data pipe to write to. | |
| */ | |
| public @NonNull Builder setRttPipeToInCall(@NonNull ParcelFileDescriptor rttPipeToInCall) { | |
| this.mRttPipeToInCall = rttPipeToInCall; | |
| return this; | |
| } | |
| /** | |
| * Build the {@link ConnectionRequest} | |
| * @return Result of the builder | |
| */ | |
| public @NonNull ConnectionRequest build() { | |
| return new ConnectionRequest( | |
| mAccountHandle, | |
| mAddress, | |
| mExtras, | |
| mVideoState, | |
| mTelecomCallId, | |
| mShouldShowIncomingCallUi, | |
| mRttPipeFromInCall, | |
| mRttPipeToInCall, | |
| mParticipants, | |
| mIsAdhocConference); | |
| } | |
| } | |
| private final PhoneAccountHandle mAccountHandle; | |
| private final Uri mAddress; | |
| private final Bundle mExtras; | |
| private final int mVideoState; | |
| private final String mTelecomCallId; | |
| 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; | |
| private List<Uri> mParticipants; | |
| private final boolean mIsAdhocConference; | |
| /** | |
| * @param accountHandle The accountHandle which should be used to place the call. | |
| * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. | |
| * @param extras Application-specific extra data. | |
| */ | |
| public ConnectionRequest( | |
| PhoneAccountHandle accountHandle, | |
| Uri handle, | |
| Bundle extras) { | |
| this(accountHandle, handle, extras, VideoProfile.STATE_AUDIO_ONLY, null, false, null, null); | |
| } | |
| /** | |
| * @param accountHandle The accountHandle which should be used to place the call. | |
| * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. | |
| * @param extras Application-specific extra data. | |
| * @param videoState Determines the video state for the connection. | |
| */ | |
| public ConnectionRequest( | |
| PhoneAccountHandle accountHandle, | |
| Uri handle, | |
| Bundle extras, | |
| int videoState) { | |
| this(accountHandle, handle, extras, videoState, null, false, null, null); | |
| } | |
| /** | |
| * @param accountHandle The accountHandle which should be used to place the call. | |
| * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. | |
| * @param extras Application-specific extra data. | |
| * @param videoState Determines the video state for the connection. | |
| * @param telecomCallId The telecom call ID. | |
| * @param shouldShowIncomingCallUi For a self-managed {@link ConnectionService}, will be | |
| * {@code true} if the {@link ConnectionService} should show its | |
| * own incoming call UI for an incoming call. When | |
| * {@code false}, Telecom shows the incoming call UI. | |
| * @hide | |
| */ | |
| public ConnectionRequest( | |
| PhoneAccountHandle accountHandle, | |
| Uri handle, | |
| Bundle extras, | |
| int videoState, | |
| String telecomCallId, | |
| boolean shouldShowIncomingCallUi) { | |
| this(accountHandle, handle, extras, videoState, telecomCallId, | |
| shouldShowIncomingCallUi, null, null); | |
| } | |
| private ConnectionRequest( | |
| PhoneAccountHandle accountHandle, | |
| Uri handle, | |
| Bundle extras, | |
| int videoState, | |
| String telecomCallId, | |
| boolean shouldShowIncomingCallUi, | |
| ParcelFileDescriptor rttPipeFromInCall, | |
| ParcelFileDescriptor rttPipeToInCall) { | |
| this(accountHandle, handle, extras, videoState, telecomCallId, | |
| shouldShowIncomingCallUi, rttPipeFromInCall, rttPipeToInCall, null, false); | |
| } | |
| private ConnectionRequest( | |
| PhoneAccountHandle accountHandle, | |
| Uri handle, | |
| Bundle extras, | |
| int videoState, | |
| String telecomCallId, | |
| boolean shouldShowIncomingCallUi, | |
| ParcelFileDescriptor rttPipeFromInCall, | |
| ParcelFileDescriptor rttPipeToInCall, | |
| List<Uri> participants, | |
| boolean isAdhocConference) { | |
| mAccountHandle = accountHandle; | |
| mAddress = handle; | |
| mExtras = extras; | |
| mVideoState = videoState; | |
| mTelecomCallId = telecomCallId; | |
| mShouldShowIncomingCallUi = shouldShowIncomingCallUi; | |
| mRttPipeFromInCall = rttPipeFromInCall; | |
| mRttPipeToInCall = rttPipeToInCall; | |
| mParticipants = participants; | |
| mIsAdhocConference = isAdhocConference; | |
| } | |
| private ConnectionRequest(Parcel in) { | |
| mAccountHandle = in.readParcelable(getClass().getClassLoader(), android.telecom.PhoneAccountHandle.class); | |
| mAddress = in.readParcelable(getClass().getClassLoader(), android.net.Uri.class); | |
| mExtras = in.readParcelable(getClass().getClassLoader(), android.os.Bundle.class); | |
| mVideoState = in.readInt(); | |
| mTelecomCallId = in.readString(); | |
| mShouldShowIncomingCallUi = in.readInt() == 1; | |
| mRttPipeFromInCall = in.readParcelable(getClass().getClassLoader(), android.os.ParcelFileDescriptor.class); | |
| mRttPipeToInCall = in.readParcelable(getClass().getClassLoader(), android.os.ParcelFileDescriptor.class); | |
| mParticipants = new ArrayList<Uri>(); | |
| in.readList(mParticipants, getClass().getClassLoader(), android.net.Uri.class); | |
| mIsAdhocConference = in.readInt() == 1; | |
| } | |
| /** | |
| * The account which should be used to place the call. | |
| */ | |
| public PhoneAccountHandle getAccountHandle() { return mAccountHandle; } | |
| /** | |
| * The handle (e.g., phone number) to which the {@link Connection} is to connect. | |
| */ | |
| public Uri getAddress() { return mAddress; } | |
| /** | |
| * The participants to which the {@link Connection} is to connect. | |
| */ | |
| public @Nullable List<Uri> getParticipants() { return mParticipants; } | |
| /** | |
| * Application-specific extra data. Used for passing back information from an incoming | |
| * call {@code Intent}, and for any proprietary extensions arranged between a client | |
| * and servant {@code ConnectionService} which agree on a vocabulary for such data. | |
| */ | |
| public Bundle getExtras() { return mExtras; } | |
| /** | |
| * Describes the video states supported by the client requesting the connection. | |
| * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY}, | |
| * {@link VideoProfile#STATE_BIDIRECTIONAL}, | |
| * {@link VideoProfile#STATE_TX_ENABLED}, | |
| * {@link VideoProfile#STATE_RX_ENABLED}. | |
| * | |
| * @return The video state for the connection. | |
| */ | |
| public int getVideoState() { | |
| return mVideoState; | |
| } | |
| /** | |
| * Returns the internal Telecom ID associated with the connection request. | |
| * | |
| * @return The Telecom ID. | |
| * @hide | |
| */ | |
| @SystemApi | |
| public @Nullable String getTelecomCallId() { | |
| return mTelecomCallId; | |
| } | |
| /** | |
| * For a self-managed {@link ConnectionService}, indicates for an incoming call whether the | |
| * {@link ConnectionService} should show its own incoming call UI for an incoming call. | |
| * | |
| * @return {@code true} if the {@link ConnectionService} should show its own incoming call UI. | |
| * When {@code false}, Telecom shows the incoming call UI for the call. | |
| * @hide | |
| */ | |
| public boolean shouldShowIncomingCallUi() { | |
| return mShouldShowIncomingCallUi; | |
| } | |
| /** | |
| * @return {@code true} if the call is a adhoc conference call else @return {@code false} | |
| */ | |
| public boolean isAdhocConferenceCall() { | |
| return mIsAdhocConference; | |
| } | |
| /** | |
| * Gets the {@link ParcelFileDescriptor} that is used to send RTT text from the connection | |
| * service to the in-call UI. In order to obtain an | |
| * {@link java.io.InputStream} from this {@link ParcelFileDescriptor}, use | |
| * {@link android.os.ParcelFileDescriptor.AutoCloseInputStream}. | |
| * Only text data encoded using UTF-8 should be written into this {@link ParcelFileDescriptor}. | |
| * @return The {@link ParcelFileDescriptor} that should be used for communication. | |
| * Do not un-hide -- only for use by Telephony | |
| * @hide | |
| */ | |
| public ParcelFileDescriptor getRttPipeToInCall() { | |
| return mRttPipeToInCall; | |
| } | |
| /** | |
| * Gets the {@link ParcelFileDescriptor} that is used to send RTT text from the in-call UI to | |
| * the connection service. In order to obtain an | |
| * {@link java.io.OutputStream} from this {@link ParcelFileDescriptor}, use | |
| * {@link android.os.ParcelFileDescriptor.AutoCloseOutputStream}. | |
| * The contents of this {@link ParcelFileDescriptor} will consist solely of text encoded in | |
| * UTF-8. | |
| * @return The {@link ParcelFileDescriptor} that should be used for communication | |
| * Do not un-hide -- only for use by Telephony | |
| * @hide | |
| */ | |
| public ParcelFileDescriptor getRttPipeFromInCall() { | |
| return mRttPipeFromInCall; | |
| } | |
| /** | |
| * Gets the {@link android.telecom.Connection.RttTextStream} object that should be used to | |
| * send and receive RTT text to/from the in-call app. | |
| * @return An instance of {@link android.telecom.Connection.RttTextStream}, or {@code null} | |
| * if this connection request is not requesting an RTT session upon connection establishment. | |
| */ | |
| public Connection.RttTextStream getRttTextStream() { | |
| if (isRequestingRtt()) { | |
| if (mRttTextStream == null) { | |
| mRttTextStream = new Connection.RttTextStream(mRttPipeToInCall, mRttPipeFromInCall); | |
| } | |
| return mRttTextStream; | |
| } else { | |
| return null; | |
| } | |
| } | |
| /** | |
| * Convenience method for determining whether the ConnectionRequest is requesting an RTT session | |
| * @return {@code true} if RTT is requested, {@code false} otherwise. | |
| */ | |
| public boolean isRequestingRtt() { | |
| return mRttPipeFromInCall != null && mRttPipeToInCall != null; | |
| } | |
| @Override | |
| public String toString() { | |
| return String.format("ConnectionRequest %s %s isAdhocConf: %s", | |
| mAddress == null | |
| ? Uri.EMPTY | |
| : Connection.toLogSafePhoneNumber(mAddress.toString()), | |
| bundleToString(mExtras), | |
| isAdhocConferenceCall() ? "Y" : "N"); | |
| } | |
| private static String bundleToString(Bundle extras){ | |
| if (extras == null) { | |
| return ""; | |
| } | |
| StringBuilder sb = new StringBuilder(); | |
| sb.append("Bundle["); | |
| for (String key : extras.keySet()) { | |
| sb.append(key); | |
| sb.append("="); | |
| switch (key) { | |
| case TelecomManager.EXTRA_INCOMING_CALL_ADDRESS: | |
| case TelecomManager.EXTRA_UNKNOWN_CALL_HANDLE: | |
| sb.append(Log.pii(extras.get(key))); | |
| break; | |
| default: | |
| sb.append(extras.get(key)); | |
| break; | |
| } | |
| sb.append(", "); | |
| } | |
| sb.append("]"); | |
| return sb.toString(); | |
| } | |
| public static final @android.annotation.NonNull Creator<ConnectionRequest> CREATOR = new Creator<ConnectionRequest> () { | |
| @Override | |
| public ConnectionRequest createFromParcel(Parcel source) { | |
| return new ConnectionRequest(source); | |
| } | |
| @Override | |
| public ConnectionRequest[] newArray(int size) { | |
| return new ConnectionRequest[size]; | |
| } | |
| }; | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| @Override | |
| public int describeContents() { | |
| return 0; | |
| } | |
| @Override | |
| public void writeToParcel(Parcel destination, int flags) { | |
| destination.writeParcelable(mAccountHandle, 0); | |
| destination.writeParcelable(mAddress, 0); | |
| destination.writeParcelable(mExtras, 0); | |
| destination.writeInt(mVideoState); | |
| destination.writeString(mTelecomCallId); | |
| destination.writeInt(mShouldShowIncomingCallUi ? 1 : 0); | |
| destination.writeParcelable(mRttPipeFromInCall, 0); | |
| destination.writeParcelable(mRttPipeToInCall, 0); | |
| destination.writeList(mParticipants); | |
| destination.writeInt(mIsAdhocConference ? 1 : 0); | |
| } | |
| } |