1ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal/*
2ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * Copyright (C) 2016 The Android Open Source Project
3ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal *
4ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * Licensed under the Apache License, Version 2.0 (the "License");
5ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * you may not use this file except in compliance with the License.
6ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * You may obtain a copy of the License at
7ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal *
8ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal *      http://www.apache.org/licenses/LICENSE-2.0
9ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal *
10ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * Unless required by applicable law or agreed to in writing, software
11ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * distributed under the License is distributed on an "AS IS" BASIS,
12ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * See the License for the specific language governing permissions and
14ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * limitations under the License
15ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal */
16ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
17ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepalpackage com.android.server.telecom;
18ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
19ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepalimport android.net.Uri;
20ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepalimport android.telecom.Connection;
21ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepalimport android.telecom.ParcelableCall;
22ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepalimport android.telecom.TelecomManager;
23ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
24ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepalimport java.util.ArrayList;
25ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepalimport java.util.List;
26ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
27ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal/**
28ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal * Utilities dealing with {@link ParcelableCall}.
29ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal */
30ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepalpublic class ParcelableCallUtils {
311e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn    private static final int CALL_STATE_OVERRIDE_NONE = -1;
321e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn
336d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu    public static class Converter {
346d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu        public ParcelableCall toParcelableCall(Call call, boolean includeVideoProvider,
356d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu                PhoneAccountRegistrar phoneAccountRegistrar) {
366d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu            return ParcelableCallUtils.toParcelableCall(
371e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    call, includeVideoProvider, phoneAccountRegistrar, false);
386d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu        }
396d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu    }
406d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu
41ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    /**
42ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     * Parcels all information for a {@link Call} into a new {@link ParcelableCall} instance.
43ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     *
44ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     * @param call The {@link Call} to parcel.
45ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     * @param includeVideoProvider {@code true} if the video provider should be parcelled with the
46ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     *      {@link Call}, {@code false} otherwise.  Since the {@link ParcelableCall#getVideoCall()}
47ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     *      method creates a {@link VideoCallImpl} instance on access it is important for the
48ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     *      recipient of the {@link ParcelableCall} to know if the video provider changed.
49ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     * @param phoneAccountRegistrar The {@link PhoneAccountRegistrar}.
501e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     * @param supportsExternalCalls Indicates whether the call should be parcelled for an
511e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     *      {@link InCallService} which supports external calls or not.
521e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     */
531e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn    public static ParcelableCall toParcelableCall(
541e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            Call call,
551e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            boolean includeVideoProvider,
561e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            PhoneAccountRegistrar phoneAccountRegistrar,
571e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            boolean supportsExternalCalls) {
581e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn        return toParcelableCall(call, includeVideoProvider, phoneAccountRegistrar,
591e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                supportsExternalCalls, CALL_STATE_OVERRIDE_NONE /* overrideState */);
601e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn    }
611e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn
621e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn    /**
631e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     * Parcels all information for a {@link Call} into a new {@link ParcelableCall} instance.
641e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     *
651e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     * @param call The {@link Call} to parcel.
661e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     * @param includeVideoProvider {@code true} if the video provider should be parcelled with the
671e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     *      {@link Call}, {@code false} otherwise.  Since the {@link ParcelableCall#getVideoCall()}
681e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     *      method creates a {@link VideoCallImpl} instance on access it is important for the
691e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     *      recipient of the {@link ParcelableCall} to know if the video provider changed.
701e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     * @param phoneAccountRegistrar The {@link PhoneAccountRegistrar}.
711e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     * @param supportsExternalCalls Indicates whether the call should be parcelled for an
721e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     *      {@link InCallService} which supports external calls or not.
731e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     * @param overrideState When not {@link #CALL_STATE_OVERRIDE_NONE}, use the provided state as an
741e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn     *      override to whatever is defined in the call.
75ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     * @return The {@link ParcelableCall} containing all call information from the {@link Call}.
76ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     */
77ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    public static ParcelableCall toParcelableCall(
78ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            Call call,
79ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            boolean includeVideoProvider,
801e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            PhoneAccountRegistrar phoneAccountRegistrar,
811e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            boolean supportsExternalCalls,
821e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            int overrideState) {
831e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn        int state;
841e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn        if (overrideState == CALL_STATE_OVERRIDE_NONE) {
851e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            state = getParcelableState(call, supportsExternalCalls);
861e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn        } else {
871e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            state = overrideState;
881e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn        }
89ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        int capabilities = convertConnectionToCallCapabilities(call.getConnectionCapabilities());
90571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn        int properties = convertConnectionToCallProperties(call.getConnectionProperties());
9196a0be67619944378d95cdedc64b004aadb341e2Christine Hallstrom        int supportedAudioRoutes = call.getSupportedAudioRoutes();
9296a0be67619944378d95cdedc64b004aadb341e2Christine Hallstrom
93ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        if (call.isConference()) {
94ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            properties |= android.telecom.Call.Details.PROPERTY_CONFERENCE;
95ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
96ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
97d29d93778fe288d87aef03e0a934099995b550bfTony Mak        if (call.isWorkCall()) {
98d9ec0ea4e4821b0ba4287df7c44c42ae77ca8a89Tony Mak            properties |= android.telecom.Call.Details.PROPERTY_ENTERPRISE_CALL;
99ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
100ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
101ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        // If this is a single-SIM device, the "default SIM" will always be the only SIM.
10228b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        boolean isDefaultSmsAccount = phoneAccountRegistrar != null &&
103ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                phoneAccountRegistrar.isUserSelectedSmsPhoneAccount(call.getTargetPhoneAccount());
104ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        if (call.isRespondViaSmsCapable() && isDefaultSmsAccount) {
105ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            capabilities |= android.telecom.Call.Details.CAPABILITY_RESPOND_VIA_TEXT;
106ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
107ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
108ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        if (call.isEmergencyCall()) {
109ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            capabilities = removeCapability(
110ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                    capabilities, android.telecom.Call.Details.CAPABILITY_MUTE);
111ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
112ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
113ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        if (state == android.telecom.Call.STATE_DIALING) {
114ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            capabilities = removeCapability(capabilities,
115ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                    android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
116ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            capabilities = removeCapability(capabilities,
117ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                    android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
118ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
119ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
120ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        String parentCallId = null;
121ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Call parentCall = call.getParentCall();
122ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        if (parentCall != null) {
123ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            parentCallId = parentCall.getId();
124ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
125ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
126ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        long connectTimeMillis = call.getConnectTimeMillis();
127ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        List<Call> childCalls = call.getChildCalls();
128ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        List<String> childCallIds = new ArrayList<>();
129ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        if (!childCalls.isEmpty()) {
130ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            long childConnectTimeMillis = Long.MAX_VALUE;
131ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            for (Call child : childCalls) {
132ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                if (child.getConnectTimeMillis() > 0) {
133ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                    childConnectTimeMillis = Math.min(child.getConnectTimeMillis(),
134ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                            childConnectTimeMillis);
135ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                }
136ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                childCallIds.add(child.getId());
137ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            }
138ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
139ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            if (childConnectTimeMillis != Long.MAX_VALUE) {
140ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                connectTimeMillis = childConnectTimeMillis;
141ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            }
142ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
143ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
144ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Uri handle = call.getHandlePresentation() == TelecomManager.PRESENTATION_ALLOWED ?
145ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getHandle() : null;
146ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        String callerDisplayName = call.getCallerDisplayNamePresentation() ==
147ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                TelecomManager.PRESENTATION_ALLOWED ?  call.getCallerDisplayName() : null;
148ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
149ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        List<Call> conferenceableCalls = call.getConferenceableCalls();
150ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        List<String> conferenceableCallIds = new ArrayList<String>(conferenceableCalls.size());
151ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        for (Call otherCall : conferenceableCalls) {
152ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            conferenceableCallIds.add(otherCall.getId());
153ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
154ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
155ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        return new ParcelableCall(
156ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getId(),
157ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state,
158ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getDisconnectCause(),
159ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getCannedSmsResponses(),
160ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                capabilities,
161ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                properties,
16296a0be67619944378d95cdedc64b004aadb341e2Christine Hallstrom                supportedAudioRoutes,
163ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                connectTimeMillis,
164ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                handle,
165ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getHandlePresentation(),
166ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                callerDisplayName,
167ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getCallerDisplayNamePresentation(),
168ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getGatewayInfo(),
169ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getTargetPhoneAccount(),
170ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                includeVideoProvider,
171ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                includeVideoProvider ? call.getVideoProvider() : null,
172ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                parentCallId,
173ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                childCallIds,
174ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getStatusHints(),
175ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getVideoState(),
176ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                conferenceableCallIds,
177ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getIntentExtras(),
178ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                call.getExtras());
179ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    }
180ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
1811e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn    private static int getParcelableState(Call call, boolean supportsExternalCalls) {
182ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        int state = CallState.NEW;
183ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        switch (call.getState()) {
184ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.ABORTED:
185ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.DISCONNECTED:
186ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_DISCONNECTED;
187ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
188ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.ACTIVE:
189ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_ACTIVE;
190ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
191ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.CONNECTING:
192ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_CONNECTING;
193ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
194ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.DIALING:
195ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_DIALING;
196ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
1971e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            case CallState.PULLING:
1981e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                if (supportsExternalCalls) {
1991e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    // The InCallService supports external calls, so it must handle
2001e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    // STATE_PULLING_CALL.
2011e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    state = android.telecom.Call.STATE_PULLING_CALL;
2021e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                } else {
2031e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    // The InCallService does NOT support external calls, so remap
2041e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    // STATE_PULLING_CALL to STATE_DIALING.  In essence, pulling a call can be seen
2051e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    // as a form of dialing, so it is appropriate for InCallServices which do not
2061e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    // handle external calls.
2071e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                    state = android.telecom.Call.STATE_DIALING;
2081e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                }
2091e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                break;
210ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.DISCONNECTING:
211ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_DISCONNECTING;
212ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
213ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.NEW:
214ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_NEW;
215ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
216ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.ON_HOLD:
217ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_HOLDING;
218ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
219ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.RINGING:
220ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_RINGING;
221ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
222ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            case CallState.SELECT_PHONE_ACCOUNT:
223ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                state = android.telecom.Call.STATE_SELECT_PHONE_ACCOUNT;
224ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                break;
225ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
226ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
227ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        // If we are marked as 'locally disconnecting' then mark ourselves as disconnecting instead.
228ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        // Unless we're disconnect*ED*, in which case leave it at that.
229ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        if (call.isLocallyDisconnecting() &&
230ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                (state != android.telecom.Call.STATE_DISCONNECTED)) {
231ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            state = android.telecom.Call.STATE_DISCONNECTING;
232ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
233ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        return state;
234ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    }
235ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
236ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    private static final int[] CONNECTION_TO_CALL_CAPABILITY = new int[] {
237ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_HOLD,
238ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_HOLD,
239ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
240ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SUPPORT_HOLD,
241ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SUPPORT_HOLD,
242ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
243ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_MERGE_CONFERENCE,
244ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE,
245ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
246ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SWAP_CONFERENCE,
247ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE,
248ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
249ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_RESPOND_VIA_TEXT,
250ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_RESPOND_VIA_TEXT,
251ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
252ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_MUTE,
253ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_MUTE,
254ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
255ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_MANAGE_CONFERENCE,
256ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_MANAGE_CONFERENCE,
257ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
258ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SUPPORTS_VT_LOCAL_RX,
259ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX,
260ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
261ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SUPPORTS_VT_LOCAL_TX,
262ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX,
263ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
264ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL,
265ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL,
266ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
267ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SUPPORTS_VT_REMOTE_RX,
268ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX,
269ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
270ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SUPPORTS_VT_REMOTE_TX,
271ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX,
272ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
273ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL,
274ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL,
275ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
276ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE,
277ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE,
278ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
279ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE,
280ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE,
281ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
282ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_CAN_UPGRADE_TO_VIDEO,
283ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_CAN_UPGRADE_TO_VIDEO,
284ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
285ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_CAN_PAUSE_VIDEO,
286ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_CAN_PAUSE_VIDEO,
287ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
288ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION,
289ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION,
290ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
291ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        Connection.CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO,
292d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        android.telecom.Call.Details.CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO,
293d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn
294d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        Connection.CAPABILITY_CAN_PULL_CALL,
295d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        android.telecom.Call.Details.CAPABILITY_CAN_PULL_CALL
296ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    };
297ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
298ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    private static int convertConnectionToCallCapabilities(int connectionCapabilities) {
299ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        int callCapabilities = 0;
300ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        for (int i = 0; i < CONNECTION_TO_CALL_CAPABILITY.length; i += 2) {
301ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            if ((CONNECTION_TO_CALL_CAPABILITY[i] & connectionCapabilities) ==
302ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                    CONNECTION_TO_CALL_CAPABILITY[i]) {
303ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
304ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                callCapabilities |= CONNECTION_TO_CALL_CAPABILITY[i + 1];
305ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            }
306ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
307ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        return callCapabilities;
308ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    }
309ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
310ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    private static final int[] CONNECTION_TO_CALL_PROPERTIES = new int[] {
311571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn        Connection.PROPERTY_HIGH_DEF_AUDIO,
312ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.PROPERTY_HIGH_DEF_AUDIO,
313ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
314571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn        Connection.PROPERTY_WIFI,
315ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.PROPERTY_WIFI,
316ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
317571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn        Connection.PROPERTY_GENERIC_CONFERENCE,
318ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        android.telecom.Call.Details.PROPERTY_GENERIC_CONFERENCE,
319ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
320ddf3f9c445699db2034da580db02dcaaddcdd322Hall Liu        Connection.PROPERTY_EMERGENCY_CALLBACK_MODE,
321d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn        android.telecom.Call.Details.PROPERTY_EMERGENCY_CALLBACK_MODE,
322d45e6d973ea7460fb605a1eb7a66ba38c6f2467dTyler Gunn
323571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn        Connection.PROPERTY_IS_EXTERNAL_CALL,
32484771f8f87f5f582bf848b621eed8c6cd99d41b0Brad Ebinger        android.telecom.Call.Details.PROPERTY_IS_EXTERNAL_CALL,
32584771f8f87f5f582bf848b621eed8c6cd99d41b0Brad Ebinger
32684771f8f87f5f582bf848b621eed8c6cd99d41b0Brad Ebinger        Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY,
32784771f8f87f5f582bf848b621eed8c6cd99d41b0Brad Ebinger        android.telecom.Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY
328ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    };
329ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
330571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn    private static int convertConnectionToCallProperties(int connectionProperties) {
331ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        int callProperties = 0;
332ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        for (int i = 0; i < CONNECTION_TO_CALL_PROPERTIES.length; i += 2) {
333571d5e66b8cbee023702b4b0a2a1c28663c5a7f8Tyler Gunn            if ((CONNECTION_TO_CALL_PROPERTIES[i] & connectionProperties) ==
334ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                    CONNECTION_TO_CALL_PROPERTIES[i]) {
335ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
336ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal                callProperties |= CONNECTION_TO_CALL_PROPERTIES[i + 1];
337ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal            }
338ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        }
339ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        return callProperties;
340ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    }
341ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
342ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    /**
343ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     * Removes the specified capability from the set of capabilities bits and returns the new set.
344ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal     */
345ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    private static int removeCapability(int capabilities, int capability) {
346ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal        return capabilities & ~capability;
347ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    }
348ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal
349ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal    private ParcelableCallUtils() {}
350ae92595c2f0f88a5bef8d2601f026b9d3ae2d7ddSailesh Nepal}
351