blob: 8a228f86f8bc0dbbe6863e8f026fa4184ae97731 [file] [log] [blame] [edit]
# Copyright (c) 2014 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 os
import logging
import time
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros.a11y import a11y_test_base
from autotest_lib.client.cros.audio import cras_utils
from autotest_lib.client.cros.audio import sox_utils
class accessibility_ChromeVoxSound(a11y_test_base.a11y_test_base):
"""Check whether ChromeVox makes noise on real hardware."""
version = 1
_audio_chunk_size = 1 # Length of chunk size in seconds.
_detect_time = 40 # Max length of time to spend detecting audio in seconds.
def _detect_audio(self, name, min_time, max_time):
"""Detects whether audio was heard and returns the approximate time.
Runs for at most self._detect_time, checking each chunk for sound.
After first detecting a chunk that has audio, counts the subsequent
chunks that also do.
Finally, check whether the found audio matches the expected length.
@param name: a string representing which sound is expected.
@param min_time: the minimum allowed sound length in seconds.
@param max_time: the maximum allowed sound length in seconds.
@raises: error.TestFail if the observed behavior doesn't match
expected: either no sound or sound of bad length.
"""
count = 0
counting = False
for i in xrange(self._detect_time / self._audio_chunk_size):
rms = self._rms_of_next_audio_chunk()
if rms > 0:
logging.info('Found passing chunk: %d.', i)
if not counting:
start_time = time.time()
counting = True
count += 1
elif counting:
audio_length = time.time() - start_time
break
if not counting:
raise error.TestFail('No audio for %s was found!' % name)
logging.info('Time taken - %s: %f', name, audio_length)
if audio_length < min_time:
raise error.TestFail(
'%s audio was only %f seconds long!' % (name, audio_length))
elif audio_length > max_time:
raise error.TestFail(
'%s audio was too long: %f seconds!' % (name, audio_length))
return
def _rms_of_next_audio_chunk(self):
"""Finds the sox_stats values of the next chunk of audio."""
cras_utils.loopback(self._loopback_file, channels=1,
duration=self._audio_chunk_size)
stat_output = sox_utils.get_stat(self._loopback_file)
logging.info(stat_output)
return vars(stat_output)['rms']
def _check_chromevox_sound(self, cr):
"""Test contents.
Enable ChromeVox, navigate to a new page, and open a new tab. Check
the audio output at each point.
@param cr: the chrome.Chrome() object
"""
chromevox_start_time = time.time()
self._toggle_chromevox()
self._confirm_chromevox_state(True)
# TODO: this sound doesn't play for Telemetry user. crbug.com/590403
# Welcome ding
# self._detect_audio('enable ChromeVox ding', 1, 2)
# "ChromeVox Spoken Feedback is ready!"
self._detect_audio('welcome message', 2, 6)
chromevox_open_time = time.time() - chromevox_start_time
logging.info('ChromeVox took %f seconds to start.')
# Page navigation sound.
cr.browser.tabs[0].Navigate('chrome://version')
self._detect_audio('page navigation sound', 2, 6)
# New tab sound
tab = cr.browser.tabs.New()
self._detect_audio('new tab ding', 2, 6)
def run_once(self):
"""Entry point of this test."""
self._loopback_file = os.path.join(self.bindir, 'cras_loopback.wav')
extension_path = self._get_extension_path()
with chrome.Chrome(extension_paths=[extension_path],
is_component=False) as cr:
self._extension = cr.get_extension(extension_path)
cr.browser.tabs[0].WaitForDocumentReadyStateToBeComplete()
self._confirm_chromevox_state(False)
self._check_chromevox_sound(cr)
def _child_test_cleanup(self):
try:
os.remove(self._loopback_file)
except OSError:
pass