blob: 6e0d6f3e497c7575b7aa69a449a248e66fb1cbc8 [file] [log] [blame]
from __future__ import print_function
import sys
import platform
import os
import os.path
import time
import re
import argparse
import subprocess
try:
input = raw_input
except NameError:
pass
arguments = None
fastboot_name = "fastboot"
fbtool_name = "fbtool.py"
prod_out_path = os.path.abspath(".")
def initialize_env():
global fastboot_name
# check python version
if sys.version_info[:2] == (2, 7) or sys.version_info[:2][0] == 3:
pass
else:
print("Python 2.7.x / Python 3.x.x required")
exit(1)
# set fastboot
if "Windows" in platform.system():
fastboot_name += ".exe"
elif "CYGWIN" in platform.system():
fastboot_name += ".exe"
elif "Linux" in platform.system():
if "arm" in platform.machine():
fastboot_name += "-linux-arm"
elif "aarch64" in platform.machine():
fastboot_name += "-linux-arm"
elif "x86_64" in platform.machine():
fastboot_name += "-linux-x86_64"
elif "Darwin" in platform.system():
fastboot_name += "-darwin"
def set_arguments():
global arguments
parser = argparse.ArgumentParser(
description='''
Auto device flasher, Python 2.7.x / Python 3.x.x required
''',
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("--productdir", default=None,
help='''
The product out dir is where to find images.
The Following is the path priority order:
1. --productdir specified
2. current directory
''')
parser.add_argument("--toolsdir", default=None,
help='''
The tools dir is where to find fbtool and fastboot.
The Following is the path priority order:
1. --toolsdir specified
2. current directory
3. $PATH
''')
parser.add_argument("partition", nargs="?", default="all",
help="partition to flash (default: all) \
, not include the test partition")
parser.add_argument("-b", "--boot", action="store_true", default=False,
help="Flash boot partition")
parser.add_argument("-d", "--dryrun", action="store_true", default=False,
help="No image would be flashed, for debug")
parser.add_argument("-s", "--userdefined",
action="store_true", default=False,
help="Flash user-defined partitions \
and run user-defined actions")
parser.add_argument("-t", "--test", action="store_true", default=False,
help="Flash test partition")
parser.add_argument("-u", "--user", action="store_true", default=False,
help="Flash user data partition")
parser.add_argument("-v", "--verbose", action="store_true", default=False,
help="print more information")
arguments = parser.parse_args()
def show_info(case):
def print_platform():
print("".center(60, "="))
print("")
print(("Running flasher on " + platform.platform()).center(60))
print("")
print("".center(60, "="))
def print_imagepath():
global prod_out_path
print("".center(60, "="))
print("= flash images under:".ljust(58), "=")
print("= ", prod_out_path.ljust(52), "=")
print("".center(60, "="))
def print_success():
if platform.system() == "Windows":
input("Success! press enter to exit: ")
else:
print("Success!")
def print_default():
print("No information about %s." % case)
information = {
"platform": print_platform,
"imagepath": print_imagepath,
"success": print_success
}
information.get(case, print_default)()
def check_flash_tools():
global arguments, fbtool_name, fastboot_name
toolsdir = ""
if arguments.toolsdir:
try:
toolsdir = os.path.abspath(arguments.toolsdir)
fastboot_name = os.path.join(toolsdir, fastboot_name)
fbtool_name = os.path.join(toolsdir, fbtool_name)
if not os.path.exists(fbtool_name):
raise Exception("Cannot find " + str(fbtool_name) + " in \
" + str(toolsdir))
if not os.path.exists(fastboot_name):
raise Exception("Cannot find " + str(fastboot_name) + " in \
" + str(toolsdir))
except Exception as err:
print(str(err))
exit(1)
else:
toolsdir = os.path.abspath(".")
if os.path.exists(os.path.join(toolsdir, fbtool_name)):
if os.path.exists(os.path.join(toolsdir, fastboot_name)):
fastboot_name = os.path.join(toolsdir, fastboot_name)
fbtool_name = os.path.join(toolsdir, fbtool_name)
def get_flashprocs():
global arguments
devProduct = "DEFAULT"
try:
from flashproc import getFlashProc
except ImportError as err:
print("ImportError: ", err)
exit(1)
flashprocs = getFlashProc(devProduct)
if arguments.userdefined:
try:
from flashproc import getFlashUserdefinedProc
flashprocs = getFlashUserdefinedProc(devProduct)
except:
flashprocs = getFlashProc(devProduct)
if arguments.user:
try:
from flashproc import getFlashUserProc
flashprocs = getFlashUserProc(devProduct)
except:
flashprocs = getFlashProc(devProduct)
if arguments.boot:
try:
from flashproc import getFlashBootProc
flashprocs = getFlashBootProc(devProduct)
except:
flashprocs = getFlashProc(devProduct)
if arguments.test:
try:
from flashproc import getFlashTestProc
flashprocs = getFlashTestProc(devProduct)
except:
flashprocs = getFlashProc(devProduct)
if flashprocs is None:
print("Cannot retrieve flash procedure according \
to product type of", devProduct)
print("Terminate program !")
exit(1)
if arguments.verbose:
print("Flash procedure".center(60))
print("".center(60, "-"))
for p in flashprocs:
print("fastboot", " ".join(p))
return flashprocs
def get_img_list():
flashprocs = get_flashprocs()
imgs = []
try:
for proc in flashprocs:
if proc[0] == "fastboot":
if proc[1] == "flash":
if proc[3] not in imgs:
imgs.append(proc[3])
except Exception as err:
print(err)
return imgs
def check_img(filename, _needreboot=True, _showdetail=False):
global fastboot_name, prod_out_path
if _showdetail:
print((filename).rjust(28), ": ", end="")
path = os.path.join(prod_out_path, filename)
if os.path.exists(path):
if _showdetail:
print("PASS!")
return path
if _needreboot:
print("FAIL!\n Rebooting...")
call([fastboot_name, "reboot"])
exit(1)
return None
def call(cmd):
global arguments
if arguments.verbose:
print("call:", " ".join(cmd))
return subprocess.call(cmd)
def check_output(cmd):
global arguments
if arguments.verbose:
print("check_output:", " ".join(cmd))
return subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
def check_img_path():
global arguments, prod_out_path
if arguments.productdir:
prod_out_path = os.path.abspath(arguments.productdir)
else:
prod_out_path = os.path.abspath(".")
for img in get_img_list():
if check_img(img, _needreboot=False, _showdetail=False) is None:
prod_out_path = None
break
if prod_out_path is None:
prod_out_path = os.getenv("PRODUCT_OUT", ".")
prod_out_path = os.path.abspath(prod_out_path)
def da_mode_wait(wait_secs=30):
global fbtool_name
print("\nWaiting for DA mode:")
ret_code = None
for i in range(wait_secs):
time.sleep(1)
print("# ", end="")
sys.stdout.flush()
ret_code = check_output("python %s " % fbtool_name)
if ret_code is not None and len(ret_code) != 0:
print("datool - device detected: ")
break
if ret_code is None:
print("No device detected.")
print("Please ensure that datool is running.\n")
exit(1)
def fastboot_wait(wait_secs=30):
global fastboot_name
print("\nWaiting for fastboot mode:")
ret_code = None
for i in range(wait_secs):
time.sleep(1)
print("# ", end="")
sys.stdout.flush()
ret_code = check_output("%s devices" % fastboot_name).decode()
if ret_code is not None and len(ret_code) != 0:
print("Fastboot - device detected: ", (ret_code.split())[0])
break
if ret_code is None:
print("No device detected. ")
exit(1)
def command_reboot(_tobootloader=True):
global fastboot_name
if _tobootloader:
call([fastboot_name, "reboot-bootloader"])
fastboot_wait()
else:
call([fastboot_name, "reboot"])
def reboot_device():
time.sleep(3)
command_reboot(_tobootloader=False)
def check_all_imgs():
images = get_img_list()
print("".center(60, "-"))
print("Checking image".center(60))
print("".center(60, "-"))
try:
for img in images:
check_img(img, _needreboot=True, _showdetail=True)
except Exception as err:
print(err)
time.sleep(3)
command_reboot(_tobootloader=False)
input("Fail, press enter to exit: ")
exit(1)
def reboot_bootloader(tries=3):
check_output("adb devices")
for i in range(tries):
print(". ", end="")
time.sleep(2)
sys.stdout.flush()
try:
device_id = check_output("adb get-serialno")
except subprocess.CalledProcessError as err:
print("command '{}' return with error (code {}): {}".format(
err.cmd, err.returncode, err.output))
continue
print("\nAdb - device detected: ", (device_id.split())[0])
check_output("adb -s %s reboot bootloader" % (device_id.split())[0])
return
print("adb is not ready!")
print("Please check whether the usb cable is plugged or adb is supported.")
exit(1)
def command_run(cmd, dryrun=False):
ret_code = 1
raw_cmd = []
if cmd[0] == "fastboot":
cmd[0] = fastboot_name
if cmd[1] == "flash":
path = check_img(cmd[3], _needreboot=False, _showdetail=False)
if path is not None:
if "CYGWIN" in platform.system():
p = subprocess.check_output(
"cygpath --absolute --mixed %s" % path, shell=True)
if p:
path = p.strip()
raw_cmd += [cmd[0], cmd[1], cmd[2], path]
else:
raw_cmd += cmd
elif cmd[0] == "fbWait":
fastboot_wait()
return 0
elif cmd[0] == "daWait":
da_mode_wait()
return 0
elif cmd[0] == "reboottobl":
reboot_bootloader()
return 0
else:
print("FAIL: Unknown command!\n")
return -1
if dryrun:
print(" ".join(raw_cmd))
ret_code = 0
else:
ret_code = call(raw_cmd)
if ret_code == 0:
if cmd[0] == "fastboot":
if cmd[1] == "reboot-bootloader":
fastboot_wait()
return ret_code
def flash_imgs():
print("\nStart flashing".center(60))
print("".center(60, "-"))
try:
for p in get_flashprocs():
if command_run(p, arguments.dryrun) != 0:
raise Exception("<FAILED> %s" % " ".join(proc))
except Exception as err:
print(err)
time.sleep(3)
command_reboot(_tobootloader=False)
exit(1)
if __name__ == "__main__":
initialize_env()
set_arguments()
show_info("platform")
check_flash_tools()
check_img_path()
show_info("imagepath")
check_all_imgs()
flash_imgs()
reboot_device()
show_info("success")
exit(0)