8
from ncd_usb import set_relay
10
log = logging.getLogger()
11
logging.basicConfig(level=logging.INFO)
14
class DeviceError(Exception):
18
def _reimage_from_fastboot(serial):
19
#Starting from fastboot mode, put a known-good image on the device
20
log.info("Flashing the last stable image")
21
subprocess.check_output(['ubuntu-device-flash', '--serial', serial,
22
'--channel', 'ubuntu-touch/stable',
23
'--bootstrap', '--password', 'ubuntuci'])
24
return _wait_for_device(serial, 600)
27
def _wait_for_device(serial, timeout=120):
28
# Wait for the device to come up to a good/booted state
29
log.info("Waiting for the device to become available")
31
subprocess.check_call(['timeout', str(timeout), 'adb', '-s',
32
serial, 'wait-for-device'])
34
log.error("Timed out waiting for reboot. Recover device manually")
36
dev_state = device_info.get_state(serial)
37
if dev_state != 'device':
38
raise DeviceError("Device in state: {0}, still not available after "
39
"{1} seconds".format(dev_state, timeout))
41
log.info("Device is now available")
45
def _wait_for_fastboot(serial, timeout=120):
51
while waited < timeout:
52
state = device_info.get_state(serial)
53
if state == 'fastboot':
58
state = device_info.get_state(serial)
59
if state == 'fastboot':
61
log.error("Timed out waiting for fastboot. Recover device manually")
62
raise DeviceError("Device in state: {0}, still not available after "
63
"{1} seconds".format(state, timeout))
66
def _mako_to_bootloader(urlbase, bank, power=1, volume=2):
68
This just works on mako for certain, but that's all we have connected
69
right now. After this runs, the device should be in the bootloader
71
log.info("Forcing the device to enter the bootloader")
72
#Power off the device from any state
73
set_relay(urlbase, bank, power, 1)
75
set_relay(urlbase, bank, power, 0)
78
set_relay(urlbase, bank, volume, 1)
79
set_relay(urlbase, bank, power, 1)
81
set_relay(urlbase, bank, volume, 0)
82
set_relay(urlbase, bank, power, 0)
85
def _full_recovery(device_name):
86
#we only support mako at the moment
87
(url, bank, power, volume) = device_info.get_power(device_name)
88
if None in (url, bank, power, volume):
89
#This device does not have information about relays
90
raise DeviceError("Full recovery not possible with this device")
91
_mako_to_bootloader(url, bank, power, volume)
92
serial = device_info.get_serial(device_name)
93
_wait_for_fastboot(serial)
94
_reimage_from_fastboot(serial)
99
serial = device_info.get_serial(device)
100
except AttributeError:
101
log.error("No device found for '{}'".format(device))
103
state = device_info.get_state(serial)
104
if state in ('device', 'recovery'):
105
#The device can proceed with testing
107
if state == 'fastboot':
108
#The device is in fastboot right now, we need it booted first
109
return _reimage_from_fastboot(serial)
110
if state in ('unknown', 'disconnected'):
111
#The device is in an unknown state, we need full recovery
112
return _full_recovery(device)
113
#In theory, we should never get here, but....
114
raise DeviceError("Device '{}' is in an unknown state!".format(device))
117
if __name__ == '__main__':
121
except AttributeError:
122
#This is what we'll get if it's an unknown device, raise for
123
#everything else so we get better debugging information