blob: 0ea48966f71f6047e8cc508b31414c97429e009b [file] [log] [blame]
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import os
import time
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import ui_utils
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros.audio import alsa_utils
from autotest_lib.client.cros.audio import audio_test_data
from autotest_lib.client.cros.audio import cras_utils
from autotest_lib.client.cros.graphics import graphics_utils
from autotest_lib.client.cros.input_playback import input_playback
from autotest_lib.client.cros.multimedia import facade_resource
from autotest_lib.client.cros.power import power_test
class audio_AudioPlaybackStress(power_test.power_Test):
""" Playing multiple local WAV audio files for longer duration without
crash and verifying that the audio is routing through INTERNAL SPEAKER.
"""
version = 1
_PLAYBACK_LOCATION = '/home/chronos/user/Downloads'
_FILES_APP_NAME = 'files'
# Timeout delay for clicking ui elements in seconds
_WAIT_DELAY = 3
# Play audio for 60 seconds
_PLAY_TIME = 60
# Names
_DOWNLOADS = 'Downloads'
_MY_FILES = '/^Files - My files$/i'
_FILES_WINDOW_DOWNLOADS = '/^Files - Downloads$/i'
_AUDIO_PLAYER = '/^audio player$/i'
_WAV_FILE = '/.wav/i'
_NEXT = '/^next$/i'
_PLAY = '/^play$/i'
_PAUSE = '/^pause$/i'
# Roles
_TREEE_ITEM = 'treeItem'
_WINDOW = 'window'
_LISTBOX_OPTION = 'listBoxOption'
_BUTTON = 'button'
def cleanup(self):
if len(self.audio_files) != 0:
for audio_file in self.audio_files:
audio_file.delete()
if self.ui:
logging.info(self.ui.get_name_role_list())
if not self.success:
graphics_utils.take_screenshot(os.path.join(self.debugdir),
'chrome')
if self.app:
self.app.close_app(self._FILES_APP_NAME)
if self.cr:
self.cr.close()
super(audio_AudioPlaybackStress, self).cleanup()
def generate_audio_files(self):
""" Audio files with constant sampling rates that needs to be generated """
sampling_rates = [8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000]
for sampling_rate in sampling_rates:
mono_audio_file = audio_test_data.GenerateAudioTestData(
path=os.path.join(self._PLAYBACK_LOCATION,
'audio_%s_mono_440_16.wav' %
sampling_rate),
data_format=dict(
file_type='wav', sample_format='S16_LE', channel=1,
rate=sampling_rate),
duration_secs=70,
frequencies=[440, 440],
volume_scale=1)
self.audio_files.append(mono_audio_file)
stereo_audio_file = audio_test_data.GenerateAudioTestData(
path=os.path.join(self._PLAYBACK_LOCATION,
'audio_%s_stereo_440_16.wav'
% sampling_rate),
data_format=dict(
file_type='wav', sample_format='S16_LE', channel=2,
rate=sampling_rate),
duration_secs=70,
frequencies=[440, 440],
volume_scale=1)
self.audio_files.append(stereo_audio_file)
def initialize_test(self):
self.success = False
self.cr = chrome.Chrome(autotest_ext=True, disable_default_apps=False)
self.audio_files = []
self.generate_audio_files()
self.ui = ui_utils.UI_Handler()
self.ui.start_ui_root(self.cr)
self._player = input_playback.InputPlayback()
self._player.emulate(input_type='keyboard')
self._player.find_connected_inputs()
self.app = facade_resource.Application(self.cr)
self.app.launch_app(self._FILES_APP_NAME)
def _open_my_files():
logging.info("Clicking on the My Files window")
self.ui.wait_for_ui_obj(name=self._MY_FILES, isRegex=True,
role=self._WINDOW)
self.app.click_on(self.ui, self._MY_FILES, isRegex=True,
role=self._WINDOW)
self.ui.wait_for_ui_obj(name=self._DOWNLOADS, isRegex=False,
role=self._TREEE_ITEM)
def _open_downloads_folder():
logging.info("Selecting %s folder", self._DOWNLOADS)
self.app.click_on(self.ui, self._DOWNLOADS, isRegex=False,
role=self._TREEE_ITEM)
if self.ui.did_obj_not_load(self._FILES_WINDOW_DOWNLOADS,
isRegex=True, timeout=self._WAIT_DELAY):
raise error.TestFail("Failed to open %s directory" %
self._DOWNLOADS)
def _play_wav_file():
self.app.click_on(self.ui, self._WAV_FILE, isRegex=True,
role=self._LISTBOX_OPTION)
self._player.blocking_playback_of_default_file(
input_type='keyboard', filename='keyboard_enter')
self.ui.wait_for_ui_obj(self._NEXT, isRegex=True, role=self._BUTTON)
if self.ui.did_obj_not_load(self._AUDIO_PLAYER, isRegex=True,
timeout=self._WAIT_DELAY):
raise error.TestFail("Audio Player is not opened")
self.previous_song = self.ui.doCommand_on_obj(self._AUDIO_PLAYER,
self.ui._GET_ON_SCREEN_ITEMS,
isRegex=True,
role=self._WINDOW)[0]
_open_my_files()
_open_downloads_folder()
_play_wav_file()
def run_once(self, test_duration=10):
""" Play the local audio files from eMMC for longer duration.
@param test_duration: Duration for playing local audio files in seconds.
"""
self.initialize_test()
start_time = time.time()
audio_not_changed = 0
device_name = cras_utils.get_selected_output_device_name()
device_type = cras_utils.get_selected_output_device_type()
logging.info("Avoid display blanking")
self.app.evaluate_javascript("""chrome.power.requestKeepAwake("display")""")
self.start_measurements()
while (time.time() - start_time) <= test_duration:
logging.info("Time duration: %s" % (time.time() - start_time))
if self.ui.did_obj_not_load(self._AUDIO_PLAYER, isRegex=True):
raise error.TestFail("Not on audio player")
logging.debug("Previous song is %s", self.previous_song)
if self.ui.did_obj_not_load(self._PAUSE, isRegex=True,
timeout=self._WAIT_DELAY):
raise error.TestFail("%s is not playing" % self.previous_song)
alsa_utils.check_audio_stream_at_selected_device(device_name,
device_type)
logging.debug('Playing next song')
self.ui.doDefault_on_obj(self._NEXT, isRegex=True,
role=self._BUTTON)
time.sleep(self._PLAY_TIME)
song = self.ui.doCommand_on_obj(self._AUDIO_PLAYER,
self.ui._GET_ON_SCREEN_ITEMS,
isRegex=True,
role=self._WINDOW)[0]
logging.debug("Current song is %s", song)
if self.previous_song == song:
audio_not_changed += 1
logging.info(
'audio file is not changed at %s. previous_song is %s,'
' current song is %s' % (time.time(), self.previous_song, song))
self.previous_song = song
if audio_not_changed != 0:
raise error.TestFail("%d audio(s) failed to change during execution"
% audio_not_changed)
self.success = True