TestConnectionService.java revision 7cc70b4f0ad1064a4a0dce6056ad82b205887160
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
19edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.content.ComponentName;
20edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.content.Intent;
21edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.media.MediaPlayer;
22edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.net.Uri;
23edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.os.Bundle;
24edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.os.Handler;
257cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.AudioState;
267cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.Conference;
277cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.Connection;
287cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccount;
297cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneCapabilities;
307cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ConnectionRequest;
317cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ConnectionService;
327cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccountHandle;
337cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.RemoteConnection;
347cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.StatusHints;
357cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.TelecomManager;
367cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.VideoProfile;
37edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.telephony.DisconnectCause;
38edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport android.util.Log;
39edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
407cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport com.android.server.telecom.tests.R;
41edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
42edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport java.lang.String;
43edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport java.util.ArrayList;
44edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport java.util.List;
45edaa77a067dff2c9011653171930c052eb87aef7Yorke Leeimport java.util.Random;
46edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
47edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee/**
48edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * Service which provides fake calls to test the ConnectionService interface.
49edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee * TODO: Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
50edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee */
51edaa77a067dff2c9011653171930c052eb87aef7Yorke Leepublic class TestConnectionService extends ConnectionService {
52edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    /**
53edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * Intent extra used to pass along whether a call is video or audio based on the user's choice
54edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * in the notification.
55edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     */
56edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public static final String EXTRA_IS_VIDEO_CALL = "extra_is_video_call";
57edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
58edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public static final String EXTRA_HANDLE = "extra_handle";
59edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
60edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    /**
61edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * Random number generator used to generate phone numbers.
62edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     */
63edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private Random mRandom = new Random();
64edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
65edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private final class TestConference extends Conference {
66edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
67edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        private final Connection.Listener mConnectionListener = new Connection.Listener() {
68edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            @Override
69edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            public void onDestroyed(Connection c) {
70edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                removeConnection(c);
71edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                if (getConnections().size() == 0) {
72edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    setDisconnected(DisconnectCause.NORMAL, null);
73edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    destroy();
74edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                }
75edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
76edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        };
77edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
78edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public TestConference(Connection a, Connection b) {
79edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            super(null);
80edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
81edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            addConnection(a);
82edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            addConnection(b);
83edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
84edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            a.addConnectionListener(mConnectionListener);
85edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            b.addConnectionListener(mConnectionListener);
86edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
87edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            a.setConference(this);
88edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            b.setConference(this);
89edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
90edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setActive();
91edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
92edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
93edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
94edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onDisconnect() {
95edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            for (Connection c : getConnections()) {
96edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.setDisconnected(DisconnectCause.NORMAL, null);
97edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.destroy();
98edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
99edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
100edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
101edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
102edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onSeparate(Connection connection) {
103edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (getConnections().contains(connection)) {
104edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                connection.setConference(null);
105edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                removeConnection(connection);
106edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                connection.removeConnectionListener(mConnectionListener);
107edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
108edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
109edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
110edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
111edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onHold() {
112edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            for (Connection c : getConnections()) {
113edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.setOnHold();
114edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
115edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setOnHold();
116edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
117edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
118edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
119edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onUnhold() {
120edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            for (Connection c : getConnections()) {
121edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.setActive();
122edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
123edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setActive();
124edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
125edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
126edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
127edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private final class TestConnection extends Connection {
128edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        private final boolean mIsIncoming;
129edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
130edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** Used to cleanup camera and media when done with connection. */
131edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        private TestVideoProvider mTestVideoCallProvider;
132edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
133edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        TestConnection(boolean isIncoming) {
134edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mIsIncoming = isIncoming;
135edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // Assume all calls are video capable.
136edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            int capabilities = getCallCapabilities();
137edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            capabilities |= PhoneCapabilities.SUPPORTS_VT_LOCAL;
138edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            capabilities |= PhoneCapabilities.ADD_CALL;
139edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            capabilities |= PhoneCapabilities.MUTE;
140edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            capabilities |= PhoneCapabilities.SUPPORT_HOLD;
141edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            capabilities |= PhoneCapabilities.HOLD;
142edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setCallCapabilities(capabilities);
143edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
144edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
145edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        void startOutgoing() {
146edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setDialing();
147edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mHandler.postDelayed(new Runnable() {
148edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                @Override
149edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                public void run() {
150edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    setActive();
151edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    activateCall(TestConnection.this);
152edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                }
153edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }, 4000);
154edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
155edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
156edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
157edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
158edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onAbort() {
159edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroyCall(this);
160edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroy();
161edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
162edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
163edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
164edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
165edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onAnswer(int videoState) {
166edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setVideoState(videoState);
167edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            activateCall(this);
168edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setActive();
169edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            updateConferenceable();
170edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
171edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
172edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
173edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
174edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onPlayDtmfTone(char c) {
175edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (c == '1') {
176edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                setDialing();
177edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
178edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
179edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
180edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
181edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
182edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onStopDtmfTone() { }
183edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
184edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
185edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
186edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onDisconnect() {
187edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setDisconnected(DisconnectCause.LOCAL, null);
188edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroyCall(this);
189edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroy();
190edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
191edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
192edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
193edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
194edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onHold() {
195edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setOnHold();
196edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
197edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
198edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
199edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
200edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onReject() {
201edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setDisconnected(DisconnectCause.INCOMING_REJECTED, null);
202edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroyCall(this);
203edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            destroy();
204edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
205edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
206edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /** ${inheritDoc} */
207edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
208edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void onUnhold() {
209edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            setActive();
210edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
211edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
212edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        @Override
2132d8eb3a3ef1c4d0d4b6d96392d8e0542d34a4b8cNancy Chen        public void onAudioStateChanged(AudioState state) { }
214edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
215edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        public void setTestVideoCallProvider(TestVideoProvider testVideoCallProvider) {
216edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mTestVideoCallProvider = testVideoCallProvider;
217edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
218edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
219edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        /**
220edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee         * Stops playback of test videos.
221edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee         */
222edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        private void stopAndCleanupMedia() {
223edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (mTestVideoCallProvider != null) {
224edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                mTestVideoCallProvider.stopAndCleanupMedia();
225edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                mTestVideoCallProvider.stopCamera();
226edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
227edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
228edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
229edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
230edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private final List<TestConnection> mCalls = new ArrayList<>();
231edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private final Handler mHandler = new Handler();
232edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
233edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    /** Used to play an audio tone during a call. */
234edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private MediaPlayer mMediaPlayer;
235edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
236edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    @Override
237edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public boolean onUnbind(Intent intent) {
238edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        log("onUnbind");
239edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        mMediaPlayer = null;
240edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        return super.onUnbind(intent);
241edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
242edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
243edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    @Override
244edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public void onConference(Connection a, Connection b) {
245edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        addConference(new TestConference(a, b));
246edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
247edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
248edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    @Override
249edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public Connection onCreateOutgoingConnection(
250edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            PhoneAccountHandle connectionManagerAccount,
251edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            final ConnectionRequest originalRequest) {
252edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
253d1f1c60957edc72ea554e18b67d33419bddddf1bNancy Chen        final Uri handle = originalRequest.getAddress();
254d1f1c60957edc72ea554e18b67d33419bddddf1bNancy Chen        String number = originalRequest.getAddress().getSchemeSpecificPart();
255edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        log("call, number: " + number);
256edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
257edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // Crash on 555-DEAD to test call service crashing.
258edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if ("5550340".equals(number)) {
259edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            throw new RuntimeException("Goodbye, cruel world.");
260edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
261edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
262edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        Bundle extras = originalRequest.getExtras();
2637cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn        String gatewayPackage = extras.getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE);
2647cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn        Uri originalHandle = extras.getParcelable(TelecomManager.GATEWAY_ORIGINAL_ADDRESS);
265edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
266edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        log("gateway package [" + gatewayPackage + "], original handle [" +
267edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                originalHandle + "]");
268edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
269edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        final TestConnection connection = new TestConnection(false /* isIncoming */);
270edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
271edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // If the number starts with 555, then we handle it ourselves. If not, then we
272edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // use a remote connection service.
273edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // TODO: Have a special phone number to test the account-picker dialog flow.
274edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (number != null && number.startsWith("555")) {
275edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // Normally we would use the original request as is, but for testing purposes, we are
276edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // adding ".." to the end of the number to follow its path more easily through the logs.
277edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            final ConnectionRequest request = new ConnectionRequest(
278edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    originalRequest.getAccountHandle(),
279edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    Uri.fromParts(handle.getScheme(),
280edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    handle.getSchemeSpecificPart() + "..", ""),
281edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    originalRequest.getExtras(),
282edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    originalRequest.getVideoState());
283edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
284edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            addCall(connection);
285edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            connection.startOutgoing();
286edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
287edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            for (Connection c : getAllConnections()) {
288edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                c.setOnHold();
289edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
290edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        } else {
291edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            log("Not a test number");
292edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
293edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        return connection;
294edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
295edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
296edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    @Override
297edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    public Connection onCreateIncomingConnection(
298edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            PhoneAccountHandle connectionManagerAccount,
299edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            final ConnectionRequest request) {
300edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        PhoneAccountHandle accountHandle = request.getAccountHandle();
301edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        ComponentName componentName = new ComponentName(this, TestConnectionService.class);
302edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
303edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (accountHandle != null && componentName.equals(accountHandle.getComponentName())) {
304edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            final TestConnection connection = new TestConnection(true);
305edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // Get the stashed intent extra that determines if this is a video call or audio call.
306edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            Bundle extras = request.getExtras();
307edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            boolean isVideoCall = extras.getBoolean(EXTRA_IS_VIDEO_CALL);
308edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
309edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
310edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            // Use dummy number for testing incoming calls.
3115be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee            Uri address = providedHandle == null ?
312af28651e86d372991c05e5c32d60d07e87021936Nancy Chen                    Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(isVideoCall), null)
313af28651e86d372991c05e5c32d60d07e87021936Nancy Chen                    : providedHandle;
314edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (isVideoCall) {
315edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                TestVideoProvider testVideoCallProvider =
316edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                        new TestVideoProvider(getApplicationContext());
317edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                connection.setVideoProvider(testVideoCallProvider);
318edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
319edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                // Keep reference to original so we can clean up the media players later.
320edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                connection.setTestVideoCallProvider(testVideoCallProvider);
321edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
322edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
323edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            int videoState = isVideoCall ?
324edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    VideoProfile.VideoState.BIDIRECTIONAL :
325edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    VideoProfile.VideoState.AUDIO_ONLY;
326edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            connection.setVideoState(videoState);
3277cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn            connection.setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
328edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
329edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            addCall(connection);
330edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
331edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            ConnectionRequest newRequest = new ConnectionRequest(
332edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    request.getAccountHandle(),
3335be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee                    address,
334edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    request.getExtras(),
335edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    videoState);
336edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            connection.setVideoState(videoState);
337edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            return connection;
338edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        } else {
339edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            return Connection.createFailedConnection(
340edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    DisconnectCause.NOT_VALID,
341edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                    "Invalid inputs: " + accountHandle + " " + componentName);
342edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
343edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
344edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
345edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private void activateCall(TestConnection connection) {
346edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (mMediaPlayer == null) {
347edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer = createMediaPlayer();
348edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
349edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (!mMediaPlayer.isPlaying()) {
350edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer.start();
351edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
352edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
353edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
354edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private void destroyCall(TestConnection connection) {
355edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        mCalls.remove(connection);
356edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
357edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // Ensure any playing media and camera resources are released.
358edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        connection.stopAndCleanupMedia();
359edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
360edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // Stops audio if there are no more calls.
361edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        if (mCalls.isEmpty() && mMediaPlayer != null && mMediaPlayer.isPlaying()) {
362edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer.stop();
363edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer.release();
364edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            mMediaPlayer = createMediaPlayer();
365edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
366edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
367edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        updateConferenceable();
368edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
369edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
370edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private void addCall(TestConnection connection) {
371edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        mCalls.add(connection);
372edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        updateConferenceable();
373edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
374edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
375edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private void updateConferenceable() {
376edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        List<Connection> freeConnections = new ArrayList<>();
377edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        freeConnections.addAll(mCalls);
378edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        for (int i = 0; i < freeConnections.size(); i++) {
379edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            if (freeConnections.get(i).getConference() != null) {
380edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee                freeConnections.remove(i);
381edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            }
382edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
383edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        for (int i = 0; i < freeConnections.size(); i++) {
384edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            Connection c = freeConnections.remove(i);
385edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            c.setConferenceableConnections(freeConnections);
386edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee            freeConnections.add(i, c);
387edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        }
388edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
389edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
390edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private MediaPlayer createMediaPlayer() {
391edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        // Prepare the media player to play a tone when there is a call.
392edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.beep_boop);
393edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        mediaPlayer.setLooping(true);
394edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        return mediaPlayer;
395edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
396edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
397edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private static void log(String msg) {
398edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        Log.w("telecomtestcs", "[TestConnectionService] " + msg);
399edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
400edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
401edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    /**
402edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * Generates a random phone number of format 555YXXX.  Where Y will be {@code 1} if the
403edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * phone number is for a video call and {@code 0} for an audio call.  XXX is a randomly
404edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * generated phone number.
405edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     *
406edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * @param isVideo {@code True} if the call is a video call.
407edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     * @return The phone number.
408edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee     */
409edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    private String getDummyNumber(boolean isVideo) {
410edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        int videoDigit = isVideo ? 1 : 0;
411edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        int number = mRandom.nextInt(999);
412edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee        return String.format("555%s%03d", videoDigit, number);
413edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee    }
414edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee}
415edaa77a067dff2c9011653171930c052eb87aef7Yorke Lee
416