def get_crashreports(self, serial=None): ''' Print the pending and submitted crash reports on device. The submitted crashs report will be displayed with URL link. @param serial: device serial number. (optional) ''' AdbWrapper.adb_root(serial=serial) logger.info('Getting Crash Reports...') pending, retcode_pending = AdbWrapper.adb_shell( 'ls -al /data/b2g/mozilla/Crash\ Reports/pending', serial=serial) print('Pending Crash Reports:\n{}\n'.format(pending)) submitted, retcode_submitted = AdbWrapper.adb_shell( 'ls -al /data/b2g/mozilla/Crash\ Reports/submitted', serial=serial) print('Submitted Crash Reports:\n{}\n'.format(submitted)) if retcode_submitted == 0: print('The links of Submitted Crash Reports:') for line in submitted.split('\n'): submmited_id = re.sub(r'\.txt\s*$', '', re.sub(r'^.+bp-', '', line)) submitted_url = 'https://crash-stats.mozilla.com/report/index/{}'.format( submmited_id) print(submitted_url)
def get_crashreports(self, serial=None): """ Print the pending and submitted crash reports on device. The submitted crashs report will be displayed with URL link. @param serial: device serial number. (optional) """ AdbWrapper.adb_root(serial=serial) logger.info('Getting Crash Reports...') self.pending_stdout, retcode_pending = AdbWrapper.adb_shell( 'ls -al "{}"'.format(self.pending_path), serial=serial) print('Pending Crash Reports:\n{}\n'.format(self.pending_stdout)) self.submitted_stdout, retcode_submitted = AdbWrapper.adb_shell( 'ls -al "{}"'.format(self.submitted_path), serial=serial) print('Submitted Crash Reports:\n{}\n'.format(self.submitted_stdout)) # parse stdout for getting filepath self.pending_files = self._parse_stdout(self.pending_path, self.pending_stdout) self.submitted_files = self._parse_stdout(self.submitted_path, self.submitted_stdout) self.submitted_url_list = [] if retcode_submitted == 0: print('The links of Submitted Crash Reports:') for line in self.submitted_stdout.split('\n'): submmited_id = re.sub(r'\.txt\s*$', '', re.sub(r'^.+bp-', '', line)) submitted_url = 'https://crash-stats.mozilla.com/report/index/{}'.format( submmited_id) self.submitted_url_list.append(submitted_url) print(submitted_url)
def get_crashreports(self, serial=None): """ Print the pending and submitted crash reports on device. The submitted crashs report will be displayed with URL link. @param serial: device serial number. (optional) """ AdbWrapper.adb_root(serial=serial) logger.info('Getting Crash Reports...') self.pending_stdout, retcode_pending = AdbWrapper.adb_shell('ls -al "{}"'.format(self.pending_path), serial=serial) print('Pending Crash Reports:\n{}\n'.format(self.pending_stdout)) self.submitted_stdout, retcode_submitted = AdbWrapper.adb_shell('ls -al "{}"'.format(self.submitted_path), serial=serial) print('Submitted Crash Reports:\n{}\n'.format(self.submitted_stdout)) # parse stdout for getting filepath self.pending_files = self._parse_stdout(self.pending_path, self.pending_stdout) self.submitted_files = self._parse_stdout(self.submitted_path, self.submitted_stdout) self.submitted_url_list = [] if retcode_submitted == 0: print('The links of Submitted Crash Reports:') for line in self.submitted_stdout.split('\n'): submmited_id = re.sub(r'\.txt\s*$', '', re.sub(r'^.+bp-', '', line)) submitted_url = 'https://crash-stats.mozilla.com/report/index/{}'.format(submmited_id) self.submitted_url_list.append(submitted_url) print(submitted_url)
def _clean_gaia(self): logger.info('Cleaning Gaia profile: Start') command_list = [ 'rm -r /cache/*', 'rm -r /data/b2g/*', 'rm -r /data/local/storage/persistent/*', 'rm -r /data/local/svoperapps', 'rm -r /data/local/webapps', 'rm -r /data/local/user.js', 'rm -r /data/local/permissions.sqlite*', 'rm -r /data/local/OfflineCache', 'rm -r /data/local/indexedDB', 'rm -r /data/local/debug_info_trigger', 'rm -r /system/b2g/webapps' ] for cmd in command_list: AdbWrapper.adb_shell(cmd, serial=self.serial) logger.info('Cleaning Gaia profile: Done')
def _push_gecko(self, source_dir): # push into device logger.info('Pushing Gecko: Start') gecko_dir = os.path.join(source_dir, 'b2g') # push target_path = '/system/b2g/' logger.debug('adb push {} to {}'.format(gecko_dir, target_path)) AdbWrapper.adb_push(gecko_dir, target_path, serial=self.serial) # set excutable source_files = os.listdir(gecko_dir) executable_files = [os.path.join('/system/b2g/', f) for f in source_files if os.access(os.path.join(gecko_dir, f), os.X_OK)] logger.debug('Add executed permission on device: {}'.format(executable_files)) for file in executable_files: AdbWrapper.adb_shell('chmod 777 {}'.format(file), serial=self.serial) logger.info('Pushing Gecko: Done')
def backup_sdcard(self, local_dir, serial=None): """ Backup data from device's SDCard to local folder. @param local_dir: the target local folder, will store data from device's SDCard to this folder. """ logger.info('Backing up SD card...') # try to get the /sdcard folder on device output, retcode = AdbWrapper.adb_shell('ls -d {0}; echo $?'.format( self._REMOTE_DIR_SDCARD), serial=serial) output_list = [ item for item in re.split(r'\n+', re.sub(r'\r+', '', output)) if item ] ret_code = output_list[-1] output_list.remove(output_list[-1]) ret_msg = '\n'.join(output_list) if ret_code == '0': target_dir = os.path.join(local_dir, self._LOCAL_DIR_SDCARD) os.makedirs(target_dir) logger.info('Backup: {0} to {1}'.format(self._REMOTE_DIR_SDCARD, target_dir)) try: AdbWrapper.adb_pull(self._REMOTE_DIR_SDCARD, target_dir, serial=serial) except Exception as e: logger.debug(e) logger.error('Can not pull files from {0} to {1}.'.format( self._REMOTE_DIR_SDCARD, target_dir)) logger.info('Backup SD card done.') else: logger.info(ret_msg)
def final_step(self): if self.gaia and not self.keep_profile: # reset phone when flash gaia and not keep profile logger.info('Reset device after shallow flash the Gaia.') PhoneReseter().reset_phone(serial=self.serial) else: # adb shell reboot logger.info('Reboot device.') AdbWrapper.adb_shell('sync', serial=self.serial) AdbWrapper.adb_shell('reboot', serial=self.serial) # wait for device, and then check version AdbWrapper.adb_wait_for_device(timeout=120) logger.info('Check versions.') checker = VersionChecker() checker.set_serial(self.serial) checker.run()
def _clean_gaia(self): logger.info('Cleaning Gaia profile: Start') command_list = ['rm -r /cache/*', 'rm -r /data/b2g/*', 'rm -r /data/local/storage/persistent/*', 'rm -r /data/local/svoperapps', 'rm -r /data/local/webapps', 'rm -r /data/local/user.js', 'rm -r /data/local/permissions.sqlite*', 'rm -r /data/local/OfflineCache', 'rm -r /data/local/indexedDB', 'rm -r /data/local/debug_info_trigger', 'rm -r /system/b2g/webapps'] for cmd in command_list: AdbWrapper.adb_shell(cmd, serial=self.serial) logger.info('Cleaning Gaia profile: Done')
def final_step(self): if self.gaia and not self.keep_profile: # reset phone when flash gaia and not keep profile logger.info('Reset device after shallow flash the Gaia.') PhoneReseter().reset_phone(serial=self.serial) else: # adb shell reboot logger.info('Reboot device.') AdbWrapper.adb_shell('sync', serial=self.serial) AdbWrapper.adb_shell('reboot', serial=self.serial) # wait for device, and then check version AdbWrapper.adb_wait_for_device(timeout=120) logger.info('Check versions.') checker = VersionChecker() checker.set_serial(self.serial) checker.run()
def get_crashreports(self, serial=None): AdbWrapper.adb_root(serial=serial) logger.info('Getting Crash Reports...') pending, retcode_pending = AdbWrapper.adb_shell('ls -al /data/b2g/mozilla/Crash\ Reports/pending', serial=serial) print('Pending Crash Reports:\n{}\n'.format(pending)) submitted, retcode_submitted = AdbWrapper.adb_shell('ls -al /data/b2g/mozilla/Crash\ Reports/submitted', serial=serial) print('Submitted Crash Reports:\n{}\n'.format(submitted)) if retcode_submitted == 0: print('The links of Submitted Crash Reports:') for line in submitted.split('\n'): submmited_id = re.sub(r'\.txt\s*$', '', re.sub(r'^.+bp-', '', line)) submitted_url = 'https://crash-stats.mozilla.com/report/index/{}'.format(submmited_id) print(submitted_url)
def backup_sdcard(self, local_dir, serial=None): """ Backup data from device's SDCard to local folder. @param local_dir: the target local folder, will store data from device's SDCard to this folder. """ logger.info('Backing up SD card...') # try to get the /sdcard folder on device output, retcode = AdbWrapper.adb_shell('ls -d {0}; echo $?'.format(self._REMOTE_DIR_SDCARD), serial=serial) output_list = [item for item in re.split(r'\n+', re.sub(r'\r+', '', output)) if item] ret_code = output_list[-1] output_list.remove(output_list[-1]) ret_msg = '\n'.join(output_list) if ret_code == '0': target_dir = os.path.join(local_dir, self._LOCAL_DIR_SDCARD) os.makedirs(target_dir) logger.info('Backup: {0} to {1}'.format(self._REMOTE_DIR_SDCARD, target_dir)) try: AdbWrapper.adb_pull(self._REMOTE_DIR_SDCARD, target_dir, serial=serial) except Exception as e: logger.debug(e) logger.error('Can not pull files from {0} to {1}.'.format(self._REMOTE_DIR_SDCARD, target_dir)) logger.info('Backup SD card done.') else: logger.info(ret_msg)
def backup_sdcard(self, local_dir, serial=None): logger.info('Backing up SD card...') # try to get the /sdcard folder on device output, retcode = AdbWrapper.adb_shell('ls -d {0}; echo $?'.format( self._REMOTE_DIR_SDCARD), serial=serial) output_list = [ item for item in re.split(r'\n+', re.sub(r'\r+', '', output)) if item ] ret_code = output_list[-1] output_list.remove(output_list[-1]) ret_msg = '\n'.join(output_list) if ret_code == '0': target_dir = os.path.join(local_dir, self._LOCAL_DIR_SDCARD) os.makedirs(target_dir) logger.info('Backup: {0} to {1}'.format(self._REMOTE_DIR_SDCARD, target_dir)) try: AdbWrapper.adb_pull(self._REMOTE_DIR_SDCARD, target_dir, serial=serial) except: logger.warning('Can not pull files from {0} to {1}'.format( self._REMOTE_DIR_SDCARD, target_dir)) else: logger.info(ret_msg) logger.info('Backup SD card done.')
def set_certapps(self, enable=True, serial=None): AdbWrapper.adb_root(serial=serial) logger.info('{} Full Privilege for WebIDE...'.format('Enabling' if enable else 'Disabling')) need_restart = True try: tmp_dir = tempfile.mkdtemp(prefix='enablecertapps_') # get profile folder name xxx.default under /data/b2g/mozilla/ profile_dir_name, retcode = AdbWrapper.adb_shell('ls /data/b2g/mozilla/ | grep default', serial=serial) device_src_file = os.path.join('/data/b2g/mozilla/', profile_dir_name, 'prefs.js') dest_temp_file = os.path.join(tmp_dir, 'prefs.js.origin') try: logger.info('Pulling prefs.js file...') AdbWrapper.adb_pull(device_src_file, dest_temp_file, serial=serial) except: raise Exception('Error pulling prefs.js file.') dest_file = os.path.join(tmp_dir, 'prefs.js') with open(dest_temp_file, 'r') as fr: with open(dest_file, 'w') as fw: match = False is_forbid = 'false' if enable else 'true' logger.debug('is_forbid: [{}]'.format(is_forbid)) for line in fr: if 'devtools.debugger.forbid-certified-apps' in line: logger.debug('line: [{}] to [{}]'.format(line, is_forbid)) if is_forbid in line: # do not need to restart if the setting isn't changed logger.info('The full privilege is already {}.'.format('enabled' if enable else 'disabled')) need_restart = False break else: logger.info('Changing setting of pref.js file...') fw.write('user_pref("devtools.debugger.forbid-certified-apps", {});\n'.format(is_forbid)) match = True else: fw.write(line) if not match: if not enable: # the forbid is true when there is no setting logger.info('The full privilege is already disabled.') need_restart = False else: if need_restart: # adding setting when there is no setting and need to enable certapps logger.info('Adding setting of pref.js file...') fw.write('user_pref("devtools.debugger.forbid-certified-apps", {});\n'.format(is_forbid)) if need_restart: B2GHelper.stop_b2g(serial=serial) try: logger.info('Pushing prefs.js file...') AdbWrapper.adb_push(dest_file, device_src_file, serial=serial) except: raise Exception('Error pushing prefs.js file.') finally: if need_restart: B2GHelper.start_b2g(serial=serial) shutil.rmtree(tmp_dir)
def reset_phone(self, serial=None): # checking the adb root for backup/restore if not AdbWrapper.adb_root(serial=serial): raise Exception('No root permission for backup and resotre.') # starting to reset logger.info('Starting to Reset Firefox OS Phone...') AdbWrapper.adb_shell('rm -r /cache/*', serial=serial) AdbWrapper.adb_shell('mkdir /cache/recovery', serial=serial) AdbWrapper.adb_shell('echo "--wipe_data" > /cache/recovery/command', serial=serial) AdbWrapper.adb_shell('reboot recovery', serial=serial) logger.info('Reset Firefox OS Phone done.')
def get_crashreports(self, serial=None): AdbWrapper.adb_root(serial=serial) logger.info('Getting Crash Reports...') pending, retcode_pending = AdbWrapper.adb_shell( 'ls -al /data/b2g/mozilla/Crash\ Reports/pending', serial=serial) print('Pending Crash Reports:\n{}\n'.format(pending)) submitted, retcode_submitted = AdbWrapper.adb_shell( 'ls -al /data/b2g/mozilla/Crash\ Reports/submitted', serial=serial) print('Submitted Crash Reports:\n{}\n'.format(submitted)) if retcode_submitted == 0: print('The links of Submitted Crash Reports:') for line in submitted.split('\n'): submmited_id = re.sub(r'\.txt\s*$', '', re.sub(r'^.+bp-', '', line)) submitted_url = 'https://crash-stats.mozilla.com/report/index/{}'.format( submmited_id) print(submitted_url)
def _push_gecko(self, source_dir): # push into device logger.info('Pushing Gecko: Start') gecko_dir = os.path.join(source_dir, 'b2g') # push target_path = '/system/b2g/' logger.debug('adb push {} to {}'.format(gecko_dir, target_path)) AdbWrapper.adb_push(gecko_dir, target_path, serial=self.serial) # set excutable source_files = os.listdir(gecko_dir) executable_files = [ os.path.join('/system/b2g/', f) for f in source_files if os.access(os.path.join(gecko_dir, f), os.X_OK) ] logger.debug( 'Add executed permission on device: {}'.format(executable_files)) for file in executable_files: AdbWrapper.adb_shell('chmod 777 {}'.format(file), serial=self.serial) logger.info('Pushing Gecko: Done')
def _clean_gecko(self, source_dir): logger.info('Cleaning Gecko profile: Start') command_list = ['rm -r /system/media'] for cmd in command_list: AdbWrapper.adb_shell(cmd, serial=self.serial) gecko_dir = os.path.join(source_dir, 'b2g') source_files = os.listdir(gecko_dir) logger.debug('The files which will push into device: {}'.format(source_files)) adb_stdout, adb_retcode = AdbWrapper.adb_shell('ls /system/b2g/') device_files = adb_stdout.split() logger.debug('The files which on device /system/b2g/: {}'.format(device_files)) removed_files = sorted(list(set(source_files + device_files))) removed_files.remove('defaults') removed_files.remove('webapps') logger.debug('Remove files list: {}'.format(removed_files)) for file in removed_files: AdbWrapper.adb_shell('rm -r /system/b2g/{}'.format(file), serial=self.serial) logger.info('Cleaning Gecko profile: Done')
def restore_profile(self, local_dir, serial=None): logger.info('Restoring profile...') if os.path.isdir(local_dir): # Restore Wifi wifi_file = os.path.join(local_dir, self._LOCAL_FILE_WIFI) if os.path.isfile(wifi_file): logger.info('Restoring Wifi information...') try: AdbWrapper.adb_push(wifi_file, self._REMOTE_FILE_WIFI, serial=serial) except: logger.warning('If you don\'t have root permission, you cannot restore Wifi information.') AdbWrapper.adb_shell('chown {0} {1}'.format(self._REMOTE_FILE_WIFI_OWNER, self._REMOTE_FILE_WIFI)) # Restore profile b2g_mozilla_dir = os.path.join(local_dir, self._LOCAL_DIR_B2G) if os.path.isdir(b2g_mozilla_dir): logger.info('Restore from {0} to {1} ...'.format(b2g_mozilla_dir, self._REMOTE_DIR_B2G)) AdbWrapper.adb_shell('rm -r {0}'.format(self._REMOTE_DIR_B2G)) try: AdbWrapper.adb_push(b2g_mozilla_dir, self._REMOTE_DIR_B2G, serial=serial) except: logger.warning('Can not push files from {0} to {1}'.format(b2g_mozilla_dir, self._REMOTE_DIR_B2G)) # Restore data/local datalocal_dir = os.path.join(local_dir, self._LOCAL_DIR_DATA) if os.path.isdir(datalocal_dir): logger.info('Restore from {0} to {1} ...'.format(datalocal_dir, self._REMOTE_DIR_DATA)) AdbWrapper.adb_shell('rm -r {0}'.format(self._REMOTE_DIR_DATA)) try: AdbWrapper.adb_push(datalocal_dir, self._REMOTE_DIR_DATA, serial=serial) except: logger.warning('Can not push files from {0} to {1}'.format(datalocal_dir, self._REMOTE_DIR_DATA)) logger.info('Restore profile done.') else: logger.info('{0}: No such file or directory'.format(local_dir)) return
def _clean_gecko(self, source_dir): logger.info('Cleaning Gecko profile: Start') command_list = ['rm -r /system/media'] for cmd in command_list: AdbWrapper.adb_shell(cmd, serial=self.serial) gecko_dir = os.path.join(source_dir, 'b2g') source_files = os.listdir(gecko_dir) logger.debug( 'The files which will push into device: {}'.format(source_files)) adb_stdout, adb_retcode = AdbWrapper.adb_shell('ls /system/b2g/') device_files = adb_stdout.split() logger.debug( 'The files which on device /system/b2g/: {}'.format(device_files)) removed_files = sorted(list(set(source_files + device_files))) removed_files.remove('defaults') removed_files.remove('webapps') logger.debug('Remove files list: {}'.format(removed_files)) for file in removed_files: AdbWrapper.adb_shell('rm -r /system/b2g/{}'.format(file), serial=self.serial) logger.info('Cleaning Gecko profile: Done')
def get_crashreports(self, serial=None): ''' Print the pending and submitted crash reports on device. The submitted crashs report will be displayed with URL link. @param serial: device serial number. (optional) ''' AdbWrapper.adb_root(serial=serial) logger.info('Getting Crash Reports...') pending, retcode_pending = AdbWrapper.adb_shell('ls -al /data/b2g/mozilla/Crash\ Reports/pending', serial=serial) print('Pending Crash Reports:\n{}\n'.format(pending)) submitted, retcode_submitted = AdbWrapper.adb_shell('ls -al /data/b2g/mozilla/Crash\ Reports/submitted', serial=serial) print('Submitted Crash Reports:\n{}\n'.format(submitted)) if retcode_submitted == 0: print('The links of Submitted Crash Reports:') for line in submitted.split('\n'): submmited_id = re.sub(r'\.txt\s*$', '', re.sub(r'^.+bp-', '', line)) submitted_url = 'https://crash-stats.mozilla.com/report/index/{}'.format(submmited_id) print(submitted_url)
def reset_phone(self, serial=None): ''' Reset the B2G device. @param serial: device serial number. (optional) @raise exception: When no root permission for reset device. ''' # checking the adb root for backup/restore if not AdbWrapper.adb_root(serial=serial): raise Exception('No root permission for reset device.') # starting to reset logger.info('Starting to Reset Firefox OS Phone...') AdbWrapper.adb_shell('rm -r /cache/*', serial=serial) AdbWrapper.adb_shell('mkdir /cache/recovery', serial=serial) AdbWrapper.adb_shell('echo "--wipe_data" > /cache/recovery/command', serial=serial) AdbWrapper.adb_shell('reboot recovery', serial=serial) logger.info('Reset Firefox OS Phone done.')
def reset_phone(serial=None): """ Reset the B2G device. @param serial: device serial number. (optional) @raise exception: When no root permission for reset device. """ # checking the adb root for backup/restore if not AdbWrapper.adb_root(serial=serial): raise Exception('No root permission for reset device.') # starting to reset logger.info('Starting to Reset Firefox OS Phone...') AdbWrapper.adb_shell('rm -r /cache/*', serial=serial) AdbWrapper.adb_shell('mkdir /cache/recovery', serial=serial) AdbWrapper.adb_shell('echo "--wipe_data" > /cache/recovery/command', serial=serial) AdbWrapper.adb_shell('reboot recovery', serial=serial) logger.info('Reset Firefox OS Phone done.')
def restore_profile(self, local_dir, serial=None): """ Restore B2G user profile from local folder to device. @param local_dir: the source local folder, the backup data will restore from this folder. @param serial: device serial number. (optional) """ logger.info('Restoring profile...') if os.path.isdir(local_dir): # Restore Wifi wifi_file = os.path.join(local_dir, self._LOCAL_FILE_WIFI) if os.path.isfile(wifi_file): logger.info('Restoring Wifi information...') try: AdbWrapper.adb_push(wifi_file, self._REMOTE_FILE_WIFI, serial=serial) except Exception as e: logger.debug(e) logger.error( 'If you don\'t have root permission, you cannot restore Wifi information.' ) AdbWrapper.adb_shell('chown {0} {1}'.format( self._REMOTE_FILE_WIFI_OWNER, self._REMOTE_FILE_WIFI)) # Restore profile b2g_mozilla_dir = os.path.join(local_dir, self._LOCAL_DIR_B2G) if os.path.isdir(b2g_mozilla_dir): logger.info('Restore from {0} to {1} ...'.format( b2g_mozilla_dir, self._REMOTE_DIR_B2G)) AdbWrapper.adb_shell('rm -r {0}'.format(self._REMOTE_DIR_B2G)) try: AdbWrapper.adb_push(b2g_mozilla_dir, self._REMOTE_DIR_B2G, serial=serial) except Exception as e: logger.debug(e) logger.error('Can not push files from {0} to {1}'.format( b2g_mozilla_dir, self._REMOTE_DIR_B2G)) # Restore data/local datalocal_dir = os.path.join(local_dir, self._LOCAL_DIR_DATA) if os.path.isdir(datalocal_dir): logger.info('Restore from {0} to {1} ...'.format( datalocal_dir, self._REMOTE_DIR_DATA)) AdbWrapper.adb_shell('rm -r {0}'.format(self._REMOTE_DIR_DATA)) try: AdbWrapper.adb_push(datalocal_dir, self._REMOTE_DIR_DATA, serial=serial) except Exception as e: logger.debug(e) logger.error('Can not push files from {0} to {1}'.format( datalocal_dir, self._REMOTE_DIR_DATA)) logger.info('Restore profile done.') else: logger.info('{0}: No such file or directory'.format(local_dir))
def run(self): """ Entry point. """ self.devices = AdbWrapper.adb_devices() logger.debug("Devices: {}".format(self.devices)) if len(self.devices) < 1: raise Exception("Can not find device, please connect your device.") elif len(self.devices) > 1: raise Exception("Find more than one device, please only connect one device.") # get device name device_name = AdbWrapper.adb_shell("getprop ro.product.device")[0] logger.info("Device found: {}".format(device_name)) if device_name not in self.SUPPORT_DEVICES.keys(): raise Exception("The {} device is not supported.".format(device_name)) # select branch branch = self.select_branch() # select build type postfix = self.select_build() # get namespace and image artifact device_info = self.SUPPORT_DEVICES.get(device_name) namespace = self.NAMESPACE_FORMAT(branch=branch, device=device_info.get("name"), postfix=postfix) artifact = self.ARTIFACT_FORMAT(build_path=self.BUILD_PATH, image=device_info.get("image")) logger.info("Device: {}".format(device_name)) logger.info("Namespace: {}".format(namespace)) logger.info("Artifact: {}".format(artifact)) ret = raw_input( '\nDownload "{artifact}" from "{namespace}".\nRight? [Y/n]'.format(artifact=artifact, namespace=namespace) ) if len(ret) > 0 and ret.lower()[0] == "n": logger.info("Stop.") exit(0) # downloading image logger.info("Downloading image...") local_image = self.download(namespace, artifact) logger.debug("Image file: {}".format(local_image)) # checking file logger.info("Checking file...") if not B2GHelper.check_b2g_image(local_image): raise Exception("This is not B2G image file: {}".format(local_image)) # flashing image logger.info("Flashing image...") self.flash_image(local_image)
def backup_sdcard(self, local_dir, serial=None): logger.info('Backing up SD card...') # try to get the /sdcard folder on device output, retcode = AdbWrapper.adb_shell('ls -d {0}; echo $?'.format(self._REMOTE_DIR_SDCARD), serial=serial) output_list = [item for item in re.split(r'\n+', re.sub(r'\r+', '', output)) if item] ret_code = output_list[-1] output_list.remove(output_list[-1]) ret_msg = '\n'.join(output_list) if ret_code == '0': target_dir = os.path.join(local_dir, self._LOCAL_DIR_SDCARD) os.makedirs(target_dir) logger.info('Backup: {0} to {1}'.format(self._REMOTE_DIR_SDCARD, target_dir)) try: AdbWrapper.adb_pull(self._REMOTE_DIR_SDCARD, target_dir, serial=serial) except: logger.warning('Can not pull files from {0} to {1}'.format(self._REMOTE_DIR_SDCARD, target_dir)) else: logger.info(ret_msg) logger.info('Backup SD card done.')
def restore_profile(self, local_dir, serial=None): logger.info('Restoring profile...') if os.path.isdir(local_dir): # Restore Wifi wifi_file = os.path.join(local_dir, self._LOCAL_FILE_WIFI) if os.path.isfile(wifi_file): logger.info('Restoring Wifi information...') try: AdbWrapper.adb_push(wifi_file, self._REMOTE_FILE_WIFI, serial=serial) except: logger.warning( 'If you don\'t have root permission, you cannot restore Wifi information.' ) AdbWrapper.adb_shell('chown {0} {1}'.format( self._REMOTE_FILE_WIFI_OWNER, self._REMOTE_FILE_WIFI)) # Restore profile b2g_mozilla_dir = os.path.join(local_dir, self._LOCAL_DIR_B2G) if os.path.isdir(b2g_mozilla_dir): logger.info('Restore from {0} to {1} ...'.format( b2g_mozilla_dir, self._REMOTE_DIR_B2G)) AdbWrapper.adb_shell('rm -r {0}'.format(self._REMOTE_DIR_B2G)) try: AdbWrapper.adb_push(b2g_mozilla_dir, self._REMOTE_DIR_B2G, serial=serial) except: logger.warning('Can not push files from {0} to {1}'.format( b2g_mozilla_dir, self._REMOTE_DIR_B2G)) # Restore data/local datalocal_dir = os.path.join(local_dir, self._LOCAL_DIR_DATA) if os.path.isdir(datalocal_dir): logger.info('Restore from {0} to {1} ...'.format( datalocal_dir, self._REMOTE_DIR_DATA)) AdbWrapper.adb_shell('rm -r {0}'.format(self._REMOTE_DIR_DATA)) try: AdbWrapper.adb_push(datalocal_dir, self._REMOTE_DIR_DATA, serial=serial) except: logger.warning('Can not push files from {0} to {1}'.format( datalocal_dir, self._REMOTE_DIR_DATA)) logger.info('Restore profile done.') else: logger.info('{0}: No such file or directory'.format(local_dir)) return
def restore_profile(self, local_dir, serial=None): """ Restore B2G user profile from local folder to device. @param local_dir: the source local folder, the backup data will restore from this folder. @param serial: device serial number. (optional) """ logger.info('Restoring profile...') if os.path.isdir(local_dir): # Restore Wifi wifi_file = os.path.join(local_dir, self._LOCAL_FILE_WIFI) if os.path.isfile(wifi_file): logger.info('Restoring Wifi information...') try: AdbWrapper.adb_push(wifi_file, self._REMOTE_FILE_WIFI, serial=serial) except Exception as e: logger.debug(e) logger.error('If you don\'t have root permission, you cannot restore Wifi information.') AdbWrapper.adb_shell('chown {0} {1}'.format(self._REMOTE_FILE_WIFI_OWNER, self._REMOTE_FILE_WIFI)) # Restore profile b2g_mozilla_dir = os.path.join(local_dir, self._LOCAL_DIR_B2G) if os.path.isdir(b2g_mozilla_dir): logger.info('Restore from {0} to {1} ...'.format(b2g_mozilla_dir, self._REMOTE_DIR_B2G)) AdbWrapper.adb_shell('rm -r {0}'.format(self._REMOTE_DIR_B2G)) try: AdbWrapper.adb_push(b2g_mozilla_dir, self._REMOTE_DIR_B2G, serial=serial) except Exception as e: logger.debug(e) logger.error('Can not push files from {0} to {1}'.format(b2g_mozilla_dir, self._REMOTE_DIR_B2G)) # Restore data/local datalocal_dir = os.path.join(local_dir, self._LOCAL_DIR_DATA) if os.path.isdir(datalocal_dir): logger.info('Restore from {0} to {1} ...'.format(datalocal_dir, self._REMOTE_DIR_DATA)) AdbWrapper.adb_shell('rm -r {0}'.format(self._REMOTE_DIR_DATA)) try: AdbWrapper.adb_push(datalocal_dir, self._REMOTE_DIR_DATA, serial=serial) except Exception as e: logger.debug(e) logger.error('Can not push files from {0} to {1}'.format(datalocal_dir, self._REMOTE_DIR_DATA)) logger.info('Restore profile done.') else: logger.info('{0}: No such file or directory'.format(local_dir))
def get_device_info(self, serial=None): """ Get the device information, include Gaia Version, Gecko Version, and so on. @param serial: device serial number. (optional) @return: the information dict object. """ try: tmp_dir = tempfile.mkdtemp(prefix="checkversions_") # pull data from device try: AdbWrapper.adb_pull("/system/b2g/omni.ja", tmp_dir, serial=serial) except: logger.error("Error pulling Gecko file.") try: AdbWrapper.adb_pull( "/data/local/webapps/settings.gaiamobile.org/application.zip", tmp_dir, serial=serial ) except: try: AdbWrapper.adb_pull( "/system/b2g/webapps/settings.gaiamobile.org/application.zip", tmp_dir, serial=serial ) except: logger.error("Error pulling Gaia file.") try: AdbWrapper.adb_pull("/system/b2g/application.ini", tmp_dir, serial=serial) except: logger.error("Error pulling application.ini file.") # get Gaia info gaia_rev = "n/a" gaia_date = "n/a" application_zip_file = os.path.join(tmp_dir, "application.zip") if os.path.isfile(application_zip_file): with open(application_zip_file, "rb") as f: z = zipfile.ZipFile(f) z.extract("resources/gaia_commit.txt", tmp_dir) else: logger.warning("Can not find application.zip file.") gaiacommit_file = os.path.join(tmp_dir, "resources/gaia_commit.txt") if os.path.isfile(gaiacommit_file): with open(gaiacommit_file, "r") as f: gaia_rev = re.sub(r"\n+", "", f.readline()) gaia_date_sec_from_epoch = re.sub(r"\n+", "", f.readline()) gaia_date = datetime.utcfromtimestamp(int(gaia_date_sec_from_epoch)).strftime("%Y-%m-%d %H:%M:%S") else: logger.warning("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(os.path.join(tmp_dir, "omni.ja")): deopt_dir = os.path.join(tmp_dir, "deopt") deopt_file = os.path.join(deopt_dir, "omni.ja") deopt_exec = os.path.join(tmp_dir, "optimizejars.py") os.makedirs(deopt_dir) # TODO rewrite optimizejars.py if possible current_dir = cur = os.path.dirname(os.path.abspath(__file__)) current_exec = os.path.join(current_dir, "misc", "optimizejars.py") shutil.copyfile(current_exec, 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): with open(deopt_file, "rb") as f: z = zipfile.ZipFile(f) z.extract("chrome/toolkit/content/global/buildconfig.html", tmp_dir) else: logger.warning("Can not deoptimize omni.ja file.") gecko_rev = "n/a" # get Gecko info from buildconfig.html file buildconfig_file = os.path.join(tmp_dir, "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: logger.warning("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(os.path.join(tmp_dir, "application.ini")): for line in open(os.path.join(tmp_dir, "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+", "", AdbWrapper.adb_shell("getprop ro.product.device", serial=serial)[0]) firmware_release = re.sub( r"\r+|\n+", "", AdbWrapper.adb_shell("getprop ro.build.version.release", serial=serial)[0] ) firmware_incremental = re.sub( r"\r+|\n+", "", AdbWrapper.adb_shell("getprop ro.build.version.incremental", serial=serial)[0] ) firmware_date = re.sub(r"\r+|\n+", "", AdbWrapper.adb_shell("getprop ro.build.date", serial=serial)[0]) firmware_bootloader = re.sub( r"\r+|\n+", "", AdbWrapper.adb_shell("getprop ro.boot.bootloader", serial=serial)[0] ) # 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 get_device_info(self, serial=None): ''' Get the device information, include Gaia Version, Gecko Version, and so on. @param serial: device serial number. (optional) @return: the information dict object. ''' try: tmp_dir = tempfile.mkdtemp(prefix='checkversions_') # pull data from device try: AdbWrapper.adb_pull('/system/b2g/omni.ja', tmp_dir, serial=serial) except: logger.error('Error pulling Gecko file.') try: AdbWrapper.adb_pull( '/data/local/webapps/settings.gaiamobile.org/application.zip', tmp_dir, serial=serial) except: try: AdbWrapper.adb_pull( '/system/b2g/webapps/settings.gaiamobile.org/application.zip', tmp_dir, serial=serial) except: logger.error('Error pulling Gaia file.') try: AdbWrapper.adb_pull('/system/b2g/application.ini', tmp_dir, serial=serial) except: logger.error('Error pulling application.ini file.') # get Gaia info gaia_rev = 'n/a' gaia_date = 'n/a' application_zip_file = os.path.join(tmp_dir, 'application.zip') if os.path.isfile(application_zip_file): with open(application_zip_file, 'rb') as f: z = zipfile.ZipFile(f) z.extract('resources/gaia_commit.txt', tmp_dir) else: logger.warning('Can not find application.zip file.') gaiacommit_file = os.path.join(tmp_dir, 'resources/gaia_commit.txt') if os.path.isfile(gaiacommit_file): with open(gaiacommit_file, "r") as f: gaia_rev = re.sub(r'\n+', '', f.readline()) gaia_date_sec_from_epoch = re.sub(r'\n+', '', f.readline()) gaia_date = datetime.utcfromtimestamp( int(gaia_date_sec_from_epoch)).strftime( '%Y-%m-%d %H:%M:%S') else: logger.warning( '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(os.path.join(tmp_dir, 'omni.ja')): deopt_dir = os.path.join(tmp_dir, 'deopt') deopt_file = os.path.join(deopt_dir, 'omni.ja') deopt_exec = os.path.join(tmp_dir, 'optimizejars.py') os.makedirs(deopt_dir) # TODO rewrite optimizejars.py if possible current_dir = cur = os.path.dirname(os.path.abspath(__file__)) current_exec = os.path.join(current_dir, 'misc', 'optimizejars.py') shutil.copyfile(current_exec, 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): with open(deopt_file, 'rb') as f: z = zipfile.ZipFile(f) z.extract( 'chrome/toolkit/content/global/buildconfig.html', tmp_dir) else: logger.warning('Can not deoptimize omni.ja file.') gecko_rev = 'n/a' # get Gecko info from buildconfig.html file buildconfig_file = os.path.join( tmp_dir, '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: logger.warning( '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(os.path.join(tmp_dir, 'application.ini')): for line in open(os.path.join(tmp_dir, '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+', '', AdbWrapper.adb_shell('getprop ro.product.device', serial=serial)[0]) firmware_release = re.sub( r'\r+|\n+', '', AdbWrapper.adb_shell('getprop ro.build.version.release', serial=serial)[0]) firmware_incremental = re.sub( r'\r+|\n+', '', AdbWrapper.adb_shell('getprop ro.build.version.incremental', serial=serial)[0]) firmware_date = re.sub( r'\r+|\n+', '', AdbWrapper.adb_shell('getprop ro.build.date', serial=serial)[0]) firmware_bootloader = re.sub( r'\r+|\n+', '', AdbWrapper.adb_shell('getprop ro.boot.bootloader', serial=serial)[0]) # 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 get_device_info(serial=None): """ Get the device information, include Gaia Version, Gecko Version, and so on. @param serial: device serial number. (optional) @return: the information dict object. """ tmp_dir = None try: tmp_dir = tempfile.mkdtemp(prefix='checkversions_') # pull data from device try: AdbWrapper.adb_pull('/system/b2g/omni.ja', tmp_dir, serial=serial) except Exception as e: logger.debug(e) logger.error('Error pulling Gecko file.') try: AdbWrapper.adb_pull('/data/local/webapps/settings.gaiamobile.org/application.zip', tmp_dir, serial=serial) except Exception as e: logger.debug(e) try: AdbWrapper.adb_pull('/system/b2g/webapps/settings.gaiamobile.org/application.zip', tmp_dir, serial=serial) except Exception as e: logger.debug(e) logger.error('Error pulling Gaia file.') try: AdbWrapper.adb_pull('/system/b2g/application.ini', tmp_dir, serial=serial) except Exception as e: logger.debug(e) logger.error('Error pulling application.ini file.') # get Gaia info gaia_rev = 'n/a' gaia_date = 'n/a' application_zip_file = os.path.join(tmp_dir, 'application.zip') if os.path.isfile(application_zip_file): with open(application_zip_file, 'rb') as f: z = zipfile.ZipFile(f) z.extract('resources/gaia_commit.txt', tmp_dir) else: logger.warning('Can not find application.zip file.') gaiacommit_file = os.path.join(tmp_dir, 'resources/gaia_commit.txt') if os.path.isfile(gaiacommit_file): with open(gaiacommit_file, "r") as f: gaia_rev = re.sub(r'\n+', '', f.readline()) gaia_date_sec_from_epoch = re.sub(r'\n+', '', f.readline()) gaia_date = datetime.utcfromtimestamp(int(gaia_date_sec_from_epoch)).strftime('%Y-%m-%d %H:%M:%S') else: logger.warning('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(os.path.join(tmp_dir, 'omni.ja')): deopt_dir = os.path.join(tmp_dir, 'deopt') deopt_file = os.path.join(deopt_dir, 'omni.ja') deopt_exec = os.path.join(tmp_dir, 'optimizejars.py') os.makedirs(deopt_dir) # TODO rewrite optimizejars.py if possible current_dir = os.path.dirname(os.path.abspath(__file__)) current_exec = os.path.join(current_dir, 'misc', 'optimizejars.py') shutil.copyfile(current_exec, 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] logger.debug('optimizejars.py stdout: {}'.format(output)) # unzip omni.ja to get Gecko info if os.path.isfile(deopt_file): with open(deopt_file, 'rb') as f: z = zipfile.ZipFile(f) z.extract('chrome/toolkit/content/global/buildconfig.html', tmp_dir) else: logger.warning('Can not deoptimize omni.ja file.') gecko_rev = 'n/a' # get Gecko info from buildconfig.html file buildconfig_file = os.path.join(tmp_dir, '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: logger.warning('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 build_id = 0 version = 0 if os.path.isfile(os.path.join(tmp_dir, 'application.ini')): for line in open(os.path.join(tmp_dir, '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+', '', AdbWrapper.adb_shell('getprop ro.product.device', serial=serial)[0]) firmware_release = re.sub(r'\r+|\n+', '', AdbWrapper.adb_shell('getprop ro.build.version.release', serial=serial)[0]) firmware_incremental = re.sub(r'\r+|\n+', '', AdbWrapper.adb_shell('getprop ro.build.version.incremental', serial=serial)[ 0]) firmware_date = re.sub(r'\r+|\n+', '', AdbWrapper.adb_shell('getprop ro.build.date', serial=serial)[0]) firmware_bootloader = re.sub(r'\r+|\n+', '', AdbWrapper.adb_shell('getprop ro.boot.bootloader', serial=serial)[0]) # prepare the return information device_info = {'Serial': serial, 'Build ID': build_id, 'Gaia Revision': gaia_rev, 'Gaia Date': gaia_date, 'Gecko Revision': gecko_rev, 'Gecko Version': version, 'Device Name': device_name, 'Firmware(Release)': firmware_release, 'Firmware(Incremental)': firmware_incremental, 'Firmware Date': firmware_date, 'Bootloader': firmware_bootloader} finally: if tmp_dir: shutil.rmtree(tmp_dir) logger.debug('Remove {}.'.format(tmp_dir)) return device_info
def set_certapps(self, enable=True, serial=None): ''' Set the devtools permission for certapps. @param enable: True will turn on the permission. False will turn off the permission. @param serial: device serial number. (optional) @raise exception: When it cannot pulling/pushing the pref.js file of device. ''' AdbWrapper.adb_root(serial=serial) logger.info('{} Full Privilege for WebIDE...'.format( 'Enabling' if enable else 'Disabling')) need_restart = True try: tmp_dir = tempfile.mkdtemp(prefix='enablecertapps_') # get profile folder name xxx.default under /data/b2g/mozilla/ profile_dir_name, retcode = AdbWrapper.adb_shell( 'ls /data/b2g/mozilla/ | grep default', serial=serial) device_src_file = os.path.join('/data/b2g/mozilla/', profile_dir_name, 'prefs.js') dest_temp_file = os.path.join(tmp_dir, 'prefs.js.origin') try: logger.info('Pulling prefs.js file...') AdbWrapper.adb_pull(device_src_file, dest_temp_file, serial=serial) except: raise Exception('Error pulling prefs.js file.') dest_file = os.path.join(tmp_dir, 'prefs.js') with open(dest_temp_file, 'r') as fr: with open(dest_file, 'w') as fw: match = False is_forbid = 'false' if enable else 'true' logger.debug('is_forbid: [{}]'.format(is_forbid)) for line in fr: if 'devtools.debugger.forbid-certified-apps' in line: logger.debug('line: [{}] to [{}]'.format( line, is_forbid)) if is_forbid in line: # do not need to restart if the setting isn't changed logger.info( 'The full privilege is already {}.'.format( 'enabled' if enable else 'disabled')) need_restart = False break else: logger.info( 'Changing setting of pref.js file...') fw.write( 'user_pref("devtools.debugger.forbid-certified-apps", {});\n' .format(is_forbid)) match = True else: fw.write(line) if not match: if not enable: # the forbid is true when there is no setting logger.info( 'The full privilege is already disabled.') need_restart = False else: if need_restart: # adding setting when there is no setting and need to enable certapps logger.info( 'Adding setting of pref.js file...') fw.write( 'user_pref("devtools.debugger.forbid-certified-apps", {});\n' .format(is_forbid)) if need_restart: B2GHelper.stop_b2g(serial=serial) try: logger.info('Pushing prefs.js file...') AdbWrapper.adb_push(dest_file, device_src_file, serial=serial) except: raise Exception('Error pushing prefs.js file.') finally: if need_restart: B2GHelper.start_b2g(serial=serial) shutil.rmtree(tmp_dir)