def get_package_name(apk_path=None): """Return package name.""" # See if our environment is already set with this info. package_name = environment.get_value('PKG_NAME') if package_name: return package_name # See if we have the apk available to derive this info. if not apk_path: # Try getting apk path from APP_PATH. apk_path = environment.get_value('APP_PATH') if not apk_path: return None # Make sure that apk has the correct extension. if not apk_path.endswith('.apk'): return None # Try retrieving package name using aapt. aapt_binary_path = os.path.join( environment.get_platform_resources_directory(), 'aapt') aapt_command = '%s dump badging %s' % (aapt_binary_path, apk_path) output = adb.execute_command(aapt_command, timeout=AAPT_CMD_TIMEOUT) match = re.match('.*package: name=\'([^\']+)\'', output, re.DOTALL) if not match: return None return match.group(1)
def get_adb_path(): """Return path to ADB binary.""" adb_path = environment.get_value('ADB') if adb_path: return adb_path return os.path.join(environment.get_platform_resources_directory(), 'adb')
def setup_asan_if_needed(): """Sets the asan.options device property.""" if not environment.get_value('ASAN_DEVICE_SETUP'): # Only do this step if explicitly enabled in the job type. This cannot be # determined from libraries in application directory since they can go # missing in a bad build, so we want to catch that. return if get_sanitizer_tool_name(): # If this is a sanitizer build, no need to setup ASAN (incompatible). return app_directory = environment.get_value('APP_DIR') if not app_directory: # No app directory -> No ASAN runtime library. No work to do, bail out. return # Initialize variables. android_directory = environment.get_platform_resources_directory() device_id = environment.get_value('ANDROID_SERIAL') # Execute the script. logs.log('Executing ASan device setup script.') asan_device_setup_script_path = os.path.join(android_directory, 'third_party', 'asan_device_setup.sh') asan_runtime_library_argument = '--lib %s' % app_directory device_argument = '--device %s' % device_id asan_options_file_path = get_sanitizer_options_file_path('ASAN') extra_asan_options = ('--extra-options include_if_exists=%s' % asan_options_file_path) command = '%s %s %s %s' % (asan_device_setup_script_path, device_argument, asan_runtime_library_argument, extra_asan_options) adb.execute_command(command, timeout=ASAN_SCRIPT_TIMEOUT)
def _get_minijail_path(): """Get the minijail path. Returns: The path to the minijail binary. """ return os.path.join(environment.get_platform_resources_directory(), 'minijail0')
def configure(force_enable=False): """Configure airplane mode and wifi on device.""" # The reproduce tool shouldn't inherit wifi settings from jobs. if environment.get_value('REPRODUCE_TOOL'): return # Airplane mode should be disabled in all cases. This can get inadvertently # turned on via gestures. disable_airplane_mode() # Need to disable wifi before changing configuration. disable() # Check if wifi needs to be enabled. If not, then no need to modify the # supplicant file. wifi_enabled = force_enable or environment.get_value('WIFI', True) if not wifi_enabled: # No more work to do, we already disabled it at start. return # Wait 2 seconds to allow the wifi to be enabled. enable() time.sleep(2) # Install helper apk to configure wifi. wifi_util_apk_path = os.path.join( environment.get_platform_resources_directory(), 'wifi_util.apk') if not app.is_installed(WIFI_UTIL_PACKAGE_NAME): app.install(wifi_util_apk_path) # Get ssid and password from admin configuration. if adb.is_gce(): wifi_ssid = 'VirtWifi' wifi_password = '' else: config = db_config.get() if not config.wifi_ssid: logs.log('No wifi ssid is set, skipping wifi config.') return wifi_ssid = config.wifi_ssid wifi_password = config.wifi_password or '' connect_wifi_command = ( 'am instrument -e method connectToNetwork -e ssid {ssid} ') if wifi_password: connect_wifi_command += '-e psk {password} ' connect_wifi_command += '-w {call_path}' output = adb.run_shell_command( connect_wifi_command.format( ssid=quote(wifi_ssid), password=quote(wifi_password), call_path=WIFI_UTIL_CALL_PATH)) if 'result=true' not in output: logs.log_error('Failed to connect to wifi.', output=output)
def setup_asan_if_needed(): """Set up asan on device.""" if not environment.get_value("ASAN_DEVICE_SETUP"): # Only do this step if explicitly enabled in the job type. This cannot be # determined from libraries in application directory since they can go # missing in a bad build, so we want to catch that. return if settings.get_sanitizer_tool_name(): # If this is a sanitizer build, no need to setup ASAN (incompatible). return app_directory = environment.get_value("APP_DIR") if not app_directory: # No app directory -> No ASAN runtime library. No work to do, bail out. return # Initialize variables. android_directory = environment.get_platform_resources_directory() device_id = environment.get_value("ANDROID_SERIAL") # Execute the script. logs.log("Executing ASan device setup script.") asan_device_setup_script_path = os.path.join(android_directory, "third_party", "asan_device_setup.sh") extra_options_arg = "include_if_exists=" + get_options_file_path("asan") asan_device_setup_script_args = [ "--lib", app_directory, "--device", device_id, "--extra-options", extra_options_arg, ] process = new_process.ProcessRunner(asan_device_setup_script_path, asan_device_setup_script_args) result = process.run_and_wait() if result.return_code: logs.log_error("Failed to setup ASan on device.", output=result.output) return logs.log( "ASan device setup script successfully finished, waiting for boot.", output=result.output, ) # Wait until fully booted as otherwise shell restart followed by a quick # reboot can trigger data corruption in /data/data. adb.wait_until_fully_booted()
def get_path(grammar): """Return the path of the peach pit for the given grammar. Return None if the Pit does not exist or the grammar is None.""" pit_dir = os.path.join(environment.get_platform_resources_directory(), 'peach', 'pits') pit_path = os.path.join(pit_dir, grammar + '.xml') if not os.path.exists(pit_path): logs.log_error('Pit file for "%s" grammar is not found.' % grammar, pit_path=pit_path) return None return pit_path
def revert_asan_device_setup_if_needed(): """Reverts ASan device setup if installed.""" if not environment.get_value('ASAN_DEVICE_SETUP'): return device_id = environment.get_value('ANDROID_SERIAL') device_argument = '--device %s' % device_id revert_argument = '--revert' asan_device_setup_script_path = os.path.join( environment.get_platform_resources_directory(), 'third_party', 'asan_device_setup.sh') command = '%s %s %s' % (asan_device_setup_script_path, device_argument, revert_argument) execute_command(command, timeout=RECOVERY_CMD_TIMEOUT)
def configure_wifi_and_airplane_mode(wifi_enabled=False): """Configure airplane mode and wifi on device.""" # Airplane mode should be disabled in all cases. This can get inadvertently # turned on via gestures. adb.disable_airplane_mode() # GCE uses Ethernet, nothing to do here. if adb.is_gce(): return # Need to disable wifi before changing configuration. adb.disable_wifi() # Check if wifi needs to be enabled. If not, then no need to modify the # supplicant file. wifi_enabled = wifi_enabled or environment.get_value('WIFI', True) if not wifi_enabled: # No more work to do, we already disabled it at start. return config = db_config.get() if not config.wifi_ssid: # No wifi config is set, skip. return adb.enable_wifi() # Wait 2 seconds to allow the wifi to be enabled. time.sleep(2) wifi_util_apk_path = os.path.join( environment.get_platform_resources_directory(), 'wifi_util.apk') if not adb.is_package_installed(WIFI_UTIL_PACKAGE_NAME): adb.install_package(wifi_util_apk_path) connect_wifi_command = ( 'am instrument -e method connectToNetwork -e ssid {ssid} ') if config.wifi_password: connect_wifi_command += '-e psk {password} ' connect_wifi_command += '-w {call_path}' output = adb.run_adb_shell_command( connect_wifi_command.format( ssid=quote(config.wifi_ssid), password=quote(config.wifi_password), call_path=WIFI_UTIL_CALL_PATH)) if 'result=true' not in output: logs.log_error('Failed to connect to wifi.', output=output)
def add_test_accounts_if_needed(): """Add test account to work with GmsCore, etc.""" last_test_account_check_time = persistent_cache.get_value( constants.LAST_TEST_ACCOUNT_CHECK_KEY, constructor=datetime.datetime.utcfromtimestamp) needs_test_account_update = (last_test_account_check_time is None or dates.time_has_expired( last_test_account_check_time, seconds=ADD_TEST_ACCOUNT_CHECK_INTERVAL)) if not needs_test_account_update: return config = db_config.get() if not config: return test_account_email = config.test_account_email test_account_password = config.test_account_password if not test_account_email or not test_account_password: return adb.run_as_root() wifi.configure(force_enable=True) if not app.is_installed(ADD_TEST_ACCOUNT_PKG_NAME): logs.log('Installing helper apk for adding test account.') android_directory = environment.get_platform_resources_directory() add_test_account_apk_path = os.path.join(android_directory, ADD_TEST_ACCOUNT_APK_NAME) app.install(add_test_account_apk_path) logs.log('Trying to add test account.') output = adb.run_shell_command( 'am instrument -e account %s -e password %s -w %s' % (test_account_email, test_account_password, ADD_TEST_ACCOUNT_CALL_PATH), timeout=ADD_TEST_ACCOUNT_TIMEOUT) if not output or test_account_email not in output: logs.log('Failed to add test account, probably due to wifi issues.') return logs.log('Test account added successfully.') persistent_cache.set_value(constants.LAST_TEST_ACCOUNT_CHECK_KEY, time.time())
def setup_memory_monitor_script_if_needed(): """Run check_process_mem.sh to monitor the memory usage""" # The script should only start if this is a low end device. device_codename = environment.get_value('DEVICE_CODENAME', get_codename()) if device_codename not in MEMORY_CONSTRAINED_DEVICES: return adb.run_as_root() if get_pid_for_script(MEMORY_MONITOR_SCRIPT): # The script is already running, no work to do. return android_directory = environment.get_platform_resources_directory() script_host_path = os.path.join(android_directory, MEMORY_MONITOR_SCRIPT) script_device_path = os.path.join(adb.DEVICE_TMP_DIR, MEMORY_MONITOR_SCRIPT) # Push memory monitor script onto device and make it executable (if needed). if not adb.file_exists(script_device_path): adb.run_adb_command(['push', script_host_path, adb.DEVICE_TMP_DIR]) adb.run_adb_shell_command(['chmod', '0755', script_device_path]) # Run the memory monitor script. adb.run_adb_shell_command('sh %s 2>/dev/null 1>/dev/null &' % script_device_path) # Wait one second to allow the script to run. time.sleep(1) # Change the priority of the process so that it will not be easily killed # by lowmemorykiller. pid = get_pid_for_script(MEMORY_MONITOR_SCRIPT) if not pid: logs.log_error('Memory monitor script failed to run.') return adb.run_adb_shell_command('echo -1000 \\> /proc/%s/oom_score_adj' % pid) adb.run_adb_shell_command('echo 0 \\> /proc/%s/oom_score' % pid) adb.run_adb_shell_command('echo -17 \\> /proc/%s/oom_adj' % pid)
def close_open_file_handles_if_needed(path): """Try to close all open file handle for a specific path.""" if environment.platform() != 'WINDOWS': # Handle closing is only applicable on Windows platform. return resources_directory = environment.get_platform_resources_directory() handle_executable_path = os.path.join(resources_directory, 'handle.exe') handle_output = execute_command('%s -accepteula "%s"' % (handle_executable_path, path)) for line in handle_output.splitlines(): match = HANDLE_OUTPUT_FILE_TYPE_REGEX.match(line) if not match: continue process_id = match.group(1).decode('utf-8') file_handle_id = match.group(2).decode('utf-8') file_path = match.group(3).decode('utf-8') logs.log('Closing file handle id %s for path %s.' % (file_handle_id, file_path)) execute_command('%s -accepteula -c %s -p %s -y' % (handle_executable_path, file_handle_id, process_id))
def get_fastboot_path(): """Return path to fastboot binary.""" return os.path.join(environment.get_platform_resources_directory(), 'fastboot')