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.bluetooth;
18 
19 import android.annotation.UnsupportedAppUsage;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.os.SystemClock;
23 
24 import java.util.UUID;
25 
26 /**
27  * This class represents a single call, its state and properties.
28  * It implements {@link Parcelable} for inter-process message passing.
29  *
30  * @hide
31  */
32 public final class BluetoothHeadsetClientCall implements Parcelable {
33 
34     /* Call state */
35     /**
36      * Call is active.
37      */
38     public static final int CALL_STATE_ACTIVE = 0;
39     /**
40      * Call is in held state.
41      */
42     public static final int CALL_STATE_HELD = 1;
43     /**
44      * Outgoing call that is being dialed right now.
45      */
46     public static final int CALL_STATE_DIALING = 2;
47     /**
48      * Outgoing call that remote party has already been alerted about.
49      */
50     public static final int CALL_STATE_ALERTING = 3;
51     /**
52      * Incoming call that can be accepted or rejected.
53      */
54     public static final int CALL_STATE_INCOMING = 4;
55     /**
56      * Waiting call state when there is already an active call.
57      */
58     public static final int CALL_STATE_WAITING = 5;
59     /**
60      * Call that has been held by response and hold
61      * (see Bluetooth specification for further references).
62      */
63     public static final int CALL_STATE_HELD_BY_RESPONSE_AND_HOLD = 6;
64     /**
65      * Call that has been already terminated and should not be referenced as a valid call.
66      */
67     public static final int CALL_STATE_TERMINATED = 7;
68 
69     private final BluetoothDevice mDevice;
70     private final int mId;
71     private int mState;
72     private String mNumber;
73     private boolean mMultiParty;
74     private final boolean mOutgoing;
75     private final UUID mUUID;
76     private final long mCreationElapsedMilli;
77     private final boolean mInBandRing;
78 
79     /**
80      * Creates BluetoothHeadsetClientCall instance.
81      */
BluetoothHeadsetClientCall(BluetoothDevice device, int id, int state, String number, boolean multiParty, boolean outgoing, boolean inBandRing)82     public BluetoothHeadsetClientCall(BluetoothDevice device, int id, int state, String number,
83             boolean multiParty, boolean outgoing, boolean inBandRing) {
84         this(device, id, UUID.randomUUID(), state, number, multiParty, outgoing, inBandRing);
85     }
86 
BluetoothHeadsetClientCall(BluetoothDevice device, int id, UUID uuid, int state, String number, boolean multiParty, boolean outgoing, boolean inBandRing)87     public BluetoothHeadsetClientCall(BluetoothDevice device, int id, UUID uuid, int state,
88             String number, boolean multiParty, boolean outgoing, boolean inBandRing) {
89         mDevice = device;
90         mId = id;
91         mUUID = uuid;
92         mState = state;
93         mNumber = number != null ? number : "";
94         mMultiParty = multiParty;
95         mOutgoing = outgoing;
96         mInBandRing = inBandRing;
97         mCreationElapsedMilli = SystemClock.elapsedRealtime();
98     }
99 
100     /**
101      * Sets call's state.
102      *
103      * <p>Note: This is an internal function and shouldn't be exposed</p>
104      *
105      * @param state new call state.
106      */
setState(int state)107     public void setState(int state) {
108         mState = state;
109     }
110 
111     /**
112      * Sets call's number.
113      *
114      * <p>Note: This is an internal function and shouldn't be exposed</p>
115      *
116      * @param number String representing phone number.
117      */
setNumber(String number)118     public void setNumber(String number) {
119         mNumber = number;
120     }
121 
122     /**
123      * Sets this call as multi party call.
124      *
125      * <p>Note: This is an internal function and shouldn't be exposed</p>
126      *
127      * @param multiParty if <code>true</code> sets this call as a part of multi party conference.
128      */
setMultiParty(boolean multiParty)129     public void setMultiParty(boolean multiParty) {
130         mMultiParty = multiParty;
131     }
132 
133     /**
134      * Gets call's device.
135      *
136      * @return call device.
137      */
getDevice()138     public BluetoothDevice getDevice() {
139         return mDevice;
140     }
141 
142     /**
143      * Gets call's Id.
144      *
145      * @return call id.
146      */
147     @UnsupportedAppUsage
getId()148     public int getId() {
149         return mId;
150     }
151 
152     /**
153      * Gets call's UUID.
154      *
155      * @return call uuid
156      * @hide
157      */
getUUID()158     public UUID getUUID() {
159         return mUUID;
160     }
161 
162     /**
163      * Gets call's current state.
164      *
165      * @return state of this particular phone call.
166      */
167     @UnsupportedAppUsage
getState()168     public int getState() {
169         return mState;
170     }
171 
172     /**
173      * Gets call's number.
174      *
175      * @return string representing phone number.
176      */
177     @UnsupportedAppUsage
getNumber()178     public String getNumber() {
179         return mNumber;
180     }
181 
182     /**
183      * Gets call's creation time in millis since epoch.
184      *
185      * @return long representing the creation time.
186      */
getCreationElapsedMilli()187     public long getCreationElapsedMilli() {
188         return mCreationElapsedMilli;
189     }
190 
191     /**
192      * Checks if call is an active call in a conference mode (aka multi party).
193      *
194      * @return <code>true</code> if call is a multi party call, <code>false</code> otherwise.
195      */
196     @UnsupportedAppUsage
isMultiParty()197     public boolean isMultiParty() {
198         return mMultiParty;
199     }
200 
201     /**
202      * Checks if this call is an outgoing call.
203      *
204      * @return <code>true</code> if its outgoing call, <code>false</code> otherwise.
205      */
206     @UnsupportedAppUsage
isOutgoing()207     public boolean isOutgoing() {
208         return mOutgoing;
209     }
210 
211     /**
212      * Checks if the ringtone will be generated by the connected phone
213      *
214      * @return <code>true</code> if in band ring is enabled, <code>false</code> otherwise.
215      */
isInBandRing()216     public boolean isInBandRing() {
217         return mInBandRing;
218     }
219 
220 
221     @Override
toString()222     public String toString() {
223         return toString(false);
224     }
225 
226     /**
227      * Generate a log string for this call
228      * @param loggable whether device address should be logged
229      * @return log string
230      */
toString(boolean loggable)231     public String toString(boolean loggable) {
232         StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mDevice: ");
233         builder.append(loggable ? mDevice : mDevice.hashCode());
234         builder.append(", mId: ");
235         builder.append(mId);
236         builder.append(", mUUID: ");
237         builder.append(mUUID);
238         builder.append(", mState: ");
239         switch (mState) {
240             case CALL_STATE_ACTIVE:
241                 builder.append("ACTIVE");
242                 break;
243             case CALL_STATE_HELD:
244                 builder.append("HELD");
245                 break;
246             case CALL_STATE_DIALING:
247                 builder.append("DIALING");
248                 break;
249             case CALL_STATE_ALERTING:
250                 builder.append("ALERTING");
251                 break;
252             case CALL_STATE_INCOMING:
253                 builder.append("INCOMING");
254                 break;
255             case CALL_STATE_WAITING:
256                 builder.append("WAITING");
257                 break;
258             case CALL_STATE_HELD_BY_RESPONSE_AND_HOLD:
259                 builder.append("HELD_BY_RESPONSE_AND_HOLD");
260                 break;
261             case CALL_STATE_TERMINATED:
262                 builder.append("TERMINATED");
263                 break;
264             default:
265                 builder.append(mState);
266                 break;
267         }
268         builder.append(", mNumber: ");
269         builder.append(loggable ? mNumber : mNumber.hashCode());
270         builder.append(", mMultiParty: ");
271         builder.append(mMultiParty);
272         builder.append(", mOutgoing: ");
273         builder.append(mOutgoing);
274         builder.append(", mInBandRing: ");
275         builder.append(mInBandRing);
276         builder.append("}");
277         return builder.toString();
278     }
279 
280     /**
281      * {@link Parcelable.Creator} interface implementation.
282      */
283     public static final @android.annotation.NonNull Parcelable.Creator<BluetoothHeadsetClientCall> CREATOR =
284             new Parcelable.Creator<BluetoothHeadsetClientCall>() {
285                 @Override
286                 public BluetoothHeadsetClientCall createFromParcel(Parcel in) {
287                     return new BluetoothHeadsetClientCall((BluetoothDevice) in.readParcelable(null),
288                             in.readInt(), UUID.fromString(in.readString()), in.readInt(),
289                             in.readString(), in.readInt() == 1, in.readInt() == 1,
290                             in.readInt() == 1);
291                 }
292 
293                 @Override
294                 public BluetoothHeadsetClientCall[] newArray(int size) {
295                     return new BluetoothHeadsetClientCall[size];
296                 }
297             };
298 
299     @Override
writeToParcel(Parcel out, int flags)300     public void writeToParcel(Parcel out, int flags) {
301         out.writeParcelable(mDevice, 0);
302         out.writeInt(mId);
303         out.writeString(mUUID.toString());
304         out.writeInt(mState);
305         out.writeString(mNumber);
306         out.writeInt(mMultiParty ? 1 : 0);
307         out.writeInt(mOutgoing ? 1 : 0);
308         out.writeInt(mInBandRing ? 1 : 0);
309     }
310 
311     @Override
describeContents()312     public int describeContents() {
313         return 0;
314     }
315 }
316