示例#1
0
def InstallCommands(device):
  if device.IsUserBuild():
    raise device_errors.CommandFailedError(
        'chromium_commands currently requires a userdebug build.',
        device_serial=device.adb.GetDeviceSerial())

  chromium_commands_jar_path = devil_env.config.FetchPath('chromium_commands')
  if not os.path.exists(chromium_commands_jar_path):
    raise device_errors.CommandFailedError(
        '%s not found. Please build chromium_commands.'
        % chromium_commands_jar_path)

  device.RunShellCommand(
      ['mkdir', '-p', BIN_DIR, _FRAMEWORK_DIR], check_return=True)
  for command, main_class in _COMMANDS.iteritems():
    shell_command = _SHELL_COMMAND_FORMAT % (
        file_system.TEST_EXECUTABLE_DIR, main_class)
    shell_file = '%s/%s' % (BIN_DIR, command)
    device.WriteFile(shell_file, shell_command)
    device.RunShellCommand(
        ['chmod', '755', shell_file], check_return=True)

  device.adb.Push(
      chromium_commands_jar_path,
      '%s/chromium_commands.jar' % _FRAMEWORK_DIR)
示例#2
0
    def _HardwareSetCharging(self, enabled, timeout=None, retries=None):
        """Enables or disables charging on the device.

    Args:
      enabled: A boolean indicating whether charging should be enabled or
        disabled.
      timeout: timeout in seconds
      retries: number of retries

    Raises:
      device_errors.CommandFailedError: If method of disabling charging cannot
        be determined.
    """
        self._DiscoverDeviceProfile()
        if not self._cache['profile']['enable_command']:
            raise device_errors.CommandFailedError(
                'Unable to find charging commands.')

        command = (self._cache['profile']['enable_command']
                   if enabled else self._cache['profile']['disable_command'])

        def verify_charging():
            return self.GetCharging() == enabled

        self._device.RunShellCommand(command,
                                     shell=True,
                                     check_return=True,
                                     as_root=True,
                                     large_output=True)
        timeout_retry.WaitFor(verify_charging, wait_period=1)
示例#3
0
def EnableSystemAppModification(device):
  """A context manager that allows system apps to be modified while in scope.

  Args:
    device: (device_utils.DeviceUtils) the device
  """
  if device.GetProp(_ENABLE_MODIFICATION_PROP) == '1':
    yield
    return

  device.EnableRoot()
  if not device.HasRoot():
    raise device_errors.CommandFailedError(
        'Failed to enable modification of system apps on non-rooted device',
        str(device))

  try:
    # Disable Marshmallow's Verity security feature
    if device.build_version_sdk >= version_codes.MARSHMALLOW:
      logger.info('Disabling Verity on %s', device.serial)
      device.adb.DisableVerity()
      device.Reboot()
      device.WaitUntilFullyBooted()
      device.EnableRoot()

    device.adb.Remount()
    device.RunShellCommand(['stop'], check_return=True)
    device.SetProp(_ENABLE_MODIFICATION_PROP, '1')
    yield
  finally:
    device.SetProp(_ENABLE_MODIFICATION_PROP, '0')
    device.Reboot()
    device.WaitUntilFullyBooted()
示例#4
0
    def Commit(self):
        """Save the current set of preferences to the device.

    Only actually saves if some preferences have been modified.
    """
        if not self.changed:
            return
        self._device.RunShellCommand(
            ['mkdir', '-p', posixpath.dirname(self.path)],
            as_root=True,
            check_return=True)
        self._device.WriteFile(self.path, str(self), as_root=True)
        # Creating the directory/file can cause issues with SELinux if they did
        # not already exist. As a workaround, apply the package's security context
        # to the shared_prefs directory, which mimics the behavior of a file
        # created by the app itself
        if self._device.build_version_sdk >= version_codes.MARSHMALLOW:
            security_context = self._GetSecurityContext(self.package)
            if security_context == None:
                raise device_errors.CommandFailedError(
                    'Failed to get security context for %s' % self.package)
            self._device.RunShellCommand([
                'chcon', '-R', security_context,
                '/data/data/%s/shared_prefs' % self.package
            ],
                                         as_root=True,
                                         check_return=True)
        self._device.KillAll(self.package,
                             exact=True,
                             as_root=True,
                             quiet=True)
        self._changed = False
示例#5
0
def _TearDownSystemAppModification(device,
                                   should_restore_root,
                                   timeout=None,
                                   retries=None):
    try:
        # The function may be re-entered after the the device loses root
        # privilege. For instance if the adb server is restarted before
        # re-entering the function then the device may lose root privilege.
        # Therefore we need to do a sanity check for root privilege
        # on the device and then re-enable root privilege if the device
        # does not have it.
        if not device.HasRoot():
            logger.warning('Need to re-enable root.')
            device.EnableRoot()

            if not device.HasRoot():
                raise device_errors.CommandFailedError(
                    ('Failed to tear down modification of '
                     'system apps on non-rooted device.'), str(device))

        device.SetProp(_ENABLE_MODIFICATION_PROP, '0')
        device.Reboot()
        device.WaitUntilFullyBooted()
        if should_restore_root:
            device.EnableRoot()
    except device_errors.CommandTimeoutError:
        logger.error('Timed out while tearing down system app modification.')
        logger.error('  device state: %s', device.adb.GetState())
        raise
示例#6
0
    def _GetTests(self):
        if self._test_instance.extract_test_list_from_filter:
            # When the exact list of tests to run is given via command-line (e.g. when
            # locally iterating on a specific test), skip querying the device (which
            # takes ~3 seconds).
            tests = _ExtractTestsFromFilter(self._test_instance.gtest_filter)
            if tests:
                return tests

        # Even when there's only one device, it still makes sense to retrieve the
        # test list so that tests can be split up and run in batches rather than all
        # at once (since test output is not streamed).
        @local_device_test_run.handle_shard_failures_with(
            on_failure=self._env.BlacklistDevice)
        def list_tests(dev):
            tests = self._delegate.Run(None,
                                       dev,
                                       flags='--gtest_list_tests',
                                       timeout=30)
            tests = gtest_test_instance.ParseGTestListTests(tests)
            tests = self._test_instance.FilterTests(tests)
            return tests

        # Query all devices in case one fails.
        test_lists = self._env.parallel_devices.pMap(list_tests).pGet(None)

        # If all devices failed to list tests, raise an exception.
        # Check that tl is not None and is not empty.
        if all(not tl for tl in test_lists):
            raise device_errors.CommandFailedError(
                'Failed to list tests on any device')
        return list(sorted(set().union(*[set(tl) for tl in test_lists if tl])))
def FinishProvisioning(device, options):
  # The lockscreen can't be disabled on user builds, so send a keyevent
  # to unlock it.
  if device.IsUserBuild():
    device.SendKeyEvent(keyevent.KEYCODE_MENU)

  if options.min_battery_level is not None:
    try:
      battery = battery_utils.BatteryUtils(device)
      battery.ChargeDeviceToLevel(options.min_battery_level)
    except device_errors.CommandFailedError:
      logging.exception('Unable to charge device to specified level.')

  if options.max_battery_temp is not None:
    try:
      battery = battery_utils.BatteryUtils(device)
      battery.LetBatteryCoolToTemperature(options.max_battery_temp)
    except device_errors.CommandFailedError:
      logging.exception('Unable to let battery cool to specified temperature.')

  def _set_and_verify_date():
    if device.build_version_sdk >= version_codes.MARSHMALLOW:
      date_format = '%m%d%H%M%Y.%S'
      set_date_command = ['date']
    else:
      date_format = '%Y%m%d.%H%M%S'
      set_date_command = ['date', '-s']
    strgmtime = time.strftime(date_format, time.gmtime())
    set_date_command.append(strgmtime)
    device.RunShellCommand(set_date_command, as_root=True, check_return=True)

    device_time = device.RunShellCommand(
        ['date', '+"%Y%m%d.%H%M%S"'], as_root=True,
        single_line=True).replace('"', '')
    device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S")
    correct_time = datetime.datetime.strptime(strgmtime, date_format)
    tdelta = (correct_time - device_time).seconds
    if tdelta <= 1:
      logging.info('Date/time successfully set on %s', device)
      return True
    else:
      logging.error('Date mismatch. Device: %s Correct: %s',
                    device_time.isoformat(), correct_time.isoformat())
      return False

  # Sometimes the date is not set correctly on the devices. Retry on failure.
  if device.IsUserBuild():
    # TODO(bpastene): Figure out how to set the date & time on user builds.
    pass
  else:
    if not timeout_retry.WaitFor(
        _set_and_verify_date, wait_period=1, max_tries=2):
      raise device_errors.CommandFailedError(
          'Failed to set date & time.', device_serial=str(device))

  props = device.RunShellCommand('getprop', check_return=True)
  for prop in props:
    logging.info('  %s', prop)
  if options.auto_reconnect:
    _PushAndLaunchAdbReboot(device, options.target)
def CheckWebViewIsUninstalled(device):
    """Throws if WebView is still installed."""
    for webview_package in WEBVIEW_PACKAGES:
        if device.IsApplicationInstalled(webview_package):
            raise device_errors.CommandFailedError(
                '{} is still installed on the device'.format(webview_package),
                device)
def RemoveSystemApps(device, system_app_remove_list,
                     system_package_remove_list):
    """Attempts to remove the provided system apps from the given device.

  Arguments:
    device: The device to remove the system apps from.
    system_app_remove_list: A list of app names to remove, e.g.
        ['WebViewGoogle', 'GoogleVrCore']
    system_package_remove_list: A list of app packages to remove, e.g.
        ['com.google.android.webview']
  """
    device.EnableRoot()
    if device.HasRoot():
        system_app_paths = (
            _FindSystemAppPaths(device, system_app_remove_list) +
            _FindSystemPackagePaths(device, system_package_remove_list))
        if system_app_paths:
            # Disable Marshmallow's Verity security feature
            if device.build_version_sdk >= version_codes.MARSHMALLOW:
                logger.info('Disabling Verity on %s', device.serial)
                device.adb.DisableVerity()
                device.Reboot()
                device.WaitUntilFullyBooted()
                device.EnableRoot()

            device.adb.Remount()
            device.RunShellCommand(['stop'], check_return=True)
            device.RemovePath(system_app_paths, force=True, recursive=True)
            device.RunShellCommand(['start'], check_return=True)
    else:
        raise device_errors.CommandFailedError(
            'Failed to remove system apps from non-rooted device', str(device))
示例#10
0
  def GetPowerData(self, timeout=None, retries=None):
    """Get power data for device.

    Args:
      timeout: timeout in seconds
      retries: number of retries

    Returns:
      Dict containing system power, and a per-package power dict keyed on
      package names.
      {
        'system_total': 23.1,
        'per_package' : {
          package_name: {
            'uid': uid,
            'data': [1,2,3]
          },
        }
      }
    """
    if 'uids' not in self._cache:
      self._cache['uids'] = {}
    dumpsys_output = self._device.RunShellCommand(
        ['dumpsys', 'batterystats', '-c'],
        check_return=True, large_output=True)
    csvreader = csv.reader(dumpsys_output)
    pwi_entries = collections.defaultdict(list)
    system_total = None
    for entry in csvreader:
      if entry[_DUMP_VERSION_INDEX] not in ['8', '9']:
        # Wrong dumpsys version.
        raise device_errors.DeviceVersionError(
            'Dumpsys version must be 8 or 9. "%s" found.'
            % entry[_DUMP_VERSION_INDEX])
      if _ROW_TYPE_INDEX < len(entry) and entry[_ROW_TYPE_INDEX] == 'uid':
        current_package = entry[_PACKAGE_NAME_INDEX]
        if (self._cache['uids'].get(current_package)
            and self._cache['uids'].get(current_package)
            != entry[_PACKAGE_UID_INDEX]):
          raise device_errors.CommandFailedError(
              'Package %s found multiple times with different UIDs %s and %s'
               % (current_package, self._cache['uids'][current_package],
               entry[_PACKAGE_UID_INDEX]))
        self._cache['uids'][current_package] = entry[_PACKAGE_UID_INDEX]
      elif (_PWI_POWER_CONSUMPTION_INDEX < len(entry)
          and entry[_ROW_TYPE_INDEX] == 'pwi'
          and entry[_PWI_AGGREGATION_INDEX] == 'l'):
        pwi_entries[entry[_PWI_UID_INDEX]].append(
            float(entry[_PWI_POWER_CONSUMPTION_INDEX]))
      elif (_PWS_POWER_CONSUMPTION_INDEX < len(entry)
          and entry[_ROW_TYPE_INDEX] == 'pws'
          and entry[_PWS_AGGREGATION_INDEX] == 'l'):
        # This entry should only appear once.
        assert system_total is None
        system_total = float(entry[_PWS_POWER_CONSUMPTION_INDEX])

    per_package = {p: {'uid': uid, 'data': pwi_entries[uid]}
                   for p, uid in self._cache['uids'].iteritems()}
    return {'system_total': system_total, 'per_package': per_package}
def CheckWebViewIsUninstalled(device):
    """Throws if WebView is still installed."""
    for webview_package in WEBVIEW_PACKAGES:
        paths = device.GetApplicationPaths(webview_package)
        if paths:
            raise device_errors.CommandFailedError(
                '{} is still installed on the device at {}'.format(
                    webview_package, paths), device)
    def _GetTests(self):
        if self._test_instance.extract_test_list_from_filter:
            # When the exact list of tests to run is given via command-line (e.g. when
            # locally iterating on a specific test), skip querying the device (which
            # takes ~3 seconds).
            tests = _ExtractTestsFromFilter(self._test_instance.gtest_filter)
            if tests:
                return tests

        # Even when there's only one device, it still makes sense to retrieve the
        # test list so that tests can be split up and run in batches rather than all
        # at once (since test output is not streamed).
        @local_device_environment.handle_shard_failures_with(
            on_failure=self._env.BlacklistDevice)
        def list_tests(dev):
            timeout = 30
            retries = 1
            if self._test_instance.wait_for_java_debugger:
                timeout = None
            # TODO(crbug.com/726880): Remove retries when no longer necessary.
            for i in range(0, retries + 1):
                raw_test_list = crash_handler.RetryOnSystemCrash(
                    lambda d: self._delegate.Run(
                        None, d, flags='--gtest_list_tests', timeout=timeout),
                    device=dev)
                tests = gtest_test_instance.ParseGTestListTests(raw_test_list)
                if not tests:
                    logging.info('No tests found. Output:')
                    for l in raw_test_list:
                        logging.info('  %s', l)
                    logging.info('Logcat:')
                    for line in dev.adb.Logcat(dump=True):
                        logging.info(line)
                    dev.adb.Logcat(clear=True)
                    if i < retries:
                        logging.info('Retrying...')
                else:
                    break
            return tests

        # Query all devices in case one fails.
        test_lists = self._env.parallel_devices.pMap(list_tests).pGet(None)

        # If all devices failed to list tests, raise an exception.
        # Check that tl is not None and is not empty.
        if all(not tl for tl in test_lists):
            raise device_errors.CommandFailedError(
                'Failed to list tests on any device')
        tests = list(sorted(set().union(*[set(tl) for tl in test_lists
                                          if tl])))
        tests = self._test_instance.FilterTests(tests)
        tests = self._ApplyExternalSharding(
            tests, self._test_instance.external_shard_index,
            self._test_instance.total_external_shards)
        return tests
def CheckBuildTypeSupportsFlags(device, command_line_flags_file):
    is_webview = command_line_flags_file == 'webview-command-line'
    if device.IsUserBuild() and is_webview:
        raise device_errors.CommandFailedError(
            'WebView only respects flags on a userdebug or eng device, yours '
            'is a user build.', device)
    elif device.IsUserBuild():
        logging.warning(
            'Your device (%s) is a user build; Chrome may or may not pick up '
            'your commandline flags. Check your '
            '"command_line_on_non_rooted_enabled" preference, or switch '
            'devices.', device)
    def _GetTestsFromRunner(self):
        test_apk_path = self._test_instance.test_apk.path
        pickle_path = '%s-runner.pickle' % test_apk_path
        try:
            return instrumentation_test_instance.GetTestsFromPickle(
                pickle_path, test_apk_path)
        except instrumentation_test_instance.TestListPickleException as e:
            logging.info('Could not get tests from pickle: %s', e)
        logging.info('Getting tests by having %s list them.',
                     self._test_instance.junit4_runner_class)

        def list_tests(d):
            def _run(dev):
                with device_temp_file.DeviceTempFile(
                        dev.adb, suffix='.json', dir=dev.
                        GetExternalStoragePath()) as dev_test_list_json:
                    junit4_runner_class = self._test_instance.junit4_runner_class
                    test_package = self._test_instance.test_package
                    extras = {}
                    extras['log'] = 'true'
                    extras[_EXTRA_TEST_LIST] = dev_test_list_json.name
                    target = '%s/%s' % (test_package, junit4_runner_class)
                    kwargs = {}
                    if self._test_instance.wait_for_java_debugger:
                        kwargs['timeout'] = None
                    test_list_run_output = dev.StartInstrumentation(
                        target, extras=extras, retries=0, **kwargs)
                    if any(test_list_run_output):
                        logging.error('Unexpected output while listing tests:')
                        for line in test_list_run_output:
                            logging.error('  %s', line)
                    with tempfile_ext.NamedTemporaryDirectory() as host_dir:
                        host_file = os.path.join(host_dir, 'list_tests.json')
                        dev.PullFile(dev_test_list_json.name, host_file)
                        with open(host_file, 'r') as host_file:
                            return json.load(host_file)

            return crash_handler.RetryOnSystemCrash(_run, d)

        raw_test_lists = self._env.parallel_devices.pMap(list_tests).pGet(None)

        # If all devices failed to list tests, raise an exception.
        # Check that tl is not None and is not empty.
        if all(not tl for tl in raw_test_lists):
            raise device_errors.CommandFailedError(
                'Failed to list tests on any device')

        # Get the first viable list of raw tests
        raw_tests = [tl for tl in raw_test_lists if tl][0]

        instrumentation_test_instance.SaveTestsToPickle(
            pickle_path, test_apk_path, raw_tests)
        return raw_tests
示例#15
0
def EnableSystemAppModification(device):
    """A context manager that allows system apps to be modified while in scope.

  Args:
    device: (device_utils.DeviceUtils) the device
  """
    if device.GetProp(_ENABLE_MODIFICATION_PROP) == '1':
        yield
        return

    # All calls that could potentially need root should run with as_root=True, but
    # it looks like some parts of Telemetry work as-is by implicitly assuming that
    # root is already granted if it's necessary. The reboot can mess with this, so
    # as a workaround, check whether we're starting with root already, and if so,
    # restore the device to that state at the end.
    should_restore_root = device.HasRoot()
    device.EnableRoot()
    if not device.HasRoot():
        raise device_errors.CommandFailedError(
            'Failed to enable modification of system apps on non-rooted device',
            str(device))

    try:
        # Disable Marshmallow's Verity security feature
        if device.build_version_sdk >= version_codes.MARSHMALLOW:
            logger.info('Disabling Verity on %s', device.serial)
            device.adb.DisableVerity()
            device.Reboot()
            device.WaitUntilFullyBooted()
            device.EnableRoot()

        device.adb.Remount()
        device.RunShellCommand(['stop'], check_return=True)
        device.SetProp(_ENABLE_MODIFICATION_PROP, '1')
        yield
    except device_errors.CommandFailedError as e:
        if device.adb.is_emulator:
            # Point the user to documentation, since there's a good chance they can
            # workaround this on an emulator.
            docs_url = (
                'https://chromium.googlesource.com/chromium/src/+/'
                'master/docs/android_emulator.md#writable-system-partition')
            logger.error(
                'Did you start the emulator with "-writable-system?"\n'
                'See %s\n', docs_url)
        raise e
    finally:
        device.SetProp(_ENABLE_MODIFICATION_PROP, '0')
        device.Reboot()
        device.WaitUntilFullyBooted()
        if should_restore_root:
            device.EnableRoot()
def SetDate(device):
    def _set_and_verify_date():
        if device.build_version_sdk >= version_codes.MARSHMALLOW:
            date_format = '%m%d%H%M%Y.%S'
            set_date_command = ['date', '-u']
            get_date_command = ['date', '-u']
        else:
            date_format = '%Y%m%d.%H%M%S'
            set_date_command = ['date', '-s']
            get_date_command = ['date']

        # TODO(jbudorick): This is wrong on pre-M devices -- get/set are
        # dealing in local time, but we're setting based on GMT.
        strgmtime = time.strftime(date_format, time.gmtime())
        set_date_command.append(strgmtime)
        device.RunShellCommand(set_date_command,
                               as_root=True,
                               check_return=True)

        get_date_command.append('+"%Y%m%d.%H%M%S"')
        device_time = device.RunShellCommand(get_date_command,
                                             check_return=True,
                                             as_root=True,
                                             single_line=True).replace(
                                                 '"', '')
        device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S")
        correct_time = datetime.datetime.strptime(strgmtime, date_format)
        tdelta = (correct_time - device_time).seconds
        if tdelta <= 1:
            logger.info('Date/time successfully set on %s', device)
            return True
        else:
            logger.error('Date mismatch. Device: %s Correct: %s',
                         device_time.isoformat(), correct_time.isoformat())
            return False

    # Sometimes the date is not set correctly on the devices. Retry on failure.
    if device.IsUserBuild():
        # TODO(bpastene): Figure out how to set the date & time on user builds.
        pass
    else:
        if not timeout_retry.WaitFor(
                _set_and_verify_date, wait_period=1, max_tries=2):
            raise device_errors.CommandFailedError(
                'Failed to set date & time.', device_serial=str(device))
        device.EnableRoot()
        # The following intent can take a bit to complete when ran shortly after
        # device boot-up.
        device.BroadcastIntent(
            intent.Intent(action='android.intent.action.TIME_SET'),
            timeout=180)
示例#17
0
def InstallCommands(device):
    if device.IsUserBuild():
        raise device_errors.CommandFailedError(
            'chromium_commands currently requires a userdebug build.',
            device_serial=device.adb.GetDeviceSerial())

    chromium_commands_jar_path = os.path.join(constants.GetOutDirectory(),
                                              constants.SDK_BUILD_JAVALIB_DIR,
                                              'chromium_commands.dex.jar')
    if not os.path.exists(chromium_commands_jar_path):
        raise device_errors.CommandFailedError(
            '%s not found. Please build chromium_commands.' %
            chromium_commands_jar_path)

    device.RunShellCommand(['mkdir', BIN_DIR, _FRAMEWORK_DIR])
    for command, main_class in _COMMANDS.iteritems():
        shell_command = _SHELL_COMMAND_FORMAT % (constants.TEST_EXECUTABLE_DIR,
                                                 main_class)
        shell_file = '%s/%s' % (BIN_DIR, command)
        device.WriteFile(shell_file, shell_command)
        device.RunShellCommand(['chmod', '755', shell_file], check_return=True)

    device.adb.Push(chromium_commands_jar_path,
                    '%s/chromium_commands.jar' % _FRAMEWORK_DIR)
示例#18
0
    def Commit(self, force_commit=False):
        """Save the current set of preferences to the device.

    Only actually saves if some preferences have been modified or force_commit
    is set to True.

    Args:
      force_commit: Commit even if no changes have been made to the SharedPrefs
        instance.
    """
        if not (self.changed or force_commit):
            return
        self._device.RunShellCommand(
            ['mkdir', '-p', posixpath.dirname(self.path)],
            as_root=True,
            check_return=True)
        self._device.WriteFile(self.path, str(self), as_root=True)
        # Creating the directory/file can cause issues with SELinux if they did
        # not already exist. As a workaround, apply the package's security context
        # to the shared_prefs directory, which mimics the behavior of a file
        # created by the app itself
        if self._device.build_version_sdk >= version_codes.MARSHMALLOW:
            security_context = self._device.GetSecurityContextForPackage(
                self.package, encrypted=self._encrypted)
            if security_context is None:
                raise device_errors.CommandFailedError(
                    'Failed to get security context for %s' % self.package)
            paths = [posixpath.dirname(self.path), self.path]
            self._device.ChangeSecurityContext(security_context, paths)

        # Ensure that there isn't both an encrypted and unencrypted version of the
        # file on the device at the same time.
        if self._device.build_version_sdk >= version_codes.NOUGAT:
            remove_path = (self._unencrypted_path
                           if self._encrypted else self._encrypted_path)
            if self._device.PathExists(remove_path, as_root=True):
                logging.warning(
                    'Found an equivalent shared prefs file at %s, removing',
                    remove_path)
                self._device.RemovePath(remove_path, as_root=True)

        self._device.KillAll(self.package,
                             exact=True,
                             as_root=True,
                             quiet=True)
        self._changed = False
示例#19
0
 def update_flags(device):
     if device.IsUserBuild() and is_webview:
         raise device_errors.CommandFailedError(
             'WebView only respects flags on a userdebug or eng device, yours '
             'is a user build.', device)
     elif device.IsUserBuild():
         logging.warning(
             'Your device (%s) is a user build; Chrome may or may not pick up '
             'your commandline flags. Check your '
             '"command_line_on_non_rooted_enabled" preference, or switch '
             'devices.', device)
     changer = flag_changer.FlagChanger(device, args.name)
     if remote_args is not None:
         flags = changer.ReplaceFlags(remote_args)
     else:
         flags = changer.GetCurrentFlags()
     return (device, device.build_description, flags)
示例#20
0
    def _ClearPowerData(self):
        """Resets battery data and makes device appear like it is not
    charging so that it will collect power data since last charge.

    Returns:
      True if power data cleared.
      False if power data clearing is not supported (pre-L)

    Raises:
      device_errors.DeviceVersionError: If power clearing is supported,
        but fails.
    """
        if self._device.build_version_sdk < version_codes.LOLLIPOP:
            logging.warning(
                'Dumpsys power data only available on 5.0 and above. '
                'Cannot clear power data.')
            return False

        self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '1'],
                                     check_return=True)
        self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'ac', '1'],
                                     check_return=True)
        reset_output = self._device.RunShellCommand(
            ['dumpsys', 'batterystats', '--reset'], check_return=True)
        logging.info('Output from resetting batterystats:')
        for l in reset_output:
            logging.info('  %s', l)
        battery_data = self._device.RunShellCommand(
            ['dumpsys', 'batterystats', '--charged', '-c'],
            check_return=True,
            large_output=True)
        for line in battery_data:
            l = line.split(',')
            if (len(l) > _PWI_POWER_CONSUMPTION_INDEX
                    and l[_ROW_TYPE_INDEX] == 'pwi'
                    and l[_PWI_POWER_CONSUMPTION_INDEX] != 0):
                self._device.RunShellCommand(['dumpsys', 'battery', 'reset'],
                                             check_return=True)
                raise device_errors.CommandFailedError(
                    'Non-zero pmi value found after reset: "%s"' % line)
        self._device.RunShellCommand(['dumpsys', 'battery', 'reset'],
                                     check_return=True)
        return True
示例#21
0
def _SetUpSystemAppModification(device, timeout=None, retries=None):
    # Ensure that the device is online & available before proceeding to
    # handle the case where something fails in the middle of set up and
    # triggers a retry.
    device.WaitUntilFullyBooted()

    # All calls that could potentially need root should run with as_root=True, but
    # it looks like some parts of Telemetry work as-is by implicitly assuming that
    # root is already granted if it's necessary. The reboot can mess with this, so
    # as a workaround, check whether we're starting with root already, and if so,
    # restore the device to that state at the end.
    should_restore_root = device.HasRoot()
    device.EnableRoot()
    if not device.HasRoot():
        raise device_errors.CommandFailedError(
            'Failed to enable modification of system apps on non-rooted device',
            str(device))

    try:
        # Disable Marshmallow's Verity security feature
        if device.build_version_sdk >= version_codes.MARSHMALLOW:
            logger.info('Disabling Verity on %s', device.serial)
            device.adb.DisableVerity()
            device.Reboot()
            device.WaitUntilFullyBooted()
            device.EnableRoot()

        device.adb.Remount()
        device.RunShellCommand(['stop'], check_return=True)
        device.SetProp(_ENABLE_MODIFICATION_PROP, '1')
    except device_errors.CommandFailedError:
        if device.adb.is_emulator:
            # Point the user to documentation, since there's a good chance they can
            # workaround this on an emulator.
            docs_url = (
                'https://chromium.googlesource.com/chromium/src/+/'
                'HEAD/docs/android_emulator.md#writable-system-partition')
            logger.error(
                'Did you start the emulator with "-writable-system?"\n'
                'See %s\n', docs_url)
        raise

    return should_restore_root
示例#22
0
def RestartServer():
    """Restarts the adb server.

  Raises:
    CommandFailedError if we fail to kill or restart the server.
  """
    def adb_killed():
        return not AdbWrapper.IsServerOnline()

    def adb_started():
        return AdbWrapper.IsServerOnline()

    AdbWrapper.KillServer()
    if not timeout_retry.WaitFor(adb_killed, wait_period=1, max_tries=5):
        # TODO(crbug.com/442319): Switch this to raise an exception if we
        # figure out why sometimes not all adb servers on bots get killed.
        logger.warning('Failed to kill adb server')
    AdbWrapper.StartServer()
    if not timeout_retry.WaitFor(adb_started, wait_period=1, max_tries=5):
        raise device_errors.CommandFailedError('Failed to start adb server')
示例#23
0
文件: system_app.py 项目: wandu80/Adb
def EnableSystemAppModification(device):
    """A context manager that allows system apps to be modified while in scope.

  Args:
    device: (device_utils.DeviceUtils) the device
  """
    if device.GetProp(_ENABLE_MODIFICATION_PROP) == '1':
        yield
        return

    # All calls that could potentially need root should run with as_root=True, but
    # it looks like some parts of Telemetry work as-is by implicitly assuming that
    # root is already granted if it's necessary. The reboot can mess with this, so
    # as a workaround, check whether we're starting with root already, and if so,
    # restore the device to that state at the end.
    should_restore_root = device.HasRoot()
    device.EnableRoot()
    if not device.HasRoot():
        raise device_errors.CommandFailedError(
            'Failed to enable modification of system apps on non-rooted device',
            str(device))

    try:
        # Disable Marshmallow's Verity security feature
        if device.build_version_sdk >= version_codes.MARSHMALLOW:
            logger.info('Disabling Verity on %s', device.serial)
            device.adb.DisableVerity()
            device.Reboot()
            device.WaitUntilFullyBooted()
            device.EnableRoot()

        device.adb.Remount()
        device.RunShellCommand(['stop'], check_return=True)
        device.SetProp(_ENABLE_MODIFICATION_PROP, '1')
        yield
    finally:
        device.SetProp(_ENABLE_MODIFICATION_PROP, '0')
        device.Reboot()
        device.WaitUntilFullyBooted()
        if should_restore_root:
            device.EnableRoot()
示例#24
0
    def GetFuelGaugeChargeCounter(self, timeout=None, retries=None):
        """Get value of charge_counter on fuel gauge chip.

    Device must have charging disabled for this, not just battery updates
    disabled. The only device that this currently works with is the nexus 5.

    Args:
      timeout: timeout in seconds
      retries: number of retries

    Returns:
      value of charge_counter for fuel gauge chip in units of nAh.

    Raises:
      device_errors.CommandFailedError: If fuel gauge chip not found.
    """
        if self.SupportsFuelGauge():
            return int(
                self._device.ReadFile(
                    self._cache['profile']['charge_counter']))
        raise device_errors.CommandFailedError('Unable to find fuel gauge.')
示例#25
0
    def _FlashPartitions(self, partitions, directory, wipe=False, force=False):
        """Flashes all given partiitons with all given images.

    Args:
      partitions: List of partitions to flash.
      directory: Directory where all partitions can be found.
      wipe: If set to true, will automatically detect if cache and userdata
          partitions are sent, and if so ignore them.
      force: boolean to decide to ignore board name safety checks.

    Raises:
      device_errors.CommandFailedError(): If image cannot be found or if bad
          partition name is give.
    """
        if not self._VerifyBoard(directory):
            if force:
                logger.warning(
                    'Could not verify build is meant to be installed on '
                    'the current device type, but force flag is set. '
                    'Flashing device. Possibly dangerous operation.')
            else:
                raise device_errors.CommandFailedError(
                    'Could not verify build is meant to be installed on the current '
                    'device type. Run again with force=True to force flashing with an '
                    'unverified board.')

        flash_image_files = _FindAndVerifyPartitionsAndImages(
            partitions, directory)
        partitions = flash_image_files.keys()
        for partition in partitions:
            if _KNOWN_PARTITIONS[partition].get('wipe_only') and not wipe:
                logger.info(
                    'Not flashing in wipe mode. Skipping partition %s.',
                    partition)
            else:
                logger.info('Flashing %s with %s', partition,
                            flash_image_files[partition])
                self.fastboot.Flash(partition, flash_image_files[partition])
                if _KNOWN_PARTITIONS[partition].get('restart', False):
                    self.Reboot(bootloader=True)
示例#26
0
 def alwaysRaisesCommandFailedError(timeout=None, retries=None):
     DecoratorsTest._decorated_function_called_count += 1
     raise device_errors.CommandFailedError('testCommand failed')
示例#27
0
    def _GetTestsFromRunner(self):
        test_apk_path = self._test_instance.test_apk.path
        pickle_path = '%s-runner.pickle' % test_apk_path
        # For incremental APKs, the code doesn't live in the apk, so instead check
        # the timestamp of the target's .stamp file.
        if self._test_instance.test_apk_incremental_install_json:
            with open(self._test_instance.test_apk_incremental_install_json
                      ) as f:
                data = json.load(f)
            out_dir = constants.GetOutDirectory()
            test_mtime = max(
                os.path.getmtime(os.path.join(out_dir, p))
                for p in data['dex_files'])
        else:
            test_mtime = os.path.getmtime(test_apk_path)

        try:
            return instrumentation_test_instance.GetTestsFromPickle(
                pickle_path, test_mtime)
        except instrumentation_test_instance.TestListPickleException as e:
            logging.info('Could not get tests from pickle: %s', e)
        logging.info('Getting tests by having %s list them.',
                     self._test_instance.junit4_runner_class)

        def list_tests(d):
            def _run(dev):
                with device_temp_file.DeviceTempFile(
                        dev.adb, suffix='.json', dir=dev.
                        GetExternalStoragePath()) as dev_test_list_json:
                    junit4_runner_class = self._test_instance.junit4_runner_class
                    test_package = self._test_instance.test_package
                    extras = {
                        'log': 'true',
                        # Workaround for https://github.com/mockito/mockito/issues/922
                        'notPackage': 'net.bytebuddy',
                    }
                    extras[_EXTRA_TEST_LIST] = dev_test_list_json.name
                    target = '%s/%s' % (test_package, junit4_runner_class)
                    timeout = 120
                    if self._test_instance.wait_for_java_debugger:
                        timeout = None
                    test_list_run_output = dev.StartInstrumentation(
                        target, extras=extras, retries=0, timeout=timeout)
                    if any(test_list_run_output):
                        logging.error('Unexpected output while listing tests:')
                        for line in test_list_run_output:
                            logging.error('  %s', line)
                    with tempfile_ext.NamedTemporaryDirectory() as host_dir:
                        host_file = os.path.join(host_dir, 'list_tests.json')
                        dev.PullFile(dev_test_list_json.name, host_file)
                        with open(host_file, 'r') as host_file:
                            return json.load(host_file)

            return crash_handler.RetryOnSystemCrash(_run, d)

        raw_test_lists = self._env.parallel_devices.pMap(list_tests).pGet(None)

        # If all devices failed to list tests, raise an exception.
        # Check that tl is not None and is not empty.
        if all(not tl for tl in raw_test_lists):
            raise device_errors.CommandFailedError(
                'Failed to list tests on any device')

        # Get the first viable list of raw tests
        raw_tests = [tl for tl in raw_test_lists if tl][0]

        instrumentation_test_instance.SaveTestsToPickle(pickle_path, raw_tests)
        return raw_tests
示例#28
0
base=%s
export CLASSPATH=$base/framework/chromium_commands.jar
exec app_process $base/bin %s $@
""")


def Installed(presentation.device):
  paths = [posixpath.join(BIN_DIR, c) for c in _COMMANDS]
  paths.append(posixpath.join(_FRAMEWORK_DIR, 'chromium_commands.jar'))
  return presentation.device.PathExists(paths)


def InstallCommands(presentation.device):
  if presentation.device.IsUserBuild():
    raise device_errors.CommandFailedError(
        'chromium_commands currently requires a userdebug build.',
        device_serial=presentation.device.adb.GetDeviceSerial())

  chromium_commands_jar_path = devil_env.config.FetchPath('chromium_commands')
  if not os.path.exists(chromium_commands_jar_path):
    raise device_errors.CommandFailedError(
        '%s not found. Please build chromium_commands.'
        % chromium_commands_jar_path)

  presentation.device.RunShellCommand(
      ['mkdir', '-p', BIN_DIR, _FRAMEWORK_DIR], check_return=True)
  for command, main_class in _COMMANDS.iteritems():
    shell_command = _SHELL_COMMAND_FORMAT % (
        file_system.TEST_EXECUTABLE_DIR, main_class)
    shell_file = '%s/%s' % (BIN_DIR, command)
    presentation.device.WriteFile(shell_file, shell_command)
示例#29
0
 def alwaysRaisesCommandFailedError(timeout=None, retries=None):
     actual_tries[0] += 1
     raise device_errors.CommandFailedError('Command failed :(')
示例#30
0
def FinishProvisioning(device, options):
  # The lockscreen can't be disabled on user builds, so send a keyevent
  # to unlock it.
  if device.IsUserBuild():
    device.SendKeyEvent(keyevent.KEYCODE_MENU)

  if options.min_battery_level is not None:
    battery = battery_utils.BatteryUtils(device)
    try:
      battery.ChargeDeviceToLevel(options.min_battery_level)
    except device_errors.DeviceChargingError:
      device.Reboot()
      battery.ChargeDeviceToLevel(options.min_battery_level)

  if options.max_battery_temp is not None:
    try:
      battery = battery_utils.BatteryUtils(device)
      battery.LetBatteryCoolToTemperature(options.max_battery_temp)
    except device_errors.CommandFailedError:
      logging.exception('Unable to let battery cool to specified temperature.')

  def _set_and_verify_date():
    if device.build_version_sdk >= version_codes.MARSHMALLOW:
      date_format = '%m%d%H%M%Y.%S'
      set_date_command = ['date', '-u']
      get_date_command = ['date', '-u']
    else:
      date_format = '%Y%m%d.%H%M%S'
      set_date_command = ['date', '-s']
      get_date_command = ['date']

    # TODO(jbudorick): This is wrong on pre-M devices -- get/set are
    # dealing in local time, but we're setting based on GMT.
    strgmtime = time.strftime(date_format, time.gmtime())
    set_date_command.append(strgmtime)
    device.RunShellCommand(set_date_command, as_root=True, check_return=True)

    get_date_command.append('+"%Y%m%d.%H%M%S"')
    device_time = device.RunShellCommand(
        get_date_command, as_root=True, single_line=True).replace('"', '')
    device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S")
    correct_time = datetime.datetime.strptime(strgmtime, date_format)
    tdelta = (correct_time - device_time).seconds
    if tdelta <= 1:
      logging.info('Date/time successfully set on %s', device)
      return True
    else:
      logging.error('Date mismatch. Device: %s Correct: %s',
                    device_time.isoformat(), correct_time.isoformat())
      return False

  if options.disable_selinux:
    device.RunShellCommand("su -c setenforce 0", as_root=True)
  if options.force_battery_status:
    device.RunShellCommand("dumpsys battery set status 5", as_root=True)
    device.RunShellCommand("dumpsys battery set level 100", as_root=True)

  if options.disable_predictive_keyboard:
    DisablePredictiveKeyboard(device)

  # Sometimes the date is not set correctly on the devices. Retry on failure.
  if device.IsUserBuild():
    # TODO(bpastene): Figure out how to set the date & time on user builds.
    pass
  else:
    # FIXME: Some samsung devices can not set the date and time. so we skip this.
    if False and not timeout_retry.WaitFor(_set_and_verify_date, wait_period=1,
                                 max_tries=2):
      raise device_errors.CommandFailedError(
          'Failed to set date & time.', device_serial=str(device))

  props = device.RunShellCommand('getprop', check_return=True)
  for prop in props:
    logging.info('  %s', prop)
  if options.auto_reconnect:
    _PushAndLaunchAdbReboot(device, options.target)