BluetoothRouteTransitionTests.java revision 2afe9027824dbe6d88fb953045e12496b0da4cbc
12afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu/*
22afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * Copyright (C) 2018 The Android Open Source Project
32afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu *
42afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * Licensed under the Apache License, Version 2.0 (the "License");
52afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * you may not use this file except in compliance with the License.
62afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * You may obtain a copy of the License at
72afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu *
82afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu *      http://www.apache.org/licenses/LICENSE-2.0
92afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu *
102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * Unless required by applicable law or agreed to in writing, software
112afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * distributed under the License is distributed on an "AS IS" BASIS,
122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * See the License for the specific language governing permissions and
142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu * limitations under the License
152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu */
162afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liupackage com.android.server.telecom.tests;
182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport android.bluetooth.BluetoothDevice;
202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport android.content.ContentResolver;
212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport android.test.suitebuilder.annotation.SmallTest;
222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.BluetoothHeadsetProxy;
242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.TelecomSystem;
252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.Timeouts;
262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.bluetooth.BluetoothDeviceManager;
272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.bluetooth.BluetoothRouteManager;
282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.junit.Before;
302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.junit.Test;
312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.junit.runner.RunWith;
322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.junit.runners.Parameterized;
332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.mockito.Mock;
342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.ArrayList;
362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.Arrays;
372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.Collection;
382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.List;
392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.Objects;
402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static com.android.server.telecom.tests.BluetoothRouteManagerTest.DEVICE1;
422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static com.android.server.telecom.tests.BluetoothRouteManagerTest.DEVICE2;
432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static com.android.server.telecom.tests.BluetoothRouteManagerTest.DEVICE3;
442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static com.android.server.telecom.tests.BluetoothRouteManagerTest.executeRoutingAction;
452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.junit.Assert.assertEquals;
462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.ArgumentMatchers.eq;
472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.ArgumentMatchers.nullable;
482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.doAnswer;
492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.never;
502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.reset;
512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.verify;
522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.when;
532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu@RunWith(Parameterized.class)
552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liupublic class BluetoothRouteTransitionTests extends TelecomTestCase {
562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private enum ListenerUpdate {
572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        DEVICE_LIST_CHANGED, DEVICE_AVAILABLE, DEVICE_UNAVAILABLE,
582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        AUDIO_CONNECTED, AUDIO_DISCONNECTED
592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static class BluetoothRouteTestParametersBuilder {
622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private String name;
632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private String initialBluetoothState;
642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private BluetoothDevice initialDevice;
652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private BluetoothDevice audioOnDevice;
662afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private int messageType;
672afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private String messageDevice;
682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private ListenerUpdate[] expectedListenerUpdates;
692afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private int expectedBluetoothInteraction;
702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private String expectedConnectionAddress;
712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private String expectedFinalStateName;
722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private BluetoothDevice[] connectedDevices;
732afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
742afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setName(String name) {
752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.name = name;
762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
792afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setInitialBluetoothState(
802afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                String initialBluetoothState) {
812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.initialBluetoothState = initialBluetoothState;
822afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
832afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
842afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setInitialDevice(BluetoothDevice
862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                initialDevice) {
872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.initialDevice = initialDevice;
882afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setMessageType(int messageType) {
922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.messageType = messageType;
932afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
942afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setMessageDevice(String messageDevice) {
972afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.messageDevice = messageDevice;
982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
992afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setExpectedListenerUpdates(
1022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                ListenerUpdate... expectedListenerUpdates) {
1032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedListenerUpdates = expectedListenerUpdates;
1042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setExpectedBluetoothInteraction(
1082afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                int expectedBluetoothInteraction) {
1092afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedBluetoothInteraction = expectedBluetoothInteraction;
1102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1112afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setExpectedConnectionAddress(String
1142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                expectedConnectionAddress) {
1152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedConnectionAddress = expectedConnectionAddress;
1162afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setExpectedFinalStateName(
1202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                String expectedFinalStateName) {
1212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedFinalStateName = expectedFinalStateName;
1222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setConnectedDevices(
1262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                BluetoothDevice... connectedDevices) {
1272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.connectedDevices = connectedDevices;
1282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setAudioOnDevice(BluetoothDevice device) {
1322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.audioOnDevice = device;
1332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParameters build() {
1372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return new BluetoothRouteTestParameters(name,
1382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    initialBluetoothState,
1392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    initialDevice,
1402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    messageType,
1412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    expectedListenerUpdates,
1422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    expectedBluetoothInteraction,
1432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    expectedConnectionAddress,
1442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    expectedFinalStateName,
1452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    connectedDevices,
1462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    messageDevice,
1472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    audioOnDevice);
1482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
1502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static class BluetoothRouteTestParameters {
1522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String name;
1532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String initialBluetoothState; // One of the state names or prefixes from BRM.
1542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothDevice initialDevice; // null if we start from AudioOff
1552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothDevice audioOnDevice; // The device (if any) that is active
1562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public int messageType; // Any of the commands from the state machine
1572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String messageDevice; // The device that should be specified in the message.
1582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public ListenerUpdate[] expectedListenerUpdates; // what the listener should expect.
1592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public int expectedBluetoothInteraction; // NONE, CONNECT, or DISCONNECT
1602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String expectedConnectionAddress; // Expected device to connect to.
1612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String expectedFinalStateName; // Expected name of the final state.
1622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothDevice[] connectedDevices; // array of connected devices
1632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParameters(String name, String initialBluetoothState,
1652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                BluetoothDevice initialDevice, int messageType, ListenerUpdate[]
1662afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                expectedListenerUpdates, int expectedBluetoothInteraction, String
1672afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                expectedConnectionAddress, String expectedFinalStateName,
1682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                BluetoothDevice[] connectedDevices, String messageDevice,
1692afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                BluetoothDevice audioOnDevice) {
1702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.name = name;
1712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.initialBluetoothState = initialBluetoothState;
1722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.initialDevice = initialDevice;
1732afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.messageType = messageType;
1742afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedListenerUpdates = expectedListenerUpdates;
1752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedBluetoothInteraction = expectedBluetoothInteraction;
1762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedConnectionAddress = expectedConnectionAddress;
1772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedFinalStateName = expectedFinalStateName;
1782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.connectedDevices = connectedDevices;
1792afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.messageDevice = messageDevice;
1802afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.audioOnDevice = audioOnDevice;
1812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1822afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1832afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        @Override
1842afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String toString() {
1852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return "BluetoothRouteTestParameters{" +
1862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    "name='" + name + '\'' +
1872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", initialBluetoothState='" + initialBluetoothState + '\'' +
1882afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", initialDevice=" + initialDevice +
1892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", messageType=" + messageType +
1902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", messageDevice='" + messageDevice + '\'' +
1912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", expectedListenerUpdate=" + expectedListenerUpdates +
1922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", expectedBluetoothInteraction=" + expectedBluetoothInteraction +
1932afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", expectedConnectionAddress='" + expectedConnectionAddress + '\'' +
1942afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", expectedFinalStateName='" + expectedFinalStateName + '\'' +
1952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", connectedDevices=" + Arrays.toString(connectedDevices) +
1962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    '}';
1972afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
1992afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static final int NONE = 1;
2012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static final int CONNECT = 2;
2022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static final int DISCONNECT = 3;
2032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static final int TEST_TIMEOUT = 1000;
2052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private final BluetoothRouteTestParameters mParams;
2072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Mock private BluetoothDeviceManager mDeviceManager;
2082afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Mock private BluetoothHeadsetProxy mHeadsetProxy;
2092afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Mock private Timeouts.Adapter mTimeoutsAdapter;
2102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Mock private BluetoothRouteManager.BluetoothStateListener mListener;
2112afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Override
2132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Before
2142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    public void setUp() throws Exception {
2152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        super.setUp();
2162afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
2172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    public BluetoothRouteTransitionTests(BluetoothRouteTestParameters params) {
2192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        mParams = params;
2202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
2212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Test
2232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @SmallTest
2242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    public void testTransitions() {
2252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        BluetoothRouteManager sm = setupStateMachine(
2262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                mParams.initialBluetoothState, mParams.initialDevice);
2272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        setupConnectedDevices(mParams.connectedDevices, mParams.audioOnDevice);
2292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        // Go through the utility methods for these two messages
2312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        if (mParams.messageType == BluetoothRouteManager.NEW_DEVICE_CONNECTED) {
2322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            sm.onDeviceAdded(mParams.messageDevice);
2332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        } else if (mParams.messageType == BluetoothRouteManager.LOST_DEVICE) {
2342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            sm.onDeviceLost(mParams.messageDevice);
2352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        } else {
2362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            executeRoutingAction(sm, mParams.messageType, mParams.messageDevice);
2372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
2382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
2402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        assertEquals(mParams.expectedFinalStateName, sm.getCurrentState().getName());
2412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        for (ListenerUpdate lu : mParams.expectedListenerUpdates) {
2432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            switch (lu) {
2442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                case DEVICE_LIST_CHANGED:
2452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    verify(mListener).onBluetoothDeviceListChanged();
2462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
2472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                case DEVICE_AVAILABLE:
2482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    verify(mListener).onBluetoothDeviceAvailable();
2492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
2502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                case DEVICE_UNAVAILABLE:
2512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    verify(mListener).onBluetoothDeviceUnavailable();
2522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
2532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                case AUDIO_CONNECTED:
2542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    verify(mListener).onBluetoothAudioConnected();
2552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
2562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                case AUDIO_DISCONNECTED:
2572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    verify(mListener).onBluetoothAudioDisconnected();
2582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
2592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            }
2602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
2612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        switch (mParams.expectedBluetoothInteraction) {
2632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            case NONE:
2642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy, never()).connectAudio(nullable(String.class));
2652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy, never()).disconnectAudio();
2662afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                break;
2672afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            case CONNECT:
2682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy).connectAudio(mParams.expectedConnectionAddress);
2692afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy, never()).disconnectAudio();
2702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                break;
2712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            case DISCONNECT:
2722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy, never()).connectAudio(nullable(String.class));
2732afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy).disconnectAudio();
2742afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                break;
2752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
2762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        sm.getHandler().removeMessages(BluetoothRouteManager.CONNECTION_TIMEOUT);
2782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        sm.quitNow();
2792afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
2802afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private void setupConnectedDevices(BluetoothDevice[] devices, BluetoothDevice activeDevice) {
2822afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mDeviceManager.getNumConnectedDevices()).thenReturn(devices.length);
2832afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mDeviceManager.getConnectedDevices()).thenReturn(Arrays.asList(devices));
2842afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mHeadsetProxy.getConnectedDevices()).thenReturn(Arrays.asList(devices));
2852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        if (activeDevice != null) {
2862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            when(mHeadsetProxy.isAudioConnected(eq(activeDevice))).thenReturn(true);
2872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
2882afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        doAnswer(invocation -> {
2892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            BluetoothDevice first = getFirstExcluding(devices,
2902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    (String) invocation.getArguments()[0]);
2912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return first == null ? null : first.getAddress();
2922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }).when(mDeviceManager).getMostRecentlyConnectedDevice(nullable(String.class));
2932afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
2942afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private BluetoothRouteManager setupStateMachine(String initialState,
2962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            BluetoothDevice initialDevice) {
2972afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        resetMocks();
2982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        BluetoothRouteManager sm = new BluetoothRouteManager(mContext,
2992afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                new TelecomSystem.SyncRoot() { }, mDeviceManager, mTimeoutsAdapter);
3002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        sm.setListener(mListener);
3012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        sm.setInitialStateForTesting(initialState, initialDevice);
3022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
3032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        resetMocks();
3042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        return sm;
3052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
3062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private void resetMocks() {
3082afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        reset(mDeviceManager, mListener, mHeadsetProxy, mTimeoutsAdapter);
3092afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mDeviceManager.getHeadsetService()).thenReturn(mHeadsetProxy);
3102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mHeadsetProxy.connectAudio(nullable(String.class))).thenReturn(true);
3112afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
3122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                nullable(ContentResolver.class))).thenReturn(100000L);
3132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mTimeoutsAdapter.getBluetoothPendingTimeoutMillis(
3142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                nullable(ContentResolver.class))).thenReturn(100000L);
3152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
3162afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static BluetoothDevice getFirstExcluding(
3182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            BluetoothDevice[] devices, String excludeAddress) {
3192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        for (BluetoothDevice x : devices) {
3202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            if (!Objects.equals(excludeAddress, x.getAddress())) {
3212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                return x;
3222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            }
3232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
3242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        return null;
3252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
3262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Parameterized.Parameters(name = "{0}")
3282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    public static Collection<BluetoothRouteTestParameters> generateTestCases() {
3292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        List<BluetoothRouteTestParameters> result = new ArrayList<>();
3302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
3312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("New device connected while audio off")
3322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
3332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(null)
3342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE1)
3352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.NEW_DEVICE_CONNECTED)
3362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE1.getAddress())
3372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.DEVICE_AVAILABLE)
3382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
3392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(null)
3402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
3412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
3422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
3442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Nonspecific connection request while audio off.")
3452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
3462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(null)
3472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1)
3482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.CONNECT_HFP)
3492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
3502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
3512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(DEVICE2.getAddress())
3522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
3532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE2.getAddress())
3542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
3552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
3572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Connection to a device succeeds after pending")
3582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
3592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
3602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setAudioOnDevice(DEVICE2)
3612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1)
3622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_IS_ON)
3632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE2.getAddress())
3642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
3652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
3662afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(null)
3672afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
3682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE2.getAddress())
3692afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
3702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
3722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device loses HFP audio but remains connected. No fallback.")
3732afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
3742afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
3752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2)
3762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_LOST)
3772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE2.getAddress())
3782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED)
3792afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
3802afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(null)
3812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
3822afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
3832afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3842afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
3852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device loses HFP audio but remains connected. Fallback.")
3862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
3872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
3882afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1, DEVICE3)
3892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_LOST)
3902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE2.getAddress())
3912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
3922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
3932afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(DEVICE1.getAddress())
3942afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
3952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE1.getAddress())
3962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
3972afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
3992afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Switch active devices")
4002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
4012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1, DEVICE3)
4032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.CONNECT_HFP)
4042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE3.getAddress())
4052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
4062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
4072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(DEVICE3.getAddress())
4082afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
4092afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE3.getAddress())
4102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4112afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Switch to another device before first device has connected")
4142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
4152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4162afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1, DEVICE3)
4172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.CONNECT_HFP)
4182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE3.getAddress())
4192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
4202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
4212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(DEVICE3.getAddress())
4222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
4232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE3.getAddress())
4242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device gets disconnected while active. No fallback.")
4282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
4292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices()
4312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.LOST_DEVICE)
4322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE2.getAddress())
4332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED,
4342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        ListenerUpdate.DEVICE_LIST_CHANGED, ListenerUpdate.DEVICE_UNAVAILABLE)
4352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
4362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(null)
4372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
4382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device gets disconnected while active. Fallback.")
4422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
4432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE3)
4452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.LOST_DEVICE)
4462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE2.getAddress())
4472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED,
4482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        ListenerUpdate.DEVICE_LIST_CHANGED)
4492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
4502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(DEVICE3.getAddress())
4512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
4522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE3.getAddress())
4532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Connection to DEVICE2 times out but device 1 still connected.")
4572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
4582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1)
4602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setAudioOnDevice(DEVICE1)
4612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.CONNECTION_TIMEOUT)
4622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
4632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
4642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
4652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE1.getAddress())
4662afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4672afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4692afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("DEVICE1 somehow becomes active when DEVICE2 is still pending.")
4702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
4712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1)
4732afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setAudioOnDevice(DEVICE1)
4742afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_IS_ON)
4752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE1.getAddress())
4762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
4772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
4782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
4792afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE1.getAddress())
4802afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4822afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4832afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device gets disconnected while pending. Fallback.")
4842afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
4852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE3)
4872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.LOST_DEVICE)
4882afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE2.getAddress())
4892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED,
4902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        ListenerUpdate.DEVICE_LIST_CHANGED)
4912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
4922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedConnectionAddress(DEVICE3.getAddress())
4932afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
4942afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE3.getAddress())
4952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4972afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device gets disconnected while pending. No fallback.")
4992afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
5002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
5012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices()
5022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.LOST_DEVICE)
5032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE2.getAddress())
5042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED,
5052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        ListenerUpdate.DEVICE_LIST_CHANGED)
5062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
5072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5082afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5092afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
5112afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Audio routing requests HFP disconnection while a device is active")
5122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
5132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
5142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE3)
5152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.DISCONNECT_HFP)
5162afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED)
5172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(DISCONNECT)
5182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
5222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Audio routing requests HFP disconnection while a device is pending")
5232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
5242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
5252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE3)
5262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.DISCONNECT_HFP)
5272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED)
5282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(DISCONNECT)
5292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
5332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Bluetooth turns itself on.")
5342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(null)
5362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE3)
5372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_IS_ON)
5382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageDevice(DEVICE3.getAddress())
5392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
5402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
5412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
5422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        + ":" + DEVICE3.getAddress())
5432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        return result;
5462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
5472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu}
548