1#!/usr/bin/env python
2#
3#   Copyright 2017 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of 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,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16"""
17Test pairing of an Android Device to a A&K XB10 Bluetooth speaker
18"""
19import logging
20import time
21
22from acts.controllers.relay_lib.relay import SynchronizeRelays
23from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
24
25log = logging
26
27
28class AkXB10PairingTest(BluetoothBaseTest):
29    DISCOVERY_TIME = 5
30
31    def __init__(self, controllers):
32        BluetoothBaseTest.__init__(self, controllers)
33        self.dut = self.android_devices[0]
34        # Do factory reset and then do delay for 3-seconds
35        self.dut.droid.bluetoothFactoryReset()
36        time.sleep(3)
37        self.ak_xb10_speaker = self.relay_devices[0]
38
39    def setup_test(self):
40        super(BluetoothBaseTest, self).setup_test()
41        self.ak_xb10_speaker.setup()
42        self.ak_xb10_speaker.power_on()
43        # Wait for a moment between pushing buttons
44        time.sleep(0.25)
45        self.ak_xb10_speaker.enter_pairing_mode()
46
47    def teardown_test(self):
48        super(BluetoothBaseTest, self).teardown_test()
49        self.ak_xb10_speaker.power_off()
50        self.ak_xb10_speaker.clean_up()
51
52    def _perform_classic_discovery(self, scan_time=DISCOVERY_TIME):
53        self.dut.droid.bluetoothStartDiscovery()
54        time.sleep(scan_time)
55        self.dut.droid.bluetoothCancelDiscovery()
56        return self.dut.droid.bluetoothGetDiscoveredDevices()
57
58    @BluetoothBaseTest.bt_test_wrap
59    def test_speaker_on(self):
60        """Test if the A&K XB10 speaker is powered on.
61
62        Use scanning to determine if the speaker is powered on.
63
64        Steps:
65        1. Put the speaker into pairing mode. (Hold the button)
66        2. Perform a scan on the DUT
67        3. Check the scan list for the device.
68
69        Expected Result:
70        Speaker is found.
71
72        Returns:
73          Pass if True
74          Fail if False
75
76        TAGS: ACTS_Relay
77        Priority: 1
78        """
79
80        for device in self._perform_classic_discovery():
81            if device['address'] == self.ak_xb10_speaker.mac_address:
82                self.dut.log.info("Desired device with MAC address %s found!",
83                                  self.ak_xb10_speaker.mac_address)
84                return True
85        return False
86
87    @BluetoothBaseTest.bt_test_wrap
88    def test_speaker_off(self):
89        """Test if the A&K XB10 speaker is powered off.
90
91        Use scanning to determine if the speaker is powered off.
92
93        Steps:
94        1. Power down the speaker
95        2. Put the speaker into pairing mode. (Hold the button)
96        3. Perform a scan on the DUT
97        4. Check the scan list for the device.
98
99        Expected Result:
100        Speaker is not found.
101
102        Returns:
103          Pass if True
104          Fail if False
105
106        TAGS: ACTS_Relay
107        Priority: 1
108        """
109        # Specific part of the test, turn off the speaker
110        self.ak_xb10_speaker.power_off()
111
112        device_not_found = True
113        for device in self._perform_classic_discovery():
114            if device['address'] == self.ak_xb10_speaker.mac_address:
115                self.dut.log.info(
116                    "Undesired device with MAC address %s found!",
117                    self.ak_xb10_speaker.mac_address)
118                device_not_found = False
119
120        # Set the speaker back to the normal for tear_down()
121        self.ak_xb10_speaker.power_on()
122        # Give the relay and speaker some time, before it is turned off.
123        time.sleep(5)
124        return device_not_found
125
126    @BluetoothBaseTest.bt_test_wrap
127    def test_pairing(self):
128        """Test pairing between a phone and A&K XB10 speaker.
129
130        Test the A&K XB10 speaker can be paired to phone.
131
132        Steps:
133        1. Find the MAC address of remote controller from relay config file.
134        2. Start the device paring process.
135        3. Enable remote controller in pairing mode.
136        4. Verify the remote is paired.
137
138        Expected Result:
139        Speaker is paired.
140
141        Returns:
142          Pass if True
143          Fail if False
144
145        TAGS: ACTS_Relay
146        Priority: 1
147        """
148
149        # BT scan activity
150        self._perform_classic_discovery()
151        self.dut.droid.bluetoothDiscoverAndBond(
152            self.ak_xb10_speaker.mac_address)
153
154        end_time = time.time() + 20
155        self.dut.log.info("Verifying devices are bonded")
156        while (time.time() < end_time):
157            bonded_devices = self.dut.droid.bluetoothGetBondedDevices()
158            for d in bonded_devices:
159                if d['address'] == self.ak_xb10_speaker.mac_address:
160                    self.dut.log.info("Successfully bonded to device.")
161                    self.log.info(
162                        "A&K XB10 Bonded devices:\n{}".format(bonded_devices))
163                    return True
164        # Timed out trying to bond.
165        self.dut.log.info("Failed to bond devices.")
166
167        return False
168