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