Index: client/site_tests/factory_Audio/factory_Audio.py |
diff --git a/client/site_tests/factory_Audio/factory_Audio.py b/client/site_tests/factory_Audio/factory_Audio.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..617ef4373db226c98b3eb5b5a3316140b52c60f0 |
--- /dev/null |
+++ b/client/site_tests/factory_Audio/factory_Audio.py |
@@ -0,0 +1,251 @@ |
+# -*- coding: utf-8 -*- |
+# Copyright (c) 2010 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. |
+ |
+ |
+# DESCRIPTION : |
+# |
+# This is a factory test to test the audio. |
+# UI based heavily on factory_Display |
+ |
+ |
+import gtk |
+import logging |
+import os |
+import re |
+import sys |
+ |
+from autotest_lib.client.bin import factory |
+from autotest_lib.client.bin import factory_ui_lib as ful |
+from autotest_lib.client.bin import test |
+from autotest_lib.client.common_lib import error, utils |
+ |
+ |
+_LABEL_BIG_SIZE = (280, 60) |
+_LABEL_STATUS_SIZE = (140, 30) |
+_LABEL_START_STR = 'hit SPACE to start each audio test\n' +\ |
+ '按空白鍵開始各項聲音測試\n\n' |
+_LABEL_RESPONSE_STR = ful.USER_PASS_FAIL_SELECT_STR + '\n' |
+_SAMPLE_LIST = ['Headset Audio Test', 'Built-in Audio Test'] |
+_VERBOSE = False |
+ |
+ |
+# FIXME: tbroch : refactor from factory_ui -> factory_ui_lib.py |
+_SEP_COLOR = gtk.gdk.color_parse('grey50') |
+def make_vsep(width=1): |
+ frame = gtk.EventBox() |
+ frame.set_size_request(width, -1) |
+ frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR) |
+ return frame |
+ |
+def make_hsep(width=1): |
+ frame = gtk.EventBox() |
+ frame.set_size_request(-1, width) |
+ frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR) |
+ return frame |
+ |
+ |
+class factory_Audio(test.test): |
+ version = 1 |
+ |
+ |
+ def audio_subtest_widget(self, name): |
+ window = gtk.Window(gtk.WINDOW_TOPLEVEL) |
+ screen = window.get_screen() |
+ screen_size = (screen.get_width(), screen.get_height()) |
+ window.set_size_request(*self._test_widget_size) |
+ |
+ vb = gtk.VBox() |
+ ebh = gtk.EventBox() |
+ ebh.modify_bg(gtk.STATE_NORMAL, ful.LABEL_COLORS[ful.ACTIVE]) |
+ ebh.add(ful.make_label(name, size=_LABEL_BIG_SIZE, |
+ fg=ful.BLACK)) |
+ vb.pack_start(ebh) |
+ vb.pack_start(make_vsep(3), False, False) |
+ if re.search('Headset', name): |
+ lab_str = 'Connect headset to device\n將耳機接上音源孔' |
+ else: |
+ lab_str = 'Remove headset from device\n將耳機移開音源孔' |
+ vb.pack_start(ful.make_label(lab_str, fg=ful.WHITE)) |
+ vb.pack_start(make_vsep(3), False, False) |
+ vb.pack_start(ful.make_label(\ |
+ 'Press & hold \'r\' to record\n壓住 \'r\' 鍵開始錄音\n' + \ |
+ '[Playback will follow]\n[之後會重播錄到的聲音]\n\n' + \ |
+ 'Press & hold \'p\' to play sample\n' + \ |
+ '壓住 \'p\' 鍵以播放範例')) |
+ vb.pack_start(make_vsep(3), False, False) |
+ vb.pack_start(ful.make_label(ful.USER_PASS_FAIL_SELECT_STR, |
+ fg=ful.WHITE)) |
+ |
+ # need event box to effect bg color |
+ eb = gtk.EventBox() |
+ eb.modify_bg(gtk.STATE_NORMAL, ful.BLACK) |
+ eb.add(vb) |
+ window.add(eb) |
+ window.show_all() |
+ self._fs_window = window |
+ |
+ def close_bgjob(self, sample_name): |
+ job = self._job |
+ if job: |
+ utils.nuke_subprocess(job.sp) |
+ utils.join_bg_jobs([job], timeout=1) |
+ result = job.result |
+ if _VERBOSE and (result.stdout or result.stderr): |
+ raise error.CmdError( |
+ sample_name, result, |
+ 'stdout: %s\nstderr: %s' % (result.stdout, result.stderr)) |
+ self._job = None |
+ |
+ def goto_next_sample(self): |
+ if not self._sample_queue: |
+ gtk.main_quit() |
+ return |
+ self._current_sample = self._sample_queue.pop() |
+ name = self._current_sample |
+ self._status_map[name] = ful.ACTIVE |
+ |
+ def cleanup_sample(self): |
+ factory.log('Inside cleanup_sample') |
+ self._fs_window.destroy() |
+ self._fs_window = None |
+ self.goto_next_sample() |
+ |
+ def key_press_callback(self, widget, event): |
+ name = self._current_sample |
+ if event.keyval == gtk.keysyms.space and not self._fs_window: |
+ # start the subtest |
+ self.audio_subtest_widget(name) |
+ else: |
+ self.close_bgjob(name) |
+ cmd = None |
+ if event.keyval == ord('r'): |
+ # record via mic |
+ if os.path.isfile('rec.wav'): |
+ os.unlink('rec.wav') |
+ cmd = 'arecord -f dat -t wav rec.wav' |
+ elif event.keyval == ord('p'): |
+ # playback canned audio |
+ cmd = 'aplay %s' % self._sample |
+ if cmd: |
+ self._job = utils.BgJob(cmd, stderr_level=logging.DEBUG) |
+ factory.log("cmd: " + cmd) |
+ self._test_widget.queue_draw() |
+ return True |
+ |
+ def key_release_callback(self, widget, event): |
+ name = self._current_sample |
+ if event.keyval == gtk.keysyms.Tab: |
+ self._status_map[name] = ful.FAILED |
+ self.cleanup_sample() |
+ elif event.keyval == gtk.keysyms.Return: |
+ self._status_map[name] = ful.PASSED |
+ self.cleanup_sample() |
+ elif event.keyval == ord('Q'): |
+ gtk.main_quit() |
+ elif event.keyval == ord('r'): |
+ self.close_bgjob(name) |
+ cmd = 'aplay rec.wav' |
+ self._job = utils.BgJob(cmd, stderr_level=logging.DEBUG) |
+ factory.log("cmd: " + cmd) |
+ elif event.keyval == ord('p'): |
+ self.close_bgjob(name) |
+ else: |
+ self._ft_state.exit_on_trigger(event) |
+ |
+ self._test_widget.queue_draw() |
+ return True |
+ |
+ def label_status_expose(self, widget, event, name=None): |
+ status = self._status_map[name] |
+ widget.set_text(status) |
+ widget.modify_fg(gtk.STATE_NORMAL, ful.LABEL_COLORS[status]) |
+ |
+ def make_sample_label_box(self, name): |
+ eb = gtk.EventBox() |
+ eb.modify_bg(gtk.STATE_NORMAL, ful.BLACK) |
+ label_status = ful.make_label(ful.UNTESTED, size=_LABEL_STATUS_SIZE, |
+ alignment=(0, 0.5), |
+ fg=ful.LABEL_COLORS['UNTESTED']) |
+ expose_cb = lambda *x: self.label_status_expose(*x, **{'name':name}) |
+ label_status.connect('expose_event', expose_cb) |
+ label_en = ful.make_label(name, alignment=(1,0.5)) |
+ label_sep = ful.make_label(' : ', alignment=(0.5, 0.5)) |
+ hbox = gtk.HBox() |
+ hbox.pack_end(label_status, False, False) |
+ hbox.pack_end(label_sep, False, False) |
+ hbox.pack_end(label_en, False, False) |
+ eb.add(hbox) |
+ return eb |
+ |
+ def register_callbacks(self, window): |
+ window.connect('key-press-event', self.key_press_callback) |
+ window.add_events(gtk.gdk.KEY_PRESS_MASK) |
+ window.connect('key-release-event', self.key_release_callback) |
+ window.add_events(gtk.gdk.KEY_RELEASE_MASK) |
+ |
+ def locate_asample(self, sample): |
+ if not sample: |
+ raise error.TestFail('ERROR: Must provide an audio sample') |
+ if not os.path.isabs(sample): |
+ # assume its in deps |
+ sample = self.autodir + '/' + sample |
+ if not os.path.exists(sample): |
+ raise error.TestFail('ERROR: Unable to find audio sample %s' \ |
+ % sample) |
+ self._sample=sample |
+ |
+ def run_once(self, |
+ test_widget_size=None, |
+ trigger_set=None, |
+ sample=None, |
+ ): |
+ |
+ factory.log('%s run_once' % self.__class__) |
+ |
+ self._job = None |
+ self._test_widget_size = test_widget_size |
+ self.locate_asample(sample) |
+ # to write the recordings |
+ os.chdir(self.tmpdir) |
+ |
+ xset_status = os.system('LD_LIBRARY_PATH=/usr/local/lib xset r off') |
+ if xset_status: |
+ raise error.TestFail('ERROR: disabling key repeat') |
+ |
+ self._ft_state = ful.State(trigger_set=trigger_set) |
+ |
+ self._sample_queue = [x for x in reversed(_SAMPLE_LIST)] |
+ self._status_map = dict((n, ful.UNTESTED) for n in _SAMPLE_LIST) |
+ |
+ prompt_label = ful.make_label(_LABEL_START_STR, alignment=(0.5, 0.5)) |
+ |
+ vbox = gtk.VBox() |
+ vbox.pack_start(prompt_label, False, False) |
+ |
+ for name in _SAMPLE_LIST: |
+ label_box = self.make_sample_label_box(name) |
+ vbox.pack_start(label_box, False, False) |
+ |
+ test_widget = gtk.EventBox() |
+ test_widget.modify_bg(gtk.STATE_NORMAL, ful.BLACK) |
+ test_widget.add(vbox) |
+ self._test_widget = test_widget |
+ |
+ self.goto_next_sample() |
+ |
+ self._fs_window = None |
+ |
+ self._ft_state.run_test_widget( |
+ test_widget=test_widget, |
+ test_widget_size=test_widget_size, |
+ window_registration_callback=self.register_callbacks) |
+ |
+ failed_set = set(name for name, status in self._status_map.items() |
+ if status is not ful.PASSED) |
+ if failed_set: |
+ raise error.TestFail('some samples failed (%s)' % |
+ ', '.join(failed_set)) |
+ |
+ factory.log('%s run_once finished' % self.__class__) |