blob: 4a2e4ac690b81cc5d96ad2ed900e9586cdac8d7d [file] [log] [blame]
# 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
from autotest_lib.client.bin import test
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros.audio import cras_utils
from autotest_lib.client.cros.audio import sox_utils
class accessibility_ChromeVoxSound(test.test):
"""Check whether ChromeVox makes noise on real hardware."""
version = 1
_audio_chunk_size = 1 # Length of chunk size in seconds.
_detect_time = 20 # Max length of time to spend detecting audio in seconds.
def _enable_ChromeVox(self):
"""Enable ChromeVox using a11y API call."""
cmd = '''
window.__result = false;
chrome.accessibilityFeatures.spokenFeedback.set({value: true});
chrome.accessibilityFeatures.spokenFeedback.get({},
function(d) {window.__result = d[\'value\'];}
);
'''
self._extension.ExecuteJavaScript(cmd)
utils.poll_for_condition(
lambda: self._extension.EvaluateJavaScript('window.__result'),
exception = error.TestError(
'Timeout waiting for ChromeVox to be enabled.'))
def _detect_audio(self):
"""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.
@return: Approximate length of time in seconds there was audio.
"""
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)
count += 1
counting = True
elif counting:
return count * self._audio_chunk_size
logging.warning('Timeout before end of audio!')
return count * self._audio_chunk_size
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 warmup(self):
self._loopback_file = os.path.join(self.bindir, 'cras_loopback.wav')
def run_once(self):
"""Entry point of this test."""
extension_path = os.path.join(os.path.dirname(__file__), 'a11y_ext')
with chrome.Chrome(extension_paths=[extension_path],
is_component=False) as cr:
# Setup ChromeVox extension
self._extension = cr.get_extension(extension_path)
# Begin actual test
logging.info('Detecting initial ChromeVox welcome sound.')
self._enable_ChromeVox()
audio_length = self._detect_audio()
if audio_length < 1:
raise error.TestError('No sound after enabling Chromevox!')
logging.info('Detecting initial ChromeVox welcome speech.')
audio_length = self._detect_audio()
if audio_length < 3:
raise error.TestError('Speech after enabling ChromeVox was <= '
'%f seconds long!' % audio_length)
logging.info('Detecting page navigation sound.')
cr.browser.tabs[0].Navigate('chrome://version')
audio_length = self._detect_audio()
if audio_length < 2:
raise error.TestError('Speech after loading a page was <= '
'%f seconds long!' % audio_length)
logging.info('Detecting new tab sound.')
tab = cr.browser.tabs.New()
audio_length = self._detect_audio()
if audio_length < 1:
raise error.TestError('No sound after opening new tab!')
def cleanup(self):
try:
os.remove(self._loopback_file)
except OSError:
pass