blob: a557cafd309a350b9e89bde554da59aeb9f020bb [file] [log] [blame]
Junhoedf3d822022-11-24 09:26:37 +00001/*
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.os.Parcel;
22import android.os.ParcelUuid;
23import android.os.Parcelable;
24import android.text.TextUtils;
25
26import java.lang.annotation.Retention;
27import java.lang.annotation.RetentionPolicy;
28import java.util.Objects;
29import java.util.UUID;
30
31/**
32 * Encapsulates the endpoint where call media can flow
33 */
34public final class CallEndpoint implements Parcelable {
35 /** @hide */
36 public static final int ENDPOINT_OPERATION_SUCCESS = 0;
37 /** @hide */
38 public static final int ENDPOINT_OPERATION_FAILED = 1;
39
40 /** @hide */
41 @Retention(RetentionPolicy.SOURCE)
42 @IntDef({TYPE_UNKNOWN, TYPE_EARPIECE, TYPE_BLUETOOTH, TYPE_WIRED_HEADSET, TYPE_SPEAKER,
43 TYPE_STREAMING})
44 public @interface EndpointType {}
45
46 /** Indicates that the type of endpoint through which call media flows is unknown type. */
47 public static final int TYPE_UNKNOWN = -1;
48
49 /** Indicates that the type of endpoint through which call media flows is an earpiece. */
50 public static final int TYPE_EARPIECE = 1;
51
52 /** Indicates that the type of endpoint through which call media flows is a Bluetooth. */
53 public static final int TYPE_BLUETOOTH = 2;
54
55 /** Indicates that the type of endpoint through which call media flows is a wired headset. */
56 public static final int TYPE_WIRED_HEADSET = 3;
57
58 /** Indicates that the type of endpoint through which call media flows is a speakerphone. */
59 public static final int TYPE_SPEAKER = 4;
60
61 /** Indicates that the type of endpoint through which call media flows is an external. */
62 public static final int TYPE_STREAMING = 5;
63
Pranav Madapurmathf39d60b2023-06-09 23:16:13 +000064 /**
65 * Error message attached to IllegalArgumentException when the endpoint name or id is null.
66 * @hide
67 */
68 private static final String CALLENDPOINT_NAME_ID_NULL_ERROR =
69 "CallEndpoint name cannot be null.";
70
Junhoedf3d822022-11-24 09:26:37 +000071 private final CharSequence mName;
72 private final int mType;
73 private final ParcelUuid mIdentifier;
74
75 /**
76 * Constructor for a {@link CallEndpoint} object.
77 *
78 * @param name Human-readable name associated with the endpoint
79 * @param type The type of endpoint through which call media being routed
80 * Allowed values:
81 * {@link #TYPE_EARPIECE}
82 * {@link #TYPE_BLUETOOTH}
83 * {@link #TYPE_WIRED_HEADSET}
84 * {@link #TYPE_SPEAKER}
85 * {@link #TYPE_STREAMING}
86 * {@link #TYPE_UNKNOWN}
87 * @param id A unique identifier for this endpoint on the device
88 */
89 public CallEndpoint(@NonNull CharSequence name, @EndpointType int type,
90 @NonNull ParcelUuid id) {
Pranav Madapurmathf39d60b2023-06-09 23:16:13 +000091 // Ensure that endpoint name and id are non-null.
92 if (name == null || id == null) {
93 throw new IllegalArgumentException(CALLENDPOINT_NAME_ID_NULL_ERROR);
94 }
95
Junhoedf3d822022-11-24 09:26:37 +000096 this.mName = name;
97 this.mType = type;
98 this.mIdentifier = id;
99 }
100
101 /** @hide */
102 public CallEndpoint(@NonNull CharSequence name, @EndpointType int type) {
103 this(name, type, new ParcelUuid(UUID.randomUUID()));
104 }
105
106 /** @hide */
107 public CallEndpoint(CallEndpoint endpoint) {
Pranav Madapurmathf39d60b2023-06-09 23:16:13 +0000108 // Ensure that endpoint name and id are non-null.
109 if (endpoint.getEndpointName() == null || endpoint.getIdentifier() == null) {
110 throw new IllegalArgumentException(CALLENDPOINT_NAME_ID_NULL_ERROR);
111 }
112
Junhoedf3d822022-11-24 09:26:37 +0000113 mName = endpoint.getEndpointName();
114 mType = endpoint.getEndpointType();
115 mIdentifier = endpoint.getIdentifier();
116 }
117
118 /**
119 * {@inheritDoc}
120 */
121 @Override
122 public boolean equals(Object obj) {
123 if (obj == null) {
124 return false;
125 }
126 if (!(obj instanceof CallEndpoint)) {
127 return false;
128 }
129 CallEndpoint endpoint = (CallEndpoint) obj;
Grant Menke5c1f88c2023-09-05 14:14:49 -0700130 return Objects.equals(getEndpointName(), endpoint.getEndpointName())
Junhoedf3d822022-11-24 09:26:37 +0000131 && getEndpointType() == endpoint.getEndpointType()
132 && getIdentifier().equals(endpoint.getIdentifier());
133 }
134
135 /**
136 * {@inheritDoc}
137 */
138 @Override
139 public int hashCode() {
140 return Objects.hash(mName, mType, mIdentifier);
141 }
142
143 /**
144 * {@inheritDoc}
145 */
146 @Override
147 public String toString() {
148 return TextUtils.formatSimple("[CallEndpoint Name: %s, Type: %s, Identifier: %s]",
149 mName.toString(), endpointTypeToString(mType), mIdentifier.toString());
150 }
151
152 /**
153 * @return Human-readable name associated with the endpoint
154 */
155 @NonNull
156 public CharSequence getEndpointName() {
157 return mName;
158 }
159
160 /**
161 * @return The type of endpoint through which call media being routed
162 */
163 @EndpointType
164 public int getEndpointType() {
165 return mType;
166 }
167
168 /**
169 * @return A unique identifier for this endpoint on the device
170 */
171 @NonNull
172 public ParcelUuid getIdentifier() {
173 return mIdentifier;
174 }
175
176 /**
177 * Converts the provided endpoint type into a human-readable string representation.
178 *
179 * @param endpointType to convert into a string.
180 * @return String representation of the provided endpoint type.
181 * @hide
182 */
183 @NonNull
184 public static String endpointTypeToString(int endpointType) {
185 switch (endpointType) {
186 case TYPE_EARPIECE:
187 return "EARPIECE";
188 case TYPE_BLUETOOTH:
189 return "BLUETOOTH";
190 case TYPE_WIRED_HEADSET:
191 return "WIRED_HEADSET";
192 case TYPE_SPEAKER:
193 return "SPEAKER";
194 case TYPE_STREAMING:
195 return "EXTERNAL";
196 default:
197 return "UNKNOWN (" + endpointType + ")";
198 }
199 }
200
201 /**
202 * Responsible for creating CallEndpoint objects for deserialized Parcels.
203 */
204 public static final @android.annotation.NonNull Parcelable.Creator<CallEndpoint> CREATOR =
205 new Parcelable.Creator<CallEndpoint>() {
206
207 @Override
208 public CallEndpoint createFromParcel(Parcel source) {
209 CharSequence name = source.readCharSequence();
210 int type = source.readInt();
211 ParcelUuid id = ParcelUuid.CREATOR.createFromParcel(source);
212
213 return new CallEndpoint(name, type, id);
214 }
215
216 @Override
217 public CallEndpoint[] newArray(int size) {
218 return new CallEndpoint[size];
219 }
220 };
221
222 /**
223 * {@inheritDoc}
224 */
225 @Override
226 public int describeContents() {
227 return 0;
228 }
229
230 /**
231 * {@inheritDoc}
232 */
233 @Override
234 public void writeToParcel(@NonNull Parcel destination, int flags) {
235 destination.writeCharSequence(mName);
236 destination.writeInt(mType);
237 mIdentifier.writeToParcel(destination, flags);
238 }
239}