1/*
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.tests;
18
19import android.os.Bundle;
20import android.telecom.Call;
21import android.telecom.Conference;
22import android.telecom.Connection;
23import android.telecom.InCallService;
24import android.telecom.ParcelableCall;
25import android.test.suitebuilder.annotation.LargeTest;
26import android.test.suitebuilder.annotation.MediumTest;
27
28import java.util.ArrayList;
29import java.util.Arrays;
30
31/**
32 * Tests the {@link Connection} and {@link Call} extras functionality.
33 */
34public class CallExtrasTest extends TelecomSystemTest {
35
36    public final static String EXTRA_KEY_STR = "STRINGKEY";
37    public final static String EXTRA_KEY_STR2 = "BLAHTEST";
38    public final static String EXTRA_KEY_INT = "INTKEY";
39    public final static String EXTRA_KEY_BOOL = "BOOLKEY";
40    public final static String EXTRA_VALUE_STR = "socks";
41    public final static String EXTRA_VALUE2_STR = "mozzarella";
42    public final static int EXTRA_VALUE_INT = 1234;
43
44    /**
45     * Tests setting extras on the connection side and ensuring they are propagated through to
46     * the InCallService.
47     *
48     * @throws Exception
49     */
50    @MediumTest
51    public void testCsPutExtras() throws Exception {
52        // Get a call up and running.
53        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
54                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
55
56        // Communicate extras from the ConnectionService to the InCallService.
57        Bundle extras = new Bundle();
58        extras.putString(EXTRA_KEY_STR, EXTRA_VALUE_STR);
59        extras.putInt(EXTRA_KEY_INT, EXTRA_VALUE_INT);
60
61        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
62        connection.putExtras(extras);
63        mInCallServiceFixtureX.waitForUpdate();
64        assertTrue(mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(
65                EXTRA_KEY_STR));
66        assertTrue(mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(
67                EXTRA_KEY_INT));
68    }
69
70    /**
71     * Tests setting extras on the connection side and ensuring they are propagated through to
72     * the InCallService.
73     *
74     * @throws Exception
75     */
76    @MediumTest
77    public void testCsPutBooleanExtra() throws Exception {
78        // Get a call up and running.
79        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
80                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
81
82        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
83        connection.putExtra(EXTRA_KEY_BOOL, true);
84        mInCallServiceFixtureX.waitForUpdate();
85        assertTrue(mInCallServiceFixtureX.getCall(ids.mCallId).getExtras()
86                .containsKey(EXTRA_KEY_BOOL));
87        assertTrue(
88                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().getBoolean(EXTRA_KEY_BOOL));
89    }
90
91    /**
92     * Tests setting extras on the connection side and ensuring they are propagated through to
93     * the InCallService.
94     *
95     * @throws Exception
96     */
97    @MediumTest
98    public void testCsPutIntExtra() throws Exception {
99        // Get a call up and running.
100        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
101                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
102
103        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
104        connection.putExtra(EXTRA_KEY_INT, EXTRA_VALUE_INT);
105        mInCallServiceFixtureX.waitForUpdate();
106        assertTrue(
107                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_INT));
108        assertEquals(EXTRA_VALUE_INT,
109                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().getInt(EXTRA_KEY_INT));
110    }
111
112    /**
113     * Tests setting extras on the connection side and ensuring they are propagated through to
114     * the InCallService.
115     *
116     * @throws Exception
117     */
118    @MediumTest
119    public void testCsPutStringExtra() throws Exception {
120        // Get a call up and running.
121        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
122                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
123
124        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
125        connection.putExtra(EXTRA_KEY_STR, EXTRA_VALUE_STR);
126
127        mInCallServiceFixtureX.waitForUpdate();
128        assertTrue(
129                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_STR));
130        assertEquals(EXTRA_VALUE_STR,
131                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().getString(EXTRA_KEY_STR));
132    }
133
134    /**
135     * Tests remove extras on the connection side and ensuring the removal is reflected in the
136     * InCallService.
137     *
138     * @throws Exception
139     */
140    @MediumTest
141    public void testCsRemoveExtra() throws Exception {
142        // Get a call up and running."STRING"
143        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
144                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
145
146        // Add something.
147        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
148        connection.putExtra(EXTRA_KEY_STR2, EXTRA_VALUE_STR);
149        connection.putExtra(EXTRA_KEY_STR, EXTRA_VALUE_STR);
150        mInCallServiceFixtureX.waitForUpdate();
151        assertTrue(
152                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_STR));
153        assertEquals(EXTRA_VALUE_STR,
154                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().getString(EXTRA_KEY_STR));
155
156        // Take it away.
157        connection.removeExtras(new ArrayList<String>(Arrays.asList(EXTRA_KEY_STR)));
158        mInCallServiceFixtureX.waitForUpdate();
159        assertFalse(
160                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_STR));
161        assertTrue(mInCallServiceFixtureX.getCall(ids.mCallId).getExtras()
162                .containsKey(EXTRA_KEY_STR2));
163    }
164
165    /**
166     * Tests putting a new value for an existing extras key.
167     *
168     * @throws Exception
169     */
170    @MediumTest
171    public void testCsUpdateExisting() throws Exception {
172        // Get a call up and running.
173        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
174                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
175
176        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
177
178        // Communicate extras from the ConnectionService to the InCallService.
179        Bundle extras = new Bundle();
180        extras.putString(EXTRA_KEY_STR, EXTRA_VALUE_STR);
181        extras.putInt(EXTRA_KEY_INT, EXTRA_VALUE_INT);
182        connection.putExtras(extras);
183        mInCallServiceFixtureX.waitForUpdate();
184        assertTrue(
185                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_STR));
186        assertTrue(
187                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_INT));
188
189        connection.putExtra(EXTRA_KEY_STR, EXTRA_VALUE2_STR);
190        mInCallServiceFixtureX.waitForUpdate();
191        assertEquals(EXTRA_VALUE2_STR,
192                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().getString(EXTRA_KEY_STR));
193        assertTrue(
194                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_INT));
195    }
196
197    /**
198     * Tests ability of the deprecated setExtras method to detect changes to the extras bundle
199     * and merge these changes into the telecom extras.  The old setExtras worked by just replacing
200     * the entire extras bundle, so we need to ensure that we can properly handle cases where an
201     * API user has added or removed items from the extras, but still gracefully merge this into the
202     * extras maintained for the connection.
203     *
204     * @throws Exception
205     */
206    @MediumTest
207    public void testCsSetExtras() throws Exception {
208        // Get a call up and running.
209        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
210                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
211
212        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
213
214        // Set the initial bundle.
215        Bundle extras = new Bundle();
216        extras.putString(EXTRA_KEY_STR, EXTRA_VALUE_STR);
217        extras.putInt(EXTRA_KEY_INT, EXTRA_VALUE_INT);
218        connection.setExtras(extras);
219        mInCallServiceFixtureX.waitForUpdate();
220        assertTrue(
221                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_STR));
222        assertTrue(
223                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_INT));
224
225        // Modify the initial bundle to add a value and remove another.
226        extras.putString(EXTRA_KEY_STR2, EXTRA_VALUE2_STR);
227        extras.remove(EXTRA_KEY_STR);
228        connection.setExtras(extras);
229        mInCallServiceFixtureX.waitForUpdate();
230        assertFalse(
231                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_STR));
232        assertTrue(
233                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_INT));
234        assertTrue(
235                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras()
236                        .containsKey(EXTRA_KEY_STR2));
237    }
238
239    /**
240     * Tests that additions to the extras via an {@link InCallService} are propagated back down to
241     * the {@link Connection}.
242     *
243     * @throws Exception
244     */
245    @MediumTest
246    public void testICSPutExtras() throws Exception {
247        Bundle extras = new Bundle();
248        extras.putString(EXTRA_KEY_STR, EXTRA_VALUE_STR);
249        extras.putInt(EXTRA_KEY_INT, EXTRA_VALUE_INT);
250
251        // Get a call up and running.
252        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
253                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
254        mInCallServiceFixtureX.mInCallAdapter.putExtras(ids.mCallId, extras);
255        mConnectionServiceFixtureA.waitForExtras();
256
257        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
258        assertNotNull(connection);
259        Bundle connectionExtras = connection.getExtras();
260        assertTrue(connectionExtras.containsKey(EXTRA_KEY_STR));
261        assertEquals(EXTRA_VALUE_STR, extras.getString(EXTRA_KEY_STR));
262        assertTrue(connectionExtras.containsKey(EXTRA_KEY_INT));
263        assertEquals(EXTRA_VALUE_INT, extras.getInt(EXTRA_KEY_INT));
264    }
265
266    /**
267     * A bi-directional test of the extras.  Tests setting extras from both the ConnectionService
268     * and InCall side and ensuring the bundles are merged appropriately.
269     *
270     * @throws Exception
271     */
272    @LargeTest
273    public void testExtrasBidirectional() throws Exception {
274        // Get a call up and running.
275        IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
276                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
277
278        Connection connection = mConnectionServiceFixtureA.mLatestConnection;
279
280        // Set the initial bundle.
281        Bundle someExtras = new Bundle();
282        someExtras.putString(EXTRA_KEY_STR, EXTRA_VALUE_STR);
283        someExtras.putInt(EXTRA_KEY_INT, EXTRA_VALUE_INT);
284        connection.setExtras(someExtras);
285        mInCallServiceFixtureX.waitForUpdate();
286        assertTrue(
287                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_STR));
288        assertTrue(
289                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_INT));
290
291        // From the InCall side, add another key
292        Bundle someMoreExtras = new Bundle();
293        someMoreExtras.putBoolean(EXTRA_KEY_BOOL, true);
294        mInCallServiceFixtureX.mInCallAdapter.putExtras(ids.mCallId, someMoreExtras);
295        mConnectionServiceFixtureA.waitForExtras();
296        Bundle connectionExtras = connection.getExtras();
297        assertTrue(connectionExtras.containsKey(EXTRA_KEY_STR));
298        assertTrue(connectionExtras.containsKey(EXTRA_KEY_INT));
299        assertTrue(connectionExtras.containsKey(EXTRA_KEY_BOOL));
300
301        // Modify the initial bundle to add a value and remove another.
302        someExtras.putString(EXTRA_KEY_STR2, EXTRA_VALUE2_STR);
303        someExtras.remove(EXTRA_KEY_STR);
304        connection.setExtras(someExtras);
305        mInCallServiceFixtureX.waitForUpdate();
306        assertFalse(
307                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_STR));
308        assertTrue(
309                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras().containsKey(EXTRA_KEY_INT));
310        assertTrue(
311                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras()
312                        .containsKey(EXTRA_KEY_STR2));
313        assertTrue(
314                mInCallServiceFixtureX.getCall(ids.mCallId).getExtras()
315                        .containsKey(EXTRA_KEY_BOOL));
316    }
317
318    /**
319     * Similar to {@link #testCsSetExtras()}, tests to ensure the existing setExtras functionality
320     * is maintained.
321     *
322     * @throws Exception
323     */
324    @LargeTest
325    public void testConferenceSetExtras() throws Exception {
326        ParcelableCall call = makeConferenceCall();
327        String conferenceId = call.getId();
328
329        Conference conference = mConnectionServiceFixtureA.mLatestConference;
330        assertNotNull(conference);
331
332        Bundle someExtras = new Bundle();
333        someExtras.putString(EXTRA_KEY_STR, EXTRA_VALUE_STR);
334        someExtras.putInt(EXTRA_KEY_INT, EXTRA_VALUE_INT);
335        conference.setExtras(someExtras);
336
337        mInCallServiceFixtureX.waitForUpdate();
338        assertTrue(
339                mInCallServiceFixtureX.getCall(conferenceId).getExtras()
340                        .containsKey(EXTRA_KEY_STR));
341        assertTrue(
342                mInCallServiceFixtureX.getCall(conferenceId).getExtras()
343                        .containsKey(EXTRA_KEY_INT));
344
345        someExtras.putString(EXTRA_KEY_STR2, EXTRA_VALUE2_STR);
346        someExtras.remove(EXTRA_KEY_INT);
347        conference.setExtras(someExtras);
348
349        mInCallServiceFixtureX.waitForUpdate();
350        assertTrue(
351                mInCallServiceFixtureX.getCall(conferenceId).getExtras()
352                        .containsKey(EXTRA_KEY_STR));
353        assertFalse(
354                mInCallServiceFixtureX.getCall(conferenceId).getExtras()
355                        .containsKey(EXTRA_KEY_INT));
356        assertTrue(
357                mInCallServiceFixtureX.getCall(conferenceId).getExtras()
358                        .containsKey(EXTRA_KEY_STR2));
359    }
360
361    /**
362     * Tests putExtras for conferences.
363     *
364     * @throws Exception
365     */
366    @LargeTest
367    public void testConferenceExtraOperations() throws Exception {
368        ParcelableCall call = makeConferenceCall();
369        String conferenceId = call.getId();
370        Conference conference = mConnectionServiceFixtureA.mLatestConference;
371        assertNotNull(conference);
372
373        conference.putExtra(EXTRA_KEY_STR, EXTRA_VALUE_STR);
374        conference.putExtra(EXTRA_KEY_INT, EXTRA_VALUE_INT);
375        conference.putExtra(EXTRA_KEY_BOOL, true);
376        mInCallServiceFixtureX.waitForUpdate();
377
378        assertTrue(mInCallServiceFixtureX.getCall(conferenceId).getExtras()
379                .containsKey(EXTRA_KEY_STR));
380        assertEquals(EXTRA_VALUE_STR,
381                mInCallServiceFixtureX.getCall(conferenceId).getExtras().get(EXTRA_KEY_STR));
382        assertTrue(
383                mInCallServiceFixtureX.getCall(conferenceId).getExtras()
384                        .containsKey(EXTRA_KEY_INT));
385        assertEquals(EXTRA_VALUE_INT,
386                mInCallServiceFixtureX.getCall(conferenceId).getExtras().get(EXTRA_KEY_INT));
387        assertEquals(true,
388                mInCallServiceFixtureX.getCall(conferenceId).getExtras().get(EXTRA_KEY_BOOL));
389
390        conference.removeExtras(new ArrayList<String>(Arrays.asList(EXTRA_KEY_STR)));
391        mInCallServiceFixtureX.waitForUpdate();
392        assertFalse(mInCallServiceFixtureX.getCall(conferenceId).getExtras()
393                .containsKey(EXTRA_KEY_STR));
394    }
395
396    /**
397     * Tests communication of extras from an InCallService to a Conference.
398     *
399     * @throws Exception
400     */
401    @LargeTest
402    public void testConferenceICS() throws Exception {
403        ParcelableCall call = makeConferenceCall();
404        String conferenceId = call.getId();
405        Conference conference = mConnectionServiceFixtureA.mLatestConference;
406
407        Bundle someExtras = new Bundle();
408        someExtras.putString(EXTRA_KEY_STR, EXTRA_VALUE_STR);
409        mInCallServiceFixtureX.mInCallAdapter.putExtras(conferenceId, someExtras);
410        mConnectionServiceFixtureA.waitForExtras();
411
412        Bundle conferenceExtras = conference.getExtras();
413        assertTrue(conferenceExtras.containsKey(EXTRA_KEY_STR));
414
415        Bundle someMoreExtras = new Bundle();
416        someMoreExtras.putString(EXTRA_KEY_STR2, EXTRA_VALUE_STR);
417        someMoreExtras.putInt(EXTRA_KEY_INT, EXTRA_VALUE_INT);
418        someMoreExtras.putBoolean(EXTRA_KEY_BOOL, true);
419        mInCallServiceFixtureX.mInCallAdapter.putExtras(conferenceId, someMoreExtras);
420        mConnectionServiceFixtureA.waitForExtras();
421        conferenceExtras = conference.getExtras();
422        assertTrue(conferenceExtras.containsKey(EXTRA_KEY_STR));
423        assertTrue(conferenceExtras.containsKey(EXTRA_KEY_STR2));
424        assertTrue(conferenceExtras.containsKey(EXTRA_KEY_INT));
425        assertTrue(conferenceExtras.containsKey(EXTRA_KEY_BOOL));
426
427        mInCallServiceFixtureX.mInCallAdapter.removeExtras(conferenceId,
428                new ArrayList<String>(Arrays.asList(EXTRA_KEY_STR)));
429        mConnectionServiceFixtureA.waitForExtras();
430        conferenceExtras = conference.getExtras();
431        assertFalse(conferenceExtras.containsKey(EXTRA_KEY_STR));
432    }
433}
434