blob: b1a7d819cd1771fdb659876b0690de6eb8e168e1 [file] [log] [blame]
Thomas Stuart9bfb2432022-09-27 15:02:07 -07001/*
2 * Copyright (C) 2022 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
17package android.telecom;
18
19import android.annotation.IntDef;
20import android.annotation.NonNull;
21import android.annotation.Nullable;
22import android.net.Uri;
23import android.os.Parcel;
24import android.os.Parcelable;
25import android.text.TextUtils;
26
27import java.util.Objects;
28
29/**
30 * CallAttributes represents a set of properties that define a new Call. Apps should build an
31 * instance of this class and use {@link TelecomManager#addCall} to start a new call with Telecom.
32 *
33 * <p>
34 * Apps should first register a {@link PhoneAccount} via {@link TelecomManager#registerPhoneAccount}
35 * and use the same {@link PhoneAccountHandle} registered with Telecom when creating an
36 * instance of CallAttributes.
37 */
38public final class CallAttributes implements Parcelable {
39
40 /** PhoneAccountHandle associated with the App managing calls **/
41 private final PhoneAccountHandle mPhoneAccountHandle;
42
43 /** Display name of the person on the other end of the call **/
44 private final CharSequence mDisplayName;
45
46 /** Address of the call. Note, this can be extended to a meeting link **/
47 private final Uri mAddress;
48
49 /** The direction (Outgoing/Incoming) of the new Call **/
50 @Direction private final int mDirection;
51
52 /** Information related to data being transmitted (voice, video, etc. ) **/
53 @CallType private final int mCallType;
54
55 /** Allows a package to opt into capabilities on the telecom side, on a per-call basis **/
56 @CallCapability private final int mCallCapabilities;
57
58 /** @hide **/
59 public static final String CALL_CAPABILITIES_KEY = "TelecomCapabilities";
60
Grace Jia13284d12022-12-01 14:02:17 -080061 /** @hide **/
Tyler Gunn545b5d82023-05-08 00:08:33 +000062 public static final String DISPLAY_NAME_KEY = "DisplayName";
63
64 /** @hide **/
Thomas Stuartf959db02023-04-05 16:59:01 -070065 public static final String CALLER_PID_KEY = "CallerPid";
66
67 /** @hide **/
68 public static final String CALLER_UID_KEY = "CallerUid";
Grace Jia13284d12022-12-01 14:02:17 -080069
Thomas Stuart9bfb2432022-09-27 15:02:07 -070070 private CallAttributes(@NonNull PhoneAccountHandle phoneAccountHandle,
71 @NonNull CharSequence displayName,
72 @NonNull Uri address,
73 int direction,
74 int callType,
75 int callCapabilities) {
76 mPhoneAccountHandle = phoneAccountHandle;
77 mDisplayName = displayName;
78 mAddress = address;
79 mDirection = direction;
80 mCallType = callType;
81 mCallCapabilities = callCapabilities;
82 }
83
84 /** @hide */
85 @IntDef(value = {DIRECTION_INCOMING, DIRECTION_OUTGOING})
86 public @interface Direction {
87 }
88 /**
89 * Indicates that the call is an incoming call.
90 */
91 public static final int DIRECTION_INCOMING = 1;
92 /**
93 * Indicates that the call is an outgoing call.
94 */
95 public static final int DIRECTION_OUTGOING = 2;
96
97 /** @hide */
98 @IntDef(value = {AUDIO_CALL, VIDEO_CALL})
99 public @interface CallType {
100 }
101 /**
102 * Used when answering or dialing a call to indicate that the call does not have a video
103 * component
104 */
105 public static final int AUDIO_CALL = 1;
106 /**
107 * Indicates video transmission is supported
108 */
109 public static final int VIDEO_CALL = 2;
110
111 /** @hide */
112 @IntDef(value = {SUPPORTS_SET_INACTIVE, SUPPORTS_STREAM, SUPPORTS_TRANSFER}, flag = true)
113 public @interface CallCapability {
114 }
115 /**
116 * The call being created can be set to inactive (traditionally referred to as hold). This
117 * means that once a new call goes active, if the active call needs to be held in order to
118 * place or receive an incoming call, the active call will be placed on hold. otherwise, the
119 * active call may be disconnected.
120 */
121 public static final int SUPPORTS_SET_INACTIVE = 1 << 1;
122 /**
123 * The call can be streamed from a root device to another device to continue the call without
124 * completely transferring it.
125 */
126 public static final int SUPPORTS_STREAM = 1 << 2;
127 /**
Tyler Gunn10d15032023-02-07 10:13:25 -0800128 * The call can be completely transferred from one endpoint to another.
Thomas Stuart9bfb2432022-09-27 15:02:07 -0700129 */
130 public static final int SUPPORTS_TRANSFER = 1 << 3;
131
132 /**
133 * Build an instance of {@link CallAttributes}. In order to build a valid instance, a
Tyler Gunn10d15032023-02-07 10:13:25 -0800134 * {@link PhoneAccountHandle}, call direction, display name, and {@link Uri} address
Thomas Stuart9bfb2432022-09-27 15:02:07 -0700135 * are required.
136 *
137 * <p>
138 * Note: Pass in the same {@link PhoneAccountHandle} that was used to register a
139 * {@link PhoneAccount} with Telecom. see {@link TelecomManager#registerPhoneAccount}
140 */
141 public static final class Builder {
142 // required and final fields
143 private final PhoneAccountHandle mPhoneAccountHandle;
144 @Direction private final int mDirection;
145 private final CharSequence mDisplayName;
146 private final Uri mAddress;
147 // optional fields
148 @CallType private int mCallType = CallAttributes.AUDIO_CALL;
149 @CallCapability private int mCallCapabilities = SUPPORTS_SET_INACTIVE;
150
151 /**
152 * Constructor for the CallAttributes.Builder class
153 *
154 * @param phoneAccountHandle that belongs to package registered with Telecom
155 * @param callDirection of the new call that will be added to Telecom
156 * @param displayName of the caller for incoming calls or initiating user for outgoing calls
157 * @param address of the caller for incoming calls or destination for outgoing calls
158 */
159 public Builder(@NonNull PhoneAccountHandle phoneAccountHandle,
160 @Direction int callDirection, @NonNull CharSequence displayName,
161 @NonNull Uri address) {
162 if (!isInRange(DIRECTION_INCOMING, DIRECTION_OUTGOING, callDirection)) {
163 throw new IllegalArgumentException(TextUtils.formatSimple("CallDirection=[%d] is"
164 + " invalid. CallDirections value should be within [%d, %d]",
165 callDirection, DIRECTION_INCOMING, DIRECTION_OUTGOING));
166 }
167 Objects.requireNonNull(phoneAccountHandle);
168 Objects.requireNonNull(displayName);
169 Objects.requireNonNull(address);
170 mPhoneAccountHandle = phoneAccountHandle;
171 mDirection = callDirection;
172 mDisplayName = displayName;
173 mAddress = address;
174 }
175
176 /**
Tyler Gunn10d15032023-02-07 10:13:25 -0800177 * Sets the type of call; uses to indicate if a call is a video call or audio call.
178 * @param callType The call type.
Thomas Stuart9bfb2432022-09-27 15:02:07 -0700179 * @return Builder
180 */
181 @NonNull
182 public Builder setCallType(@CallType int callType) {
183 if (!isInRange(AUDIO_CALL, VIDEO_CALL, callType)) {
184 throw new IllegalArgumentException(TextUtils.formatSimple("CallType=[%d] is"
185 + " invalid. CallTypes value should be within [%d, %d]",
186 callType, AUDIO_CALL, VIDEO_CALL));
187 }
188 mCallType = callType;
189 return this;
190 }
191
192 /**
Tyler Gunn10d15032023-02-07 10:13:25 -0800193 * Sets the capabilities of this call. Use this to indicate whether your app supports
194 * holding, streaming and call transfers.
195 * @param callCapabilities Bitmask of call capabilities.
Thomas Stuart9bfb2432022-09-27 15:02:07 -0700196 * @return Builder
197 */
198 @NonNull
199 public Builder setCallCapabilities(@CallCapability int callCapabilities) {
200 mCallCapabilities = callCapabilities;
201 return this;
202 }
203
204 /**
205 * Build an instance of {@link CallAttributes} based on the last values passed to the
206 * setters or default values.
207 *
208 * @return an instance of {@link CallAttributes}
209 */
210 @NonNull
211 public CallAttributes build() {
212 return new CallAttributes(mPhoneAccountHandle, mDisplayName, mAddress, mDirection,
213 mCallType, mCallCapabilities);
214 }
215
216 /** @hide */
217 private boolean isInRange(int floor, int ceiling, int value) {
218 return value >= floor && value <= ceiling;
219 }
220 }
221
222 /**
223 * The {@link PhoneAccountHandle} that should be registered to Telecom to allow calls. The
224 * {@link PhoneAccountHandle} should be registered before creating a CallAttributes instance.
225 *
226 * @return the {@link PhoneAccountHandle} for this package that allows this call to be created
227 */
228 @NonNull public PhoneAccountHandle getPhoneAccountHandle() {
229 return mPhoneAccountHandle;
230 }
231
232 /**
233 * @return display name of the incoming caller or the person being called for an outgoing call
234 */
235 @NonNull public CharSequence getDisplayName() {
236 return mDisplayName;
237 }
238
239 /**
240 * @return address of the incoming caller
241 * or the address of the person being called for an outgoing call
242 */
243 @NonNull public Uri getAddress() {
244 return mAddress;
245 }
246
247 /**
248 * @return the direction of the new call.
249 */
250 public @Direction int getDirection() {
251 return mDirection;
252 }
253
254 /**
255 * @return Information related to data being transmitted (voice, video, etc. )
256 */
257 public @CallType int getCallType() {
258 return mCallType;
259 }
260
261 /**
262 * @return The allowed capabilities of the new call
263 */
264 public @CallCapability int getCallCapabilities() {
265 return mCallCapabilities;
266 }
267
268 @Override
269 public int describeContents() {
270 return 0;
271 }
272
273 @Override
274 public void writeToParcel(@Nullable Parcel dest, int flags) {
275 dest.writeParcelable(mPhoneAccountHandle, flags);
276 dest.writeCharSequence(mDisplayName);
277 dest.writeParcelable(mAddress, flags);
278 dest.writeInt(mDirection);
279 dest.writeInt(mCallType);
280 dest.writeInt(mCallCapabilities);
281 }
282
283 /**
284 * Responsible for creating CallAttribute objects for deserialized Parcels.
285 */
286 public static final @android.annotation.NonNull
287 Parcelable.Creator<CallAttributes> CREATOR =
288 new Parcelable.Creator<>() {
289 @Override
290 public CallAttributes createFromParcel(Parcel source) {
291 return new CallAttributes(source.readParcelable(getClass().getClassLoader(),
292 android.telecom.PhoneAccountHandle.class),
293 source.readCharSequence(),
294 source.readParcelable(getClass().getClassLoader(),
295 android.net.Uri.class),
296 source.readInt(),
297 source.readInt(),
298 source.readInt());
299 }
300
301 @Override
302 public CallAttributes[] newArray(int size) {
303 return new CallAttributes[size];
304 }
305 };
306
307 /**
308 * {@inheritDoc}
309 */
310 @Override
311 public String toString() {
312 StringBuilder sb = new StringBuilder();
313
314 sb.append("{ CallAttributes: [phoneAccountHandle: ")
315 .append(mPhoneAccountHandle) /* PhoneAccountHandle#toString handles PII */
316 .append("], [contactName: ")
317 .append(Log.pii(mDisplayName))
318 .append("], [address=")
319 .append(Log.pii(mAddress))
320 .append("], [direction=")
321 .append(mDirection)
322 .append("], [callType=")
323 .append(mCallType)
324 .append("], [mCallCapabilities=")
325 .append(mCallCapabilities)
326 .append("] }");
327
328 return sb.toString();
329 }
330
331 /**
332 * {@inheritDoc}
333 */
334 @Override
335 public boolean equals(Object obj) {
336 if (obj == null || obj.getClass() != this.getClass()) {
337 return false;
338 }
339 CallAttributes that = (CallAttributes) obj;
340 return this.mDirection == that.mDirection
341 && this.mCallType == that.mCallType
342 && this.mCallCapabilities == that.mCallCapabilities
343 && Objects.equals(this.mPhoneAccountHandle, that.mPhoneAccountHandle)
344 && Objects.equals(this.mAddress, that.mAddress)
345 && Objects.equals(this.mDisplayName, that.mDisplayName);
346 }
347
348 /**
349 * {@inheritDoc}
350 */
351 @Override
352 public int hashCode() {
353 return Objects.hash(mPhoneAccountHandle, mAddress, mDisplayName,
354 mDirection, mCallType, mCallCapabilities);
355 }
356}