def run_android_webview(device, adapter):
    if adapter.options.package_name:
        logger.warn(
            '--package-name has no effect for android_webview, provider'
            'will be set to the --apk if it is provided.')

    if adapter.options.system_webview_shell:
        shell_pkg = apk_helper.GetPackageName(
            adapter.options.system_webview_shell)
        if shell_pkg != SYSTEM_WEBVIEW_SHELL_PKG:
            raise Exception(
                '{} has incorrect package name: {}, expected {}.'.format(
                    '--system-webview-shell apk', shell_pkg,
                    SYSTEM_WEBVIEW_SHELL_PKG))
        install_shell_as_needed = system_app.ReplaceSystemApp(
            device, shell_pkg, adapter.options.system_webview_shell)
        logger.info('Will install ' + shell_pkg + ' at ' +
                    adapter.options.system_webview_shell)
    else:
        install_shell_as_needed = no_op()

    if adapter.options.apk:
        install_webview_as_needed = webview_app.UseWebViewProvider(
            device, adapter.options.apk)
        logger.info('Will install WebView apk at ' + adapter.options.apk)
    else:
        install_webview_as_needed = no_op()

    with install_shell_as_needed, install_webview_as_needed:
        return adapter.run_test()
 def testReplace(self):
   self._check_preconditions()
   replacement = devil_env.config.FetchPath(
       'empty_system_webview', device=self._device)
   with system_app.ReplaceSystemApp(self._device, self.PACKAGE, replacement):
     replaced_paths = self._device.GetApplicationPaths(self.PACKAGE)
     self.assertNotEqual(self._original_paths, replaced_paths)
   restored_paths = self._device.GetApplicationPaths(self.PACKAGE)
   self.assertEqual(self._original_paths, restored_paths)
 def replace_package(dev):
   # We need the context manager to be applied before modifying any
   # shared preference files in case the replacement APK needs to be
   # set up, and it needs to be applied while the test is running.
   # Thus, it needs to be applied early during setup, but must still be
   # applied during _RunTest, which isn't possible using 'with' without
   # applying the context manager up in test_runner. Instead, we
   # manually invoke its __enter__ and __exit__ methods in setup and
   # teardown.
   self._replace_package_contextmanager = system_app.ReplaceSystemApp(
       dev, self._test_instance.replace_system_package.package,
       self._test_instance.replace_system_package.replacement_apk)
   self._replace_package_contextmanager.__enter__()
 def replace_package(dev):
   # We need the context manager to be applied before modifying any
   # shared preference files in case the replacement APK needs to be
   # set up, and it needs to be applied while the test is running.
   # Thus, it needs to be applied early during setup, but must still be
   # applied during _RunTest, which isn't possible using 'with' without
   # applying the context manager up in test_runner. Instead, we
   # manually invoke its __enter__ and __exit__ methods in setup and
   # teardown.
   self._replace_package_contextmanager = system_app.ReplaceSystemApp(
       dev, self._test_instance.replace_system_package.package,
       self._test_instance.replace_system_package.replacement_apk)
   # Pylint is not smart enough to realize that this field has
   # an __enter__ method, and will complain loudly.
   # pylint: disable=no-member
   self._replace_package_contextmanager.__enter__()
Exemple #5
0
        def individual_device_set_up(dev, host_device_tuples):
            steps = []

            if self._test_instance.replace_system_package:
                # We need the context manager to be applied before modifying any shared
                # preference files in case the replacement APK needs to be set up, and
                # it needs to be applied while the test is running. Thus, it needs to
                # be applied early during setup, but must still be applied during
                # _RunTest, which isn't possible using 'with' without applying the
                # context manager up in test_runner. Instead, we manually invoke
                # its __enter__ and __exit__ methods in setup and teardown
                self._replace_package_contextmanager = system_app.ReplaceSystemApp(
                    dev, self._test_instance.replace_system_package.package,
                    self._test_instance.replace_system_package.replacement_apk)
                steps.append(self._replace_package_contextmanager.__enter__)

            def install_helper(apk, permissions):
                @trace_event.traced("apk_path")
                def install_helper_internal(d, apk_path=apk.path):
                    # pylint: disable=unused-argument
                    d.Install(apk, permissions=permissions)

                return lambda: crash_handler.RetryOnSystemCrash(
                    install_helper_internal, dev)

            def incremental_install_helper(apk, script):
                @trace_event.traced("apk_path")
                def incremental_install_helper_internal(d, apk_path=apk.path):
                    # pylint: disable=unused-argument
                    local_device_test_run.IncrementalInstall(d, apk, script)

                return lambda: crash_handler.RetryOnSystemCrash(
                    incremental_install_helper_internal, dev)

            if self._test_instance.apk_under_test:
                if self._test_instance.apk_under_test_incremental_install_script:
                    steps.append(
                        incremental_install_helper(
                            self._test_instance.apk_under_test,
                            self._test_instance.
                            apk_under_test_incremental_install_script))
                else:
                    permissions = self._test_instance.apk_under_test.GetPermissions(
                    )
                    steps.append(
                        install_helper(self._test_instance.apk_under_test,
                                       permissions))

            if self._test_instance.test_apk_incremental_install_script:
                steps.append(
                    incremental_install_helper(
                        self._test_instance.test_apk, self._test_instance.
                        test_apk_incremental_install_script))
            else:
                permissions = self._test_instance.test_apk.GetPermissions()
                steps.append(
                    install_helper(self._test_instance.test_apk, permissions))

            steps.extend(
                install_helper(apk, None)
                for apk in self._test_instance.additional_apks)

            @trace_event.traced
            def set_debug_app():
                # Set debug app in order to enable reading command line flags on user
                # builds
                if self._test_instance.flags:
                    if not self._test_instance.package_info:
                        logging.error(
                            "Couldn't set debug app: no package info")
                    elif not self._test_instance.package_info.package:
                        logging.error(
                            "Couldn't set debug app: no package defined")
                    else:
                        dev.RunShellCommand([
                            'am', 'set-debug-app', '--persistent',
                            self._test_instance.package_info.package
                        ],
                                            check_return=True)

            @trace_event.traced
            def edit_shared_prefs():
                shared_preference_utils.ApplySharedPreferenceSettings(
                    dev, self._test_instance.edit_shared_prefs)

            @trace_event.traced
            def push_test_data():
                device_root = posixpath.join(dev.GetExternalStoragePath(),
                                             'chromium_tests_root')
                host_device_tuples_substituted = [
                    (h,
                     local_device_test_run.SubstituteDeviceRoot(
                         d, device_root)) for h, d in host_device_tuples
                ]
                logging.info('instrumentation data deps:')
                for h, d in host_device_tuples_substituted:
                    logging.info('%r -> %r', h, d)
                dev.PushChangedFiles(host_device_tuples_substituted,
                                     delete_device_stale=True)
                if not host_device_tuples_substituted:
                    dev.RunShellCommand(['rm', '-rf', device_root],
                                        check_return=True)
                    dev.RunShellCommand(['mkdir', '-p', device_root],
                                        check_return=True)

            @trace_event.traced
            def create_flag_changer():
                if self._test_instance.flags:
                    if not self._test_instance.package_info:
                        logging.error("Couldn't set flags: no package info")
                    elif not self._test_instance.package_info.cmdline_file:
                        logging.error("Couldn't set flags: no cmdline_file")
                    else:
                        self._CreateFlagChangerIfNeeded(dev)
                        logging.debug('Attempting to set flags: %r',
                                      self._test_instance.flags)
                        self._flag_changers[str(dev)].AddFlags(
                            self._test_instance.flags)

                valgrind_tools.SetChromeTimeoutScale(
                    dev, self._test_instance.timeout_scale)

            @trace_event.traced
            def setup_ui_capture_dir():
                # Make sure the UI capture directory exists and is empty by deleting
                # and recreating it.
                # TODO (aberent) once DeviceTempDir exists use it here.
                self._ui_capture_dir[dev] = posixpath.join(
                    dev.GetExternalStoragePath(), *UI_CAPTURE_DIRS)

                if dev.PathExists(self._ui_capture_dir[dev]):
                    dev.RunShellCommand(
                        ['rm', '-rf', self._ui_capture_dir[dev]])
                dev.RunShellCommand(['mkdir', self._ui_capture_dir[dev]])

            steps += [
                set_debug_app, edit_shared_prefs, push_test_data,
                create_flag_changer, setup_ui_capture_dir
            ]
            if self._env.concurrent_adb:
                reraiser_thread.RunAsync(steps)
            else:
                for step in steps:
                    step()
            if self._test_instance.store_tombstones:
                tombstones.ClearAllTombstones(dev)
Exemple #6
0
def UseWebViewProvider(device, apk, expected_package=''):
    """A context manager that uses the apk as the webview provider while in scope.

  Args:
    device: (device_utils.DeviceUtils) The device for which the webview apk
      should be used as the provider.
    apk: (str) The path to the webview APK to use.
    expected_package: (str) If non-empty, verify apk's package name matches
                      this value.
  """
    package_name = apk_helper.GetPackageName(apk)

    if expected_package:
        if package_name != expected_package:
            raise device_errors.CommandFailedError(
                'WebView Provider package %s does not match expected %s' %
                (package_name, expected_package), str(device))

    if (device.build_version_sdk
            in [version_codes.NOUGAT, version_codes.NOUGAT_MR1]):
        logger.warning(
            'Due to webviewupdate bug in Nougat, WebView Fallback Logic '
            'will be disabled and WebView provider may be changed after '
            'exit of UseWebViewProvider context manager scope.')

    webview_update = device.GetWebViewUpdateServiceDump()
    original_fallback_logic = webview_update.get('FallbackLogicEnabled', None)
    original_provider = webview_update.get('CurrentWebViewPackage', None)

    # This is only necessary if the provider is a fallback provider, but we can't
    # generally determine this, so we set this just in case.
    device.SetWebViewFallbackLogic(False)

    try:
        # If user installed versions of the package is present, they must be
        # uninstalled first, so that the system version of the package,
        # if any, can be found by the ReplaceSystemApp context manager
        with _UninstallNonSystemApp(device, package_name):
            all_paths = device.GetApplicationPaths(package_name)
            system_paths = _FilterPaths(all_paths, True)
            non_system_paths = _FilterPaths(all_paths, False)
            if non_system_paths:
                raise device_errors.CommandFailedError(
                    'Non-System application paths found after uninstallation: ',
                    str(non_system_paths))
            elif system_paths:
                # app is system app, use ReplaceSystemApp to install
                with system_app.ReplaceSystemApp(
                        device,
                        package_name,
                        apk,
                        install_timeout=_WEBVIEW_INSTALL_TIMEOUT):
                    _SetWebViewProvider(device, package_name)
                    yield
            else:
                # app is not present on device, can directly install
                with _InstallApp(device, apk):
                    _SetWebViewProvider(device, package_name)
                    yield
    finally:
        # restore the original provider only if it was known and not the current
        # provider
        if original_provider is not None:
            webview_update = device.GetWebViewUpdateServiceDump()
            new_provider = webview_update.get('CurrentWebViewPackage', None)
            if new_provider != original_provider:
                device.SetWebViewImplementation(original_provider)

        # enable the fallback logic only if it was known to be enabled
        if original_fallback_logic is True:
            device.SetWebViewFallbackLogic(True)