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;
20740989589390582f097a0f8a4a44bdab9eb0d26cHall Liuimport android.bluetooth.BluetoothHeadset;
212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport android.content.ContentResolver;
222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport android.test.suitebuilder.annotation.SmallTest;
232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.BluetoothHeadsetProxy;
252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.TelecomSystem;
262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.Timeouts;
272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.bluetooth.BluetoothDeviceManager;
282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport com.android.server.telecom.bluetooth.BluetoothRouteManager;
292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.junit.Before;
312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.junit.Test;
322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.junit.runner.RunWith;
332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.junit.runners.Parameterized;
342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport org.mockito.Mock;
352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.ArrayList;
372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.Arrays;
382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.Collection;
392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.List;
402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport java.util.Objects;
412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static com.android.server.telecom.tests.BluetoothRouteManagerTest.DEVICE1;
432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static com.android.server.telecom.tests.BluetoothRouteManagerTest.DEVICE2;
442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static com.android.server.telecom.tests.BluetoothRouteManagerTest.DEVICE3;
452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static com.android.server.telecom.tests.BluetoothRouteManagerTest.executeRoutingAction;
462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.junit.Assert.assertEquals;
472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.ArgumentMatchers.eq;
482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.ArgumentMatchers.nullable;
492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.doAnswer;
502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.never;
512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.reset;
522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.verify;
532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liuimport static org.mockito.Mockito.when;
542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu@RunWith(Parameterized.class)
562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liupublic class BluetoothRouteTransitionTests extends TelecomTestCase {
572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private enum ListenerUpdate {
58cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        DEVICE_LIST_CHANGED, ACTIVE_DEVICE_PRESENT, ACTIVE_DEVICE_GONE,
592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        AUDIO_CONNECTED, AUDIO_DISCONNECTED
602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static class BluetoothRouteTestParametersBuilder {
632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private String name;
642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private String initialBluetoothState;
652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private BluetoothDevice initialDevice;
662afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private BluetoothDevice audioOnDevice;
672afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private int messageType;
6867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        private BluetoothDevice messageDevice;
692afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private ListenerUpdate[] expectedListenerUpdates;
702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private int expectedBluetoothInteraction;
7167eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        private BluetoothDevice expectedConnectionDevice;
722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private String expectedFinalStateName;
732afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        private BluetoothDevice[] connectedDevices;
74cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        // the active device as returned by BluetoothHeadset#getActiveDevice
75cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        private BluetoothDevice activeDevice = null;
762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setName(String name) {
782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.name = name;
792afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
802afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
822afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setInitialBluetoothState(
832afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                String initialBluetoothState) {
842afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.initialBluetoothState = initialBluetoothState;
852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
882afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setInitialDevice(BluetoothDevice
892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                initialDevice) {
902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.initialDevice = initialDevice;
912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
932afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
942afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setMessageType(int messageType) {
952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.messageType = messageType;
962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
972afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
9967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        public BluetoothRouteTestParametersBuilder setMessageDevice(BluetoothDevice messageDevice) {
1002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.messageDevice = messageDevice;
1012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setExpectedListenerUpdates(
1052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                ListenerUpdate... expectedListenerUpdates) {
1062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedListenerUpdates = expectedListenerUpdates;
1072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1082afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1092afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setExpectedBluetoothInteraction(
1112afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                int expectedBluetoothInteraction) {
1122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedBluetoothInteraction = expectedBluetoothInteraction;
1132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
11667eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        public BluetoothRouteTestParametersBuilder setExpectedConnectionDevice(
11767eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                BluetoothDevice expectedConnectionDevice) {
11867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu            this.expectedConnectionDevice = expectedConnectionDevice;
1192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setExpectedFinalStateName(
1232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                String expectedFinalStateName) {
1242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedFinalStateName = expectedFinalStateName;
1252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setConnectedDevices(
1292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                BluetoothDevice... connectedDevices) {
1302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.connectedDevices = connectedDevices;
1312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParametersBuilder setAudioOnDevice(BluetoothDevice device) {
1352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.audioOnDevice = device;
1362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return this;
1372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
139cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        public BluetoothRouteTestParametersBuilder setActiveDevice(BluetoothDevice device) {
140cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu            this.activeDevice = device;
141cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu            return this;
142cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        }
143cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu
1442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParameters build() {
1452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return new BluetoothRouteTestParameters(name,
1462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    initialBluetoothState,
1472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    initialDevice,
1482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    messageType,
1492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    expectedListenerUpdates,
1502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    expectedBluetoothInteraction,
15167eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                    expectedConnectionDevice,
1522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    expectedFinalStateName,
1532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    connectedDevices,
1542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    messageDevice,
155cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                    audioOnDevice,
156cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                    activeDevice);
157cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu
1582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
1602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static class BluetoothRouteTestParameters {
1622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String name;
1632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String initialBluetoothState; // One of the state names or prefixes from BRM.
1642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothDevice initialDevice; // null if we start from AudioOff
1652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothDevice audioOnDevice; // The device (if any) that is active
1662afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public int messageType; // Any of the commands from the state machine
16767eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        public BluetoothDevice messageDevice; // The device that should be specified in the message.
1682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public ListenerUpdate[] expectedListenerUpdates; // what the listener should expect.
1692afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public int expectedBluetoothInteraction; // NONE, CONNECT, or DISCONNECT
17067eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        public BluetoothDevice expectedConnectionDevice; // Expected device to connect to.
1712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String expectedFinalStateName; // Expected name of the final state.
1722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothDevice[] connectedDevices; // array of connected devices
173cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        // the active device as returned by BluetoothHeadset#getActiveDevice
174cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        private BluetoothDevice activeDevice = null;
1752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public BluetoothRouteTestParameters(String name, String initialBluetoothState,
1772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                BluetoothDevice initialDevice, int messageType, ListenerUpdate[]
17867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                expectedListenerUpdates, int expectedBluetoothInteraction, BluetoothDevice
17967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                expectedConnectionDevice, String expectedFinalStateName,
18067eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                BluetoothDevice[] connectedDevices, BluetoothDevice messageDevice,
181cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                BluetoothDevice audioOnDevice, BluetoothDevice activeDevice) {
1822afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.name = name;
1832afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.initialBluetoothState = initialBluetoothState;
1842afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.initialDevice = initialDevice;
1852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.messageType = messageType;
1862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedListenerUpdates = expectedListenerUpdates;
1872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedBluetoothInteraction = expectedBluetoothInteraction;
18867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu            this.expectedConnectionDevice = expectedConnectionDevice;
1892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.expectedFinalStateName = expectedFinalStateName;
1902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.connectedDevices = connectedDevices;
1912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.messageDevice = messageDevice;
1922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            this.audioOnDevice = audioOnDevice;
193cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu            this.activeDevice = activeDevice;
1942afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
1952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
1962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        @Override
1972afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        public String toString() {
1982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return "BluetoothRouteTestParameters{" +
1992afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    "name='" + name + '\'' +
2002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", initialBluetoothState='" + initialBluetoothState + '\'' +
2012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", initialDevice=" + initialDevice +
2022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", messageType=" + messageType +
2032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", messageDevice='" + messageDevice + '\'' +
2042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", expectedListenerUpdate=" + expectedListenerUpdates +
2052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", expectedBluetoothInteraction=" + expectedBluetoothInteraction +
20667eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                    ", expectedConnectionDevice='" + expectedConnectionDevice + '\'' +
2072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", expectedFinalStateName='" + expectedFinalStateName + '\'' +
2082afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    ", connectedDevices=" + Arrays.toString(connectedDevices) +
209cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                    ", activeDevice='" + activeDevice + '\'' +
2102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    '}';
2112afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
2122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
2132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static final int NONE = 1;
2152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static final int CONNECT = 2;
2162afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static final int DISCONNECT = 3;
2172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static final int TEST_TIMEOUT = 1000;
2192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private final BluetoothRouteTestParameters mParams;
2212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Mock private BluetoothDeviceManager mDeviceManager;
2222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Mock private BluetoothHeadsetProxy mHeadsetProxy;
2232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Mock private Timeouts.Adapter mTimeoutsAdapter;
2242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Mock private BluetoothRouteManager.BluetoothStateListener mListener;
2252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Override
2272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Before
2282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    public void setUp() throws Exception {
2292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        super.setUp();
2302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
2312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    public BluetoothRouteTransitionTests(BluetoothRouteTestParameters params) {
2332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        mParams = params;
2342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
2352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Test
2372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @SmallTest
2382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    public void testTransitions() {
2392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        BluetoothRouteManager sm = setupStateMachine(
2402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                mParams.initialBluetoothState, mParams.initialDevice);
2412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
242cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        setupConnectedDevices(mParams.connectedDevices,
243cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                mParams.audioOnDevice, mParams.activeDevice);
244cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        sm.setActiveDeviceCacheForTesting(mParams.activeDevice);
2452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        // Go through the utility methods for these two messages
2472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        if (mParams.messageType == BluetoothRouteManager.NEW_DEVICE_CONNECTED) {
24867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu            sm.onDeviceAdded(mParams.messageDevice.getAddress());
249cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu            sm.onActiveDeviceChanged(mParams.messageDevice);
2502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        } else if (mParams.messageType == BluetoothRouteManager.LOST_DEVICE) {
25167eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu            sm.onDeviceLost(mParams.messageDevice.getAddress());
252cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu            sm.onActiveDeviceChanged(null);
2532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        } else {
25467eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu            executeRoutingAction(sm, mParams.messageType,
25567eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                    mParams.messageDevice == null ? null : mParams.messageDevice.getAddress());
2562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
2572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
2592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        assertEquals(mParams.expectedFinalStateName, sm.getCurrentState().getName());
2602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        for (ListenerUpdate lu : mParams.expectedListenerUpdates) {
2622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            switch (lu) {
2632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                case DEVICE_LIST_CHANGED:
2642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    verify(mListener).onBluetoothDeviceListChanged();
2652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
266cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                case ACTIVE_DEVICE_PRESENT:
267cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                    verify(mListener).onBluetoothActiveDevicePresent();
2682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
269cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                case ACTIVE_DEVICE_GONE:
270cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                    verify(mListener).onBluetoothActiveDeviceGone();
2712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
2722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                case AUDIO_CONNECTED:
2732afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    verify(mListener).onBluetoothAudioConnected();
2742afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
2752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                case AUDIO_DISCONNECTED:
2762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    verify(mListener).onBluetoothAudioDisconnected();
2772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    break;
2782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            }
2792afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
2802afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        switch (mParams.expectedBluetoothInteraction) {
2822afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            case NONE:
28367eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                verify(mHeadsetProxy, never()).connectAudio();
28467eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                verify(mHeadsetProxy, never()).setActiveDevice(nullable(BluetoothDevice.class));
2852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy, never()).disconnectAudio();
2862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                break;
2872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            case CONNECT:
28867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                verify(mHeadsetProxy).connectAudio();
28967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                verify(mHeadsetProxy).setActiveDevice(mParams.expectedConnectionDevice);
2902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy, never()).disconnectAudio();
2912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                break;
2922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            case DISCONNECT:
29367eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                verify(mHeadsetProxy, never()).connectAudio();
29467eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                verify(mHeadsetProxy, never()).setActiveDevice(nullable(BluetoothDevice.class));
2952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                verify(mHeadsetProxy).disconnectAudio();
2962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                break;
2972afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
2982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
2992afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        sm.getHandler().removeMessages(BluetoothRouteManager.CONNECTION_TIMEOUT);
3002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        sm.quitNow();
3012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
3022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
303cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu    private void setupConnectedDevices(BluetoothDevice[] devices,
304cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu            BluetoothDevice audioOnDevice, BluetoothDevice activeDevice) {
3052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mDeviceManager.getNumConnectedDevices()).thenReturn(devices.length);
3062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mDeviceManager.getConnectedDevices()).thenReturn(Arrays.asList(devices));
3072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mHeadsetProxy.getConnectedDevices()).thenReturn(Arrays.asList(devices));
308cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        when(mHeadsetProxy.getActiveDevice()).thenReturn(activeDevice);
309cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu        if (audioOnDevice != null) {
310740989589390582f097a0f8a4a44bdab9eb0d26cHall Liu            when(mHeadsetProxy.getAudioState(eq(audioOnDevice)))
311740989589390582f097a0f8a4a44bdab9eb0d26cHall Liu                    .thenReturn(BluetoothHeadset.STATE_AUDIO_CONNECTED);
3122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
3132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        doAnswer(invocation -> {
3142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            BluetoothDevice first = getFirstExcluding(devices,
3152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                    (String) invocation.getArguments()[0]);
3162afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            return first == null ? null : first.getAddress();
3172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }).when(mDeviceManager).getMostRecentlyConnectedDevice(nullable(String.class));
31867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        for (BluetoothDevice device : devices) {
31967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu            when(mDeviceManager.getDeviceFromAddress(device.getAddress())).thenReturn(device);
32067eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        }
3212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
3222afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private BluetoothRouteManager setupStateMachine(String initialState,
3242afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            BluetoothDevice initialDevice) {
3252afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        resetMocks();
3262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        BluetoothRouteManager sm = new BluetoothRouteManager(mContext,
3272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                new TelecomSystem.SyncRoot() { }, mDeviceManager, mTimeoutsAdapter);
3282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        sm.setListener(mListener);
3292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        sm.setInitialStateForTesting(initialState, initialDevice);
3302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
3312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        resetMocks();
3322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        return sm;
3332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
3342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private void resetMocks() {
3362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        reset(mDeviceManager, mListener, mHeadsetProxy, mTimeoutsAdapter);
3372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mDeviceManager.getHeadsetService()).thenReturn(mHeadsetProxy);
33867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        when(mHeadsetProxy.connectAudio()).thenReturn(true);
33967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu        when(mHeadsetProxy.setActiveDevice(nullable(BluetoothDevice.class))).thenReturn(true);
3402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
3412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                nullable(ContentResolver.class))).thenReturn(100000L);
3422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        when(mTimeoutsAdapter.getBluetoothPendingTimeoutMillis(
3432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                nullable(ContentResolver.class))).thenReturn(100000L);
3442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
3452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    private static BluetoothDevice getFirstExcluding(
3472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            BluetoothDevice[] devices, String excludeAddress) {
3482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        for (BluetoothDevice x : devices) {
3492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            if (!Objects.equals(excludeAddress, x.getAddress())) {
3502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                return x;
3512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu            }
3522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        }
3532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        return null;
3542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
3552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    @Parameterized.Parameters(name = "{0}")
3572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    public static Collection<BluetoothRouteTestParameters> generateTestCases() {
3582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        List<BluetoothRouteTestParameters> result = new ArrayList<>();
3592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
3602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("New device connected while audio off")
3612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
3622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(null)
3632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE1)
3642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.NEW_DEVICE_CONNECTED)
36567eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE1)
366cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedListenerUpdates(ListenerUpdate.DEVICE_LIST_CHANGED,
367cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                        ListenerUpdate.ACTIVE_DEVICE_PRESENT)
3682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
36967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setExpectedConnectionDevice(null)
3702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
3712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
3722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3732afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
374cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setName("Nonspecific connection request while audio off with BT-active device")
3752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
3762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(null)
3772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1)
378cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setActiveDevice(DEVICE1)
3792afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.CONNECT_HFP)
3802afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
3812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
382cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedConnectionDevice(DEVICE1)
3832afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
384cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                        + ":" + DEVICE1)
3852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
3862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
3872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
3882afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Connection to a device succeeds after pending")
3892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
3902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
3912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setAudioOnDevice(DEVICE2)
3922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1)
3932afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_IS_ON)
39467eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE2)
3952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
3962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
39767eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setExpectedConnectionDevice(null)
3982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
39967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                        + ":" + DEVICE2)
4002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device loses HFP audio but remains connected. No fallback.")
4042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
4052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2)
4072afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_LOST)
40867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE2)
4092afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED)
4102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
41167eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setExpectedConnectionDevice(null)
4122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
4132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4152afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
416cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setName("Device loses HFP audio but remains connected."
417cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                        + " No fallback even though other devices available.")
4182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
4192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1, DEVICE3)
4212afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_LOST)
42267eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE2)
423cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED)
424cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedBluetoothInteraction(NONE)
425cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedConnectionDevice(null)
426cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
4272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
430cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setName("Switch the device that audio is being routed to")
4312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
4322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1, DEVICE3)
4342afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.CONNECT_HFP)
43567eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE3)
4362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
4372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
43867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setExpectedConnectionDevice(DEVICE3)
4392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
44067eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                        + ":" + DEVICE3)
4412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Switch to another device before first device has connected")
4452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
4462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1, DEVICE3)
4482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.CONNECT_HFP)
44967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE3)
4502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
4512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(CONNECT)
45267eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setExpectedConnectionDevice(DEVICE3)
4532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX
45467eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                        + ":" + DEVICE3)
4552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device gets disconnected while active. No fallback.")
4592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
4602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
461cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setActiveDevice(DEVICE2)
4622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices()
4632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.LOST_DEVICE)
46467eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE2)
4652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED,
466cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                        ListenerUpdate.DEVICE_LIST_CHANGED, ListenerUpdate.ACTIVE_DEVICE_GONE)
4672afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
46867eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setExpectedConnectionDevice(null)
4692afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
4702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
473cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setName("Device gets disconnected while active."
474cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                        + " No fallback even though other devices available.")
4752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
4762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE3)
4782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.LOST_DEVICE)
47967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE2)
480cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED,
4812afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        ListenerUpdate.DEVICE_LIST_CHANGED)
482cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedBluetoothInteraction(NONE)
483cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedConnectionDevice(null)
484cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
4852afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4862afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
4872afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
4882afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Connection to DEVICE2 times out but device 1 still connected.")
4892afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
4902afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
4912afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1)
4922afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setAudioOnDevice(DEVICE1)
4932afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.CONNECTION_TIMEOUT)
4942afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
4952afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
4962afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
49767eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                        + ":" + DEVICE1)
4982afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
4992afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5002afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
5012afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("DEVICE1 somehow becomes active when DEVICE2 is still pending.")
5022afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
5032afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
5042afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE1)
5052afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setAudioOnDevice(DEVICE1)
5062afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_IS_ON)
50767eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE1)
5082afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
5092afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
5102afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
51167eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                        + ":" + DEVICE1)
5122afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5132afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5142afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
515cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setName("Device gets disconnected while pending."
516cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                        + " No fallback even though other devices available.")
5172afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
5182afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
5192afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE3)
5202afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.LOST_DEVICE)
52167eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE2)
522cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED,
5232afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        ListenerUpdate.DEVICE_LIST_CHANGED)
524cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedBluetoothInteraction(NONE)
525cc74215b6e52d550f36b929319129a5dabb4b616Hall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5262afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5272afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5282afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
5292afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Device gets disconnected while pending. No fallback.")
5302afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
5312afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
5322afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices()
5332afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.LOST_DEVICE)
53467eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE2)
5352afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED,
5362afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                        ListenerUpdate.DEVICE_LIST_CHANGED)
5372afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
5382afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5392afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5402afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5412afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
5422afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Audio routing requests HFP disconnection while a device is active")
5432afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
5442afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
5452afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE3)
5462afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.DISCONNECT_HFP)
5472afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED)
5482afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(DISCONNECT)
5492afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5502afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5512afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5522afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
5532afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Audio routing requests HFP disconnection while a device is pending")
5542afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTING_STATE_NAME_PREFIX)
5552afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(DEVICE2)
5562afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE3)
5572afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.DISCONNECT_HFP)
5582afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_DISCONNECTED)
5592afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(DISCONNECT)
5602afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5612afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5622afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5632afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        result.add(new BluetoothRouteTestParametersBuilder()
5642afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setName("Bluetooth turns itself on.")
5652afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_OFF_STATE_NAME)
5662afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setInitialDevice(null)
5672afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setConnectedDevices(DEVICE2, DEVICE3)
5682afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setMessageType(BluetoothRouteManager.HFP_IS_ON)
56967eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                .setMessageDevice(DEVICE3)
5702afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedListenerUpdates(ListenerUpdate.AUDIO_CONNECTED)
5712afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedBluetoothInteraction(NONE)
5722afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
57367eb3b08235d34f0f6411f1021808c97042ecbbcHall Liu                        + ":" + DEVICE3)
5742afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu                .build());
5752afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu
5762afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu        return result;
5772afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu    }
5782afe9027824dbe6d88fb953045e12496b0da4cbcHall Liu}
579