#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Graphical tool for managing the ATFA and AT communication.

This tool allows for easy graphical access to common ATFA commands.  It also
locates Fastboot devices and can initiate communication between the ATFA and
an Android Things device.
"""
import copy
import datetime
import json
import math
import os
import sets
import sys
import threading
import time

from atftman import AtftManager
from atftman import ProvisionState
from atftman import ProvisionStatus
from atftman import RebootCallback

from fastboot_exceptions import DeviceCreationException
from fastboot_exceptions import DeviceNotFoundException
from fastboot_exceptions import FastbootFailure
from fastboot_exceptions import NoKeysException
from fastboot_exceptions import OsVersionNotAvailableException
from fastboot_exceptions import OsVersionNotCompatibleException
from fastboot_exceptions import PasswordErrorException
from fastboot_exceptions import ProductAttributesFileFormatError
from fastboot_exceptions import ProductNotSpecifiedException

from passlib.hash import pbkdf2_sha256

import psutil

import wx

if sys.platform.startswith('linux'):
  from fastbootsh import FastbootDevice
  from serialmapperlinux import SerialMapper
elif sys.platform.startswith('win'):
  from fastbootsubp import FastbootDevice
  from serialmapperwin import SerialMapper


# colors
COLOR_WHITE = wx.Colour(255, 255, 255)
COLOR_RED = wx.Colour(192, 40, 40)
COLOR_YELLOW = wx.Colour(218, 165, 32)
COLOR_GREEN = wx.Colour(15, 133, 33)
COLOR_BLUE = wx.Colour(36, 120, 198)
COLOR_GREY = wx.Colour(237, 237, 237)
COLOR_DARK_GREY = wx.Colour(117, 117, 117)
COLOR_LIGHT_GREY = wx.Colour(247, 247, 247)
COLOR_LIGHT_GREY_TEXT = wx.Colour(214, 214, 214)
COLOR_BLACK = wx.Colour(0, 0, 0)
COLOR_PICK_BLUE = wx.Colour(149, 169, 235)

# How many target devices allowed.
TARGET_DEV_SIZE = 6

# How many audit files are kept for each ATFA in the atft_audit folder
MAX_AUDIT_FILE_NUMBER = 1

LANGUAGE_OPTIONS = ['English', '简体中文']
LANGUAGE_CONFIGS = ['eng', 'cn']


class AtftException(Exception):
  """The exception class to include device and operation information.
  """

  def __init__(self, exception, operation=None, targets=None):
    """Init the exception class.

    Args:
      exception: The original exception object.
      operation: The operation that generates this exception.
      targets: The list of operating target devices.
    """
    Exception.__init__(self)
    self.exception = exception
    self.operation = operation
    self.targets = targets

  def __str__(self):
    msg = ''
    if self.targets:
      if len(self.targets) == 1:
        msg += '{' + str(self.targets[0]) + '}'
      else:
        msg += '['
        for target in self.targets:
          msg += '{' + str(target) + '}'
        msg += ']'

    if self.operation:
      msg += self.operation + ' Failed! \n'
    msg += self._AddExceptionType(self.exception)
    return msg

  def _AddExceptionType(self, e):
    """Format the exception. Concatenate the exception type with the message.

    Args:
      e: The exception to be printed.
    Returns:
      The exception message.
    """
    return '{0}: {1}'.format(e.__class__.__name__, e)


class AtftString(object):
  """The class containing literal string. """


  def __init__(self, index):
    # Top level menus
    self.MENU_APPLICATION = ['&Application', '&A应用'][index]
    self.MENU_KEY_PROVISIONING = ['Key Provisioning', '密钥传输'][index]
    self.MENU_ATFA_DEVICE = ['ATFA Device', 'ATFA 管理'][index]
    self.MENU_AUDIT = ['Audit', '审计'][index]
    self.MENU_DOWNLOAD_AUDIT = ['Download Audit File', '下载审计文件'][index]
    self.MENU_KEY_MANAGEMENT = ['Key Management', '密钥管理'][index]

    # Second level menus
    self.MENU_CLEAR_COMMAND = ['Clear Command Output', '清空控制台'][index]
    self.MENU_SHOW_STATUS_BAR = ['Show Statusbar', '显示状态栏'][index]
    self.MENU_CHOOSE_PRODUCT = ['Choose Product', '选择产品'][index]
    self.MENU_APP_SETTINGS = ['App Settings', '程序设置'][index]
    self.MENU_QUIT = ['quit', '退出'][index]

    self.MENU_MANUAL_FUSE_VBOOT = ['Fuse Bootloader Vboot Key',
                                   '烧录引导密钥'][index]
    self.MENU_MANUAL_FUSE_ATTR = ['Fuse Permanent Attributes',
                                  '烧录产品信息'][index]
    self.MENU_MANUAL_LOCK_AVB = ['Lock Android Verified Boot', '锁定AVB'][index]
    self.MENU_MANUAL_PROV = ['Provision Key', '传输密钥'][index]

    self.MENU_ATFA_STATUS = ['ATFA Status', '查询余量'][index]
    self.MENU_ATFA_UPDATE = ['Update', '升级'][index]
    self.MENU_KEY_THRESHOLD = ['Key Warning Threshold', '密钥警告阈值'][index]
    self.MENU_REG_FILE = ['Download Reg File', '下载注册文件'][index]
    self.MENU_REBOOT = ['Reboot', '重启'][index]
    self.MENU_SHUTDOWN = ['Shutdown', '关闭'][index]

    self.MENU_STOREKEY = ['Store Key Bundle', '存储密钥打包文件'][index]
    self.MENU_PURGE = ['Purge Key Bundle', '清除密钥'][index]

    # Title
    self.TITLE = ['Android Things Factory Tool',
                  'Android Things 工厂程序'][index]

    # Area titles
    self.TITLE_ATFA_DEV = ['ATFA Device: ', 'ATFA 设备： '][index]
    self.TITLE_SOM_NAME = 'SoM: '
    self.TITLE_PRODUCT_NAME = ['Product: ', '产品： '][index]
    self.TITLE_PRODUCT_NAME_NOTCHOSEN = ['Not Chosen', '未选择'][index]
    self.TITLE_KEYS_LEFT = ['Attestation Keys Left:', '剩余密钥:'][index]
    self.TITLE_TARGET_DEV = ['Target Devices', '目标设备'][index]
    self.TITLE_COMMAND_OUTPUT = ['Command Output', '控制台输出'][index]
    self.TITLE_MAP_USB = [
        'Auto map: Click \'Remap\' button, the UI slots would be randomly '
        'mapped to one of the connected Android Things device. \n'
        'Manual map: Insert one Android Things device into the USB port you '
        'want to map, \nthen select one of the six corresponding UI slots and '
        'click \'Map\' button.',
        '自动关联：点击\'自动关联\', 界面上的目标设备将会分配给任意已经连接的Android '
        'Things设备。\n手动关联：将一个Android Things设备插入到你想关联的USB接口，'
        '然后选择界面上六个目标设备位置中的一个并点击\'关联\'。'][index]
    self.TITLE_FIRST_WARNING = ['1st\twarning: ', '警告一：'][index]
    self.TITLE_SECOND_WARNING = ['2nd\twarning: ', '警告二：'][index]
    self.TITLE_SELECT_LANGUAGE = ['Select a language', '选择一种语言'][index]
    # Field names
    self.FIELD_SERIAL_NUMBER = ['SN', '序列号'][index]
    self.SERIAL_NOT_MAPPED = ['Not Mapped', '未分配'][index]
    self.FIELD_USB_LOCATION = ['USB Location', '插入位置'][index]
    self.FIELD_STATUS = ['Status', '状态'][index]

    # Dialogs
    self.DIALOG_CHANGE_THRESHOLD_TEXT = ['ATFA Key Warning Threshold:',
                                         '密钥警告阈值:'][index]
    self.DIALOG_CHANGE_THRESHOLD_TITLE = ['Change ATFA Key Warning Threshold',
                                          '更改密钥警告阈值'][index]
    self.DIALOG_LOW_KEY_TEXT = ''
    self.DIALOG_LOW_KEY_TITLE = ['Low Key Alert', '密钥不足警告'][index]
    self.DIALOG_ALERT_TEXT = ''
    self.DIALOG_ALERT_TITLE = ['Alert', '警告'][index]
    self.DIALOG_WARNING_TITLE = ['Warning', '警告'][index]
    self.DIALOG_CHOOSE_PRODUCT_ATTRIBUTE_FILE = [
        'Choose Product Attributes File', '选择产品文件'][index]
    self.DIALOG_CHOOSE_KEY_FILE = ['Choose Key File', '选择密钥文件'][index]
    self.DIALOG_CHOOSE_UPDATE_FILE = [
        'Choose Update Patch File', '选择升级补丁文件'][index]
    self.DIALOG_SELECT_DIRECTORY = ['Select directory', '选择文件夹'][index]
    self.DIALOG_INPUT_PASSWORD = ['Input the password', '输入密码'][index]
    self.DIALOG_PASSWORD = ['Password', '密码'][index]
    self.DIALOG_ORIG_PASSWORD = ['Original Password: ', '原密码：'][index]
    self.DIALOG_NEW_PASSWORD = ['New Password: ', '新密码：'][index]

    # Buttons
    self.BUTTON_ENTER_SUP_MODE = ['Enter Supervisor Mode', '进入管理模式'][index]
    self.BUTTON_LEAVE_SUP_MODE = ['Leave Supervisor Mode', '离开管理模式'][index]
    self.BUTTON_MAP_USB_LOCATION = ['Map USB Locations', '关联USB位置'][index]
    self.BUTTON_LANGUAGE_PREFERENCE = ['Language Preference', '语言偏好'][index]
    self.BUTTON_SET_PASSWORD = ['Set Password', '设置密码'][index]
    self.BUTTON_AUTOMAP = ['Automap', '自动关联'][index]
    self.BUTTON_REMAP = ['Remap', '重新关联'][index]
    self.BUTTON_MAP = ['Map', '关联'][index]
    self.BUTTON_CANCEL = ['Cancel', '取消'][index]
    self.BUTTON_SAVE = ['Save', '保存'][index]

    # Alerts
    self.ALERT_NO_ATFA = [
        'No ATFA device available!',
        '没有可用的ATFA设备！'][index]
    self.ALERT_AUTO_PROV_NO_ATFA = [
        'Cannot enter auto provision mode\nNo ATFA device available!',
        '无法开启自动模式\n没有可用的ATFA设备！'][index]
    self.ALERT_AUTO_PROV_NO_PRODUCT = [
        'Cannot enter auto provision mode\nNo product specified!',
        '无法开启自动模式\n没有选择产品！'][index]
    self.ALERT_PROV_NO_SELECTED = [
        "Can't Provision! No target device selected!",
        '无法传输密钥！目标设备没有选择！'][index]
    self.ALERT_PROV_NO_ATFA = [
        "Can't Provision! No Available ATFA device!",
        '无法传输密钥！没有ATFA设备!'][index]
    self.ALERT_PROV_NO_KEYS = [
        "Can't Provision! No keys left!",
        '无法传输密钥！没有剩余密钥!'][index]
    self.ALERT_FUSE_NO_SELECTED = [
        "Can't Fuse vboot key! No target device selected!",
        '无法烧录！目标设备没有选择！'][index]
    self.ALERT_FUSE_NO_PRODUCT = [
        "Can't Fuse vboot key! No product specified!",
        '无法烧录！没有选择产品！'][index]
    self.ALERT_FUSE_PERM_NO_SELECTED = [
        "Can't Fuse permanent attributes! No target device selected!",
        '无法烧录产品信息！目标设备没有选择！'][index]
    self.ALERT_FUSE_PERM_NO_PRODUCT = [
        "Can't Fuse permanent attributes! No product specified!",
        '无法烧录产品信息！没有选择产品！'][index]
    self.ALERT_LOCKAVB_NO_SELECTED = [
        "Can't Lock Android Verified Boot! No target device selected!",
        '无法锁定AVB！目标设备没有选择！'][index]
    self.ALERT_FAIL_TO_CREATE_LOG = [
        'Failed to create log!',
        '无法创建日志文件！'][index]
    self.ALERT_FAIL_TO_PARSE_CONFIG = [
        'Failed to find or parse config file!',
        '无法找到或解析配置文件！'][index]
    self.ALERT_NO_DEVICE = [
        'No devices found!',
        '无设备！'][index]
    self.ALERT_CANNOT_OPEN_FILE = [
        'Can not open file: ',
        '无法打开文件: '][index]
    self.ALERT_CANNOT_SAVE_FILE = [
        'Cannot save file at file path: ',
        '无法保存文件路径: '][index]
    self.ALERT_FILE_EXISTS = [
        ' already exists, do you want to overwrite it?',
        ' 已经存在，是否覆盖？'][index]
    self.ALERT_PRODUCT_FILE_FORMAT_WRONG = [
        'The format for the product attributes file is not correct!',
        '产品文件格式不正确！'][index]
    self.ALERT_ATFA_UNPLUG = [
        'ATFA device unplugged, exit auto mode!',
        'ATFA设备拔出，退出自动模式！'][index]
    self.ALERT_NO_KEYS_LEFT_LEAVE_PROV = [
        'No keys left! Leave auto provisioning mode!',
        '没有剩余密钥，退出自动模式！'][index]
    self.ALERT_FUSE_VBOOT_FUSED = [
        'Cannot fuse bootloader vboot key for device that is already fused!',
        '无法烧录一个已经烧录过引导密钥的设备！'][index]
    self.ALERT_FUSE_PERM_ATTR_FUSED = [
        'Cannot fuse permanent attributes for device that is not fused '
        'bootloader vboot key or already fused permanent attributes!',
        '无法烧录一个没有烧录过引导密钥或者已经烧录过产品信息的设备！'][index]
    self.ALERT_LOCKAVB_LOCKED = [
        'Cannot lock android verified boot for device that is not fused '
        'permanent attributes or already locked!',
        '无法锁定一个没有烧录过产品信息或者已经锁定AVB的设备！'][index]
    self.ALERT_UNLOCKAVB_UNLOCKED = [
        'Cannot unlock android verified boot for device that is already '
        'unlocked!',
        '无法解锁一个已经解锁AVB的设备'][index]
    self.ALERT_PROV_PROVED = [
        'Cannot provision device that is not ready for provisioning or '
        'already provisioned!',
        '无法传输密钥给一个不在正确状态或者已经拥有密钥的设备！'][index]
    self.ALERT_NO_MAP_DEVICE_CHOSEN = [
        'No device location chosen for mapping!',
        ' 未选择要关联的设备位置'][index]
    self.ALERT_MAP_DEVICE_TIMEOUT = [
        'Mapping Failure!\nNo ATFA device detected at any USB Location!',
        '关联失败！\n没有在任何USB口检测到ATFA设备！'][index]
    self.ALERT_INCOMPATIBLE_ATFA = [
        'Detected an ATFA device having incompatible version with this tool, '
        'please upgrade your ATFA device to the latest version!',
        '检测到一个与这个软件不兼容的ATFA设备，请升级你的ATFA设备！'][index]
    self.ALERT_REMAP_LOCATION_SLOT = [
        lambda location, slot :
            ('The USB location ' + location.encode('utf-8') +
             ' was aleady mapped to slot ' + slot.encode('utf-8') +
             ' before, do you want to overwrite?'),
        lambda location, slot :
            ('USB位置' + location.encode('utf-8') + '已经被关联到设备位置' +
             slot.encode('utf-8') + ', 是否覆盖?')
        ][index]
    self.ALERT_REMAP_SLOT_LOCATION = [
        lambda slot, location :
            'The slot ' + slot + ' was aleady mapped to '
            'USB Location ' + location.encode('utf-8') + ' before, '
            'do you want to overwrite?',
        lambda slot, location :
            ('设备位置' + slot.encode('utf-8') +
             '已经被关联到USB位置' + location.encode('utf-8') + ', 是否覆盖?')
        ][index]
    self.ALERT_REMAP_ALL = [
        'Auto mapping would overwrite previous configure, do you want to '
        'continue?',
        '自动关联将会覆盖之前的关联配置，是否继续？'
        ][index]
    self.ALERT_ADD_MORE_KEY = [
        lambda keys_left:
            'Warning - add more keys\n'
            'There are ' + str(keys_left) + ' keys left.',
        lambda keys_left:
            '警告！请添加更多密钥！当前剩余密钥：' + str(keys_left)][index]
    self.ALERT_PROCESS_KEY_FAILURE = [
        'Process key failed, Error: ',
        '处理密钥文件失败！错误信息：'][index]
    self.ALERT_UPDATE_FAILURE = [
        'Update ATFA failed, Error: ',
        '升级ATFA设备失败！错误信息：'][index]
    self.ALERT_PURGE_KEY_FAILURE = [
        'Purge key failed, Error: ',
        '清除密钥失败！错误信息：'][index]
    self.ALERT_CANNOT_GET_REG = [
        'Cannot get registration file! Error: ',
        '无法获得注册文件！错误：'][index]
    self.ALERT_REG_DOWNLOADED = [
        'Registration file downloaded at: ',
        '注册文件下载完成，位置：'][index]
    self.ALERT_CANNOT_GET_AUDIT = [
        'Cannot get audit file! Error: ',
        '无法获得审计文件！错误：'][index]
    self.ALERT_AUDIT_DOWNLOADED = [
        'Audit file downloaded at: ',
        '审计文件下载完成，位置：'][index]
    self.ALERT_KEYS_LEFT = [
        lambda keys_left:
            'There are ' + str(keys_left) + ' keys left for '
            'this product in the ATFA device.',
        lambda keys_left:
            'ATFA设备中对于此产品剩余密钥数量：' + str(keys_left)
        ][index]
    self.ALERT_CONFIRM_PURGE_KEY = [
        'Are you sure you want to purge all the keys for this product?\n'
        'The keys would be purged permanently!!!',
        '你确定要清楚密钥吗？\n设备中的密钥将永久丢失！！！'][index]
    # This variable is intentionally a list instead of a string since we need
    # to show the correct message after language setting is changed.
    self.ALERT_LANGUAGE_RESTART = [
        'The language setting would take effect after you restart the '
        'application.',
        '语言设置将在下次重启程序后生效。']
    self.ALERT_WRONG_PASSWORD = [
        'Wrong Password!!!',
        '密码错误!!!'][index]
    self.ALERT_WRONG_ORIG_PASSWORD = [
        'Wrong Original Password!!!',
        '原密码错误!!!'][index]
    self.ALERT_REPROVISION = [
        lambda device:
            'The device ' + str(device) + ' already has attestation key, '
            'do you want to reprovision a new key?',
        lambda device:
            '设备' + str(device) + '中已经有一个密钥，是否覆盖？'][index]
    self.ALERT_PROVISION_STEPS_SYNTAX_ERROR = [
        'Config "PROVISION_STEPS" is not an array or contains unsupported '
        'operations',
        '设置项"PROVISION_STEPS"不是一个数组或者包含不支持的步骤'][index]
    self.ALERT_PROVISION_STEPS_SECURITY_REQ = [
        'Config "PROVISION_STEPS" does not meet the necessary security '
        'requirement, please check again or set TEST_MODE to true if you are '
        'really sure what you are doing.',
        '设置项"PROVISION_STEPS"不符合必要的信息安全要求，请检查或者设定TEST_MODE为True'
        '如果你明确此行为带来的后果.'][index]
    self.ALERT_INSTANCE_RUNNING = [
        'Another instance of this tool is already running. If you continue, '
        'the tool WILL NOT behave as expected, are you sure you want to '
        'continue?',
        '检测到已经有一个相同的程序在运行，如果继续运行可能会导致错误，确定要'
        '继续吗？'][index]
    self.ALERT_NO_TARGET_DEVICE = [
        'No Android Things device detected, please make sure your device is in '
        'fastboot mode.',
        '没有检测到已连接的Android Things设备，请确保设备在fastboot状态。'][index]
    self.ALERT_MULTIPLE_TARGET_DEVICE = [
        'More than one Android Things connected, please only plug in the one '
        'you want to map.',
        '检测到多个已连接的Android Things设备，请确保仅有一个想要关联的设备。'][index]

    self.STATUS_MAPPED = ['Mapped', '已关联位置'][index]
    self.STATUS_NOT_MAPPED = ['Not mapped', '未关联位置'][index]


class AtftAudit(object):
  """The class to manage audit files in ATFA. """

  @staticmethod
  def GetAuditFileName(serial):
    time = datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S')
    return '{}_{}.audit'.format(serial, time)

  def __init__(self,
               audit_dir,
               download_interval,
               get_file_handler,
               handle_exception_handler,
               get_atfa_serial):
    """Initialize ATFT Audit object.

    Args:
      audit_dir: The audit file directory.
      download_interval: How often (keys) to pull audit file.
      get_file_handler: The function to get file from ATFA.
      handle_exception_handler: The function to handle exception.
      get_atfa_serial: The function to get current ATFA serial.
    """
    self.audit_dir = audit_dir
    self.last_audit_keys_left = -1
    self.download_interval = download_interval
    self.get_file_handler = get_file_handler
    self.get_atfa_serial = get_atfa_serial
    self.handle_exception_handler = handle_exception_handler
    if not os.path.exists(self.audit_dir):
      # If audit directory does not exist, try to create it.
      try:
        os.mkdir(self.audit_dir)
      except IOError:
        return

  def PullAudit(self, keys_left):
    """Pull audit file from ATFA if the download_interval keys has been used.

    Args:
      keys_left: Currently how many keys left in the ATFA.
    """
    if (self.last_audit_keys_left == -1 or (
        self.last_audit_keys_left - self.download_interval >= keys_left)):
      if self._DownloadAudit():
        self.last_audit_keys_left = keys_left

  def _GetAuditFiles(self, serial_number):
    """Get a list of all the audit files in the audit directory.

    Args:
      serial_number: The serial number for the current ATFA.
    Returns:
      A list of audit file names.
    """
    audit_files = []
    for file_name in os.listdir(self.audit_dir):
      if (os.path.isfile(os.path.join(self.audit_dir, file_name)) and
          file_name.endswith('.audit') and
          file_name.startswith(serial_number)):
        audit_files.append(file_name)
    audit_files.sort()
    return audit_files

  def ResetKeysLeft(self):
    """Force to pull ATFA audit file. """
    self.last_audit_keys_left = -1

  def _DownloadAudit(self):
    """Download audit file from ATFA and remove old audit files.

    Returns:
      Whether the audit file is downloaded successfully.
    """
    try:
      serial = self.get_atfa_serial()
    except DeviceNotFoundException as e:
      return False
    except FastbootFailure as e:
      self.handle_exception_handler('E', e)
      return False

    filepath = os.path.join(
        self.audit_dir, AtftAudit.GetAuditFileName(serial))

    if not self.get_file_handler(filepath, 'audit', False, True):
      return False

    # We only remove old files if we successfully pull audit file.
    while True:
      audit_files = self._GetAuditFiles(serial)
      # We keep at most MAX_AUDIT_FILE_NUMBER records in case one is broken.
      if len(audit_files) <= MAX_AUDIT_FILE_NUMBER:
        break
      oldest_file = os.path.join(self.audit_dir, audit_files[0])
      os.remove(oldest_file)

    return True


class AtftKeyHandler(object):
  """The class to manage key file processing."""

  def __init__(self,
               key_dir,
               log_dir,
               key_file_extension,
               process_key_handler,
               handle_exception_handler,
               get_atfa_serial):
    """Initialize ATFT Key object.

    Args:
      key_dir: The folder to look for key files.
      log_dir: The log directory folder to store processed key information.
      key_file_extension: The extension for the key file.
      process_key_handler: The handler to store the key into the ATFA.
      handle_exception_handler: The function to handle exception.
      get_atfa_serial: The handler to get the ATFA serial number.
    """
    # Check for unprocessed key files every 5 minutes.
    self.refresh_interval = 300
    self.key_dir = key_dir
    self.log_dir = log_dir
    self.key_file_extension = key_file_extension
    self.process_key_handler = process_key_handler
    self.handle_exception_handler = handle_exception_handler
    self.get_atfa_serial = get_atfa_serial
    self.timer = None
    self.processed_keys = {}

  def StartProcessKey(self):
    """Start periodically processing keys in the key_dir."""
    if not self.key_dir or not os.path.exists(self.key_dir):
      return
    for key_log_file in os.listdir(self.log_dir):
      if not key_log_file.startswith('ATFA') or not key_log_file.endswith('.log'):
        continue
      atfa_id = key_log_file.replace('.log', '')
      try:
        with open(os.path.join(self.log_dir, key_log_file), 'r') as log_file:
          self.processed_keys[atfa_id] = sets.Set()
          for file_name in log_file:
            self.processed_keys[atfa_id].add(file_name.replace('\n', ''))
      except IOError:
        continue
    self.ProcessKeyFile()

  def StopProcessKey(self):
    """End the processing."""
    if self.timer:
      self.timer.cancel()
    self.timer = None

  def ProcessKeyFile(self):
    """Read unprocessed key files from the key directory and process them."""
    key_files  = []
    atfa_id = None
    self.timer = threading.Timer(self.refresh_interval, self.ProcessKeyFile)
    self.timer.start()
    try:
      atfa_id = self.get_atfa_serial()
    except (DeviceNotFoundException, FastbootFailure):
      # Either ATFA does not exist or something wrong with it, ignore and
      # try again next time.
      return

    for key_file in os.listdir(self.key_dir):
      if not key_file.endswith(self.key_file_extension.replace("*.", "")):
        continue
      if not key_file.startswith(atfa_id):
        continue
      if (atfa_id in self.processed_keys and
          key_file in self.processed_keys[atfa_id]):
        continue
      if os.path.isfile(os.path.join(self.key_dir, key_file)):
        key_files.append(key_file)

    for key_file in key_files:
      key_path = os.path.join(self.key_dir, key_file)
      try:
        self.process_key_handler(key_path, True)
        # Process succeed, record the key file name.
        self.WriteToLog(key_file, atfa_id)
      except DeviceNotFoundException:
        continue
      except FastbootFailure as e:
        # If the process fails, this may because the key bundle file is being
        # written to, the key bundle corrupts or other ephemeral errors that
        # might be fixed in another try. As a result, we don't write it to
        # log and let it automatically retry.
        self.handle_exception_handler('E', e)

  def WriteToLog(self, key_file_name, atfa_id):
    """Record key-processed information.

    Args:
      key_file_name: The file name for the key that has been processed.
      atfa_id: The ATFA ID this key file is for.
    """
    if atfa_id not in self.processed_keys:
      self.processed_keys[atfa_id] = sets.Set()
    self.processed_keys[atfa_id].add(key_file_name)

    key_log_file = os.path.join(self.log_dir, '{}.log'.format(atfa_id))
    if not os.path.exists(key_log_file):
      try:
        log_file = open(key_log_file, 'w+')
        log_file.close()
      except IOError:
        return
    try:
      with open(key_log_file, 'a+') as log_file:
        log_file.write(key_file_name + '\n')
        log_file.flush()
    except IOError:
      return


class AtftLog(object):
  """The class to handle logging.

  Logs would be created under log_dir with the time stamp when the log is
  created as file name. There would be at most LOG_FILE_NUMBER log files and
  each log file size would be less than log_size/log_file_number, so the total
  log size would less than log_size.
  """

  def __init__(self, log_dir, log_size, log_file_number):
    """Initiate the AtftLog object.

    This function would also write the first 'Program Start' log entry.

    Args:
      log_dir: The directory to store logs.
      log_size: The maximum total size for all the log files.
      log_file_number: The maximum number for log files.
    """
    self.log_dir = log_dir
    self.log_dir_file = None
    self.file_size = 0
    self.log_size = log_size
    self.log_file_number = log_file_number
    self.file_size_max = math.floor(self.log_size / self.log_file_number)
    self.lock = threading.Lock()
    self.Initialize()

  def Initialize(self):
    """Do the necessary initialization.

    Create log directory if not exists. Also create the first log file if not
    exists. Log a 'Program Start' entry. Point the current log directory to
    the latest log file.
    """
    if not os.path.exists(self.log_dir):
      # If log directory does not exist, try to create it.
      try:
        os.mkdir(self.log_dir)
      except IOError:
        return

    log_files = self._GetLogFiles()
    if not log_files:
      # Create the first log file.
      self._CreateLogFile()
    else:
      self.log_dir_file = os.path.join(self.log_dir, log_files.pop())

  def Error(self, tag, string):
    """Print an error message to the log.

    Args:
      tag: The tag for the message.
      string: The error message.
    """
    self._Output('E', tag, string)

  def Debug(self, tag, string):
    """Print a debug message to the log.

    Args:
      tag: The tag for the message.
      string: The debug message.
    """
    self._Output('D', tag, string)

  def Warning(self, tag, string):
    """Print a warning message to the log.

    Args:
      tag: The tag for the message.
      string: The warning message.
    """
    self._Output('W', tag, string)

  def Info(self, tag, string):
    """Print an info message to the log.

    Args:
      tag: The tag for the message.
      string: The info message.
    """
    self._Output('I', tag, string)

  def CheckInstanceRunning(self):
    """Check whether there is already an instance of ATFT running.

    We do this by checking the log file for 'Program start' without
    'Program exit'.

    Returns:
      True if no other instance is running, false otherwise.
    """
    running_processes = []
    for p in psutil.process_iter(attrs=['name', 'pid', 'ppid', 'cmdline']):
      pname = p.info['name']
      if ('atft.exe' == pname or 'atft' == pname in pname or
          p.info['cmdline'] == ['python', 'atft.py']):
        running_processes.append(p)

    # Remove forked process.
    dedup_running_processes = []
    for p in running_processes:
      dup = False
      for p2 in running_processes:
        if p.info['ppid'] == p2.info['pid']:
          dup = True
          break
      if not dup:
        dedup_running_processes.append(p)

    # Current running process should be 1.
    if len(dedup_running_processes) > 1:
      return False
    return True

  def _Output(self, code, tag, string):
    """Output a line of message to the log file.

    Args:
      code: The log level.
      tag: The log tag.
      string: The log message.
    """
    time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    message = '[{0}] {1}/{2}: {3}'.format(
        time, code, tag, string.replace('\n', '\t'))
    if self.log_dir_file:
      message += '\n'
      with self.lock:
        self._LimitSize(message)
        with open(self.log_dir_file, 'a') as log_file:
          log_file.write(message)
          log_file.flush()

  def _GetLogFiles(self):
    log_files = []
    for file_name in os.listdir(self.log_dir):
      if (os.path.isfile(os.path.join(self.log_dir, file_name)) and
          file_name.startswith('atft_log_')):
        log_files.append(file_name)
    log_files.sort()
    return log_files

  def _LimitSize(self, message):
    """This function limits the total size of logs.

    It would create a new log file if the log file is too large. If the total
    number of log files is larger than threshold, then it would delete the
    oldest log.

    Args:
      message: The log message about to be added.
    """
    file_size = os.path.getsize(self.log_dir_file)
    if file_size + len(message) > self.file_size_max:
      # If file size will exceed file_size_max, then create a new file and close
      # the current one.
      self._CreateLogFile()

    log_files = self._GetLogFiles()
    if len(log_files) > self.log_file_number:
      # If file number exceeds LOG_FILE_NUMBER, then delete the oldest file.
      try:
        oldest_file = os.path.join(self.log_dir, log_files[0])
        os.remove(oldest_file)
      except IOError:
        pass

  def _CreateLogFile(self):
    """Create a new log file using timestamp as file name.
    """
    timestamp = self._GetCurrentTimestamp()
    log_file_name = 'atft_log_' + str(timestamp)
    log_file_path = os.path.join(self.log_dir, log_file_name)
    i = 1
    while os.path.exists(log_file_path):
      # If already exists, create another name, timestamp_1, timestamp_2, etc.
      log_file_name_new = log_file_name + '_' + str(i)
      log_file_path = os.path.join(self.log_dir, log_file_name_new)
      i += 1
    try:
      log_file = open(log_file_path, 'w+')
      log_file.close()
      self.log_dir_file = log_file_path
    except IOError:
      self.log_dir_file = None

  def _GetCurrentTimestamp(self):
    return int((datetime.datetime.now() -
                datetime.datetime(1970, 1, 1)).total_seconds())

  def __del__(self):
    """Cleanup function. This would log the 'Program Exit' message.
    """
    self.Info('Program', 'Program exit')


class Event(wx.PyCommandEvent):
  """The customized event class.
  """

  def __init__(self, etype, eid=-1, value=None):
    """Create a new customized event.

    Args:
      etype: The event type.
      eid: The event id.
      value: The additional data included in the event.
    """
    wx.PyCommandEvent.__init__(self, etype, eid)
    self._value = value

  def GetValue(self):
    """Get the data included in this event.

    Returns:
      The event data.
    """
    return self._value


class ChangeThresholdDialog(wx.Dialog):
  """The dialog class to ask user to change key warning threshold."""

  def GetFirstWarning(self):
    """Get the first warning value.

    Returns:
      The first warning value.
    """
    return self.first_warning

  def GetSecondWarning(self):
    """Get the second warning value.

    Returns:
      The second warning value.
    """
    return self.second_warning

  def __init__(self, atft_string, first_warning, second_warning):
    """Initiate the dialog using the atft class instance.

    Args:
      atft_string: The class for all the string literals.
    """
    self.atft_string = atft_string
    self.first_warning = first_warning
    self.second_warning = second_warning

  def CreateDialog(self, *args, **kwargs):
    """The actual initializer to create the dialog.

    This function creates UI elements within the dialog and only need to be
    called once. This function should be called with the same argument for
    wx.Dialog class and should be called as part of the initialization after
    using __init__.
    """
    super(ChangeThresholdDialog, self).__init__(*args, **kwargs)
    self.SetForegroundColour(wx.Colour(0, 0, 0))
    panel_sizer = wx.BoxSizer(wx.VERTICAL)
    self.SetSizer(panel_sizer)
    self.SetSize(300, 250)

    self._CreateTitle(panel_sizer)
    self._CreateFirstWarningInput(panel_sizer)
    panel_sizer.AddSpacer(10)
    self._CreateSecondWarningInput(panel_sizer)
    panel_sizer.AddSpacer(40)
    self._CreateButtons(panel_sizer)

  def _CreateTitle(self, panel_sizer):
    dialog_title = wx.StaticText(
        self, wx.ID_ANY, self.atft_string.DIALOG_CHANGE_THRESHOLD_TEXT)
    title_font = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    dialog_title.SetFont(title_font)
    panel_sizer.Add(dialog_title, 0, wx.ALL, 20)

  def _CreateFirstWarningInput(self, panel_sizer):
    line_sizer = wx.BoxSizer(wx.HORIZONTAL)
    first_warning_hint = wx.StaticText(
        self, wx.ID_ANY, self.atft_string.TITLE_FIRST_WARNING)
    line_sizer.Add(first_warning_hint, 0, wx.TOP, 5)
    self.first_warning_input = wx.TextCtrl(self, wx.ID_ANY, '')
    line_sizer.Add(self.first_warning_input, 0, wx.LEFT, 10)
    panel_sizer.Add(line_sizer, 0, wx.LEFT, 20)
    font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    first_warning_hint.SetFont(font)
    self.first_warning_input.SetFont(font)

  def _CreateSecondWarningInput(self, panel_sizer):
    line_sizer = wx.BoxSizer(wx.HORIZONTAL)
    second_warning_hint = wx.StaticText(
        self, wx.ID_ANY, self.atft_string.TITLE_SECOND_WARNING)
    line_sizer.Add(second_warning_hint, 0, wx.TOP, 5)
    self.second_warning_input = wx.TextCtrl(
        self, wx.ID_ANY, '')
    line_sizer.Add(self.second_warning_input, 0, wx.LEFT, 10)
    panel_sizer.Add(line_sizer, 0, wx.LEFT, 20)
    font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    second_warning_hint.SetFont(font)
    self.second_warning_input.SetFont(font)

  def _CreateButtons(self, panel_sizer):
    button_sizer = wx.BoxSizer(wx.HORIZONTAL)
    button_font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    button_cancel = wx.Button(
        self, label=self.atft_string.BUTTON_CANCEL, size=(130, 30), id=wx.ID_CANCEL)
    button_save = wx.Button(
        self, label=self.atft_string.BUTTON_SAVE, size=(130, 30), id=wx.ID_OK)
    button_save.SetFont(button_font)
    button_cancel.SetFont(button_font)
    button_sizer.Add(button_cancel, 0)
    button_sizer.Add(button_save, 0, wx.LEFT, 5)
    panel_sizer.Add(button_sizer, 0, wx.ALIGN_CENTER)
    button_save.Bind(wx.EVT_BUTTON, self.OnSave)

  def ShowModal(self):
    """Show the dialog.

    This function would set default value and call wx.Dialog.ShowModal.
    """
    self.first_warning_input.Clear()
    if self.first_warning:
      self.first_warning_input.AppendText(str(self.first_warning))
    self.second_warning_input.Clear()
    if self.second_warning:
      self.second_warning_input.AppendText(str(self.second_warning))
    return super(ChangeThresholdDialog, self).ShowModal()

  def OnSave(self, e):
    """Change warning dialog save callback.

    We allow user to:
    No warning: first warning and second warning empty
    One warning: first warning not empty, second warning empty
    Two warnings: first warning not empty, second warning not empty.

    Args:
      e: The triggering event.
    """
    first_warning = self.first_warning_input.GetValue()
    second_warning = self.second_warning_input.GetValue()
    if not first_warning and second_warning:
      # Do not allow second warning set while first warning is not.
      return
    try:
      if not second_warning:
        if not first_warning:
          # No warning
          self.first_warning = None
          self.second_warning = None
        else:
          # User disable second warning
          self.second_warning = None
          first_warning_number = int(first_warning)
          if first_warning_number <= 0:
            return
          self.first_warning = first_warning_number
      else:
        # Second warning set.
        first_warning_number = int(first_warning)
        second_warning_number = int(second_warning)
        if first_warning_number <= 0 or second_warning_number <= 0:
          # Invalid setting, just ignore.
          return
        if second_warning_number >= first_warning_number:
          return
        self.first_warning = first_warning_number
        self.second_warning = second_warning_number
    except ValueError:
      # If any field is invalid, let user input again.
      return
    self.EndModal(0)


class AppSettingsDialog(wx.Dialog):
  """The dialog class to ask user to change application settings.

  Now support Mapping USB Location to UI slot, Setting language and Setting
  password for supervisor mode.
  """

  def __init__(self, atft_string,
               auto_map_usb_location_handler,
               manual_map_usb_location_handler,
               map_usb_to_slot_handler,
               change_language_handler,
               change_password_handler,
               language_index,
               device_usb_locations):
    """Initiate the dialog using the atft class instance.

    Args:
      atft_string: The class for string constants.
      auto_map_usb_location_handler: The handler for clicking 'automap' button.
      manual_map_usb_location_handler: The handler for clicking 'map' button.
      map_usb_to_slot_handler: The handler for clicking each slot.
      change_language_handler: The handler for changing language.
      change_password_handler: The handler for changing password.
      language_index: The language index.
      device_usb_locations: The device usb location mapping.
    """
    self.atft_string = atft_string
    self.settings = []
    self.menu_items = []
    self.current_setting = None
    self.auto_map_usb_location_handler = auto_map_usb_location_handler
    self.manual_map_usb_location_handler = manual_map_usb_location_handler
    self.map_usb_to_slot_handler = map_usb_to_slot_handler
    self.change_language_handler = change_language_handler
    self.change_password_handler = change_password_handler
    self.language_index = language_index
    self.device_usb_locations = device_usb_locations

  def CreateDialog(self, *args, **kwargs):
    """The actual initializer to create the dialog.

    This function creates UI elements within the dialog and only need to be
    called once. This function should be called with the same argument for
    wx.Dialog class and should be called as part of the initialization after
    using __init__.
    """
    super(AppSettingsDialog, self).__init__(*args, **kwargs)
    self.SetForegroundColour(COLOR_BLACK)
    self.SetBackgroundColour(COLOR_WHITE)
    self.SetSize(850, 650)
    panel_sizer = wx.BoxSizer(wx.VERTICAL)
    self.SetSizer(panel_sizer)

    self.menu_sizer = wx.BoxSizer(wx.HORIZONTAL)
    self.menu_font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    self.menu_font_bold = wx.Font(
        10, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)

    panel_sizer.Add(self.menu_sizer, 0, wx.ALL, 15)
    panel_sizer.AddSpacer(10)
    self.settings_sizer = wx.BoxSizer(wx.VERTICAL)

    self._CreateUSBMappingPanel()
    self._CreateLanguagePanel()
    self._CreatePasswordPanel()

    panel_sizer.Add(self.settings_sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
    self.panel_sizer = panel_sizer

    self._CreateButtons()
    self.UpdateMappingStatus()

    # By default, we show map usb location setting.
    self.ShowUSBMappingSetting(None)

  def _CreateButtons(self):
    """Add the save, cancel and save buttons."""
    buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
    button_cancel = wx.Button(
        self,label=self.atft_string.BUTTON_CANCEL, size=(130, 30),
        id=wx.ID_CANCEL)
    button_map = wx.Button(
        self, label=self.atft_string.BUTTON_MAP, size=(130, 30), id=wx.ID_ANY)
    button_automap = wx.Button(
        self, label=self.atft_string.BUTTON_AUTOMAP, size=(130, 30),
        id=wx.ID_ANY)
    button_save = wx.Button(
        self, label=self.atft_string.BUTTON_SAVE, size=(130, 30), id=wx.ID_ANY)
    button_font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    button_map.SetFont(button_font)
    button_automap.SetFont(button_font)
    button_cancel.SetFont(button_font)
    button_save.SetFont(button_font)

    buttons_sizer.Add(button_cancel)
    buttons_sizer.Add(button_map, 0, wx.LEFT, 10)
    buttons_sizer.Add(button_automap, 0, wx.LEFT, 10)
    buttons_sizer.Add(button_save, 0, wx.LEFT, 10)

    self.button_cancel = button_cancel
    self.button_map = button_map
    self.button_automap = button_automap
    self.button_save = button_save
    self.buttons_sizer = buttons_sizer
    self.panel_sizer.AddSpacer(20)
    self.panel_sizer.Add(buttons_sizer, 0, wx.ALIGN_RIGHT | wx.RIGHT, 10)

    # Bind handlers
    self.button_map.Bind(wx.EVT_BUTTON, self.manual_map_usb_location_handler)
    self.button_automap.Bind(wx.EVT_BUTTON, self.auto_map_usb_location_handler)
    self.button_cancel.Bind(wx.EVT_BUTTON, self.OnExit)
    self.button_save.Bind(wx.EVT_BUTTON, self.OnSaveSetting)

  def _CreateUSBMappingPanel(self):
    """Create the panel for mapping USB location to UI slot."""
    menu_map_usb = wx.Button(
        self, label=self.atft_string.BUTTON_MAP_USB_LOCATION,
        style=wx.BORDER_NONE)
    menu_map_usb.Bind(wx.EVT_BUTTON, self.ShowUSBMappingSetting)
    menu_map_usb.SetFont(self.menu_font)
    self.menu_map_usb = menu_map_usb
    self.AddMenuItem(self.menu_map_usb)
    usb_mapping_panel = wx.Window(self, style=wx.BORDER_SUNKEN)
    self.settings_sizer.Add(usb_mapping_panel, 0, wx.EXPAND)
    usb_mapping_panel.SetBackgroundColour(COLOR_WHITE)
    usb_mapping_panel_sizer = wx.BoxSizer(wx.VERTICAL)
    usb_mapping_panel_sizer.SetMinSize((0, 480))
    usb_mapping_title = wx.StaticText(
        usb_mapping_panel, wx.ID_ANY, self.atft_string.TITLE_MAP_USB)
    usb_mapping_panel_sizer.AddSpacer(10)
    usb_mapping_panel_sizer.Add(usb_mapping_title, 0, wx.EXPAND | wx.ALL, 10)
    usb_mapping_panel_sizer.AddSpacer(10)
    usb_mapping_title_font = wx.Font(
        10, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    usb_mapping_title.SetFont(usb_mapping_title_font)
    self.dev_mapping_components = Atft.CreateTargetDeviceList(
        usb_mapping_panel, usb_mapping_panel_sizer, True)
    i = 0
    for dev_component in self.dev_mapping_components:
      handler = lambda event, index=i : self.map_usb_to_slot_handler(
          event, index)
      # Bind the select handler
      Atft._BindEventRecursive(wx.EVT_LEFT_DOWN, dev_component.panel, handler)
      i += 1

    usb_mapping_panel.SetSizerAndFit(usb_mapping_panel_sizer)
    self.usb_mapping_panel = usb_mapping_panel
    self.settings.append(self.usb_mapping_panel)

  def _CreateLanguagePanel(self):
    """Create the panel for setting language."""
    menu_language = wx.Button(
        self, label=self.atft_string.BUTTON_LANGUAGE_PREFERENCE,
        style=wx.BORDER_NONE)
    menu_language.Bind(wx.EVT_BUTTON, self.ShowLanguageSetting)
    self.menu_language = menu_language
    self.AddMenuItem(self.menu_language)
    language_setting = wx.Window(self, size=(0, 480))
    language_setting.SetBackgroundColour(COLOR_WHITE)
    language_setting_sizer = wx.BoxSizer(wx.VERTICAL)
    self.settings_sizer.Add(language_setting)
    language_title = wx.StaticText(
        language_setting, wx.ID_ANY, self.atft_string.TITLE_SELECT_LANGUAGE)
    language_title_font = wx.Font(
        14, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    language_title.SetFont(language_title_font)
    language_setting_sizer.AddSpacer(10)
    language_setting_sizer.Add(language_title, 0, wx.EXPAND | wx.LEFT, 20)
    language_setting_sizer.AddSpacer(10)
    language_setting_list = wx.ComboBox(
        language_setting, wx.ID_ANY, style=wx.CB_READONLY | wx.CB_DROPDOWN,
        value=LANGUAGE_OPTIONS[self.language_index],
        choices=LANGUAGE_OPTIONS,
        size=(250, 30))
    language_setting_sizer.Add(language_setting_list, 0, wx.LEFT, 20)
    language_setting.SetSizerAndFit(language_setting_sizer)
    self.language_setting_list = language_setting_list
    self.language_setting = language_setting
    self.settings.append(self.language_setting)

  def _CreatePasswordPanel(self):
    menu_set_password = wx.Button(
        self, label=self.atft_string.BUTTON_SET_PASSWORD, style=wx.BORDER_NONE)
    menu_set_password.Bind(wx.EVT_BUTTON, self.ShowPasswordSetting)
    self.menu_set_password = menu_set_password
    self.AddMenuItem(self.menu_set_password)
    password_setting = wx.Window(self, size=(0, 480))
    password_setting.SetBackgroundColour(COLOR_WHITE)
    password_setting_sizer = wx.BoxSizer(wx.VERTICAL)
    password_middle_sizer = wx.BoxSizer(wx.HORIZONTAL)
    self.settings_sizer.Add(password_setting, 0, wx.EXPAND)
    original_password_title = wx.StaticText(
        password_setting, wx.ID_ANY, self.atft_string.DIALOG_ORIG_PASSWORD)
    original_password_title_sizer = wx.BoxSizer(wx.VERTICAL)
    original_password_title_sizer.SetMinSize(0, 30)
    original_password_title_sizer.Add(original_password_title)
    new_password_title = wx.StaticText(
        password_setting, wx.ID_ANY, self.atft_string.DIALOG_NEW_PASSWORD)
    new_password_title_sizer = wx.BoxSizer(wx.VERTICAL)
    new_password_title_sizer.SetMinSize(0, 30)
    new_password_title_sizer.Add(new_password_title)
    password_title_font = wx.Font(
        12, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    original_password_title.SetFont(password_title_font)
    new_password_title.SetFont(password_title_font)
    self.original_password_input = wx.TextCtrl(
        password_setting, wx.ID_ANY, '', size=(240, 30),
        style=wx.TE_PASSWORD)
    self.new_password_input = wx.TextCtrl(
        password_setting, wx.ID_ANY, '', size=(240, 30),
        style=wx.TE_PASSWORD)
    self.original_password_input.SetFont(password_title_font)
    self.new_password_input.SetFont(password_title_font)

    password_title_sizer = wx.BoxSizer(wx.VERTICAL)
    password_title_sizer.Add(original_password_title_sizer)
    password_title_sizer.AddSpacer(10)
    password_title_sizer.Add(new_password_title_sizer)

    password_input_sizer = wx.BoxSizer(wx.VERTICAL)
    password_input_sizer.Add(self.original_password_input)
    password_input_sizer.AddSpacer(10)
    password_input_sizer.Add(self.new_password_input)

    password_middle_sizer.AddSpacer(20)
    password_middle_sizer.Add(password_title_sizer)
    password_middle_sizer.AddSpacer(20)
    password_middle_sizer.Add(password_input_sizer)

    password_setting_sizer.AddSpacer(40)
    password_setting_sizer.Add(password_middle_sizer)

    password_setting.SetSizerAndFit(password_setting_sizer)
    self.password_setting = password_setting
    self.settings.append(self.password_setting)

  def AddMenuItem(self, menu_button):
    menu_button.SetFont(self.menu_font)
    self.menu_sizer.Add(menu_button)
    self.menu_sizer.AddSpacer(10)
    self.menu_items.append(menu_button)

  def UpdateMappingStatus(self):
    """Refresh the mapping status (mapped/not mapped) for each device slot.

    In order for the status to be aligned correctly, this function needs to be
    called each time the status text changes.
    """
    i = 0
    for dev_component in self.dev_mapping_components:
      if self.device_usb_locations[i]:
        dev_component.status.SetLabel(self.atft_string.STATUS_MAPPED)
      else:
        dev_component.status.SetLabel(self.atft_string.STATUS_NOT_MAPPED)
      dev_component.status.GetParent().Layout()
      dev_component.status_wrapper.Layout()
      i += 1

  def ShowUSBMappingSetting(self, event):
    """Show the sub panel for mapping USB location.

    Args:
      event: The triggering event.
    """
    self.button_save.Hide()
    self.button_map.Show()
    self.button_automap.Show()
    self.buttons_sizer.Layout()
    self.current_setting = self.usb_mapping_panel
    self.current_menu = self.menu_map_usb
    self.ShowCurrentSetting()

  def ShowLanguageSetting(self, event):
    """Show the sub panel for language preference setting.

    Args:
      event: The triggering event.
    """
    self.button_save.Show()
    self.button_map.Hide()
    self.button_automap.Hide()
    self.buttons_sizer.Layout()
    self.current_setting = self.language_setting
    self.current_menu = self.menu_language
    self.ShowCurrentSetting()

  def ShowPasswordSetting(self, event):
    self.button_save.Show()
    self.button_map.Hide()
    self.button_automap.Hide()
    self.buttons_sizer.Layout()
    self.current_setting = self.password_setting
    self.current_menu = self.menu_set_password
    self.ShowCurrentSetting()

  def ShowCurrentSetting(self):
    """Switch the setting page to the current chosen page."""
    for setting in self.settings:
      setting.Hide()
    for menu_item in self.menu_items:
      menu_item.SetFont(self.menu_font)
    self.current_setting.Show()
    self.current_menu.SetFont(self.menu_font_bold)
    self.settings_sizer.Layout()
    self.panel_sizer.Layout()

  def OnSaveSetting(self, event):
    """The handler if user clicks save button."""
    if self.current_setting == self.language_setting:
      language_text = self.language_setting_list.GetValue().encode('utf-8')
      self.change_language_handler(language_text)
      self.EndModal(0)
      return
    elif self.current_setting == self.password_setting:
      old_password = self.original_password_input.GetValue()
      self.original_password_input.SetValue('')
      new_password = self.new_password_input.GetValue()
      if self.change_password_handler(old_password, new_password):
        self.new_password_input.SetValue('')
        self.EndModal(0)
      else:
        self.original_password_input.SetValue('')

  def OnExit(self, event):
    """Exit handler when user clicks cancel or press 'esc'.

    Args:
      event: The triggering event.
    """
    self.original_password_input.SetValue('')
    self.new_password_input.SetValue('')
    event.Skip()


class DevComponent(object):
  """The class to represent a target device UI component. """

  # The index for this component.
  index = -1
  # The main target device panel that displays the information.
  panel = None
  # The serial number
  serial_number = None
  # The serial number text field.
  serial_text = None
  # The status text field.
  status = None
  # The field wrapping the status text field. This should be used to change
  # the background color.
  status_background = None
  # The sizer to align status text field. Need to use
  # status_wrapper.Layout() in order to align status text correctly after
  # every status change.
  status_wrapper = None
  # The field wrapping the title text field. This should be used to change
  # background color if the device is selected.
  title_background = None
  # Whether this device slot is selected.
  selected = False
  # Whether this device slot is in use.
  active = False

  def __init__(self, index):
    self.index = index


class Atft(wx.Frame):
  """wxpython class to handle all GUI commands for the ATFA.

  Creates the GUI and provides various functions for interacting with an
  ATFA and an Android Things device.

  """
  CONFIG_FILE = 'config.json'

  ID_TOOL_PROVISION = 1
  ID_TOOL_CLEAR = 2

  def __init__(self):
    # If this is set to True, no prerequisites would be checked against manual
    # operation, such as you can do key provisioning before fusing the vboot key.
    self.test_mode = False

    self.provision_steps = []

    # The default steps included in the auto provisioning process.
    self.DEFAULT_PROVISION_STEPS_PRODUCT = [
        'FuseVbootKey', 'FusePermAttr', 'LockAvb', 'ProvisionProduct']

    self.DEFAULT_PROVISION_STEPS_SOM = ['FuseVbootKey', 'ProvisionSom']

    # The available provision steps.
    self.AVAILABLE_PROVISION_STEPS = [
        'FuseVbootKey', 'FusePermAttr', 'LockAvb', 'ProvisionProduct',
        'UnlockAvb', 'ProvisionSom']

    self.configs = self.ParseConfigFile()

    self.SetLanguage()

    self.atft_string.TITLE += ' ' + self.atft_version

    # The atft_manager instance to manage various operations.
    self.atft_manager = self.CreateAtftManager()

    # The target devices refresh timer object.
    self.refresh_timer = None

    # The field to sort target devices
    self.sort_by = self.atft_manager.SORT_BY_LOCATION

    # List of serial numbers for the devices in auto provisioning mode.
    self.auto_dev_serials = []

    # Store the last refreshed target list, we use this list to prevent
    # refreshing the same list.
    self.last_target_list = []

    # Indicate whether in auto provisioning mode.
    self.auto_prov = False

    # Indicate whether refresh is paused. If we could acquire this lock, this
    # means that the refresh is paused. We would pause the refresh during each
    # fastboot command since on Windows, a fastboot device would disappear from
    # fastboot devices while a fastboot command is issued. We use semaphore to
    # allow layered pause and resume, unless the last layer is resumed, the
    # refresh is in pause state.
    self.refresh_pause_lock = threading.Semaphore(0)

    # 'fastboot devices' can only run sequentially, so we use this lock to check
    # if there's already a 'fastboot devices' command running. If so, we ignore
    # the second request.
    self.listing_device_lock = threading.Lock()

    # To prevent low key alert to show by each provisioning.
    # We only show it once per auto provision.
    self.first_key_alert_shown = False
    self.second_key_alert_shown = False

    # Lock to make sure only one device is doing auto provisioning at one time.
    self.auto_prov_lock = threading.Lock()

    # Lock for showing alert box
    self.alert_lock = threading.Lock()

    # Supervisor Mode
    self.sup_mode = True

    self.InitializeUI()

    self.CreateShortCuts()

    self.log = self.CreateAtftLog()

    self.audit = self.CreateAtftAudit()

    self.key_handler = self.CreateAtftKeyHandler()
    self.key_handler.StartProcessKey()

    if self.configs == None:
      self.ShowAlert(self.atft_string.ALERT_FAIL_TO_PARSE_CONFIG)
      sys.exit(0)

    if not self.log.log_dir_file:
      self._SendAlertEvent(self.atft_string.ALERT_FAIL_TO_CREATE_LOG)

    if (not self.log.CheckInstanceRunning() and
        not self._ShowWarning(self.atft_string.ALERT_INSTANCE_RUNNING)):
        sys.exit(0)

    self.log.Info('Program', 'Program start')

    # Leave supervisor mode
    self._OnToggleSupMode(None)

    self.ShowStartScreen()
    self.StartRefreshingDevices()

  @staticmethod
  def _BindEventRecursive(event, widget, handler):
    """Bind a event to all the children under a widget recursively.

    Because some event such as mouse down would not propagate to parent window,
    we need to bind the event handler to all the children of the target widget.

    Args:
      event: The event to bind.
      widget: The current widget to bind.
      handler: The event handler.
    """
    widget.Bind(event, handler)
    for child in widget.GetChildren():
      Atft._BindEventRecursive(event, child, handler)

  @staticmethod
  def CreateTargetDeviceList(parent, parent_sizer, map_usb=False):
    """Create the grid style panel to display target device information.

    Args:
      parent: The parent window.
      parent_sizer: The parent sizer.
      map_usb: Whether the target list is for USB location mapping.
    Returns:
      A list of DevComponent object that contains necessary information and UI
        element about each target device.
    """
    # target device output components
    target_dev_components = []

    # The scale of the display size. We need a smaller version of the target
    # device list for the settings page, so we can use this scale factor to
    # scale the panel's size.
    scale = 1

    if map_usb:
      scale = 0.9

    # Device Output Window
    devices_list = wx.GridSizer(2, 3, 40 * scale, 0)
    parent_sizer.Add(devices_list, flag=wx.BOTTOM, border=20)

    for i in range(TARGET_DEV_SIZE):
      dev_component = DevComponent(i)
      # Create each target device panel.
      target_devs_output_panel = wx.Window(
          parent, style=wx.BORDER_RAISED)
      target_devs_output_panel_sizer = wx.BoxSizer(wx.VERTICAL)
      dev_component.panel = target_devs_output_panel

      # Create the title panel.
      target_devs_output_title = wx.Window(
          target_devs_output_panel, style=wx.BORDER_NONE,
          size=(270 * scale, 50 * scale))
      target_devs_output_title.SetBackgroundColour(COLOR_WHITE)
      # Don't accept user input, otherwise user input would change the style.
      target_devs_output_title_sizer = wx.BoxSizer(wx.HORIZONTAL)
      target_devs_output_title.SetSizer(target_devs_output_title_sizer)
      dev_component.title_background = target_devs_output_title

      # The number in the title bar.
      target_devs_output_number = wx.StaticText(
          target_devs_output_title, wx.ID_ANY, str(i + 1).zfill(2))
      dev_component.index_text = target_devs_output_number
      target_devs_output_title_sizer.Add(
          target_devs_output_number, 0, wx.ALL, 10)
      number_font = wx.Font(
          18, wx.FONTFAMILY_SWISS, wx.NORMAL, wx.FONTWEIGHT_BOLD)
      target_devs_output_number.SetForegroundColour(COLOR_DARK_GREY)
      target_devs_output_number.SetFont(number_font)

      # The serial number in the title bar.
      target_devs_output_serial = wx.StaticText(
          target_devs_output_title, wx.ID_ANY, '')
      target_devs_output_serial.SetForegroundColour(COLOR_BLACK)
      target_devs_output_serial.SetMinSize((180 * scale, 15))
      target_devs_output_title_sizer.Add(
          target_devs_output_serial, 0, wx.TOP, 18)
      serial_font = wx.Font(
          9, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
      target_devs_output_serial.SetFont(serial_font)
      dev_component.serial_text = target_devs_output_serial

      # The selected icon in the title bar
      selected_image = wx.Image('selected.png', type=wx.BITMAP_TYPE_PNG)
      selected_bitmap = wx.Bitmap(selected_image)
      selected_icon = wx.StaticBitmap(
          target_devs_output_title, bitmap=selected_bitmap)
      target_devs_output_title_sizer.Add(selected_icon, 0, wx.TOP, 12 * scale)

      # The device status panel.
      target_devs_output_status = wx.Window(
          target_devs_output_panel, style=wx.BORDER_NONE,
          size=(270 * scale, 110 * scale))
      target_devs_output_status.SetBackgroundColour(COLOR_GREY)
      target_devs_output_status_sizer = wx.BoxSizer(wx.HORIZONTAL)
      target_devs_output_status.SetSizer(target_devs_output_status_sizer)
      dev_component.status_background = target_devs_output_status

      # The device status string.
      device_status_string = ''
      target_devs_output_status_info = wx.StaticText(
          target_devs_output_status, wx.ID_ANY, device_status_string)
      font_size = 18
      if map_usb:
        font_size = 20
      status_font = wx.Font(
          font_size, wx.FONTFAMILY_SWISS, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
      target_devs_output_status_info.SetForegroundColour(COLOR_BLACK)
      target_devs_output_status_info.SetFont(status_font)
      dev_component.status = target_devs_output_status_info

      # We need two sizers, one for vertical alignment and one for horizontal.
      target_devs_output_status_ver_sizer = wx.BoxSizer(wx.VERTICAL)
      target_devs_output_status_ver_sizer.Add(
          target_devs_output_status_info, 1, wx.ALIGN_CENTER)
      target_devs_output_status_sizer.Add(
          target_devs_output_status_ver_sizer, 1, wx.ALIGN_CENTER)
      dev_component.status_wrapper = target_devs_output_status_ver_sizer

      target_devs_output_panel_sizer.Add(target_devs_output_title, 0, wx.EXPAND)
      target_devs_output_panel_sizer.Add(
          target_devs_output_status, 0, wx.EXPAND)
      target_devs_output_panel.SetSizer(target_devs_output_panel_sizer)

      # This sizer is only to add 15px right border
      target_devs_output_panel_sizer_wrap = wx.BoxSizer(wx.HORIZONTAL)
      target_devs_output_panel_sizer_wrap.Add(target_devs_output_panel)
      target_devs_output_panel_sizer_wrap.AddSpacer(15 * scale)

      devices_list.Add(
          target_devs_output_panel_sizer_wrap, 0, wx.LEFT | wx.RIGHT, 10)
      target_dev_components.append(dev_component)

    return target_dev_components

  @staticmethod
  def VerifyPassword(password, password_hash):
    """Use pbkdf2_sha256 to verify password against the stored hash.

    Args:
      password: The password to be verified.
      password_hash: The hash for the password.
    Returns:
      True: if password match.
      False: if password does not match.
    """
    try:
      return pbkdf2_sha256.verify(password, password_hash)
    except:
      return False

  @staticmethod
  def GeneratePasswordHash(password):
    """Use pbkdf2_sha256 to generate password hash.

    Args:
      password: The password to be verified.
    Returns:
      password hash
    """
    return pbkdf2_sha256.hash(password)

  def CreateAtftManager(self):
    """Create an AtftManager object.

    This function exists for test mocking.
    """
    return AtftManager(FastbootDevice, SerialMapper, self.configs)

  def CreateAtftLog(self):
    """Create an AtftLog object.

    This function exists for test mocking.
    """
    return AtftLog(self.log_dir, self.log_size, self.log_file_number)

  def CreateAtftAudit(self):
    """Create an AtftAudit object.

    This function exists for test mocking.
    """
    return AtftAudit(self.audit_dir,
                     self.audit_interval,
                     self._GetFileFromATFA,
                     self._HandleException,
                     self.atft_manager.GetATFASerial)

  def CreateAtftKeyHandler(self):
    return AtftKeyHandler(self.key_dir,
                   self.log_dir,
                   self.key_file_extension,
                   self._ProcessKey,
                   self._HandleException,
                   self.atft_manager.GetATFASerial)

  def ParseConfigFile(self):
    """Parse the configuration file and read in the necessary configurations.

    Returns:
      The parsed configuration map.
    """
    # Give default values
    self.atft_version = 'v0.0'
    self.compatible_atfa_version = '0'
    self.device_refresh_interval = 1.0
    self.default_key_threshold_1 = None
    self.default_key_threshold_2 = None
    self.log_dir = None
    self.log_size = 0
    self.log_file_number = 0
    self.audit_dir = None
    # By default we download audit file per 10 keys provisioned.
    self.audit_interval = 10
    self.language = 'eng'
    self.reboot_timeout = 0
    self.atfa_reboot_timeout = 0
    self.product_attribute_file_extension = '*.atpa'
    self.key_file_extension = '*.atfa'
    self.update_file_extension = '*.upd'
    self.key_dir = None

    # The list to store the device location for each target device slot. If the
    # slot is not mapped, it will be None.
    self.device_usb_locations = []
    for i in range(TARGET_DEV_SIZE):
      self.device_usb_locations.append(None)

    config_file_path = os.path.join(self._GetCurrentPath(), self.CONFIG_FILE)
    if not os.path.exists(config_file_path):
      return None

    with open(config_file_path, 'r') as config_file:
      configs = json.loads(config_file.read())

    if not configs:
      return None

    try:
      self.atft_version = str(configs['ATFT_VERSION'])
      self.compatible_atfa_version = str(configs['COMPATIBLE_ATFA_VERSION'])
      self.device_refresh_interval = float(configs['DEVICE_REFRESH_INTERVAL'])
      if 'DEFAULT_KEY_THRESHOLD_1' in configs:
        self.default_key_threshold_1 = int(configs['DEFAULT_KEY_THRESHOLD_1'])
      if 'DEFAULT_KEY_THRESHOLD_2' in configs:
        self.default_key_threshold_2 = int(configs['DEFAULT_KEY_THRESHOLD_2'])
      self.log_dir = str(configs['LOG_DIR'])
      self.log_size = int(configs['LOG_SIZE'])
      self.log_file_number = int(configs['LOG_FILE_NUMBER'])
      self.audit_dir = str(configs['AUDIT_DIR'])
      self.language = str(configs['LANGUAGE'])
      self.reboot_timeout = float(configs['REBOOT_TIMEOUT'])
      self.atfa_reboot_timeout = float(configs['ATFA_REBOOT_TIMEOUT'])
      self.product_attribute_file_extension = str(
          configs['PRODUCT_ATTRIBUTE_FILE_EXTENSION'])
      self.key_file_extension = str(configs['KEY_FILE_EXTENSION'])
      self.update_file_extension = str(configs['UPDATE_FILE_EXTENSION'])
      self.password_hash = str(configs['PASSWORD_HASH'])
      if 'DEVICE_USB_LOCATIONS' in configs:
        self.device_usb_locations = configs['DEVICE_USB_LOCATIONS']
      if 'TEST_MODE' in configs:
        self.test_mode = configs['TEST_MODE']
      if 'PROVISION_STEPS' in configs:
        self.provision_steps = configs['PROVISION_STEPS']
      if 'AUDIT_INTERVAL' in configs:
        self.audit_interval = int(configs['AUDIT_INTERVAL'])
      if 'KEY_DIR' in configs:
        self.key_dir = configs['KEY_DIR']
    except (KeyError, ValueError):
      return None

    return configs

  def _CheckProvisionSteps(self):
    """Check whether the "PROVISION_STEPS" config is valid.

    Check the format of "PROVISION_STEPS" config. If test_mode is not set to
    True, verify that the customized provision steps meet the necessary security
    requirement.
    """
    if self.atft_manager.product_info:
      default_provision_steps = self.DEFAULT_PROVISION_STEPS_PRODUCT
    else:
      default_provision_steps = self.DEFAULT_PROVISION_STEPS_SOM

    if not self.provision_steps:
      self.provision_steps = default_provision_steps
      return
    try:
      provision_steps_verified = (
          self._VerifyProvisionSteps(self.provision_steps))
    except ValueError:
      self.provision_steps = default_provision_steps
      self._SendAlertEvent(self.atft_string.ALERT_PROVISION_STEPS_SYNTAX_ERROR)
      return

    if self.test_mode:
      return
    if not provision_steps_verified:
      self.provision_steps = default_provision_steps
      self._SendAlertEvent(self.atft_string.ALERT_PROVISION_STEPS_SECURITY_REQ)


  def _VerifyProvisionSteps(self, provision_steps):
    """Verify if the customized provision steps meet security requirements.

    Args:
      provision_steps: The customized provision steps to verify.
    Raises:
      ValueError: If the syntax for provision_steps is not correct.
    """
    if not isinstance(provision_steps, list):
      raise ValueError()
    provision_state = ProvisionState()
    for operation in provision_steps:
      if operation not in self.AVAILABLE_PROVISION_STEPS:
        raise ValueError()
      if operation == 'FuseVbootKey':
        provision_state.bootloader_locked = True
        continue
      elif operation == 'FusePermAttr':
        if (not provision_state.bootloader_locked or
            provision_state.avb_perm_attr_set):
          return False
        else:
          provision_state.avb_perm_attr_set = True
          continue
      elif operation == 'LockAvb':
        if (not provision_state.bootloader_locked or
            not provision_state.avb_perm_attr_set):
          return False
        else:
          provision_state.avb_locked = True
        continue
      elif operation == 'UnlockAvb':
        provision_state.avb_locked = False
        continue
      elif operation == 'ProvisionProduct':
        if (not provision_state.bootloader_locked or
            not provision_state.avb_perm_attr_set or
            provision_state.product_provisioned):
          return False
        else:
          provision_state.product_provisioned = True
      elif operation == 'ProvisionSom':
        if (not provision_state.bootloader_locked or
            provision_state.som_provisioned):
          return False
        else:
          provision_state.som_provisioned = True
    return True

  def _StoreConfigToFile(self):
    """Store the configuration to the configuration file.

    By storing the configuration back, the program would remember the
    configuration if it's opened again.
    """
    self.configs['DEVICE_USB_LOCATIONS'] = self.device_usb_locations
    self.configs['PASSWORD_HASH'] = self.password_hash
    self.configs['LANGUAGE'] = self.language
    config_file_path = os.path.join(self._GetCurrentPath(), self.CONFIG_FILE)
    with open(config_file_path, 'w') as config_file:
      config_file.write(json.dumps(self.configs, sort_keys=True, indent=4))

  def _GetCurrentPath(self):
    """Get the current directory.

    Returns:
      The current directory.
    """
    if getattr(sys, 'frozen', False):
      # we are running in a bundle
      path = sys._MEIPASS  # pylint: disable=protected-access
    else:
      # we are running in a normal Python environment
      path = os.path.dirname(os.path.abspath(__file__))
    return path

  def GetLanguageIndex(self):
    """Translate language setting to an index.

    Returns:
      index: A index representing the language.
    """
    for index in range(len(LANGUAGE_CONFIGS)):
      if self.language == LANGUAGE_CONFIGS[index]:
        return index
    return -1

  def SetLanguage(self):
    """Set the string constants according to the language setting.
    """
    self.atft_string = AtftString(self.GetLanguageIndex())

  def InitializeUI(self):
    """Initialize the application UI."""
    # The frame style is default style without border.
    style = wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
    wx.Frame.__init__(self, None, style=style)

    # Menu:
    # Application   -> App Settings
    #               -> Choose Product
    #               -> Key Warning Threshold
    #               -> Clear Command Output
    #               -> Show Statusbar
    #               -> Quit

    # Key Provision -> Fuse Bootloader Vboot Key
    #               -> Fuse Permanent Attributes
    #               -> Lock Android Verified Boot
    #               -> Provision Key

    # ATFA Device   -> ATFA Status
    #               -> Registration
    #               -> Update
    #               -> Reboot
    #               -> Shutdown

    # Audit         -> Download Audit File

    # Key Management-> Store Key Bundle
    #               -> Purge Key Bundle

    # Add Menu items to Menubar
    self.menubar = wx.MenuBar()
    self._CreateAppMenu()
    self._CreateProvisionMenu()
    self._CreateATFAMenu()
    self._CreateAuditMenu()
    self._CreateKeyMenu()
    self.SetMenuBar(self.menubar)

    # The main panel
    self.panel = wx.Window(self)
    self.main_box = wx.BoxSizer(wx.VERTICAL)
    self._CreateHeaderPanel()
    self._CreateTargetDevsPanel()
    self._CreateCommandOutputPanel()
    self._CreateStatusBar()

    self.SetTitle(self.atft_string.TITLE)
    self.panel.SetSizerAndFit(self.main_box)
    self.Show(True)

    # App Settings Dialog
    self.app_settings_dialog = AppSettingsDialog(
        self.atft_string,
        self.AutoMapUSBLocationToSlot,
        self.ManualMapUSBLocationToSlot,
        self.MapUSBToSlotHandler,
        self.ChangeLanguage,
        self.ChangePassword,
        self.GetLanguageIndex(),
        self.device_usb_locations)
    self.app_settings_dialog.CreateDialog(
        self, wx.ID_ANY, self.atft_string.MENU_APP_SETTINGS)

    # Change Key Threshold Dialog
    self.change_threshold_dialog = ChangeThresholdDialog(
        self.atft_string,
        self.default_key_threshold_1,
        self.default_key_threshold_2)
    self.change_threshold_dialog.CreateDialog(
        self,
        wx.ID_ANY,
        self.atft_string.DIALOG_CHANGE_THRESHOLD_TITLE)

    # Low Key Alert Dialog
    self.low_key_dialog = wx.MessageDialog(
        self,
        self.atft_string.DIALOG_LOW_KEY_TEXT,
        self.atft_string.DIALOG_LOW_KEY_TITLE,
        style=wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE)

    # General Alert Dialog
    self.alert_dialog = wx.MessageDialog(
        self,
        self.atft_string.DIALOG_ALERT_TEXT,
        self.atft_string.DIALOG_ALERT_TITLE,
        style=wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE)

    # Password Dialog
    self.password_dialog = wx.PasswordEntryDialog(
        self,
        self.atft_string.DIALOG_INPUT_PASSWORD,
        self.atft_string.DIALOG_PASSWORD)

    self._CreateBindEvents()

    self.main_box.Layout()
    self.panel.SetSizerAndFit(self.main_box)
    self.Layout()
    self.SetSize(self.GetWindowSize())

    # Display correct target device active/non-active status.
    self._PrintTargetDevices()

  def CreateShortCuts(self):
    """Create hot key bindings. """
    accel_entries = []
    event_id = wx.NewId()
    accel_entries.append(
        wx.AcceleratorEntry(wx.ACCEL_ALT, ord('S'), event_id))
    self.Bind(wx.EVT_MENU, self._OnToggleSupMode, id=event_id)
    event_id = wx.NewId()
    accel_entries.append(
        wx.AcceleratorEntry(wx.ACCEL_ALT, ord('T'), event_id))
    self.Bind(wx.EVT_MENU, self._OnFocusTargetDevList, id=event_id)
    event_id = wx.NewId()
    accel_entries.append(
        wx.AcceleratorEntry(wx.ACCEL_NORMAL, wx.WXK_TAB, event_id))
    self.Bind(wx.EVT_MENU, self._OnPressTab, id=event_id)
    event_id = wx.NewId()
    accel_entries.append(
        wx.AcceleratorEntry(wx.ACCEL_NORMAL, wx.WXK_RETURN, event_id))
    self.Bind(wx.EVT_MENU, self._OnPressEnter, id=event_id)
    self.SetAcceleratorTable(wx.AcceleratorTable(accel_entries))

  def _OnFocusTargetDevList(self, event):
    """Focus on the first target device slot.

    Args:
      event: The triggering event.
    """
    if not self.sup_mode:
      return
    self.target_dev_components[0].panel.SetFocus()

  def _OnPressTab(self, event):
    """Handler when 'tab' is pressed. Change focus on target device slot.

    Args:
      event: The triggering event.
    """
    if not self.sup_mode:
      return

    window = wx.Window.FindFocus()

    # If the current focus is on target d
    for i in range(0, TARGET_DEV_SIZE):
      if window == self.target_dev_components[i].panel:
        j = (i + 1) % TARGET_DEV_SIZE
        self.target_dev_components[j].panel.SetFocus()
        return

  def _OnPressEnter(self, event):
    """Handler when 'enter' is pressed.

    If the current focus is on a target device slot, click that slot.

    Args:
      event: The triggering event.
    """
    window = wx.Window.FindFocus()
    for i in range(0, TARGET_DEV_SIZE):
      if window == self.target_dev_components[i].panel:
        window.QueueEvent(wx.MouseEvent(wx.wxEVT_LEFT_DOWN));
        return

  def _CreateAppMenu(self):
    """Create the app menu items."""
    app_menu = wx.Menu()
    self.menubar.Append(app_menu, self.atft_string.MENU_APPLICATION)
    # App Menu Options
    menu_app_settings = app_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_APP_SETTINGS)
    self.Bind(wx.EVT_MENU, self.ChangeSettings, menu_app_settings)
    self.menu_app_settings = menu_app_settings

    menu_choose_product = app_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_CHOOSE_PRODUCT)
    self.Bind(wx.EVT_MENU, self.ChooseProduct, menu_choose_product)

    menu_key_threshold = app_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_KEY_THRESHOLD)
    self.Bind(wx.EVT_MENU, self.OnChangeKeyThreshold, menu_key_threshold)

    menu_clear_command = app_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_CLEAR_COMMAND)

    self.Bind(wx.EVT_MENU, self.OnClearCommandWindow, menu_clear_command)

    self.menu_show_status_bar = app_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_SHOW_STATUS_BAR, kind=wx.ITEM_CHECK)
    app_menu.Check(self.menu_show_status_bar.GetId(), True)
    self.Bind(wx.EVT_MENU, self.ToggleStatusBar, self.menu_show_status_bar)

    menu_quit = app_menu.Append(wx.ID_EXIT, self.atft_string.MENU_QUIT)
    self.Bind(wx.EVT_MENU, self.OnQuit, menu_quit)
    self.app_menu = app_menu

  def _CreateProvisionMenu(self):
    """Create the provision menu items."""
    provision_menu = wx.Menu()
    self.menubar.Append(provision_menu, self.atft_string.MENU_KEY_PROVISIONING)
    # Key Provision Menu Options
    menu_manual_fuse_vboot = provision_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_MANUAL_FUSE_VBOOT)
    self.Bind(wx.EVT_MENU, self.OnFuseVbootKey, menu_manual_fuse_vboot)

    menu_manual_fuse_attr = provision_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_MANUAL_FUSE_ATTR)
    self.Bind(wx.EVT_MENU, self.OnFusePermAttr, menu_manual_fuse_attr)

    menu_manual_lock_avb = provision_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_MANUAL_LOCK_AVB)
    self.Bind(wx.EVT_MENU, self.OnLockAvb, menu_manual_lock_avb)

    menu_manual_prov = provision_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_MANUAL_PROV)
    self.Bind(wx.EVT_MENU, self.OnManualProvision, menu_manual_prov)

    self.provision_menu = provision_menu

  def _CreateATFAMenu(self):
    """Create the ATFA menu items."""
    atfa_menu = wx.Menu()
    self.menubar.Append(atfa_menu, self.atft_string.MENU_ATFA_DEVICE)
    # ATFA Menu Options
    menu_atfa_status = atfa_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_ATFA_STATUS)
    self.Bind(wx.EVT_MENU, self.OnCheckATFAStatus, menu_atfa_status)

    menu_reg_file = atfa_menu.Append(wx.ID_ANY, self.atft_string.MENU_REG_FILE)
    self.Bind(wx.EVT_MENU, self.OnGetRegFile, menu_reg_file)

    menu_update = atfa_menu.Append(wx.ID_ANY, self.atft_string.MENU_ATFA_UPDATE)
    self.Bind(wx.EVT_MENU, self.OnUpdateAtfa, menu_update)

    menu_reboot = atfa_menu.Append(wx.ID_ANY, self.atft_string.MENU_REBOOT)
    self.Bind(wx.EVT_MENU, self.OnReboot, menu_reboot)

    menu_shutdown = atfa_menu.Append(wx.ID_ANY, self.atft_string.MENU_SHUTDOWN)
    self.Bind(wx.EVT_MENU, self.OnShutdown, menu_shutdown)

    self.atfa_menu = atfa_menu

  def _CreateAuditMenu(self):
    """Create the audit menu items."""
    audit_menu = wx.Menu()
    self.menubar.Append(audit_menu, self.atft_string.MENU_AUDIT)
    # Audit Menu Options
    menu_download_audit = audit_menu.Append(
        wx.ID_ANY, self.atft_string.MENU_DOWNLOAD_AUDIT)
    self.Bind(wx.EVT_MENU, self.OnGetAuditFile, menu_download_audit)

    self.audit_menu = audit_menu

  def _CreateKeyMenu(self):
    """Create the key menu items."""
    key_menu = wx.Menu()
    self.menubar.Append(key_menu, self.atft_string.MENU_KEY_MANAGEMENT)
    # Key Management Menu Options
    menu_storekey = key_menu.Append(wx.ID_ANY, self.atft_string.MENU_STOREKEY)
    self.Bind(wx.EVT_MENU, self.OnStoreKey, menu_storekey)

    menu_purgekey = key_menu.Append(wx.ID_ANY, self.atft_string.MENU_PURGE)
    self.Bind(wx.EVT_MENU, self.OnPurgeKey, menu_purgekey)

    self.key_menu = key_menu

  def _CreateHeaderPanel(self):
    """Create the header panel.

    The header panel contains the supervisor button, product information and
    ATFA device information.
    """
    header_panel = wx.Window(self.panel)
    header_panel.SetForegroundColour(COLOR_BLACK)
    header_panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
    header_panel_left_sizer = wx.BoxSizer(wx.VERTICAL)
    header_panel_right_sizer = wx.BoxSizer(wx.VERTICAL)
    header_panel_sizer.Add(header_panel_left_sizer, 0)
    header_panel_sizer.Add(
        header_panel_right_sizer, 1, wx.RIGHT, 10)

    self.button_supervisor = wx.Button(
        header_panel, wx.ID_ANY, style=wx.BORDER_NONE, label='...',
        name='Toggle Supervisor Mode', size=(40, 40))
    button_supervisor_font = wx.Font(
        20, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    self.button_supervisor.SetFont(button_supervisor_font)
    self.button_supervisor.SetForegroundColour(COLOR_BLACK)
    header_panel_right_sizer.Add(self.button_supervisor, 0, wx.ALIGN_RIGHT)
    self.button_supervisor_toggle = wx.Button(
        header_panel,
        wx.ID_ANY,
        style=wx.BU_LEFT,
        label=self.atft_string.BUTTON_LEAVE_SUP_MODE,
        name=self.atft_string.BUTTON_LEAVE_SUP_MODE,
        size=(200, 30))
    button_supervisor_font = wx.Font(
        10, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    self.button_supervisor_toggle.SetFont(button_supervisor_font)
    self.button_supervisor_toggle.SetForegroundColour(COLOR_BLACK)
    self.button_supervisor_toggle.Hide()
    header_panel_right_sizer.Add(
        self.button_supervisor_toggle, 0, wx.ALIGN_RIGHT)
    self.header_panel_right_sizer = header_panel_right_sizer

    self.Bind(wx.EVT_BUTTON, self._OnToggleSupButton, self.button_supervisor)
    self.Bind(
        wx.EVT_BUTTON, self._OnToggleSupMode, self.button_supervisor_toggle)

    # Product Name Display
    self.product_name_title = wx.StaticText(header_panel, wx.ID_ANY, '')
    self.product_name_display = wx.StaticText(
        header_panel, wx.ID_ANY, self.atft_string.TITLE_PRODUCT_NAME_NOTCHOSEN)
    product_name_font = wx.Font(16, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    self.product_name_title.SetFont(product_name_font)
    self.product_name_display.SetFont(product_name_font)
    self.product_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
    self.product_name_sizer.Add(self.product_name_title)
    self.product_name_sizer.Add(self.product_name_display, 0, wx.LEFT, 2)
    header_panel_left_sizer.Add(self.product_name_sizer, 0, wx.ALL, 5)

    self.main_box.Add(header_panel, 0, wx.EXPAND)

    # Device Output Title
    atfa_dev_title = wx.StaticText(
        header_panel,
        wx.ID_ANY,
        self.atft_string.TITLE_ATFA_DEV)
    self.atfa_dev_output = wx.StaticText(header_panel, wx.ID_ANY, '')
    atfa_dev_title_sizer = wx.BoxSizer(wx.HORIZONTAL)
    atfa_dev_title_sizer.Add(atfa_dev_title)
    atfa_dev_title_sizer.Add(self.atfa_dev_output)
    header_panel_left_sizer.Add(atfa_dev_title_sizer, 0, wx.LEFT | wx.BOTTOM, 5)

    header_panel.SetSizerAndFit(header_panel_sizer)

  def _CreateTargetDevsPanel(self):
    """Create the target device panel to list target devices."""
    # Device Output Title
    target_devs_panel = wx.Window(self.panel, style=wx.BORDER_NONE)
    target_devs_panel_sizer = wx.BoxSizer(wx.VERTICAL)

    self.target_devs_title = wx.StaticText(
        target_devs_panel, wx.ID_ANY, self.atft_string.TITLE_TARGET_DEV)
    target_dev_font = wx.Font(
        16, wx.FONTFAMILY_SWISS, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    self.target_devs_title.SetFont(target_dev_font)
    self.target_devs_title_sizer = wx.BoxSizer(wx.HORIZONTAL)
    self.target_devs_title_sizer.Add(self.target_devs_title, 0, wx.LEFT, 10)

    target_devs_panel_sizer.Add(
        self.target_devs_title_sizer, 0, wx.TOP | wx.BOTTOM, 10)

    self.target_dev_components = Atft.CreateTargetDeviceList(
        target_devs_panel, target_devs_panel_sizer)

    target_devs_panel.SetSizerAndFit(target_devs_panel_sizer)
    target_devs_panel.SetBackgroundColour(COLOR_WHITE)

    self.main_box.Add(target_devs_panel, 0, wx.EXPAND)

  def _CreateCommandOutputPanel(self):
    """Create command output panel to show command outputs."""
    # Command Output Title
    self.cmd_output_wrap = wx.Window(self.panel)
    cmd_output_wrap_sizer = wx.BoxSizer(wx.VERTICAL)

    static_line = wx.StaticLine(self.cmd_output_wrap)
    static_line.SetForegroundColour(COLOR_BLACK)
    cmd_output_wrap_sizer.Add(static_line, 0, wx.EXPAND)

    command_title_panel = wx.Window(self.cmd_output_wrap)
    command_title_sizer = wx.BoxSizer(wx.VERTICAL)
    command_title = wx.StaticText(
        command_title_panel, wx.ID_ANY, self.atft_string.TITLE_COMMAND_OUTPUT)
    command_title.SetForegroundColour(COLOR_BLACK)
    command_title_font = wx.Font(
        16, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.FONTWEIGHT_BOLD)
    command_title.SetFont(command_title_font)
    command_title_sizer.Add(command_title, 0, wx.ALL, 5)
    command_title_panel.SetSizerAndFit(command_title_sizer)
    command_title_panel.SetBackgroundColour(COLOR_WHITE)
    cmd_output_wrap_sizer.Add(
        command_title_panel, 0, wx.EXPAND)
    self.cmd_output_wrap_sizer = cmd_output_wrap_sizer

    # Command Output Window
    cmd_output_panel = wx.Window(self.cmd_output_wrap)
    self.cmd_output = wx.TextCtrl(
        cmd_output_panel,
        wx.ID_ANY,
        size=(0, 110),
        style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL | wx.BORDER_NONE)
    cmd_output_sizer = wx.BoxSizer(wx.VERTICAL)
    cmd_output_sizer.Add(
        self.cmd_output, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 10)
    cmd_output_panel.SetSizerAndFit(cmd_output_sizer)
    cmd_output_panel.SetBackgroundColour(COLOR_WHITE)

    cmd_output_wrap_sizer.Add(cmd_output_panel, 0, wx.ALL | wx.EXPAND, 0)
    self.cmd_output_wrap.SetSizerAndFit(cmd_output_wrap_sizer)

    self.main_box.Add(self.cmd_output_wrap, 0, wx.EXPAND, 0)

  def _CreateStatusBar(self):
    """Create the bottom status bar."""
    self.statusbar = self.CreateStatusBar(1, style=wx.STB_DEFAULT_STYLE)
    self.statusbar.SetBackgroundColour(COLOR_BLACK)
    self.statusbar.SetForegroundColour(COLOR_WHITE)
    status_sizer = wx.BoxSizer(wx.VERTICAL)
    self.status_text = wx.StaticText(
        self.statusbar, wx.ID_ANY, self.atft_string.TITLE_KEYS_LEFT)
    status_sizer.AddSpacer(5)
    status_sizer.Add(self.status_text, 0, wx.LEFT, 10)
    statusbar_font = wx.Font(
        10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    self.status_text.SetFont(statusbar_font)
    self.status_text.SetForegroundColour(COLOR_WHITE)
    self.statusbar.SetSize(0, 35)
    self.statusbar.SetSizer(status_sizer)
    # Add the spacer for statusbar
    self.main_box.AddSpacer(40)

  def ShowStartScreen(self):
    """Show the start screen which contains start logo.

    We also ask user to choose product file at the start screen
    """
    self.start_screen_shown = True
    self.panel.Hide()
    self.statusbar.Hide()
    self.SetMenuBar(None)
    self.start_screen = wx.Window(self, size=(960, 600))
    self.start_screen.SetBackgroundColour(COLOR_BLACK)
    start_screen_sizer = wx.BoxSizer(wx.VERTICAL)
    self.start_screen.SetSizer(start_screen_sizer)
    start_screen_sizer.AddSpacer(120)
    athings_logo_img = wx.Image('athings_icon.png', type=wx.BITMAP_TYPE_PNG)
    athings_logo = wx.Bitmap(athings_logo_img)
    logo_img = wx.StaticBitmap(self.start_screen, bitmap=athings_logo)
    start_screen_sizer.Add(logo_img, 0, wx.ALIGN_CENTER)
    start_screen_sizer.AddSpacer(30)
    athings_text_image = wx.Image('androidthings.png', type=wx.BITMAP_TYPE_PNG)
    athings_text = wx.Bitmap(athings_text_image)
    athings_img = wx.StaticBitmap(self.start_screen, bitmap=athings_text)
    start_screen_sizer.Add(athings_img, 0, wx.ALIGN_CENTER)
    start_screen_sizer.AddSpacer(50)

    button_choose_product = wx.Button(
        self.start_screen,
        label=self.atft_string.MENU_CHOOSE_PRODUCT,
        size=(250, 50))
    font = wx.Font(16, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_NORMAL)
    button_choose_product.SetFont(font)
    button_choose_product.SetBackgroundColour(COLOR_DARK_GREY)
    button_choose_product.SetForegroundColour(COLOR_WHITE)

    start_screen_sizer.Add(button_choose_product, 0, wx.ALIGN_CENTER)
    button_choose_product.Bind(wx.EVT_BUTTON, self.ChooseProduct)
    self.start_screen.Layout()
    self.SetSize(self.start_screen.GetSize())
    self.CenterOnParent()
    button_choose_product.SetFocus()

  def HideStartScreen(self):
    """Hide the start screen."""
    self.start_screen_shown = False
    self.start_screen.Hide()
    self.panel.Show()
    self.statusbar.Show()
    if self.sup_mode:
      self.SetMenuBar(self.menubar)
    self.main_box.Layout()
    self.panel.SetSizerAndFit(self.main_box)
    self.Layout()
    self.SetSize(self.GetWindowSize())
    self.SetFocus()

  def GetWindowSize(self):
    """Get the current main window size."""
    size_x = self.panel.GetSize()[0]
    size_y = 0
    if self.menubar.IsShown():
      size_y += self.menubar.GetSize()[1]
    size_y += self.panel.GetSize()[1]
    if self.statusbar.IsShown():
      size_y += self.statusbar.GetSize()[1]
    return (size_x, size_y)

  def PauseRefresh(self):
    """Pause the refresh for device list during fastboot operations.
    """
    self.refresh_pause_lock.release()

  def ResumeRefresh(self):
    """Resume the refresh for device list.
    """
    self.refresh_pause_lock.acquire()

  def PrintToWindow(self, text_entry, text, append=False):
    """Print some message to a text_entry window.

    Args:
      text_entry: The window to print to.
      text: The text to be printed.
      append: Whether to replace or append the message.
    """
    # Append the message.
    if append:
      text_entry.AppendText(text)
      return

    # Replace existing message. Need to clean first. The GetValue() returns
    # unicode string, need to encode that to utf-8 to compare.
    current_text = text_entry.GetValue().encode('utf-8')
    if text == current_text:
      # If nothing changes, don't refresh.
      return
    text_entry.Clear()
    text_entry.AppendText(text)

  def PrintToCommandWindow(self, text):
    """Print some message to the command window.

    Args:
      text: The text to be printed.
    """
    msg = '[' + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + '] '
    msg += text + '\n'
    self.PrintToWindow(self.cmd_output, msg, True)

  def StartRefreshingDevices(self):
    """Refreshing the device list by interval of device_refresh_interval.
    """
    # If there's already a timer running, stop it first.
    self.StopRefresh()
    # Start a new timer.
    self.refresh_timer = threading.Timer(self.device_refresh_interval,
                                         self.StartRefreshingDevices)
    self.refresh_timer.start()
    if self.refresh_pause_lock.acquire(False):
      # Semaphore > 0, refresh is still paused.
      self.refresh_pause_lock.release()
      self._SendDeviceListedEvent()
    else:
      # If refresh is not paused, refresh the devices.
      self._ListDevices()

  def StopRefresh(self):
    """Stop the refresh timer if there's any.
    """
    if self.refresh_timer:
      timer = self.refresh_timer
      self.refresh_timer = None
      timer.cancel()

  def OnClearCommandWindow(self, event=None):
    """Clear the command window.

    Args:
      event: The triggering event.
    """
    self.cmd_output.Clear()

  def OnListDevices(self, event=None):
    """List devices asynchronously.

    Args:
      event: The triggering event.
    """
    if event is not None:
      event.Skip()

    self._CreateThread(self._ListDevices)

  def OnReboot(self, event):
    """Reboot ATFA device asynchronously.

    Args:
      event: The triggering event.
    """
    try:
      self.atft_manager.CheckDevice(self.atft_manager.GetATFADevice())
    except DeviceNotFoundException:
      self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return
    self._CreateThread(self._Reboot)

  def OnShutdown(self, event):
    """Shutdown ATFA device asynchronously.

    Args:
      event: The triggering event.
    """
    try:
      self.atft_manager.CheckDevice(self.atft_manager.GetATFADevice())
    except DeviceNotFoundException:
      self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return
    self._CreateThread(self._Shutdown)

  def OnEnterAutoProv(self):
    """Enter auto provisioning mode."""
    if self.auto_prov:
      return
    if (self.atft_manager.GetATFADevice() and
        self._GetCachedATFAKeysLeft() > 0 and
        (self.atft_manager.product_info or self.atft_manager.som_info)):
      # If product info file is chosen and atfa device is present and there are
      # keys left. Enter auto provisioning mode.
      self.auto_prov = True
      self.first_key_alert_shown = False
      self.second_key_alert_shown = False
      message = 'Automatic key provisioning start'
      self.PrintToCommandWindow(message)
      self.log.Info('Autoprov', message)

  def OnLeaveAutoProv(self):
    """Leave auto provisioning mode."""
    if not self.auto_prov:
      return
    self.auto_prov = False
    for device in self._GetTargetDevices():
      # Change all waiting devices' status to it's original state.
      if device.provision_status == ProvisionStatus.WAITING:
        self.atft_manager.CheckProvisionStatus(device)
    message = 'Automatic key provisioning end'
    self.PrintToCommandWindow(message)
    self.log.Info('Autoprov', message)

  def _OnToggleSupButton(self, event):
    """Show/Hide 'Enter Supervisor Mode' button.

    Args:
      event: The triggering event.
    """
    if self.button_supervisor_toggle.IsShown():
      self.button_supervisor_toggle.Show(False)
    else:
      self.button_supervisor_toggle.SetPosition((630,20))
      self.button_supervisor_toggle.Show(True)
      self.button_supervisor_toggle.Layout()
      self.button_supervisor_toggle.SetSize(250, 30)
      self.button_supervisor_toggle.Raise()

  def _OnToggleSupMode(self, event):
    """Enter/leave supervisor mode.

    Args:
      event: The triggering event.
    """
    if self.sup_mode:
     self.OnLeaveSupMode()
    else:
      self.OnEnterSupMode()
    self.button_supervisor_toggle.Show(False)
    self.main_box.Layout()
    self.panel.SetSizerAndFit(self.main_box)
    self.Layout()
    self.SetSize(self.GetWindowSize())
    self.SetFocus()

  def OnLeaveSupMode(self):
    """Leave supervisor mode"""
    message = 'Leave supervisor mode'
     # Clear all the selected target devices.
    for index in range(0, TARGET_DEV_SIZE):
      if self.target_dev_components[index].selected:
        self._DeviceSelectHandler(None, index)
    self.PrintToCommandWindow(message)
    self.log.Info('Supmode', message)
    self.sup_mode = False
    self.button_supervisor_toggle.SetLabel(
        self.atft_string.BUTTON_ENTER_SUP_MODE)
    self.main_box.Hide(self.cmd_output_wrap)
    self.SetMenuBar(None)
    self.OnEnterAutoProv()

  def OnEnterSupMode(self):
    """Enter supervisor mode, ask for credential."""
    self.password_dialog.CenterOnParent()
    if self.password_dialog.ShowModal() != wx.ID_OK:
      return
    password = self.password_dialog.GetValue()
    self.password_dialog.SetValue('')
    result = Atft.VerifyPassword(password, self.password_hash)
    password = None
    if result:
      message = 'Enter supervisor mode'
      self.PrintToCommandWindow(message)
      self.log.Info('Supmode', message)
      self.sup_mode = True
      self.button_supervisor_toggle.SetLabel(
          self.atft_string.BUTTON_LEAVE_SUP_MODE)
      self.SetMenuBar(self.menubar)
      self.cmd_output_wrap.Show()
      self.OnLeaveAutoProv()
    else:
      e = PasswordErrorException()
      # Log the wrong password event.
      self._HandleException('W', e)
      self._SendAlertEvent(self.atft_string.ALERT_WRONG_PASSWORD)

  def OnManualProvision(self, event):
    """Manual provision key asynchronously.

    Args:
      event: The triggering event.
    """
    selected_serials = self._GetSelectedSerials()
    if not selected_serials:
      self._SendAlertEvent(self.atft_string.ALERT_PROV_NO_SELECTED)
      return
    if not self.atft_manager.GetATFADevice():
      self._SendAlertEvent(self.atft_string.ALERT_PROV_NO_ATFA)
      return
    if self._GetCachedATFAKeysLeft() == 0:
      self._SendAlertEvent(self.atft_string.ALERT_PROV_NO_KEYS)
      return
    is_som_key = (self.atft_manager.som_info is not None)
    for serial in selected_serials:
      target_dev = self.atft_manager.GetTargetDevice(serial)
      if not target_dev:
        continue
      status = target_dev.provision_status
      if (self.test_mode):
        target_dev.provision_status = ProvisionStatus.WAITING
      elif (
          target_dev.provision_state.bootloader_locked and
          target_dev.provision_state.avb_perm_attr_set and
          target_dev.provision_state.avb_locked):
        if ((target_dev.provision_state.product_provisioned and not is_som_key)
            or
            (target_dev.provision_state.som_provisioned and is_som_key)):
          if not self._ShowWarning(
              self.atft_string.ALERT_REPROVISION(target_dev)):
            continue
        target_dev.provision_status = ProvisionStatus.WAITING
      else:
        self._SendAlertEvent(self.atft_string.ALERT_PROV_PROVED)
    self._CreateThread(self._ManualProvision, selected_serials, is_som_key)

  def OnCheckATFAStatus(self, event):
    """Check the attestation key status from ATFA device asynchronously.

    Args:
      event: The triggering event.
    """
    self._CreateThread(self._ShowATFAStatus)

  def OnFuseVbootKey(self, event):
    """Fuse the vboot key to the target device asynchronously.

    Args:
      event: The triggering event.
    """
    selected_serials = self._GetSelectedSerials()
    if not selected_serials:
      self._SendAlertEvent(self.atft_string.ALERT_FUSE_NO_SELECTED)
      return
    if not self.atft_manager.product_info and not self.atft_manager.som_info:
      self._SendAlertEvent(self.atft_string.ALERT_FUSE_NO_PRODUCT)
      return

    self._CreateThread(self._FuseVbootKey, selected_serials)

  def OnFusePermAttr(self, event):
    """Fuse the permanent attributes to the target device asynchronously.

    Args:
      event: The triggering event.
    """
    selected_serials = self._GetSelectedSerials()
    if not selected_serials:
      self._SendAlertEvent(self.atft_string.ALERT_FUSE_PERM_NO_SELECTED)
      return
    if not self.atft_manager.product_info:
      self._SendAlertEvent(self.atft_string.ALERT_FUSE_PERM_NO_PRODUCT)
      return

    self._CreateThread(self._FusePermAttr, selected_serials)

  def OnLockAvb(self, event):
    """Lock the AVB asynchronously.

    Args:
      event: The triggering event
    """
    selected_serials = self._GetSelectedSerials()
    if not selected_serials:
      self._SendAlertEvent(self.atft_string.ALERT_LOCKAVB_NO_SELECTED)
      return

    self._CreateThread(self._LockAvb, selected_serials)

  def OnQuit(self, event):
    """Quit the application.

    Args:
      event: The triggering event.
    """
    self.Close()

  def ToggleStatusBar(self, event):
    """Toggle the status bar.

    Args:
      event: The triggering event.
    """
    if self.menu_show_status_bar.IsChecked():
      self.statusbar.Show()
    else:
      self.statusbar.Hide()
    self.SetSize(self.GetWindowSize())

  class SelectFileArg(object):
    """The argument structure for SelectFileHandler.

    Attributes:
      message: The message for the select file window.
      wildcard: The wildcard to filter the files to be selected.
      callback: The callback to be called once the file is selected with
        argument pathname of the selected file.
    """

    def __init__(self, message, wildcard, callback):
      self.message = message
      self.wildcard = wildcard
      self.callback = callback

  class SaveFileArg(object):
    """The argument structure for SaveFileHandler.

    Attributes:
      message: The message for the select file window.
      filename: The filename of the file to be saved to.
      callback: The callback to be called once the file is selected with
        argument pathname of the selected file.
    """
    def __init__(self, message, filename, callback):
      self.message = message
      self.filename = filename
      self.callback = callback

  def ChooseProduct(self, event):
    """Ask user to choose the product attributes file.

    Args:
      event: The triggering event.
    """
    message = self.atft_string.DIALOG_CHOOSE_PRODUCT_ATTRIBUTE_FILE
    wildcard = self.product_attribute_file_extension
    callback = self.ProcessAttributesFile
    data = self.SelectFileArg(message, wildcard, callback)
    event = Event(self.select_file_event, value=data)
    wx.QueueEvent(self, event)

  def ChangeSettings(self, event):
    self.app_settings_dialog.CenterOnParent()
    self.app_settings_dialog.ShowModal()

  def ProcessAttributesFile(self, pathname):
    """Process the selected attributes file.

    Args:
      pathname: The path for the attributes file to parse.
    """
    try:
      with open(pathname, 'r') as attribute_file:
        content = attribute_file.read()
        self.atft_manager.ProcessAttributesFile(content)
        if self.start_screen_shown:
          self.HideStartScreen()
        name = ''
        if self.atft_manager.product_info:
          # product mode
          self.product_name_title.SetLabel(self.atft_string.TITLE_PRODUCT_NAME)
          name = self.atft_manager.product_info.product_name
        elif self.atft_manager.som_info:
          # som mode
          self.product_name_title.SetLabel(self.atft_string.TITLE_SOM_NAME)
          name = self.atft_manager.som_info.som_name

        # Update the name display
        self.product_name_display.SetLabel(name)
        self.product_name_title.Refresh()
        self.product_name_display.Refresh()
        self.product_name_sizer.Layout()
        self.main_box.Layout()
        # User choose a new product, reset how many keys left.
        if (self.atft_manager.GetATFADevice() and (
              self.atft_manager.product_info or self.atft_manager.som_info)):
          self.audit.ResetKeysLeft()
          self._UpdateKeysLeftInATFA()

        # If user change from one mode to another mode, change the default
        # provision steps.
        if (self.provision_steps == self.DEFAULT_PROVISION_STEPS_SOM and
            self.atft_manager.product_info):
          self.provision_steps = self.DEFAULT_PROVISION_STEPS_PRODUCT
        elif (self.provision_steps == self.DEFAULT_PROVISION_STEPS_PRODUCT and
              self.atft_manager.som_info):
          self.provision_steps = self.DEFAULT_PROVISION_STEPS_SOM
        self._CheckProvisionSteps()
    except IOError:
      self._SendAlertEvent(
          self.atft_string.ALERT_CANNOT_OPEN_FILE + pathname.encode('utf-8'))
    except ProductAttributesFileFormatError as e:
      self._SendAlertEvent(self.atft_string.ALERT_PRODUCT_FILE_FORMAT_WRONG)
      self._HandleException('W', e)

  def OnChangeKeyThreshold(self, event):
    """Change the threshold for low number of key warning.

    Args:
      event: The button click event.
    """
    self.change_threshold_dialog.ShowModal()
    # Update the configuration
    first_warning = self.change_threshold_dialog.GetFirstWarning()
    second_warning = self.change_threshold_dialog.GetSecondWarning()
    if first_warning:
      self.configs['DEFAULT_KEY_THRESHOLD_1'] = str(first_warning)
    elif 'DEFAULT_KEY_THRESHOLD_1' in self.configs:
      del self.configs['DEFAULT_KEY_THRESHOLD_1']
    if second_warning:
      self.configs['DEFAULT_KEY_THRESHOLD_2'] = str(second_warning)
    elif 'DEFAULT_KEY_THRESHOLD_2' in self.configs:
      del self.configs['DEFAULT_KEY_THRESHOLD_2']

  def OnGetRegFile(self, event):
    """Download the registration file from the atfa device.

    Args:
      event: The triggering event.
    """
    message = self.atft_string.DIALOG_SELECT_DIRECTORY
    try:
      filename = self.atft_manager.GetATFASerial() + '.reg'
    except DeviceNotFoundException as e:
      self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return
    except FastbootFailure as e:
      self._HandleException('E', e)
      return
    callback = self._GetRegFile
    data = self.SaveFileArg(message, filename, callback)
    event = Event(self.save_file_event, value=data)
    wx.QueueEvent(self, event)

  def OnGetAuditFile(self, event):
    """Download the audit file from the atfa device.

    Args:
      event: The triggering event.
    """
    message = self.atft_string.DIALOG_SELECT_DIRECTORY
    try:
      serial = self.atft_manager.GetATFASerial()
    except DeviceNotFoundException as e:
      self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return
    except FastbootFailure as e:
      self._HandleException('E', e)
      return
    filename = AtftAudit.GetAuditFileName(serial)
    callback = self._GetAuditFile
    data = self.SaveFileArg(message, filename, callback)
    event = Event(self.save_file_event, value=data)
    wx.QueueEvent(self, event)

  def OnStoreKey(self, event):
    """Upload the key bundle file to ATFA device and process it.

    Give user a prompt to choose a keybundle file then upload that file
    to the ATFA device and process it.

    Args:
      event: The button click event.
    """
    try:
      self.atft_manager.CheckDevice(self.atft_manager.GetATFADevice())
    except DeviceNotFoundException:
      self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return

    message = self.atft_string.DIALOG_CHOOSE_KEY_FILE
    wildcard = self.key_file_extension
    callback = self._ProcessKeyCallback
    data = self.SelectFileArg(message, wildcard, callback)
    event = Event(self.select_file_event, value=data)
    wx.QueueEvent(self, event)

  def OnUpdateAtfa(self, event):
    """Store the update file to the ATFA device and process it.

    Give user a prompt to choose an update patch file and then upload that
    file to the ATFA device and process it.

    Args:
      event: The button click event.
    """
    try:
      self.atft_manager.CheckDevice(self.atft_manager.GetATFADevice())
    except DeviceNotFoundException:
      self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return

    message = self.atft_string.DIALOG_CHOOSE_UPDATE_FILE
    wildcard = self.update_file_extension
    callback = self._UpdateATFACallback
    data = self.SelectFileArg(message, wildcard, callback)
    event = Event(self.select_file_event, value=data)
    wx.QueueEvent(self, event)

  def OnPurgeKey(self, event):
    """Purge the keybundle for the product in the ATFA device.

    Args:
      event: The button click event.
    """
    try:
      self.atft_manager.CheckDevice(self.atft_manager.GetATFADevice())
    except DeviceNotFoundException:
      self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return
    if self._ShowWarning(self.atft_string.ALERT_CONFIRM_PURGE_KEY):
      self._CreateThread(self._PurgeKey)

  def ShowAlert(self, msg):
    """Show an alert box at the center of the parent window.

    Args:
      msg: The message to be shown in the alert box.
    """
    self.alert_dialog.CenterOnParent()
    self.alert_dialog.SetMessage(msg)
    self.alert_dialog.ShowModal()

  def OnClose(self, event):
    """This is the place for close callback, need to do cleanups.

    Args:
      event: The triggering event.
    """
    self._StoreConfigToFile()
    # Stop the refresh timer on close.
    self.StopRefresh()
    # Stop automatic processing keys.
    self.key_handler.StopProcessKey()
    self.Destroy()

  def _is_provision_steps_finished(self, provision_state):
    """Check if the target device has successfully finished provision steps.

    Args:
      target: The target device.
    Returns:
      success if the target device has already gone through the provision steps
      successfully.
    """
    final_state = copy.deepcopy(provision_state)
    for operation in self.provision_steps:
      if operation == 'FuseVbootKey':
        final_state.bootloader_locked = True
        continue
      elif operation == 'FusePermAttr':
        final_state.avb_perm_attr_set = True
        continue
      elif operation == 'LockAvb':
        final_state.avb_locked = True
        continue
      elif operation == 'UnlockAvb':
        final_state.avb_locked = False
        continue
      elif operation == 'ProvisionProduct':
        final_state.product_provisioned = True
        continue
      elif operation == 'ProvisionSom':
        final_state.som_provisioned = True
    return (provision_state == final_state);

  def _HandleAutoProv(self):
    """Do the state transition for devices if in auto provisioning mode.

    """
    # All idle devices -> waiting.
    for target_dev in self._GetTargetDevices():
      if (target_dev.serial_number not in self.auto_dev_serials and
          not self._is_provision_steps_finished(target_dev.provision_state) and
          not ProvisionStatus.isFailed(target_dev.provision_status)
          ):
        self.auto_dev_serials.append(target_dev.serial_number)
        target_dev.provision_status = ProvisionStatus.WAITING
        self._CreateThread(self._HandleStateTransition, target_dev)


  def _HandleKeysLeft(self):
    """Display how many keys left in the ATFA device.
    """
    text = self.atft_string.TITLE_KEYS_LEFT
    color = COLOR_BLACK

    try:
      if (not self.atft_manager.GetATFADevice() or (
          not self.atft_manager.product_info and
          not self.atft_manager.som_info)):
        raise DeviceNotFoundException
      keys_left = self._GetCachedATFAKeysLeft()
      if not keys_left and keys_left != 0:
        # If keys_left is not set, try to set it and pull the audit.
        self.audit.ResetKeysLeft()
        self._UpdateKeysLeftInATFA()
        keys_left = self._GetCachedATFAKeysLeft()
      text = self.atft_string.TITLE_KEYS_LEFT + str(keys_left)
      if not keys_left or keys_left < 0:
        raise NoKeysException

      first_warning = self.change_threshold_dialog.GetFirstWarning()
      second_warning = self.change_threshold_dialog.GetSecondWarning()
      if first_warning and keys_left < first_warning:
        color = COLOR_YELLOW
      if second_warning and keys_left < second_warning:
        color = COLOR_RED
      self._SetStatusTextColor(text, color)
    except (DeviceNotFoundException, NoKeysException):
      self._SetStatusTextColor(text, color)

  def _SetStatusTextColor(self, text, color):
    """Set the background color and the text for the status bar.

    Args:
      text: The text to be displayed on the status bar.
      color: The background color.
    """
    if self.statusbar.GetBackgroundColour() != color:
      self.statusbar.SetBackgroundColour(color)
      self.statusbar.Refresh()
    if self.statusbar.GetStatusText().encode('utf-8') != text:
      self.status_text.SetLabel(text)
      self.statusbar.Refresh()

  def _ShowWarning(self, text):
    """Show a warning to the user.

    Args:
      text: The content of the warning.
    Returns:
      True if the user clicks yes, otherwise, False.
    """
    warning_dialog = wx.MessageDialog(
        self,
        text,
        self.atft_string.DIALOG_WARNING_TITLE,
        style=wx.YES_NO | wx.ICON_EXCLAMATION)
    if warning_dialog.ShowModal() == wx.ID_YES:
      return True
    return False

  def _CopyList(self, old_list):
    """Copy a device list.

    Args:
      old_list: The original list
    Returns:
      The duplicate with all the public member copied.
    """
    copy_list = []
    for dev in old_list:
      copy_list.append(dev.Copy())
    return copy_list

  def _HandleException(self, level, e, operation=None, targets=None):
    """Handle the exception.

    Fires a exception event which would be handled in main thread. The exception
    would be shown in the command window. This function also wraps the
    associated operation and device object.

    Args:
      level: The log level for the exception.
      e: The original exception.
      operation: The operation associated with this exception.
      targets: The list of DeviceInfo object associated with this exception.
    """
    atft_exception = AtftException(e, operation, targets)
    wx.QueueEvent(self,
                  Event(
                      self.exception_event,
                      wx.ID_ANY,
                      value=str(atft_exception)))
    self._LogException(level, atft_exception)

  def _LogException(self, level, atft_exception):
    """Log the exceptions.

    Args:
      level: The log level for this exception. 'E': error or 'W': warning.
      atft_exception: The exception to be logged.
    """
    if level == 'E':
      self.log.Error('OpException', str(atft_exception))
    elif level == 'W':
      self.log.Warning('OpException', str(atft_exception))

  def _CreateBindEvents(self):
    """Create customized events and bind them to the event handlers.
    """

    # Event for refreshing device list.
    self.refresh_event = wx.NewEventType()
    self.refresh_event_bind = wx.PyEventBinder(self.refresh_event)

    # Event for device listed.
    self.dev_listed_event = wx.NewEventType()
    self.dev_listed_event_bind = wx.PyEventBinder(self.dev_listed_event)
    # Event when general exception happens.
    self.exception_event = wx.NewEventType()
    self.exception_event_bind = wx.PyEventBinder(self.exception_event)
    # Event for alert box.
    self.alert_event = wx.NewEventType()
    self.alert_event_bind = wx.PyEventBinder(self.alert_event)
    # Event for general message to be printed in command window.
    self.print_event = wx.NewEventType()
    self.print_event_bind = wx.PyEventBinder(self.print_event)
    # Event for low key alert.
    self.low_key_alert_event = wx.NewEventType()
    self.low_key_alert_event_bind = wx.PyEventBinder(self.low_key_alert_event)
    # Event for select a file.
    self.select_file_event = wx.NewEventType()
    self.select_file_event_bind = wx.PyEventBinder(self.select_file_event)
    # Event for save a file.
    self.save_file_event = wx.NewEventType()
    self.save_file_event_bind = wx.PyEventBinder(self.save_file_event)
    # Event for update the mapping status for mapping USB location
    self.update_mapping_status_event = wx.NewEventType()
    self.update_mapping_status_bind = wx.PyEventBinder(
        self.update_mapping_status_event)

    self.map_usb_success_event = wx.NewEventType()
    self.map_usb_success_bind = wx.PyEventBinder(self.map_usb_success_event)

    self.Bind(self.refresh_event_bind, self.OnListDevices)
    self.Bind(self.dev_listed_event_bind, self._DeviceListedEventHandler)
    self.Bind(self.exception_event_bind, self._PrintEventHandler)
    self.Bind(self.alert_event_bind, self._AlertEventHandler)
    self.Bind(self.print_event_bind, self._PrintEventHandler)
    self.Bind(self.low_key_alert_event_bind, self._LowKeyAlertEventHandler)
    self.Bind(self.select_file_event_bind, self._SelectFileEventHandler)
    self.Bind(self.save_file_event_bind, self._SaveFileEventHandler)
    self.Bind(self.update_mapping_status_bind, self._UpdateMappingStatusHandler)

    i = 0
    for dev_component in self.target_dev_components:
      Atft._BindEventRecursive(
          wx.EVT_LEFT_DOWN, dev_component.panel,
          lambda event, index=i : self._DeviceSelectHandler(event, index))
      dev_component.panel.Bind(
          wx.EVT_SET_FOCUS,
          lambda event, index=i : self._DeviceFocusHandler(event, index))
      dev_component.panel.Bind(
          wx.EVT_KILL_FOCUS,
          lambda event, index=i : self._DeviceLostFocusHandler(event, index))
      i += 1

    # Bind the close event
    self.Bind(wx.EVT_CLOSE, self.OnClose)

  def _DeviceSelectHandler(self, event, index):
    """The handler to handle user selecting a target device.
    Args:
      event: The triggering event.
      index: The index for the target device.
    """
    if not self.sup_mode:
      return
    dev_component = self.target_dev_components[index]
    if not dev_component.active or not dev_component.serial_number:
      return
    title_background = dev_component.title_background
    if not dev_component.selected:
      title_background.SetBackgroundColour(COLOR_PICK_BLUE)
    else:
      title_background.SetBackgroundColour(COLOR_WHITE)
    title_background.Refresh()
    dev_component.selected = not dev_component.selected
    dev_component.panel.SetFocus()
    if event:
      event.Skip()

  def _DeviceFocusHandler(self, event, index):
    """The handler when a target device slot is focused.

    Args:
      event: The triggering event.
      index: The index for the target device.
    """
    dev_component = self.target_dev_components[index]
    dev_component.panel.SetWindowStyleFlag(wx.BORDER_SUNKEN)
    dev_component.panel.GetParent().Refresh()

  def _DeviceLostFocusHandler(self, event, index):
    """The handler when a target device slot loses focus.

    Args:
      event: The triggering event.
      index: The index for the target device.
    """
    dev_component = self.target_dev_components[index]
    dev_component.panel.SetWindowStyleFlag(wx.BORDER_RAISED)
    dev_component.panel.GetParent().Refresh()

  def MapUSBToSlotHandler(self, event, index):
    """The handler to map a target device's USB location to a UI slot.

    This should be a single select since user can only select one device
    location to be mapped.

    Args:
      event: The triggering event.
      index: The index for the target device.
    """
    i = 0
    for dev_component in self.app_settings_dialog.dev_mapping_components:
      title_background = dev_component.title_background
      if i == index:
        title_background.SetBackgroundColour(COLOR_PICK_BLUE)
        if self.device_usb_locations[i]:
          # If already selected, change the button to 'remap'
          self.app_settings_dialog.button_map.SetLabel(
              self.atft_string.BUTTON_REMAP)
        else:
          self.app_settings_dialog.button_map.SetLabel(
              self.atft_string.BUTTON_MAP)
        self.app_settings_dialog.button_map.GetParent().Layout()
        dev_component.selected = True
      else:
        title_background.SetBackgroundColour(COLOR_WHITE)
        dev_component.selected = False
      title_background.Refresh()
      i += 1

    event.Skip()

  def _SendAlertEvent(self, msg):
    """Send an event to generate an alert box.

    Args:
      msg: The message to be displayed in the alert box.
    """
    evt = Event(self.alert_event, wx.ID_ANY, msg)
    wx.QueueEvent(self, evt)

  def _PrintEventHandler(self, event):
    """The handler to handle the event to display a message in the cmd output.

    Args:
      event: The message to be displayed.
    """
    msg = str(event.GetValue())
    self.PrintToCommandWindow(msg)

  def _SendPrintEvent(self, msg):
    """Send an event to print a message to the cmd output.

    Args:
      msg: The message to be displayed.
    """
    evt = Event(self.print_event, wx.ID_ANY, msg)
    wx.QueueEvent(self, evt)

  def _StartOperation(self, operation, target, show_alert=True, blocking=False):
    """Set the target to operating status, print out the start message.

    This methods prevent two operations on the same device interleaving with
    each other. If blocking is False, then this function would return False
    if there is another interleaving operation running. Otherwise, this call
    would block until the other operation finishes. This function would then
    obtain the operation lock the target device. This function would also
    pause the 'fastboot devices' refresh because that would interfere with any
    other operations.

    Args:
      operation: The operation to start.
      target: The target device.
      show_alert: Whether to print alert message if another operation is
        ongoing.
      blocking: Whether to wait for the other operation.
    Returns:
      False if blocking is set to False and another operation is ongoing,
      otherwise return True.
    """
    if not target:
      self.PauseRefresh()
      return True
    if target.operation_lock.acquire(blocking):
      target.operation = operation
      self._SendOperationStartEvent(operation, target)
      self.PauseRefresh()
      return True

    if show_alert:
      self._SendAlertEvent(
          'Unable to start operation: ' + operation + ', ' +
          'Target: ' + str(target) + ' is currently in another operation: '  +
          target.operation + '. Please try again later')
    return False

  def _EndOperation(self, target):
    """Clear the operation status and release the operation lock.

    Args:
      target: The target device.
    """
    self.ResumeRefresh()
    if not target:
      return
    target.operation = None
    target.operation_lock.release()

  def _SendOperationStartEvent(self, operation, target):
    """Send an event to print an operation start message.

    Args:
      operation: The operation name.
      target: The target of the operation.
    """
    msg = ''
    if target:
      msg += '{' + str(target) + '} '
    msg += operation + ' Start'
    self._SendPrintEvent(msg)
    self.log.Info('OpStart', msg)

  def _SendOperationSucceedEvent(self, operation, target=None):
    """Send an event to print an operation succeed message.

    Args:
      operation: The operation name.
      target: The target of the operation.
    """
    msg = ''
    if target:
      msg += '{' + str(target) + '} '
    msg += operation + ' Succeed'
    self._SendPrintEvent(msg)
    self.log.Info('OpSucceed', msg)

  def _SendDeviceListedEvent(self):
    """Send an event to indicate device list is refreshed, need to refresh UI.
    """
    wx.QueueEvent(self, Event(self.dev_listed_event))

  def _SendLowKeyAlertEvent(self, keys_left):
    """Send low key alert event.

    Send an event to indicate the keys left in the ATFA device is lower than
    threshold.

    Args:
      keys_left: The number of keys left.
    """
    wx.QueueEvent(self, Event(self.low_key_alert_event, value=keys_left))

  def SendUpdateMappingEvent(self):
    """Send an event to indicate the mapping status need to be updated.
    """
    wx.QueueEvent(self, Event(self.update_mapping_status_event))

  def _AlertEventHandler(self, event):
    """The handler to handle the event to display an alert box.

    Args:
      event: The alert event containing the message to be displayed.
    """
    msg = event.GetValue()
    # Need to check if any other handler is using the alert box.
    # All the handler is in the main thread
    # So we cannot block to acquire this lock
    # The main reason of the async is the showModal is async
    # However, we cannot make sure SetMsg and ShowModel is atomic
    # So we can only ignore the overlapping request.
    if self.alert_lock.acquire(False):
      self.ShowAlert(msg)
      self.alert_lock.release()

  def _DeviceListedEventHandler(self, event):
    """Handles the device listed event and list the devices.

    Args:
      event: The event object.
    """
    self._HandleKeysLeft()

    if not self.sup_mode:
      # If in normal mode
      if self.auto_prov and not self.atft_manager.GetATFADevice():
        # If ATFA unplugged during normal mode,
        # exit the mode with an alert.
        self.OnLeaveAutoProv()
        # Add log here.
        self._SendAlertEvent('ATFA device unplugged, exit auto mode!')
      if not self.auto_prov:
        # If not already in auto provisioning mode, try enable it.
        self.OnEnterAutoProv()

    # If in auto provisioning mode, handle the newly added devices.
    if self.auto_prov:
      self._HandleAutoProv()

    self._PrintAtfaDevice()

    if self.last_target_list == self.atft_manager.target_devs:
      # Nothing changes, no need to refresh
      return

    # Update the stored target list. Need to make a deep copy instead of copying
    # the reference.
    self.last_target_list = self._CopyList(self.atft_manager.target_devs)
    self._PrintTargetDevices()

  def _PrintAtfaDevice(self):
    """Print atfa device to atfa device output area.
    """
    if self.atft_manager.GetATFADevice():
      atfa_message = str(self.atft_manager.GetATFADevice())
    else:
      atfa_message = self.atft_string.ALERT_NO_DEVICE
    self.atfa_dev_output.SetLabel(atfa_message)

  def _PrintTargetDevices(self):
    """Print target devices to target device output area.
    """
    target_devs = self.atft_manager.target_devs
    for i in range(TARGET_DEV_SIZE):
      serial_text = ''
      status = None
      state = None
      serial_number = None
      if self.device_usb_locations[i]:
        self.target_dev_components[i].active = True
        for target_dev in self.atft_manager.target_devs:
          if target_dev.location == self.device_usb_locations[i]:
            serial_number = target_dev.serial_number
            serial_text = (
                self.atft_string.FIELD_SERIAL_NUMBER +
                ': ' + str(serial_number))
            status = target_dev.provision_status
            state = target_dev.provision_state
      else:
        self.target_dev_components[i].active = False
      self._ShowTargetDevice(i, serial_number, serial_text, status, state)

  def _GetTargetDevices(self):
    target_devs = []
    for target_dev in self.atft_manager.target_devs:
      for i in range(TARGET_DEV_SIZE):
        if (self.device_usb_locations[i] and
            target_dev.location == self.device_usb_locations[i]):
          target_devs.append(target_dev)
          break
    return target_devs

  def _ShowTargetDevice(self, i, serial_number, serial_text, status, state):
    """Display information about one target device.

    Args:
      i: The slot index of the device to be displayed.
      serial_nubmer: The serial number of the device.
      serial_text: The serial number text to be displayed.
      status: The provision status.
      state: The provision state.
    """
    dev_component = self.target_dev_components[i]
    if not dev_component.active:
      serial_text = self.atft_string.SERIAL_NOT_MAPPED
      dev_component.serial_text.SetForegroundColour(COLOR_LIGHT_GREY_TEXT)
      dev_component.index_text.SetForegroundColour(COLOR_LIGHT_GREY_TEXT)
    else:
      dev_component.serial_text.SetForegroundColour(COLOR_BLACK)
      dev_component.index_text.SetForegroundColour(COLOR_DARK_GREY)
    dev_component.serial_text.SetLabel(serial_text)
    dev_component.serial_text.Refresh()
    dev_component.index_text.Refresh()
    dev_component.serial_number = serial_number
    color = self._GetStatusColor(status, state)
    if status != None:
      dev_component.status.SetLabel(
          ProvisionStatus.ToString(status, self.GetLanguageIndex()))
    else:
      # This slot currently has no device
      dev_component.status.SetLabel('')
      # If the device is selected, unselect it.
      if dev_component.selected:
        dev_component.title_background.SetBackgroundColour(COLOR_WHITE)
        dev_component.title_background.Refresh()
        dev_component.selected = False
    if status == ProvisionStatus.IDLE:
      dev_component.status.SetForegroundColour(COLOR_DARK_GREY)
    else:
      dev_component.status.SetForegroundColour(COLOR_WHITE)
    dev_component.status_wrapper.Layout()
    dev_component.status_background.SetBackgroundColour(color)
    dev_component.status_background.Refresh()

  def _GetStatusColor(self, status, state):
    """Get the color according to the status.

    Args:
      status: The target device status.
      state: The target device provision state.
    Returns:
      The color to be shown for the status.
    """
    if status == None:
      return COLOR_LIGHT_GREY
    if status == ProvisionStatus.IDLE:
      return COLOR_GREY
    if self._is_provision_steps_finished(state):
      return COLOR_GREEN
    if ProvisionStatus.isFailed(status):
      return COLOR_RED
    return COLOR_BLUE

  def _SelectFileEventHandler(self, event):
    """Show the select file window.

    Args:
      event: containing data of SelectFileArg type.
    """
    data = event.GetValue()
    message = data.message
    wildcard = data.wildcard
    callback = data.callback
    with wx.FileDialog(
        self,
        message,
        wildcard=wildcard,
        style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
      ) as file_dialog:
      if file_dialog.ShowModal() == wx.ID_CANCEL:
        return  # the user changed their mind
      pathname = file_dialog.GetPath()
    callback(pathname)

  def _SaveFileEventHandler(self, event):
    """Show the save file window and save the file to selected folder.

    This function would give user a directory selection dialog, and download
    the files from the atfa device to a file named event.filename under the
    selected folder.

    Args:
      event: containing data of SaveFileArg type.
    """
    data = event.GetValue()
    message = data.message
    filename = data.filename
    callback = data.callback
    with wx.DirDialog(
        self, message, '', wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST
      ) as file_dialog:
      if file_dialog.ShowModal() == wx.ID_CANCEL:
        return  # the user changed their mind
      pathname = file_dialog.GetPath()
      filepath = os.path.join(pathname, filename)
      if os.path.isdir(filepath):
        self._SendAlertEvent(
            self.atft_string.ALERT_CANNOT_SAVE_FILE + filepath.encode('utf-8'))
      warning_text = (
          filepath.encode('utf-8') +
          self.atft_string.ALERT_FILE_EXISTS)
      if os.path.isfile(filepath) and not self._ShowWarning(warning_text):
        return
    callback(filepath)

  def _LowKeyAlertEventHandler(self, event):
    """Show the alert box to alert user that the key in ATFA device is low.

    Args:
      event: The triggering event.
    """
    keys_left = event.GetValue()
    self.low_key_dialog.SetMessage(
        self.atft_string.ALERT_ADD_MORE_KEY(keys_left))
    self.low_key_dialog.CenterOnParent()
    self.low_key_dialog.ShowModal()

  def _UpdateMappingStatusHandler(self, event):
    """Update the device mapping status in the Mapping USB Location page.

    Args:
      event: The triggering event.
    """
    if self.app_settings_dialog:
      self.app_settings_dialog.UpdateMappingStatus()

    # Update the UI on the target devices (grey out unmapped devices).
    self._PrintTargetDevices()

  def _CreateThread(self, target, *args):
    """Create and start a thread.

    Args:
      target: The function that the thread should run.
      *args: The arguments for the function
    Returns:
      The thread object
    """
    t = threading.Thread(target=target, args=args)
    t.setDaemon(True)
    t.start()
    return t

  def _ListDevices(self):
    """List fastboot devices.
    """

    # We need to check the lock to prevent two _ListDevices running at the same
    # time.
    if self.listing_device_lock.acquire(False):
      operation = 'List Devices'
      try:
        self.atft_manager.ListDevices(self.sort_by)
      except DeviceCreationException as e:
        self._HandleException('W', e, operation, e.devices)
      except OsVersionNotAvailableException as e:
        e.msg = 'Failed to get ATFA version'
        self._HandleException('W', e, operation, e.devices)
        self._SendAlertEvent(self.atft_string.ALERT_INCOMPATIBLE_ATFA)
      except OsVersionNotCompatibleException as e:
        e.msg = 'Incompatible ATFA version, version is ' + str(e.version)
        self._HandleException('W', e, operation, e.devices)
        self._SendAlertEvent(self.atft_string.ALERT_INCOMPATIBLE_ATFA)
      except FastbootFailure as e:
        self._HandleException('W', e, operation)
      finally:
        # 'Release the lock'.
        self.listing_device_lock.release()
      wx.QueueEvent(self, Event(self.dev_listed_event, wx.ID_ANY))

  def _UpdateKeysLeftInATFA(self):
    """Update the number of keys left in ATFA.

    Update the number of keys left for the selected product in the ATFA device.

    Returns:
      Whether the check succeed or not.
    """
    operation = 'Check ATFA status'
    self._SendOperationStartEvent(operation, self.atft_manager.GetATFADevice())
    self.PauseRefresh()

    try:
      if self.atft_manager.product_info:
        self.atft_manager.UpdateATFAKeysLeft(False)
      elif self.atft_manager.som_info:
        self.atft_manager.UpdateATFAKeysLeft(True)
    except DeviceNotFoundException as e:
      e.SetMsg('No Available ATFA!')
      self._HandleException('W', e, operation)
      return False
    except ProductNotSpecifiedException as e:
      self._HandleException('W', e, operation)
      return False
    except FastbootFailure as e:
      self._HandleException('E', e, operation)
      return False
    finally:
      self.ResumeRefresh()

    self._SendOperationSucceedEvent(operation)
    # Try to pull audit from ATFA if keys_left changes.
    self.audit.PullAudit(self._GetCachedATFAKeysLeft())
    return True

  def _GetCachedATFAKeysLeft(self):
    """Get the cached number of keys left in the ATFA device.

    Returns:
      The cached number of keys left in the ATFA.
    """
    return self.atft_manager.GetCachedATFAKeysLeft()

  def _ShowATFAStatus(self):
    """Show the attestation key status of the ATFA device.
    """
    try:
      self.atft_manager.CheckDevice(self.atft_manager.GetATFADevice())
    except DeviceNotFoundException:
      self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return
    if self._UpdateKeysLeftInATFA():
      self._SendAlertEvent(
          self.atft_string.ALERT_KEYS_LEFT(self._GetCachedATFAKeysLeft()))

  def _FuseVbootKey(self, selected_serials):
    """Fuse the verified boot key to the devices.

    Args:
      selected_serials: The list of serial numbers for the selected devices.
    """
    pending_targets = []
    for serial in selected_serials:
      target = self.atft_manager.GetTargetDevice(serial)
      if not target:
        continue
      # Start state could be IDLE or FUSEVBOOT_FAILED
      if (self.test_mode or not target.provision_state.bootloader_locked):
        target.provision_status = ProvisionStatus.WAITING
        pending_targets.append(target)
      else:
        self._SendAlertEvent(self.atft_string.ALERT_FUSE_VBOOT_FUSED)

    for target in pending_targets:
      self._FuseVbootKeyTarget(target)

  def _FuseVbootKeyTarget(self, target, auto_prov=False):
    """Fuse the verified boot key to a specific device.

    We would first fuse the bootloader vboot key
    and then reboot the device to check whether the bootloader is locked.
    This function would block until the reboot succeed or timeout.

    Args:
      target: The target device DeviceInfo object.
      auto_prov: Whether this operation is done in automatic mode.
    """
    operation = 'Fuse bootloader verified boot key'
    serial = target.serial_number
    if not self._StartOperation(operation, target, True, auto_prov):
      return

    try:
      self.atft_manager.FuseVbootKey(target)
      self._SendOperationSucceedEvent(operation, target)

      operation = 'Verify bootloader locked, rebooting'
      self._SendOperationStartEvent(operation, target)

      if auto_prov:
        # Allow other devices to continue state transition.
        self.auto_prov_lock.release()

      # If the device would reboot after fusing vboot key, need to wait for
      # device to disappear, then the reboot command would hold until the
      # device is back online.
      time.sleep(1)

      success_msg = '{' + str(target) + '} ' + 'Reboot Succeed'
      timeout_msg = '{' + str(target) + '} ' + 'Reboot Failed! Timeout!'
      reboot_lock = threading.Lock()
      reboot_lock.acquire()

      def LambdaSuccessCallback(msg=success_msg, lock=reboot_lock):
        self._RebootSuccessCallback(msg, lock)

      def LambdaTimeoutCallback(msg=timeout_msg, lock=reboot_lock):
        self._RebootTimeoutCallback(msg, lock)

      # Reboot the device to verify the bootloader is locked.
      target.provision_status = ProvisionStatus.REBOOT_ING
      wx.QueueEvent(self, Event(self.dev_listed_event, wx.ID_ANY))

      # Reboot would change device status, so we disable reading device status
      # during reboot.
      try:
        self.listing_device_lock.acquire()
        self.atft_manager.Reboot(
            target, self.reboot_timeout, LambdaSuccessCallback,
            LambdaTimeoutCallback)
      finally:
        self.listing_device_lock.release()
    except ProductNotSpecifiedException as e:
      self._HandleException('W', e, operation, [target])
      return
    except FastbootFailure as e:
      self._HandleException('E', e, operation, [target])
      return
    finally:
      self._EndOperation(target)

    # Wait until callback finishes. After the callback, reboot_lock would be
    # released.
    reboot_lock.acquire()
    if auto_prov:
      # Try to get our turn again.
      self.auto_prov_lock.acquire()

    target = self.atft_manager.GetTargetDevice(serial)
    if target and not target.provision_state.bootloader_locked:
      target.provision_status = ProvisionStatus.FUSEVBOOT_FAILED
      e = FastbootFailure('Status not updated.')
      self._HandleException('E', e, operation, [target])
      return

  def _RebootSuccessCallback(self, msg, lock):
    """The callback if reboot succeed.

    Args:
      msg: The message to be shown
      lock: The lock to indicate the callback is called.
    """
    self._SendPrintEvent(msg)
    self.log.Info('OpSucceed', msg)
    lock.release()

  def _RebootTimeoutCallback(self, msg, lock):
    """The callback if reboot timeout.

    Args:
      msg: The message to be shown
      lock: The lock to indicate the callback is called.
    """
    self._SendPrintEvent(msg)
    self.log.Error('OpException', msg)
    lock.release()

  def _FusePermAttr(self, selected_serials):
    """Fuse the permanent attributes to the target devices.

    Args:
      selected_serials: The list of serial numbers for the selected devices.
    """
    pending_targets = []
    for serial in selected_serials:
      target = self.atft_manager.GetTargetDevice(serial)
      if not target:
        return
      # Start state could be FUSEVBOOT_SUCCESS or REBOOT_SUCCESS
      # or FUSEATTR_FAILED
      # Note: Reboot to check vboot is optional, user can skip that manually.
      if (self.test_mode or (
            target.provision_state.bootloader_locked and
            not target.provision_state.avb_perm_attr_set
          )):
        pending_targets.append(target)
      else:
        self._SendAlertEvent(self.atft_string.ALERT_FUSE_PERM_ATTR_FUSED)

    for target in pending_targets:
      self._FusePermAttrTarget(target)

  def _FusePermAttrTarget(self, target, auto_prov=False):
    """Fuse the permanent attributes to the specific target device.

    Args:
      target: The target device DeviceInfo object.
      auto_prov: Whether this operation is part of automatic operations.
    """
    operation = 'Fuse permanent attributes'
    if not self._StartOperation(operation, target, True, auto_prov):
      return

    try:
      self.atft_manager.FusePermAttr(target)
    except ProductNotSpecifiedException as e:
      self._HandleException('W', e, operation, [target])
      return
    except FastbootFailure as e:
      self._HandleException('E', e, operation, [target])
      return
    finally:
      self._EndOperation(target)

    self._SendOperationSucceedEvent(operation, target)

  def _LockAvb(self, selected_serials):
    """Lock android verified boot for selected devices.

    Args:
      selected_serials: The list of serial numbers for the selected devices.
    """
    pending_targets = []
    for serial in selected_serials:
      target = self.atft_manager.GetTargetDevice(serial)
      if not target:
        continue
      # Start state could be FUSEATTR_SUCCESS or LOCKAVB_FAIELD
      if (self.test_mode or(
            target.provision_state.bootloader_locked and
            target.provision_state.avb_perm_attr_set and
            not target.provision_state.avb_locked
          )):
        target.provision_status = ProvisionStatus.WAITING
        pending_targets.append(target)
      else:
        self._SendAlertEvent(self.atft_string.ALERT_LOCKAVB_LOCKED)

    for target in pending_targets:
      self._LockAvbTarget(target)

  def _LockAvbTarget(self, target, auto_prov=False):
    """Lock android verified boot for the specific target device.

    Args:
      target: The target device DeviceInfo object.
      auto_prov: Whether this operation is part of automatic operations.
    """
    operation = 'Lock android verified boot'
    if not self._StartOperation(operation, target, True, auto_prov):
      return

    try:
      self.atft_manager.LockAvb(target)
    except FastbootFailure as e:
      self._HandleException('E', e, operation, [target])
      return
    finally:
      self._EndOperation(target)

    self._SendOperationSucceedEvent(operation, target)

  def _UnlockAvb(self, selected_serials):
    """Unlock android verified boot for selected devices.

    Args:
      selected_serials: The list of serial numbers for the selected devices.
    """
    pending_targets = []
    for serial in selected_serials:
      target = self.atft_manager.GetTargetDevice(serial)
      if not target:
        continue
      if (self.test_mode or target.provision_state.avb_locked):
        target.provision_status = ProvisionStatus.WAITING
        pending_targets.append(target)
      else:
        self._SendAlertEvent(self.atft_string.ALERT_UNLOCKAVB_UNLOCKED)

    for target in pending_targets:
      self._UnlockAvbTarget(target)

  def _UnlockAvbTarget(self, target, auto_prov=False):
    """Unlock android verified boot for the specific target device.

    Args:
      target: The target device DeviceInfo object.
      auto_prov: Whether this operation is part of automatic operations.
    """
    operation = 'Unlock android verified boot'
    if not self._StartOperation(operation, target, True, auto_prov):
      return

    try:
      self.atft_manager.UnlockAvb(target)
    except FastbootFailure as e:
      self._HandleException('E', e, operation, [target])
      return
    finally:
      self._EndOperation(target)

    self._SendOperationSucceedEvent(operation, target)

  def _CheckLowKeyAlert(self):
    """Check whether the attestation key is lower than the threshold.

    If so, an alert box would appear to warn the user.
    """
    operation = 'Check ATFA Status'

    if self._UpdateKeysLeftInATFA():
      keys_left = self._GetCachedATFAKeysLeft()
      if keys_left and keys_left >= 0:
        first_warning = self.change_threshold_dialog.GetFirstWarning()
        second_warning = self.change_threshold_dialog.GetSecondWarning()
        if (second_warning and keys_left < second_warning and
            not self.second_key_alert_shown):
          self.second_key_alert_shown = True
          if not self.first_key_alert_shown:
            # If already past the first alert and second alert is shown,
            # We would not show the first alert again.
            self.first_key_alert_shown = True
          self._SendLowKeyAlertEvent(keys_left)
          return

        if keys_left < first_warning and not self.first_key_alert_shown:
          self.first_key_alert_shown = True
          self._SendLowKeyAlertEvent(keys_left)
          return

  def _Reboot(self):
    """Reboot ATFA device.
    """
    operation = 'Reboot ATFA device'
    atfa_dev = self.atft_manager.GetATFADevice()
    if not self._StartOperation(operation, atfa_dev):
      return

    try:
      self.atft_manager.RebootATFA()
    except DeviceNotFoundException as e:
      e.SetMsg('No Available ATFA!')
      self._HandleException('W', e, operation)
      return
    except FastbootFailure as e:
      self._HandleException('E', e, operation, [atfa_dev])
      return
    finally:
      self._EndOperation(atfa_dev)

    self._SendOperationSucceedEvent(operation)

  def _Shutdown(self):
    """Shutdown ATFA device.
    """
    operation = 'Shutdown ATFA device'
    atfa_dev = self.atft_manager.GetATFADevice()
    if not self._StartOperation(operation, atfa_dev):
      return

    try:
      self.atft_manager.ShutdownATFA()
    except DeviceNotFoundException as e:
      e.SetMsg('No Available ATFA!')
      self._HandleException('W', e, operation)
      return
    except FastbootFailure as e:
      self._HandleException('E', e, operation, [atfa_dev])
      return
    finally:
      self._EndOperation(atfa_dev)

    self._SendOperationSucceedEvent(operation)

  def _ManualProvision(self, selected_serials, is_som_key):
    """Manual provision the selected devices.

    Args:
      selected_serials: A list of the serial numbers of the target devices.
      is_som_key: Whether provision som key (or product key).
    """
    # Reset alert_shown
    self.first_key_alert_shown = False
    self.second_key_alert_shown = False
    for serial in selected_serials:
      target_dev = self.atft_manager.GetTargetDevice(serial)
      if not target_dev:
        continue
      if target_dev.provision_status == ProvisionStatus.WAITING:
        self._ProvisionTarget(target_dev, is_som_key)

  def _ProvisionTarget(self, target, is_som_key, auto_prov=False):
    """Provision the attestation key into the specific target.

    Args:
      target: The target to be provisioned.
      is_som_key: Whether provision som key (or product key).
      auto_prov: Whether this operation is part of automatic operations.
    """
    operation = 'Product Attestation Key Provisioning'
    if is_som_key:
      operation = 'SoM Attestation Key Provisioning'
    atfa_dev = self.atft_manager.GetATFADevice()
    if not self._StartOperation(operation, target, True, auto_prov):
      return
    if not self._StartOperation(operation, atfa_dev, True, auto_prov):
     return

    try:
      self.atft_manager.Provision(target, is_som_key)
    except DeviceNotFoundException as e:
      e.SetMsg('No Available ATFA!')
      self._HandleException('W', e, operation, [target])
      return
    except FastbootFailure as e:
      self._HandleException('E', e, operation, [target])
      # If it fails, one key might also be used.
      self._UpdateKeysLeftInATFA()
      return
    finally:
      self._EndOperation(atfa_dev)
      self._EndOperation(target)

    self._SendOperationSucceedEvent(operation, target)
    if not is_som_key:
      self.log.Info(
        'Key Provisioning',
        'Device: ' + str(target) + ' AT-ATTEST-UUID: ' + target.at_attest_uuid)
    self._CheckLowKeyAlert()

  def _HandleStateTransition(self, target):
    """Handles the state transition for automatic key provisioning.

    A normal flow should be:
      WAITING->FUSEVBOOT_SUCCESS->REBOOT_SUCCESS->LOCKAVB_SUCCESS
      ->PROVISION_SUCCESS

    Args:
      target: The target device object.
    """
    self.auto_prov_lock.acquire()
    serial = target.serial_number
    i = 0
    while True:
      target = self.atft_manager.GetTargetDevice(serial)
      if not target or ProvisionStatus.isFailed(target.provision_status):
        break
      if not self.auto_prov:
        # Auto provision mode exited.
        break
      if i == len(self.provision_steps):
        break
      operation = self.provision_steps[i]
      i += 1
      if (not target.provision_state.bootloader_locked and
          operation == 'FuseVbootKey'):
        self._FuseVbootKeyTarget(target, True)
        continue
      elif (not target.provision_state.avb_perm_attr_set and
            operation == 'FusePermAttr'):
        self._FusePermAttrTarget(target, True)
        continue
      elif (not target.provision_state.avb_locked and operation == 'LockAvb'):
        self._LockAvbTarget(target, True)
        continue
      elif (target.provision_state.avb_locked and operation == 'UnlockAvb'):
        self._UnlockAvbTarget(target, True)
        continue
      elif (not target.provision_state.product_provisioned and
            operation == 'ProvisionProduct'):
        # Provision product key.
        self._ProvisionTarget(target, False, True)
        if self._GetCachedATFAKeysLeft() == 0:
          # No keys left. If it's auto provisioning mode, exit.
          self._SendAlertEvent(self.atft_string.ALERT_NO_KEYS_LEFT_LEAVE_PROV)
          self.OnLeaveAutoProv()
        continue
      elif (not target.provision_state.som_provisioned and
            operation == 'ProvisionSom'):
        # Provision som key.
        self._ProvisionTarget(target, True, True)
        if self._GetCachedATFAKeysLeft() == 0:
          # No keys left. If it's auto provisioning mode, exit.
          self._SendAlertEvent(self.atft_string.ALERT_NO_KEYS_LEFT_LEAVE_PROV)
          self.OnLeaveAutoProv()

    if target and self._is_provision_steps_finished(target.provision_state):
      self._SendOperationSucceedEvent('All steps', target)

    self.auto_dev_serials.remove(serial)
    self.auto_prov_lock.release()

  def _ProcessKeyCallback(self, pathname):
    self._CreateThread(self._ProcessKey, pathname)

  def _ProcessKey(self, pathname, auto_process=False):
    """Ask ATFA device to store and process the stored keybundle.

    Args:
      pathname: The path name to the key bundle file.
      auto_process: Whether this operation is automatic.
    """
    operation = 'ATFA device store and process key bundle'
    atfa_dev = self.atft_manager.GetATFADevice()
    show_alert = True
    blocking = False
    if auto_process:
      show_alert = False
      blocking = True
    if not self._StartOperation(operation, atfa_dev, show_alert, blocking):
      return
    try:
      self.atft_manager.CheckDevice(atfa_dev)
      atfa_dev.Download(pathname)
      self.atft_manager.ProcessATFAKey()
      self._SendOperationSucceedEvent(operation)

    except DeviceNotFoundException as e:
      if auto_process:
        raise e
        return
      e.SetMsg('No Available ATFA!')
      self._HandleException('W', e, operation)
      return
    except FastbootFailure as e:
      if auto_process:
        raise e
        return
      self._HandleException('E', e, operation)
      if show_alert:
        self._SendAlertEvent(
            self.atft_string.ALERT_PROCESS_KEY_FAILURE + e.msg.encode('utf-8'))
      return
    finally:
      self._EndOperation(atfa_dev)

    # Check ATFA status after new key stored.
    if self.atft_manager.product_info or self.atft_manager.som_info:
      # Force download audit file if you switch to a new product.
      self.audit.ResetKeysLeft()
      self._UpdateKeysLeftInATFA()

  def _UpdateATFACallback(self, pathname):
    self._CreateThread(self._UpdateATFA, pathname)

  def _UpdateATFA(self, pathname):
    """Ask ATFA device to store and process the stored keybundle.

    Args:
      pathname: The path name to the key bundle file.
    """
    operation = 'Update ATFA device'
    atfa_dev = self.atft_manager.GetATFADevice()
    if not self._StartOperation(operation, atfa_dev):
      return
    try:
      atfa_dev.Download(pathname)
      self.atft_manager.UpdateATFA()
    except DeviceNotFoundException as e:
      e.SetMsg('No Available ATFA!')
      self._HandleException('W', e, operation)
      return
    except FastbootFailure as e:
      self._HandleException('E', e, operation)
      self._SendAlertEvent(
          self.atft_string.ALERT_UPDATE_FAILURE + e.msg.encode('utf-8'))
      return
    finally:
      self._EndOperation(atfa_dev)

    self._SendOperationSucceedEvent(operation)

  def _PurgeKey(self):
    """Purge the key for the selected product in the ATFA device.
    """
    operation = 'ATFA purge key'
    atfa_dev = self.atft_manager.GetATFADevice()
    if not self._StartOperation(operation, atfa_dev):
      return
    try:
      is_som_key = self.atft_manager.som_info is not None
      self.atft_manager.PurgeATFAKey(is_som_key)
      self._SendOperationSucceedEvent(operation)
      self._UpdateKeysLeftInATFA()
    except ProductNotSpecifiedException as e:
      self._HandleException('W', e, operation)
      return
    except DeviceNotFoundException as e:
      e.SetMsg('No Available ATFA!')
      self._HandleException('W', e, operation)
      return
    except FastbootFailure as e:
      self._HandleException('E', e, operation)
      self._SendAlertEvent(
          self.atft_string.ALERT_PURGE_KEY_FAILURE + e.msg.encode('utf-8'))
      return
    finally:
      self._EndOperation(atfa_dev)

  def _GetRegFile(self, filepath):
    self._CreateThread(self._GetFileFromATFA, filepath, 'reg', True, False)

  def _GetAuditFile(self, filepath):
    self._CreateThread(self._GetFileFromATFA, filepath, 'audit', True, False)

  def _GetFileFromATFA(self, filepath, file_type, show_alert, blocking):
    """Download a type of file from the ATFA device.

    Args:
      filepath: The path to the downloaded file.
      file_type: The type of the file to be downloaded. Supported options are
        'reg'/'audit'.
      show_alert: Whether to display an alert if error happens.
      blocking: Whether to block the operation on other pending operations.
    Returns:
      Whether this operation succeed.
    """
    atfa_dev = self.atft_manager.GetATFADevice()
    if file_type == 'audit':
      alert_message = self.atft_string.ALERT_AUDIT_DOWNLOADED
      alert_cannot_get_file_message = self.atft_string.ALERT_CANNOT_GET_AUDIT
    elif file_type == 'reg':
      alert_message = self.atft_string.ALERT_REG_DOWNLOADED
      alert_cannot_get_file_message = self.atft_string.ALERT_CANNOT_GET_REG
    else:
      # Should not reach here.
      return False
    operation = 'ATFA device prepare and download ' + file_type + ' file'
    if not self._StartOperation(operation, atfa_dev, show_alert, blocking):
      return False
    try:
      filepath = filepath.encode('utf-8')
      write_file = open(filepath, 'w+')
      write_file.close()
      self.atft_manager.PrepareFile(file_type)
      atfa_dev.Upload(filepath)
    except DeviceNotFoundException as e:
      e.SetMsg('No Available ATFA!')
      self._HandleException('W', e, operation)
      if show_alert:
        self._SendAlertEvent(self.atft_string.ALERT_NO_ATFA)
      return False
    except IOError as e:
      self._HandleException('E', e)
      if show_alert:
        self._SendAlertEvent(self.atft_string.ALERT_CANNOT_SAVE_FILE + filepath)
      return False
    except FastbootFailure as e:
      self._HandleException('E', e)
      if show_alert:
        self._SendAlertEvent(
            alert_cannot_get_file_message + e.msg.encode('utf-8'))
      return False
    finally:
      self._EndOperation(atfa_dev)

    self._SendOperationSucceedEvent(operation)
    if show_alert:
      self._SendAlertEvent(alert_message + filepath)
    return True

  def _GetSelectedSerials(self):
    """Get the list of selected serial numbers in the device list.

    Returns:
      A list of serial numbers of the selected target devices.
    """
    selected_serials = []
    i = 0
    for dev_component in self.target_dev_components:
      if self.device_usb_locations[i] and dev_component.selected:
        selected_serials.append(dev_component.serial_number)
      i += 1
    return selected_serials

  def ManualMapUSBLocationToSlot(self, event):
    """The handler to map a USB location to an UI slot in the tool.

    This handler would be triggered if the 'map' button on the USB Location
    Mapping interface is clicked. It would map the connected Android Things
    device to the selected UI slot.

    Args:
      event: The triggering event.
    """
    selected = [
        dev_component
            for dev_component in self.app_settings_dialog.dev_mapping_components
            if dev_component.selected]

    if not selected:
      self._SendAlertEvent(self.atft_string.ALERT_NO_MAP_DEVICE_CHOSEN)
      return

    component = selected[0]
    index = component.index

    if self.device_usb_locations[index]:
      # If this slot was already mapped, warn the user.
      warning_message = self.atft_string.ALERT_REMAP_SLOT_LOCATION(
          str(component.index + 1), self.device_usb_locations[component.index])
      if not self._ShowWarning(warning_message):
        return

    if not self.atft_manager.target_devs:
      self._SendAlertEvent(self.atft_string.ALERT_NO_TARGET_DEVICE)
      return

    if len(self.atft_manager.target_devs) > 1:
      self._SendAlertEvent(self.atft_string.ALERT_MULTIPLE_TARGET_DEVICE)
      return

    location = self.atft_manager.target_devs[0].location

    # Check if the location is already mounted to a slot, if so gives a warning
    # since this mapping would overwrite previous configuration.
    for i in range(TARGET_DEV_SIZE):
      if (self.device_usb_locations[i] and
          self.device_usb_locations[i] == location and i != component.index):
        warning_text = self.atft_string.ALERT_REMAP_LOCATION_SLOT(
            self.device_usb_locations[i], str(i + 1))
        if not self._ShowWarning(warning_text):
          self.SendUpdateMappingEvent()
          return
        else:
          self.device_usb_locations[i] = None

    self.device_usb_locations[index] = location
    self.SendUpdateMappingEvent()

  def AutoMapUSBLocationToSlot(self, event):
    """The handler to map connected target devices to UI slots in the tool.

    This handler would be triggered if the 'automap' button on the USB Location
    Mapping interface is clicked. It would randomly map the connected Android
    Things device to the UI slots.

    Args:
      event: The triggering event.
    """
    for i in range(TARGET_DEV_SIZE):
      if (self.device_usb_locations[i]):
        if not self._ShowWarning(self.atft_string.ALERT_REMAP_ALL):
          return
        else:
          break

    if not self.atft_manager.target_devs:
      self._SendAlertEvent(self.atft_string.ALERT_NO_TARGET_DEVICE)
      return

    for i in range(TARGET_DEV_SIZE):
      if i >= len(self.atft_manager.target_devs):
        self.device_usb_locations[i] = None
        continue
      self.device_usb_locations[i] = self.atft_manager.target_devs[i].location

    self.SendUpdateMappingEvent()

  def ChangeLanguage(self, language_text):
    """Change the language setting according to the selected language name.

    Args:
      language_text: The name of the language selected.
    """
    for i in range(len(LANGUAGE_OPTIONS)):
      if LANGUAGE_OPTIONS[i] == language_text:
        self.language = LANGUAGE_CONFIGS[i]
        self._SendAlertEvent(
            self.atft_string.ALERT_LANGUAGE_RESTART[self.GetLanguageIndex()])
        break

  def ChangePassword(self, old_password, new_password):
    result = Atft.VerifyPassword(old_password, self.password_hash)
    if result:
      new_hash = Atft.GeneratePasswordHash(new_password)
      self.password_hash = new_hash
      self.log.Info('Password', 'Password Changed')
      self._SendPrintEvent('Password Changed!')
      return True
    else:
      e = PasswordErrorException()
      self._HandleException('W', e)
      self._SendAlertEvent(self.atft_string.ALERT_WRONG_ORIG_PASSWORD)
      return False

def main():
  app = wx.App()
  Atft()
  app.MainLoop()


if __name__ == '__main__':
  main()
