blob: 6c523dd3fdad6ee693bcd116f5b3fd4fc13f90db [file] [log] [blame]
Sailesh Nepalae925952016-01-24 18:56:58 -08001/*
2 * Copyright (C) 2016 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 com.android.server.telecom;
18
19import android.net.Uri;
20import android.telecom.Connection;
21import android.telecom.ParcelableCall;
22import android.telecom.TelecomManager;
23
24import java.util.ArrayList;
25import java.util.List;
26
27/**
28 * Utilities dealing with {@link ParcelableCall}.
29 */
30public class ParcelableCallUtils {
31 /**
32 * Parcels all information for a {@link Call} into a new {@link ParcelableCall} instance.
33 *
34 * @param call The {@link Call} to parcel.
35 * @param includeVideoProvider {@code true} if the video provider should be parcelled with the
36 * {@link Call}, {@code false} otherwise. Since the {@link ParcelableCall#getVideoCall()}
37 * method creates a {@link VideoCallImpl} instance on access it is important for the
38 * recipient of the {@link ParcelableCall} to know if the video provider changed.
39 * @param phoneAccountRegistrar The {@link PhoneAccountRegistrar}.
40 * @return The {@link ParcelableCall} containing all call information from the {@link Call}.
41 */
42 public static ParcelableCall toParcelableCall(
43 Call call,
44 boolean includeVideoProvider,
45 PhoneAccountRegistrar phoneAccountRegistrar) {
46 int state = getParcelableState(call);
47 int capabilities = convertConnectionToCallCapabilities(call.getConnectionCapabilities());
48 int properties = convertConnectionToCallProperties(call.getConnectionCapabilities());
49 if (call.isConference()) {
50 properties |= android.telecom.Call.Details.PROPERTY_CONFERENCE;
51 }
52
53 if (call.isWorkCall(phoneAccountRegistrar)) {
54 properties |= android.telecom.Call.Details.PROPERTY_WORK_CALL;
55 }
56
57 // If this is a single-SIM device, the "default SIM" will always be the only SIM.
58 boolean isDefaultSmsAccount =
59 phoneAccountRegistrar.isUserSelectedSmsPhoneAccount(call.getTargetPhoneAccount());
60 if (call.isRespondViaSmsCapable() && isDefaultSmsAccount) {
61 capabilities |= android.telecom.Call.Details.CAPABILITY_RESPOND_VIA_TEXT;
62 }
63
64 if (call.isEmergencyCall()) {
65 capabilities = removeCapability(
66 capabilities, android.telecom.Call.Details.CAPABILITY_MUTE);
67 }
68
69 if (state == android.telecom.Call.STATE_DIALING) {
70 capabilities = removeCapability(capabilities,
71 android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL);
72 capabilities = removeCapability(capabilities,
73 android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
74 }
75
76 String parentCallId = null;
77 Call parentCall = call.getParentCall();
78 if (parentCall != null) {
79 parentCallId = parentCall.getId();
80 }
81
82 long connectTimeMillis = call.getConnectTimeMillis();
83 List<Call> childCalls = call.getChildCalls();
84 List<String> childCallIds = new ArrayList<>();
85 if (!childCalls.isEmpty()) {
86 long childConnectTimeMillis = Long.MAX_VALUE;
87 for (Call child : childCalls) {
88 if (child.getConnectTimeMillis() > 0) {
89 childConnectTimeMillis = Math.min(child.getConnectTimeMillis(),
90 childConnectTimeMillis);
91 }
92 childCallIds.add(child.getId());
93 }
94
95 if (childConnectTimeMillis != Long.MAX_VALUE) {
96 connectTimeMillis = childConnectTimeMillis;
97 }
98 }
99
100 Uri handle = call.getHandlePresentation() == TelecomManager.PRESENTATION_ALLOWED ?
101 call.getHandle() : null;
102 String callerDisplayName = call.getCallerDisplayNamePresentation() ==
103 TelecomManager.PRESENTATION_ALLOWED ? call.getCallerDisplayName() : null;
104
105 List<Call> conferenceableCalls = call.getConferenceableCalls();
106 List<String> conferenceableCallIds = new ArrayList<String>(conferenceableCalls.size());
107 for (Call otherCall : conferenceableCalls) {
108 conferenceableCallIds.add(otherCall.getId());
109 }
110
111 return new ParcelableCall(
112 call.getId(),
113 state,
114 call.getDisconnectCause(),
115 call.getCannedSmsResponses(),
116 capabilities,
117 properties,
118 connectTimeMillis,
119 handle,
120 call.getHandlePresentation(),
121 callerDisplayName,
122 call.getCallerDisplayNamePresentation(),
123 call.getGatewayInfo(),
124 call.getTargetPhoneAccount(),
125 includeVideoProvider,
126 includeVideoProvider ? call.getVideoProvider() : null,
127 parentCallId,
128 childCallIds,
129 call.getStatusHints(),
130 call.getVideoState(),
131 conferenceableCallIds,
132 call.getIntentExtras(),
133 call.getExtras());
134 }
135
136 private static int getParcelableState(Call call) {
137 int state = CallState.NEW;
138 switch (call.getState()) {
139 case CallState.ABORTED:
140 case CallState.DISCONNECTED:
141 state = android.telecom.Call.STATE_DISCONNECTED;
142 break;
143 case CallState.ACTIVE:
144 state = android.telecom.Call.STATE_ACTIVE;
145 break;
146 case CallState.CONNECTING:
147 state = android.telecom.Call.STATE_CONNECTING;
148 break;
149 case CallState.DIALING:
150 state = android.telecom.Call.STATE_DIALING;
151 break;
152 case CallState.DISCONNECTING:
153 state = android.telecom.Call.STATE_DISCONNECTING;
154 break;
155 case CallState.NEW:
156 state = android.telecom.Call.STATE_NEW;
157 break;
158 case CallState.ON_HOLD:
159 state = android.telecom.Call.STATE_HOLDING;
160 break;
161 case CallState.RINGING:
162 state = android.telecom.Call.STATE_RINGING;
163 break;
164 case CallState.SELECT_PHONE_ACCOUNT:
165 state = android.telecom.Call.STATE_SELECT_PHONE_ACCOUNT;
166 break;
167 }
168
169 // If we are marked as 'locally disconnecting' then mark ourselves as disconnecting instead.
170 // Unless we're disconnect*ED*, in which case leave it at that.
171 if (call.isLocallyDisconnecting() &&
172 (state != android.telecom.Call.STATE_DISCONNECTED)) {
173 state = android.telecom.Call.STATE_DISCONNECTING;
174 }
175 return state;
176 }
177
178 private static final int[] CONNECTION_TO_CALL_CAPABILITY = new int[] {
179 Connection.CAPABILITY_HOLD,
180 android.telecom.Call.Details.CAPABILITY_HOLD,
181
182 Connection.CAPABILITY_SUPPORT_HOLD,
183 android.telecom.Call.Details.CAPABILITY_SUPPORT_HOLD,
184
185 Connection.CAPABILITY_MERGE_CONFERENCE,
186 android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE,
187
188 Connection.CAPABILITY_SWAP_CONFERENCE,
189 android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE,
190
191 Connection.CAPABILITY_RESPOND_VIA_TEXT,
192 android.telecom.Call.Details.CAPABILITY_RESPOND_VIA_TEXT,
193
194 Connection.CAPABILITY_MUTE,
195 android.telecom.Call.Details.CAPABILITY_MUTE,
196
197 Connection.CAPABILITY_MANAGE_CONFERENCE,
198 android.telecom.Call.Details.CAPABILITY_MANAGE_CONFERENCE,
199
200 Connection.CAPABILITY_SUPPORTS_VT_LOCAL_RX,
201 android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX,
202
203 Connection.CAPABILITY_SUPPORTS_VT_LOCAL_TX,
204 android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX,
205
206 Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL,
207 android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL,
208
209 Connection.CAPABILITY_SUPPORTS_VT_REMOTE_RX,
210 android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX,
211
212 Connection.CAPABILITY_SUPPORTS_VT_REMOTE_TX,
213 android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX,
214
215 Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL,
216 android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL,
217
218 Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE,
219 android.telecom.Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE,
220
221 Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE,
222 android.telecom.Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE,
223
224 Connection.CAPABILITY_CAN_UPGRADE_TO_VIDEO,
225 android.telecom.Call.Details.CAPABILITY_CAN_UPGRADE_TO_VIDEO,
226
227 Connection.CAPABILITY_CAN_PAUSE_VIDEO,
228 android.telecom.Call.Details.CAPABILITY_CAN_PAUSE_VIDEO,
229
230 Connection.CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION,
231 android.telecom.Call.Details.CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION,
232
233 Connection.CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO,
234 android.telecom.Call.Details.CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO
235 };
236
237 private static int convertConnectionToCallCapabilities(int connectionCapabilities) {
238 int callCapabilities = 0;
239 for (int i = 0; i < CONNECTION_TO_CALL_CAPABILITY.length; i += 2) {
240 if ((CONNECTION_TO_CALL_CAPABILITY[i] & connectionCapabilities) ==
241 CONNECTION_TO_CALL_CAPABILITY[i]) {
242
243 callCapabilities |= CONNECTION_TO_CALL_CAPABILITY[i + 1];
244 }
245 }
246 return callCapabilities;
247 }
248
249 private static final int[] CONNECTION_TO_CALL_PROPERTIES = new int[] {
250 Connection.CAPABILITY_HIGH_DEF_AUDIO,
251 android.telecom.Call.Details.PROPERTY_HIGH_DEF_AUDIO,
252
253 Connection.CAPABILITY_WIFI,
254 android.telecom.Call.Details.PROPERTY_WIFI,
255
256 Connection.CAPABILITY_GENERIC_CONFERENCE,
257 android.telecom.Call.Details.PROPERTY_GENERIC_CONFERENCE,
258
259 Connection.CAPABILITY_SHOW_CALLBACK_NUMBER,
260 android.telecom.Call.Details.PROPERTY_EMERGENCY_CALLBACK_MODE
261 };
262
263 private static int convertConnectionToCallProperties(int connectionCapabilities) {
264 int callProperties = 0;
265 for (int i = 0; i < CONNECTION_TO_CALL_PROPERTIES.length; i += 2) {
266 if ((CONNECTION_TO_CALL_PROPERTIES[i] & connectionCapabilities) ==
267 CONNECTION_TO_CALL_PROPERTIES[i]) {
268
269 callProperties |= CONNECTION_TO_CALL_PROPERTIES[i + 1];
270 }
271 }
272 return callProperties;
273 }
274
275 /**
276 * Removes the specified capability from the set of capabilities bits and returns the new set.
277 */
278 private static int removeCapability(int capabilities, int capability) {
279 return capabilities & ~capability;
280 }
281
282 private ParcelableCallUtils() {}
283}