| OLD | NEW |
| 1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
| 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 | 6 |
| 7 # DESCRIPTION : | 7 # DESCRIPTION : |
| 8 # | 8 # |
| 9 # This is a factory test to test the audio. Operator will test both record and | 9 # This is a factory test to test the audio. Operator will test both record and |
| 10 # playback for headset and built-in audio. Recordings are played back for | 10 # playback for headset and built-in audio. Recordings are played back for |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 _LABEL_BIG_SIZE = (280, 60) | 27 _LABEL_BIG_SIZE = (280, 60) |
| 28 _LABEL_STATUS_SIZE = (140, 30) | 28 _LABEL_STATUS_SIZE = (140, 30) |
| 29 _LABEL_START_STR = 'hit SPACE to start each audio test\n' +\ | 29 _LABEL_START_STR = 'hit SPACE to start each audio test\n' +\ |
| 30 '按空白鍵開始各項聲音測試\n\n' | 30 '按空白鍵開始各項聲音測試\n\n' |
| 31 _LABEL_RESPONSE_STR = ful.USER_PASS_FAIL_SELECT_STR + '\n' | 31 _LABEL_RESPONSE_STR = ful.USER_PASS_FAIL_SELECT_STR + '\n' |
| 32 _SAMPLE_LIST = ['Headset Audio Test', 'Built-in Audio Test'] | 32 _SAMPLE_LIST = ['Headset Audio Test', 'Built-in Audio Test'] |
| 33 _VERBOSE = False | 33 _VERBOSE = False |
| 34 | 34 |
| 35 | 35 |
| 36 # FIXME: tbroch : refactor from factory_ui -> factory_ui_lib.py | |
| 37 _SEP_COLOR = gtk.gdk.color_parse('grey50') | |
| 38 def make_vsep(width=1): | |
| 39 frame = gtk.EventBox() | |
| 40 frame.set_size_request(width, -1) | |
| 41 frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR) | |
| 42 return frame | |
| 43 | |
| 44 def make_hsep(width=1): | |
| 45 frame = gtk.EventBox() | |
| 46 frame.set_size_request(-1, width) | |
| 47 frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR) | |
| 48 return frame | |
| 49 | |
| 50 | |
| 51 class factory_Audio(test.test): | 36 class factory_Audio(test.test): |
| 52 version = 1 | 37 version = 1 |
| 53 | 38 |
| 54 | |
| 55 def audio_subtest_widget(self, name): | 39 def audio_subtest_widget(self, name): |
| 56 window = gtk.Window(gtk.WINDOW_TOPLEVEL) | |
| 57 screen = window.get_screen() | |
| 58 screen_size = (screen.get_width(), screen.get_height()) | |
| 59 window.set_size_request(*self._test_widget_size) | |
| 60 | |
| 61 vb = gtk.VBox() | 40 vb = gtk.VBox() |
| 62 ebh = gtk.EventBox() | 41 ebh = gtk.EventBox() |
| 63 ebh.modify_bg(gtk.STATE_NORMAL, ful.LABEL_COLORS[ful.ACTIVE]) | 42 ebh.modify_bg(gtk.STATE_NORMAL, ful.LABEL_COLORS[ful.ACTIVE]) |
| 64 ebh.add(ful.make_label(name, size=_LABEL_BIG_SIZE, | 43 ebh.add(ful.make_label(name, size=_LABEL_BIG_SIZE, |
| 65 fg=ful.BLACK)) | 44 fg=ful.BLACK)) |
| 66 vb.pack_start(ebh) | 45 vb.pack_start(ebh) |
| 67 vb.pack_start(make_vsep(3), False, False) | 46 vb.pack_start(ful.make_vsep(3), False, False) |
| 68 if re.search('Headset', name): | 47 if re.search('Headset', name): |
| 69 lab_str = 'Connect headset to device\n將耳機接上音源孔' | 48 lab_str = 'Connect headset to device\n將耳機接上音源孔' |
| 70 else: | 49 else: |
| 71 lab_str = 'Remove headset from device\n將耳機移開音源孔' | 50 lab_str = 'Remove headset from device\n將耳機移開音源孔' |
| 72 vb.pack_start(ful.make_label(lab_str, fg=ful.WHITE)) | 51 vb.pack_start(ful.make_label(lab_str, fg=ful.WHITE)) |
| 73 vb.pack_start(make_vsep(3), False, False) | 52 vb.pack_start(ful.make_vsep(3), False, False) |
| 74 vb.pack_start(ful.make_label(\ | 53 vb.pack_start(ful.make_label(\ |
| 75 'Press & hold \'r\' to record\n壓住 \'r\' 鍵開始錄音\n' + \ | 54 'Press & hold \'r\' to record\n壓住 \'r\' 鍵開始錄音\n' + \ |
| 76 '[Playback will follow]\n[之後會重播錄到的聲音]\n\n' + \ | 55 '[Playback will follow]\n[之後會重播錄到的聲音]\n\n' + \ |
| 77 'Press & hold \'p\' to play sample\n' + \ | 56 'Press & hold \'p\' to play sample\n' + \ |
| 78 '壓住 \'p\' 鍵以播放範例')) | 57 '壓住 \'p\' 鍵以播放範例')) |
| 79 vb.pack_start(make_vsep(3), False, False) | 58 vb.pack_start(ful.make_vsep(3), False, False) |
| 80 vb.pack_start(ful.make_label(ful.USER_PASS_FAIL_SELECT_STR, | 59 vb.pack_start(ful.make_label(ful.USER_PASS_FAIL_SELECT_STR, |
| 81 fg=ful.WHITE)) | 60 fg=ful.WHITE)) |
| 82 | 61 |
| 83 # need event box to effect bg color | 62 # Need event box to effect bg color. |
| 84 eb = gtk.EventBox() | 63 eb = gtk.EventBox() |
| 85 eb.modify_bg(gtk.STATE_NORMAL, ful.BLACK) | 64 eb.modify_bg(gtk.STATE_NORMAL, ful.BLACK) |
| 86 eb.add(vb) | 65 eb.add(vb) |
| 87 window.add(eb) | 66 |
| 88 window.show_all() | 67 self._subtest_widget = eb |
| 89 self._fs_window = window | 68 |
| 69 self._test_widget.remove(self._top_level_test_list) |
| 70 self._test_widget.add(self._subtest_widget) |
| 71 self._test_widget.show_all() |
| 90 | 72 |
| 91 def close_bgjob(self, sample_name): | 73 def close_bgjob(self, sample_name): |
| 92 job = self._job | 74 job = self._bg_job |
| 93 if job: | 75 if job: |
| 94 utils.nuke_subprocess(job.sp) | 76 utils.nuke_subprocess(job.sp) |
| 95 utils.join_bg_jobs([job], timeout=1) | 77 utils.join_bg_jobs([job], timeout=1) |
| 96 result = job.result | 78 result = job.result |
| 97 if _VERBOSE and (result.stdout or result.stderr): | 79 if _VERBOSE and (result.stdout or result.stderr): |
| 98 raise error.CmdError( | 80 raise error.CmdError( |
| 99 sample_name, result, | 81 sample_name, result, |
| 100 'stdout: %s\nstderr: %s' % (result.stdout, result.stderr)) | 82 'stdout: %s\nstderr: %s' % (result.stdout, result.stderr)) |
| 101 self._job = None | 83 self._bg_job = None |
| 102 | 84 |
| 103 def goto_next_sample(self): | 85 def goto_next_sample(self): |
| 104 if not self._sample_queue: | 86 if not self._sample_queue: |
| 105 gtk.main_quit() | 87 gtk.main_quit() |
| 106 return | 88 return |
| 107 self._current_sample = self._sample_queue.pop() | 89 self._current_sample = self._sample_queue.pop() |
| 108 name = self._current_sample | 90 name = self._current_sample |
| 109 self._status_map[name] = ful.ACTIVE | 91 self._status_map[name] = ful.ACTIVE |
| 110 | 92 |
| 111 def cleanup_sample(self): | 93 def cleanup_sample(self): |
| 112 factory.log('Inside cleanup_sample') | 94 factory.log('Inside cleanup_sample') |
| 113 self._fs_window.destroy() | 95 self._test_widget.remove(self._subtest_widget) |
| 114 self._fs_window = None | 96 self._subtest_widget = None |
| 97 self._test_widget.add(self._top_level_test_list) |
| 98 self._test_widget.show_all() |
| 115 self.goto_next_sample() | 99 self.goto_next_sample() |
| 116 | 100 |
| 117 def key_press_callback(self, widget, event): | 101 def key_press_callback(self, widget, event): |
| 118 name = self._current_sample | 102 name = self._current_sample |
| 119 if event.keyval == gtk.keysyms.space and not self._fs_window: | 103 if (event.keyval == gtk.keysyms.space and self._subtest_widget is None): |
| 120 # start the subtest | 104 # Start subtest. |
| 121 self.audio_subtest_widget(name) | 105 self.audio_subtest_widget(name) |
| 122 else: | 106 else: |
| 123 self.close_bgjob(name) | 107 self.close_bgjob(name) |
| 124 cmd = None | 108 cmd = None |
| 125 if event.keyval == ord('r'): | 109 if event.keyval == ord('r'): |
| 126 # record via mic | 110 # Record via mic. |
| 127 if os.path.isfile('rec.wav'): | 111 if os.path.isfile('rec.wav'): |
| 128 os.unlink('rec.wav') | 112 os.unlink('rec.wav') |
| 129 cmd = 'arecord -f dat -t wav rec.wav' | 113 cmd = 'arecord -f dat -t wav rec.wav' |
| 130 elif event.keyval == ord('p'): | 114 elif event.keyval == ord('p'): |
| 131 # playback canned audio | 115 # Playback canned audio. |
| 132 cmd = 'aplay %s' % self._sample | 116 cmd = 'aplay %s' % self._audio_sample_path |
| 133 if cmd: | 117 if cmd: |
| 134 self._job = utils.BgJob(cmd, stderr_level=logging.DEBUG) | 118 self._bg_job = utils.BgJob(cmd, stderr_level=logging.DEBUG) |
| 135 factory.log("cmd: " + cmd) | 119 factory.log("cmd: " + cmd) |
| 136 self._test_widget.queue_draw() | 120 self._test_widget.queue_draw() |
| 137 return True | 121 return True |
| 138 | 122 |
| 139 def key_release_callback(self, widget, event): | 123 def key_release_callback(self, widget, event): |
| 140 name = self._current_sample | 124 name = self._current_sample |
| 141 if event.keyval == gtk.keysyms.Tab: | 125 if event.keyval == gtk.keysyms.Tab: |
| 142 self._status_map[name] = ful.FAILED | 126 self._status_map[name] = ful.FAILED |
| 143 self.cleanup_sample() | 127 self.cleanup_sample() |
| 144 elif event.keyval == gtk.keysyms.Return: | 128 elif event.keyval == gtk.keysyms.Return: |
| 145 self._status_map[name] = ful.PASSED | 129 self._status_map[name] = ful.PASSED |
| 146 self.cleanup_sample() | 130 self.cleanup_sample() |
| 147 elif event.keyval == ord('Q'): | 131 elif event.keyval == ord('Q'): |
| 148 gtk.main_quit() | 132 gtk.main_quit() |
| 149 elif event.keyval == ord('r'): | 133 elif event.keyval == ord('r'): |
| 150 self.close_bgjob(name) | 134 self.close_bgjob(name) |
| 151 cmd = 'aplay rec.wav' | 135 cmd = 'aplay rec.wav' |
| 152 self._job = utils.BgJob(cmd, stderr_level=logging.DEBUG) | 136 self._bg_job = utils.BgJob(cmd, stderr_level=logging.DEBUG) |
| 153 factory.log("cmd: " + cmd) | 137 factory.log("cmd: " + cmd) |
| 154 elif event.keyval == ord('p'): | 138 elif event.keyval == ord('p'): |
| 155 self.close_bgjob(name) | 139 self.close_bgjob(name) |
| 156 else: | |
| 157 self._ft_state.exit_on_trigger(event) | |
| 158 | |
| 159 self._test_widget.queue_draw() | 140 self._test_widget.queue_draw() |
| 160 return True | 141 return True |
| 161 | 142 |
| 162 def label_status_expose(self, widget, event, name=None): | 143 def label_status_expose(self, widget, event, name=None): |
| 163 status = self._status_map[name] | 144 status = self._status_map[name] |
| 164 widget.set_text(status) | 145 widget.set_text(status) |
| 165 widget.modify_fg(gtk.STATE_NORMAL, ful.LABEL_COLORS[status]) | 146 widget.modify_fg(gtk.STATE_NORMAL, ful.LABEL_COLORS[status]) |
| 166 | 147 |
| 167 def make_sample_label_box(self, name): | 148 def make_sample_label_box(self, name): |
| 168 eb = gtk.EventBox() | 149 eb = gtk.EventBox() |
| (...skipping 11 matching lines...) Expand all Loading... |
| 180 hbox.pack_end(label_en, False, False) | 161 hbox.pack_end(label_en, False, False) |
| 181 eb.add(hbox) | 162 eb.add(hbox) |
| 182 return eb | 163 return eb |
| 183 | 164 |
| 184 def register_callbacks(self, window): | 165 def register_callbacks(self, window): |
| 185 window.connect('key-press-event', self.key_press_callback) | 166 window.connect('key-press-event', self.key_press_callback) |
| 186 window.add_events(gtk.gdk.KEY_PRESS_MASK) | 167 window.add_events(gtk.gdk.KEY_PRESS_MASK) |
| 187 window.connect('key-release-event', self.key_release_callback) | 168 window.connect('key-release-event', self.key_release_callback) |
| 188 window.add_events(gtk.gdk.KEY_RELEASE_MASK) | 169 window.add_events(gtk.gdk.KEY_RELEASE_MASK) |
| 189 | 170 |
| 190 def locate_asample(self, sample): | 171 def locate_audio_sample(self, path): |
| 191 if not sample: | 172 if path is None: |
| 192 raise error.TestFail('ERROR: Must provide an audio sample') | 173 raise error.TestFail('ERROR: Must provide an audio sample') |
| 193 if not os.path.isabs(sample): | 174 if not os.path.isabs(path): |
| 194 # assume its in deps | 175 # Assume rel-path samples are in deps/factory. |
| 195 sample = self.autodir + '/' + sample | 176 path = self.job.autodir + '/deps/factory/' + path |
| 196 if not os.path.exists(sample): | 177 if not os.path.exists(path): |
| 197 raise error.TestFail('ERROR: Unable to find audio sample %s' \ | 178 raise error.TestFail('ERROR: Unable to find audio sample %s' % path) |
| 198 % sample) | 179 return path |
| 199 self._sample=sample | |
| 200 | 180 |
| 201 def run_once(self, | 181 def run_once(self, audio_sample_path=None): |
| 202 test_widget_size=None, | |
| 203 trigger_set=None, | |
| 204 sample=None, | |
| 205 ): | |
| 206 | 182 |
| 207 factory.log('%s run_once' % self.__class__) | 183 factory.log('%s run_once' % self.__class__) |
| 208 | 184 |
| 209 self._job = None | 185 # Write recordings in tmpdir. |
| 210 self._test_widget_size = test_widget_size | |
| 211 self.locate_asample(sample) | |
| 212 # to write the recordings | |
| 213 os.chdir(self.tmpdir) | 186 os.chdir(self.tmpdir) |
| 214 | 187 |
| 215 xset_status = os.system('LD_LIBRARY_PATH=/usr/local/lib xset r off') | 188 self._bg_job = None |
| 216 if xset_status: | 189 self._audio_sample_path = self.locate_audio_sample(audio_sample_path) |
| 217 raise error.TestFail('ERROR: disabling key repeat') | |
| 218 | |
| 219 self._ft_state = ful.State(trigger_set=trigger_set) | |
| 220 | 190 |
| 221 self._sample_queue = [x for x in reversed(_SAMPLE_LIST)] | 191 self._sample_queue = [x for x in reversed(_SAMPLE_LIST)] |
| 222 self._status_map = dict((n, ful.UNTESTED) for n in _SAMPLE_LIST) | 192 self._status_map = dict((n, ful.UNTESTED) for n in _SAMPLE_LIST) |
| 223 | 193 |
| 224 prompt_label = ful.make_label(_LABEL_START_STR, alignment=(0.5, 0.5)) | 194 prompt_label = ful.make_label(_LABEL_START_STR, alignment=(0.5, 0.5)) |
| 225 | 195 |
| 226 vbox = gtk.VBox() | 196 self._top_level_test_list = gtk.VBox() |
| 227 vbox.pack_start(prompt_label, False, False) | 197 self._top_level_test_list.pack_start(prompt_label, False, False) |
| 228 | 198 |
| 229 for name in _SAMPLE_LIST: | 199 for name in _SAMPLE_LIST: |
| 230 label_box = self.make_sample_label_box(name) | 200 label_box = self.make_sample_label_box(name) |
| 231 vbox.pack_start(label_box, False, False) | 201 self._top_level_test_list.pack_start(label_box, False, False) |
| 232 | 202 |
| 233 test_widget = gtk.EventBox() | 203 self._test_widget = gtk.EventBox() |
| 234 test_widget.modify_bg(gtk.STATE_NORMAL, ful.BLACK) | 204 self._test_widget.modify_bg(gtk.STATE_NORMAL, ful.BLACK) |
| 235 test_widget.add(vbox) | 205 self._test_widget.add(self._top_level_test_list) |
| 236 self._test_widget = test_widget | 206 |
| 207 self._subtest_widget = None |
| 237 | 208 |
| 238 self.goto_next_sample() | 209 self.goto_next_sample() |
| 239 | 210 |
| 240 self._fs_window = None | 211 ful.run_test_widget(self.job, self._test_widget, |
| 241 | |
| 242 self._ft_state.run_test_widget( | |
| 243 test_widget=test_widget, | |
| 244 test_widget_size=test_widget_size, | |
| 245 window_registration_callback=self.register_callbacks) | 212 window_registration_callback=self.register_callbacks) |
| 246 | 213 |
| 247 failed_set = set(name for name, status in self._status_map.items() | 214 failed_set = set(name for name, status in self._status_map.items() |
| 248 if status is not ful.PASSED) | 215 if status is not ful.PASSED) |
| 249 if failed_set: | 216 if failed_set: |
| 250 raise error.TestFail('some samples failed (%s)' % | 217 raise error.TestFail('some samples failed (%s)' % |
| 251 ', '.join(failed_set)) | 218 ', '.join(failed_set)) |
| 252 | 219 |
| 253 factory.log('%s run_once finished' % self.__class__) | 220 factory.log('%s run_once finished' % self.__class__) |
| OLD | NEW |