-
Notifications
You must be signed in to change notification settings - Fork 64
/
check_versions.py
executable file
·248 lines (236 loc) · 13.4 KB
/
check_versions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import re
import os
import json
import shutil
import zipfile
import tempfile
import argparse
import subprocess
from distutils import util
from datetime import datetime
from argparse import ArgumentDefaultsHelpFormatter
from utilities import console_utilities
from utilities.adb_helper import AdbHelper
class VersionChecker(object):
def __init__(self, **kwargs):
self.arg_parser = argparse.ArgumentParser(description='Check the version information of Firefox OS.',
formatter_class=ArgumentDefaultsHelpFormatter)
self.arg_parser.add_argument('--no-color', action='store_true', dest='no_color', default=False, help='Do not print with color. NO_COLOR will overrides this option.')
self.arg_parser.add_argument('-s', '--serial', action='store', dest='serial', default=None, help='Directs command to the device or emulator with the given serial number. Overrides ANDROID_SERIAL environment variable.')
self.arg_parser.add_argument('--log-text', action='store', dest='log_text', default=None, help='Text ouput.')
self.arg_parser.add_argument('--log-json', action='store', dest='log_json', default=None, help='JSON output.')
self.args = self.arg_parser.parse_args()
def get_device_info(self, serial=None):
try:
tmp_dir = tempfile.mkdtemp(prefix='checkversions_')
# pull data from device
if not AdbHelper.adb_pull('/system/b2g/omni.ja', tmp_dir, serial=serial):
print 'Error pulling Gecko file.'
if not AdbHelper.adb_pull('/data/local/webapps/settings.gaiamobile.org/application.zip', tmp_dir, serial=serial):
if not AdbHelper.adb_pull('/system/b2g/webapps/settings.gaiamobile.org/application.zip', tmp_dir, serial=serial):
print 'Error pulling Gaia file.'
if not AdbHelper.adb_pull('/system/b2g/application.ini', tmp_dir, serial=serial):
print 'Error pulling application.ini file.'
# get Gaia info
gaia_rev = 'n/a'
gaia_date = 'n/a'
application_zip_file = tmp_dir + os.sep + 'application.zip'
if os.path.isfile(application_zip_file):
f = open(application_zip_file, 'rb')
z = zipfile.ZipFile(f)
z.extract('resources/gaia_commit.txt', tmp_dir)
f.close()
else:
print 'Can not find application.zip file.'
gaiacommit_file = tmp_dir + os.sep + 'resources/gaia_commit.txt'
if os.path.isfile(gaiacommit_file):
f = open(gaiacommit_file, "r")
gaia_rev = re.sub(r'\n+', '', f.readline())
gaia_date_sec_from_epoch = re.sub(r'\n+', '', f.readline())
f.close()
gaia_date = datetime.utcfromtimestamp(int(gaia_date_sec_from_epoch)).strftime('%Y-%m-%d %H:%M:%S')
else:
print 'Can not get gaia_commit.txt file from application.zip file.'
# deoptimize omni.ja for Gecko info
gecko_rev = 'n/a'
if os.path.isfile(tmp_dir + os.sep + 'omni.ja'):
deopt_dir = tmp_dir + os.sep + 'deopt'
deopt_file = deopt_dir + os.sep + 'omni.ja'
deopt_exec = tmp_dir + os.sep + 'optimizejars.py'
os.makedirs(deopt_dir)
shutil.copyfile('./optimizejars.py', deopt_exec)
cmd = 'python %s --deoptimize %s %s %s' % (deopt_exec, tmp_dir, tmp_dir, deopt_dir)
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = p.communicate()[0]
# unzip omni.ja to get Gecko info
if os.path.isfile(deopt_file):
f = open(deopt_file, 'rb')
z = zipfile.ZipFile(f)
z.extract('chrome/toolkit/content/global/buildconfig.html', tmp_dir)
f.close()
else:
print 'Can not deoptimize omni.ja file.'
gecko_rev = 'n/a'
# get Gecko info from buildconfig.html file
buildconfig_file = tmp_dir + os.sep + 'chrome/toolkit/content/global/buildconfig.html'
if os.path.isfile(buildconfig_file):
for line in open(buildconfig_file, "r"):
if re.search(r'Built from', line):
ret = re.findall(r'>(.*?)<', line)
gecko_rev = ret[1]
break
else:
print 'Can not get buildconfig.html file from omni.ja file.'
else:
print 'Can not find omni.ja file.'
# get Gecko version, and B2G BuildID from application.ini file
if os.path.isfile(tmp_dir + os.sep + 'application.ini'):
for line in open(tmp_dir + os.sep + 'application.ini', "r"):
if re.search(r'^\s*BuildID', line):
ret = re.findall(r'.*?=(.*)', line)
build_id = ret[0]
if re.search(r'^\s*Version', line):
ret = re.findall(r'.*?=(.*)', line)
version = ret[0]
else:
build_id = 'n/a'
version = 'n/a'
# get device information by getprop command
device_name = re.sub(r'\r+|\n+', '', AdbHelper.adb_shell('getprop ro.product.device', serial=serial))
firmware_release = re.sub(r'\r+|\n+', '', AdbHelper.adb_shell('getprop ro.build.version.release', serial=serial))
firmware_incremental = re.sub(r'\r+|\n+', '', AdbHelper.adb_shell('getprop ro.build.version.incremental', serial=serial))
firmware_date = re.sub(r'\r+|\n+', '', AdbHelper.adb_shell('getprop ro.build.date', serial=serial))
firmware_bootloader = re.sub(r'\r+|\n+', '', AdbHelper.adb_shell('getprop ro.boot.bootloader', serial=serial))
# prepare the return information
device_info = {}
device_info['Serial'] = serial
device_info['Build ID'] = build_id
device_info['Gaia Revision'] = gaia_rev
device_info['Gaia Date'] = gaia_date
device_info['Gecko Revision'] = gecko_rev
device_info['Gecko Version'] = version
device_info['Device Name'] = device_name
device_info['Firmware(Release)'] = firmware_release
device_info['Firmware(Incremental)'] = firmware_incremental
device_info['Firmware Date'] = firmware_date
device_info['Bootloader'] = firmware_bootloader
finally:
shutil.rmtree(tmp_dir)
return device_info
def _print_device_info_item(self, title, value, title_color=None, value_color=None):
console_utilities.print_color('{0:22s}'.format(title), fg_color=title_color, newline=False)
console_utilities.print_color(value, fg_color=value_color)
def print_device_info(self, device_info, no_color=False):
# setup the format by platform
if no_color:
title_color = None
sw_color = None
hw_color = None
else:
title_color = console_utilities.COLOR_LIGHT_BLUE
sw_color = console_utilities.COLOR_LIGHT_GREEN
hw_color = console_utilities.COLOR_LIGHT_YELLOW
# print the device information
self._print_device_info_item('Build ID', device_info['Build ID'], title_color=title_color, value_color=sw_color)
self._print_device_info_item('Gaia Revision', device_info['Gaia Revision'], title_color=title_color, value_color=sw_color)
self._print_device_info_item('Gaia Date', device_info['Gaia Date'], title_color=title_color, value_color=sw_color)
self._print_device_info_item('Gecko Revision', device_info['Gecko Revision'], title_color=title_color, value_color=sw_color)
self._print_device_info_item('Gecko Version', device_info['Gecko Version'], title_color=title_color, value_color=sw_color)
self._print_device_info_item('Device Name', device_info['Device Name'], title_color=title_color, value_color=hw_color)
self._print_device_info_item('Firmware(Release)', device_info['Firmware(Release)'], title_color=title_color, value_color=hw_color)
self._print_device_info_item('Firmware(Incremental)', device_info['Firmware(Incremental)'], title_color=title_color, value_color=hw_color)
self._print_device_info_item('Firmware Date', device_info['Firmware Date'], title_color=title_color, value_color=hw_color)
if device_info['Bootloader'] is not '':
self._print_device_info_item('Bootloader', device_info['Bootloader'], title_color=title_color, value_color=hw_color)
print ''
def output_log(self, device_info_list):
if self.args.log_json is None and self.args.log_text is None:
return
# prepare the result dict for parsing
result = {}
unknown_serial_index = 1
for device_info in device_info_list:
if device_info['Serial'] == None:
device_serial = 'unknown_serial_' + str(unknown_serial_index)
unknown_serial_index = unknown_serial_index + 1
else:
device_serial = device_info['Serial']
result[device_serial] = device_info
# output
if self.args.log_text is not None:
with open(self.args.log_text, 'w') as outfile:
for device_serial, device_info in result.items():
outfile.write('# %s\n' % device_serial)
if 'Skip' in device_info and device_info['Skip'] is True:
outfile.write('%s=%s\n' % ('Skip', device_info['Skip']))
else:
for key, value in device_info.items():
outfile.write('%s=%s\n' % (re.sub(r'\s+|\(|\)', '', key), re.sub(r'\s+', '_', value)))
outfile.write('\n')
if self.args.log_json is not None:
with open(self.args.log_json, 'w') as outfile:
json.dump(result, outfile, indent=4)
def run(self):
devices = AdbHelper.adb_devices()
is_no_color = self.args.no_color
if 'NO_COLOR' in os.environ:
try:
is_no_color = bool(util.strtobool(os.environ['NO_COLOR'].lower()))
except:
print 'Invalid NO_COLOR value [{0}].'.format(os.environ['NO_COLOR'])
if len(devices) == 0:
print 'No device.'
exit(1)
elif len(devices) >= 1:
# has --serial, then skip ANDROID_SERIAL, then list one device by --serial
if (self.args.serial is not None):
if self.args.serial in devices:
serial = self.args.serial
print 'Serial: {0} (State: {1})'.format(serial, devices[serial])
device_info = self.get_device_info(serial=serial)
self.print_device_info(device_info, no_color=is_no_color)
self.output_log([device_info])
else:
print 'Can not found {0}.\nDevices:'.format(self.args.serial)
for device, state in devices.items():
print 'Serial: {0} (State: {1})'.format(device, state)
exit(1)
# no --serial, but has ANDROID_SERIAL, then list one device by ANDROID_SERIAL
elif (self.args.serial is None) and ('ANDROID_SERIAL' in os.environ):
if os.environ['ANDROID_SERIAL'] in devices:
serial = os.environ['ANDROID_SERIAL']
print 'Serial: {0} (State: {1})'.format(serial, devices[serial])
device_info = self.get_device_info(serial=serial)
self.print_device_info(device_info, no_color=is_no_color)
self.output_log([device_info])
else:
print 'Can not found {0}.\nDevices:'.format(os.environ['ANDROID_SERIAL'])
for device, state in devices.items():
print 'Serial: {0} (State: {1})'.format(device, state)
exit(1)
# no --serial, no ANDROID_SERIAL, then list all devices
if (self.args.serial is None) and (not 'ANDROID_SERIAL' in os.environ):
if len(devices) > 1:
print 'More than one device.'
print 'You can specify ANDROID_SERIAL by "--serial" option.\n'
device_info_list = []
for device, state in devices.items():
print 'Serial: {0} (State: {1})'.format(device, state)
if state == 'device':
device_info = self.get_device_info(serial=device)
self.print_device_info(device_info, no_color=is_no_color)
device_info_list.append(device_info)
else:
print 'Skipped.\n'
device_info_list.append({'Serial': device, 'Skip': True})
self.output_log(device_info_list)
if __name__ == "__main__":
if not AdbHelper.has_adb():
print 'There is no "adb" in your environment PATH.'
exit(1)
my_app = VersionChecker()
my_app.run()