def _fail_with_python2_warning(): msg = ( 'You are using Python 2\nADB-enhanced no longer supports Python 2.\n' + 'Install Python 3 and then re-install this tool using\n' + '\"sudo pip uninstall adb-enhanced && sudo pip3 install adb-enhanced\"' ) print_error_and_exit(msg)
def list_others(self): cmd = '%s --verbose --list --include_obsolete' % self._get_sdk_manager_path() return_code, stdout, stderr = PlatformHelper.execute_cmd(cmd) if return_code != 0: print_error_and_exit('Failed to list packages') print('Installed Packages:') lines = stdout.split('\n') for (i, line) in enumerate(lines): line = line.strip() previous_line = None if i > 0: previous_line = lines[i - 1].strip() is_package_name = not previous_line or previous_line.startswith('---') if not is_package_name: continue print_verbose('Line is \"%s\" and previous line is \"%s\"' % (line, previous_line)) if not line: continue elif line.startswith('system-images;') or line.startswith('platforms;') or line.startswith('sources;'): continue elif line.startswith('platform-tools'): continue elif line.startswith('build-tools;'): continue elif line.find('Info:') != -1: continue if line.endswith(':'): print('') print(line)
def _get_binary(binary_name, binary_paths_relative_to_android_sdk) -> str: sdk_location = AndroidSdkHelper._get_location_of_android_sdk() if not sdk_location: print_verbose('ANDROID_SDK_ROOT not defined') else: for relative_path in binary_paths_relative_to_android_sdk: binary_path = os.path.join(sdk_location, relative_path) if os.path.exists(binary_path): print_error('\"%s\" found at \"%s\"' % (binary_name, binary_path)) return binary_path else: print_error('\"%s\" not found at \"%s\"' % (binary_name, binary_path)) # Only works on Mac and GNU/Linux if PlatformHelper.on_linux() or PlatformHelper.on_mac(): return_code, stdout, stderr = PlatformHelper.execute_cmd( 'command -v %s' % binary_name) if return_code == 0: return stdout.strip() else: print_error('\"%s\" not in path' % binary_name) print_error_and_exit( 'Set ANDROID_SDK_ROOT environment variable to point to Android SDK root' )
def run_doctor(self) -> None: print_message('Checking java version...') self._ensure_correct_java_version() print_message('Checking SDK manager is installed...') self._ensure_sdkmanager_is_installed() print_message('Checking that basic Android packages are installed...') if not self._ensure_basic_packages_are_installed(): print_error_and_exit('Not all basic packages are installed')
def validate_options(args): count = 0 if args['--emulator']: count += 1 if args['--device']: count += 1 if args['--serial']: count += 1 if count > 1: print_error_and_exit('Only one out of -e, -d, or -s can be provided')
def _accept_all_licenses(self): cmd = 'yes | %s --licenses' % self._get_sdk_manager_path() return_code, stdout, stderr = PlatformHelper.execute_cmd(cmd) if return_code != 0: print_error_and_exit('Failed to accept licenses, return code: %d' % return_code) license_regex = '([0-9]*) of ([0-9]*) SDK package licenses not accepted' result = re.search(license_regex, stdout) if result is None: print_message('All licenses accepted') else: print_message('%d of %d licenses accepted' % (int(result.group(1)), int(result.group(2))))
def _get_build_tools(self) -> [str]: """ :return: List of build tools packages, sorted by version number, latest package comes last """ cmd = '%s --verbose --list --include_obsolete' % self._get_sdk_manager_path() return_code, stdout, stderr = PlatformHelper.execute_cmd(cmd) if return_code != 0: print_error_and_exit('Failed to list build tools, stdout: %s, stderr: %s' % (stdout, stderr)) build_tools = re.findall(_BUILD_TOOLS_REGEX, stdout) build_tools = sorted(set(build_tools)) print_verbose('Build tools are %s' % build_tools) return build_tools
def list_avds(self): avd_manager = self._get_avd_manager_path() if not avd_manager: print_error_and_exit('avdmanager not found') cmd = '%s --verbose list avd' % avd_manager return_code, stdout, stderr = PlatformHelper.execute_cmd(cmd) if return_code != 0: print_error_and_exit('Failed to execute avdmanager') start = stdout.find('Virtual Devices') if start != -1: stdout = stdout[start:] print(stdout)
def list_packages(self, arch=None, api_type=None) -> None: print_verbose('List packages(arch: %s, api_type: %s)' % (arch, api_type)) if api_type is None: google_api_type = '.*?' else: google_api_type = api_type if arch is None: arch_pattern = '.*?' else: arch_pattern = arch + '.*?' regex_pattern = 'system-images;android-([0-9]+);(%s);(%s)\n' % ( google_api_type, arch_pattern) print_verbose('Package pattern: %s' % regex_pattern) return_code, stdout, stderr = PlatformHelper.execute_cmd( '%s --verbose --list --include_obsolete' % self._get_sdk_manager_path()) if return_code != 0: print_error_and_exit('Failed to list packages (return code: %d)' % return_code) system_images = re.findall(regex_pattern, stdout) arch_to_android_version_map = {} for system_image in system_images: android_api_version = system_image[0] google_api_type = system_image[1] arch = system_image[2] if google_api_type not in arch_to_android_version_map: arch_to_android_version_map[google_api_type] = {} if arch not in arch_to_android_version_map[google_api_type]: arch_to_android_version_map[google_api_type][arch] = [] arch_to_android_version_map[google_api_type][arch].append( android_api_version) for (google_api_type, architectures) in arch_to_android_version_map.items(): if google_api_type == 'default': print( 'Google API type: default (Standard Android image; no Google API)' ) else: print('Google API type: %s' % google_api_type) for architecture in architectures: android_api_versions = arch_to_android_version_map[ google_api_type][architecture] print('%s -> %s' % (architecture, ', '.join(android_api_versions))) print()
def install_api_version(self, version, arch=None, api_type=None) -> None: platform_package = self._get_platform_package(version) sources_package = self._get_sources_package(version) addons_package = self._get_add_ons_package(version, api_type) system_images_package = self._get_system_images_package(version, arch, api_type) package_list = list() package_list.append(platform_package) if sources_package: package_list.append(sources_package) if addons_package: package_list.append(addons_package) if system_images_package: package_list.append(system_images_package) if not self._install_sdk_packages(package_list): print_error_and_exit('Failed to install packages for api version: %s' % version)
def main(): args = docopt.docopt(_USAGE_STRING, version=_get_version()) verbose_mode = args['--verbose'] output_helper.set_verbose(verbose_mode) androide = android_enhanced.AndroidEnhanced() if args['doctor']: androide.run_doctor() elif args['list'] and args['api'] and args['versions']: arch = get_architecture(args) api_type = get_api_type(args) androide.list_packages(arch, api_type) elif args['install'] and args['version']: arch = get_architecture(args) api_type = get_api_type(args) if api_type is None: api_type = 'default' if arch is None: arch = 'x86' version = args['<android-api-version>'] androide.install_api_version(version, arch, api_type) elif args['list'] and args['build'] and args['tools']: androide.list_build_tools() elif args['list'] and args['other'] and args['packages']: androide.list_others() elif args['list'] and args['installed'] and args['packages']: androide.list_installed_packages() elif args['update'] and args['all']: androide.update_all() elif args['install'] and args['basic'] and args['packages']: androide.install_basic_packages() elif args['list'] and args['avds']: androide.list_avds() elif args['create'] and args['avd']: name = args['<avd-name>'] api_version = args['<android-api-version>'] api_type = get_api_type(args) arch = get_architecture(args) androide.create_avd(name, api_version, arch, api_type) elif args['start'] and args['avd']: # To be implemented name = args['<avd-name>'] headless_mode = args['--headless'] androide.start_avd(name, headless_mode, verbose_mode) else: output_helper.print_error_and_exit('Not implemented: "%s"' % ' '.join(sys.argv))
def update_all(self): cmd = '%s --update' % self._get_sdk_manager_path() return_code, stdout, stderr = PlatformHelper.execute_cmd(cmd) if return_code != 0: print_error_and_exit('Failed to update, return code: %d' % return_code) count = 0 if stdout: for line in stdout.split('\r'): if line.find('Fetch remote repository'): continue else: count += 1 if count == 0: print_message('No packages to update') self._accept_all_licenses() else: print_message(stdout)
def create_avd(self, avd_name, api_version, arch, api_type): if api_type is None: api_type = 'google_apis' # Preferred if arch is None: if PlatformHelper.is_64bit_architecture(): arch = 'x86_64' else: arch = 'x86' package_name = AndroidEnhanced._get_system_images_package(api_version, arch, api_type) print_verbose('Package is %s' % package_name) self.install_api_version(api_version, arch=arch, api_type=api_type) # Say no to custom hardware profile. print_message('Creating AVD "%s" of type "%s" ' % (avd_name, package_name)) create_cmd = 'echo no | %s --verbose create avd --name %s --package "%s"' % ( self._get_avd_manager_path(), avd_name, package_name) return_code, stdout, stderr = PlatformHelper.execute_cmd(create_cmd) if return_code != 0: print_error('Failed to create AVD') print_error('stdout: %s' % stdout) print_error_and_exit('stderr: %s' % stderr) print_message('AVD \"%s\" created successfully' % avd_name)
def _get_basic_packages(self) -> [str]: build_tools = self._get_build_tools() if not build_tools: print_error_and_exit('Build tools list is empty, this is unexpected') latest_build_package = build_tools[-1] print_verbose('Latest build package is \"%s\"' % latest_build_package) packages_to_install = [ latest_build_package, 'emulator', 'tools', 'platform-tools', 'extras;android;m2repository', 'extras;google;m2repository', 'patcher;v4', ] # HAXM is not required on Linux. It is required on Windows and OSX. # I am assuming that this tool will never run on anything except Windows and OSX. # I don't know whether HAXM is required on BSD or not. if not PlatformHelper.on_linux(): packages_to_install.append('extras;intel;Hardware_Accelerated_Execution_Manager') return packages_to_install
def _ensure_correct_java_version(): default_java_version = AndroidEnhanced._get_default_java_version() if default_java_version is None: print_error_and_exit( 'Java is not installed. Install Java for Android via %s' % _JAVA8_INSTALL_COMMAND_FOR_MAC) if default_java_version != _JAVA_VERSION_FOR_ANDROID: all_java_versions = AndroidEnhanced._get_all_java_versions() if _JAVA_VERSION_FOR_ANDROID in all_java_versions: print_error_and_exit( 'Java version %s is installed but default is set to Java %s.\n' 'Set the correct java version via "%s"' % (_JAVA_VERSION_FOR_ANDROID, default_java_version, _SET_JAVA8_AS_DEFAULT_ON_MAC)) else: print_error_and_exit( 'Java version is %s, Android needs Java %s.\n' 'On Mac install it with "%s"\nAnd then set default version' 'via "%s"' % (default_java_version, _JAVA_VERSION_FOR_ANDROID, _JAVA8_INSTALL_COMMAND_FOR_MAC, _SET_JAVA8_AS_DEFAULT_ON_MAC)) else: print_message('Correct Java version %s is installed' % default_java_version)
def _ensure_sdkmanager_is_installed(self): if not self._get_sdk_manager_path(): print_error_and_exit('sdkamanger not found, is Android SDK installed?')
def install_basic_packages(self): packages_to_install = self._get_basic_packages() if not self._install_sdk_packages(packages_to_install): print_error_and_exit('Failed to install basic packages')
def main(): if _using_python2(): _fail_with_python2_warning() args = docopt.docopt(USAGE_STRING, version=get_version()) set_verbose(args['--verbose']) validate_options(args) options = get_generic_options_from_args(args) if options: adb_prefix = '%s %s' % (adb_helper.get_adb_prefix(), options) adb_helper.set_adb_prefix(adb_prefix) # rotate if args['rotate'] and args['portrait']: adb_enhanced.handle_rotate('portrait') elif args['rotate'] and args['landscape']: adb_enhanced.handle_rotate('landscape') elif args['rotate'] and args['left']: adb_enhanced.handle_rotate('left') elif args['rotate'] and args['right']: adb_enhanced.handle_rotate('right') # gfx elif args['gfx'] and args['on']: adb_enhanced.handle_gfx('on') elif args['gfx'] and args['off']: adb_enhanced.handle_gfx('off') elif args['gfx'] and args['lines']: adb_enhanced.handle_gfx('lines') # overdraw elif args['overdraw'] and args['on']: adb_enhanced.handle_overdraw('on') elif args['overdraw'] and args['off']: adb_enhanced.handle_overdraw('off') elif args['overdraw'] and args['deut']: adb_enhanced.handle_overdraw('deut') elif args['layout']: adb_enhanced.handle_layout(args['on']) elif args['airplane']: # This command does not always work adb_enhanced.handle_airplane(args['on']) # battery elif args['battery'] and args['saver']: current_state = adb_enhanced.get_battery_saver_state() adb_enhanced.handle_battery_saver(args['on']) new_state = adb_enhanced.get_battery_saver_state() print_state_change_info('Battery saver', current_state, new_state) elif args['battery'] and args['level']: adb_enhanced.handle_battery_level(int(args['<percentage>'])) elif args['battery'] and args['reset']: adb_enhanced.handle_battery_reset() elif args['doze']: adb_enhanced.handle_doze(args['on']) elif args['jank']: adb_enhanced.handle_get_jank(args['<app_name>']) elif args['devices']: adb_enhanced.handle_list_devices() elif args['top-activity']: adb_enhanced.print_top_activity() elif args['dump-ui']: adb_enhanced.dump_ui(args['<xml_file>']) elif args['force-stop']: app_name = args['<app_name>'] adb_enhanced.force_stop(app_name) elif args['clear-data']: app_name = args['<app_name>'] adb_enhanced.clear_disk_data(app_name) # mobile-data elif args['mobile-data'] and args['saver']: current_state = adb_enhanced.get_mobile_data_saver_state() adb_enhanced.handle_mobile_data_saver(args['on']) new_state = adb_enhanced.get_mobile_data_saver_state() print_state_change_info('Mobile data saver', current_state, new_state) elif args['mobile-data']: current_state = adb_enhanced.get_mobile_data_state() adb_enhanced.handle_mobile_data(args['on']) # sleep before getting the new value or you will get a stale value time.sleep(1) new_state = adb_enhanced.get_mobile_data_state() print_state_change_info('Mobile data', current_state, new_state) elif args['wifi']: current_state = adb_enhanced.get_wifi_state() adb_enhanced.set_wifi(args['on']) new_state = adb_enhanced.get_wifi_state() print_state_change_info('Wi-Fi', current_state, new_state) elif args['rtl']: # This is not working as expected adb_enhanced.force_rtl(args['on']) elif args['screenshot']: adb_enhanced.dump_screenshot(args['<filename.png>']) elif args['screenrecord']: adb_enhanced.dump_screenrecord(args['<filename.mp4>']) elif args['dont-keep-activities']: current_state = adb_enhanced.get_dont_keep_activities_in_background_state( ) adb_enhanced.handle_dont_keep_activities_in_background(args['on']) new_state = adb_enhanced.get_dont_keep_activities_in_background_state() print_state_change_info('Don\'t keep activities', current_state, new_state) elif args['animations']: adb_enhanced.toggle_animations(args['on']) elif args['show-taps']: current_state = adb_enhanced.get_show_taps_state() adb_enhanced.toggle_show_taps(args['on']) new_state = adb_enhanced.get_show_taps_state() print_state_change_info('Show user taps', current_state, new_state) elif args['stay-awake-while-charging']: current_state = adb_enhanced.get_stay_awake_while_charging_state() # Keep screen on while the device is charging. adb_enhanced.stay_awake_while_charging(args['on']) new_state = adb_enhanced.get_stay_awake_while_charging_state() print_state_change_info('Stay awake while charging', current_state, new_state) elif args['input-text']: adb_enhanced.input_text(args['<text>']) elif args['back']: adb_enhanced.press_back() elif args['open-url']: url = args['<url>'] adb_enhanced.open_url(url) elif args['permission-groups'] and args['list'] and args['all']: adb_enhanced.list_permission_groups() elif args['permissions'] and args['list']: adb_enhanced.list_permissions(args['dangerous']) elif args['permissions']: app_name = args['<app_name>'] permission_group = adb_enhanced.get_permission_group(args) permissions = adb_enhanced.get_permissions_in_permission_group( permission_group) if not permissions: print_error_and_exit( 'No permissions found in permissions group: %s' % permission_group) adb_enhanced.grant_or_revoke_runtime_permissions( app_name, args['grant'], permissions) # apps list elif args['apps'] and args['list'] and args['all']: adb_enhanced.list_all_apps() elif args['apps'] and args['list'] and args['system']: adb_enhanced.list_system_apps() elif args['apps'] and args['list'] and args['third-party']: adb_enhanced.list_non_system_apps() elif args['apps'] and args['list'] and args['debug']: adb_enhanced.list_debug_apps() elif args['apps'] and args['list'] and args['backup-enabled']: adb_enhanced.list_allow_backup_apps() # standby bucket elif args['standby-bucket'] and args['get']: adb_enhanced.get_standby_bucket(args['<app_name>']) elif args['standby-bucket'] and args['set']: adb_enhanced.set_standby_bucket( args['<app_name>'], adb_enhanced.calculate_standby_mode(args)) elif args['restrict-background']: adb_enhanced.apply_or_remove_background_restriction( args['<app_name>'], args['true']) elif args['ls']: file_path = args['<file_path>'] long_format = args['-l'] # Always include hidden files, -a is left for backward-compatibility but is a no-op now. include_hidden_files = True recursive = args['-R'] or args['-r'] adb_enhanced.list_directory(file_path, long_format, recursive, include_hidden_files) elif args['rm']: file_path = args['<file_path>'] force_delete = args['-f'] recursive = args['-R'] or args['-r'] adb_enhanced.delete_file(file_path, force_delete, recursive) elif args['mv']: src_path = args['<src_path>'] dest_path = args['<dest_path>'] force_move = args['-f'] adb_enhanced.move_file(src_path, dest_path, force_move) elif args['pull']: remote_file_path = args['<file_path_on_android>'] local_file_path = args['<file_path_on_machine>'] copy_ancillary = args['-a'] adb_enhanced.pull_file(remote_file_path, local_file_path, copy_ancillary) elif args['push']: remote_file_path = args['<file_path_on_android>'] local_file_path = args['<file_path_on_machine>'] adb_enhanced.push_file(local_file_path, remote_file_path) elif args['cat']: file_path = args['<file_path>'] adb_enhanced.cat_file(file_path) elif args['start']: adb_enhanced.launch_app(args['<app_name>']) elif args['stop']: adb_enhanced.stop_app(args['<app_name>']) elif args['restart']: app_name = args['<app_name>'] adb_enhanced.force_stop(app_name) adb_enhanced.launch_app(app_name) # app elif args['app'] and args['info']: adb_enhanced.print_app_info(args['<app_name>']) elif args['app'] and args['path']: adb_enhanced.print_app_path(args['<app_name>']) elif args['app'] and args['signature']: adb_enhanced.print_app_signature(args['<app_name>']) elif args['app'] and args['backup']: app_name = args['<app_name>'] backup_tar_file_path = args['<backup_tar_file_path>'] if not backup_tar_file_path: backup_tar_file_path = '%s_backup.tar' % app_name adb_enhanced.perform_app_backup(app_name, backup_tar_file_path) elif args['screen'] and args['on']: adb_enhanced.switch_screen(adb_enhanced.SCREEN_ON) elif args['screen'] and args['off']: adb_enhanced.switch_screen(adb_enhanced.SCREEN_OFF) elif args['screen'] and args['toggle']: adb_enhanced.switch_screen(adb_enhanced.SCREEN_TOGGLE) elif args['install']: file_path = args['<file_path>'] adb_enhanced.perform_install(file_path) elif args['uninstall']: adb_enhanced.perform_uninstall(args['<app_name>']) else: print_error_and_exit('Not implemented: "%s"' % ' '.join(sys.argv))