1edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee/*
2edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * Copyright (C) 2013 The Android Open Source Project
3edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee *
4edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License");
5edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * you may not use this file except in compliance with the License.
6edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * You may obtain a copy of the License at
7edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee *
8edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee *      http://www.apache.org/licenses/LICENSE-2.0
9edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee *
10edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * Unless required by applicable law or agreed to in writing, software
11edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * distributed under the License is distributed on an "AS IS" BASIS,
12edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * See the License for the specific language governing permissions and
14edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * limitations under the License.
15edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee */
16edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnpackage com.android.server.telecom.testapps;
18edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
197a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Leeimport android.content.BroadcastReceiver;
20edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.content.ComponentName;
217a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Leeimport android.content.Context;
22edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.content.Intent;
237a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Leeimport android.content.IntentFilter;
24edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.media.MediaPlayer;
25edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.net.Uri;
26edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.os.Bundle;
27edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.os.Handler;
287a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Leeimport android.support.v4.content.LocalBroadcastManager;
297cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.Conference;
307cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.Connection;
31701dc006ac11625b55d872f1639107b028933895Andrew Leeimport android.telecom.DisconnectCause;
327cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccount;
337cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ConnectionRequest;
347cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ConnectionService;
357cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccountHandle;
367cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.TelecomManager;
377cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.VideoProfile;
38dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liuimport android.telecom.Log;
3924b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunnimport android.widget.Toast;
40edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
41edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport java.lang.String;
42edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport java.util.ArrayList;
43edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport java.util.List;
44edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport java.util.Random;
45edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
46edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee/**
47edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * Service which provides fake calls to test the ConnectionService interface.
48edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * TODO: Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
49edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee */
50edaa77a067dff2c9011653171930c052eb87aef7Yorke Leepublic class TestConnectionService extends ConnectionService {
51edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    /**
52141c4bf96b6091833d3d321a2503f6ab5aa80441Tyler Gunn     * Intent extra used to pass along the video state for a new test call.
53edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     */
54141c4bf96b6091833d3d321a2503f6ab5aa80441Tyler Gunn    public static final String EXTRA_START_VIDEO_STATE = "extra_start_video_state";
55edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
56edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public static final String EXTRA_HANDLE = "extra_handle";
57edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
58dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu    private static final String LOG_TAG = TestConnectionService.class.getSimpleName();
59edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    /**
60edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * Random number generator used to generate phone numbers.
61edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     */
62edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private Random mRandom = new Random();
63edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
64edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private final class TestConference extends Conference {
65edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
66edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        private final Connection.Listener mConnectionListener = new Connection.Listener() {
67edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            @Override
68edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            public void onDestroyed(Connection c) {
69edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                removeConnection(c);
70edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                if (getConnections().size() == 0) {
71701dc006ac11625b55d872f1639107b028933895Andrew Lee                    setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
72edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    destroy();
73edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                }
74edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
75edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        };
76edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
77edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public TestConference(Connection a, Connection b) {
78edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            super(null);
7907bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad            setConnectionCapabilities(
8007bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad                    Connection.CAPABILITY_SUPPORT_HOLD |
8107bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad                    Connection.CAPABILITY_HOLD |
8207bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad                    Connection.CAPABILITY_MUTE |
8307bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad                    Connection.CAPABILITY_MANAGE_CONFERENCE);
84edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            addConnection(a);
85edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            addConnection(b);
86edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
87edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            a.addConnectionListener(mConnectionListener);
88edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            b.addConnectionListener(mConnectionListener);
89edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
90edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            a.setConference(this);
91edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            b.setConference(this);
92edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
93edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setActive();
94edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
95edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
96edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
97edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onDisconnect() {
98edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            for (Connection c : getConnections()) {
99701dc006ac11625b55d872f1639107b028933895Andrew Lee                c.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
100edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.destroy();
101edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
102edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
103edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
104edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
105edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onSeparate(Connection connection) {
106edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (getConnections().contains(connection)) {
107edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                connection.setConference(null);
108edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                removeConnection(connection);
109edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                connection.removeConnectionListener(mConnectionListener);
110edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
111edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
112edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
113edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
114edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onHold() {
115edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            for (Connection c : getConnections()) {
116edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.setOnHold();
117edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
118edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setOnHold();
119edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
120edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
121edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
122edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onUnhold() {
123edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            for (Connection c : getConnections()) {
124edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.setActive();
125edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
126edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setActive();
127edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
128edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
129edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
130b2dfc423ce184eb2c1411725f317338d1581cd96Vinit Deshpande    final class TestConnection extends Connection {
131edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        private final boolean mIsIncoming;
132edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
133edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** Used to cleanup camera and media when done with connection. */
134edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        private TestVideoProvider mTestVideoCallProvider;
135b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        private ConnectionRequest mOriginalRequest;
136b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        private RttChatbot mRttChatbot;
137edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
1387a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee        private BroadcastReceiver mHangupReceiver = new BroadcastReceiver() {
1397a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee            @Override
1407a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee            public void onReceive(Context context, Intent intent) {
1417a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee                setDisconnected(new DisconnectCause(DisconnectCause.MISSED));
1427a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee                destroyCall(TestConnection.this);
1437a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee                destroy();
1447a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee            }
1457a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee        };
1467a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee
147817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee        private BroadcastReceiver mUpgradeRequestReceiver = new BroadcastReceiver() {
148817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee            @Override
149817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee            public void onReceive(Context context, Intent intent) {
150817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee                final int request = Integer.parseInt(intent.getData().getSchemeSpecificPart());
151817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee                final VideoProfile videoProfile = new VideoProfile(request);
152817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee                mTestVideoCallProvider.receiveSessionModifyRequest(videoProfile);
153817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee            }
154817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee        };
155817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee
156b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        private BroadcastReceiver mRttUpgradeReceiver = new BroadcastReceiver() {
157b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            @Override
158b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            public void onReceive(Context context, Intent intent) {
159b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                sendRemoteRttRequest();
160b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            }
161b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        };
162b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu
163b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        TestConnection(boolean isIncoming, ConnectionRequest request) {
164edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mIsIncoming = isIncoming;
165b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            mOriginalRequest = request;
166edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // Assume all calls are video capable.
16707bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad            int capabilities = getConnectionCapabilities();
168fd93244c8d002699942dfd45be9c7fb9f0eaa4a8Andrew Lee            capabilities |= CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL;
16928adac49563a104948ba6ab7e3f6d9ca12e552a7Yorke Lee            capabilities |= CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL;
17028adac49563a104948ba6ab7e3f6d9ca12e552a7Yorke Lee            capabilities |= CAPABILITY_CAN_UPGRADE_TO_VIDEO;
17107bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad            capabilities |= CAPABILITY_MUTE;
17207bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad            capabilities |= CAPABILITY_SUPPORT_HOLD;
17307bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad            capabilities |= CAPABILITY_HOLD;
174581dbe94f1cab2d5fda91e2a4624431c50d09976Yorke Lee            capabilities |= CAPABILITY_RESPOND_VIA_TEXT;
17507bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad            setConnectionCapabilities(capabilities);
1767a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee
177b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            int properties = getConnectionProperties();
178b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            if (mOriginalRequest.isRequestingRtt()) {
179b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                properties |= PROPERTY_IS_RTT;
180b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            }
181b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            setConnectionProperties(properties);
182b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu
1831e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            if (isIncoming) {
1841e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn                putExtra(Connection.EXTRA_ANSWERING_DROPS_FG_CALL, true);
1851e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn            }
1867a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee            LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(
1877a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee                    mHangupReceiver, new IntentFilter(TestCallActivity.ACTION_HANGUP_CALLS));
188817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee            final IntentFilter filter =
189817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee                    new IntentFilter(TestCallActivity.ACTION_SEND_UPGRADE_REQUEST);
190817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee            filter.addDataScheme("int");
191817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee            LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(
192817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee                    mUpgradeRequestReceiver, filter);
193b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu
194b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(
195b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                    mRttUpgradeReceiver,
196b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                    new IntentFilter(TestCallActivity.ACTION_REMOTE_RTT_UPGRADE));
197edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
198edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
199edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        void startOutgoing() {
200edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setDialing();
201b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            mHandler.postDelayed(() -> {
202b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                setActive();
203b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                activateCall(TestConnection.this);
204edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }, 4000);
205b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            if (mOriginalRequest.isRequestingRtt()) {
206b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                Log.i(LOG_TAG, "Is RTT call. Starting chatbot service.");
207b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                mRttChatbot = new RttChatbot(getApplicationContext(),
208b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                        mOriginalRequest.getRttTextStream());
209b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                mRttChatbot.start();
210b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            }
211edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
212edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
213edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
214edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
215edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onAbort() {
216edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroyCall(this);
217edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroy();
218edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
219edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
220edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
221edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
222edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onAnswer(int videoState) {
223edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setVideoState(videoState);
224edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            activateCall(this);
225edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setActive();
226edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            updateConferenceable();
227b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            if (mOriginalRequest.isRequestingRtt()) {
228b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                Log.i(LOG_TAG, "Is RTT call. Starting chatbot service.");
229b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                mRttChatbot = new RttChatbot(getApplicationContext(),
230b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                        mOriginalRequest.getRttTextStream());
231b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                mRttChatbot.start();
232b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            }
233edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
234edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
235edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
236edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
237edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onPlayDtmfTone(char c) {
238edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (c == '1') {
239edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                setDialing();
240edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
241edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
242edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
243edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
244edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
245edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onStopDtmfTone() { }
246edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
247edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
248edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
249edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onDisconnect() {
250701dc006ac11625b55d872f1639107b028933895Andrew Lee            setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
251edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroyCall(this);
252edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroy();
253edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
254edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
255edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
256edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
257edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onHold() {
258edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setOnHold();
259edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
260edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
261edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
262edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
263edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onReject() {
264701dc006ac11625b55d872f1639107b028933895Andrew Lee            setDisconnected(new DisconnectCause(DisconnectCause.REJECTED));
265edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroyCall(this);
266edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroy();
267edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
268edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
269edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
270edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
271edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onUnhold() {
272edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setActive();
273edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
274edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
275b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        @Override
276b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        public void onStopRtt() {
277b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            int newProperties = getConnectionProperties() & ~PROPERTY_IS_RTT;
278b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            setConnectionProperties(newProperties);
279b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            mRttChatbot.stop();
280b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            mRttChatbot = null;
281b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        }
282b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu
283b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        @Override
284b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        public void handleRttUpgradeResponse(RttTextStream rttTextStream) {
285b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            Log.i(this, "RTT request response was %s", rttTextStream == null);
286b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            if (rttTextStream != null) {
287b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                mRttChatbot = new RttChatbot(getApplicationContext(), rttTextStream);
288b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                mRttChatbot.start();
289b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                sendRttInitiationSuccess();
290b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            }
291b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        }
292b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu
293b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        @Override
294b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        public void onStartRtt(RttTextStream textStream) {
295b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            boolean doAccept = Math.random() < 0.5;
296b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            if (doAccept) {
297b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                Log.i(this, "Accepting RTT request.");
298b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                mRttChatbot = new RttChatbot(getApplicationContext(), textStream);
299b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                mRttChatbot.start();
300b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                sendRttInitiationSuccess();
301b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            } else {
302b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                sendRttInitiationFailure(RttModifyStatus.SESSION_MODIFY_REQUEST_FAIL);
303b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            }
304b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        }
305b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu
306edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void setTestVideoCallProvider(TestVideoProvider testVideoCallProvider) {
307edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mTestVideoCallProvider = testVideoCallProvider;
308edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
309edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
3107a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee        public void cleanup() {
3117a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee            LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(
3127a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee                    mHangupReceiver);
313817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee            LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(
314817090c6c6e43e13d2dbd6000c90331bfcbddaf8Yorke Lee                    mUpgradeRequestReceiver);
3157a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee        }
3167a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee
317edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /**
318edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee         * Stops playback of test videos.
319edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee         */
320edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        private void stopAndCleanupMedia() {
321edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (mTestVideoCallProvider != null) {
322edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                mTestVideoCallProvider.stopAndCleanupMedia();
323edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                mTestVideoCallProvider.stopCamera();
324edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
325edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
326edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
327edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
328edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private final List<TestConnection> mCalls = new ArrayList<>();
329edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private final Handler mHandler = new Handler();
330edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
331edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    /** Used to play an audio tone during a call. */
332edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private MediaPlayer mMediaPlayer;
333edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
334edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    @Override
335edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public boolean onUnbind(Intent intent) {
336edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        log("onUnbind");
337edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        mMediaPlayer = null;
338edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        return super.onUnbind(intent);
339edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
340edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
341edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    @Override
342edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public void onConference(Connection a, Connection b) {
343edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        addConference(new TestConference(a, b));
344edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
345edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
346edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    @Override
347edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public Connection onCreateOutgoingConnection(
348edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            PhoneAccountHandle connectionManagerAccount,
349edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            final ConnectionRequest originalRequest) {
350edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
351d1f1c60957edc72ea554e18b67d33419bddddf1bNancy Chen        final Uri handle = originalRequest.getAddress();
352d1f1c60957edc72ea554e18b67d33419bddddf1bNancy Chen        String number = originalRequest.getAddress().getSchemeSpecificPart();
353edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        log("call, number: " + number);
354edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
355edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // Crash on 555-DEAD to test call service crashing.
356edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if ("5550340".equals(number)) {
357edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            throw new RuntimeException("Goodbye, cruel world.");
358edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
359edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
360edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        Bundle extras = originalRequest.getExtras();
3617cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn        String gatewayPackage = extras.getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE);
3627cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn        Uri originalHandle = extras.getParcelable(TelecomManager.GATEWAY_ORIGINAL_ADDRESS);
363edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
36424b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn        if (extras.containsKey(TelecomManager.EXTRA_CALL_SUBJECT)) {
36524b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            String callSubject = extras.getString(TelecomManager.EXTRA_CALL_SUBJECT);
36624b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            log("Got subject: " + callSubject);
36724b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            Toast.makeText(getApplicationContext(), "Got subject :" + callSubject,
36824b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn                    Toast.LENGTH_SHORT).show();
36924b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn        }
37024b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn
371edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        log("gateway package [" + gatewayPackage + "], original handle [" +
372edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                originalHandle + "]");
373edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
374b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu        final TestConnection connection =
375b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu                new TestConnection(false /* isIncoming */, originalRequest);
376596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee        setAddress(connection, handle);
377edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
378edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // If the number starts with 555, then we handle it ourselves. If not, then we
379edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // use a remote connection service.
380edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // TODO: Have a special phone number to test the account-picker dialog flow.
381edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (number != null && number.startsWith("555")) {
382edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // Normally we would use the original request as is, but for testing purposes, we are
383edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // adding ".." to the end of the number to follow its path more easily through the logs.
384edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            final ConnectionRequest request = new ConnectionRequest(
385edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    originalRequest.getAccountHandle(),
386edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    Uri.fromParts(handle.getScheme(),
387edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    handle.getSchemeSpecificPart() + "..", ""),
388edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    originalRequest.getExtras(),
389edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    originalRequest.getVideoState());
39020afacc3ccd361c93ab80ce7c438a113b4b5183dYorke Lee            connection.setVideoState(originalRequest.getVideoState());
391e09b47b2f8b96780fc5c921785d73082cd932828Yorke Lee            addVideoProvider(connection);
392edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            addCall(connection);
393edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            connection.startOutgoing();
394edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
395edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            for (Connection c : getAllConnections()) {
396edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.setOnHold();
397edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
398edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        } else {
399edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            log("Not a test number");
400edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
401edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        return connection;
402edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
403edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
404edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    @Override
405edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public Connection onCreateIncomingConnection(
406edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            PhoneAccountHandle connectionManagerAccount,
407edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            final ConnectionRequest request) {
408edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        PhoneAccountHandle accountHandle = request.getAccountHandle();
409edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        ComponentName componentName = new ComponentName(this, TestConnectionService.class);
410edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
411edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (accountHandle != null && componentName.equals(accountHandle.getComponentName())) {
412b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            final TestConnection connection = new TestConnection(true, request);
413edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // Get the stashed intent extra that determines if this is a video call or audio call.
414edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            Bundle extras = request.getExtras();
415141c4bf96b6091833d3d321a2503f6ab5aa80441Tyler Gunn            int videoState = extras.getInt(EXTRA_START_VIDEO_STATE, VideoProfile.STATE_AUDIO_ONLY);
416edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
417edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
418edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // Use dummy number for testing incoming calls.
4195be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee            Uri address = providedHandle == null ?
420141c4bf96b6091833d3d321a2503f6ab5aa80441Tyler Gunn                    Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(
421141c4bf96b6091833d3d321a2503f6ab5aa80441Tyler Gunn                            VideoProfile.isVideo(videoState)), null)
422af28651e86d372991c05e5c32d60d07e87021936Nancy Chen                    : providedHandle;
423edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            connection.setVideoState(videoState);
42424b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn
42524b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            Bundle connectionExtras = connection.getExtras();
42624b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            if (connectionExtras == null) {
42724b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn                connectionExtras = new Bundle();
42824b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            }
42924b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn
43024b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            // Randomly choose a varying length call subject.
43124b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            int subjectFormat = mRandom.nextInt(3);
43224b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            if (subjectFormat == 0) {
43324b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn                connectionExtras.putString(Connection.EXTRA_CALL_SUBJECT,
43424b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn                        "This is a test of call subject lines. Subjects for a call can be long " +
43524b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn                                " and can go even longer.");
43624b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            } else if (subjectFormat == 1) {
43724b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn                connectionExtras.putString(Connection.EXTRA_CALL_SUBJECT,
43824b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn                        "This is a test of call subject lines.");
43924b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn            }
440dd68bc36a3278557b1c4d9183ed9e3dee077eb20Hall Liu
441961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn            connection.putExtras(connectionExtras);
44224b6d7743ea4c896afe51830b2600527f97916c9Tyler Gunn
443596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee            setAddress(connection, address);
444edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
445e09b47b2f8b96780fc5c921785d73082cd932828Yorke Lee            addVideoProvider(connection);
44620afacc3ccd361c93ab80ce7c438a113b4b5183dYorke Lee
447edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            addCall(connection);
448edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
449edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            connection.setVideoState(videoState);
450edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            return connection;
451edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        } else {
452701dc006ac11625b55d872f1639107b028933895Andrew Lee            return Connection.createFailedConnection(new DisconnectCause(DisconnectCause.ERROR,
453701dc006ac11625b55d872f1639107b028933895Andrew Lee                    "Invalid inputs: " + accountHandle + " " + componentName));
454edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
455edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
456edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
4579250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    @Override
4589250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
4599250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            final ConnectionRequest request) {
4609250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        PhoneAccountHandle accountHandle = request.getAccountHandle();
4619250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        ComponentName componentName = new ComponentName(this, TestConnectionService.class);
4629250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        if (accountHandle != null && componentName.equals(accountHandle.getComponentName())) {
463b8b5a6976b44f92494971672ca3c1e6a71974d54Hall Liu            final TestConnection connection = new TestConnection(false, request);
4649250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            final Bundle extras = request.getExtras();
4659250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            final Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
4669250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee
4679250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            Uri handle = providedHandle == null ?
4689250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee                    Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(false), null)
4699250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee                    : providedHandle;
4709250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee
4719250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            connection.setAddress(handle,  TelecomManager.PRESENTATION_ALLOWED);
4729250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            connection.setDialing();
4739250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee
4749250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            addCall(connection);
4759250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            return connection;
4769250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        } else {
4779250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            return Connection.createFailedConnection(new DisconnectCause(DisconnectCause.ERROR,
4789250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee                    "Invalid inputs: " + accountHandle + " " + componentName));
4799250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        }
4809250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    }
4819250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee
482e09b47b2f8b96780fc5c921785d73082cd932828Yorke Lee    private void addVideoProvider(TestConnection connection) {
483e09b47b2f8b96780fc5c921785d73082cd932828Yorke Lee        TestVideoProvider testVideoCallProvider =
484e09b47b2f8b96780fc5c921785d73082cd932828Yorke Lee                new TestVideoProvider(getApplicationContext(), connection);
485e09b47b2f8b96780fc5c921785d73082cd932828Yorke Lee        connection.setVideoProvider(testVideoCallProvider);
48620afacc3ccd361c93ab80ce7c438a113b4b5183dYorke Lee
487e09b47b2f8b96780fc5c921785d73082cd932828Yorke Lee        // Keep reference to original so we can clean up the media players later.
488e09b47b2f8b96780fc5c921785d73082cd932828Yorke Lee        connection.setTestVideoCallProvider(testVideoCallProvider);
48920afacc3ccd361c93ab80ce7c438a113b4b5183dYorke Lee    }
49020afacc3ccd361c93ab80ce7c438a113b4b5183dYorke Lee
491edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private void activateCall(TestConnection connection) {
492edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (mMediaPlayer == null) {
493edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer = createMediaPlayer();
494edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
495edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (!mMediaPlayer.isPlaying()) {
496edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer.start();
497edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
498edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
499edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
500edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private void destroyCall(TestConnection connection) {
5017a593fa6806014a4f391c8a0d68b23f1ca7f6f04Yorke Lee        connection.cleanup();
502edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        mCalls.remove(connection);
503edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
504edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // Ensure any playing media and camera resources are released.
505edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        connection.stopAndCleanupMedia();
506edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
507edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // Stops audio if there are no more calls.
508edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (mCalls.isEmpty() && mMediaPlayer != null && mMediaPlayer.isPlaying()) {
509edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer.stop();
510edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer.release();
511edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer = createMediaPlayer();
512edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
513edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
514edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        updateConferenceable();
515edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
516edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
517edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private void addCall(TestConnection connection) {
518edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        mCalls.add(connection);
519edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        updateConferenceable();
520edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
521edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
522edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private void updateConferenceable() {
523edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        List<Connection> freeConnections = new ArrayList<>();
524edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        freeConnections.addAll(mCalls);
525edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        for (int i = 0; i < freeConnections.size(); i++) {
526edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (freeConnections.get(i).getConference() != null) {
527edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                freeConnections.remove(i);
528edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
529edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
530edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        for (int i = 0; i < freeConnections.size(); i++) {
531edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            Connection c = freeConnections.remove(i);
532edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            c.setConferenceableConnections(freeConnections);
533edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            freeConnections.add(i, c);
534edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
535edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
536edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
537596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee    private void setAddress(Connection connection, Uri address) {
538596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee        connection.setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
539596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee        if ("5551234".equals(address.getSchemeSpecificPart())) {
540596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee            connection.setCallerDisplayName("Hello World", TelecomManager.PRESENTATION_ALLOWED);
541596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee        }
542596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee    }
543596c396ff31cc66ec6cf0d3cbc7044e69c0c8cefYorke Lee
544edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private MediaPlayer createMediaPlayer() {
545edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // Prepare the media player to play a tone when there is a call.
546edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.beep_boop);
547edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        mediaPlayer.setLooping(true);
548edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        return mediaPlayer;
549edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
550edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
551edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private static void log(String msg) {
552edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        Log.w("telecomtestcs", "[TestConnectionService] " + msg);
553edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
554edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
555edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    /**
556edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * Generates a random phone number of format 555YXXX.  Where Y will be {@code 1} if the
557edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * phone number is for a video call and {@code 0} for an audio call.  XXX is a randomly
558edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * generated phone number.
559edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     *
560edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * @param isVideo {@code True} if the call is a video call.
561edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * @return The phone number.
562edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     */
563edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private String getDummyNumber(boolean isVideo) {
564edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        int videoDigit = isVideo ? 1 : 0;
565edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        int number = mRandom.nextInt(999);
566edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        return String.format("555%s%03d", videoDigit, number);
567edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
568edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee}
569edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
570