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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 120 public Builder setRttPipeToInCall(ParcelFileDescriptor rttPipeToInCall) { 121 this.mRttPipeToInCall = rttPipeToInCall; 122 return this; 123 } 124 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 */ 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 */ 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 */ 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 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 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 */ 231 public PhoneAccountHandle getAccountHandle() { return mAccountHandle; } 232 233 /** 234 * The handle (e.g., phone number) to which the {@link Connection} is to connect. 235 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 330 public boolean isRequestingRtt() { 331 return mRttPipeFromInCall != null && mRttPipeToInCall != null; 332 } 333 334 @Override 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 359 public int describeContents() { 360 return 0; 361 } 362 363 @Override 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