Home | History | Annotate | Download | only in accessibility_ChromeVoxSound
      1 # Copyright (c) 2014 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 import os
      6 import logging
      7 import time
      8 
      9 from autotest_lib.client.common_lib import error
     10 from autotest_lib.client.common_lib.cros import chrome
     11 from autotest_lib.client.cros.a11y import a11y_test_base
     12 from autotest_lib.client.cros.audio import cras_utils
     13 from autotest_lib.client.cros.audio import sox_utils
     14 
     15 
     16 class accessibility_ChromeVoxSound(a11y_test_base.a11y_test_base):
     17     """Check whether ChromeVox makes noise on real hardware."""
     18     version = 1
     19 
     20     _audio_chunk_size = 1 # Length of chunk size in seconds.
     21     _detect_time = 40 # Max length of time to spend detecting audio in seconds.
     22 
     23 
     24     def _detect_audio(self, name, min_time, max_time):
     25         """Detects whether audio was heard and returns the approximate time.
     26 
     27         Runs for at most self._detect_time, checking each chunk for sound.
     28         After first detecting a chunk that has audio, counts the subsequent
     29         chunks that also do.
     30 
     31         Finally, check whether the found audio matches the expected length.
     32 
     33         @param name: a string representing which sound is expected.
     34         @param min_time: the minimum allowed sound length in seconds.
     35         @param max_time: the maximum allowed sound length in seconds.
     36 
     37         @raises: error.TestFail if the observed behavior doesn't match
     38                  expected: either no sound or sound of bad length.
     39 
     40         """
     41         count = 0
     42         counting = False
     43 
     44         for i in xrange(self._detect_time / self._audio_chunk_size):
     45             rms = self._rms_of_next_audio_chunk()
     46             if rms > 0:
     47                 logging.info('Found passing chunk: %d.', i)
     48                 if not counting:
     49                     start_time = time.time()
     50                     counting = True
     51                 count += 1
     52             elif counting:
     53                 audio_length = time.time() - start_time
     54                 break
     55         if not counting:
     56             raise error.TestFail('No audio for %s was found!' % name)
     57 
     58         logging.info('Time taken - %s: %f', name, audio_length)
     59         if audio_length < min_time:
     60             raise error.TestFail(
     61                     '%s audio was only %f seconds long!' % (name, audio_length))
     62         elif audio_length > max_time:
     63             raise error.TestFail(
     64                     '%s audio was too long: %f seconds!' % (name, audio_length))
     65         return
     66 
     67 
     68     def _rms_of_next_audio_chunk(self):
     69         """Finds the sox_stats values of the next chunk of audio."""
     70         cras_utils.loopback(self._loopback_file, channels=1,
     71                             duration=self._audio_chunk_size)
     72         stat_output = sox_utils.get_stat(self._loopback_file)
     73         logging.info(stat_output)
     74         return vars(stat_output)['rms']
     75 
     76 
     77     def _check_chromevox_sound(self, cr):
     78         """Test contents.
     79 
     80         Enable ChromeVox, navigate to a new page, and open a new tab.  Check
     81         the audio output at each point.
     82 
     83         @param cr: the chrome.Chrome() object
     84 
     85         """
     86         chromevox_start_time = time.time()
     87         self._toggle_chromevox()
     88         self._confirm_chromevox_state(True)
     89 
     90         # TODO: this sound doesn't play for Telemetry user.  crbug.com/590403
     91         # Welcome ding
     92         # self._detect_audio('enable ChromeVox ding', 1, 2)
     93 
     94         # "ChromeVox Spoken Feedback is ready!"
     95         self._detect_audio('welcome message', 2, 6)
     96         chromevox_open_time = time.time() - chromevox_start_time
     97         logging.info('ChromeVox took %f seconds to start.')
     98 
     99         # Page navigation sound.
    100         cr.browser.tabs[0].Navigate('chrome://version')
    101         self._detect_audio('page navigation sound', 2, 6)
    102 
    103         # New tab sound
    104         tab = cr.browser.tabs.New()
    105         self._detect_audio('new tab ding', 2, 6)
    106 
    107 
    108     def run_once(self):
    109         """Entry point of this test."""
    110         self._loopback_file = os.path.join(self.bindir, 'cras_loopback.wav')
    111         extension_path = self._get_extension_path()
    112 
    113         with chrome.Chrome(extension_paths=[extension_path]) as cr:
    114             self._extension = cr.get_extension(extension_path)
    115             cr.browser.tabs[0].WaitForDocumentReadyStateToBeComplete()
    116             self._confirm_chromevox_state(False)
    117             self._check_chromevox_sound(cr)
    118 
    119 
    120     def _child_test_cleanup(self):
    121         try:
    122             os.remove(self._loopback_file)
    123         except OSError:
    124             pass
    125