Home | History | Annotate | Download | only in power_AudioDetector
      1 # Copyright (c) 2012 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 logging, threading, time
      6 from autotest_lib.client.bin import test, utils
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.client.common_lib.cros import chrome
      9 from autotest_lib.client.cros import power_utils, rtc
     10 from autotest_lib.client.cros.audio import audio_helper
     11 
     12 class power_AudioDetector(test.test):
     13     """Verifies that audio playback prevents powerd from suspending."""
     14     version = 1
     15 
     16     def run_once(self, run_time_sec=60):
     17         if run_time_sec < 10:
     18             raise error.TestFail('Must run for at least 10 seconds')
     19 
     20         with chrome.Chrome():
     21             # Audio loop time should be significantly shorter than
     22             # |run_time_sec| time, so that the total playback time doesn't
     23             # exceed it by much.
     24             audio_loop_time_sec = min(10, run_time_sec / 10 + 0.5)
     25 
     26             # Set a low audio volume to avoid annoying people during tests.
     27             audio_helper.set_volume_levels(10, 100)
     28 
     29             # Start playing audio file.
     30             self._enable_audio_playback = True
     31             thread = threading.Thread(target=self._play_audio,
     32                                       args=(audio_loop_time_sec,))
     33             thread.start()
     34 
     35             # Restart powerd with timeouts for quick idle events.
     36             gap_ms = run_time_sec * 1000 / 4
     37             dim_ms = min(10000, gap_ms)
     38             off_ms = min(20000, gap_ms * 2)
     39             suspend_ms = min(30000, gap_ms * 3)
     40             prefs = { 'disable_idle_suspend'   : 0,
     41                       'ignore_external_policy' : 1,
     42                       'plugged_dim_ms'         : dim_ms,
     43                       'plugged_off_ms'         : off_ms,
     44                       'plugged_suspend_ms'     : suspend_ms,
     45                       'unplugged_dim_ms'       : dim_ms,
     46                       'unplugged_off_ms'       : off_ms,
     47                       'unplugged_suspend_ms'   : suspend_ms }
     48             self._pref_change = power_utils.PowerPrefChanger(prefs)
     49 
     50             # Set an alarm to wake up the system in case the audio detector
     51             # fails and the system suspends.
     52             alarm_time = rtc.get_seconds() + run_time_sec
     53             rtc.set_wake_alarm(alarm_time)
     54 
     55             time.sleep(run_time_sec)
     56 
     57             # Stop powerd to avoid suspending when the audio stops.
     58             utils.system_output('stop powerd')
     59 
     60             # Stop audio and wait for the audio thread to terminate.
     61             self._enable_audio_playback = False
     62             thread.join(timeout=(audio_loop_time_sec * 2))
     63             if thread.is_alive():
     64                 logging.error('Audio thread did not terminate at end of test.')
     65 
     66             # Check powerd's log to make sure that no suspend took place.
     67             powerd_log_path = '/var/log/power_manager/powerd.LATEST'
     68             log = open(powerd_log_path, 'r').read()
     69             if log.find('Starting suspend') != -1:
     70                 err_str = 'System suspended while audio was playing.'
     71                 raise error.TestFail(err_str)
     72 
     73 
     74     def cleanup(self):
     75         utils.restart_job('powerd')
     76 
     77 
     78     def _play_audio(self, loop_time):
     79         """
     80         Repeatedly plays audio until self._audio_playback_enabled == False.
     81         """
     82         # TODO(crosbug.com/33988): Allow for pauses in audio playback to
     83         # simulate delays in loading the next song.
     84         while self._enable_audio_playback:
     85             audio_helper.play_sound(duration_seconds=loop_time)
     86         logging.info('Done playing audio.')
     87