1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telecom; 18 19 import android.net.Uri; 20 import android.os.Bundle; 21 import android.os.Parcel; 22 import android.os.ParcelFileDescriptor; 23 import android.os.Parcelable; 24 25 /** 26 * Simple data container encapsulating a request to some entity to 27 * create a new {@link Connection}. 28 */ 29 public final class ConnectionRequest implements Parcelable { 30 31 /** 32 * Builder class for {@link ConnectionRequest} 33 * @hide 34 */ 35 public static final class Builder { 36 private PhoneAccountHandle mAccountHandle; 37 private Uri mAddress; 38 private Bundle mExtras; 39 private int mVideoState = VideoProfile.STATE_AUDIO_ONLY; 40 private String mTelecomCallId; 41 private boolean mShouldShowIncomingCallUi = false; 42 private ParcelFileDescriptor mRttPipeToInCall; 43 private ParcelFileDescriptor mRttPipeFromInCall; 44 Builder()45 public Builder() { } 46 47 /** 48 * Sets the phone account handle for the resulting {@link ConnectionRequest} 49 * @param accountHandle The accountHandle which should be used to place the call. 50 */ setAccountHandle(PhoneAccountHandle accountHandle)51 public Builder setAccountHandle(PhoneAccountHandle accountHandle) { 52 this.mAccountHandle = accountHandle; 53 return this; 54 } 55 56 /** 57 * Sets the address for the resulting {@link ConnectionRequest} 58 * @param address The address(e.g., phone number) to which the {@link Connection} is to 59 * connect. 60 */ setAddress(Uri address)61 public Builder setAddress(Uri address) { 62 this.mAddress = address; 63 return this; 64 } 65 66 /** 67 * Sets the extras bundle for the resulting {@link ConnectionRequest} 68 * @param extras Application-specific extra data. 69 */ setExtras(Bundle extras)70 public Builder setExtras(Bundle extras) { 71 this.mExtras = extras; 72 return this; 73 } 74 75 /** 76 * Sets the video state for the resulting {@link ConnectionRequest} 77 * @param videoState Determines the video state for the connection. 78 */ setVideoState(int videoState)79 public Builder setVideoState(int videoState) { 80 this.mVideoState = videoState; 81 return this; 82 } 83 84 /** 85 * Sets the Telecom call ID for the resulting {@link ConnectionRequest} 86 * @param telecomCallId The telecom call ID. 87 */ setTelecomCallId(String telecomCallId)88 public Builder setTelecomCallId(String telecomCallId) { 89 this.mTelecomCallId = telecomCallId; 90 return this; 91 } 92 93 /** 94 * Sets shouldShowIncomingUi for the resulting {@link ConnectionRequest} 95 * @param shouldShowIncomingCallUi For a self-managed {@link ConnectionService}, will be 96 * {@code true} if the {@link ConnectionService} should show 97 * its own incoming call UI for an incoming call. When 98 * {@code false}, Telecom shows the incoming call UI. 99 */ setShouldShowIncomingCallUi(boolean shouldShowIncomingCallUi)100 public Builder setShouldShowIncomingCallUi(boolean shouldShowIncomingCallUi) { 101 this.mShouldShowIncomingCallUi = shouldShowIncomingCallUi; 102 return this; 103 } 104 105 /** 106 * Sets the RTT pipe for transferring text into the {@link ConnectionService} for the 107 * resulting {@link ConnectionRequest} 108 * @param rttPipeFromInCall The data pipe to read from. 109 */ setRttPipeFromInCall(ParcelFileDescriptor rttPipeFromInCall)110 public Builder setRttPipeFromInCall(ParcelFileDescriptor rttPipeFromInCall) { 111 this.mRttPipeFromInCall = rttPipeFromInCall; 112 return this; 113 } 114 115 /** 116 * Sets the RTT pipe for transferring text out of {@link ConnectionService} for the 117 * resulting {@link ConnectionRequest} 118 * @param rttPipeToInCall The data pipe to write to. 119 */ setRttPipeToInCall(ParcelFileDescriptor rttPipeToInCall)120 public Builder setRttPipeToInCall(ParcelFileDescriptor rttPipeToInCall) { 121 this.mRttPipeToInCall = rttPipeToInCall; 122 return this; 123 } 124 build()125 public ConnectionRequest build() { 126 return new ConnectionRequest( 127 mAccountHandle, 128 mAddress, 129 mExtras, 130 mVideoState, 131 mTelecomCallId, 132 mShouldShowIncomingCallUi, 133 mRttPipeFromInCall, 134 mRttPipeToInCall); 135 } 136 } 137 138 private final PhoneAccountHandle mAccountHandle; 139 private final Uri mAddress; 140 private final Bundle mExtras; 141 private final int mVideoState; 142 private final String mTelecomCallId; 143 private final boolean mShouldShowIncomingCallUi; 144 private final ParcelFileDescriptor mRttPipeToInCall; 145 private final ParcelFileDescriptor mRttPipeFromInCall; 146 // Cached return value of getRttTextStream -- we don't want to wrap it more than once. 147 private Connection.RttTextStream mRttTextStream; 148 149 /** 150 * @param accountHandle The accountHandle which should be used to place the call. 151 * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. 152 * @param extras Application-specific extra data. 153 */ ConnectionRequest( PhoneAccountHandle accountHandle, Uri handle, Bundle extras)154 public ConnectionRequest( 155 PhoneAccountHandle accountHandle, 156 Uri handle, 157 Bundle extras) { 158 this(accountHandle, handle, extras, VideoProfile.STATE_AUDIO_ONLY, null, false, null, null); 159 } 160 161 /** 162 * @param accountHandle The accountHandle which should be used to place the call. 163 * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. 164 * @param extras Application-specific extra data. 165 * @param videoState Determines the video state for the connection. 166 */ ConnectionRequest( PhoneAccountHandle accountHandle, Uri handle, Bundle extras, int videoState)167 public ConnectionRequest( 168 PhoneAccountHandle accountHandle, 169 Uri handle, 170 Bundle extras, 171 int videoState) { 172 this(accountHandle, handle, extras, videoState, null, false, null, null); 173 } 174 175 /** 176 * @param accountHandle The accountHandle which should be used to place the call. 177 * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. 178 * @param extras Application-specific extra data. 179 * @param videoState Determines the video state for the connection. 180 * @param telecomCallId The telecom call ID. 181 * @param shouldShowIncomingCallUi For a self-managed {@link ConnectionService}, will be 182 * {@code true} if the {@link ConnectionService} should show its 183 * own incoming call UI for an incoming call. When 184 * {@code false}, Telecom shows the incoming call UI. 185 * @hide 186 */ ConnectionRequest( PhoneAccountHandle accountHandle, Uri handle, Bundle extras, int videoState, String telecomCallId, boolean shouldShowIncomingCallUi)187 public ConnectionRequest( 188 PhoneAccountHandle accountHandle, 189 Uri handle, 190 Bundle extras, 191 int videoState, 192 String telecomCallId, 193 boolean shouldShowIncomingCallUi) { 194 this(accountHandle, handle, extras, videoState, telecomCallId, 195 shouldShowIncomingCallUi, null, null); 196 } 197 ConnectionRequest( PhoneAccountHandle accountHandle, Uri handle, Bundle extras, int videoState, String telecomCallId, boolean shouldShowIncomingCallUi, ParcelFileDescriptor rttPipeFromInCall, ParcelFileDescriptor rttPipeToInCall)198 private ConnectionRequest( 199 PhoneAccountHandle accountHandle, 200 Uri handle, 201 Bundle extras, 202 int videoState, 203 String telecomCallId, 204 boolean shouldShowIncomingCallUi, 205 ParcelFileDescriptor rttPipeFromInCall, 206 ParcelFileDescriptor rttPipeToInCall) { 207 mAccountHandle = accountHandle; 208 mAddress = handle; 209 mExtras = extras; 210 mVideoState = videoState; 211 mTelecomCallId = telecomCallId; 212 mShouldShowIncomingCallUi = shouldShowIncomingCallUi; 213 mRttPipeFromInCall = rttPipeFromInCall; 214 mRttPipeToInCall = rttPipeToInCall; 215 } 216 ConnectionRequest(Parcel in)217 private ConnectionRequest(Parcel in) { 218 mAccountHandle = in.readParcelable(getClass().getClassLoader()); 219 mAddress = in.readParcelable(getClass().getClassLoader()); 220 mExtras = in.readParcelable(getClass().getClassLoader()); 221 mVideoState = in.readInt(); 222 mTelecomCallId = in.readString(); 223 mShouldShowIncomingCallUi = in.readInt() == 1; 224 mRttPipeFromInCall = in.readParcelable(getClass().getClassLoader()); 225 mRttPipeToInCall = in.readParcelable(getClass().getClassLoader()); 226 } 227 228 /** 229 * The account which should be used to place the call. 230 */ getAccountHandle()231 public PhoneAccountHandle getAccountHandle() { return mAccountHandle; } 232 233 /** 234 * The handle (e.g., phone number) to which the {@link Connection} is to connect. 235 */ getAddress()236 public Uri getAddress() { return mAddress; } 237 238 /** 239 * Application-specific extra data. Used for passing back information from an incoming 240 * call {@code Intent}, and for any proprietary extensions arranged between a client 241 * and servant {@code ConnectionService} which agree on a vocabulary for such data. 242 */ getExtras()243 public Bundle getExtras() { return mExtras; } 244 245 /** 246 * Describes the video states supported by the client requesting the connection. 247 * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY}, 248 * {@link VideoProfile#STATE_BIDIRECTIONAL}, 249 * {@link VideoProfile#STATE_TX_ENABLED}, 250 * {@link VideoProfile#STATE_RX_ENABLED}. 251 * 252 * @return The video state for the connection. 253 */ getVideoState()254 public int getVideoState() { 255 return mVideoState; 256 } 257 258 /** 259 * Returns the internal Telecom ID associated with the connection request. 260 * 261 * @return The Telecom ID. 262 * @hide 263 */ getTelecomCallId()264 public String getTelecomCallId() { 265 return mTelecomCallId; 266 } 267 268 /** 269 * For a self-managed {@link ConnectionService}, indicates for an incoming call whether the 270 * {@link ConnectionService} should show its own incoming call UI for an incoming call. 271 * 272 * @return {@code true} if the {@link ConnectionService} should show its own incoming call UI. 273 * When {@code false}, Telecom shows the incoming call UI for the call. 274 * @hide 275 */ shouldShowIncomingCallUi()276 public boolean shouldShowIncomingCallUi() { 277 return mShouldShowIncomingCallUi; 278 } 279 280 /** 281 * Gets the {@link ParcelFileDescriptor} that is used to send RTT text from the connection 282 * service to the in-call UI. In order to obtain an 283 * {@link java.io.InputStream} from this {@link ParcelFileDescriptor}, use 284 * {@link android.os.ParcelFileDescriptor.AutoCloseInputStream}. 285 * Only text data encoded using UTF-8 should be written into this {@link ParcelFileDescriptor}. 286 * @return The {@link ParcelFileDescriptor} that should be used for communication. 287 * Do not un-hide -- only for use by Telephony 288 * @hide 289 */ getRttPipeToInCall()290 public ParcelFileDescriptor getRttPipeToInCall() { 291 return mRttPipeToInCall; 292 } 293 294 /** 295 * Gets the {@link ParcelFileDescriptor} that is used to send RTT text from the in-call UI to 296 * the connection service. In order to obtain an 297 * {@link java.io.OutputStream} from this {@link ParcelFileDescriptor}, use 298 * {@link android.os.ParcelFileDescriptor.AutoCloseOutputStream}. 299 * The contents of this {@link ParcelFileDescriptor} will consist solely of text encoded in 300 * UTF-8. 301 * @return The {@link ParcelFileDescriptor} that should be used for communication 302 * Do not un-hide -- only for use by Telephony 303 * @hide 304 */ getRttPipeFromInCall()305 public ParcelFileDescriptor getRttPipeFromInCall() { 306 return mRttPipeFromInCall; 307 } 308 309 /** 310 * Gets the {@link android.telecom.Connection.RttTextStream} object that should be used to 311 * send and receive RTT text to/from the in-call app. 312 * @return An instance of {@link android.telecom.Connection.RttTextStream}, or {@code null} 313 * if this connection request is not requesting an RTT session upon connection establishment. 314 */ getRttTextStream()315 public Connection.RttTextStream getRttTextStream() { 316 if (isRequestingRtt()) { 317 if (mRttTextStream == null) { 318 mRttTextStream = new Connection.RttTextStream(mRttPipeToInCall, mRttPipeFromInCall); 319 } 320 return mRttTextStream; 321 } else { 322 return null; 323 } 324 } 325 326 /** 327 * Convenience method for determining whether the ConnectionRequest is requesting an RTT session 328 * @return {@code true} if RTT is requested, {@code false} otherwise. 329 */ isRequestingRtt()330 public boolean isRequestingRtt() { 331 return mRttPipeFromInCall != null && mRttPipeToInCall != null; 332 } 333 334 @Override toString()335 public String toString() { 336 return String.format("ConnectionRequest %s %s", 337 mAddress == null 338 ? Uri.EMPTY 339 : Connection.toLogSafePhoneNumber(mAddress.toString()), 340 mExtras == null ? "" : mExtras); 341 } 342 343 public static final Creator<ConnectionRequest> CREATOR = new Creator<ConnectionRequest> () { 344 @Override 345 public ConnectionRequest createFromParcel(Parcel source) { 346 return new ConnectionRequest(source); 347 } 348 349 @Override 350 public ConnectionRequest[] newArray(int size) { 351 return new ConnectionRequest[size]; 352 } 353 }; 354 355 /** 356 * {@inheritDoc} 357 */ 358 @Override describeContents()359 public int describeContents() { 360 return 0; 361 } 362 363 @Override writeToParcel(Parcel destination, int flags)364 public void writeToParcel(Parcel destination, int flags) { 365 destination.writeParcelable(mAccountHandle, 0); 366 destination.writeParcelable(mAddress, 0); 367 destination.writeParcelable(mExtras, 0); 368 destination.writeInt(mVideoState); 369 destination.writeString(mTelecomCallId); 370 destination.writeInt(mShouldShowIncomingCallUi ? 1 : 0); 371 destination.writeParcelable(mRttPipeFromInCall, 0); 372 destination.writeParcelable(mRttPipeToInCall, 0); 373 } 374 } 375