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

Side by Side Diff: client/site_tests/factory_DeveloperRecovery/DevRecTest.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
(Empty)
1 #!/usr/bin/python
2 #
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 # DESCRIPTION :
8 #
9 # Intended for use during manufacturing to validate that developer
10 # switch and recovery button function properly. Run normally, test
11 # will display an D-housing image identifying where recovery button and
12 # developer switch are located. It will highlight when recovery has
13 # been pressed and released. It will highlight when developer switch
14 # has been switched & unswitched. If successful, a brief 'PASS' message
15 # will be displayed and the test will terminate. If not, the test will
16 # fail with an 'ERROR' message that is displayed forever (unless the
17 # 'hwqual' argument is passed in).
18
19 import cairo
20 import gobject
21 import gtk
22 import sys
23 import time
24 import os
25 import math
26
27 class DevRecTest():
28
29 gpio_info = {
30 'developer' : {'type' : 'switch',
31 'cx' : 355,
32 'cy' : 175,
33 'size' : 30,
34 'arrow' : {'x' : 305,
35 'y' : 175,
36 'width' : 15,
37 'length' : 100,
38 # in degrees starts as rt arrow
39 'direction' : 0,
40 },
41 },
42 'recovery' : {'type' : 'button',
43 'cx' : 635,
44 'cy' : 425,
45 'size' : 30,
46 'arrow' : {'x' : 580,
47 'y' : 425,
48 'width' : 15,
49 'length' : 100,
50 'direction' : 270,
51 }
52 },
53 }
54
55 # How long DevRecTest allows in seconds until failing
56 timeout = 20
57
58 # How long to display the success message in seconds before exit.
59 pass_msg_timeout = 2
60
61 # Background color and alpha for the final result message.
62 bg_rgba_fail = (0.7, 0, 0, 0.9)
63 bg_rgba_pass = ( 0, 0.7, 0, 0.9)
64
65 rgba_state = [(0.0, 1.0, 0.0, 0.9),
66 (0.9, 0.9, 0.0, 0.6),
67 (0.9, 0.0, 0.0, 0.6)]
68
69 def __init__(self, autodir, devrec_image):
70 self._devrec_image = devrec_image
71 self._successful = set()
72 self._deadline = None
73 self._success = None
74 self.gpios = devrec_gpio(autodir)
75 self.gpios.cfg()
76
77 def show_arrow(self, context, cx, cy, headx, heady, awidth, length,
78 degrees):
79
80 '''Draw a simple arrow in given context.
81 '''
82
83 context.save()
84
85 # rotation transform
86 matrix = cairo.Matrix(1, 0, 0, 1, 0, 0)
87 context.set_source_rgba(0, 0, 0, 1)
88 cairo.Matrix.translate(matrix, cx, cy)
89 cairo.Matrix.rotate(matrix, math.radians(degrees))
90 cairo.Matrix.translate(matrix, -cx, -cy)
91 context.transform(matrix)
92
93 # right arrow default
94 context.set_line_width(5)
95 context.move_to(headx, heady)
96 context.rel_line_to(-awidth, -awidth/2.0)
97 context.rel_line_to(0, awidth)
98 context.rel_line_to(awidth, -awidth/2.0)
99 context.fill_preserve()
100 context.rel_line_to(-length, 0)
101 context.stroke_preserve()
102 context.set_source_rgba(0, 0, 0, 0.5)
103 context.stroke_preserve()
104 context.restore()
105
106 def start_countdown(self, duration):
107 self._deadline = int(time.time()) + duration
108
109 def request_action(self, widget, context, name):
110 '''Determine action required by gpio state and show
111 '''
112
113 gpio_default = self.gpios.table[name][1]
114 gpio_state = self.gpios.table[name][2]
115 gpio_val = self.gpios.gpio_read(name)
116
117 # state transitions based on current value
118 if (gpio_state == 2) and (gpio_val != gpio_default):
119 gpio_state-=1
120 # refresh countdown
121 self.start_countdown(self.timeout)
122 elif (gpio_state == 1) and (gpio_val == gpio_default):
123 gpio_state-=1
124 self._successful.add(name)
125 if self.gpio_info.__len__() is self._successful.__len__():
126 self._success = True
127 self.start_countdown(self.pass_msg_timeout)
128
129 # store state change
130 self.gpios.table[name][2] = gpio_state
131
132 widget_width, widget_height = widget.get_size_request()
133 context.save()
134 ginfo = self.gpio_info[name]
135
136 context.set_source_rgba(0, 0, 0, 1)
137
138 if (ginfo['type'] == 'button'):
139 text = ['Done', 'Release', 'Press']
140 context.arc(ginfo['cx'], ginfo['cy'], ginfo['size'],
141 0, math.radians(360))
142 context.stroke()
143 context.arc(ginfo['cx'], ginfo['cy'], ginfo['size'],
144 0, math.radians(360))
145 elif (ginfo['type'] == 'switch'):
146 text = ['Done', 'Restore', 'Move']
147 # two rects one outline of switch body the other
148 # representing the position
149 rect_x = ginfo['cx'] - ginfo['size']
150 rect_y = ginfo['cy'] - ginfo['size'] / 2.0
151 context.rectangle(rect_x, rect_y, ginfo['size'] * 2,
152 ginfo['size'])
153
154 context.stroke()
155
156 if gpio_state == 1:
157 rect_x = rect_x + ginfo['size']
158 context.rectangle(rect_x, rect_y, ginfo['size'],
159 ginfo['size'])
160 else:
161 raise
162
163 context.set_source_rgba(*self.rgba_state[gpio_state])
164 context.fill()
165
166 if ginfo['arrow'] is not None:
167 arrow_x = ginfo['arrow']['x']
168 arrow_y = ginfo['arrow']['y']
169 arrow_l = ginfo['arrow']['length']
170 arrow_w = ginfo['arrow']['width']
171
172 arrow_dir = ginfo['arrow']['direction']
173 if (gpio_state == 1) and (ginfo['type'] == 'switch'):
174 arrow_dir =+ 180
175
176 self.show_arrow(context, ginfo['cx'], ginfo['cy'],
177 arrow_x, arrow_y, arrow_w, arrow_l, arrow_dir)
178
179 context.scale(widget_width / 1.0, widget_height / 1.0)
180 context.set_source_rgba(0.1, 0.1, 0.1, 0.95)
181 context.select_font_face(
182 'Verdana', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
183 context.set_font_size(.05)
184
185 if gpio_state > 0:
186 dtext = "%s %s %s now [ %d ] " % \
187 (text[gpio_state], name, ginfo['type'],
188 (self._deadline - int(time.time())))
189 else:
190 dtext = "%s with %s %s" % (text[gpio_state], name, ginfo['type'])
191
192 x_bearing, y_bearing, width, height = context.text_extents(dtext)[:4]
193 context.move_to(0.5 - (width / 2) - x_bearing,
194 0.5 - (height / 2) - y_bearing)
195 context.show_text(dtext)
196 context.restore()
197 return True
198
199 def expose_event(self, widget, event):
200 context = widget.window.cairo_create()
201
202 context.set_source_surface(self._devrec_image, 0, 0)
203 context.paint()
204
205 if self._success is None:
206 for key in self.gpio_info:
207 if key not in self._successful:
208 self.request_action(widget, context, key)
209 break
210 return True
211
212 def timer_event(self, window):
213 if not self._deadline:
214 # Ignore timer events with no countdown in progress.
215 return True
216 if self._deadline <= time.time():
217 self._deadline = None
218 if self._success is None:
219 self._success = False
220 elif self._success:
221 sys.exit(0)
222 window.queue_draw()
223 return True
224
225 class devrec_gpio:
226 '''
227 Borrowed from site_tests/hardware_GPIOSwitches. Will replace
228 iotools implementation with successor chromium-os issue id=3119
229 '''
230
231 def __init__(self, autodir):
232 self._autodir = autodir
233 self.gpio_read = None
234 self.table = None
235
236 def cfg(self):
237 self.sku_table = {
238 # SKU: gpio_read, recovery GPIO, developer mode,
239 # firmware writeprotect
240 'atom-proto': {'gpio_read': self.pinetrail_gpio_read,
241 # name : [<bit>, <type>, <default>,
242 # <assert>, <state>]
243 # <type> == button || switch || ro (read-only)
244 # <default> == 0 || 1
245 # <state> == number counts down 0
246 'developer': [7, 1, 2],
247
248 'recovery': [6, 1, 2],
249 },
250 }
251
252 # TODO(nsanders): Detect actual system type here by HWQual ID (?)
253 # and redirect to the correct check.
254 # We're just checking for any Atom here, and hoping for the best.
255 if not os.system('cat /proc/cpuinfo | grep "model name" | '
256 'grep -qe "N4[0-9][0-9]"'):
257 systemsku = 'atom-proto'
258 else:
259 systemsku = 'unknown'
260
261 # Look up hardware configuration.
262 if systemsku in self.sku_table:
263 table = self.sku_table[systemsku]
264 self.table = table
265 self.gpio_read = table['gpio_read']
266 else:
267 raise KeyError('System settings not defined for board %s' %
268 systemsku)
269
270 def pinetrail_gpio_read(self, name):
271 if not self.table.__contains__(name):
272 raise
273
274 # Tigerpoint LPC Interface.
275 tp_device = (0, 31, 0)
276 # TP io port location of GPIO registers.
277 tp_GPIOBASE = 0x48
278 # IO offset to check GPIO levels.
279 tp_GP_LVL_off = 0xc
280
281 try:
282 tp_gpio_iobase_str = os.popen('pci_read32 %s %s %s %s' % (
283 tp_device[0], tp_device[1], tp_device[2],
284 tp_GPIOBASE)).readlines()[0]
285 except:
286 print "ERROR: reading gpio iobase"
287
288
289 # Bottom bit of GPIOBASE is a flag indicating io space.
290 tp_gpio_iobase = long(tp_gpio_iobase_str, 16) & ~1
291
292 try:
293 tp_gpio_mask_str = os.popen('io_read32 %s' % (
294 tp_gpio_iobase + tp_GP_LVL_off)).readlines()[0]
295 except:
296 print "ERROR: reading gpio value"
297
298 tp_gpio_mask = long(tp_gpio_mask_str, 16)
299
300 gpio_val = int((tp_gpio_mask >> self.table[name][0]) & 1)
301 return gpio_val
302
303 def make_test_widget(autodir, devrec_image):
304 test = DevRecTest(autodir, devrec_image)
305
306 image_size = (devrec_image.get_width(), devrec_image.get_height())
307
308 drawing_area = gtk.DrawingArea()
309 drawing_area.set_size_request(*image_size)
310 drawing_area.connect('expose_event', test.expose_event)
311 drawing_area.add_events(gtk.gdk.EXPOSURE_MASK)
312 gobject.timeout_add(200, test.timer_event, drawing_area)
313
314 test.start_countdown(test.timeout)
315
316 return drawing_area
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698