1/*
2 * Copyright 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.telecom;
18
19import android.net.Uri;
20import android.os.Bundle;
21import android.os.Parcel;
22import android.os.Parcelable;
23import android.os.RemoteException;
24
25import java.util.ArrayList;
26import java.util.Collections;
27import java.util.List;
28
29import com.android.internal.telecom.IVideoProvider;
30
31/**
32 * Information about a call that is used between InCallService and Telecom.
33 * @hide
34 */
35public final class ParcelableCall implements Parcelable {
36    private final String mId;
37    private final int mState;
38    private final DisconnectCause mDisconnectCause;
39    private final List<String> mCannedSmsResponses;
40    private final int mCapabilities;
41    private final int mProperties;
42    private final long mConnectTimeMillis;
43    private final Uri mHandle;
44    private final int mHandlePresentation;
45    private final String mCallerDisplayName;
46    private final int mCallerDisplayNamePresentation;
47    private final GatewayInfo mGatewayInfo;
48    private final PhoneAccountHandle mAccountHandle;
49    private final boolean mIsVideoCallProviderChanged;
50    private final IVideoProvider mVideoCallProvider;
51    private InCallService.VideoCall mVideoCall;
52    private final String mParentCallId;
53    private final List<String> mChildCallIds;
54    private final StatusHints mStatusHints;
55    private final int mVideoState;
56    private final List<String> mConferenceableCallIds;
57    private final Bundle mIntentExtras;
58    private final Bundle mExtras;
59
60    public ParcelableCall(
61            String id,
62            int state,
63            DisconnectCause disconnectCause,
64            List<String> cannedSmsResponses,
65            int capabilities,
66            int properties,
67            long connectTimeMillis,
68            Uri handle,
69            int handlePresentation,
70            String callerDisplayName,
71            int callerDisplayNamePresentation,
72            GatewayInfo gatewayInfo,
73            PhoneAccountHandle accountHandle,
74            boolean isVideoCallProviderChanged,
75            IVideoProvider videoCallProvider,
76            String parentCallId,
77            List<String> childCallIds,
78            StatusHints statusHints,
79            int videoState,
80            List<String> conferenceableCallIds,
81            Bundle intentExtras,
82            Bundle extras) {
83        mId = id;
84        mState = state;
85        mDisconnectCause = disconnectCause;
86        mCannedSmsResponses = cannedSmsResponses;
87        mCapabilities = capabilities;
88        mProperties = properties;
89        mConnectTimeMillis = connectTimeMillis;
90        mHandle = handle;
91        mHandlePresentation = handlePresentation;
92        mCallerDisplayName = callerDisplayName;
93        mCallerDisplayNamePresentation = callerDisplayNamePresentation;
94        mGatewayInfo = gatewayInfo;
95        mAccountHandle = accountHandle;
96        mIsVideoCallProviderChanged = isVideoCallProviderChanged;
97        mVideoCallProvider = videoCallProvider;
98        mParentCallId = parentCallId;
99        mChildCallIds = childCallIds;
100        mStatusHints = statusHints;
101        mVideoState = videoState;
102        mConferenceableCallIds = Collections.unmodifiableList(conferenceableCallIds);
103        mIntentExtras = intentExtras;
104        mExtras = extras;
105    }
106
107    /** The unique ID of the call. */
108    public String getId() {
109        return mId;
110    }
111
112    /** The current state of the call. */
113    public int getState() {
114        return mState;
115    }
116
117    /**
118     * Reason for disconnection, as described by {@link android.telecomm.DisconnectCause}. Valid
119     * when call state is {@link CallState#DISCONNECTED}.
120     */
121    public DisconnectCause getDisconnectCause() {
122        return mDisconnectCause;
123    }
124
125    /**
126     * The set of possible text message responses when this call is incoming.
127     */
128    public List<String> getCannedSmsResponses() {
129        return mCannedSmsResponses;
130    }
131
132    // Bit mask of actions a call supports, values are defined in {@link CallCapabilities}.
133    public int getCapabilities() {
134        return mCapabilities;
135    }
136
137    /** Bitmask of properties of the call. */
138    public int getProperties() { return mProperties; }
139
140    /** The time that the call switched to the active state. */
141    public long getConnectTimeMillis() {
142        return mConnectTimeMillis;
143    }
144
145    /** The endpoint to which the call is connected. */
146    public Uri getHandle() {
147        return mHandle;
148    }
149
150    /**
151     * The presentation requirements for the handle. See {@link TelecomManager} for valid values.
152     */
153    public int getHandlePresentation() {
154        return mHandlePresentation;
155    }
156
157    /** The endpoint to which the call is connected. */
158    public String getCallerDisplayName() {
159        return mCallerDisplayName;
160    }
161
162    /**
163     * The presentation requirements for the caller display name.
164     * See {@link TelecomManager} for valid values.
165     */
166    public int getCallerDisplayNamePresentation() {
167        return mCallerDisplayNamePresentation;
168    }
169
170    /** Gateway information for the call. */
171    public GatewayInfo getGatewayInfo() {
172        return mGatewayInfo;
173    }
174
175    /** PhoneAccountHandle information for the call. */
176    public PhoneAccountHandle getAccountHandle() {
177        return mAccountHandle;
178    }
179
180    /**
181     * Returns an object for remotely communicating through the video call provider's binder.
182     * @return The video call.
183     */
184    public InCallService.VideoCall getVideoCall(Call call) {
185        if (mVideoCall == null && mVideoCallProvider != null) {
186            try {
187                mVideoCall = new VideoCallImpl(mVideoCallProvider, call);
188            } catch (RemoteException ignored) {
189                // Ignore RemoteException.
190            }
191        }
192
193        return mVideoCall;
194    }
195
196    /**
197     * The conference call to which this call is conferenced. Null if not conferenced.
198     */
199    public String getParentCallId() {
200        return mParentCallId;
201    }
202
203    /**
204     * The child call-IDs if this call is a conference call. Returns an empty list if this is not
205     * a conference call or if the conference call contains no children.
206     */
207    public List<String> getChildCallIds() {
208        return mChildCallIds;
209    }
210
211    public List<String> getConferenceableCallIds() {
212        return mConferenceableCallIds;
213    }
214
215    /**
216     * The status label and icon.
217     *
218     * @return Status hints.
219     */
220    public StatusHints getStatusHints() {
221        return mStatusHints;
222    }
223
224    /**
225     * The video state.
226     * @return The video state of the call.
227     */
228    public int getVideoState() {
229        return mVideoState;
230    }
231
232    /**
233     * Any extras associated with this call.
234     *
235     * @return a bundle of extras
236     */
237    public Bundle getExtras() {
238        return mExtras;
239    }
240
241    /**
242     * Extras passed in as part of the original call intent.
243     *
244     * @return The intent extras.
245     */
246    public Bundle getIntentExtras() {
247        return mIntentExtras;
248    }
249
250    /**
251     * Indicates to the receiver of the {@link ParcelableCall} whether a change has occurred in the
252     * {@link android.telecom.InCallService.VideoCall} associated with this call.  Since
253     * {@link #getVideoCall()} creates a new {@link VideoCallImpl}, it is useful to know whether
254     * the provider has changed (which can influence whether it is accessed).
255     *
256     * @return {@code true} if the video call changed, {@code false} otherwise.
257     */
258    public boolean isVideoCallProviderChanged() {
259        return mIsVideoCallProviderChanged;
260    }
261
262    /** Responsible for creating ParcelableCall objects for deserialized Parcels. */
263    public static final Parcelable.Creator<ParcelableCall> CREATOR =
264            new Parcelable.Creator<ParcelableCall> () {
265        @Override
266        public ParcelableCall createFromParcel(Parcel source) {
267            ClassLoader classLoader = ParcelableCall.class.getClassLoader();
268            String id = source.readString();
269            int state = source.readInt();
270            DisconnectCause disconnectCause = source.readParcelable(classLoader);
271            List<String> cannedSmsResponses = new ArrayList<>();
272            source.readList(cannedSmsResponses, classLoader);
273            int capabilities = source.readInt();
274            int properties = source.readInt();
275            long connectTimeMillis = source.readLong();
276            Uri handle = source.readParcelable(classLoader);
277            int handlePresentation = source.readInt();
278            String callerDisplayName = source.readString();
279            int callerDisplayNamePresentation = source.readInt();
280            GatewayInfo gatewayInfo = source.readParcelable(classLoader);
281            PhoneAccountHandle accountHandle = source.readParcelable(classLoader);
282            boolean isVideoCallProviderChanged = source.readByte() == 1;
283            IVideoProvider videoCallProvider =
284                    IVideoProvider.Stub.asInterface(source.readStrongBinder());
285            String parentCallId = source.readString();
286            List<String> childCallIds = new ArrayList<>();
287            source.readList(childCallIds, classLoader);
288            StatusHints statusHints = source.readParcelable(classLoader);
289            int videoState = source.readInt();
290            List<String> conferenceableCallIds = new ArrayList<>();
291            source.readList(conferenceableCallIds, classLoader);
292            Bundle intentExtras = source.readBundle(classLoader);
293            Bundle extras = source.readBundle(classLoader);
294            return new ParcelableCall(
295                    id,
296                    state,
297                    disconnectCause,
298                    cannedSmsResponses,
299                    capabilities,
300                    properties,
301                    connectTimeMillis,
302                    handle,
303                    handlePresentation,
304                    callerDisplayName,
305                    callerDisplayNamePresentation,
306                    gatewayInfo,
307                    accountHandle,
308                    isVideoCallProviderChanged,
309                    videoCallProvider,
310                    parentCallId,
311                    childCallIds,
312                    statusHints,
313                    videoState,
314                    conferenceableCallIds,
315                    intentExtras,
316                    extras);
317        }
318
319        @Override
320        public ParcelableCall[] newArray(int size) {
321            return new ParcelableCall[size];
322        }
323    };
324
325    /** {@inheritDoc} */
326    @Override
327    public int describeContents() {
328        return 0;
329    }
330
331    /** Writes ParcelableCall object into a Parcel. */
332    @Override
333    public void writeToParcel(Parcel destination, int flags) {
334        destination.writeString(mId);
335        destination.writeInt(mState);
336        destination.writeParcelable(mDisconnectCause, 0);
337        destination.writeList(mCannedSmsResponses);
338        destination.writeInt(mCapabilities);
339        destination.writeInt(mProperties);
340        destination.writeLong(mConnectTimeMillis);
341        destination.writeParcelable(mHandle, 0);
342        destination.writeInt(mHandlePresentation);
343        destination.writeString(mCallerDisplayName);
344        destination.writeInt(mCallerDisplayNamePresentation);
345        destination.writeParcelable(mGatewayInfo, 0);
346        destination.writeParcelable(mAccountHandle, 0);
347        destination.writeByte((byte) (mIsVideoCallProviderChanged ? 1 : 0));
348        destination.writeStrongBinder(
349                mVideoCallProvider != null ? mVideoCallProvider.asBinder() : null);
350        destination.writeString(mParentCallId);
351        destination.writeList(mChildCallIds);
352        destination.writeParcelable(mStatusHints, 0);
353        destination.writeInt(mVideoState);
354        destination.writeList(mConferenceableCallIds);
355        destination.writeBundle(mIntentExtras);
356        destination.writeBundle(mExtras);
357    }
358
359    @Override
360    public String toString() {
361        return String.format("[%s, parent:%s, children:%s]", mId, mParentCallId, mChildCallIds);
362    }
363}
364