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