Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1244)

Side by Side Diff: client/site_tests/factory_DeveloperRecovery/factory_DeveloperRecovery.py

Issue 2836043: Relocate library files for wider access and re-use; also associated cleanup. (Closed) Base URL: ssh://gitrw.chromium.org/autotest.git
Patch Set: patch typo Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 5
6 # DESCRIPTION : 6 # DESCRIPTION :
7 # 7 #
8 # Intended for use during manufacturing to validate Developer mode 8 # Intended for use during manufacturing to validate Developer mode
9 # switch and Recovery button function properly. This program will 9 # switch and Recovery button function properly. This program will
10 # display an image of the d-housing with Developer switch and Recovery 10 # display an image of the d-housing with Developer switch and Recovery
11 # button. Operator will then be instructed via text and visually to 11 # button. Operator will then be instructed via text and visually to
12 # switch and restore the Developer switch and press/release the 12 # switch and restore the Developer switch and press/release the
13 # Recovery button. Success at each step resets a 20 second countdown timer. 13 # Recovery button. Success at each step resets a 20 second countdown timer.
14 14
15
16 import cairo
17 import gobject
18 import gtk
19 import sys
20 import time
21 import os
22 import math
23
24 from autotest_lib.client.bin import factory
25 from autotest_lib.client.bin import factory_ui_lib as ful
15 from autotest_lib.client.bin import test 26 from autotest_lib.client.bin import test
16 from autotest_lib.client.common_lib import error 27 from autotest_lib.client.common_lib import error
17 from autotest_lib.client.common_lib import factory_test 28
18 29
19 import gtk 30 class DevRecTest():
20 import cairo 31
21 import os 32 gpio_info = {
22 33 'developer' : {'type' : 'switch',
23 import DevRecTest 34 'cx' : 355,
35 'cy' : 175,
36 'size' : 30,
37 'arrow' : {'x' : 305,
38 'y' : 175,
39 'width' : 15,
40 'length' : 100,
41 # in degrees starts as rt arrow
42 'direction' : 0,
43 },
44 },
45 'recovery' : {'type' : 'button',
46 'cx' : 635,
47 'cy' : 425,
48 'size' : 30,
49 'arrow' : {'x' : 580,
50 'y' : 425,
51 'width' : 15,
52 'length' : 100,
53 'direction' : 270,
54 }
55 },
56 }
57
58 # How long DevRecTest allows in seconds until failing
59 timeout = 20
60
61 # How long to display the success message in seconds before exit.
62 pass_msg_timeout = 2
63
64 # Background color and alpha for the final result message.
65 bg_rgba_fail = (0.7, 0, 0, 0.9)
66 bg_rgba_pass = ( 0, 0.7, 0, 0.9)
67
68 rgba_state = [(0.0, 1.0, 0.0, 0.9),
69 (0.9, 0.9, 0.0, 0.6),
70 (0.9, 0.0, 0.0, 0.6)]
71
72 def __init__(self, autodir, devrec_image):
73 self._devrec_image = devrec_image
74 self._successful = set()
75 self._deadline = None
76 self._success = None
77 self.gpios = DevRecGpio(autodir)
78 self.gpios.cfg()
79
80 def show_arrow(self, context, cx, cy, headx, heady, awidth, length,
81 degrees):
82
83 '''Draw a simple arrow in given context.
84 '''
85
86 context.save()
87
88 # rotation transform
89 matrix = cairo.Matrix(1, 0, 0, 1, 0, 0)
90 context.set_source_rgba(0, 0, 0, 1)
91 cairo.Matrix.translate(matrix, cx, cy)
92 cairo.Matrix.rotate(matrix, math.radians(degrees))
93 cairo.Matrix.translate(matrix, -cx, -cy)
94 context.transform(matrix)
95
96 # right arrow default
97 context.set_line_width(5)
98 context.move_to(headx, heady)
99 context.rel_line_to(-awidth, -awidth/2.0)
100 context.rel_line_to(0, awidth)
101 context.rel_line_to(awidth, -awidth/2.0)
102 context.fill_preserve()
103 context.rel_line_to(-length, 0)
104 context.stroke_preserve()
105 context.set_source_rgba(0, 0, 0, 0.5)
106 context.stroke_preserve()
107 context.restore()
108
109 def start_countdown(self, duration):
110 self._deadline = int(time.time()) + duration
111
112 def request_action(self, widget, context, name):
113 '''Determine action required by gpio state and show
114 '''
115
116 gpio_default = self.gpios.table[name][1]
117 gpio_state = self.gpios.table[name][2]
118 gpio_val = self.gpios.gpio_read(name)
119
120 # state transitions based on current value
121 if (gpio_state == 2) and (gpio_val != gpio_default):
122 gpio_state-=1
123 # refresh countdown
124 self.start_countdown(self.timeout)
125 elif (gpio_state == 1) and (gpio_val == gpio_default):
126 gpio_state-=1
127 self._successful.add(name)
128 if self.gpio_info.__len__() is self._successful.__len__():
129 self._success = True
130 self.start_countdown(self.pass_msg_timeout)
131
132 # store state change
133 self.gpios.table[name][2] = gpio_state
134
135 widget_width, widget_height = widget.get_size_request()
136 context.save()
137 ginfo = self.gpio_info[name]
138
139 context.set_source_rgba(0, 0, 0, 1)
140
141 if (ginfo['type'] == 'button'):
142 text = ['Done', 'Release', 'Press']
143 context.arc(ginfo['cx'], ginfo['cy'], ginfo['size'],
144 0, math.radians(360))
145 context.stroke()
146 context.arc(ginfo['cx'], ginfo['cy'], ginfo['size'],
147 0, math.radians(360))
148 elif (ginfo['type'] == 'switch'):
149 text = ['Done', 'Restore', 'Move']
150 # two rects one outline of switch body the other
151 # representing the position
152 rect_x = ginfo['cx'] - ginfo['size']
153 rect_y = ginfo['cy'] - ginfo['size'] / 2.0
154 context.rectangle(rect_x, rect_y, ginfo['size'] * 2,
155 ginfo['size'])
156
157 context.stroke()
158
159 if gpio_state == 1:
160 rect_x = rect_x + ginfo['size']
161 context.rectangle(rect_x, rect_y, ginfo['size'],
162 ginfo['size'])
163 else:
164 raise
165
166 context.set_source_rgba(*self.rgba_state[gpio_state])
167 context.fill()
168
169 if ginfo['arrow'] is not None:
170 arrow_x = ginfo['arrow']['x']
171 arrow_y = ginfo['arrow']['y']
172 arrow_l = ginfo['arrow']['length']
173 arrow_w = ginfo['arrow']['width']
174
175 arrow_dir = ginfo['arrow']['direction']
176 if (gpio_state == 1) and (ginfo['type'] == 'switch'):
177 arrow_dir =+ 180
178
179 self.show_arrow(context, ginfo['cx'], ginfo['cy'],
180 arrow_x, arrow_y, arrow_w, arrow_l, arrow_dir)
181
182 context.scale(widget_width / 1.0, widget_height / 1.0)
183 context.set_source_rgba(0.1, 0.1, 0.1, 0.95)
184 context.select_font_face(
185 'Verdana', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
186 context.set_font_size(.05)
187
188 if gpio_state > 0:
189 dtext = "%s %s %s now [ %d ] " % \
190 (text[gpio_state], name, ginfo['type'],
191 (self._deadline - int(time.time())))
192 else:
193 dtext = "%s with %s %s" % (text[gpio_state], name, ginfo['type'])
194
195 x_bearing, y_bearing, width, height = context.text_extents(dtext)[:4]
196 context.move_to(0.5 - (width / 2) - x_bearing,
197 0.5 - (height / 2) - y_bearing)
198 context.show_text(dtext)
199 context.restore()
200 return True
201
202 def expose_event(self, widget, event):
203 context = widget.window.cairo_create()
204
205 context.set_source_surface(self._devrec_image, 0, 0)
206 context.paint()
207
208 if self._success is None:
209 for key in self.gpio_info:
210 if key not in self._successful:
211 self.request_action(widget, context, key)
212 break
213 return True
214
215 def timer_event(self, window):
216 if not self._deadline:
217 # Ignore timer events with no countdown in progress.
218 return True
219 if self._deadline <= time.time():
220 self._deadline = None
221 if self._success is None:
222 self._success = False
223 elif self._success:
224 sys.exit(0)
225 window.queue_draw()
226 return True
227
228
229 class DevRecGpio:
230 '''
231 Borrowed from site_tests/hardware_GPIOSwitches. Will replace
232 iotools implementation with successor chromium-os issue id=3119
233 '''
234
235 def __init__(self, autodir):
236 self._autodir = autodir
237 self.gpio_read = None
238 self.table = None
239
240 def cfg(self):
241 self.sku_table = {
242 # SKU: gpio_read, recovery GPIO, developer mode,
243 # firmware writeprotect
244 'atom-proto': {'gpio_read': self.pinetrail_gpio_read,
245 # name : [<bit>, <type>, <default>,
246 # <assert>, <state>]
247 # <type> == button || switch || ro (read-only)
248 # <default> == 0 || 1
249 # <state> == number counts down 0
250 'developer': [7, 1, 2],
251
252 'recovery': [6, 1, 2],
253 },
254 }
255
256 # TODO(nsanders): Detect actual system type here by HWQual ID (?)
257 # and redirect to the correct check.
258 # We're just checking for any Atom here, and hoping for the best.
259 if not os.system('cat /proc/cpuinfo | grep "model name" | '
260 'grep -qe "N4[0-9][0-9]"'):
261 systemsku = 'atom-proto'
262 else:
263 systemsku = 'unknown'
264
265 # Look up hardware configuration.
266 if systemsku in self.sku_table:
267 table = self.sku_table[systemsku]
268 self.table = table
269 self.gpio_read = table['gpio_read']
270 else:
271 raise KeyError('System settings not defined for board %s' %
272 systemsku)
273
274 def pinetrail_gpio_read(self, name):
275 if not self.table.__contains__(name):
276 raise
277
278 # Tigerpoint LPC Interface.
279 tp_device = (0, 31, 0)
280 # TP io port location of GPIO registers.
281 tp_GPIOBASE = 0x48
282 # IO offset to check GPIO levels.
283 tp_GP_LVL_off = 0xc
284
285 try:
286 tp_gpio_iobase_str = os.popen('pci_read32 %s %s %s %s' % (
287 tp_device[0], tp_device[1], tp_device[2],
288 tp_GPIOBASE)).readlines()[0]
289 except:
290 factory.log("ERROR: reading gpio iobase")
291
292
293 # Bottom bit of GPIOBASE is a flag indicating io space.
294 tp_gpio_iobase = long(tp_gpio_iobase_str, 16) & ~1
295
296 try:
297 tp_gpio_mask_str = os.popen('io_read32 %s' % (
298 tp_gpio_iobase + tp_GP_LVL_off)).readlines()[0]
299 except:
300 factory.log("ERROR: reading gpio value")
301
302 tp_gpio_mask = long(tp_gpio_mask_str, 16)
303
304 gpio_val = int((tp_gpio_mask >> self.table[name][0]) & 1)
305 return gpio_val
306
24 307
25 class factory_DeveloperRecovery(test.test): 308 class factory_DeveloperRecovery(test.test):
26 version = 1 309 version = 1
27 preserve_srcdir = True 310 preserve_srcdir = True
28 311
29 def key_release_callback(self, widget, event): 312 def key_release_callback(self, widget, event):
30 char = event.keyval in range(32,127) and chr(event.keyval) or None 313 self._ft_state.exit_on_trigger(event)
31 factory_test.XXX_log('key_release_callback %s(%s)' %
32 (event.keyval, char))
33 if event.keyval == self.quit_key:
34 factory_test.XXX_log('%s exiting...' % self.tagged_testname)
35 gtk.main_quit()
36 factory_test.test_switch_on_trigger(event)
37 return True 314 return True
38 315
39 def register_callbacks(self, window): 316 def register_callbacks(self, window):
40 window.connect('key-release-event', self.key_release_callback) 317 window.connect('key-release-event', self.key_release_callback)
41 window.add_events(gtk.gdk.KEY_RELEASE_MASK) 318 window.add_events(gtk.gdk.KEY_RELEASE_MASK)
42 319
43 def run_once(self, test_widget_size=None, trigger_set=None, layout='devrec', 320 def run_once(self,
44 result_file_path=None, quit_key=ord('Q'), 321 test_widget_size=None,
45 msg='factory_DeveloperRecovery'): 322 trigger_set=None,
46 323 result_file_path=None,
47 factory_test.XXX_log(self.tagged_testname) 324 layout=None):
48 325
49 self.quit_key = quit_key 326 factory.log('%s run_once' % self.__class__)
50 327
51 factory_test.init(trigger_set=trigger_set, 328 self._ft_state = ful.State(
52 result_file_path=result_file_path) 329 trigger_set=trigger_set,
330 result_file_path=result_file_path)
53 331
54 os.chdir(self.srcdir) 332 os.chdir(self.srcdir)
55 dr_image = cairo.ImageSurface.create_from_png('%s.png' % layout) 333 dr_image = cairo.ImageSurface.create_from_png('%s.png' % layout)
56 334 image_size = (dr_image.get_width(), dr_image.get_height())
57 test_widget = DevRecTest.make_test_widget(self.autodir, dr_image) 335
58 336 test = DevRecTest(autodir, dr_image)
59 factory_test.run_test_widget( 337
60 test_widget=test_widget, 338 drawing_area = gtk.DrawingArea()
339 drawing_area.set_size_request(*image_size)
340 drawing_area.connect('expose_event', test.expose_event)
341 drawing_area.add_events(gtk.gdk.EXPOSURE_MASK)
342 gobject.timeout_add(200, test.timer_event, drawing_area)
343
344 test.start_countdown(test.timeout)
345
346 self._ft_state.run_test_widget(
347 test_widget=drawing_area,
61 test_widget_size=test_widget_size, 348 test_widget_size=test_widget_size,
62 window_registration_callback=self.register_callbacks) 349 window_registration_callback=self.register_callbacks)
63 350
64 factory_test.XXX_log('exiting %s' % self.tagged_testname) 351 factory.log('%s run_once finished' % self.__class__)
OLDNEW
« no previous file with comments | « client/site_tests/factory_DeveloperRecovery/DevRecTest.py ('k') | client/site_tests/factory_Display/factory_Display.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698