blob: 78d37319a58b4c354f3498d38ae41547964a0336 [file] [log] [blame]
# -*- 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 LEDs (wifi, battery, etc).
import cairo
import gtk
import pango
import os
import subprocess
import sys
import re
from cmath import pi
from gtk import gdk
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.cros import factory
from autotest_lib.client.cros.factory import ui as ful
_LABEL_STATUS_SIZE = (140, 30)
_LABEL_FONT = pango.FontDescription('courier new condensed 16')
_LABEL_FG = gtk.gdk.color_parse('light green')
_LABEL_UNTESTED_FG = gtk.gdk.color_parse('grey40')
_PATTERN_LABEL_STR = 'pattern / 圖樣: '
_ORANGE = gtk.gdk.color_parse('orange')
_LED_NAMES = 'sleepled battchgled wlan battfulled powerled 3g'.split()
_ORANGE_LED_NAMES = _LED_NAMES[0:3]
_BLUE_LED_NAMES = _LED_NAMES[3:]
_LED_COUNT = 3
_LED_Y_OFFSET = 10
_LED_X_OFFSETS = [10, 80, 150]
_LED_RADIUS = 18
_SHFL_XYR = {'x':166,'y':20, 'r':9}
def run_led_ctl(led_ctl_path, args):
rc = subprocess.call([led_ctl_path] + args.split())
if rc != 1:
factory.log('%s(%s) failed with rc %s' % (led_ctl_path, args, rc))
def pattern_all_off(led_ctl_fn):
for n in _LED_NAMES:
led_ctl_fn('-%s -off' % n)
return [ful.BLACK, ful.BLACK, ful.BLACK]
def pattern_blue_on(led_ctl_fn):
pattern_all_off(led_ctl_fn)
for n in _BLUE_LED_NAMES:
led_ctl_fn('-%s -on' % n)
return [ful.BLUE, ful.BLUE, ful.BLUE]
def pattern_orange_on(led_ctl_fn):
pattern_all_off(led_ctl_fn)
for n in _ORANGE_LED_NAMES:
led_ctl_fn('-%s -on' % n)
return [_ORANGE, _ORANGE, _ORANGE]
_PATTERN_LIST = [
('all off', pattern_all_off),
('blue on', pattern_blue_on),
('orange on', pattern_orange_on),
('shift led', False)]
class factory_Leds(test.test):
version = 1
preserve_srcdir = True
def goto_next_pattern(self):
if not self._pattern_queue:
gtk.main_quit()
return
self._current_pattern, cb_fn = self._pattern_queue.pop()
self._status_map[self._current_pattern] = ful.ACTIVE
if cb_fn:
led_ctl_fn = lambda args: run_led_ctl(self._led_ctl_path, args)
self._led_colors = cb_fn(led_ctl_fn)
else:
self._pattern_da.connect('expose_event', self.shift_led_expose)
self._pattern_da.queue_draw()
def shift_led_expose(self, widget, event):
context = widget.window.cairo_create()
context.set_source_surface(self._shf_image, 0, 0)
context.paint()
if self._shift_cnt is 2:
if self._shift_color is ful.BLACK:
self._shift_color = ful.BLUE
else:
self._shift_color = ful.BLACK
self._shift_cnt = 0
context.set_source_color(self._shift_color)
context.arc(_SHFL_XYR['x'], _SHFL_XYR['y'], _SHFL_XYR['r'],
0.0, 2.0 * pi)
context.fill()
def pattern_expose(self, widget, event):
context = widget.window.cairo_create()
context.set_source_surface(self._leds_image, 0, 0)
context.paint()
for led_index in range(_LED_COUNT):
color = self._led_colors[led_index]
x_offset = _LED_X_OFFSETS[led_index] + _LED_RADIUS + 3
y_offset = _LED_Y_OFFSET + _LED_RADIUS + 3
context.set_source_color(color)
context.arc(x_offset, y_offset, _LED_RADIUS, 0.0, 2.0 * pi)
context.fill()
def quit(self):
factory.log('releasing LEDs ...')
run_led_ctl(self._led_ctl_path, '-ledrelease')
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_pattern_label_box(self, name):
eb = gtk.EventBox()
eb.modify_bg(gtk.STATE_NORMAL, ful.BLACK)
label_status = gtk.Label(ful.UNTESTED)
label_status.set_size_request(*_LABEL_STATUS_SIZE)
label_status.set_alignment(0, 0.5)
label_status.modify_font(_LABEL_FONT)
label_status.modify_fg(gtk.STATE_NORMAL, _LABEL_UNTESTED_FG)
expose_cb = lambda *x: self.label_status_expose(*x, **{'name':name})
label_status.connect('expose_event', expose_cb)
label_en = gtk.Label(name)
label_en.set_alignment(1, 0.5)
label_en.modify_font(_LABEL_FONT)
label_en.modify_fg(gtk.STATE_NORMAL, _LABEL_FG)
label_sep = gtk.Label(' : ')
label_sep.set_alignment(0.5, 0.5)
label_sep.modify_font(_LABEL_FONT)
label_sep.modify_fg(gtk.STATE_NORMAL, _LABEL_FG)
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 key_release_callback(self, widget, event):
if event.keyval == gtk.keysyms.Tab:
self._status_map[self._current_pattern] = ful.FAILED
self.goto_next_pattern()
elif event.keyval == gtk.keysyms.Return:
self._status_map[self._current_pattern] = ful.PASSED
self.goto_next_pattern()
elif self._current_pattern.startswith("shift") and \
event.keyval == gtk.keysyms.Shift_L:
self._shift_cnt += 1
self._pattern_da.queue_draw()
return True
def register_callbacks(self, window):
window.connect('key-release-event', self.key_release_callback)
window.add_events(gdk.KEY_RELEASE_MASK)
def _get_embedded_controller_vendor(self):
# example output of superiotool:
# Found Nuvoton WPCE775x (id=0x05, rev=0x02) at 0x2e
re_vendor = re.compile(r'Found (\w*)')
vendor = []
res = utils.system_output('superiotool', ignore_status=True).split('\n')
for line in res:
match = re_vendor.search(line)
if match:
vendor.append(match.group(1))
return vendor
def run_once(self, led_ctl_path=None):
factory.log('%s run_once' % self.__class__)
ec_vendor = self._get_embedded_controller_vendor()
if len(ec_vendor) == 0:
raise error.TestNAError('No embedded controller vendor found')
if 'Nuvoton' not in ec_vendor:
raise error.TestNAError('Currently not supported embedded controllers: %s' %
', '.join(ec_vendor))
self._led_ctl_path = led_ctl_path
if not os.path.exists(self._led_ctl_path):
raise error.TestNAError('Command %s does not exist' %
self._led_ctl_path)
self._shift_color = ful.BLACK
self._shift_cnt = 0
os.chdir(self.srcdir)
try:
image = cairo.ImageSurface.create_from_png('leds.png')
except cairo.Error as e:
raise error.TestNAError('Error while opening leds.png: %s' %
e.message)
image_size = (image.get_width(), image.get_height())
self._leds_image = image
image = cairo.ImageSurface.create_from_png('shf.png')
self._shf_image = image
self._pattern_queue = [x for x in reversed(_PATTERN_LIST)]
self._status_map = dict((n, ful.UNTESTED) for n, f in _PATTERN_LIST)
pattern_da = gtk.DrawingArea()
pattern_da.set_size_request(*image_size)
pattern_da.connect('expose_event', self.pattern_expose)
self._pattern_da = pattern_da
pattern_label = ful.make_label(_PATTERN_LABEL_STR)
pattern_box = gtk.HBox()
pattern_box.pack_start(pattern_label, False, False)
pattern_box.pack_start(pattern_da, False, False)
prompt_label = ful.make_label(ful.USER_PASS_FAIL_SELECT_STR)
subvbox = gtk.VBox()
for name, cb_fun in _PATTERN_LIST:
label_box = self.make_pattern_label_box(name)
subvbox.pack_start(label_box, False, False)
vbox = gtk.VBox()
vbox.set_spacing(20)
vbox.pack_start(prompt_label, False, False)
vbox.pack_start(pattern_box, False, False)
vbox.pack_start(subvbox, 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_pattern()
ful.run_test_widget(self.job, test_widget,
window_registration_callback=self.register_callbacks,
cleanup_callback=self.quit)
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 patterns failed\n' \
'以下圖樣測試未通過: %s' %
', '.join(failed_set))
factory.log('%s run_once finished' % self.__class__)