Change the whitelist to a blacklist.

Various fixes, including 4-to-2-space-indentation change.

BUG=None
TEST=make lint, make test

Change-Id: Ic41e96936b47e66833a9773d36779c004f69aae1
Reviewed-on: https://gerrit.chromium.org/gerrit/26773
Commit-Ready: Jon Salz <jsalz@chromium.org>
Reviewed-by: Jon Salz <jsalz@chromium.org>
Tested-by: Jon Salz <jsalz@chromium.org>
diff --git a/py/test/ui.py b/py/test/ui.py
index 729f18e..a3c4ef7 100755
--- a/py/test/ui.py
+++ b/py/test/ui.py
@@ -19,12 +19,12 @@
 #
 # In short, the UI is composed of a 'console' panel on the bottom of
 # the screen which displays the autotest log, and there is also a
-# 'test list' panel on the right hand side of the screen.  The
+# 'test list' panel on the right hand side of the screen. The
 # majority of the screen is dedicated to tests, which are executed in
 # seperate processes, but instructed to display their own UIs in this
-# dedicated area whenever possible.  Tests in the test list are
+# dedicated area whenever possible. Tests in the test list are
 # executed in order by default, but can be activated on demand via
-# associated keyboard shortcuts.  As tests are run, their status is
+# associated keyboard shortcuts. As tests are run, their status is
 # color-indicated to the operator -- greyed out means untested, yellow
 # means active, green passed and red failed.
 
@@ -45,16 +45,16 @@
 import pango
 
 # Guard loading Xlib because it is currently not available in the
-# image build process host-depends list.  Failure to load in
+# image build process host-depends list. Failure to load in
 # production should always manifest during regular use.
 try:
-    from Xlib import X
-    from Xlib.display import Display
+  from Xlib import X
+  from Xlib.display import Display
 except:
-    pass
+  pass
 
 # Factory and autotest modules
-import factory_common
+import factory_common # pylint: disable=W0611
 from cros.factory.test import factory
 from cros.factory.test.factory import TestState
 from cros.factory.test.test_ui import FactoryTestFailure
@@ -73,9 +73,9 @@
 
 # Color definition
 BLACK = gtk.gdk.Color()
-RED =   gtk.gdk.Color(0xFFFF, 0, 0)
+RED =  gtk.gdk.Color(0xFFFF, 0, 0)
 GREEN = gtk.gdk.Color(0, 0xFFFF, 0)
-BLUE =  gtk.gdk.Color(0, 0, 0xFFFF)
+BLUE = gtk.gdk.Color(0, 0, 0xFFFF)
 WHITE = gtk.gdk.Color(0xFFFF, 0xFFFF, 0xFFFF)
 LIGHT_GREEN = gtk.gdk.color_parse('light green')
 SEP_COLOR = gtk.gdk.color_parse('grey50')
@@ -85,10 +85,10 @@
 RGBA_RED_OVERLAY = (0.5, 0, 0, 0.6)
 
 LABEL_COLORS = {
-    TestState.ACTIVE: gtk.gdk.color_parse('light goldenrod'),
-    TestState.PASSED: gtk.gdk.color_parse('pale green'),
-    TestState.FAILED: gtk.gdk.color_parse('tomato'),
-    TestState.UNTESTED: gtk.gdk.color_parse('dark slate grey')}
+  TestState.ACTIVE: gtk.gdk.color_parse('light goldenrod'),
+  TestState.PASSED: gtk.gdk.color_parse('pale green'),
+  TestState.FAILED: gtk.gdk.color_parse('tomato'),
+  TestState.UNTESTED: gtk.gdk.color_parse('dark slate grey')}
 
 LABEL_FONT = pango.FontDescription('courier new condensed 16')
 LABEL_LARGE_FONT = pango.FontDescription('courier new condensed 24')
@@ -96,21 +96,21 @@
 FAIL_TIMEOUT = 60
 
 MESSAGE_NO_ACTIVE_TESTS = (
-        "No more tests to run. To re-run items, press shortcuts\n"
-        "from the test list in right side or from following list:\n\n"
-        "Ctrl-Alt-A (Auto-Run):\n"
-        "  Test remaining untested items.\n\n"
-        "Ctrl-Alt-F (Re-run Failed):\n"
-        "  Re-test failed items.\n\n"
-        "Ctrl-Alt-R (Reset):\n"
-        "  Re-test everything.\n\n"
-        "Ctrl-Alt-Z (Information):\n"
-        "  Review test results and information.\n\n"
-        )
+    "No more tests to run. To re-run items, press shortcuts\n"
+    "from the test list in right side or from following list:\n\n"
+    "Ctrl-Alt-A (Auto-Run):\n"
+    " Test remaining untested items.\n\n"
+    "Ctrl-Alt-F (Re-run Failed):\n"
+    " Re-test failed items.\n\n"
+    "Ctrl-Alt-R (Reset):\n"
+    " Re-test everything.\n\n"
+    "Ctrl-Alt-Z (Information):\n"
+    " Review test results and information.\n\n"
+    )
 
 USER_PASS_FAIL_SELECT_STR = (
-    'hit TAB to fail and ENTER to pass\n' +
-    '錯誤請按 TAB,成功請按 ENTER')
+  'hit TAB to fail and ENTER to pass\n' +
+  '錯誤請按 TAB,成功請按 ENTER')
 # Resolution where original UI is designed for.
 _UI_SCREEN_WIDTH = 1280
 _UI_SCREEN_HEIGHT = 800
@@ -126,22 +126,22 @@
 _LABEL_TROUGH_COLOR = gtk.gdk.color_parse('grey20')
 _LABEL_STATUS_SIZE = (140, 30)
 _LABEL_STATUS_FONT = pango.FontDescription(
-    'courier new bold extra-condensed 16')
+  'courier new bold extra-condensed 16')
 _OTHER_LABEL_FONT = pango.FontDescription('courier new condensed 20')
 
 _NO_ACTIVE_TEST_DELAY_MS = 500
 
 GLOBAL_HOT_KEY_EVENTS = {
-    'r': Event.Type.RESTART_TESTS,
-    'a': Event.Type.AUTO_RUN,
-    'f': Event.Type.RE_RUN_FAILED,
-    'z': Event.Type.REVIEW,
-    }
+  'r': Event.Type.RESTART_TESTS,
+  'a': Event.Type.AUTO_RUN,
+  'f': Event.Type.RE_RUN_FAILED,
+  'z': Event.Type.REVIEW,
+  }
 try:
-    # Works only if X is available.
-    GLOBAL_HOT_KEY_MASK = X.ControlMask | X.Mod1Mask
+  # Works only if X is available.
+  GLOBAL_HOT_KEY_MASK = X.ControlMask | X.Mod1Mask
 except:
-    pass
+  pass
 
 # ---------------------------------------------------------------------------
 # Client Library
@@ -150,415 +150,415 @@
 # TODO(hungte) Replace gtk_lock by gtk.gdk.lock when it's availble (need pygtk
 # 2.2x, and we're now pinned by 2.1x)
 class _GtkLock(object):
-    __enter__ = gtk.gdk.threads_enter
-    def __exit__(*ignored):
-        gtk.gdk.threads_leave()
+  __enter__ = gtk.gdk.threads_enter
+  def __exit__(*ignored):
+    gtk.gdk.threads_leave()
 
 
 gtk_lock = _GtkLock()
 
 
 def make_label(message, font=LABEL_FONT, fg=LIGHT_GREEN,
-               size=None, alignment=None):
-    """Returns a label widget.
+        size=None, alignment=None):
+  """Returns a label widget.
 
-    A wrapper for gtk.Label. The unit of size is pixels under resolution
-    _UI_SCREEN_WIDTH*_UI_SCREEN_HEIGHT.
+  A wrapper for gtk.Label. The unit of size is pixels under resolution
+  _UI_SCREEN_WIDTH*_UI_SCREEN_HEIGHT.
 
-    @param message: A string to be displayed.
-    @param font: Font descriptor for the label.
-    @param fg: Foreground color.
-    @param size: Minimum size for this label.
-    @param alignment: Alignment setting.
-    @return: A label widget.
-    """
-    l = gtk.Label(message)
-    l.modify_font(font)
-    l.modify_fg(gtk.STATE_NORMAL, fg)
-    if size:
-        # Convert size according to the current resolution.
-        l.set_size_request(*convert_pixels(size))
-    if alignment:
-        l.set_alignment(*alignment)
-    return l
+  @param message: A string to be displayed.
+  @param font: Font descriptor for the label.
+  @param fg: Foreground color.
+  @param size: Minimum size for this label.
+  @param alignment: Alignment setting.
+  @return: A label widget.
+  """
+  l = gtk.Label(message)
+  l.modify_font(font)
+  l.modify_fg(gtk.STATE_NORMAL, fg)
+  if size:
+    # Convert size according to the current resolution.
+    l.set_size_request(*convert_pixels(size))
+  if alignment:
+    l.set_alignment(*alignment)
+  return l
 
 
 def make_status_row(init_prompt,
-                    init_status,
-                    label_size=_LABEL_STATUS_ROW_SIZE,
-                    is_standard_status=True):
-    """Returns a widget that live updates prompt and status in a row.
+          init_status,
+          label_size=_LABEL_STATUS_ROW_SIZE,
+          is_standard_status=True):
+  """Returns a widget that live updates prompt and status in a row.
 
-    Args:
-        init_prompt: The prompt label text.
-        init_status: The status label text.
-        label_size: The desired size of the prompt label and the status label.
-        is_standard_status: True to interpret status by the values defined by
-            LABEL_COLORS, and render text by corresponding color. False to
-            display arbitrary text without changing text color.
+  Args:
+    init_prompt: The prompt label text.
+    init_status: The status label text.
+    label_size: The desired size of the prompt label and the status label.
+    is_standard_status: True to interpret status by the values defined by
+      LABEL_COLORS, and render text by corresponding color. False to
+      display arbitrary text without changing text color.
 
-    Returns:
-        1) A dict whose content is linked by the widget.
-        2) A widget to render dict content in "prompt:   status" format.
-    """
-    display_dict = {}
-    display_dict['prompt'] = init_prompt
-    display_dict['status'] = init_status
-    display_dict['is_standard_status'] = is_standard_status
+  Returns:
+    1) A dict whose content is linked by the widget.
+    2) A widget to render dict content in "prompt:  status" format.
+  """
+  display_dict = {}
+  display_dict['prompt'] = init_prompt
+  display_dict['status'] = init_status
+  display_dict['is_standard_status'] = is_standard_status
 
-    def prompt_label_expose(widget, event):
-        prompt = display_dict['prompt']
-        widget.set_text(prompt)
+  def prompt_label_expose(widget, event):
+    prompt = display_dict['prompt']
+    widget.set_text(prompt)
 
-    def status_label_expose(widget, event):
-        status = display_dict['status']
-        widget.set_text(status)
-        if is_standard_status:
-            widget.modify_fg(gtk.STATE_NORMAL, LABEL_COLORS[status])
+  def status_label_expose(widget, event):
+    status = display_dict['status']
+    widget.set_text(status)
+    if is_standard_status:
+      widget.modify_fg(gtk.STATE_NORMAL, LABEL_COLORS[status])
 
-    prompt_label = make_label(
-            init_prompt, size=label_size,
-            alignment=(0, 0.5))
-    delimiter_label = make_label(':', alignment=(0, 0.5))
-    status_label = make_label(
-            init_status, size=label_size,
-            alignment=(0, 0.5))
+  prompt_label = make_label(
+      init_prompt, size=label_size,
+      alignment=(0, 0.5))
+  delimiter_label = make_label(':', alignment=(0, 0.5))
+  status_label = make_label(
+      init_status, size=label_size,
+      alignment=(0, 0.5))
 
-    widget = gtk.HBox()
-    widget.pack_end(status_label, False, False)
-    widget.pack_end(delimiter_label, False, False)
-    widget.pack_end(prompt_label, False, False)
+  widget = gtk.HBox()
+  widget.pack_end(status_label, False, False)
+  widget.pack_end(delimiter_label, False, False)
+  widget.pack_end(prompt_label, False, False)
 
-    status_label.connect('expose_event', status_label_expose)
-    prompt_label.connect('expose_event', prompt_label_expose)
-    return display_dict, widget
+  status_label.connect('expose_event', status_label_expose)
+  prompt_label.connect('expose_event', prompt_label_expose)
+  return display_dict, widget
 
 
 def convert_pixels(size):
-    """Converts a pair in pixel that is suitable for current resolution.
+  """Converts a pair in pixel that is suitable for current resolution.
 
-    GTK takes pixels as its unit in many function calls. To maintain the
-    consistency of the UI in different resolution, a conversion is required.
-    Take current resolution and (_UI_SCREEN_WIDTH, _UI_SCREEN_HEIGHT) as
-    the original resolution, this function returns a pair of width and height
-    that is converted for current resolution.
+  GTK takes pixels as its unit in many function calls. To maintain the
+  consistency of the UI in different resolution, a conversion is required.
+  Take current resolution and (_UI_SCREEN_WIDTH, _UI_SCREEN_HEIGHT) as
+  the original resolution, this function returns a pair of width and height
+  that is converted for current resolution.
 
-    Because pixels in negative usually indicates unspecified, no conversion
-    will be done for negative pixels.
+  Because pixels in negative usually indicates unspecified, no conversion
+  will be done for negative pixels.
 
-    In addition, the aspect ratio is not maintained in this function.
+  In addition, the aspect ratio is not maintained in this function.
 
-    Usage Example:
-        width,_ = convert_pixels((20,-1))
+  Usage Example:
+    width,_ = convert_pixels((20,-1))
 
-    @param size: A pair of pixels that designed under original resolution.
-    @return: A pair of pixels of (width, height) format.
-             Pixels returned are always integer.
-    """
-    return (int(float(size[0]) / _UI_SCREEN_WIDTH * gtk.gdk.screen_width()
-           if (size[0] > 0) else size[0]),
-           int(float(size[1]) / _UI_SCREEN_HEIGHT * gtk.gdk.screen_height()
-           if (size[1] > 0) else size[1]))
+  @param size: A pair of pixels that designed under original resolution.
+  @return: A pair of pixels of (width, height) format.
+       Pixels returned are always integer.
+  """
+  return (int(float(size[0]) / _UI_SCREEN_WIDTH * gtk.gdk.screen_width()
+      if (size[0] > 0) else size[0]),
+      int(float(size[1]) / _UI_SCREEN_HEIGHT * gtk.gdk.screen_height()
+      if (size[1] > 0) else size[1]))
 
 
 def make_hsep(height=1):
-    """Returns a widget acts as a horizontal separation line.
+  """Returns a widget acts as a horizontal separation line.
 
-    The unit is pixels under resolution _UI_SCREEN_WIDTH*_UI_SCREEN_HEIGHT.
-    """
-    frame = gtk.EventBox()
-    # Convert height according to the current resolution.
-    frame.set_size_request(*convert_pixels((-1, height)))
-    frame.modify_bg(gtk.STATE_NORMAL, SEP_COLOR)
-    return frame
+  The unit is pixels under resolution _UI_SCREEN_WIDTH*_UI_SCREEN_HEIGHT.
+  """
+  frame = gtk.EventBox()
+  # Convert height according to the current resolution.
+  frame.set_size_request(*convert_pixels((-1, height)))
+  frame.modify_bg(gtk.STATE_NORMAL, SEP_COLOR)
+  return frame
 
 
 def make_vsep(width=1):
-    """Returns a widget acts as a vertical separation line.
+  """Returns a widget acts as a vertical separation line.
 
-    The unit is pixels under resolution _UI_SCREEN_WIDTH*_UI_SCREEN_HEIGHT.
-    """
-    frame = gtk.EventBox()
-    # Convert width according to the current resolution.
-    frame.set_size_request(*convert_pixels((width, -1)))
-    frame.modify_bg(gtk.STATE_NORMAL, SEP_COLOR)
-    return frame
+  The unit is pixels under resolution _UI_SCREEN_WIDTH*_UI_SCREEN_HEIGHT.
+  """
+  frame = gtk.EventBox()
+  # Convert width according to the current resolution.
+  frame.set_size_request(*convert_pixels((width, -1)))
+  frame.modify_bg(gtk.STATE_NORMAL, SEP_COLOR)
+  return frame
 
 
 def make_countdown_widget(prompt=None, value=None, fg=LIGHT_GREEN):
-    if prompt is None:
-        prompt = 'time remaining / 剩餘時間: '
-    if value is None:
-        value = '%s' % FAIL_TIMEOUT
-    title = make_label(prompt, fg=fg, alignment=(1, 0.5))
-    countdown = make_label(value, fg=fg, alignment=(0, 0.5))
-    hbox = gtk.HBox()
-    hbox.pack_start(title)
-    hbox.pack_start(countdown)
-    eb = gtk.EventBox()
-    eb.modify_bg(gtk.STATE_NORMAL, BLACK)
-    eb.add(hbox)
-    return eb, countdown
+  if prompt is None:
+    prompt = 'time remaining / 剩餘時間: '
+  if value is None:
+    value = '%s' % FAIL_TIMEOUT
+  title = make_label(prompt, fg=fg, alignment=(1, 0.5))
+  countdown = make_label(value, fg=fg, alignment=(0, 0.5))
+  hbox = gtk.HBox()
+  hbox.pack_start(title)
+  hbox.pack_start(countdown)
+  eb = gtk.EventBox()
+  eb.modify_bg(gtk.STATE_NORMAL, BLACK)
+  eb.add(hbox)
+  return eb, countdown
 
 
 def is_chrome_ui():
-    return os.environ.get('CROS_UI') == 'chrome'
+  return os.environ.get('CROS_UI') == 'chrome'
 
 
 def hide_cursor(gdk_window):
-    pixmap = gtk.gdk.Pixmap(None, 1, 1, 1)
-    color = gtk.gdk.Color()
-    cursor = gtk.gdk.Cursor(pixmap, pixmap, color, color, 0, 0)
-    gdk_window.set_cursor(cursor)
+  pixmap = gtk.gdk.Pixmap(None, 1, 1, 1)
+  color = gtk.gdk.Color()
+  cursor = gtk.gdk.Cursor(pixmap, pixmap, color, color, 0, 0)
+  gdk_window.set_cursor(cursor)
 
 
 def calc_scale(wanted_x, wanted_y):
-    (widget_size_x, widget_size_y) = factory.get_shared_data('test_widget_size')
-    scale_x = (0.9 * widget_size_x) / wanted_x
-    scale_y = (0.9 * widget_size_y) / wanted_y
-    scale = scale_y if scale_y < scale_x else scale_x
-    scale = 1 if scale > 1 else scale
-    factory.log('scale: %s' % scale)
-    return scale
+  (widget_size_x, widget_size_y) = factory.get_shared_data('test_widget_size')
+  scale_x = (0.9 * widget_size_x) / wanted_x
+  scale_y = (0.9 * widget_size_y) / wanted_y
+  scale = scale_y if scale_y < scale_x else scale_x
+  scale = 1 if scale > 1 else scale
+  factory.log('scale: %s' % scale)
+  return scale
 
 
 def trim(text, length):
-    if len(text) > length:
-        text = text[:length-3] + '...'
-    return text
+  if len(text) > length:
+    text = text[:length-3] + '...'
+  return text
 
 
 class InputError(ValueError):
-    """Execption for input window callbacks to change status text message."""
-    pass
+  """Execption for input window callbacks to change status text message."""
+  pass
 
 
 def make_input_window(prompt=None,
-                      init_value=None,
-                      msg_invalid=None,
-                      font=None,
-                      on_validate=None,
-                      on_keypress=None,
-                      on_complete=None):
-    """Creates a widget to prompt user for a valid string.
+           init_value=None,
+           msg_invalid=None,
+           font=None,
+           on_validate=None,
+           on_keypress=None,
+           on_complete=None):
+  """Creates a widget to prompt user for a valid string.
 
-    @param prompt: A string to be displayed. None for default message.
-    @param init_value: Initial value to be set.
-    @param msg_invalid: Status string to display when input is invalid. None for
-        default message.
-    @param font: Font specification (string or pango.FontDescription) for label
-        and entry. None for default large font.
-    @param on_validate: A callback function to validate if the input from user
-        is valid. None for allowing any non-empty input. Any ValueError or
-        ui.InputError raised during execution in on_validate will be displayed
-        in bottom status.
-    @param on_keypress: A callback function when each keystroke is hit.
-    @param on_complete: A callback function when a valid string is passed.
-        None to stop (gtk.main_quit).
-    @return: A widget with prompt, input entry, and status label. To access
-        these elements, use attribute 'prompt', 'entry', and 'label'.
-    """
-    DEFAULT_MSG_INVALID = "Invalid input / 輸入不正確"
-    DEFAULT_PROMPT = "Enter Data / 輸入資料:"
+  @param prompt: A string to be displayed. None for default message.
+  @param init_value: Initial value to be set.
+  @param msg_invalid: Status string to display when input is invalid. None for
+    default message.
+  @param font: Font specification (string or pango.FontDescription) for label
+    and entry. None for default large font.
+  @param on_validate: A callback function to validate if the input from user
+    is valid. None for allowing any non-empty input. Any ValueError or
+    ui.InputError raised during execution in on_validate will be displayed
+    in bottom status.
+  @param on_keypress: A callback function when each keystroke is hit.
+  @param on_complete: A callback function when a valid string is passed.
+    None to stop (gtk.main_quit).
+  @return: A widget with prompt, input entry, and status label. To access
+    these elements, use attribute 'prompt', 'entry', and 'label'.
+  """
+  DEFAULT_MSG_INVALID = "Invalid input / 輸入不正確"
+  DEFAULT_PROMPT = "Enter Data / 輸入資料:"
 
-    def enter_callback(entry):
-        text = entry.get_text()
-        try:
-            if (on_validate and (not on_validate(text))) or (not text.strip()):
-                raise ValueError(msg_invalid)
-            on_complete(text) if on_complete else gtk.main_quit()
-        except ValueError as e:
-            gtk.gdk.beep()
-            status_label.set_text('ERROR: %s' % e.message)
-        return True
+  def enter_callback(entry):
+    text = entry.get_text()
+    try:
+      if (on_validate and (not on_validate(text))) or (not text.strip()):
+        raise ValueError(msg_invalid)
+      on_complete(text) if on_complete else gtk.main_quit()
+    except ValueError as e:
+      gtk.gdk.beep()
+      status_label.set_text('ERROR: %s' % e.message)
+    return True
 
-    def key_press_callback(entry, key):
-        status_label.set_text('')
-        if on_keypress:
-            return on_keypress(entry, key)
-        return False
+  def key_press_callback(entry, key):
+    status_label.set_text('')
+    if on_keypress:
+      return on_keypress(entry, key)
+    return False
 
-    # Populate default parameters
-    if msg_invalid is None:
-        msg_invalid = DEFAULT_MSG_INVALID
+  # Populate default parameters
+  if msg_invalid is None:
+    msg_invalid = DEFAULT_MSG_INVALID
 
-    if prompt is None:
-        prompt = DEFAULT_PROMPT
+  if prompt is None:
+    prompt = DEFAULT_PROMPT
 
-    if font is None:
-        font = LABEL_LARGE_FONT
-    elif not isinstance(font, pango.FontDescription):
-        font = pango.FontDescription(font)
+  if font is None:
+    font = LABEL_LARGE_FONT
+  elif not isinstance(font, pango.FontDescription):
+    font = pango.FontDescription(font)
 
-    widget = gtk.VBox()
-    label = make_label(prompt, font=font)
-    status_label = make_label('', font=font)
-    entry = gtk.Entry()
-    entry.modify_font(font)
-    entry.connect("activate", enter_callback)
-    entry.connect("key_press_event", key_press_callback)
-    if init_value:
-        entry.set_text(init_value)
-    widget.modify_bg(gtk.STATE_NORMAL, BLACK)
-    status_label.modify_fg(gtk.STATE_NORMAL, RED)
-    widget.add(label)
-    widget.pack_start(entry)
-    widget.pack_start(status_label)
+  widget = gtk.VBox()
+  label = make_label(prompt, font=font)
+  status_label = make_label('', font=font)
+  entry = gtk.Entry()
+  entry.modify_font(font)
+  entry.connect("activate", enter_callback)
+  entry.connect("key_press_event", key_press_callback)
+  if init_value:
+    entry.set_text(init_value)
+  widget.modify_bg(gtk.STATE_NORMAL, BLACK)
+  status_label.modify_fg(gtk.STATE_NORMAL, RED)
+  widget.add(label)
+  widget.pack_start(entry)
+  widget.pack_start(status_label)
 
-    widget.entry = entry
-    widget.status = status_label
-    widget.prompt = label
+  widget.entry = entry
+  widget.status = status_label
+  widget.prompt = label
 
-    # TODO(itspeter) Replace deprecated get_entry by widget.entry.
-    # Method for getting the entry.
-    widget.get_entry = lambda : entry
-    return widget
+  # TODO(itspeter) Replace deprecated get_entry by widget.entry.
+  # Method for getting the entry.
+  widget.get_entry = lambda : entry
+  return widget
 
 
 def make_summary_box(tests, state_map, rows=15):
-    '''Creates a widget display status of a set of test.
+  '''Creates a widget display status of a set of test.
 
-    @param tests: A list of FactoryTest nodes whose status (and children's
-        status) should be displayed.
-    @param state_map: The state map as provide by the state instance.
-    @param rows: The number of rows to display.
-    @return: A tuple (widget, label_map), where widget is the widget, and
-        label_map is a map from each test to the corresponding label.
-    '''
-    LABEL_EN_SIZE = (170, 35)
-    LABEL_EN_SIZE_2 = (450, 25)
-    LABEL_EN_FONT = pango.FontDescription('courier new extra-condensed 16')
+  @param tests: A list of FactoryTest nodes whose status (and children's
+    status) should be displayed.
+  @param state_map: The state map as provide by the state instance.
+  @param rows: The number of rows to display.
+  @return: A tuple (widget, label_map), where widget is the widget, and
+    label_map is a map from each test to the corresponding label.
+  '''
+  LABEL_EN_SIZE = (170, 35)
+  LABEL_EN_SIZE_2 = (450, 25)
+  LABEL_EN_FONT = pango.FontDescription('courier new extra-condensed 16')
 
-    all_tests = sum([list(t.walk(in_order=True)) for t in tests], [])
-    columns = len(all_tests) / rows + (len(all_tests) % rows != 0)
+  all_tests = sum([list(t.walk(in_order=True)) for t in tests], [])
+  columns = len(all_tests) / rows + (len(all_tests) % rows != 0)
 
-    info_box = gtk.HBox()
-    info_box.set_spacing(20)
-    for status in (TestState.ACTIVE, TestState.PASSED,
-                   TestState.FAILED, TestState.UNTESTED):
-        label = make_label(status,
-                               size=LABEL_EN_SIZE,
-                               font=LABEL_EN_FONT,
-                               alignment=(0.5, 0.5),
-                               fg=LABEL_COLORS[status])
-        info_box.pack_start(label, False, False)
+  info_box = gtk.HBox()
+  info_box.set_spacing(20)
+  for status in (TestState.ACTIVE, TestState.PASSED,
+          TestState.FAILED, TestState.UNTESTED):
+    label = make_label(status,
+                size=LABEL_EN_SIZE,
+                font=LABEL_EN_FONT,
+                alignment=(0.5, 0.5),
+                fg=LABEL_COLORS[status])
+    info_box.pack_start(label, False, False)
 
-    vbox = gtk.VBox()
-    vbox.set_spacing(20)
-    vbox.pack_start(info_box, False, False)
+  vbox = gtk.VBox()
+  vbox.set_spacing(20)
+  vbox.pack_start(info_box, False, False)
 
-    label_map = {}
+  label_map = {}
 
-    if all_tests:
-        status_table = gtk.Table(rows, columns, True)
-        for (j, i), t in izip(product(xrange(columns), xrange(rows)),
-                              all_tests):
-            msg_en = '  ' * (t.depth() - 1) + t.label_en
-            msg_en = trim(msg_en, 12)
-            if t.label_zh:
-                msg = '{0:<12} ({1})'.format(msg_en, t.label_zh)
-            else:
-                msg = msg_en
-            status = state_map[t].status
-            status_label = make_label(msg,
-                                      size=LABEL_EN_SIZE_2,
-                                      font=LABEL_EN_FONT,
-                                      alignment=(0.0, 0.5),
-                                      fg=LABEL_COLORS[status])
-            label_map[t] = status_label
-            status_table.attach(status_label, j, j+1, i, i+1)
-        vbox.pack_start(status_table, False, False)
+  if all_tests:
+    status_table = gtk.Table(rows, columns, True)
+    for (j, i), t in izip(product(xrange(columns), xrange(rows)),
+               all_tests):
+      msg_en = ' ' * (t.depth() - 1) + t.label_en
+      msg_en = trim(msg_en, 12)
+      if t.label_zh:
+        msg = '{0:<12} ({1})'.format(msg_en, t.label_zh)
+      else:
+        msg = msg_en
+      status = state_map[t].status
+      status_label = make_label(msg,
+                   size=LABEL_EN_SIZE_2,
+                   font=LABEL_EN_FONT,
+                   alignment=(0.0, 0.5),
+                   fg=LABEL_COLORS[status])
+      label_map[t] = status_label
+      status_table.attach(status_label, j, j+1, i, i+1)
+    vbox.pack_start(status_table, False, False)
 
-    return vbox, label_map
+  return vbox, label_map
 
 
 def run_test_widget(dummy_job, test_widget,
-                    invisible_cursor=True,
-                    window_registration_callback=None,
-                    cleanup_callback=None):
-    test_widget_size = factory.get_shared_data('test_widget_size')
+          invisible_cursor=True,
+          window_registration_callback=None,
+          cleanup_callback=None):
+  test_widget_size = factory.get_shared_data('test_widget_size')
 
-    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
-    window.modify_bg(gtk.STATE_NORMAL, BLACK)
-    window.set_size_request(*test_widget_size)
+  window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+  window.modify_bg(gtk.STATE_NORMAL, BLACK)
+  window.set_size_request(*test_widget_size)
 
-    test_widget_position = factory.get_shared_data('test_widget_position')
-    if test_widget_position:
-        window.move(*test_widget_position)
+  test_widget_position = factory.get_shared_data('test_widget_position')
+  if test_widget_position:
+    window.move(*test_widget_position)
 
-    def show_window():
-        window.show()
-        window.window.raise_()  # pylint: disable=E1101
-        if is_chrome_ui():
-            window.present()
-            window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
-        else:
-            gtk.gdk.pointer_grab(window.window, confine_to=window.window)
-            if invisible_cursor:
-                hide_cursor(window.window)
-
-    test_path = factory.get_current_test_path()
-
-    def handle_event(event):
-        if (event.type == Event.Type.STATE_CHANGE and
-            test_path and event.path == test_path and
-            event.state.visible):
-            show_window()
-
-    event_client = EventClient(
-            callback=handle_event, event_loop=EventClient.EVENT_LOOP_GOBJECT_IO)
-
-    align = gtk.Alignment(xalign=0.5, yalign=0.5)
-    align.add(test_widget)
-
-    window.add(align)
-    for c in window.get_children():
-        # Show all children, but not the window itself yet.
-        c.show_all()
-
-    if window_registration_callback is not None:
-        window_registration_callback(window)
-
-    # Show the window if it is the visible test, or if the test_path is not
-    # available (e.g., run directly from the command line).
-    if (not test_path) or (
-        TestState.from_dict_or_object(
-            factory.get_state_instance().get_test_state(test_path)).visible):
-        show_window()
+  def show_window():
+    window.show()
+    window.window.raise_() # pylint: disable=E1101
+    if is_chrome_ui():
+      window.present()
+      window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
     else:
-        window.hide()
+      gtk.gdk.pointer_grab(window.window, confine_to=window.window)
+      if invisible_cursor:
+        hide_cursor(window.window)
 
-    # When gtk.main() is running, it ignores all uncaught exceptions, which is
-    # not preferred by most of our factory tests.  To prevent writing special
-    # function raising errors, we hook top level exception handler to always
-    # leave GTK main and raise exception again.
+  test_path = factory.get_current_test_path()
 
-    def exception_hook(exc_type, value, traceback):
-       # Prevent re-entrant.
-       sys.excepthook = old_excepthook
-       session['exception'] = (exc_type, value, traceback)
-       gobject.idle_add(gtk.main_quit)
-       return old_excepthook(exc_type, value, traceback)
+  def handle_event(event):
+    if (event.type == Event.Type.STATE_CHANGE and
+      test_path and event.path == test_path and
+      event.state.visible):
+      show_window()
 
-    session = {}
-    old_excepthook = sys.excepthook
-    sys.excepthook = exception_hook
+  event_client = EventClient(
+      callback=handle_event, event_loop=EventClient.EVENT_LOOP_GOBJECT_IO)
 
-    gtk.main()
+  align = gtk.Alignment(xalign=0.5, yalign=0.5)
+  align.add(test_widget)
 
-    if not is_chrome_ui():
-        gtk.gdk.pointer_ungrab()
+  window.add(align)
+  for c in window.get_children():
+    # Show all children, but not the window itself yet.
+    c.show_all()
 
-    if cleanup_callback is not None:
-        cleanup_callback()
+  if window_registration_callback is not None:
+    window_registration_callback(window)
 
-    del event_client
+  # Show the window if it is the visible test, or if the test_path is not
+  # available (e.g., run directly from the command line).
+  if (not test_path) or (
+    TestState.from_dict_or_object(
+      factory.get_state_instance().get_test_state(test_path)).visible):
+    show_window()
+  else:
+    window.hide()
 
+  # When gtk.main() is running, it ignores all uncaught exceptions, which is
+  # not preferred by most of our factory tests. To prevent writing special
+  # function raising errors, we hook top level exception handler to always
+  # leave GTK main and raise exception again.
+
+  def exception_hook(exc_type, value, traceback):
+    # Prevent re-entrant.
     sys.excepthook = old_excepthook
-    exc_info = session.get('exception')
-    if exc_info is not None:
-       logging.error(exc_info[0], exc_info=exc_info)
-       raise FactoryTestFailure(exc_info[1])
+    session['exception'] = (exc_type, value, traceback)
+    gobject.idle_add(gtk.main_quit)
+    return old_excepthook(exc_type, value, traceback)
+
+  session = {}
+  old_excepthook = sys.excepthook
+  sys.excepthook = exception_hook
+
+  gtk.main()
+
+  if not is_chrome_ui():
+    gtk.gdk.pointer_ungrab()
+
+  if cleanup_callback is not None:
+    cleanup_callback()
+
+  del event_client
+
+  sys.excepthook = old_excepthook
+  exc_info = session.get('exception')
+  if exc_info is not None:
+    logging.error(exc_info[0], exc_info=exc_info)
+    raise FactoryTestFailure(exc_info[1])
 
 
 
@@ -567,607 +567,607 @@
 
 
 class Console(object):
-    '''Display a progress log.  Implemented by launching an borderless
-    xterm at a strategic location, and running tail against the log.'''
+  '''Display a progress log. Implemented by launching an borderless
+  xterm at a strategic location, and running tail against the log.'''
 
-    def __init__(self, allocation):
-        # Specify how many lines and characters per line are displayed.
-        XTERM_DISPLAY_LINES = 13
-        XTERM_DISPLAY_CHARS = 120
-        # Extra space reserved for pixels between lines.
-        XTERM_RESERVED_LINES = 3
+  def __init__(self, allocation):
+    # Specify how many lines and characters per line are displayed.
+    XTERM_DISPLAY_LINES = 13
+    XTERM_DISPLAY_CHARS = 120
+    # Extra space reserved for pixels between lines.
+    XTERM_RESERVED_LINES = 3
 
-        xterm_coords = '%dx%d+%d+%d' % (XTERM_DISPLAY_CHARS,
-                                        XTERM_DISPLAY_LINES,
-                                        allocation.x,
-                                        allocation.y)
-        xterm_reserved_height = gtk.gdk.screen_height() - allocation.y
-        font_size = int(float(xterm_reserved_height) / (XTERM_DISPLAY_LINES +
-                                                        XTERM_RESERVED_LINES))
-        logging.info('xterm_reserved_height = %d' % xterm_reserved_height)
-        logging.info('font_size = %d' % font_size)
-        logging.info('xterm_coords = %s', xterm_coords)
-        xterm_opts = ('-bg black -fg lightgray -bw 0 -g %s' % xterm_coords)
-        xterm_cmd = (
-            ['urxvt'] + xterm_opts.split() +
-            ['-fn', 'xft:DejaVu Sans Mono:pixelsize=%s' % font_size] +
-            ['-e', 'bash'] +
-            ['-c', 'tail -f "%s"' % factory.CONSOLE_LOG_PATH])
-        logging.info('xterm_cmd = %s', xterm_cmd)
-        self._proc = subprocess.Popen(xterm_cmd)
+    xterm_coords = '%dx%d+%d+%d' % (XTERM_DISPLAY_CHARS,
+                    XTERM_DISPLAY_LINES,
+                    allocation.x,
+                    allocation.y)
+    xterm_reserved_height = gtk.gdk.screen_height() - allocation.y
+    font_size = int(float(xterm_reserved_height) / (XTERM_DISPLAY_LINES +
+                            XTERM_RESERVED_LINES))
+    logging.info('xterm_reserved_height = %d' % xterm_reserved_height)
+    logging.info('font_size = %d' % font_size)
+    logging.info('xterm_coords = %s', xterm_coords)
+    xterm_opts = ('-bg black -fg lightgray -bw 0 -g %s' % xterm_coords)
+    xterm_cmd = (
+      ['urxvt'] + xterm_opts.split() +
+      ['-fn', 'xft:DejaVu Sans Mono:pixelsize=%s' % font_size] +
+      ['-e', 'bash'] +
+      ['-c', 'tail -f "%s"' % factory.CONSOLE_LOG_PATH])
+    logging.info('xterm_cmd = %s', xterm_cmd)
+    self._proc = subprocess.Popen(xterm_cmd)
 
-    def __del__(self):
-        logging.info('console_proc __del__')
-        self._proc.kill()
+  def __del__(self):
+    logging.info('console_proc __del__')
+    self._proc.kill()
 
 
-class TestLabelBox(gtk.EventBox):  # pylint: disable=R0904
+class TestLabelBox(gtk.EventBox): # pylint: disable=R0904
 
-    def __init__(self, test):
-        gtk.EventBox.__init__(self)
-        self.modify_bg(gtk.STATE_NORMAL, LABEL_COLORS[TestState.UNTESTED])
-        self._is_group = test.is_group()
-        depth = len(test.get_ancestor_groups())
-        self._label_text = ' %s%s%s' % (
-                ' ' * depth,
-                SYMBOL_RIGHT_ARROW if self._is_group else ' ',
-                test.label_en)
-        if self._is_group:
-            self._label_text_collapsed = ' %s%s%s' % (
-                    ' ' * depth,
-                    SYMBOL_DOWN_ARROW if self._is_group else '',
-                    test.label_en)
-        self._label_en = make_label(
-            self._label_text, size=_LABEL_EN_SIZE,
-            font=_LABEL_EN_FONT, alignment=(0, 0.5),
-            fg=_LABEL_UNTESTED_FG)
-        self._label_zh = make_label(
-            test.label_zh, size=_LABEL_ZH_SIZE,
-            font=_LABEL_ZH_FONT, alignment=(0.5, 0.5),
-            fg=_LABEL_UNTESTED_FG)
-        self._label_t = make_label(
-            '', size=_LABEL_T_SIZE, font=_LABEL_T_FONT,
-            alignment=(0.5, 0.5), fg=BLACK)
-        hbox = gtk.HBox()
-        hbox.pack_start(self._label_en, False, False)
-        hbox.pack_start(self._label_zh, False, False)
-        hbox.pack_start(self._label_t, False, False)
-        vbox = gtk.VBox()
-        vbox.pack_start(hbox, False, False)
-        vbox.pack_start(make_hsep(), False, False)
-        self.add(vbox)
-        self._status = None
+  def __init__(self, test):
+    gtk.EventBox.__init__(self)
+    self.modify_bg(gtk.STATE_NORMAL, LABEL_COLORS[TestState.UNTESTED])
+    self._is_group = test.is_group()
+    depth = len(test.get_ancestor_groups())
+    self._label_text = ' %s%s%s' % (
+        ' ' * depth,
+        SYMBOL_RIGHT_ARROW if self._is_group else ' ',
+        test.label_en)
+    if self._is_group:
+      self._label_text_collapsed = ' %s%s%s' % (
+          ' ' * depth,
+          SYMBOL_DOWN_ARROW if self._is_group else '',
+          test.label_en)
+    self._label_en = make_label(
+      self._label_text, size=_LABEL_EN_SIZE,
+      font=_LABEL_EN_FONT, alignment=(0, 0.5),
+      fg=_LABEL_UNTESTED_FG)
+    self._label_zh = make_label(
+      test.label_zh, size=_LABEL_ZH_SIZE,
+      font=_LABEL_ZH_FONT, alignment=(0.5, 0.5),
+      fg=_LABEL_UNTESTED_FG)
+    self._label_t = make_label(
+      '', size=_LABEL_T_SIZE, font=_LABEL_T_FONT,
+      alignment=(0.5, 0.5), fg=BLACK)
+    hbox = gtk.HBox()
+    hbox.pack_start(self._label_en, False, False)
+    hbox.pack_start(self._label_zh, False, False)
+    hbox.pack_start(self._label_t, False, False)
+    vbox = gtk.VBox()
+    vbox.pack_start(hbox, False, False)
+    vbox.pack_start(make_hsep(), False, False)
+    self.add(vbox)
+    self._status = None
 
-    def set_shortcut(self, shortcut):
-        if shortcut is None:
-            return
-        self._label_t.set_text('C-%s' % shortcut.upper())
-        attrs = self._label_en.get_attributes() or pango.AttrList()
-        attrs.filter(lambda attr: attr.type == pango.ATTR_UNDERLINE)
-        index_hotkey = self._label_en.get_text().upper().find(shortcut.upper())
-        if index_hotkey != -1:
-            attrs.insert(pango.AttrUnderline(
-                pango.UNDERLINE_LOW, index_hotkey, index_hotkey + 1))
-            attrs.insert(pango.AttrWeight(
-                pango.WEIGHT_BOLD, index_hotkey, index_hotkey + 1))
-        self._label_en.set_attributes(attrs)
-        self.queue_draw()
+  def set_shortcut(self, shortcut):
+    if shortcut is None:
+      return
+    self._label_t.set_text('C-%s' % shortcut.upper())
+    attrs = self._label_en.get_attributes() or pango.AttrList()
+    attrs.filter(lambda attr: attr.type == pango.ATTR_UNDERLINE)
+    index_hotkey = self._label_en.get_text().upper().find(shortcut.upper())
+    if index_hotkey != -1:
+      attrs.insert(pango.AttrUnderline(
+        pango.UNDERLINE_LOW, index_hotkey, index_hotkey + 1))
+      attrs.insert(pango.AttrWeight(
+        pango.WEIGHT_BOLD, index_hotkey, index_hotkey + 1))
+    self._label_en.set_attributes(attrs)
+    self.queue_draw()
 
-    def update(self, status):
-        if self._status == status:
-            return
-        self._status = status
-        label_fg = (_LABEL_UNTESTED_FG if status == TestState.UNTESTED
-                    else BLACK)
-        if self._is_group:
-            self._label_en.set_text(
-                    self._label_text_collapsed if status == TestState.ACTIVE
-                    else self._label_text)
+  def update(self, status):
+    if self._status == status:
+      return
+    self._status = status
+    label_fg = (_LABEL_UNTESTED_FG if status == TestState.UNTESTED
+          else BLACK)
+    if self._is_group:
+      self._label_en.set_text(
+          self._label_text_collapsed if status == TestState.ACTIVE
+          else self._label_text)
 
-        for label in [self._label_en, self._label_zh, self._label_t]:
-            label.modify_fg(gtk.STATE_NORMAL, label_fg)
-        self.modify_bg(gtk.STATE_NORMAL, LABEL_COLORS[status])
-        self.queue_draw()
+    for label in [self._label_en, self._label_zh, self._label_t]:
+      label.modify_fg(gtk.STATE_NORMAL, label_fg)
+    self.modify_bg(gtk.STATE_NORMAL, LABEL_COLORS[status])
+    self.queue_draw()
 
 
 class ReviewInformation(object):
 
-    LABEL_EN_FONT = pango.FontDescription('courier new extra-condensed 16')
-    TAB_BORDER = 20
+  LABEL_EN_FONT = pango.FontDescription('courier new extra-condensed 16')
+  TAB_BORDER = 20
 
-    def __init__(self, test_list):
-        self.test_list = test_list
+  def __init__(self, test_list):
+    self.test_list = test_list
 
-    def make_error_tab(self, test, state):
-        msg = '%s (%s)\n%s' % (test.label_en, test.label_zh,
-                               str(state.error_msg))
-        label = make_label(msg, font=self.LABEL_EN_FONT, alignment=(0.0, 0.0))
-        label.set_line_wrap(True)
-        frame = gtk.Frame()
-        frame.add(label)
-        return frame
+  def make_error_tab(self, test, state):
+    msg = '%s (%s)\n%s' % (test.label_en, test.label_zh,
+                str(state.error_msg))
+    label = make_label(msg, font=self.LABEL_EN_FONT, alignment=(0.0, 0.0))
+    label.set_line_wrap(True)
+    frame = gtk.Frame()
+    frame.add(label)
+    return frame
 
-    def make_widget(self):
-        bg_color = gtk.gdk.Color(0x1000, 0x1000, 0x1000)
-        self.notebook = gtk.Notebook()
-        self.notebook.modify_bg(gtk.STATE_NORMAL, bg_color)
+  def make_widget(self):
+    bg_color = gtk.gdk.Color(0x1000, 0x1000, 0x1000)
+    self.notebook = gtk.Notebook()
+    self.notebook.modify_bg(gtk.STATE_NORMAL, bg_color)
 
-        test_list = self.test_list
-        state_map = test_list.get_state_map()
-        tab, _ = make_summary_box([test_list], state_map)
-        tab.set_border_width(self.TAB_BORDER)
-        self.notebook.append_page(tab, make_label('Summary'))
+    test_list = self.test_list
+    state_map = test_list.get_state_map()
+    tab, _ = make_summary_box([test_list], state_map)
+    tab.set_border_width(self.TAB_BORDER)
+    self.notebook.append_page(tab, make_label('Summary'))
 
-        for i, t in izip(
-            count(1),
-            [t for t in test_list.walk()
-             if state_map[t].status == factory.TestState.FAILED
-             and t.is_leaf()]):
-            tab = self.make_error_tab(t, state_map[t])
-            tab.set_border_width(self.TAB_BORDER)
-            self.notebook.append_page(tab, make_label('#%02d' % i))
+    for i, t in izip(
+      count(1),
+      [t for t in test_list.walk()
+       if state_map[t].status == factory.TestState.FAILED
+       and t.is_leaf()]):
+      tab = self.make_error_tab(t, state_map[t])
+      tab.set_border_width(self.TAB_BORDER)
+      self.notebook.append_page(tab, make_label('#%02d' % i))
 
-        prompt = 'Review: Test Status Information'
-        if self.notebook.get_n_pages() > 1:
-            prompt += '\nPress left/right to change tabs'
+    prompt = 'Review: Test Status Information'
+    if self.notebook.get_n_pages() > 1:
+      prompt += '\nPress left/right to change tabs'
 
-        control_label = make_label(prompt, font=self.LABEL_EN_FONT,
-                                   alignment=(0.5, 0.5))
-        vbox = gtk.VBox()
-        vbox.set_spacing(self.TAB_BORDER)
-        vbox.pack_start(control_label, False, False)
-        vbox.pack_start(self.notebook, False, False)
-        vbox.show_all()
-        vbox.grab_focus = self.notebook.grab_focus
-        return vbox
+    control_label = make_label(prompt, font=self.LABEL_EN_FONT,
+                  alignment=(0.5, 0.5))
+    vbox = gtk.VBox()
+    vbox.set_spacing(self.TAB_BORDER)
+    vbox.pack_start(control_label, False, False)
+    vbox.pack_start(self.notebook, False, False)
+    vbox.show_all()
+    vbox.grab_focus = self.notebook.grab_focus
+    return vbox
 
 
 class TestDirectory(gtk.VBox):
-    '''Widget containing a list of tests, colored by test status.
+  '''Widget containing a list of tests, colored by test status.
 
-    This is the widget corresponding to the RHS test panel.
+  This is the widget corresponding to the RHS test panel.
 
-    Attributes:
-      _label_map: Dict of test path to TestLabelBox objects.  Should
-          contain an entry for each test that has been visible at some
-          time.
-      _visible_status: List of (test, status) pairs reflecting the
-          last refresh of the set of visible tests.  This is used to
-          rememeber what tests were active, to allow implementation of
-          visual refresh only when new active tests appear.
-      _shortcut_map: Dict of keyboard shortcut key to test path.
-          Tracks the current set of keyboard shortcut mappings for the
-          visible set of tests.  This will change when the visible
-          test set changes.
+  Attributes:
+   _label_map: Dict of test path to TestLabelBox objects. Should
+     contain an entry for each test that has been visible at some
+     time.
+   _visible_status: List of (test, status) pairs reflecting the
+     last refresh of the set of visible tests. This is used to
+     rememeber what tests were active, to allow implementation of
+     visual refresh only when new active tests appear.
+   _shortcut_map: Dict of keyboard shortcut key to test path.
+     Tracks the current set of keyboard shortcut mappings for the
+     visible set of tests. This will change when the visible
+     test set changes.
+  '''
+
+  def __init__(self, test_list):
+    gtk.VBox.__init__(self)
+    self.set_spacing(0)
+    self._label_map = {}
+    self._visible_status = []
+    self._shortcut_map = {}
+    self._hard_shortcuts = set(
+      test.kbd_shortcut for test in test_list.walk()
+      if test.kbd_shortcut is not None)
+
+  def _get_test_label(self, test):
+    if test.path in self._label_map:
+      return self._label_map[test.path]
+    label_box = TestLabelBox(test)
+    self._label_map[test.path] = label_box
+    return label_box
+
+  def _remove_shortcut(self, path):
+    reverse_map = dict((v, k) for k, v in self._shortcut_map.items())
+    if path not in reverse_map:
+      logging.error('Removal of non-present shortcut for %s' % path)
+      return
+    shortcut = reverse_map[path]
+    del self._shortcut_map[shortcut]
+
+  def _add_shortcut(self, test):
+    shortcut = test.kbd_shortcut
+    if shortcut in self._shortcut_map:
+      logging.error('Shortcut %s already in use by %s; cannot apply to %s'
+             % (shortcut, self._shortcut_map[shortcut], test.path))
+      shortcut = None
+    if shortcut is None:
+      # Find a suitable shortcut. For groups, use numbers. For
+      # regular tests, use alpha (letters).
+      if test.is_group():
+        gen = (x for x in string.digits if x not in self._shortcut_map)
+      else:
+        gen = (x for x in test.label_en.lower() + string.lowercase
+            if x.isalnum() and x not in self._shortcut_map
+            and x not in self._hard_shortcuts)
+      shortcut = next(gen, None)
+    if shortcut is None:
+      logging.error('Unable to find shortcut for %s' % test.path)
+      return
+    self._shortcut_map[shortcut] = test.path
+    return shortcut
+
+  def handle_xevent(self, dummy_src, dummy_cond,
+           xhandle, keycode_map, event_client):
+    for dummy_i in range(0, xhandle.pending_events()):
+      xevent = xhandle.next_event()
+      if xevent.type != X.KeyPress:
+        continue
+      keycode = xevent.detail
+      if keycode not in keycode_map:
+        logging.warning('Ignoring unknown keycode %r' % keycode)
+        continue
+      shortcut = keycode_map[keycode]
+
+      if (xevent.state & GLOBAL_HOT_KEY_MASK == GLOBAL_HOT_KEY_MASK):
+        event_type = GLOBAL_HOT_KEY_EVENTS.get(shortcut)
+        if event_type:
+          event_client.post_event(Event(event_type))
+        else:
+          logging.warning('Unbound global hot key %s', key)
+      else:
+        if shortcut not in self._shortcut_map:
+          logging.warning('Ignoring unbound shortcut %r' % shortcut)
+          continue
+        test_path = self._shortcut_map[shortcut]
+        event_client.post_event(Event(Event.Type.SWITCH_TEST,
+                       path=test_path))
+    return True
+
+  def update(self, new_test_status):
+    '''Refresh the RHS test list to show current status and active groups.
+
+    Refresh the set of visible tests only when new active tests
+    arise. This avoids visual volatility when switching between
+    tests (intervals where no test is active). Also refresh at
+    initial startup.
+
+    Args:
+     new_test_status: A list of (test, status) tuples. The tests
+       order should match how they should be displayed in the
+       directory (rhs panel).
     '''
+    old_active = set(t for t, s in self._visible_status
+             if s == TestState.ACTIVE)
+    new_active = set(t for t, s in new_test_status
+             if s == TestState.ACTIVE)
+    new_visible = set(t for t, s in new_test_status)
+    old_visible = set(t for t, s in self._visible_status)
 
-    def __init__(self, test_list):
-        gtk.VBox.__init__(self)
-        self.set_spacing(0)
-        self._label_map = {}
-        self._visible_status = []
-        self._shortcut_map = {}
-        self._hard_shortcuts = set(
-            test.kbd_shortcut for test in test_list.walk()
-            if test.kbd_shortcut is not None)
+    if old_active and not new_active - old_active:
+      # No new active tests, so do not change the displayed test
+      # set, only update the displayed status for currently
+      # visible tests. Not updating _visible_status allows us
+      # to remember the last set of active tests.
+      for test, _ in self._visible_status:
+        status = test.get_state().status
+        self._label_map[test.path].update(status)
+      return
 
-    def _get_test_label(self, test):
-        if test.path in self._label_map:
-            return self._label_map[test.path]
-        label_box = TestLabelBox(test)
-        self._label_map[test.path] = label_box
-        return label_box
+    self._visible_status = new_test_status
 
-    def _remove_shortcut(self, path):
-        reverse_map = dict((v, k) for k, v in self._shortcut_map.items())
-        if path not in reverse_map:
-            logging.error('Removal of non-present shortcut for %s' % path)
-            return
-        shortcut = reverse_map[path]
-        del self._shortcut_map[shortcut]
+    new_test_map = dict((t.path, t) for t, s in new_test_status)
 
-    def _add_shortcut(self, test):
-        shortcut = test.kbd_shortcut
-        if shortcut in self._shortcut_map:
-            logging.error('Shortcut %s already in use by %s; cannot apply to %s'
-                          % (shortcut, self._shortcut_map[shortcut], test.path))
-            shortcut = None
-        if shortcut is None:
-            # Find a suitable shortcut.  For groups, use numbers.  For
-            # regular tests, use alpha (letters).
-            if test.is_group():
-                gen = (x for x in string.digits if x not in self._shortcut_map)
-            else:
-                gen = (x for x in test.label_en.lower() + string.lowercase
-                       if x.isalnum() and x not in self._shortcut_map
-                       and x not in self._hard_shortcuts)
-            shortcut = next(gen, None)
-        if shortcut is None:
-            logging.error('Unable to find shortcut for %s' % test.path)
-            return
-        self._shortcut_map[shortcut] = test.path
-        return shortcut
+    for test in old_visible - new_visible:
+      label_box = self._label_map[test.path]
+      logging.debug('removing %s test label' % test.path)
+      self.remove(label_box)
+      self._remove_shortcut(test.path)
 
-    def handle_xevent(self, dummy_src, dummy_cond,
-                      xhandle, keycode_map, event_client):
-        for dummy_i in range(0, xhandle.pending_events()):
-            xevent = xhandle.next_event()
-            if xevent.type != X.KeyPress:
-                continue
-            keycode = xevent.detail
-            if keycode not in keycode_map:
-                logging.warning('Ignoring unknown keycode %r' % keycode)
-                continue
-            shortcut = keycode_map[keycode]
+    new_tests = new_visible - old_visible
 
-            if (xevent.state & GLOBAL_HOT_KEY_MASK == GLOBAL_HOT_KEY_MASK):
-                event_type = GLOBAL_HOT_KEY_EVENTS.get(shortcut)
-                if event_type:
-                    event_client.post_event(Event(event_type))
-                else:
-                    logging.warning('Unbound global hot key %s', key)
-            else:
-                if shortcut not in self._shortcut_map:
-                    logging.warning('Ignoring unbound shortcut %r' % shortcut)
-                    continue
-                test_path = self._shortcut_map[shortcut]
-                event_client.post_event(Event(Event.Type.SWITCH_TEST,
-                                              path=test_path))
-        return True
+    for position, (test, status) in enumerate(new_test_status):
+      label_box = self._get_test_label(test)
+      if test in new_tests:
+        shortcut = self._add_shortcut(test)
+        label_box = self._get_test_label(test)
+        label_box.set_shortcut(shortcut)
+        logging.debug('adding %s test label (sortcut %r, pos %d)' %
+               (test.path, shortcut, position))
+        self.pack_start(label_box, False, False)
+      self.reorder_child(label_box, position)
+      label_box.update(status)
 
-    def update(self, new_test_status):
-        '''Refresh the RHS test list to show current status and active groups.
-
-        Refresh the set of visible tests only when new active tests
-        arise.  This avoids visual volatility when switching between
-        tests (intervals where no test is active).  Also refresh at
-        initial startup.
-
-        Args:
-          new_test_status: A list of (test, status) tuples.  The tests
-              order should match how they should be displayed in the
-              directory (rhs panel).
-        '''
-        old_active = set(t for t, s in self._visible_status
-                         if s == TestState.ACTIVE)
-        new_active = set(t for t, s in new_test_status
-                         if s == TestState.ACTIVE)
-        new_visible = set(t for t, s in new_test_status)
-        old_visible = set(t for t, s in self._visible_status)
-
-        if old_active and not new_active - old_active:
-            # No new active tests, so do not change the displayed test
-            # set, only update the displayed status for currently
-            # visible tests.  Not updating _visible_status allows us
-            # to remember the last set of active tests.
-            for test, _ in self._visible_status:
-                status = test.get_state().status
-                self._label_map[test.path].update(status)
-            return
-
-        self._visible_status = new_test_status
-
-        new_test_map = dict((t.path, t) for t, s in new_test_status)
-
-        for test in old_visible - new_visible:
-            label_box = self._label_map[test.path]
-            logging.debug('removing %s test label' % test.path)
-            self.remove(label_box)
-            self._remove_shortcut(test.path)
-
-        new_tests = new_visible - old_visible
-
-        for position, (test, status) in enumerate(new_test_status):
-            label_box = self._get_test_label(test)
-            if test in new_tests:
-                shortcut = self._add_shortcut(test)
-                label_box = self._get_test_label(test)
-                label_box.set_shortcut(shortcut)
-                logging.debug('adding %s test label (sortcut %r, pos %d)' %
-                              (test.path, shortcut, position))
-                self.pack_start(label_box, False, False)
-            self.reorder_child(label_box, position)
-            label_box.update(status)
-
-        self.show_all()
+    self.show_all()
 
 
 
 class UiState(object):
 
-    WIDGET_NONE = 0
-    WIDGET_IDLE = 1
-    WIDGET_SUMMARY = 2
-    WIDGET_REVIEW = 3
+  WIDGET_NONE = 0
+  WIDGET_IDLE = 1
+  WIDGET_SUMMARY = 2
+  WIDGET_REVIEW = 3
 
-    def __init__(self, test_widget_box, test_directory_widget, test_list):
-        self._test_widget_box = test_widget_box
-        self._test_directory_widget = test_directory_widget
-        self._test_list = test_list
-        self._transition_count = 0
-        self._active_test_label_map = None
-        self._active_widget = self.WIDGET_NONE
-        self.update_test_state()
+  def __init__(self, test_widget_box, test_directory_widget, test_list):
+    self._test_widget_box = test_widget_box
+    self._test_directory_widget = test_directory_widget
+    self._test_list = test_list
+    self._transition_count = 0
+    self._active_test_label_map = None
+    self._active_widget = self.WIDGET_NONE
+    self.update_test_state()
 
-    def show_idle_widget(self):
-        self.remove_state_widget()
-        self._test_widget_box.set(0.5, 0.5, 0.0, 0.0)
-        self._test_widget_box.set_padding(0, 0, 0, 0)
-        label = make_label(MESSAGE_NO_ACTIVE_TESTS,
-                           font=_OTHER_LABEL_FONT,
-                           alignment=(0.5, 0.5))
-        self._test_widget_box.add(label)
-        self._test_widget_box.show_all()
-        self._active_widget = self.WIDGET_IDLE
+  def show_idle_widget(self):
+    self.remove_state_widget()
+    self._test_widget_box.set(0.5, 0.5, 0.0, 0.0)
+    self._test_widget_box.set_padding(0, 0, 0, 0)
+    label = make_label(MESSAGE_NO_ACTIVE_TESTS,
+              font=_OTHER_LABEL_FONT,
+              alignment=(0.5, 0.5))
+    self._test_widget_box.add(label)
+    self._test_widget_box.show_all()
+    self._active_widget = self.WIDGET_IDLE
 
-    def show_summary_widget(self):
-        self.remove_state_widget()
-        state_map = self._test_list.get_state_map()
-        self._test_widget_box.set(0.5, 0.0, 0.0, 0.0)
-        self._test_widget_box.set_padding(40, 0, 0, 0)
-        vbox, self._active_test_label_map = make_summary_box(
-            [t for t in self._test_list.subtests
-             if state_map[t].status == TestState.ACTIVE],
-            state_map)
-        self._test_widget_box.add(vbox)
-        self._test_widget_box.show_all()
-        self._active_widget = self.WIDGET_SUMMARY
+  def show_summary_widget(self):
+    self.remove_state_widget()
+    state_map = self._test_list.get_state_map()
+    self._test_widget_box.set(0.5, 0.0, 0.0, 0.0)
+    self._test_widget_box.set_padding(40, 0, 0, 0)
+    vbox, self._active_test_label_map = make_summary_box(
+      [t for t in self._test_list.subtests
+       if state_map[t].status == TestState.ACTIVE],
+      state_map)
+    self._test_widget_box.add(vbox)
+    self._test_widget_box.show_all()
+    self._active_widget = self.WIDGET_SUMMARY
 
-    def show_review_widget(self):
-        self.remove_state_widget()
-        self._review_request = False
-        self._test_widget_box.set(0.5, 0.5, 0.0, 0.0)
-        self._test_widget_box.set_padding(0, 0, 0, 0)
-        widget = ReviewInformation(self._test_list).make_widget()
-        self._test_widget_box.add(widget)
-        self._test_widget_box.show_all()
-        widget.grab_focus()
-        self._active_widget = self.WIDGET_REVIEW
+  def show_review_widget(self):
+    self.remove_state_widget()
+    self._review_request = False
+    self._test_widget_box.set(0.5, 0.5, 0.0, 0.0)
+    self._test_widget_box.set_padding(0, 0, 0, 0)
+    widget = ReviewInformation(self._test_list).make_widget()
+    self._test_widget_box.add(widget)
+    self._test_widget_box.show_all()
+    widget.grab_focus()
+    self._active_widget = self.WIDGET_REVIEW
 
-    def remove_state_widget(self):
-        for child in self._test_widget_box.get_children():
-            child.hide()
-            self._test_widget_box.remove(child)
-        self._active_test_label_map = None
-        self._active_widget = self.WIDGET_NONE
+  def remove_state_widget(self):
+    for child in self._test_widget_box.get_children():
+      child.hide()
+      self._test_widget_box.remove(child)
+    self._active_test_label_map = None
+    self._active_widget = self.WIDGET_NONE
 
-    def update_test_state(self):
-        state_map = self._test_list.get_state_map()
-        active_tests = set(
-            t for t in self._test_list.walk()
-            if t.is_leaf() and state_map[t].status == TestState.ACTIVE)
-        active_groups = set(g for t in active_tests
-                            for g in t.get_ancestor_groups())
+  def update_test_state(self):
+    state_map = self._test_list.get_state_map()
+    active_tests = set(
+      t for t in self._test_list.walk()
+      if t.is_leaf() and state_map[t].status == TestState.ACTIVE)
+    active_groups = set(g for t in active_tests
+              for g in t.get_ancestor_groups())
 
-        def filter_visible_test_state(tests):
-            '''List currently visible tests and their status.
+    def filter_visible_test_state(tests):
+      '''List currently visible tests and their status.
 
-            Visible means currently displayed in the RHS panel.
-            Visiblity is implied by being a top level test or having
-            membership in a group with at least one active test.
+      Visible means currently displayed in the RHS panel.
+      Visiblity is implied by being a top level test or having
+      membership in a group with at least one active test.
 
-            Returns:
-              A list of (test, status) tuples for all visible tests,
-              in the order they should be displayed.
-            '''
-            results = []
-            for test in tests:
-                if test.is_group():
-                    results.append((test, TestState.UNTESTED))
-                    if test not in active_groups:
-                        continue
-                    results += filter_visible_test_state(test.subtests)
-                else:
-                    results.append((test, state_map[test].status))
-            return results
+      Returns:
+       A list of (test, status) tuples for all visible tests,
+       in the order they should be displayed.
+      '''
+      results = []
+      for test in tests:
+        if test.is_group():
+          results.append((test, TestState.UNTESTED))
+          if test not in active_groups:
+            continue
+          results += filter_visible_test_state(test.subtests)
+        else:
+          results.append((test, state_map[test].status))
+      return results
 
-        visible_test_state = filter_visible_test_state(self._test_list.subtests)
-        self._test_directory_widget.update(visible_test_state)
+    visible_test_state = filter_visible_test_state(self._test_list.subtests)
+    self._test_directory_widget.update(visible_test_state)
 
-        if not active_tests:
-            # Display the idle or review information screen.
-            def waiting_for_transition():
-                return (self._active_widget not in
-                        [self.WIDGET_REVIEW, self.WIDGET_IDLE])
+    if not active_tests:
+      # Display the idle or review information screen.
+      def waiting_for_transition():
+        return (self._active_widget not in
+            [self.WIDGET_REVIEW, self.WIDGET_IDLE])
 
-            # For smooth transition between tests, idle widget if activated only
-            # after _NO_ACTIVE_TEST_DELAY_MS without state change.
-            def idle_transition_check(cookie):
-                if (waiting_for_transition() and
-                    cookie == self._transition_count):
-                    self._transition_count += 1
-                    self.show_idle_widget()
-                return False
+      # For smooth transition between tests, idle widget if activated only
+      # after _NO_ACTIVE_TEST_DELAY_MS without state change.
+      def idle_transition_check(cookie):
+        if (waiting_for_transition() and
+          cookie == self._transition_count):
+          self._transition_count += 1
+          self.show_idle_widget()
+        return False
 
-            if waiting_for_transition():
-                gobject.timeout_add(_NO_ACTIVE_TEST_DELAY_MS,
-                                    idle_transition_check,
-                                    self._transition_count)
-            return
+      if waiting_for_transition():
+        gobject.timeout_add(_NO_ACTIVE_TEST_DELAY_MS,
+                  idle_transition_check,
+                  self._transition_count)
+      return
 
-        self._transition_count += 1
+    self._transition_count += 1
 
-        if any(t.has_ui for t in active_tests):
-            # Remove the widget (if any) since there is an active test
-            # with a UI.
-            self.remove_state_widget()
-            return
+    if any(t.has_ui for t in active_tests):
+      # Remove the widget (if any) since there is an active test
+      # with a UI.
+      self.remove_state_widget()
+      return
 
-        if (self._active_test_label_map is not None and
-            all(t in self._active_test_label_map for t in active_tests)):
-            # All active tests are already present in the summary, so just
-            # update their states.
-            for test, label in self._active_test_label_map.iteritems():
-                label.modify_fg(
-                    gtk.STATE_NORMAL,
-                    LABEL_COLORS[state_map[test].status])
-            return
+    if (self._active_test_label_map is not None and
+      all(t in self._active_test_label_map for t in active_tests)):
+      # All active tests are already present in the summary, so just
+      # update their states.
+      for test, label in self._active_test_label_map.iteritems():
+        label.modify_fg(
+          gtk.STATE_NORMAL,
+          LABEL_COLORS[state_map[test].status])
+      return
 
-        # No active UI; draw summary of current test states
-        self.show_summary_widget()
+    # No active UI; draw summary of current test states
+    self.show_summary_widget()
 
 
 def grab_shortcut_keys(disp, event_handler, event_client):
-    # We want to receive KeyPress events
-    root = disp.screen().root
-    root.change_attributes(event_mask = X.KeyPressMask)
-    shortcut_set = set(string.lowercase + string.digits)
-    keycode_map = {}
-    for mod, shortcut in ([(X.ControlMask, k) for k in shortcut_set] +
-                          [(GLOBAL_HOT_KEY_MASK, k)
-                           for k in GLOBAL_HOT_KEY_EVENTS] +
-                          [(X.Mod1Mask, 'Tab')]):  # Mod1 = Alt
-        keysym = gtk.gdk.keyval_from_name(shortcut)
-        keycode = disp.keysym_to_keycode(keysym)
-        keycode_map[keycode] = shortcut
-        root.grab_key(keycode, mod, 1, X.GrabModeAsync, X.GrabModeAsync)
-    # This flushes the XGrabKey calls to the server.
-    for dummy_x in range(0, root.display.pending_events()):
-        root.display.next_event()
-    gobject.io_add_watch(root.display, gobject.IO_IN, event_handler,
-                         root.display, keycode_map, event_client)
+  # We want to receive KeyPress events
+  root = disp.screen().root
+  root.change_attributes(event_mask = X.KeyPressMask)
+  shortcut_set = set(string.lowercase + string.digits)
+  keycode_map = {}
+  for mod, shortcut in ([(X.ControlMask, k) for k in shortcut_set] +
+             [(GLOBAL_HOT_KEY_MASK, k)
+              for k in GLOBAL_HOT_KEY_EVENTS] +
+             [(X.Mod1Mask, 'Tab')]): # Mod1 = Alt
+    keysym = gtk.gdk.keyval_from_name(shortcut)
+    keycode = disp.keysym_to_keycode(keysym)
+    keycode_map[keycode] = shortcut
+    root.grab_key(keycode, mod, 1, X.GrabModeAsync, X.GrabModeAsync)
+  # This flushes the XGrabKey calls to the server.
+  for dummy_x in range(0, root.display.pending_events()):
+    root.display.next_event()
+  gobject.io_add_watch(root.display, gobject.IO_IN, event_handler,
+             root.display, keycode_map, event_client)
 
 
 def start_reposition_thread(title_regexp):
-    '''Starts a thread to reposition a client window once it appears.
+  '''Starts a thread to reposition a client window once it appears.
 
-    This is useful to avoid blocking the console.
+  This is useful to avoid blocking the console.
 
-    Args:
-      title_regexp: A regexp for the window's title (used to find the
-        window to reposition).
-    '''
-    test_widget_position = (
-        factory.get_shared_data('test_widget_position'))
-    if not test_widget_position:
+  Args:
+   title_regexp: A regexp for the window's title (used to find the
+    window to reposition).
+  '''
+  test_widget_position = (
+    factory.get_shared_data('test_widget_position'))
+  if not test_widget_position:
+    return
+
+  def reposition():
+    display = Display()
+    root = display.screen().root
+    for i in xrange(50):
+      wins = [win for win in root.query_tree().children
+          if re.match(title_regexp, win.get_wm_name())]
+      if wins:
+        wins[0].configure(x=test_widget_position[0],
+                 y=test_widget_position[1])
+        display.sync()
         return
-
-    def reposition():
-        display = Display()
-        root = display.screen().root
-        for i in xrange(50):
-            wins = [win for win in root.query_tree().children
-                    if re.match(title_regexp, win.get_wm_name())]
-            if wins:
-                wins[0].configure(x=test_widget_position[0],
-                                  y=test_widget_position[1])
-                display.sync()
-                return
-            # Wait 100 ms and try again.
-            time.sleep(.1)
-    thread = threading.Thread(target=reposition)
-    thread.daemon = True
-    thread.start()
+      # Wait 100 ms and try again.
+      time.sleep(.1)
+  thread = threading.Thread(target=reposition)
+  thread.daemon = True
+  thread.start()
 
 
 def main(test_list_path):
-    '''Starts the main UI.
+  '''Starts the main UI.
 
-    This is launched by the autotest/cros/factory/client.
-    When operators press keyboard shortcuts, the shortcut
-    value is sent as an event to the control program.'''
+  This is launched by the autotest/cros/factory/client.
+  When operators press keyboard shortcuts, the shortcut
+  value is sent as an event to the control program.'''
 
-    test_list = None
-    ui_state = None
-    event_client = None
+  test_list = None
+  ui_state = None
+  event_client = None
 
-    def handle_key_release_event(_, event):
-        logging.info('base ui key event (%s)', event.keyval)
-        return True
+  def handle_key_release_event(_, event):
+    logging.info('base ui key event (%s)', event.keyval)
+    return True
 
-    def handle_event(event):
-        if event.type == Event.Type.STATE_CHANGE:
-            ui_state.update_test_state()
-        elif event.type == Event.Type.REVIEW:
-            logging.info("Operator activates review information screen")
-            ui_state.show_review_widget()
+  def handle_event(event):
+    if event.type == Event.Type.STATE_CHANGE:
+      ui_state.update_test_state()
+    elif event.type == Event.Type.REVIEW:
+      logging.info("Operator activates review information screen")
+      ui_state.show_review_widget()
 
-    test_list = factory.read_test_list(test_list_path)
+  test_list = factory.read_test_list(test_list_path)
 
-    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
-    window.connect('destroy', lambda _: gtk.main_quit())
-    window.modify_bg(gtk.STATE_NORMAL, BLACK)
+  window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+  window.connect('destroy', lambda _: gtk.main_quit())
+  window.modify_bg(gtk.STATE_NORMAL, BLACK)
 
-    disp = Display()
+  disp = Display()
 
-    event_client = EventClient(
-        callback=handle_event,
-        event_loop=EventClient.EVENT_LOOP_GOBJECT_IO)
+  event_client = EventClient(
+    callback=handle_event,
+    event_loop=EventClient.EVENT_LOOP_GOBJECT_IO)
 
-    screen = window.get_screen()
-    if (screen is None):
-        logging.info('ERROR: communication with the X server is not working, ' +
-                    'could not find a working screen.  UI exiting.')
-        sys.exit(1)
+  screen = window.get_screen()
+  if (screen is None):
+    logging.info('ERROR: communication with the X server is not working, ' +
+          'could not find a working screen. UI exiting.')
+    sys.exit(1)
 
-    screen_size_str = os.environ.get('CROS_SCREEN_SIZE')
-    if screen_size_str:
-        match = re.match(r'^(\d+)x(\d+)$', screen_size_str)
-        assert match, 'CROS_SCREEN_SIZE should be {width}x{height}'
-        screen_size = (int(match.group(1)), int(match.group(2)))
-    else:
-        screen_size = (screen.get_width(), screen.get_height())
-    window.set_size_request(*screen_size)
+  screen_size_str = os.environ.get('CROS_SCREEN_SIZE')
+  if screen_size_str:
+    match = re.match(r'^(\d+)x(\d+)$', screen_size_str)
+    assert match, 'CROS_SCREEN_SIZE should be {width}x{height}'
+    screen_size = (int(match.group(1)), int(match.group(2)))
+  else:
+    screen_size = (screen.get_width(), screen.get_height())
+  window.set_size_request(*screen_size)
 
-    test_directory = TestDirectory(test_list)
+  test_directory = TestDirectory(test_list)
 
-    rhs_box = gtk.EventBox()
-    rhs_box.modify_bg(gtk.STATE_NORMAL, _LABEL_TROUGH_COLOR)
-    rhs_box.add(test_directory)
+  rhs_box = gtk.EventBox()
+  rhs_box.modify_bg(gtk.STATE_NORMAL, _LABEL_TROUGH_COLOR)
+  rhs_box.add(test_directory)
 
-    console_box = gtk.EventBox()
-    console_box.set_size_request(*convert_pixels((-1, 180)))
-    console_box.modify_bg(gtk.STATE_NORMAL, BLACK)
+  console_box = gtk.EventBox()
+  console_box.set_size_request(*convert_pixels((-1, 180)))
+  console_box.modify_bg(gtk.STATE_NORMAL, BLACK)
 
-    test_widget_box = gtk.Alignment()
-    test_widget_box.set_size_request(-1, -1)
+  test_widget_box = gtk.Alignment()
+  test_widget_box.set_size_request(-1, -1)
 
-    lhs_box = gtk.VBox()
-    lhs_box.pack_end(console_box, False, False)
-    lhs_box.pack_start(test_widget_box)
-    lhs_box.pack_start(make_hsep(3), False, False)
+  lhs_box = gtk.VBox()
+  lhs_box.pack_end(console_box, False, False)
+  lhs_box.pack_start(test_widget_box)
+  lhs_box.pack_start(make_hsep(3), False, False)
 
-    base_box = gtk.HBox()
-    base_box.pack_end(rhs_box, False, False)
-    base_box.pack_end(make_vsep(3), False, False)
-    base_box.pack_start(lhs_box)
+  base_box = gtk.HBox()
+  base_box.pack_end(rhs_box, False, False)
+  base_box.pack_end(make_vsep(3), False, False)
+  base_box.pack_start(lhs_box)
 
-    window.connect('key-release-event', handle_key_release_event)
-    window.add_events(gtk.gdk.KEY_RELEASE_MASK)
+  window.connect('key-release-event', handle_key_release_event)
+  window.add_events(gtk.gdk.KEY_RELEASE_MASK)
 
-    ui_state = UiState(test_widget_box, test_directory, test_list)
+  ui_state = UiState(test_widget_box, test_directory, test_list)
 
-    window.add(base_box)
-    window.show_all()
+  window.add(base_box)
+  window.show_all()
 
-    grab_shortcut_keys(disp, test_directory.handle_xevent, event_client)
+  grab_shortcut_keys(disp, test_directory.handle_xevent, event_client)
 
-    hide_cursor(window.window)
+  hide_cursor(window.window)
 
-    test_widget_allocation = test_widget_box.get_allocation()
-    test_widget_size = (test_widget_allocation.width,
-                        test_widget_allocation.height)
-    factory.set_shared_data('test_widget_size', test_widget_size)
+  test_widget_allocation = test_widget_box.get_allocation()
+  test_widget_size = (test_widget_allocation.width,
+            test_widget_allocation.height)
+  factory.set_shared_data('test_widget_size', test_widget_size)
 
-    if not factory.in_chroot():
-        dummy_console = Console(console_box.get_allocation())
+  if not factory.in_chroot():
+    dummy_console = Console(console_box.get_allocation())
 
-    event_client.post_event(Event(Event.Type.UI_READY))
+  event_client.post_event(Event(Event.Type.UI_READY))
 
-    logging.info('cros/factory/ui setup done, starting gtk.main()...')
-    gtk.main()
-    logging.info('cros/factory/ui gtk.main() finished, exiting.')
+  logging.info('cros/factory/ui setup done, starting gtk.main()...')
+  gtk.main()
+  logging.info('cros/factory/ui gtk.main() finished, exiting.')
 
 
 if __name__ == '__main__':
-    parser = OptionParser(usage='usage: %prog [options] TEST-LIST-PATH')
-    parser.add_option('-v', '--verbose', dest='verbose',
-                      action='store_true',
-                      help='Enable debug logging')
-    (options, args) = parser.parse_args()
+  parser = OptionParser(usage='usage: %prog [options] TEST-LIST-PATH')
+  parser.add_option('-v', '--verbose', dest='verbose',
+           action='store_true',
+           help='Enable debug logging')
+  (options, args) = parser.parse_args()
 
-    if len(args) != 1:
-        parser.error('Incorrect number of arguments')
+  if len(args) != 1:
+    parser.error('Incorrect number of arguments')
 
-    factory.init_logging('ui', verbose=options.verbose)
-    main(sys.argv[1])
+  factory.init_logging('ui', verbose=options.verbose)
+  main(sys.argv[1])