Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1078653
  • 博文数量: 104
  • 博客积分: 3715
  • 博客等级: 中校
  • 技术积分: 1868
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-30 08:38
文章分类

全部博文(104)

文章存档

2013年(1)

2012年(9)

2011年(41)

2010年(3)

2009年(3)

2008年(47)

分类: Python/Ruby

2011-01-15 12:03:55

  1. #!/usr/bin/env python3
  2. '''This program is used to flash an n1 image.'''

  3. import os.path
  4. import re
  5. import time
  6. import subprocess

  7. # command to use
  8. ADB = 'adb'
  9. FASTBOOT = 'fastboot'
  10. LOG_FILE = './flash.log'

  11. class TimeoutError(Exception): pass

  12. class Unbuffered:
  13.     '''Unbuffered streams decorator.'''
  14.     def __init__(self, stream):
  15.         self.stream = stream

  16.     def write(self, data):
  17.         '''Each write followed a flush.'''
  18.         self.stream.write(data)
  19.         self.stream.flush()

  20.     def __getattr__(self, attr):
  21.         '''Keep other operations non-modified.'''
  22.         return getattr(self.stream, attr)

  23. def waitingDevice(mode='adb', timeout=60, logfile=None):
  24.     '''Waiting nexus one to connect on the usb port.

  25.     @param mode could be adb or fastboot.
  26.     @param timeout.
  27.     @logfile where to put log.
  28.     @raises TimeoutError, ValueError.
  29.     '''
  30.     if mode == 'adb':
  31.         cmd = ADB
  32.         deviceLine = 1
  33.         connectedIdentifer = 'device'
  34.     elif mode == 'fastboot':
  35.         cmd = FASTBOOT
  36.         deviceLine = 0
  37.         connectedIdentifer = 'fastboot'
  38.     else:
  39.         raise ValueError('unknown device connection mode: ' + mode)

  40.     checkTime = 30
  41.     checkInterval = timeout / checkTime
  42.     i = 0
  43.     while i < checkTime:
  44.         lines = subprocess.Popen((cmd, 'devices'),
  45.                                  stderr=logfile,
  46.                                  stdout=subprocess.PIPE,
  47.                                  universal_newlines=True).communicate()[0].splitlines()
  48.         if len(lines) >= (deviceLine + 1):
  49.             deviceInfo = re.split('\s+', lines[deviceLine])
  50.             if (len(deviceInfo) >= 2 and
  51.                 deviceInfo[0].startswith('HT9CWP') and
  52.                 deviceInfo[1] == connectedIdentifer):
  53.                 return
  54.         time.sleep(checkInterval)
  55.         i += 1

  56.     raise TimeoutError('device not connected in {} mode'.format(mode))

  57. def reboot(mode='normal', logfile=None):
  58.     '''Reboot the device.
  59.     
  60.     @param mode could be normal or fastboot.
  61.     @param logfile where to put log.
  62.     @raises TimeoutError, CalledProcessError, ValueError.'''

  63.     if mode =='fastboot':
  64.         waitingDevice('adb')
  65.         subprocess.check_call((ADB, 'reboot', 'bootloader'),
  66.                               stderr=subprocess.STDOUT,
  67.                               stdout=logfile)
  68.         waitingDevice('fastboot')
  69.     elif mode == 'normal':
  70.         waitingDevice('fastboot')
  71.         subprocess.check_call((FASTBOOT, 'reboot'),
  72.                               stderr=subprocess.STDOUT,
  73.                               stdout=logfile)
  74.         waitingDevice('adb')
  75.     else:
  76.         raise ValueError('unknown reboot mode: {}'.format(mode))

  77. def eraseData(logfile=None):
  78.     '''Erase device data.'''
  79.     waitingDevice('fastboot')
  80.     subprocess.check_call((FASTBOOT, 'erase', 'cache'),
  81.                           stderr=subprocess.STDOUT,
  82.                           stdout=logfile)
  83.     subprocess.check_call((FASTBOOT, 'erase', 'userdata'),
  84.                           stderr=subprocess.STDOUT,
  85.                           stdout=logfile)

  86. def flash(boot, system, userdata, logfile=None):
  87.     '''Flash the specified image.'''
  88.     waitingDevice('fastboot')
  89.     subprocess.check_call((FASTBOOT, 'flash', 'boot', boot),
  90.                           stderr=subprocess.STDOUT,
  91.                           stdout=logfile)
  92.     subprocess.check_call((FASTBOOT, 'flash', 'system', system),
  93.                           stderr=subprocess.STDOUT,
  94.                           stdout=logfile)
  95.     subprocess.check_call((FASTBOOT, 'flash', 'userdata', userdata),
  96.                           stderr=subprocess.STDOUT,
  97.                           stdout=logfile)

  98. def main(boot, system, userdata, logfile=None):
  99.     '''Main entry point of flashing device.'''
  100.     try:
  101.         print('Waiting n1 to be connected ... ', end='')
  102.         waitingDevice('adb', logfile=logfile)
  103.         print('Done')

  104.         print('Rebooting n1 to fastboot mode ... ', end='')
  105.         reboot('fastboot',logfile=logfile)
  106.         print('Done')

  107.         print('Erasing cache and user data ... ', end='')
  108.         eraseData(logfile=logfile)
  109.         print('Done')

  110.         print('Flashing device ... ', end='')
  111.         flash(boot, system, userdata, logfile=logfile)
  112.         print('Done')

  113.         print('Rebooting n1 to normal mode ... ', end='')
  114.         reboot('normal', logfile=logfile)
  115.         print('Done')
  116.     except Exception as e:
  117.         print('\nFailed due to {}'.format(e))

  118. def usage():
  119.     '''Print usage information.'''
  120.     print('Usage: {} --test/image_dir'.format(sys.argv[0]))

  121. def test():
  122.     try:
  123.         '''Testing various functions of this module.'''
  124.         print('\ttesting waitingDevice on adb mode ... ', end='')
  125.         waitingDevice()
  126.         print('ok')

  127.         print('\ttesting reboot to fast boot mode ... ', end='')
  128.         reboot('fastboot')
  129.         print('ok')

  130.         print('\ttesting reboot to normal mode ... ', end='')
  131.         reboot('normal')
  132.         print('ok')
  133.     except Exception as e:
  134.         print('\nFailed tests due to {}'.format(e))

  135. if __name__ == '__main__':
  136.     import sys
  137.     # disable stdout bufferring
  138.     sys.stdout = Unbuffered(sys.stdout)
  139.     if len(sys.argv) != 2:
  140.         usage()
  141.         sys.exit(1)
  142.     if sys.argv[1] == '--test':
  143.         print("Running tests ...")
  144.         test()
  145.         sys.exit(0)

  146.     # we will flash the device
  147.     bootImg = os.path.join(sys.argv[1], "boot.img")
  148.     systemImg = os.path.join(sys.argv[1], "system.img")
  149.     userdataImg = os.path.join(sys.argv[1], "userdata.img")

  150.     if (os.path.isfile(systemImg) and
  151.         os.path.isfile(userdataImg) and
  152.         os.path.isfile(bootImg)):
  153.         print("Flashing image:\n\t'{}',\n\t'{}',\n\t'{}' to n1 ...".
  154.               format(bootImg, systemImg, userdataImg))
  155.         logfile = Unbuffered(open(LOG_FILE, 'a'))
  156.         logfile.write("\n======= Begin of new log {} =======\n".
  157.                       format(time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())))
  158.         main(bootImg, systemImg, userdataImg, logfile)
  159.         logfile.close()
  160.         print("See {} for other details.".format(LOG_FILE))
  161.     else:
  162.         print("image file:\n\t'{}',\n\t'{}' or\n\t'{}' does not exists.".
  163.               format(bootImg, systemImg, userdataImg))
阅读(1348) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~