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