1#!/usr/bin/env python3
2#
3# Copyright (C) 2016 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16"""
17Test script to test connect and disconnect sequence between two devices which can run
18SL4A. The script does the following:
19  Setup:
20    Clear up the bonded devices on both bluetooth adapters and bond the DUTs to each other.
21  Test (NUM_TEST_RUNS times):
22    1. Connect A2dpSink and HeadsetClient
23      1.1. Check that devices are connected.
24    2. Disconnect A2dpSink and HeadsetClient
25      2.1 Check that devices are disconnected.
26"""
27
28import time
29
30from acts.test_decorators import test_tracker_info
31from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
32from acts.base_test import BaseTestClass
33from acts.test_utils.bt import bt_test_utils
34from acts.test_utils.bt import BtEnum
35from acts import asserts
36
37
38class BtCarPairedConnectDisconnectTest(BluetoothBaseTest):
39    def setup_class(self):
40        self.car = self.android_devices[0]
41        self.ph = self.android_devices[1]
42        self.car_bt_addr = self.car.droid.bluetoothGetLocalAddress()
43        self.ph_bt_addr = self.ph.droid.bluetoothGetLocalAddress()
44
45        bt_test_utils.setup_multiple_devices_for_bt_test([self.car, self.ph])
46
47        # Pair the devices.
48        # This call may block until some specified timeout in bt_test_utils.py.
49        result = bt_test_utils.pair_pri_to_sec(
50            self.car, self.ph, auto_confirm=False)
51
52        asserts.assert_true(result, "pair_pri_to_sec returned false.")
53
54        # Check for successful setup of test.
55        devices = self.car.droid.bluetoothGetBondedDevices()
56        asserts.assert_equal(
57            len(devices), 1,
58            "pair_pri_to_sec succeeded but no bonded devices.")
59
60    @test_tracker_info(uuid='b0babf3b-8049-4b64-9125-408efb1bbcd2')
61    @BluetoothBaseTest.bt_test_wrap
62    def test_pairing(self):
63        """
64        Tests if we can connect two devices over A2dp and then disconnect
65
66        Precondition:
67        1. Devices are paired.
68
69        Steps:
70        1. Set the priority to OFF for all profiles.
71        2. Initiate connection over A2dp Sink client profile.
72
73        Returns:
74          Pass if True
75          Fail if False
76
77        """
78        # Set the priority to OFF for all profiles.
79        self.car.droid.bluetoothHfpClientSetPriority(
80            self.ph.droid.bluetoothGetLocalAddress(),
81            BtEnum.BluetoothPriorityLevel.PRIORITY_OFF.value)
82        self.ph.droid.bluetoothHspSetPriority(
83            self.car.droid.bluetoothGetLocalAddress(),
84            BtEnum.BluetoothPriorityLevel.PRIORITY_OFF.value)
85        addr = self.ph.droid.bluetoothGetLocalAddress()
86        if not bt_test_utils.connect_pri_to_sec(
87                self.car, self.ph,
88                set([BtEnum.BluetoothProfile.A2DP_SINK.value])):
89            if not bt_test_utils.is_a2dp_snk_device_connected(self.car, addr):
90                return False
91        return True
92
93    @test_tracker_info(uuid='a44f13e2-c012-4292-8dd5-9f32a023e297')
94    @BluetoothBaseTest.bt_test_wrap
95    def test_connect_disconnect_paired(self):
96        """
97        Tests if we can connect two devices over Headset, A2dp and then disconnect them with success
98
99        Precondition:
100        1. Devices are paired.
101
102        Steps:
103        1. Initiate connection over A2dp Sink and Headset client profiles.
104        2. Check if the connection succeeded.
105
106        Returns:
107          Pass if True
108          Fail if False
109
110        Priority: 0
111        """
112
113        NUM_TEST_RUNS = 2
114        failure = 0
115        addr = self.ph.droid.bluetoothGetLocalAddress()
116        for i in range(NUM_TEST_RUNS):
117            self.log.info("Running test [" + str(i) + "/" + str(NUM_TEST_RUNS)
118                          + "]")
119            success = bt_test_utils.connect_pri_to_sec(
120                self.car, self.ph,
121                set([
122                    BtEnum.BluetoothProfile.HEADSET_CLIENT.value,
123                    BtEnum.BluetoothProfile.A2DP_SINK.value
124                ]))
125
126            # Check if we got connected.
127            if not success:
128                self.car.log.info("Not all profiles connected.")
129                if (bt_test_utils.is_hfp_client_device_connected(self.car,
130                                                                 addr) and
131                        bt_test_utils.is_a2dp_snk_device_connected(self.car,
132                                                                   addr)):
133                    self.car.log.info(
134                        "HFP Client or A2DP SRC connected successfully.")
135                else:
136                    failure = failure + 1
137                continue
138
139            # Disconnect the devices.
140            success = bt_test_utils.disconnect_pri_from_sec(
141                self.car, self.ph, [
142                    BtEnum.BluetoothProfile.HEADSET_CLIENT.value,
143                    BtEnum.BluetoothProfile.A2DP_SINK.value
144                ])
145
146            if success is False:
147                self.car.log.info("Disconnect failed.")
148                if (bt_test_utils.is_hfp_client_device_connected(self.car,
149                                                                 addr) or
150                        bt_test_utils.is_a2dp_snk_device_connected(self.car,
151                                                                   addr)):
152                    self.car.log.info(
153                        "HFP Client or A2DP SRC failed to disconnect.")
154                    failure = failure + 1
155                continue
156
157        self.log.info("Failure {} total tests {}".format(failure,
158                                                         NUM_TEST_RUNS))
159        if failure > 0:
160            return False
161        return True
162