1 # Copyright 2019 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 """ 6 Bluetooth audio test to verify that audio connection can be established 7 and stay connected during audio. In the futuer the test can be expanded 8 to test audio quality etc. 9 """ 10 import logging 11 import time 12 13 from autotest_lib.client.common_lib import error 14 from autotest_lib.client.cros.chameleon import chameleon_audio_helper 15 from autotest_lib.client.cros.chameleon import chameleon_audio_ids 16 from autotest_lib.server.cros.audio import audio_test 17 from autotest_lib.server.cros.bluetooth import bluetooth_adapter_tests 18 from autotest_lib.server.cros.multimedia import remote_facade_factory 19 20 class bluetooth_AdapterAudioLink( 21 bluetooth_adapter_tests.BluetoothAdapterTests): 22 """ 23 Bluetooth audio test to verify that audio connection can be established 24 and stay connected during audio. In the futuer the test can be expanded 25 to test audio quality etc. 26 """ 27 version = 1 28 29 def play_audio(self, binder, factory, widget_factory, num_iterations): 30 """Test Body - playing audio and checking connection stability""" 31 with chameleon_audio_helper.bind_widgets(binder): 32 start_time = time.time() 33 dut_device = binder._link._bt_adapter 34 cham_bt_addr = binder._link._mac_address 35 logging.info('DUT Address: %s', dut_device.get_address()) 36 logging.info('Playing an audio file. num inter %d', num_iterations) 37 audio_facade = factory.create_audio_facade() 38 39 # The raw audio file is short. In order to test long time, 40 # Need to run it in iterations 41 for x in range(num_iterations): 42 is_connected = dut_device.device_is_connected(cham_bt_addr) 43 logging.info('Playback iter %d, is chameleon connected %d', 44 x, is_connected) 45 #Fail the test if the link was lost 46 if not is_connected: 47 raise error.TestNAError("Failure: BT link diconnection") 48 file_path = '/usr/local/autotest/cros/audio/fix_440_16.raw' 49 audio_facade.playback(client_path=file_path, 50 data_format={'file_type': 'raw', 51 'sample_format': 'S16_LE', 52 'channel': 2, 53 'rate': 48000}, 54 blocking=False) 55 # Playback for 5 seconds, which is shorter than the 56 # duration for the file 57 time.sleep(5) 58 audio_facade.stop_playback() 59 end_time = time.time() 60 logging.info('Running time %0.1f seconds.', end_time - start_time) 61 62 def run_once(self, host, num_iterations=12): 63 """Running Bluetooth adapter tests for basic audio link 64 65 @param host: the DUT, usually a chromebook 66 @param num_iterations: the number of rounds to execute the test 67 """ 68 self.host = host 69 self.check_chameleon(); 70 71 # Setup Bluetooth widgets and their binder, but do not yet connect. 72 audio_test.audio_test_requirement() 73 factory = remote_facade_factory.RemoteFacadeFactory( 74 host, results_dir=self.resultsdir) 75 chameleon_board = self.host.chameleon 76 if chameleon_board is None: 77 raise error.TestNAError("No chameleon device is present") 78 79 chameleon_board.setup_and_reset(self.outputdir) 80 widget_factory = chameleon_audio_helper.AudioWidgetFactory( 81 factory, host) 82 source = widget_factory.create_widget( 83 chameleon_audio_ids.CrosIds.BLUETOOTH_HEADPHONE) 84 bluetooth_widget = widget_factory.create_widget( 85 chameleon_audio_ids.PeripheralIds.BLUETOOTH_DATA_RX) 86 binder = widget_factory.create_binder( 87 source, bluetooth_widget) 88 89 # Test body 90 self.play_audio(binder, factory, widget_factory, num_iterations); 91 92 def cleanup(self): 93 return 0 94