diff --git a/DEPS b/DEPS index 5f4c80fd..cf0edba 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '7551898f8eba322acb04c74ae12aae1ed3548105', + 'skia_revision': '9ea894b4d030b55e377fc3858ebde12198f205ce', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '72f50f2021cd9f66016c962df8d27fc0c34748cd', + 'pdfium_revision': '4741b291f462c0c4a5de4abf1653c3b3c87b613a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '4ffd54d31cd52fdcc697562667985eac477a95ce', + 'catapult_revision': 'a067dd2f2b17fc0cb7057ac4500b07590c596e34', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/ash/mus/window_manager_application.cc b/ash/mus/window_manager_application.cc index 9660303..51c3aa1 100644 --- a/ash/mus/window_manager_application.cc +++ b/ash/mus/window_manager_application.cc
@@ -25,7 +25,6 @@ #include "ui/events/event.h" #include "ui/message_center/message_center.h" #include "ui/views/mus/aura_init.h" -#include "ui/views/mus/surface_context_factory.h" #if defined(OS_CHROMEOS) #include "ash/common/system/chromeos/power/power_status.h"
diff --git a/ash/touch_hud/mus/touch_hud_application.cc b/ash/touch_hud/mus/touch_hud_application.cc index 37d1b48..c58db00 100644 --- a/ash/touch_hud/mus/touch_hud_application.cc +++ b/ash/touch_hud/mus/touch_hud_application.cc
@@ -17,7 +17,6 @@ #include "ui/aura/mus/property_converter.h" #include "ui/views/mus/aura_init.h" #include "ui/views/mus/mus_client.h" -#include "ui/views/mus/native_widget_mus.h" #include "ui/views/mus/pointer_watcher_event_router2.h" #include "ui/views/pointer_watcher.h" #include "ui/views/widget/widget.h"
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py index ded427f..48ef76a7 100644 --- a/build/android/PRESUBMIT.py +++ b/build/android/PRESUBMIT.py
@@ -31,6 +31,7 @@ J(), J('gyp'), J('buildbot'), + J('..', 'util', 'lib', 'common'), J('..', '..', 'third_party', 'catapult', 'common', 'py_trace_event'), J('..', '..', 'third_party', 'catapult', 'common', 'py_utils'), J('..', '..', 'third_party', 'catapult', 'devil'), @@ -58,7 +59,6 @@ J('.', 'emma_coverage_stats_test.py'), J('gyp', 'util', 'md5_check_test.py'), J('play_services', 'update_test.py'), - J('pylib', 'base', 'test_dispatcher_unittest.py'), J('pylib', 'gtest', 'gtest_test_instance_test.py'), J('pylib', 'instrumentation', 'instrumentation_test_instance_test.py'),
diff --git a/build/android/pylib/base/base_test_runner.py b/build/android/pylib/base/base_test_runner.py deleted file mode 100644 index 77d05f7..0000000 --- a/build/android/pylib/base/base_test_runner.py +++ /dev/null
@@ -1,138 +0,0 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Base class for running tests on a single device.""" - -# TODO(jbudorick) Deprecate and remove this class and all subclasses after -# any relevant parts have been ported to the new environment + test instance -# model. - -import logging - -from devil.android import device_utils -from devil.android import forwarder -from devil.android import ports -from pylib.valgrind_tools import CreateTool -# TODO(frankf): Move this to pylib/utils - - -# A file on device to store ports of net test server. The format of the file is -# test-spawner-server-port:test-server-port -NET_TEST_SERVER_PORT_INFO_FILE = 'net-test-server-ports' - - -class BaseTestRunner(object): - """Base class for running tests on a single device.""" - - def __init__(self, device, tool): - """ - Args: - device: An instance of DeviceUtils that the tests will run on. - tool: Name of the Valgrind tool. - """ - assert isinstance(device, device_utils.DeviceUtils) - self.device = device - self.device_serial = self.device.adb.GetDeviceSerial() - self.tool = CreateTool(tool, self.device) - self._http_server = None - self._forwarder_device_port = 8000 - self.forwarder_base_url = ('http://localhost:%d' % - self._forwarder_device_port) - # We will allocate port for test server spawner when calling method - # LaunchChromeTestServerSpawner and allocate port for test server when - # starting it in TestServerThread. - self.test_server_spawner_port = 0 - self.test_server_port = 0 - - def _PushTestServerPortInfoToDevice(self): - """Pushes the latest port information to device.""" - self.device.WriteFile( - self.device.GetExternalStoragePath() + '/' + - NET_TEST_SERVER_PORT_INFO_FILE, - '%d:%d' % (self.test_server_spawner_port, self.test_server_port)) - - def RunTest(self, test): - """Runs a test. Needs to be overridden. - - Args: - test: A test to run. - - Returns: - Tuple containing: - (base_test_result.TestRunResults, tests to rerun or None) - """ - raise NotImplementedError - - def InstallTestPackage(self): - """Installs the test package once before all tests are run.""" - pass - - def SetUp(self): - """Run once before all tests are run.""" - self.InstallTestPackage() - - def TearDown(self): - """Run once after all tests are run.""" - self.ShutdownHelperToolsForTestSuite() - - def LaunchTestHttpServer(self, document_root, port=None, - extra_config_contents=None): - """Launches an HTTP server to serve HTTP tests. - - Args: - document_root: Document root of the HTTP server. - port: port on which we want to the http server bind. - extra_config_contents: Extra config contents for the HTTP server. - """ - import lighttpd_server - self._http_server = lighttpd_server.LighttpdServer( - document_root, port=port, extra_config_contents=extra_config_contents) - if self._http_server.StartupHttpServer(): - logging.info('http server started: http://localhost:%s', - self._http_server.port) - else: - logging.critical('Failed to start http server') - self._ForwardPortsForHttpServer() - return (self._forwarder_device_port, self._http_server.port) - - def _ForwardPorts(self, port_pairs): - """Forwards a port.""" - forwarder.Forwarder.Map(port_pairs, self.device, self.tool) - - def _UnmapPorts(self, port_pairs): - """Unmap previously forwarded ports.""" - for (device_port, _) in port_pairs: - forwarder.Forwarder.UnmapDevicePort(device_port, self.device) - - # Deprecated: Use ForwardPorts instead. - def StartForwarder(self, port_pairs): - """Starts TCP traffic forwarding for the given |port_pairs|. - - Args: - host_port_pairs: A list of (device_port, local_port) tuples to forward. - """ - self._ForwardPorts(port_pairs) - - def _ForwardPortsForHttpServer(self): - """Starts a forwarder for the HTTP server. - - The forwarder forwards HTTP requests and responses between host and device. - """ - self._ForwardPorts([(self._forwarder_device_port, self._http_server.port)]) - - def _RestartHttpServerForwarderIfNecessary(self): - """Restarts the forwarder if it's not open.""" - # Checks to see if the http server port is being used. If not forwards the - # request. - # TODO(dtrainor): This is not always reliable because sometimes the port - # will be left open even after the forwarder has been killed. - if not ports.IsDevicePortUsed(self.device, self._forwarder_device_port): - self._ForwardPortsForHttpServer() - - def ShutdownHelperToolsForTestSuite(self): - """Shuts down the server and the forwarder.""" - if self._http_server: - self._UnmapPorts([(self._forwarder_device_port, self._http_server.port)]) - self._http_server.ShutdownHttpServer() -
diff --git a/build/android/pylib/base/test_dispatcher.py b/build/android/pylib/base/test_dispatcher.py deleted file mode 100644 index 327709ca..0000000 --- a/build/android/pylib/base/test_dispatcher.py +++ /dev/null
@@ -1,343 +0,0 @@ -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Dispatches tests, either sharding or replicating them. - -Performs the following steps: -* Create a test collection factory, using the given tests - - If sharding: test collection factory returns the same shared test collection - to all test runners - - If replciating: test collection factory returns a unique test collection to - each test runner, with the same set of tests in each. -* Create a test runner for each device. -* Run each test runner in its own thread, grabbing tests from the test - collection until there are no tests left. -""" - -# TODO(jbudorick) Deprecate and remove this class after any relevant parts have -# been ported to the new environment / test instance model. - -import logging -import threading - -from devil.android import device_errors -from devil.utils import reraiser_thread -from devil.utils import watchdog_timer -from pylib import constants -from pylib.base import base_test_result -from pylib.base import test_collection - - -DEFAULT_TIMEOUT = 7 * 60 # seven minutes - - -class _ThreadSafeCounter(object): - """A threadsafe counter.""" - - def __init__(self): - self._lock = threading.Lock() - self._value = 0 - - def GetAndIncrement(self): - """Get the current value and increment it atomically. - - Returns: - The value before incrementing. - """ - with self._lock: - pre_increment = self._value - self._value += 1 - return pre_increment - - -class _Test(object): - """Holds a test with additional metadata.""" - - def __init__(self, test, tries=0): - """Initializes the _Test object. - - Args: - test: The test. - tries: Number of tries so far. - """ - self.test = test - self.tries = tries - - -def _RunTestsFromQueue(runner, collection, out_results, watcher, - num_retries, tag_results_with_device=False): - """Runs tests from the collection until empty using the given runner. - - Adds TestRunResults objects to the out_results list and may add tests to the - out_retry list. - - Args: - runner: A TestRunner object used to run the tests. - collection: A TestCollection from which to get _Test objects to run. - out_results: A list to add TestRunResults to. - watcher: A watchdog_timer.WatchdogTimer object, used as a shared timeout. - num_retries: Number of retries for a test. - tag_results_with_device: If True, appends the name of the device on which - the test was run to the test name. Used when replicating to identify - which device ran each copy of the test, and to ensure each copy of the - test is recorded separately. - """ - - def TagTestRunResults(test_run_results): - """Tags all results with the last 4 digits of the device id. - - Used when replicating tests to distinguish the same tests run on different - devices. We use a set to store test results, so the hash (generated from - name and tag) must be unique to be considered different results. - """ - new_test_run_results = base_test_result.TestRunResults() - for test_result in test_run_results.GetAll(): - test_result.SetName('%s_%s' % (runner.device_serial[-4:], - test_result.GetName())) - new_test_run_results.AddResult(test_result) - return new_test_run_results - - for test in collection: - watcher.Reset() - try: - if not runner.device.IsOnline(): - # Device is unresponsive, stop handling tests on this device. - msg = 'Device %s is unresponsive.' % runner.device_serial - logging.warning(msg) - raise device_errors.DeviceUnreachableError(msg) - result, retry = runner.RunTest(test.test) - if tag_results_with_device: - result = TagTestRunResults(result) - test.tries += 1 - if retry and test.tries <= num_retries: - # Retry non-passing results, only record passing results. - pass_results = base_test_result.TestRunResults() - pass_results.AddResults(result.GetPass()) - out_results.append(pass_results) - logging.warning('Will retry test %s, try #%s.', retry, test.tries) - collection.add(_Test(test=retry, tries=test.tries)) - else: - # All tests passed or retry limit reached. Either way, record results. - out_results.append(result) - except: - # An unhandleable exception, ensure tests get run by another device and - # reraise this exception on the main thread. - collection.add(test) - raise - finally: - # Retries count as separate tasks so always mark the popped test as done. - collection.test_completed() - - -def _SetUp(runner_factory, device, out_runners, threadsafe_counter): - """Creates a test runner for each device and calls SetUp() in parallel. - - Note: if a device is unresponsive the corresponding TestRunner will not be - added to out_runners. - - Args: - runner_factory: Callable that takes a device and index and returns a - TestRunner object. - device: The device serial number to set up. - out_runners: List to add the successfully set up TestRunner object. - threadsafe_counter: A _ThreadSafeCounter object used to get shard indices. - """ - try: - index = threadsafe_counter.GetAndIncrement() - logging.warning('Creating shard %s for device %s.', index, device) - runner = runner_factory(device, index) - if runner: - runner.SetUp() - out_runners.append(runner) - else: - logging.info('Device %s is not active. Will not create shard %s.', - str(device), index) - except (device_errors.CommandFailedError, - device_errors.CommandTimeoutError, - device_errors.DeviceUnreachableError): - logging.exception('Failed to create shard for %s', str(device)) - - -def _RunAllTests(runners, test_collection_factory, num_retries, timeout=None, - tag_results_with_device=False): - """Run all tests using the given TestRunners. - - Args: - runners: A list of TestRunner objects. - test_collection_factory: A callable to generate a TestCollection object for - each test runner. - num_retries: Number of retries for a test. - timeout: Watchdog timeout in seconds. - tag_results_with_device: If True, appends the name of the device on which - the test was run to the test name. Used when replicating to identify - which device ran each copy of the test, and to ensure each copy of the - test is recorded separately. - - Returns: - A tuple of (TestRunResults object, exit code) - """ - logging.warning('Running tests with %s test %s.', - len(runners), 'runners' if len(runners) != 1 else 'runner') - results = [] - exit_code = 0 - run_results = base_test_result.TestRunResults() - watcher = watchdog_timer.WatchdogTimer(timeout) - test_collections = [test_collection_factory() for _ in runners] - - threads = [ - reraiser_thread.ReraiserThread( - _RunTestsFromQueue, - [r, tc, results, watcher, num_retries, tag_results_with_device], - name=r.device_serial[-4:]) - for r, tc in zip(runners, test_collections)] - - workers = reraiser_thread.ReraiserThreadGroup(threads) - workers.StartAll() - - try: - workers.JoinAll(watcher) - except device_errors.CommandFailedError: - logging.exception('Command failed on device.') - except device_errors.CommandTimeoutError: - logging.exception('Command timed out on device.') - except device_errors.DeviceUnreachableError: - logging.exception('Device became unreachable.') - - if not all((len(tc) == 0 for tc in test_collections)): - logging.error('Only ran %d tests (all devices are likely offline).', - len(results)) - for tc in test_collections: - run_results.AddResults(base_test_result.BaseTestResult( - t, base_test_result.ResultType.UNKNOWN) for t in tc.test_names()) - - for r in results: - run_results.AddTestRunResults(r) - if not run_results.DidRunPass(): - exit_code = constants.ERROR_EXIT_CODE - return (run_results, exit_code) - - -def _CreateRunners(runner_factory, devices, timeout=None): - """Creates a test runner for each device and calls SetUp() in parallel. - - Note: if a device is unresponsive the corresponding TestRunner will not be - included in the returned list. - - Args: - runner_factory: Callable that takes a device and index and returns a - TestRunner object. - devices: List of device serial numbers as strings. - timeout: Watchdog timeout in seconds, defaults to the default timeout. - - Returns: - A list of TestRunner objects. - """ - logging.warning('Creating %s test %s.', len(devices), - 'runners' if len(devices) != 1 else 'runner') - runners = [] - counter = _ThreadSafeCounter() - threads = reraiser_thread.ReraiserThreadGroup( - [reraiser_thread.ReraiserThread(_SetUp, - [runner_factory, d, runners, counter], - name=str(d)[-4:]) - for d in devices]) - threads.StartAll() - threads.JoinAll(watchdog_timer.WatchdogTimer(timeout)) - return runners - - -def _TearDownRunners(runners, timeout=None): - """Calls TearDown() for each test runner in parallel. - - Args: - runners: A list of TestRunner objects. - timeout: Watchdog timeout in seconds, defaults to the default timeout. - """ - threads = reraiser_thread.ReraiserThreadGroup( - [reraiser_thread.ReraiserThread(r.TearDown, name=r.device_serial[-4:]) - for r in runners]) - threads.StartAll() - threads.JoinAll(watchdog_timer.WatchdogTimer(timeout)) - - -def ApplyMaxPerRun(tests, max_per_run): - """Rearrange the tests so that no group contains more than max_per_run tests. - - Args: - tests: - max_per_run: - - Returns: - A list of tests with no more than max_per_run per run. - """ - tests_expanded = [] - for test_group in tests: - if type(test_group) != str: - # Do not split test objects which are not strings. - tests_expanded.append(test_group) - else: - test_split = test_group.split(':') - for i in range(0, len(test_split), max_per_run): - tests_expanded.append(':'.join(test_split[i:i+max_per_run])) - return tests_expanded - - -def RunTests(tests, runner_factory, devices, shard=True, - test_timeout=DEFAULT_TIMEOUT, setup_timeout=DEFAULT_TIMEOUT, - num_retries=2, max_per_run=256): - """Run all tests on attached devices, retrying tests that don't pass. - - Args: - tests: List of tests to run. - runner_factory: Callable that takes a device and index and returns a - TestRunner object. - devices: List of attached devices. - shard: True if we should shard, False if we should replicate tests. - - Sharding tests will distribute tests across all test runners through a - shared test collection. - - Replicating tests will copy all tests to each test runner through a - unique test collection for each test runner. - test_timeout: Watchdog timeout in seconds for running tests. - setup_timeout: Watchdog timeout in seconds for creating and cleaning up - test runners. - num_retries: Number of retries for a test. - max_per_run: Maximum number of tests to run in any group. - - Returns: - A tuple of (base_test_result.TestRunResults object, exit code). - """ - if not tests: - logging.critical('No tests to run.') - return (base_test_result.TestRunResults(), constants.ERROR_EXIT_CODE) - - tests_expanded = ApplyMaxPerRun(tests, max_per_run) - if shard: - # Generate a shared TestCollection object for all test runners, so they - # draw from a common pool of tests. - shared_test_collection = test_collection.TestCollection( - [_Test(t) for t in tests_expanded]) - test_collection_factory = lambda: shared_test_collection - tag_results_with_device = False - log_string = 'sharded across devices' - else: - # Generate a unique TestCollection object for each test runner, but use - # the same set of tests. - test_collection_factory = lambda: test_collection.TestCollection( - [_Test(t) for t in tests_expanded]) - tag_results_with_device = True - log_string = 'replicated on each device' - - logging.info('Will run %d tests (%s): %s', - len(tests_expanded), log_string, str(tests_expanded)) - runners = _CreateRunners(runner_factory, devices, setup_timeout) - try: - return _RunAllTests(runners, test_collection_factory, - num_retries, test_timeout, tag_results_with_device) - finally: - try: - _TearDownRunners(runners, setup_timeout) - except device_errors.DeviceUnreachableError as e: - logging.warning('Device unresponsive during TearDown: [%s]', e) - except Exception: # pylint: disable=broad-except - logging.exception('Unexpected exception caught during TearDown')
diff --git a/build/android/pylib/base/test_dispatcher_unittest.py b/build/android/pylib/base/test_dispatcher_unittest.py deleted file mode 100755 index 186a0721..0000000 --- a/build/android/pylib/base/test_dispatcher_unittest.py +++ /dev/null
@@ -1,241 +0,0 @@ -#!/usr/bin/env python -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Unittests for test_dispatcher.py.""" - -# pylint: disable=no-self-use -# pylint: disable=protected-access - -import unittest - -from pylib.base import base_test_result -from pylib.base import test_collection -from pylib.base import test_dispatcher -from pylib.constants import host_paths - -with host_paths.SysPath(host_paths.DEVIL_PATH): - from devil.android import device_utils - from devil.android.sdk import adb_wrapper - from devil.constants import exit_codes - from devil.utils import watchdog_timer - -with host_paths.SysPath(host_paths.PYMOCK_PATH): - import mock # pylint: disable=import-error - - -class TestException(Exception): - pass - - -def _MockDevice(serial): - d = mock.MagicMock(spec=device_utils.DeviceUtils) - d.__str__.return_value = serial - d.adb = mock.MagicMock(spec=adb_wrapper.AdbWrapper) - d.adb.GetDeviceSerial = mock.MagicMock(return_value=serial) - d.IsOnline = mock.MagicMock(return_value=True) - return d - - -class MockRunner(object): - """A mock TestRunner.""" - def __init__(self, device=None, shard_index=0): - self.device = device or _MockDevice('0') - self.device_serial = self.device.adb.GetDeviceSerial() - self.shard_index = shard_index - self.setups = 0 - self.teardowns = 0 - - def RunTest(self, test): - results = base_test_result.TestRunResults() - results.AddResult( - base_test_result.BaseTestResult(test, base_test_result.ResultType.PASS)) - return (results, None) - - def SetUp(self): - self.setups += 1 - - def TearDown(self): - self.teardowns += 1 - - -class MockRunnerFail(MockRunner): - def RunTest(self, test): - results = base_test_result.TestRunResults() - results.AddResult( - base_test_result.BaseTestResult(test, base_test_result.ResultType.FAIL)) - return (results, test) - - -class MockRunnerFailTwice(MockRunner): - def __init__(self, device=None, shard_index=0): - super(MockRunnerFailTwice, self).__init__(device, shard_index) - self._fails = 0 - - def RunTest(self, test): - self._fails += 1 - results = base_test_result.TestRunResults() - if self._fails <= 2: - results.AddResult(base_test_result.BaseTestResult( - test, base_test_result.ResultType.FAIL)) - return (results, test) - else: - results.AddResult(base_test_result.BaseTestResult( - test, base_test_result.ResultType.PASS)) - return (results, None) - - -class MockRunnerException(MockRunner): - def RunTest(self, test): - raise TestException - - -class TestFunctions(unittest.TestCase): - """Tests test_dispatcher._RunTestsFromQueue.""" - @staticmethod - def _RunTests(mock_runner, tests): - results = [] - tests = test_collection.TestCollection( - [test_dispatcher._Test(t) for t in tests]) - test_dispatcher._RunTestsFromQueue(mock_runner, tests, results, - watchdog_timer.WatchdogTimer(None), 2) - run_results = base_test_result.TestRunResults() - for r in results: - run_results.AddTestRunResults(r) - return run_results - - def testRunTestsFromQueue(self): - results = TestFunctions._RunTests(MockRunner(), ['a', 'b']) - self.assertEqual(len(results.GetPass()), 2) - self.assertEqual(len(results.GetNotPass()), 0) - - def testRunTestsFromQueueRetry(self): - results = TestFunctions._RunTests(MockRunnerFail(), ['a', 'b']) - self.assertEqual(len(results.GetPass()), 0) - self.assertEqual(len(results.GetFail()), 2) - - def testRunTestsFromQueueFailTwice(self): - results = TestFunctions._RunTests(MockRunnerFailTwice(), ['a', 'b']) - self.assertEqual(len(results.GetPass()), 2) - self.assertEqual(len(results.GetNotPass()), 0) - - def testSetUp(self): - runners = [] - counter = test_dispatcher._ThreadSafeCounter() - test_dispatcher._SetUp(MockRunner, _MockDevice('0'), runners, counter) - self.assertEqual(len(runners), 1) - self.assertEqual(runners[0].setups, 1) - - def testThreadSafeCounter(self): - counter = test_dispatcher._ThreadSafeCounter() - for i in xrange(5): - self.assertEqual(counter.GetAndIncrement(), i) - - def testApplyMaxPerRun(self): - self.assertEqual( - ['A:B', 'C:D', 'E', 'F:G', 'H:I'], - test_dispatcher.ApplyMaxPerRun(['A:B', 'C:D:E', 'F:G:H:I'], 2)) - - -class TestThreadGroupFunctions(unittest.TestCase): - """Tests test_dispatcher._RunAllTests and test_dispatcher._CreateRunners.""" - def setUp(self): - self.tests = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - shared_test_collection = test_collection.TestCollection( - [test_dispatcher._Test(t) for t in self.tests]) - self.test_collection_factory = lambda: shared_test_collection - - def testCreate(self): - runners = test_dispatcher._CreateRunners( - MockRunner, [_MockDevice('0'), _MockDevice('1')]) - for runner in runners: - self.assertEqual(runner.setups, 1) - self.assertEqual(set([r.device_serial for r in runners]), - set(['0', '1'])) - self.assertEqual(set([r.shard_index for r in runners]), - set([0, 1])) - - def testRun(self): - runners = [MockRunner(_MockDevice('0')), MockRunner(_MockDevice('1'))] - results, exit_code = test_dispatcher._RunAllTests( - runners, self.test_collection_factory, 0) - self.assertEqual(len(results.GetPass()), len(self.tests)) - self.assertEqual(exit_code, 0) - - def testTearDown(self): - runners = [MockRunner(_MockDevice('0')), MockRunner(_MockDevice('1'))] - test_dispatcher._TearDownRunners(runners) - for runner in runners: - self.assertEqual(runner.teardowns, 1) - - def testRetry(self): - runners = test_dispatcher._CreateRunners( - MockRunnerFail, [_MockDevice('0'), _MockDevice('1')]) - results, exit_code = test_dispatcher._RunAllTests( - runners, self.test_collection_factory, 0) - self.assertEqual(len(results.GetFail()), len(self.tests)) - self.assertEqual(exit_code, exit_codes.ERROR) - - def testReraise(self): - runners = test_dispatcher._CreateRunners( - MockRunnerException, [_MockDevice('0'), _MockDevice('1')]) - with self.assertRaises(TestException): - test_dispatcher._RunAllTests(runners, self.test_collection_factory, 0) - - -class TestShard(unittest.TestCase): - """Tests test_dispatcher.RunTests with sharding.""" - @staticmethod - def _RunShard(runner_factory): - return test_dispatcher.RunTests( - ['a', 'b', 'c'], runner_factory, [_MockDevice('0'), _MockDevice('1')], - shard=True) - - def testShard(self): - results, exit_code = TestShard._RunShard(MockRunner) - self.assertEqual(len(results.GetPass()), 3) - self.assertEqual(exit_code, 0) - - def testFailing(self): - results, exit_code = TestShard._RunShard(MockRunnerFail) - self.assertEqual(len(results.GetPass()), 0) - self.assertEqual(len(results.GetFail()), 3) - self.assertEqual(exit_code, exit_codes.ERROR) - - def testNoTests(self): - results, exit_code = test_dispatcher.RunTests( - [], MockRunner, [_MockDevice('0'), _MockDevice('1')], shard=True) - self.assertEqual(len(results.GetAll()), 0) - self.assertEqual(exit_code, exit_codes.ERROR) - - -class TestReplicate(unittest.TestCase): - """Tests test_dispatcher.RunTests with replication.""" - @staticmethod - def _RunReplicate(runner_factory): - return test_dispatcher.RunTests( - ['a', 'b', 'c'], runner_factory, [_MockDevice('0'), _MockDevice('1')], - shard=False) - - def testReplicate(self): - results, exit_code = TestReplicate._RunReplicate(MockRunner) - # We expect 6 results since each test should have been run on every device - self.assertEqual(len(results.GetPass()), 6) - self.assertEqual(exit_code, 0) - - def testFailing(self): - results, exit_code = TestReplicate._RunReplicate(MockRunnerFail) - self.assertEqual(len(results.GetPass()), 0) - self.assertEqual(len(results.GetFail()), 6) - self.assertEqual(exit_code, exit_codes.ERROR) - - def testNoTests(self): - results, exit_code = test_dispatcher.RunTests( - [], MockRunner, [_MockDevice('0'), _MockDevice('1')], shard=False) - self.assertEqual(len(results.GetAll()), 0) - self.assertEqual(exit_code, exit_codes.ERROR) - - -if __name__ == '__main__': - unittest.main()
diff --git a/build/android/pylib/base/test_instance_factory.py b/build/android/pylib/base/test_instance_factory.py index 3ce77f9d..7c21260 100644 --- a/build/android/pylib/base/test_instance_factory.py +++ b/build/android/pylib/base/test_instance_factory.py
@@ -5,6 +5,7 @@ from pylib.gtest import gtest_test_instance from pylib.instrumentation import instrumentation_test_instance from pylib.junit import junit_test_instance +from pylib.linker import linker_test_instance from pylib.monkey import monkey_test_instance from pylib.perf import perf_test_instance from pylib.utils import device_dependencies @@ -20,6 +21,8 @@ args, device_dependencies.GetDataDependencies, error_func) elif args.command == 'junit': return junit_test_instance.JunitTestInstance(args, error_func) + elif args.command == 'linker': + return linker_test_instance.LinkerTestInstance(args) elif args.command == 'monkey': return monkey_test_instance.MonkeyTestInstance(args, error_func) elif args.command == 'perf':
diff --git a/build/android/pylib/base/test_run_factory.py b/build/android/pylib/base/test_run_factory.py index 0d71e97..1a28728 100644 --- a/build/android/pylib/base/test_run_factory.py +++ b/build/android/pylib/base/test_run_factory.py
@@ -5,10 +5,12 @@ from pylib.gtest import gtest_test_instance from pylib.instrumentation import instrumentation_test_instance from pylib.junit import junit_test_instance +from pylib.linker import linker_test_instance from pylib.monkey import monkey_test_instance from pylib.local.device import local_device_environment from pylib.local.device import local_device_gtest_run from pylib.local.device import local_device_instrumentation_test_run +from pylib.local.device import local_device_linker_test_run from pylib.local.device import local_device_monkey_test_run from pylib.local.device import local_device_perf_test_run from pylib.local.machine import local_machine_environment @@ -35,6 +37,9 @@ instrumentation_test_instance.InstrumentationTestInstance): return (local_device_instrumentation_test_run .LocalDeviceInstrumentationTestRun(env, test_instance)) + if isinstance(test_instance, linker_test_instance.LinkerTestInstance): + return (local_device_linker_test_run + .LocalDeviceLinkerTestRun(env, test_instance)) if isinstance(test_instance, monkey_test_instance.MonkeyTestInstance): return (local_device_monkey_test_run .LocalDeviceMonkeyTestRun(env, test_instance))
diff --git a/build/android/pylib/linker/linker_test_instance.py b/build/android/pylib/linker/linker_test_instance.py new file mode 100644 index 0000000..ce696f2 --- /dev/null +++ b/build/android/pylib/linker/linker_test_instance.py
@@ -0,0 +1,56 @@ +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from pylib.base import test_instance +from pylib.constants import host_paths +from pylib.linker import test_case + +with host_paths.SysPath(host_paths.BUILD_COMMON_PATH): + import unittest_util + +_MODERN_LINKER_MINIMUM_SDK_INT = 23 + +class LinkerTestInstance(test_instance.TestInstance): + + def __init__(self, args): + super(LinkerTestInstance, self).__init__() + self._test_apk = args.test_apk + self._test_filter = args.test_filter + + @property + def test_apk(self): + return self._test_apk + + @property + def test_filter(self): + return self._test_filter + + def GetTests(self, min_device_sdk): + tests = [ + test_case.LinkerSharedRelroTest(is_modern_linker=False, + is_low_memory=False), + test_case.LinkerSharedRelroTest(is_modern_linker=False, + is_low_memory=True) + ] + if min_device_sdk >= _MODERN_LINKER_MINIMUM_SDK_INT: + tests.append(test_case.LinkerSharedRelroTest(is_modern_linker=True)) + + if self._test_filter: + filtered_names = unittest_util.FilterTestNames( + (t.qualified_name for t in tests), self._test_filter) + tests = [ + t for t in tests + if t.qualified_name in filtered_names] + + return tests + + def SetUp(self): + pass + + def TearDown(self): + pass + + def TestType(self): + return 'linker' +
diff --git a/build/android/pylib/linker/setup.py b/build/android/pylib/linker/setup.py deleted file mode 100644 index 3f380ead..0000000 --- a/build/android/pylib/linker/setup.py +++ /dev/null
@@ -1,60 +0,0 @@ -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Setup for linker tests.""" - -import logging - -from pylib.constants import host_paths -from pylib.linker import test_case -from pylib.linker import test_runner - -with host_paths.SysPath(host_paths.BUILD_COMMON_PATH): - import unittest_util # pylint: disable=import-error - -# ModernLinker requires Android M (API level 23) or later. -_VERSION_SDK_PROPERTY = 'ro.build.version.sdk' -_MODERN_LINKER_MINIMUM_SDK_INT = 23 - -def Setup(args, devices): - """Creates a list of test cases and a runner factory. - - Args: - args: an argparse.Namespace object. - devices: an iterable of available devices. - Returns: - A tuple of (TestRunnerFactory, tests). - """ - legacy_linker_tests = [ - test_case.LinkerSharedRelroTest(is_modern_linker=False, - is_low_memory=False), - test_case.LinkerSharedRelroTest(is_modern_linker=False, - is_low_memory=True), - ] - modern_linker_tests = [ - test_case.LinkerSharedRelroTest(is_modern_linker=True), - ] - - min_sdk_int = 1 << 31 - for device in devices: - min_sdk_int = min(min_sdk_int, device.build_version_sdk) - - if min_sdk_int >= _MODERN_LINKER_MINIMUM_SDK_INT: - all_tests = legacy_linker_tests + modern_linker_tests - else: - all_tests = legacy_linker_tests - logging.warn('Not running LinkerModern tests (requires API %d, found %d)', - _MODERN_LINKER_MINIMUM_SDK_INT, min_sdk_int) - - if args.test_filter: - all_test_names = [test.qualified_name for test in all_tests] - filtered_test_names = unittest_util.FilterTestNames(all_test_names, - args.test_filter) - all_tests = [t for t in all_tests \ - if t.qualified_name in filtered_test_names] - - def TestRunnerFactory(device, _shard_index): - return test_runner.LinkerTestRunner(device, args.tool) - - return (TestRunnerFactory, all_tests)
diff --git a/build/android/pylib/linker/test_case.py b/build/android/pylib/linker/test_case.py index 475b730..f4ae7c65 100644 --- a/build/android/pylib/linker/test_case.py +++ b/build/android/pylib/linker/test_case.py
@@ -94,7 +94,10 @@ except device_errors.CommandTimeoutError: result = ResultType.TIMEOUT - return result, '\n'.join(device.adb.Logcat(dump=True)) + logcat = device.adb.Logcat(dump=True) + + logmon.Close() + return result, '\n'.join(logcat) class LibraryLoadMap(dict): @@ -182,14 +185,8 @@ result_text = 'TIMEOUT' print '[ %*s ] %s' % (margin, result_text, self.tagged_name) - results = base_test_result.TestRunResults() - results.AddResult( - base_test_result.BaseTestResult( - self.tagged_name, - status, - log=logs)) + return base_test_result.BaseTestResult(self.tagged_name, status, log=logs) - return results def __str__(self): return self.tagged_name
diff --git a/build/android/pylib/linker/test_runner.py b/build/android/pylib/linker/test_runner.py deleted file mode 100644 index d345952..0000000 --- a/build/android/pylib/linker/test_runner.py +++ /dev/null
@@ -1,97 +0,0 @@ -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Runs linker tests on a particular device.""" - -import logging -import os.path -import sys -import traceback - -from pylib import constants -from pylib.base import base_test_result -from pylib.base import base_test_runner -from pylib.linker import test_case - - -# Name of the Android package to install for this to work. -_PACKAGE_NAME = 'ChromiumLinkerTest' - - -class LinkerExceptionTestResult(base_test_result.BaseTestResult): - """Test result corresponding to a python exception in a host-custom test.""" - - def __init__(self, test_name, exc_info): - """Constructs a LinkerExceptionTestResult object. - - Args: - test_name: name of the test which raised an exception. - exc_info: exception info, ostensibly from sys.exc_info(). - """ - exc_type, exc_value, exc_traceback = exc_info - trace_info = ''.join(traceback.format_exception(exc_type, exc_value, - exc_traceback)) - log_msg = 'Exception:\n' + trace_info - - super(LinkerExceptionTestResult, self).__init__( - test_name, - base_test_result.ResultType.FAIL, - log="%s %s" % (exc_type, log_msg)) - - -class LinkerTestRunner(base_test_runner.BaseTestRunner): - """Orchestrates running a set of linker tests. - - Any Python exceptions in the tests are caught and translated into a failed - result, rather than being re-raised on the main thread. - """ - - #override - def __init__(self, device, tool): - """Creates a new LinkerTestRunner. - - Args: - device: Attached android device. - tool: Name of the Valgrind tool. - """ - super(LinkerTestRunner, self).__init__(device, tool) - - #override - def InstallTestPackage(self): - apk_path = os.path.join( - constants.GetOutDirectory(), 'apks', '%s.apk' % _PACKAGE_NAME) - - if not os.path.exists(apk_path): - raise Exception('%s not found, please build it' % apk_path) - - self.device.Install(apk_path) - - #override - def RunTest(self, test): - """Sets up and runs a test case. - - Args: - test: An object which is ostensibly a subclass of LinkerTestCaseBase. - - Returns: - A TestRunResults object which contains the result produced by the test - and, in the case of a failure, the test that should be retried. - """ - - assert isinstance(test, test_case.LinkerTestCaseBase) - - try: - results = test.Run(self.device) - except Exception: # pylint: disable=broad-except - logging.exception('Caught exception while trying to run test: ' + - test.tagged_name) - exc_info = sys.exc_info() - results = base_test_result.TestRunResults() - results.AddResult(LinkerExceptionTestResult( - test.tagged_name, exc_info)) - - if not results.DidRunPass(): - return results, test - else: - return results, None
diff --git a/build/android/pylib/local/device/local_device_linker_test_run.py b/build/android/pylib/local/device/local_device_linker_test_run.py new file mode 100644 index 0000000..7b32538 --- /dev/null +++ b/build/android/pylib/local/device/local_device_linker_test_run.py
@@ -0,0 +1,76 @@ +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import logging +import sys +import traceback + +from pylib.base import base_test_result +from pylib.linker import test_case +from pylib.local.device import local_device_environment +from pylib.local.device import local_device_test_run + + +class LinkerExceptionTestResult(base_test_result.BaseTestResult): + """Test result corresponding to a python exception in a host-custom test.""" + + def __init__(self, test_name, exc_info): + """Constructs a LinkerExceptionTestResult object. + + Args: + test_name: name of the test which raised an exception. + exc_info: exception info, ostensibly from sys.exc_info(). + """ + exc_type, exc_value, exc_traceback = exc_info + trace_info = ''.join(traceback.format_exception(exc_type, exc_value, + exc_traceback)) + log_msg = 'Exception:\n' + trace_info + + super(LinkerExceptionTestResult, self).__init__( + test_name, + base_test_result.ResultType.FAIL, + log="%s %s" % (exc_type, log_msg)) + + +class LocalDeviceLinkerTestRun(local_device_test_run.LocalDeviceTestRun): + + def _CreateShards(self, tests): + return tests + + def _GetTests(self): + min_device_sdk = min(d.build_version_sdk for d in self._env.devices) + return self._test_instance.GetTests(min_device_sdk) + + def _GetUniqueTestName(self, test): + return test.qualified_name + + def _RunTest(self, device, test): + assert isinstance(test, test_case.LinkerTestCaseBase) + + try: + result = test.Run(device) + except Exception: # pylint: disable=broad-except + logging.exception('Caught exception while trying to run test: ' + + test.tagged_name) + exc_info = sys.exc_info() + result = LinkerExceptionTestResult(test.tagged_name, exc_info) + + return result, None + + def SetUp(self): + @local_device_environment.handle_shard_failures_with( + on_failure=self._env.BlacklistDevice) + def individual_device_set_up(dev): + dev.Install(self._test_instance.test_apk) + + self._env.parallel_devices.pMap(individual_device_set_up) + + def _ShouldShard(self): + return True + + def TearDown(self): + pass + + def TestPackage(self): + pass
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index 39e87bc..b5b4da12 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -31,11 +31,9 @@ from pylib import constants from pylib.base import base_test_result from pylib.base import environment_factory -from pylib.base import test_dispatcher from pylib.base import test_instance_factory from pylib.base import test_run_factory from pylib.constants import host_paths -from pylib.linker import setup as linker_setup from pylib.results import json_results from pylib.results import report_results @@ -80,6 +78,13 @@ type=int, default=2, help=('Number of retries for a test before ' 'giving up (default: %(default)s).')) + group.add_argument('--repeat', '--gtest_repeat', '--gtest-repeat', + dest='repeat', type=int, default=0, + help='Number of times to repeat the specified set of ' + 'tests.') + group.add_argument('--break-on-failure', '--break_on_failure', + dest='break_on_failure', action='store_true', + help='Whether to break on failure.') group.add_argument('-v', '--verbose', dest='verbose_count', @@ -220,13 +225,6 @@ group.add_argument('--delete-stale-data', dest='delete_stale_data', action='store_true', help='Delete stale test data on the device.') - group.add_argument('--repeat', '--gtest_repeat', '--gtest-repeat', - dest='repeat', type=int, default=0, - help='Number of times to repeat the specified set of ' - 'tests.') - group.add_argument('--break-on-failure', '--break_on_failure', - dest='break_on_failure', action='store_true', - help='Whether to break on failure.') group.add_argument('--extract-test-list-from-filter', action='store_true', help='When a test filter is specified, and the list of ' @@ -259,6 +257,8 @@ group = parser.add_argument_group('Linker Test Options') group.add_argument('-f', '--gtest-filter', dest='test_filter', help='googletest-style filter string.') + group.add_argument('--test-apk', type=os.path.realpath, + help='Path to the linker test APK.') AddCommonOptions(parser) AddDeviceOptions(parser) @@ -271,14 +271,6 @@ dest='test_filter', help=('Test filter (if not fully qualified, will run all matches).')) argument_group.add_argument( - '--repeat', '--gtest_repeat', '--gtest-repeat', dest='repeat', - type=int, default=0, - help='Number of times to repeat the specified set of tests.') - argument_group.add_argument( - '--break-on-failure', '--break_on_failure', - dest='break_on_failure', action='store_true', - help='Whether to break on failure.') - argument_group.add_argument( '-A', '--annotation', dest='annotation_str', help=('Comma-separated list of annotations. Run only tests with any of ' 'the given annotations. An annotation can be either a key or a ' @@ -421,15 +413,6 @@ group.add_argument( '--package-filter', dest='package_filter', help='Filters tests by package.') - # TODO(mikecase): Add --repeat and --break-on-failure to common options. - # These options are required for platform-mode support. - group.add_argument( - '--repeat', dest='repeat', type=int, default=0, - help='Number of times to repeat the specified set of tests.') - group.add_argument( - '--break-on-failure', '--break_on_failure', - dest='break_on_failure', action='store_true', - help='Whether to break on failure.') group.add_argument( '--runner-filter', dest='runner_filter', help='Filters tests by runner class. Must be fully qualified.') @@ -460,13 +443,6 @@ '--seed', type=int, help='Seed value for pseudo-random generator. Same seed value generates ' 'the same sequence of events. Seed is randomized by default.') - group.add_argument( - '--repeat', dest='repeat', type=int, default=0, - help='Number of times to repeat the specified set of tests.') - group.add_argument( - '--break-on-failure', '--break_on_failure', - dest='break_on_failure', action='store_true', - help='Whether to break on failure.') AddCommonOptions(parser) AddDeviceOptions(parser) @@ -559,12 +535,6 @@ 'given level.') group.add_argument('--known-devices-file', help='Path to known device list.') group.add_argument( - '--repeat', dest='repeat', type=int, default=0, - help='Number of times to repeat the specified set of tests.') - group.add_argument( - '--break-on-failure', '--break_on_failure', dest='break_on_failure', - action='store_true', help='Whether to break on failure.') - group.add_argument( '--write-buildbot-json', action='store_true', help='Whether to output buildbot json.') # TODO(rnephew): Move up to top level options when implemented on all tests. @@ -584,25 +554,6 @@ AddCommonOptions(parser) -def _RunLinkerTests(args, devices): - """Subcommand of RunTestsCommands which runs linker tests.""" - runner_factory, tests = linker_setup.Setup(args, devices) - - results, exit_code = test_dispatcher.RunTests( - tests, runner_factory, devices, shard=True, test_timeout=60, - num_retries=args.num_retries) - - report_results.LogFull( - results=results, - test_type='Linker test', - test_package='ChromiumLinkerTest') - - if args.json_results_file: - json_results.GenerateJsonResultsFile([results], args.json_results_file) - - return exit_code - - def _RunPythonTests(args): """Subcommand of RunTestsCommand which runs python unit tests.""" suite_vars = constants.PYTHON_UNIT_TEST_SUITES[args.suite_name] @@ -653,7 +604,7 @@ _DEFAULT_PLATFORM_MODE_TESTS = ['gtest', 'instrumentation', 'junit', - 'monkey', 'perf'] + 'linker', 'monkey', 'perf'] def RunTestsCommand(args): # pylint: disable=too-many-return-statements @@ -685,13 +636,7 @@ os.unlink(ports._TEST_SERVER_PORT_LOCKFILE) # pylint: enable=protected-access - def get_devices(): - return _GetAttachedDevices(args.blacklist_file, args.test_device, - args.enable_device_cache, args.num_retries) - - if command == 'linker': - return _RunLinkerTests(args, get_devices()) - elif command == 'python': + if command == 'python': return _RunPythonTests(args) else: raise Exception('Unknown test type.') @@ -702,6 +647,7 @@ 'gtest', 'instrumentation', 'junit', + 'linker', 'monkey', 'perf', ]
diff --git a/build/android/test_runner.pydeps b/build/android/test_runner.pydeps index 2d4200c..7a687cf 100644 --- a/build/android/test_runner.pydeps +++ b/build/android/test_runner.pydeps
@@ -126,11 +126,9 @@ pylib/android/logdog_logcat_monitor.py pylib/base/__init__.py pylib/base/base_test_result.py -pylib/base/base_test_runner.py pylib/base/environment.py pylib/base/environment_factory.py pylib/base/test_collection.py -pylib/base/test_dispatcher.py pylib/base/test_exception.py pylib/base/test_instance.py pylib/base/test_instance_factory.py @@ -149,14 +147,14 @@ pylib/junit/__init__.py pylib/junit/junit_test_instance.py pylib/linker/__init__.py -pylib/linker/setup.py +pylib/linker/linker_test_instance.py pylib/linker/test_case.py -pylib/linker/test_runner.py pylib/local/__init__.py pylib/local/device/__init__.py pylib/local/device/local_device_environment.py pylib/local/device/local_device_gtest_run.py pylib/local/device/local_device_instrumentation_test_run.py +pylib/local/device/local_device_linker_test_run.py pylib/local/device/local_device_monkey_test_run.py pylib/local/device/local_device_perf_test_run.py pylib/local/device/local_device_test_run.py
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 322f5ae..b7a42d3 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -553,6 +553,11 @@ "--test-suite", invoker.test_suite, ] + } else if (_test_type == "linker") { + test_runner_args += [ + "--test-apk", + "@FileArg($_rebased_apk_build_config:deps_info:apk_path)", + ] } else { assert(false, "Invalid test type: $_test_type.") }
diff --git a/cc/input/main_thread_scrolling_reason.h b/cc/input/main_thread_scrolling_reason.h index 191318b..85a8ea117 100644 --- a/cc/input/main_thread_scrolling_reason.h +++ b/cc/input/main_thread_scrolling_reason.h
@@ -32,6 +32,8 @@ kHandlingScrollFromMainThread = 1 << 13, kCustomScrollbarScrolling = 1 << 15, kHasOpacity = 1 << 16, + kHasTransform = 1 << 17, + kBackgroundNotOpaqueInRect = 1 << 18, // Transient scrolling reasons. These are computed for each scroll begin. kNonFastScrollableRegion = 1 << 5, @@ -43,7 +45,7 @@ kPageBasedScrolling = 1 << 12, // The number of flags in this struct (excluding itself). - kMainThreadScrollingReasonCount = 18, + kMainThreadScrollingReasonCount = 20, }; // Returns true if the given MainThreadScrollingReason can be set by the main @@ -53,7 +55,8 @@ kNotScrollingOnMain | kHasBackgroundAttachmentFixedObjects | kHasNonLayerViewportConstrainedObjects | kThreadedScrollingDisabled | kScrollbarScrolling | kPageOverlay | kHandlingScrollFromMainThread | - kCustomScrollbarScrolling | kHasOpacity; + kCustomScrollbarScrolling | kHasOpacity | kHasTransform | + kBackgroundNotOpaqueInRect; return (reasons & reasons_set_by_main_thread) == reasons; } @@ -100,6 +103,10 @@ tracedValue->AppendString("Custom scrollbar scrolling"); if (reasons & MainThreadScrollingReason::kHasOpacity) tracedValue->AppendString("Has opacity"); + if (reasons & MainThreadScrollingReason::kHasTransform) + tracedValue->AppendString("Has transform"); + if (reasons & MainThreadScrollingReason::kBackgroundNotOpaqueInRect) + tracedValue->AppendString("Background is not opaque in rect"); // Transient scrolling reasons. if (reasons & MainThreadScrollingReason::kNonFastScrollableRegion)
diff --git a/cc/ipc/BUILD.gn b/cc/ipc/BUILD.gn index e8070f1..e5cbcef4b 100644 --- a/cc/ipc/BUILD.gn +++ b/cc/ipc/BUILD.gn
@@ -53,6 +53,7 @@ "selection.mojom", "shared_quad_state.mojom", "surface_id.mojom", + "surface_info.mojom", "surface_reference.mojom", "surface_sequence.mojom", "transferable_resource.mojom", @@ -111,6 +112,7 @@ "selection_struct_traits.h", "shared_quad_state_struct_traits.h", "surface_id_struct_traits.h", + "surface_info_struct_traits.h", "surface_reference_struct_traits.h", "surface_sequence_struct_traits.h", "transferable_resource_struct_traits.cc",
diff --git a/cc/ipc/display_compositor.mojom b/cc/ipc/display_compositor.mojom index dd1e371c..1b405f8 100644 --- a/cc/ipc/display_compositor.mojom +++ b/cc/ipc/display_compositor.mojom
@@ -7,7 +7,7 @@ import "cc/ipc/frame_sink_id.mojom"; import "cc/ipc/mojo_compositor_frame_sink.mojom"; import "cc/ipc/surface_id.mojom"; -import "cc/ipc/surface_sequence.mojom"; +import "cc/ipc/surface_info.mojom"; import "gpu/ipc/common/surface_handle.mojom"; import "mojo/common/time.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; @@ -68,7 +68,5 @@ // Called by the display compositor immediately upon receiving a // CompositorFrame with a new SurfaceId for the first time. - OnSurfaceCreated(cc.mojom.SurfaceId surface_id, - gfx.mojom.Size frame_size, - float device_scale_factor); + OnSurfaceCreated(SurfaceInfo surface_info); };
diff --git a/cc/ipc/surface_info.mojom b/cc/ipc/surface_info.mojom new file mode 100644 index 0000000..490009a --- /dev/null +++ b/cc/ipc/surface_info.mojom
@@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module cc.mojom; + +import "cc/ipc/surface_id.mojom"; +import "ui/gfx/geometry/mojo/geometry.mojom"; + +// Holds information about an embeddable surface. This data can be passed +// across clients to embed the associated surface in another client. +struct SurfaceInfo { + SurfaceId surface_id; + float device_scale_factor; + gfx.mojom.Size size_in_pixels; +}; +
diff --git a/cc/ipc/surface_info.typemap b/cc/ipc/surface_info.typemap new file mode 100644 index 0000000..3faab7de --- /dev/null +++ b/cc/ipc/surface_info.typemap
@@ -0,0 +1,11 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +mojom = "//cc/ipc/surface_info.mojom" +public_headers = [ "//cc/surfaces/surface_info.h" ] +traits_headers = [ "//cc/ipc/surface_info_struct_traits.h" ] +deps = [ + "//cc/ipc:struct_traits", +] +type_mappings = [ "cc.mojom.SurfaceInfo=cc::SurfaceInfo" ]
diff --git a/cc/ipc/surface_info_struct_traits.h b/cc/ipc/surface_info_struct_traits.h new file mode 100644 index 0000000..b1484f8 --- /dev/null +++ b/cc/ipc/surface_info_struct_traits.h
@@ -0,0 +1,36 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_IPC_SURFACE_INFO_STRUCT_TRAITS_H_ +#define CC_IPC_SURFACE_INFO_STRUCT_TRAITS_H_ + +#include "cc/ipc/surface_info.mojom-shared.h" +#include "cc/surfaces/surface_info.h" + +namespace mojo { + +template <> +struct StructTraits<cc::mojom::SurfaceInfoDataView, cc::SurfaceInfo> { + static const cc::SurfaceId& surface_id(const cc::SurfaceInfo& surface_info) { + return surface_info.id(); + } + + static float device_scale_factor(const cc::SurfaceInfo& surface_info) { + return surface_info.device_scale_factor(); + } + + static const gfx::Size& size_in_pixels(const cc::SurfaceInfo& surface_info) { + return surface_info.size_in_pixels(); + } + + static bool Read(cc::mojom::SurfaceInfoDataView data, cc::SurfaceInfo* out) { + out->device_scale_factor_ = data.device_scale_factor(); + return data.ReadSurfaceId(&out->id_) && + data.ReadSizeInPixels(&out->size_in_pixels_); + } +}; + +} // namespace mojo + +#endif // CC_IPC_SURFACE_INFO_STRUCT_TRAITS_H_
diff --git a/cc/ipc/typemaps.gni b/cc/ipc/typemaps.gni index c0e8c47..f141dc1 100644 --- a/cc/ipc/typemaps.gni +++ b/cc/ipc/typemaps.gni
@@ -15,6 +15,7 @@ "//cc/ipc/selection.typemap", "//cc/ipc/shared_quad_state.typemap", "//cc/ipc/surface_id.typemap", + "//cc/ipc/surface_info.typemap", "//cc/ipc/surface_reference.typemap", "//cc/ipc/surface_sequence.typemap", "//cc/ipc/transferable_resource.typemap",
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index 5a097f81..2e28374 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc
@@ -392,9 +392,7 @@ UpdateRootSurfaceResourcesLocked(); } -void Display::OnSurfaceCreated(const SurfaceId& surface_id, - const gfx::Size& frame, - float device_scale_factor) {} +void Display::OnSurfaceCreated(const SurfaceInfo& surface_info) {} const SurfaceId& Display::CurrentSurfaceId() { return current_surface_id_;
diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h index 238f00c5..a93f317 100644 --- a/cc/surfaces/display.h +++ b/cc/surfaces/display.h
@@ -86,9 +86,7 @@ // SurfaceObserver implementation. void OnSurfaceDamaged(const SurfaceId& surface, bool* changed) override; - void OnSurfaceCreated(const SurfaceId& surface_id, - const gfx::Size& frame, - float device_scale_factor) override; + void OnSurfaceCreated(const SurfaceInfo& surface_info) override; bool has_scheduler() const { return !!scheduler_; } DirectRenderer* renderer_for_testing() const { return renderer_.get(); }
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc index 75c46bee..8a859f66 100644 --- a/cc/surfaces/surface_factory.cc +++ b/cc/surfaces/surface_factory.cc
@@ -12,6 +12,7 @@ #include "cc/output/copy_output_request.h" #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_factory_client.h" +#include "cc/surfaces/surface_info.h" #include "cc/surfaces/surface_manager.h" #include "ui/gfx/geometry/size.h" @@ -67,8 +68,8 @@ // CompositorFrames may not be populated with a RenderPass in unit tests. if (!frame.render_pass_list.empty()) frame_size = frame.render_pass_list[0]->output_rect.size(); - manager_->SurfaceCreated(surface->surface_id(), frame_size, - frame.metadata.device_scale_factor); + manager_->SurfaceCreated(SurfaceInfo( + surface->surface_id(), frame.metadata.device_scale_factor, frame_size)); } surface->QueueFrame(std::move(frame), callback); if (!manager_->SurfaceModified(SurfaceId(frame_sink_id_, local_frame_id))) {
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc index 3e7e25e..2bc51e9 100644 --- a/cc/surfaces/surface_factory_unittest.cc +++ b/cc/surfaces/surface_factory_unittest.cc
@@ -18,6 +18,7 @@ #include "cc/resources/resource_provider.h" #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_factory_client.h" +#include "cc/surfaces/surface_info.h" #include "cc/surfaces/surface_manager.h" #include "cc/test/scheduler_test_common.h" #include "testing/gtest/include/gtest/gtest.h" @@ -83,11 +84,9 @@ } // SurfaceObserver implementation. - void OnSurfaceCreated(const SurfaceId& surface_id, - const gfx::Size& frame, - float device_scale_factor) override { - EXPECT_EQ(kArbitraryFrameSinkId, surface_id.frame_sink_id()); - last_created_surface_id_ = surface_id; + void OnSurfaceCreated(const SurfaceInfo& surface_info) override { + EXPECT_EQ(kArbitraryFrameSinkId, surface_info.id().frame_sink_id()); + last_created_surface_id_ = surface_info.id(); } void OnSurfaceDamaged(const SurfaceId& id, bool* changed) override {
diff --git a/cc/surfaces/surface_info.h b/cc/surfaces/surface_info.h index 877d9b7..cbe7a0a0 100644 --- a/cc/surfaces/surface_info.h +++ b/cc/surfaces/surface_info.h
@@ -9,6 +9,9 @@ #include "ui/gfx/geometry/size.h" namespace cc { +namespace mojom { +class SurfaceInfoDataView; +} // This class contains information about the surface that is being embedded. class SurfaceInfo { @@ -34,6 +37,8 @@ const gfx::Size& size_in_pixels() const { return size_in_pixels_; } private: + friend struct mojo::StructTraits<mojom::SurfaceInfoDataView, SurfaceInfo>; + SurfaceId id_; float device_scale_factor_ = 1.f; gfx::Size size_in_pixels_;
diff --git a/cc/surfaces/surface_manager.cc b/cc/surfaces/surface_manager.cc index 63700ba..34bd3948 100644 --- a/cc/surfaces/surface_manager.cc +++ b/cc/surfaces/surface_manager.cc
@@ -495,12 +495,10 @@ return changed; } -void SurfaceManager::SurfaceCreated(const SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { +void SurfaceManager::SurfaceCreated(const SurfaceInfo& surface_info) { CHECK(thread_checker_.CalledOnValidThread()); for (auto& observer : observer_list_) - observer.OnSurfaceCreated(surface_id, frame_size, device_scale_factor); + observer.OnSurfaceCreated(surface_info); } } // namespace cc
diff --git a/cc/surfaces/surface_manager.h b/cc/surfaces/surface_manager.h index a17d5a7..5e45a62 100644 --- a/cc/surfaces/surface_manager.h +++ b/cc/surfaces/surface_manager.h
@@ -61,9 +61,7 @@ // Called when a CompositorFrame is submitted to a SurfaceFactory for a given // |surface_id| for the first time. - void SurfaceCreated(const SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor); + void SurfaceCreated(const SurfaceInfo& surface_info); // A frame for a surface satisfies a set of sequence numbers in a particular // id namespace.
diff --git a/cc/surfaces/surface_observer.h b/cc/surfaces/surface_observer.h index 3e829b4..e1c182a 100644 --- a/cc/surfaces/surface_observer.h +++ b/cc/surfaces/surface_observer.h
@@ -5,21 +5,15 @@ #ifndef CC_SURFACES_SURFACE_OBSERVER_H_ #define CC_SURFACES_SURFACE_OBSERVER_H_ -namespace gfx { -class Size; -} - namespace cc { -class SurfaceId; +class SurfaceInfo; class SurfaceObserver { public: - // Runs when a CompositorFrame is received for the given |surface_id| for the + // Runs when a CompositorFrame is received for the given SurfaceInfo for the // first time. - virtual void OnSurfaceCreated(const SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) = 0; + virtual void OnSurfaceCreated(const SurfaceInfo& surface_info) = 0; // Runs when a Surface is damaged. *changed should be set to true if this // causes a Display to be damaged.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java new file mode 100644 index 0000000..316dd59a --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser; + +import org.chromium.base.VisibleForTesting; + +/** + * Helper that shows the search geolocation disclosure when required. This class currently is only + * used to set static test variables in the native code. + */ +public class SearchGeolocationDisclosureTabHelper { + @VisibleForTesting + public static void setIgnoreUrlChecksForTesting() { + nativeSetIgnoreUrlChecksForTesting(); + } + + @VisibleForTesting + public static void setDayOffsetForTesting(int days) { + nativeSetDayOffsetForTesting(days); + } + + private static native void nativeSetIgnoreUrlChecksForTesting(); + private static native void nativeSetDayOffsetForTesting(int days); +}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index feb9767..a0c5cff 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -51,6 +51,7 @@ "java/src/org/chromium/chrome/browser/PasswordUIView.java", "java/src/org/chromium/chrome/browser/PowerBroadcastReceiver.java", "java/src/org/chromium/chrome/browser/RepostFormWarningDialog.java", + "java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java", "java/src/org/chromium/chrome/browser/ServiceTabLauncher.java", "java/src/org/chromium/chrome/browser/SnackbarActivity.java", "java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java", @@ -1275,6 +1276,7 @@ "javatests/src/org/chromium/chrome/browser/infobar/InfoBarControlLayoutTest.java", "javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java", "javatests/src/org/chromium/chrome/browser/infobar/PermissionUpdateInfobarTest.java", + "javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java", "javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java", "javatests/src/org/chromium/chrome/browser/instantapps/InstantAppsHandlerTest.java", "javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java new file mode 100644 index 0000000..191337e6 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java
@@ -0,0 +1,168 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.infobar; + +import android.support.test.filters.SmallTest; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.SearchGeolocationDisclosureTabHelper; +import org.chromium.chrome.test.ChromeActivityTestCaseBase; +import org.chromium.chrome.test.util.InfoBarTestAnimationListener; +import org.chromium.chrome.test.util.InfoBarUtil; +import org.chromium.net.test.EmbeddedTestServer; + +import java.util.concurrent.TimeoutException; + +/** Tests for the SearchGeolocationDisclosureInfobar. */ +public class SearchGeolocationDisclosureInfoBarTest + extends ChromeActivityTestCaseBase<ChromeActivity> { + private static final String SEARCH_PAGE = "/chrome/test/data/empty.html"; + private static final String ENABLE_NEW_DISCLOSURE_FEATURE = + "enable-features=ConsistentOmniboxGeolocation"; + private static final String DISABLE_NEW_DISCLOSURE_FEATURE = + "disable-features=ConsistentOmniboxGeolocation"; + + private EmbeddedTestServer mTestServer; + + public SearchGeolocationDisclosureInfoBarTest() { + super(ChromeActivity.class); + } + + @Override + public void startMainActivity() throws InterruptedException { + startMainActivityOnBlankPage(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext()); + } + + @Override + protected void tearDown() throws Exception { + mTestServer.stopAndDestroyServer(); + super.tearDown(); + } + + @SmallTest + @Feature({"Browser", "Main"}) + @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE) + public void testInfoBarAppears() throws InterruptedException, TimeoutException { + SearchGeolocationDisclosureTabHelper.setIgnoreUrlChecksForTesting(); + assertEquals("Wrong starting infobar count", 0, getInfoBars().size()); + + // Infobar should appear when doing the first search. + InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); + InfoBarTestAnimationListener listener = new InfoBarTestAnimationListener(); + container.setAnimationListener(listener); + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + // Note: the number of infobars is checked immediately after the URL is loaded, unlike in + // other infobar tests where it is checked after animations have completed. This is because + // (a) in this case it should work, as these infobars are added as part of the URL loading + // process, and + // (b) if this doesn't work, it is important to catch it as otherwise the checks that + // infobars haven't being shown are invalid. + assertEquals("Wrong infobar count after search", 1, getInfoBars().size()); + listener.addInfoBarAnimationFinished("InfoBar not added."); + + // Infobar should not appear again on the same day. + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + + // Infobar should appear again the next day. + SearchGeolocationDisclosureTabHelper.setDayOffsetForTesting(1); + listener = new InfoBarTestAnimationListener(); + container.setAnimationListener(listener); + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 1, getInfoBars().size()); + listener.addInfoBarAnimationFinished("InfoBar not added."); + + // Infobar should not appear again on the same day. + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + + // Infobar should appear again the next day. + SearchGeolocationDisclosureTabHelper.setDayOffsetForTesting(2); + listener = new InfoBarTestAnimationListener(); + container.setAnimationListener(listener); + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 1, getInfoBars().size()); + listener.addInfoBarAnimationFinished("InfoBar not added."); + + // Infobar should not appear again on the same day. + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + + // Infobar has appeared three times now, it should not appear again. + SearchGeolocationDisclosureTabHelper.setDayOffsetForTesting(3); + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + } + + @SmallTest + @Feature({"Browser", "Main"}) + @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE) + public void testInfoBarDismiss() throws InterruptedException, TimeoutException { + SearchGeolocationDisclosureTabHelper.setIgnoreUrlChecksForTesting(); + assertEquals("Wrong starting infobar count", 0, getInfoBars().size()); + + // Infobar should appear when doing the first search. + InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer(); + InfoBarTestAnimationListener listener = new InfoBarTestAnimationListener(); + container.setAnimationListener(listener); + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 1, getInfoBars().size()); + listener.addInfoBarAnimationFinished("InfoBar not added."); + + // Dismiss the infobar. + assertTrue(InfoBarUtil.clickCloseButton(getInfoBars().get(0))); + + // Infobar should not appear again on the same day. + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + + // Infobar should not appear the next day either, as it has been dismissed. + SearchGeolocationDisclosureTabHelper.setDayOffsetForTesting(1); + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + } + + @SmallTest + @Feature({"Browser", "Main"}) + @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE) + public void testNoInfoBarForRandomUrl() throws InterruptedException, TimeoutException { + assertEquals("Wrong starting infobar count", 0, getInfoBars().size()); + + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + } + + @SmallTest + @Feature({"Browser", "Main"}) + @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE) + public void testNoInfoBarInIncognito() throws InterruptedException, TimeoutException { + SearchGeolocationDisclosureTabHelper.setIgnoreUrlChecksForTesting(); + newIncognitoTabFromMenu(); + assertEquals("Wrong starting infobar count", 0, getInfoBars().size()); + + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + } + + @SmallTest + @Feature({"Browser", "Main"}) + @CommandLineFlags.Add(DISABLE_NEW_DISCLOSURE_FEATURE) + public void testInfoBarAppearsDoesntAppearWithoutFeature() + throws InterruptedException, TimeoutException { + SearchGeolocationDisclosureTabHelper.setIgnoreUrlChecksForTesting(); + assertEquals("Wrong starting infobar count", 0, getInfoBars().size()); + + loadUrl(mTestServer.getURL(SEARCH_PAGE)); + assertEquals("Wrong infobar count after search", 0, getInfoBars().size()); + } +}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index f6a85ed..0403cff 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3890,6 +3890,7 @@ "../android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java", "../android/java/src/org/chromium/chrome/browser/PasswordUIView.java", "../android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java", + "../android/java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java", "../android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java", "../android/java/src/org/chromium/chrome/browser/ShortcutHelper.java", "../android/java/src/org/chromium/chrome/browser/TabState.java",
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index d7587c0..d090ae74 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -89,6 +89,7 @@ #include "chrome/browser/android/recently_closed_tabs_bridge.h" #include "chrome/browser/android/rlz/revenue_stats.h" #include "chrome/browser/android/safe_browsing/safe_browsing_api_handler_bridge.h" +#include "chrome/browser/android/search_geolocation_disclosure_tab_helper.h" #include "chrome/browser/android/service_tab_launcher.h" #include "chrome/browser/android/sessions/session_tab_helper_android.h" #include "chrome/browser/android/shortcut_helper.h" @@ -373,6 +374,8 @@ {"SceneLayer", RegisterSceneLayer}, {"ScreenshotTask", chrome::android::RegisterScreenshotTask}, {"ServiceTabLauncher", ServiceTabLauncher::Register}, + {"SearchGeolocationDisclosureTabHelper", + SearchGeolocationDisclosureTabHelper::Register}, {"ServiceWorkerPaymentAppBridge", RegisterServiceWorkerPaymentAppBridge}, {"SessionTabHelper", RegisterSessionTabHelper}, {"SigninInvestigator", SigninInvestigatorAndroid::Register},
diff --git a/chrome/browser/android/search_geolocation_disclosure_tab_helper.cc b/chrome/browser/android/search_geolocation_disclosure_tab_helper.cc index 82942d1..5bfdc99 100644 --- a/chrome/browser/android/search_geolocation_disclosure_tab_helper.cc +++ b/chrome/browser/android/search_geolocation_disclosure_tab_helper.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/android/search_geolocation_disclosure_tab_helper.h" +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" #include "base/feature_list.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" @@ -23,6 +25,7 @@ #include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents.h" #include "jni/GeolocationHeader_jni.h" +#include "jni/SearchGeolocationDisclosureTabHelper_jni.h" #include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h" namespace { @@ -32,6 +35,9 @@ const char kMaxShowCountVariation[] = "MaxShowCount"; const char kDaysPerShowVariation[] = "DaysPerShow"; +bool gIgnoreUrlChecksForTesting = false; +int gDayOffsetForTesting = 0; + int GetMaxShowCount() { std::string variation = variations::GetVariationParamValueByFeature( features::kConsistentOmniboxGeolocation, kMaxShowCountVariation); @@ -52,6 +58,10 @@ return kDefaultDaysPerShow; } +base::Time GetTimeNow() { + return base::Time::Now() + base::TimeDelta::FromDays(gDayOffsetForTesting); +} + } // namespace DEFINE_WEB_CONTENTS_USER_DATA_KEY(SearchGeolocationDisclosureTabHelper); @@ -88,30 +98,20 @@ prefs::kSearchGeolocationPostDisclosureMetricsRecorded, false); } +// static +bool SearchGeolocationDisclosureTabHelper::Register(JNIEnv* env) { + return RegisterNativesImpl(env); +} + void SearchGeolocationDisclosureTabHelper:: MaybeShowDefaultSearchGeolocationDisclosure(const GURL& gurl) { // Don't show in incognito. if (GetProfile()->IsOffTheRecord()) return; - // Only show the disclosure for default search navigations from the omnibox. - TemplateURLService* template_url_service = - TemplateURLServiceFactory::GetForProfile(GetProfile()); - bool is_search_url = - template_url_service->IsSearchResultsPageFromDefaultSearchProvider( - gurl); - if (!is_search_url) + if (!ShouldShowDisclosureForUrl(gurl)) return; - // Only show the disclosure if Google is the default search engine. - TemplateURL* default_search = - template_url_service->GetDefaultSearchProvider(); - if (!default_search || - !default_search->url_ref().HasGoogleBaseURLs( - template_url_service->search_terms_data())) { - return; - } - // Don't show the infobar if the user has dismissed it, or they've seen it // enough times already. PrefService* prefs = GetProfile()->GetPrefs(); @@ -132,8 +132,7 @@ // Or if it has been shown too recently. base::Time last_shown = base::Time::FromInternalValue( prefs->GetInt64(prefs::kSearchGeolocationDisclosureLastShowDate)); - if (base::Time::Now() - last_shown < - base::TimeDelta::FromDays(GetDaysPerShow())) { + if (GetTimeNow() - last_shown < base::TimeDelta::FromDays(GetDaysPerShow())) { return; } @@ -160,7 +159,33 @@ shown_count++; prefs->SetInteger(prefs::kSearchGeolocationDisclosureShownCount, shown_count); prefs->SetInt64(prefs::kSearchGeolocationDisclosureLastShowDate, - base::Time::Now().ToInternalValue()); + GetTimeNow().ToInternalValue()); +} + +bool SearchGeolocationDisclosureTabHelper::ShouldShowDisclosureForUrl( + const GURL& gurl) { + if (gIgnoreUrlChecksForTesting) + return true; + + // Only show the disclosure for default search navigations from the omnibox. + TemplateURLService* template_url_service = + TemplateURLServiceFactory::GetForProfile(GetProfile()); + bool is_search_url = + template_url_service->IsSearchResultsPageFromDefaultSearchProvider( + gurl); + if (!is_search_url) + return false; + + // Only show the disclosure if Google is the default search engine. + TemplateURL* default_search = + template_url_service->GetDefaultSearchProvider(); + if (!default_search || + !default_search->url_ref().HasGoogleBaseURLs( + template_url_service->search_terms_data())) { + return false; + } + + return true; } void SearchGeolocationDisclosureTabHelper::RecordPreDisclosureMetrics( @@ -204,3 +229,17 @@ Profile* SearchGeolocationDisclosureTabHelper::GetProfile() { return Profile::FromBrowserContext(web_contents()->GetBrowserContext()); } + +// static +void SetIgnoreUrlChecksForTesting( + JNIEnv* env, + const base::android::JavaParamRef<jclass>& clazz) { + gIgnoreUrlChecksForTesting = true; +} + +// static +void SetDayOffsetForTesting(JNIEnv* env, + const base::android::JavaParamRef<jclass>& clazz, + jint days) { + gDayOffsetForTesting = days; +}
diff --git a/chrome/browser/android/search_geolocation_disclosure_tab_helper.h b/chrome/browser/android/search_geolocation_disclosure_tab_helper.h index 00ed39c0..1eac8be 100644 --- a/chrome/browser/android/search_geolocation_disclosure_tab_helper.h +++ b/chrome/browser/android/search_geolocation_disclosure_tab_helper.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_ANDROID_SEARCH_GEOLOCATION_DISCLOSURE_TAB_HELPER_H_ #define CHROME_BROWSER_ANDROID_SEARCH_GEOLOCATION_DISCLOSURE_TAB_HELPER_H_ +#include <jni.h> + #include "base/macros.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -30,6 +32,9 @@ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + // Registers native methods. + static bool Register(JNIEnv* env); + private: explicit SearchGeolocationDisclosureTabHelper(content::WebContents* contents); friend class content::WebContentsUserData< @@ -37,6 +42,8 @@ void MaybeShowDefaultSearchGeolocationDisclosure(const GURL& gurl); + bool ShouldShowDisclosureForUrl(const GURL& gurl); + // Record metrics, once per client, of the permission state before and after // the disclosure has been shown. void RecordPreDisclosureMetrics(const GURL& gurl);
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc index e4be8323..40f4f5c4 100644 --- a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
@@ -311,11 +311,12 @@ EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } +// Flaky: http://crbug.com/675851 // Tests that fullscreen transitions during a tab capture session dispatch // events to the onStatusChange listener. The test loads a page that toggles // fullscreen mode, using the Fullscreen Javascript API, in response to mouse // clicks. -IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, FullscreenEvents) { +IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, DISABLED_FullscreenEvents) { AddExtensionToCommandLineWhitelist(); ExtensionTestMessageListener capture_started("tab_capture_started", false);
diff --git a/chrome/browser/resources/net_internals/alt_svc_view.js b/chrome/browser/resources/net_internals/alt_svc_view.js index 91bc82e..528e4862 100644 --- a/chrome/browser/resources/net_internals/alt_svc_view.js +++ b/chrome/browser/resources/net_internals/alt_svc_view.js
@@ -41,8 +41,8 @@ onLoadLogFinish: function(data) { // TODO(rch): Remove the check for spdyAlternateProtocolMappings after // M53 (It was renamed to altSvcMappings in M50). - return this.onAltSvcMappingsChanged(data.altSvcMappings || - data.spdyAlternateProtocolMappings); + return this.onAltSvcMappingsChanged( + data.altSvcMappings || data.spdyAlternateProtocolMappings); }, /**
diff --git a/chrome/browser/resources/net_internals/bandwidth_view.js b/chrome/browser/resources/net_internals/bandwidth_view.js index 067151c..09050f1 100644 --- a/chrome/browser/resources/net_internals/bandwidth_view.js +++ b/chrome/browser/resources/net_internals/bandwidth_view.js
@@ -61,7 +61,7 @@ return this.onBadProxiesChanged(data.badProxies) && this.onDataReductionProxyInfoChanged(data.dataReductionProxyInfo) && (this.onSessionNetworkStatsChanged(data.sessionNetworkStats) || - this.onHistoricNetworkStatsChanged(data.historicNetworkStats)); + this.onHistoricNetworkStatsChanged(data.historicNetworkStats)); }, /** @@ -106,7 +106,7 @@ this.updateDataReductionProxyConfig_(); for (var eventIndex = info.events.length - 1; eventIndex >= 0; - --eventIndex) { + --eventIndex) { var event = info.events[eventIndex]; var headerRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr'); var detailsRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr'); @@ -165,27 +165,26 @@ var rows = []; rows.push({ - title: 'Original (KB)', - sessionValue: bytesToRoundedKilobytes_(sessionOriginal), - historicValue: bytesToRoundedKilobytes_(historicOriginal) + title: 'Original (KB)', + sessionValue: bytesToRoundedKilobytes_(sessionOriginal), + historicValue: bytesToRoundedKilobytes_(historicOriginal) }); rows.push({ - title: 'Received (KB)', - sessionValue: bytesToRoundedKilobytes_(sessionReceived), - historicValue: bytesToRoundedKilobytes_(historicReceived) + title: 'Received (KB)', + sessionValue: bytesToRoundedKilobytes_(sessionReceived), + historicValue: bytesToRoundedKilobytes_(historicReceived) }); rows.push({ - title: 'Savings (KB)', - sessionValue: - bytesToRoundedKilobytes_(sessionOriginal - sessionReceived), - historicValue: - bytesToRoundedKilobytes_(historicOriginal - historicReceived) + title: 'Savings (KB)', + sessionValue: + bytesToRoundedKilobytes_(sessionOriginal - sessionReceived), + historicValue: + bytesToRoundedKilobytes_(historicOriginal - historicReceived) }); rows.push({ - title: 'Savings (%)', - sessionValue: getPercentSavings_(sessionOriginal, sessionReceived), - historicValue: getPercentSavings_(historicOriginal, - historicReceived) + title: 'Savings (%)', + sessionValue: getPercentSavings_(sessionOriginal, sessionReceived), + historicValue: getPercentSavings_(historicOriginal, historicReceived) }); var input = new JsEvalContext({rows: rows}); @@ -206,8 +205,8 @@ if (event.phase == EventPhase.PHASE_BEGIN || event.phase == EventPhase.PHASE_END) { actionText = actionText + ' (' + - getKeyWithValue(EventPhase, event.phase) - .replace('PHASE_', '') + ')'; + getKeyWithValue(EventPhase, event.phase).replace('PHASE_', '') + + ')'; } addTextNode(actionCell, actionText); @@ -256,14 +255,15 @@ } if (hasBypassedProxy) { - this.createEventTable_(this.last_bypass_.params, - $(BandwidthView.BYPASS_STATE_ID)); + this.createEventTable_( + this.last_bypass_.params, $(BandwidthView.BYPASS_STATE_ID)); } - this.createEventTable_(this.data_reduction_proxy_config_, - $(BandwidthView.PROXY_CONFIG_ID)); - setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), - hasBypassedProxy); + this.createEventTable_( + this.data_reduction_proxy_config_, + $(BandwidthView.PROXY_CONFIG_ID)); + setNodeDisplay( + $(BandwidthView.BYPASS_STATE_CONTAINER_ID), hasBypassedProxy); } }, @@ -317,8 +317,8 @@ } else if (key == 'bypass_type') { value = getKeyWithValue(DataReductionProxyBypassEventType, value); } else if (key == 'bypass_action_type') { - value = getKeyWithValue(DataReductionProxyBypassActionType, - value); + value = + getKeyWithValue(DataReductionProxyBypassActionType, value); } else if (key == 'expiration') { value = timeutil.convertTimeTicksToDate(value); }
diff --git a/chrome/browser/resources/net_internals/browser_bridge.js b/chrome/browser/resources/net_internals/browser_bridge.js index 4e48bbc..112a006 100644 --- a/chrome/browser/resources/net_internals/browser_bridge.js +++ b/chrome/browser/resources/net_internals/browser_bridge.js
@@ -39,44 +39,41 @@ // Add PollableDataHelpers for NetInfoSources, which retrieve information // directly from the network stack. - this.addNetInfoPollableDataHelper('proxySettings', - 'onProxySettingsChanged'); + this.addNetInfoPollableDataHelper( + 'proxySettings', 'onProxySettingsChanged'); this.addNetInfoPollableDataHelper('badProxies', 'onBadProxiesChanged'); - this.addNetInfoPollableDataHelper('hostResolverInfo', - 'onHostResolverInfoChanged'); - this.addNetInfoPollableDataHelper('socketPoolInfo', - 'onSocketPoolInfoChanged'); - this.addNetInfoPollableDataHelper('spdySessionInfo', - 'onSpdySessionInfoChanged'); + this.addNetInfoPollableDataHelper( + 'hostResolverInfo', 'onHostResolverInfoChanged'); + this.addNetInfoPollableDataHelper( + 'socketPoolInfo', 'onSocketPoolInfoChanged'); + this.addNetInfoPollableDataHelper( + 'spdySessionInfo', 'onSpdySessionInfoChanged'); this.addNetInfoPollableDataHelper('spdyStatus', 'onSpdyStatusChanged'); - this.addNetInfoPollableDataHelper('altSvcMappings', - 'onAltSvcMappingsChanged'); + this.addNetInfoPollableDataHelper( + 'altSvcMappings', 'onAltSvcMappingsChanged'); this.addNetInfoPollableDataHelper('quicInfo', 'onQuicInfoChanged'); this.addNetInfoPollableDataHelper('sdchInfo', 'onSdchInfoChanged'); - this.addNetInfoPollableDataHelper('httpCacheInfo', - 'onHttpCacheInfoChanged'); + this.addNetInfoPollableDataHelper( + 'httpCacheInfo', 'onHttpCacheInfoChanged'); // Add other PollableDataHelpers. - this.pollableDataHelpers_.sessionNetworkStats = - new PollableDataHelper('onSessionNetworkStatsChanged', - this.sendGetSessionNetworkStats.bind(this)); - this.pollableDataHelpers_.historicNetworkStats = - new PollableDataHelper('onHistoricNetworkStatsChanged', - this.sendGetHistoricNetworkStats.bind(this)); + this.pollableDataHelpers_.sessionNetworkStats = new PollableDataHelper( + 'onSessionNetworkStatsChanged', + this.sendGetSessionNetworkStats.bind(this)); + this.pollableDataHelpers_.historicNetworkStats = new PollableDataHelper( + 'onHistoricNetworkStatsChanged', + this.sendGetHistoricNetworkStats.bind(this)); if (cr.isWindows) { - this.pollableDataHelpers_.serviceProviders = - new PollableDataHelper('onServiceProvidersChanged', - this.sendGetServiceProviders.bind(this)); + this.pollableDataHelpers_.serviceProviders = new PollableDataHelper( + 'onServiceProvidersChanged', this.sendGetServiceProviders.bind(this)); } - this.pollableDataHelpers_.prerenderInfo = - new PollableDataHelper('onPrerenderInfoChanged', - this.sendGetPrerenderInfo.bind(this)); - this.pollableDataHelpers_.extensionInfo = - new PollableDataHelper('onExtensionInfoChanged', - this.sendGetExtensionInfo.bind(this)); - this.pollableDataHelpers_.dataReductionProxyInfo = - new PollableDataHelper('onDataReductionProxyInfoChanged', - this.sendGetDataReductionProxyInfo.bind(this)); + this.pollableDataHelpers_.prerenderInfo = new PollableDataHelper( + 'onPrerenderInfoChanged', this.sendGetPrerenderInfo.bind(this)); + this.pollableDataHelpers_.extensionInfo = new PollableDataHelper( + 'onExtensionInfoChanged', this.sendGetExtensionInfo.bind(this)); + this.pollableDataHelpers_.dataReductionProxyInfo = new PollableDataHelper( + 'onDataReductionProxyInfoChanged', + this.sendGetDataReductionProxyInfo.bind(this)); // Setting this to true will cause messages from the browser to be ignored, // and no messages will be sent to the browser, either. Intended for use @@ -128,9 +125,8 @@ } if (intervalMs > 0) { - this.pollIntervalId_ = - window.setInterval(this.checkForUpdatedInfo.bind(this, false), - intervalMs); + this.pollIntervalId_ = window.setInterval( + this.checkForUpdatedInfo.bind(this, false), intervalMs); } }, @@ -169,10 +165,11 @@ this.send('hstsQuery', [domain]); }, - sendHSTSAdd: function(domain, sts_include_subdomains, - pkp_include_subdomains, pins) { - this.send('hstsAdd', [domain, sts_include_subdomains, - pkp_include_subdomains, pins]); + sendHSTSAdd: function( + domain, sts_include_subdomains, pkp_include_subdomains, pins) { + this.send( + 'hstsAdd', + [domain, sts_include_subdomains, pkp_include_subdomains, pins]); }, sendHSTSDelete: function(domain) { @@ -239,7 +236,7 @@ // If no constants have been received, and params does not contain the // constants, delay handling the data. if (Constants == null && command != 'receivedConstants') { - this.earlyReceivedData_.push({ command: command, params: params }); + this.earlyReceivedData_.push({command: command, params: params}); return; } @@ -387,8 +384,8 @@ * If it's false, data is sent whenever it's received from the browser. */ addProxySettingsObserver: function(observer, ignoreWhenUnchanged) { - this.pollableDataHelpers_.proxySettings.addObserver(observer, - ignoreWhenUnchanged); + this.pollableDataHelpers_.proxySettings.addObserver( + observer, ignoreWhenUnchanged); }, /** @@ -403,8 +400,8 @@ * bad. Note the time is in time ticks. */ addBadProxiesObserver: function(observer, ignoreWhenUnchanged) { - this.pollableDataHelpers_.badProxies.addObserver(observer, - ignoreWhenUnchanged); + this.pollableDataHelpers_.badProxies.addObserver( + observer, ignoreWhenUnchanged); }, /** @@ -425,8 +422,8 @@ * observer.onSocketPoolInfoChanged(socketPoolInfo) */ addSocketPoolInfoObserver: function(observer, ignoreWhenUnchanged) { - this.pollableDataHelpers_.socketPoolInfo.addObserver(observer, - ignoreWhenUnchanged); + this.pollableDataHelpers_.socketPoolInfo.addObserver( + observer, ignoreWhenUnchanged); }, /** @@ -480,8 +477,8 @@ * observer.onSpdyStatusChanged(spdyStatus) */ addSpdyStatusObserver: function(observer, ignoreWhenUnchanged) { - this.pollableDataHelpers_.spdyStatus.addObserver(observer, - ignoreWhenUnchanged); + this.pollableDataHelpers_.spdyStatus.addObserver( + observer, ignoreWhenUnchanged); }, /**
diff --git a/chrome/browser/resources/net_internals/capture_view.js b/chrome/browser/resources/net_internals/capture_view.js index 244dc1ce..2d3b76fd 100644 --- a/chrome/browser/resources/net_internals/capture_view.js +++ b/chrome/browser/resources/net_internals/capture_view.js
@@ -37,11 +37,12 @@ throw 'Not expecting byte logging to be enabled!'; } - new MouseOverHelp(CaptureView.LIMIT_HELP_ID, - CaptureView.LIMIT_HELP_HOVER_ID); + new MouseOverHelp( + CaptureView.LIMIT_HELP_ID, CaptureView.LIMIT_HELP_HOVER_ID); - new MouseOverHelp(CaptureView.BYTE_LOGGING_HELP_ID, - CaptureView.BYTE_LOGGING_HELP_HOVER_ID); + new MouseOverHelp( + CaptureView.BYTE_LOGGING_HELP_ID, + CaptureView.BYTE_LOGGING_HELP_HOVER_ID); this.onChangeLimit_(); }
diff --git a/chrome/browser/resources/net_internals/chromeos_view.js b/chrome/browser/resources/net_internals/chromeos_view.js index f71bb3d..30533e7e 100644 --- a/chrome/browser/resources/net_internals/chromeos_view.js +++ b/chrome/browser/resources/net_internals/chromeos_view.js
@@ -18,9 +18,8 @@ */ function clearFileInput_() { $(CrosView.IMPORT_DIV_ID).innerHTML = $(CrosView.IMPORT_DIV_ID).innerHTML; - $(CrosView.IMPORT_ONC_ID).addEventListener('change', - handleFileChangeEvent_, - false); + $(CrosView.IMPORT_ONC_ID) + .addEventListener('change', handleFileChangeEvent_, false); } /** @@ -74,10 +73,10 @@ // Ignore any parse errors: they'll get handled in the C++ import code. try { jsonObject = JSON.parse(fileContent); - } catch (error) {} + } catch (error) { + } // Check if file is encrypted. - if (jsonObject && - jsonObject.hasOwnProperty('Type') && + if (jsonObject && jsonObject.hasOwnProperty('Type') && jsonObject.Type == 'EncryptedConfiguration') { promptForPasscode_(); } else { @@ -104,8 +103,8 @@ function setParseStatus_(error) { var parseStatus = $(CrosView.PARSE_STATUS_ID); parseStatus.hidden = false; - parseStatus.textContent = error ? - 'ONC file parse failed: ' + error : 'ONC file successfully parsed'; + parseStatus.textContent = error ? 'ONC file parse failed: ' + error : + 'ONC file successfully parsed'; reset_(); } @@ -150,9 +149,8 @@ * @private */ function addEventListeners_() { - $(CrosView.IMPORT_ONC_ID).addEventListener('change', - handleFileChangeEvent_, - false); + $(CrosView.IMPORT_ONC_ID) + .addEventListener('change', handleFileChangeEvent_, false); $(CrosView.PASSCODE_INPUT_ID).addEventListener('change', function(event) { setPasscode_(this.value); @@ -164,19 +162,19 @@ }, false); $(CrosView.DEBUG_WIFI_ID).addEventListener('click', function(event) { - setNetworkDebugMode_('wifi'); + setNetworkDebugMode_('wifi'); }, false); $(CrosView.DEBUG_ETHERNET_ID).addEventListener('click', function(event) { - setNetworkDebugMode_('ethernet'); + setNetworkDebugMode_('ethernet'); }, false); $(CrosView.DEBUG_CELLULAR_ID).addEventListener('click', function(event) { - setNetworkDebugMode_('cellular'); + setNetworkDebugMode_('cellular'); }, false); $(CrosView.DEBUG_WIMAX_ID).addEventListener('click', function(event) { - setNetworkDebugMode_('wimax'); + setNetworkDebugMode_('wimax'); }, false); $(CrosView.DEBUG_NONE_ID).addEventListener('click', function(event) { - setNetworkDebugMode_('none'); + setNetworkDebugMode_('none'); }, false); }
diff --git a/chrome/browser/resources/net_internals/details_view.js b/chrome/browser/resources/net_internals/details_view.js index 0bfa0ea..1b1792f 100644 --- a/chrome/browser/resources/net_internals/details_view.js +++ b/chrome/browser/resources/net_internals/details_view.js
@@ -41,8 +41,7 @@ // Repaint the view. if (this.isVisible() && !this.outstandingRepaint_) { this.outstandingRepaint_ = true; - window.setTimeout(this.repaint.bind(this), - REPAINT_TIMEOUT_MS); + window.setTimeout(this.repaint.bind(this), REPAINT_TIMEOUT_MS); } }, @@ -62,9 +61,9 @@ div.className = 'log-source-entry'; var p = addNode(div, 'p'); - addNodeWithText(p, 'h4', - sourceEntry.getSourceId() + ': ' + - sourceEntry.getSourceTypeString()); + addNodeWithText( + p, 'h4', sourceEntry.getSourceId() + ': ' + + sourceEntry.getSourceTypeString()); if (sourceEntry.getDescription()) addNodeWithText(p, 'h4', sourceEntry.getDescription());
diff --git a/chrome/browser/resources/net_internals/dns_view.js b/chrome/browser/resources/net_internals/dns_view.js index b431b74..05bb521 100644 --- a/chrome/browser/resources/net_internals/dns_view.js +++ b/chrome/browser/resources/net_internals/dns_view.js
@@ -104,14 +104,12 @@ addTextNode(hostnameCell, e.hostname); var familyCell = addNode(tr, 'td'); - addTextNode(familyCell, - addressFamilyToString(e.address_family)); + addTextNode(familyCell, addressFamilyToString(e.address_family)); var addressesCell = addNode(tr, 'td'); if (e.error != undefined) { - var errorText = - e.error + ' (' + netErrorToString(e.error) + ')'; + var errorText = e.error + ' (' + netErrorToString(e.error) + ')'; var errorNode = addTextNode(addressesCell, 'error: ' + errorText); addressesCell.classList.add('warning-text'); } else { @@ -146,10 +144,9 @@ // Figure out if the internal DNS resolver is disabled or has no valid // configuration information, and update display accordingly. - var enabled = hostResolverInfo && - hostResolverInfo.dns_config !== undefined; - var noConfig = enabled && - hostResolverInfo.dns_config.nameservers === undefined; + var enabled = hostResolverInfo && hostResolverInfo.dns_config !== undefined; + var noConfig = + enabled && hostResolverInfo.dns_config.nameservers === undefined; $(DnsView.INTERNAL_DNS_ENABLED_SPAN_ID).innerText = enabled; setNodeDisplay($(DnsView.INTERNAL_DNS_INVALID_CONFIG_SPAN_ID), noConfig);
diff --git a/chrome/browser/resources/net_internals/events_view.js b/chrome/browser/resources/net_internals/events_view.js index 03c887b..679fdbc 100644 --- a/chrome/browser/resources/net_internals/events_view.js +++ b/chrome/browser/resources/net_internals/events_view.js
@@ -42,8 +42,8 @@ superClass.call(this); // Initialize the sub-views. - var leftPane = new VerticalSplitView(new DivView(EventsView.TOPBAR_ID), - new DivView(EventsView.LIST_BOX_ID)); + var leftPane = new VerticalSplitView( + new DivView(EventsView.TOPBAR_ID), new DivView(EventsView.LIST_BOX_ID)); this.detailsView_ = new DetailsView(EventsView.DETAILS_LOG_BOX_ID); @@ -57,23 +57,23 @@ this.filterInput_ = $(EventsView.FILTER_INPUT_ID); this.filterCount_ = $(EventsView.FILTER_COUNT_ID); - this.filterInput_.addEventListener('search', - this.onFilterTextChanged_.bind(this), true); + this.filterInput_.addEventListener( + 'search', this.onFilterTextChanged_.bind(this), true); - $(EventsView.SELECT_ALL_ID).addEventListener( - 'click', this.selectAll_.bind(this), true); + $(EventsView.SELECT_ALL_ID) + .addEventListener('click', this.selectAll_.bind(this), true); - $(EventsView.SORT_BY_ID_ID).addEventListener( - 'click', this.sortById_.bind(this), true); + $(EventsView.SORT_BY_ID_ID) + .addEventListener('click', this.sortById_.bind(this), true); - $(EventsView.SORT_BY_SOURCE_TYPE_ID).addEventListener( - 'click', this.sortBySourceType_.bind(this), true); + $(EventsView.SORT_BY_SOURCE_TYPE_ID) + .addEventListener('click', this.sortBySourceType_.bind(this), true); - $(EventsView.SORT_BY_DESCRIPTION_ID).addEventListener( - 'click', this.sortByDescription_.bind(this), true); + $(EventsView.SORT_BY_DESCRIPTION_ID) + .addEventListener('click', this.sortByDescription_.bind(this), true); - new MouseOverHelp(EventsView.FILTER_HELP_ID, - EventsView.FILTER_HELP_HOVER_ID); + new MouseOverHelp( + EventsView.FILTER_HELP_ID, EventsView.FILTER_HELP_HOVER_ID); // Sets sort order and filter. this.setFilter_(''); @@ -232,8 +232,8 @@ break; var prevSourceRow = this.sourceIdToRowMap_[prevSourceId]; if (this.comparisonFuncWithReversing_( - sourceRow.getSourceEntry(), - prevSourceRow.getSourceEntry()) >= 0) { + sourceRow.getSourceEntry(), prevSourceRow.getSourceEntry()) >= + 0) { break; } sourceRowAfter = prevSourceRow; @@ -250,8 +250,8 @@ break; var nextSourceRow = this.sourceIdToRowMap_[nextSourceId]; if (this.comparisonFuncWithReversing_( - sourceRow.getSourceEntry(), - nextSourceRow.getSourceEntry()) <= 0) { + sourceRow.getSourceEntry(), nextSourceRow.getSourceEntry()) <= + 0) { break; } sourceRowBefore = nextSourceRow; @@ -472,16 +472,17 @@ invalidateFilterCounter_: function() { if (!this.outstandingRepaintFilterCounter_) { this.outstandingRepaintFilterCounter_ = true; - window.setTimeout(this.repaintFilterCounter_.bind(this), - REPAINT_FILTER_COUNTER_TIMEOUT_MS); + window.setTimeout( + this.repaintFilterCounter_.bind(this), + REPAINT_FILTER_COUNTER_TIMEOUT_MS); } }, repaintFilterCounter_: function() { this.outstandingRepaintFilterCounter_ = false; this.filterCount_.innerHTML = ''; - addTextNode(this.filterCount_, - this.numPostfilter_ + ' of ' + this.numPrefilter_); + addTextNode( + this.filterCount_, this.numPostfilter_ + ' of ' + this.numPrefilter_); } }; // end of prototype.
diff --git a/chrome/browser/resources/net_internals/export_view.js b/chrome/browser/resources/net_internals/export_view.js index c7b556e..7732e23 100644 --- a/chrome/browser/resources/net_internals/export_view.js +++ b/chrome/browser/resources/net_internals/export_view.js
@@ -138,17 +138,14 @@ // If we have a cached log dump, update it synchronously. if (this.loadedLogDump_) { - var dumpText = log_util.createUpdatedLogDump(userComments, - this.loadedLogDump_, - privacyStripping); + var dumpText = log_util.createUpdatedLogDump( + userComments, this.loadedLogDump_, privacyStripping); callback(dumpText); return; } // Otherwise, poll information from the browser before creating one. - log_util.createLogDumpAsync(userComments, - callback, - privacyStripping); + log_util.createLogDumpAsync(userComments, callback, privacyStripping); }, /**
diff --git a/chrome/browser/resources/net_internals/hsts_view.js b/chrome/browser/resources/net_internals/hsts_view.js index fae98f0..84f2514 100644 --- a/chrome/browser/resources/net_internals/hsts_view.js +++ b/chrome/browser/resources/net_internals/hsts_view.js
@@ -73,10 +73,9 @@ __proto__: superClass.prototype, onSubmitAdd_: function(event) { - g_browser.sendHSTSAdd(this.addInput_.value, - this.addStsCheck_.checked, - this.addPkpCheck_.checked, - this.addPins_.value); + g_browser.sendHSTSAdd( + this.addInput_.value, this.addStsCheck_.checked, + this.addPkpCheck_.checked, this.addPins_.value); g_browser.sendHSTSQuery(this.addInput_.value); this.queryInput_.value = this.addInput_.value; this.addStsCheck_.checked = false; @@ -119,19 +118,26 @@ s.innerHTML = '<b>Found:</b><br/>'; var keys = [ - 'static_sts_domain', 'static_upgrade_mode', - 'static_sts_include_subdomains', 'static_sts_observed', - 'static_pkp_domain', 'static_pkp_include_subdomains', - 'static_pkp_observed', 'static_spki_hashes', 'dynamic_sts_domain', - 'dynamic_upgrade_mode', 'dynamic_sts_include_subdomains', - 'dynamic_sts_observed', 'dynamic_pkp_domain', - 'dynamic_pkp_include_subdomains', 'dynamic_pkp_observed', + 'static_sts_domain', + 'static_upgrade_mode', + 'static_sts_include_subdomains', + 'static_sts_observed', + 'static_pkp_domain', + 'static_pkp_include_subdomains', + 'static_pkp_observed', + 'static_spki_hashes', + 'dynamic_sts_domain', + 'dynamic_upgrade_mode', + 'dynamic_sts_include_subdomains', + 'dynamic_sts_observed', + 'dynamic_pkp_domain', + 'dynamic_pkp_include_subdomains', + 'dynamic_pkp_observed', 'dynamic_spki_hashes', ]; - var kStaticHashKeys = [ - 'public_key_hashes', 'preloaded_spki_hashes', 'static_spki_hashes' - ]; + var kStaticHashKeys = + ['public_key_hashes', 'preloaded_spki_hashes', 'static_spki_hashes']; var staticHashes = []; for (var i = 0; i < kStaticHashKeys.length; ++i) { @@ -157,8 +163,8 @@ } else if (key.indexOf('_upgrade_mode') >= 0) { addNodeWithText(this.queryOutputDiv_, 'tt', modeToString(value)); } else { - addNodeWithText(this.queryOutputDiv_, 'tt', - value == undefined ? '' : value); + addNodeWithText( + this.queryOutputDiv_, 'tt', value == undefined ? '' : value); } addNode(this.queryOutputDiv_, 'br'); }
diff --git a/chrome/browser/resources/net_internals/import_view.js b/chrome/browser/resources/net_internals/import_view.js index deb554deb..458317b 100644 --- a/chrome/browser/resources/net_internals/import_view.js +++ b/chrome/browser/resources/net_internals/import_view.js
@@ -82,7 +82,7 @@ // http://crbug.com/115433. TODO(dbeam): Remove when standardized more. var indexOf = Array.prototype.indexOf; return indexOf.call(event.dataTransfer.types, 'Files') == -1 || - event.dataTransfer.files.length > 1; + event.dataTransfer.files.length > 1; }, /**
diff --git a/chrome/browser/resources/net_internals/index.js b/chrome/browser/resources/net_internals/index.js index d614267..eadc020 100644 --- a/chrome/browser/resources/net_internals/index.js +++ b/chrome/browser/resources/net_internals/index.js
@@ -2,51 +2,51 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -<include src="util.js"> -<include src="table_printer.js"> -<include src="view.js"> -<include src="mouse_over_help.js"> -<include src="tab_switcher_view.js"> -<include src="import_view.js"> -<include src="capture_view.js"> -<include src="export_view.js"> -<include src="http_cache_view.js"> -<include src="hsts_view.js"> -<include src="browser_bridge.js"> -<include src="events_tracker.js"> -<include src="source_tracker.js"> -<include src="resizable_vertical_split_view.js"> -<include src="main.js"> -<include src="time_util.js"> -<include src="log_util.js"> -<include src="capture_status_view.js"> -<include src="loaded_status_view.js"> -<include src="halted_status_view.js"> -<include src="top_bar_view.js"> -<include src="dns_view.js"> -<include src="source_filter_parser.js"> -<include src="source_row.js"> -<include src="events_view.js"> -<include src="details_view.js"> -<include src="source_entry.js"> -<include src="horizontal_scrollbar_view.js"> -<include src="top_mid_bottom_view.js"> -<include src="timeline_data_series.js"> -<include src="timeline_graph_view.js"> -<include src="timeline_view.js"> -<include src="log_view_painter.js"> -<include src="log_grouper.js"> -<include src="proxy_view.js"> -<include src="quic_view.js"> -<include src="socket_pool_wrapper.js"> -<include src="sockets_view.js"> -<include src="alt_svc_view.js"> -<include src="spdy_view.js"> -<include src="modules_view.js"> -<include src="prerender_view.js"> -<include src="chromeos_view.js"> -<include src="bandwidth_view.js"> -<include src="sdch_view.js"> +// <include src="util.js"> +// <include src="table_printer.js"> +// <include src="view.js"> +// <include src="mouse_over_help.js"> +// <include src="tab_switcher_view.js"> +// <include src="import_view.js"> +// <include src="capture_view.js"> +// <include src="export_view.js"> +// <include src="http_cache_view.js"> +// <include src="hsts_view.js"> +// <include src="browser_bridge.js"> +// <include src="events_tracker.js"> +// <include src="source_tracker.js"> +// <include src="resizable_vertical_split_view.js"> +// <include src="main.js"> +// <include src="time_util.js"> +// <include src="log_util.js"> +// <include src="capture_status_view.js"> +// <include src="loaded_status_view.js"> +// <include src="halted_status_view.js"> +// <include src="top_bar_view.js"> +// <include src="dns_view.js"> +// <include src="source_filter_parser.js"> +// <include src="source_row.js"> +// <include src="events_view.js"> +// <include src="details_view.js"> +// <include src="source_entry.js"> +// <include src="horizontal_scrollbar_view.js"> +// <include src="top_mid_bottom_view.js"> +// <include src="timeline_data_series.js"> +// <include src="timeline_graph_view.js"> +// <include src="timeline_view.js"> +// <include src="log_view_painter.js"> +// <include src="log_grouper.js"> +// <include src="proxy_view.js"> +// <include src="quic_view.js"> +// <include src="socket_pool_wrapper.js"> +// <include src="sockets_view.js"> +// <include src="alt_svc_view.js"> +// <include src="spdy_view.js"> +// <include src="modules_view.js"> +// <include src="prerender_view.js"> +// <include src="chromeos_view.js"> +// <include src="bandwidth_view.js"> +// <include src="sdch_view.js"> document.addEventListener('DOMContentLoaded', function() { MainView.getInstance(); // from main.js
diff --git a/chrome/browser/resources/net_internals/log_grouper.js b/chrome/browser/resources/net_internals/log_grouper.js index a45b5cd..44ad0f7 100644 --- a/chrome/browser/resources/net_internals/log_grouper.js +++ b/chrome/browser/resources/net_internals/log_grouper.js
@@ -69,8 +69,7 @@ if (groupEntry.isEnd()) { // Walk up the parent stack to find the corresponding BEGIN for this // END. - var parentIndex = - findParentIndex(parentStack, groupEntry.orig.type); + var parentIndex = findParentIndex(parentStack, groupEntry.orig.type); if (parentIndex == -1) { // Unmatched end.
diff --git a/chrome/browser/resources/net_internals/log_util.js b/chrome/browser/resources/net_internals/log_util.js index 54a0607..a8ebe76 100644 --- a/chrome/browser/resources/net_internals/log_util.js +++ b/chrome/browser/resources/net_internals/log_util.js
@@ -31,8 +31,9 @@ * |polledData| and |tabData| may be empty objects, or may be missing data for * tabs not present on the OS the log is from. */ - function createLogDump(userComments, constants, events, polledData, tabData, - numericDate, privacyStripping) { + function createLogDump( + userComments, constants, events, polledData, tabData, numericDate, + privacyStripping) { if (privacyStripping) events = events.map(stripPrivacyInfo); @@ -64,13 +65,9 @@ numericDate = oldLogDump.constants.clientInfo.numericDate; } var logDump = createLogDump( - userComments, - Constants, + userComments, Constants, EventsTracker.getInstance().getAllCapturedEvents(), - oldLogDump.polledData, - getTabData_(), - numericDate, - privacyStripping); + oldLogDump.polledData, getTabData_(), numericDate, privacyStripping); return JSON.stringify(logDump); } @@ -78,16 +75,12 @@ * Creates a full log dump using |polledData| and the return value of each * tab's saveState function and passes it to |callback|. */ - function onUpdateAllCompleted(userComments, callback, privacyStripping, - polledData) { + function onUpdateAllCompleted( + userComments, callback, privacyStripping, polledData) { var logDump = createLogDump( - userComments, - Constants, - EventsTracker.getInstance().getAllCapturedEvents(), - polledData, - getTabData_(), - timeutil.getCurrentTime(), - privacyStripping); + userComments, Constants, + EventsTracker.getInstance().getAllCapturedEvents(), polledData, + getTabData_(), timeutil.getCurrentTime(), privacyStripping); callback(JSON.stringify(logDump)); } @@ -97,9 +90,8 @@ * text as a string. */ function createLogDumpAsync(userComments, callback, privacyStripping) { - g_browser.updateAllInfo( - onUpdateAllCompleted.bind(null, userComments, callback, - privacyStripping)); + g_browser.updateAllInfo(onUpdateAllCompleted.bind( + null, userComments, callback, privacyStripping)); } /** @@ -163,8 +155,8 @@ if (logDump.constants.logFormatVersion != Constants.logFormatVersion) { return 'Unable to load different log version.' + - ' Found ' + logDump.constants.logFormatVersion + - ', Expected ' + Constants.logFormatVersion; + ' Found ' + logDump.constants.logFormatVersion + ', Expected ' + + Constants.logFormatVersion; } g_browser.receivedConstants(logDump.constants); @@ -176,8 +168,7 @@ var numDeprecatedPassiveEvents = 0; for (var eventIndex = 0; eventIndex < logDump.events.length; ++eventIndex) { var event = logDump.events[eventIndex]; - if (typeof event == 'object' && - typeof event.source == 'object' && + if (typeof event == 'object' && typeof event.source == 'object' && typeof event.time == 'string' && typeof EventTypeNames[event.type] == 'string' && typeof EventSourceTypeNames[event.source.type] == 'string' && @@ -233,7 +224,7 @@ (validEvents.length + numDeprecatedPassiveEvents); if (numInvalidEvents > 0) { errorString += 'Unable to load ' + numInvalidEvents + - ' events, due to invalid data.\n\n'; + ' events, due to invalid data.\n\n'; } if (numDeprecatedPassiveEvents > 0) { @@ -250,14 +241,13 @@ // The try block eliminates the need for checking every single value // before trying to access it. try { - if (view.onLoadLogFinish(logDump.polledData, - logDump.tabData[tabId], - logDump)) { + if (view.onLoadLogFinish( + logDump.polledData, logDump.tabData[tabId], logDump)) { showView = true; } } catch (error) { - errorString += 'Caught error while calling onLoadLogFinish: ' + - error + '\n\n'; + errorString += + 'Caught error while calling onLoadLogFinish: ' + error + '\n\n'; } tabSwitcher.showTabLink(tabId, showView); } @@ -282,14 +272,14 @@ try { // We may have a --log-net-log=blah log dump. If so, remove the comma // after the final good entry, and add the necessary close brackets. - var end = Math.max(logFileContents.lastIndexOf(',\n'), - logFileContents.lastIndexOf(',\r')); + var end = Math.max( + logFileContents.lastIndexOf(',\n'), + logFileContents.lastIndexOf(',\r')); if (end != -1) { parsedDump = JSON.parse(logFileContents.substring(0, end) + ']}'); errorString += 'Log file truncated. Events may be missing.\n'; } - } - catch (error2) { + } catch (error2) { } }
diff --git a/chrome/browser/resources/net_internals/log_view_painter.js b/chrome/browser/resources/net_internals/log_view_painter.js index 228de54..ce2ef34 100644 --- a/chrome/browser/resources/net_internals/log_view_painter.js +++ b/chrome/browser/resources/net_internals/log_view_painter.js
@@ -10,261 +10,262 @@ // Start of anonymous namespace. (function() { -'use strict'; + 'use strict'; -function canCollapseBeginWithEnd(beginEntry) { - return beginEntry && - beginEntry.isBegin() && - beginEntry.end && - beginEntry.end.index == beginEntry.index + 1 && - (!beginEntry.orig.params || !beginEntry.end.orig.params); -} - -/** - * Creates a TablePrinter for use by the above two functions. baseTime is - * the time relative to which other times are displayed. - */ -createLogEntryTablePrinter = function(logEntries, privacyStripping, - baseTime, logCreationTime) { - var entries = LogGroupEntry.createArrayFrom(logEntries); - var tablePrinter = new TablePrinter(); - var parameterOutputter = new ParameterOutputter(tablePrinter); - - if (entries.length == 0) - return tablePrinter; - - var startTime = timeutil.convertTimeTicksToTime(entries[0].orig.time); - - for (var i = 0; i < entries.length; ++i) { - var entry = entries[i]; - - // Avoid printing the END for a BEGIN that was immediately before, unless - // both have extra parameters. - if (!entry.isEnd() || !canCollapseBeginWithEnd(entry.begin)) { - var entryTime = timeutil.convertTimeTicksToTime(entry.orig.time); - addRowWithTime(tablePrinter, entryTime - baseTime, startTime - baseTime); - - for (var j = entry.getDepth(); j > 0; --j) - tablePrinter.addCell(' '); - - var eventText = getTextForEvent(entry); - // Get the elapsed time, and append it to the event text. - if (entry.isBegin()) { - var dt = '?'; - // Definite time. - if (entry.end) { - dt = entry.end.orig.time - entry.orig.time; - } else if (logCreationTime != undefined) { - dt = (logCreationTime - entryTime) + '+'; - } - eventText += ' [dt=' + dt + ']'; - } - - var mainCell = tablePrinter.addCell(eventText); - mainCell.allowOverflow = true; - } - - // Output the extra parameters. - if (typeof entry.orig.params == 'object') { - // Those 5 skipped cells are: two for "t=", and three for "st=". - tablePrinter.setNewRowCellIndent(5 + entry.getDepth()); - writeParameters(entry.orig, privacyStripping, parameterOutputter); - - tablePrinter.setNewRowCellIndent(0); - } + function canCollapseBeginWithEnd(beginEntry) { + return beginEntry && beginEntry.isBegin() && beginEntry.end && + beginEntry.end.index == beginEntry.index + 1 && + (!beginEntry.orig.params || !beginEntry.end.orig.params); } - // If viewing a saved log file, add row with just the time the log was - // created, if the event never completed. - var lastEntry = entries[entries.length - 1]; - // If the last entry has a non-zero depth or is a begin event, the source is - // still active. - var isSourceActive = lastEntry.getDepth() != 0 || lastEntry.isBegin(); - if (logCreationTime != undefined && isSourceActive) { - addRowWithTime(tablePrinter, - logCreationTime - baseTime, - startTime - baseTime); - } - - return tablePrinter; -}; - -/** - * Adds a new row to the given TablePrinter, and adds five cells containing - * information about the time an event occured. - * Format is '[t=<time of the event in ms>] [st=<ms since the source started>]'. - * @param {TablePrinter} tablePrinter The table printer to add the cells to. - * @param {number} eventTime The time the event occured, in milliseconds, - * relative to some base time. - * @param {number} startTime The time the first event for the source occured, - * relative to the same base time as eventTime. - */ -function addRowWithTime(tablePrinter, eventTime, startTime) { - tablePrinter.addRow(); - tablePrinter.addCell('t='); - var tCell = tablePrinter.addCell(eventTime); - tCell.alignRight = true; - tablePrinter.addCell(' [st='); - var stCell = tablePrinter.addCell(eventTime - startTime); - stCell.alignRight = true; - tablePrinter.addCell('] '); -} - -/** - * |hexString| must be a string of hexadecimal characters with no whitespace, - * whose length is a multiple of two. Writes multiple lines to |out| with - * the hexadecimal characters from |hexString| on the left, in groups of - * two, and their corresponding ASCII characters on the right. - * - * 16 bytes will be placed on each line of the output string, split into two - * columns of 8. - */ -function writeHexString(hexString, out) { - var asciiCharsPerLine = 16; - // Number of transferred bytes in a line of output. Length of a - // line is roughly 4 times larger. - var hexCharsPerLine = 2 * asciiCharsPerLine; - for (var i = 0; i < hexString.length; i += hexCharsPerLine) { - var hexLine = ''; - var asciiLine = ''; - for (var j = i; j < i + hexCharsPerLine && j < hexString.length; j += 2) { - // Split into two columns of 8 bytes each. - if (j == i + hexCharsPerLine / 2) - hexLine += ' '; - var hex = hexString.substr(j, 2); - hexLine += hex + ' '; - var charCode = parseInt(hex, 16); - // For ASCII codes 32 though 126, display the corresponding - // characters. Use a space for nulls, and a period for - // everything else. - if (charCode >= 0x20 && charCode <= 0x7E) { - asciiLine += String.fromCharCode(charCode); - } else if (charCode == 0x00) { - asciiLine += ' '; - } else { - asciiLine += '.'; - } - } - - // Make the ASCII text for the last line of output align with the previous - // lines. - hexLine += makeRepeatedString(' ', - 3 * asciiCharsPerLine + 1 - hexLine.length); - out.writeLine(' ' + hexLine + ' ' + asciiLine); - } -} - -/** - * Wrapper around a TablePrinter to simplify outputting lines of text for event - * parameters. - */ -var ParameterOutputter = (function() { /** - * @constructor + * Creates a TablePrinter for use by the above two functions. baseTime is + * the time relative to which other times are displayed. */ - function ParameterOutputter(tablePrinter) { - this.tablePrinter_ = tablePrinter; - } + createLogEntryTablePrinter = function( + logEntries, privacyStripping, baseTime, logCreationTime) { + var entries = LogGroupEntry.createArrayFrom(logEntries); + var tablePrinter = new TablePrinter(); + var parameterOutputter = new ParameterOutputter(tablePrinter); - ParameterOutputter.prototype = { - /** - * Outputs a single line. - */ - writeLine: function(line) { - this.tablePrinter_.addRow(); - var cell = this.tablePrinter_.addCell(line); - cell.allowOverflow = true; - return cell; - }, + if (entries.length == 0) + return tablePrinter; - /** - * Outputs a key=value line which looks like: - * - * --> key = value - */ - writeArrowKeyValue: function(key, value, link) { - var cell = this.writeLine(kArrow + key + ' = ' + value); - cell.link = link; - }, + var startTime = timeutil.convertTimeTicksToTime(entries[0].orig.time); - /** - * Outputs a key= line which looks like: - * - * --> key = - */ - writeArrowKey: function(key) { - this.writeLine(kArrow + key + ' ='); - }, + for (var i = 0; i < entries.length; ++i) { + var entry = entries[i]; - /** - * Outputs multiple lines, each indented by numSpaces. - * For instance if numSpaces=8 it might look like this: - * - * line 1 - * line 2 - * line 3 - */ - writeSpaceIndentedLines: function(numSpaces, lines) { - var prefix = makeRepeatedString(' ', numSpaces); - for (var i = 0; i < lines.length; ++i) - this.writeLine(prefix + lines[i]); - }, + // Avoid printing the END for a BEGIN that was immediately before, unless + // both have extra parameters. + if (!entry.isEnd() || !canCollapseBeginWithEnd(entry.begin)) { + var entryTime = timeutil.convertTimeTicksToTime(entry.orig.time); + addRowWithTime( + tablePrinter, entryTime - baseTime, startTime - baseTime); - /** - * Outputs multiple lines such that the first line has - * an arrow pointing at it, and subsequent lines - * align with the first one. For example: - * - * --> line 1 - * line 2 - * line 3 - */ - writeArrowIndentedLines: function(lines) { - if (lines.length == 0) - return; + for (var j = entry.getDepth(); j > 0; --j) + tablePrinter.addCell(' '); - this.writeLine(kArrow + lines[0]); + var eventText = getTextForEvent(entry); + // Get the elapsed time, and append it to the event text. + if (entry.isBegin()) { + var dt = '?'; + // Definite time. + if (entry.end) { + dt = entry.end.orig.time - entry.orig.time; + } else if (logCreationTime != undefined) { + dt = (logCreationTime - entryTime) + '+'; + } + eventText += ' [dt=' + dt + ']'; + } - for (var i = 1; i < lines.length; ++i) - this.writeLine(kArrowIndentation + lines[i]); + var mainCell = tablePrinter.addCell(eventText); + mainCell.allowOverflow = true; + } + + // Output the extra parameters. + if (typeof entry.orig.params == 'object') { + // Those 5 skipped cells are: two for "t=", and three for "st=". + tablePrinter.setNewRowCellIndent(5 + entry.getDepth()); + writeParameters(entry.orig, privacyStripping, parameterOutputter); + + tablePrinter.setNewRowCellIndent(0); + } } + + // If viewing a saved log file, add row with just the time the log was + // created, if the event never completed. + var lastEntry = entries[entries.length - 1]; + // If the last entry has a non-zero depth or is a begin event, the source is + // still active. + var isSourceActive = lastEntry.getDepth() != 0 || lastEntry.isBegin(); + if (logCreationTime != undefined && isSourceActive) { + addRowWithTime( + tablePrinter, logCreationTime - baseTime, startTime - baseTime); + } + + return tablePrinter; }; - var kArrow = ' --> '; - var kArrowIndentation = ' '; - - return ParameterOutputter; -})(); // end of ParameterOutputter - -/** - * Formats the parameters for |entry| and writes them to |out|. - * Certain event types have custom pretty printers. Everything else will - * default to a JSON-like format. - */ -function writeParameters(entry, privacyStripping, out) { - if (privacyStripping) { - // If privacy stripping is enabled, remove data as needed. - entry = stripPrivacyInfo(entry); - } else { - // If headers are in an object, convert them to an array for better display. - entry = reformatHeaders(entry); + /** + * Adds a new row to the given TablePrinter, and adds five cells containing + * information about the time an event occured. + * Format is '[t=<time of the event in ms>] [st=<ms since the source + * started>]'. + * @param {TablePrinter} tablePrinter The table printer to add the cells to. + * @param {number} eventTime The time the event occured, in milliseconds, + * relative to some base time. + * @param {number} startTime The time the first event for the source occured, + * relative to the same base time as eventTime. + */ + function addRowWithTime(tablePrinter, eventTime, startTime) { + tablePrinter.addRow(); + tablePrinter.addCell('t='); + var tCell = tablePrinter.addCell(eventTime); + tCell.alignRight = true; + tablePrinter.addCell(' [st='); + var stCell = tablePrinter.addCell(eventTime - startTime); + stCell.alignRight = true; + tablePrinter.addCell('] '); } - // Use any parameter writer available for this event type. - var paramsWriter = getParameterWriterForEventType(entry.type); - var consumedParams = {}; - if (paramsWriter) - paramsWriter(entry, out, consumedParams); + /** + * |hexString| must be a string of hexadecimal characters with no whitespace, + * whose length is a multiple of two. Writes multiple lines to |out| with + * the hexadecimal characters from |hexString| on the left, in groups of + * two, and their corresponding ASCII characters on the right. + * + * 16 bytes will be placed on each line of the output string, split into two + * columns of 8. + */ + function writeHexString(hexString, out) { + var asciiCharsPerLine = 16; + // Number of transferred bytes in a line of output. Length of a + // line is roughly 4 times larger. + var hexCharsPerLine = 2 * asciiCharsPerLine; + for (var i = 0; i < hexString.length; i += hexCharsPerLine) { + var hexLine = ''; + var asciiLine = ''; + for (var j = i; j < i + hexCharsPerLine && j < hexString.length; j += 2) { + // Split into two columns of 8 bytes each. + if (j == i + hexCharsPerLine / 2) + hexLine += ' '; + var hex = hexString.substr(j, 2); + hexLine += hex + ' '; + var charCode = parseInt(hex, 16); + // For ASCII codes 32 though 126, display the corresponding + // characters. Use a space for nulls, and a period for + // everything else. + if (charCode >= 0x20 && charCode <= 0x7E) { + asciiLine += String.fromCharCode(charCode); + } else if (charCode == 0x00) { + asciiLine += ' '; + } else { + asciiLine += '.'; + } + } - // Write any un-consumed parameters. - for (var k in entry.params) { - if (consumedParams[k]) - continue; - defaultWriteParameter(k, entry.params[k], out); + // Make the ASCII text for the last line of output align with the previous + // lines. + hexLine += + makeRepeatedString(' ', 3 * asciiCharsPerLine + 1 - hexLine.length); + out.writeLine(' ' + hexLine + ' ' + asciiLine); + } } -} -/** + /** + * Wrapper around a TablePrinter to simplify outputting lines of text for + * event + * parameters. + */ + var ParameterOutputter = (function() { + /** + * @constructor + */ + function ParameterOutputter(tablePrinter) { + this.tablePrinter_ = tablePrinter; + } + + ParameterOutputter.prototype = { + /** + * Outputs a single line. + */ + writeLine: function(line) { + this.tablePrinter_.addRow(); + var cell = this.tablePrinter_.addCell(line); + cell.allowOverflow = true; + return cell; + }, + + /** + * Outputs a key=value line which looks like: + * + * --> key = value + */ + writeArrowKeyValue: function(key, value, link) { + var cell = this.writeLine(kArrow + key + ' = ' + value); + cell.link = link; + }, + + /** + * Outputs a key= line which looks like: + * + * --> key = + */ + writeArrowKey: function(key) { + this.writeLine(kArrow + key + ' ='); + }, + + /** + * Outputs multiple lines, each indented by numSpaces. + * For instance if numSpaces=8 it might look like this: + * + * line 1 + * line 2 + * line 3 + */ + writeSpaceIndentedLines: function(numSpaces, lines) { + var prefix = makeRepeatedString(' ', numSpaces); + for (var i = 0; i < lines.length; ++i) + this.writeLine(prefix + lines[i]); + }, + + /** + * Outputs multiple lines such that the first line has + * an arrow pointing at it, and subsequent lines + * align with the first one. For example: + * + * --> line 1 + * line 2 + * line 3 + */ + writeArrowIndentedLines: function(lines) { + if (lines.length == 0) + return; + + this.writeLine(kArrow + lines[0]); + + for (var i = 1; i < lines.length; ++i) + this.writeLine(kArrowIndentation + lines[i]); + } + }; + + var kArrow = ' --> '; + var kArrowIndentation = ' '; + + return ParameterOutputter; + })(); // end of ParameterOutputter + + /** + * Formats the parameters for |entry| and writes them to |out|. + * Certain event types have custom pretty printers. Everything else will + * default to a JSON-like format. + */ + function writeParameters(entry, privacyStripping, out) { + if (privacyStripping) { + // If privacy stripping is enabled, remove data as needed. + entry = stripPrivacyInfo(entry); + } else { + // If headers are in an object, convert them to an array for better + // display. + entry = reformatHeaders(entry); + } + + // Use any parameter writer available for this event type. + var paramsWriter = getParameterWriterForEventType(entry.type); + var consumedParams = {}; + if (paramsWriter) + paramsWriter(entry, out, consumedParams); + + // Write any un-consumed parameters. + for (var k in entry.params) { + if (consumedParams[k]) + continue; + defaultWriteParameter(k, entry.params[k], out); + } + } + + /** * Finds a writer to format the parameters for events of type |eventType|. * * @return {function} The returned function "writer" can be invoked @@ -274,539 +275,540 @@ * consumed. If no writer is available for |eventType| then * returns null. */ -function getParameterWriterForEventType(eventType) { - switch (eventType) { - case EventType.HTTP_TRANSACTION_SEND_REQUEST_HEADERS: - case EventType.HTTP_TRANSACTION_SEND_TUNNEL_HEADERS: - case EventType.TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS: - return writeParamsForRequestHeaders; + function getParameterWriterForEventType(eventType) { + switch (eventType) { + case EventType.HTTP_TRANSACTION_SEND_REQUEST_HEADERS: + case EventType.HTTP_TRANSACTION_SEND_TUNNEL_HEADERS: + case EventType.TYPE_HTTP_CACHE_CALLER_REQUEST_HEADERS: + return writeParamsForRequestHeaders; - case EventType.PROXY_CONFIG_CHANGED: - return writeParamsForProxyConfigChanged; + case EventType.PROXY_CONFIG_CHANGED: + return writeParamsForProxyConfigChanged; - case EventType.CERT_VERIFIER_JOB: - case EventType.SSL_CERTIFICATES_RECEIVED: - return writeParamsForCertificates; - case EventType.CERT_CT_COMPLIANCE_CHECKED: - case EventType.EV_CERT_CT_COMPLIANCE_CHECKED: - return writeParamsForCheckedCertificates; + case EventType.CERT_VERIFIER_JOB: + case EventType.SSL_CERTIFICATES_RECEIVED: + return writeParamsForCertificates; + case EventType.CERT_CT_COMPLIANCE_CHECKED: + case EventType.EV_CERT_CT_COMPLIANCE_CHECKED: + return writeParamsForCheckedCertificates; - case EventType.SSL_VERSION_FALLBACK: - return writeParamsForSSLVersionFallback; - } - return null; -} - -/** - * Default parameter writer that outputs a visualization of field named |key| - * with value |value| to |out|. - */ -function defaultWriteParameter(key, value, out) { - if (key == 'headers' && value instanceof Array) { - out.writeArrowIndentedLines(value); - return; - } - - // For transferred bytes, display the bytes in hex and ASCII. - if (key == 'hex_encoded_bytes' && typeof value == 'string') { - out.writeArrowKey(key); - writeHexString(value, out); - return; - } - - // Handle source_dependency entries - add link and map source type to - // string. - if (key == 'source_dependency' && typeof value == 'object') { - var link = '#events&s=' + value.id; - var valueStr = value.id + ' (' + EventSourceTypeNames[value.type] + ')'; - out.writeArrowKeyValue(key, valueStr, link); - return; - } - - if (key == 'net_error' && typeof value == 'number') { - var valueStr = value + ' (' + netErrorToString(value) + ')'; - out.writeArrowKeyValue(key, valueStr); - return; - } - - if (key == 'quic_error' && typeof value == 'number') { - var valueStr = value + ' (' + quicErrorToString(value) + ')'; - out.writeArrowKeyValue(key, valueStr); - return; - } - - if (key == 'quic_crypto_handshake_message' && typeof value == 'string') { - var lines = value.split('\n'); - out.writeArrowIndentedLines(lines); - return; - } - - if (key == 'quic_rst_stream_error' && typeof value == 'number') { - var valueStr = value + ' (' + quicRstStreamErrorToString(value) + ')'; - out.writeArrowKeyValue(key, valueStr); - return; - } - - if (key == 'load_flags' && typeof value == 'number') { - var valueStr = value + ' (' + getLoadFlagSymbolicString(value) + ')'; - out.writeArrowKeyValue(key, valueStr); - return; - } - - if (key == 'load_state' && typeof value == 'number') { - var valueStr = value + ' (' + getKeyWithValue(LoadState, value) + ')'; - out.writeArrowKeyValue(key, valueStr); - return; - } - - if (key == 'sdch_problem_code' && typeof value == 'number') { - var valueStr = value + ' (' + sdchProblemCodeToString(value) + ')'; - out.writeArrowKeyValue(key, valueStr); - return; - } - - // Otherwise just default to JSON formatting of the value. - out.writeArrowKeyValue(key, JSON.stringify(value)); -} - -/** - * Returns the set of LoadFlags that make up the integer |loadFlag|. - * For example: getLoadFlagSymbolicString( - */ -function getLoadFlagSymbolicString(loadFlag) { - - return getSymbolicString(loadFlag, LoadFlag, - getKeyWithValue(LoadFlag, loadFlag)); -} - -/** - * Returns the set of CertStatusFlags that make up the integer |certStatusFlag| - */ -function getCertStatusFlagSymbolicString(certStatusFlag) { - return getSymbolicString(certStatusFlag, CertStatusFlag, ''); -} - -/** - * Returns a string representing the flags composing the given bitmask. - */ -function getSymbolicString(bitmask, valueToName, zeroName) { - var matchingFlagNames = []; - - for (var k in valueToName) { - if (bitmask & valueToName[k]) - matchingFlagNames.push(k); - } - - // If no flags were matched, returns a special value. - if (matchingFlagNames.length == 0) - return zeroName; - - return matchingFlagNames.join(' | '); -} - -/** - * Converts an SSL version number to a textual representation. - * For instance, SSLVersionNumberToName(0x0301) returns 'TLS 1.0'. - */ -function SSLVersionNumberToName(version) { - if ((version & 0xFFFF) != version) { - // If the version number is more than 2 bytes long something is wrong. - // Print it as hex. - return 'SSL 0x' + version.toString(16); - } - - // See if it is a known TLS name. - var kTLSNames = { - 0x0301: 'TLS 1.0', - 0x0302: 'TLS 1.1', - 0x0303: 'TLS 1.2' - }; - var name = kTLSNames[version]; - if (name) - return name; - - // Otherwise label it as an SSL version. - var major = (version & 0xFF00) >> 8; - var minor = version & 0x00FF; - - return 'SSL ' + major + '.' + minor; -} - -/** - * TODO(eroman): get rid of this, as it is only used by 1 callsite. - * - * Indent |lines| by |start|. - * - * For example, if |start| = ' -> ' and |lines| = ['line1', 'line2', 'line3'] - * the output will be: - * - * " -> line1\n" + - * " line2\n" + - * " line3" - */ -function indentLines(start, lines) { - return start + lines.join('\n' + makeRepeatedString(' ', start.length)); -} - -/** - * If entry.param.headers exists and is an object other than an array, converts - * it into an array and returns a new entry. Otherwise, just returns the - * original entry. - */ -function reformatHeaders(entry) { - // If there are no headers, or it is not an object other than an array, - // return |entry| without modification. - if (!entry.params || entry.params.headers === undefined || - typeof entry.params.headers != 'object' || - entry.params.headers instanceof Array) { - return entry; - } - - // Duplicate the top level object, and |entry.params|, so the original object - // will not be modified. - entry = shallowCloneObject(entry); - entry.params = shallowCloneObject(entry.params); - - // Convert headers to an array. - var headers = []; - for (var key in entry.params.headers) - headers.push(key + ': ' + entry.params.headers[key]); - entry.params.headers = headers; - - return entry; -} - -/** - * Removes a cookie or unencrypted login information from a single HTTP header - * line, if present, and returns the modified line. Otherwise, just returns - * the original line. - * - * Note: this logic should be kept in sync with - * net::ElideHeaderValueForNetLog in net/http/http_log_util.cc. - */ -function stripCookieOrLoginInfo(line) { - var patterns = [ - // Cookie patterns - /^set-cookie: /i, - /^set-cookie2: /i, - /^cookie: /i, - - // Unencrypted authentication patterns - /^authorization: \S*\s*/i, - /^proxy-authorization: \S*\s*/i]; - - // Prefix will hold the first part of the string that contains no private - // information. If null, no part of the string contains private information. - var prefix = null; - for (var i = 0; i < patterns.length; i++) { - var match = patterns[i].exec(line); - if (match != null) { - prefix = match[0]; - break; + case EventType.SSL_VERSION_FALLBACK: + return writeParamsForSSLVersionFallback; } + return null; } - // Look for authentication information from data received from the server in - // multi-round Negotiate authentication. - if (prefix === null) { - var challengePatterns = [ - /^www-authenticate: (\S*)\s*/i, - /^proxy-authenticate: (\S*)\s*/i]; - for (var i = 0; i < challengePatterns.length; i++) { - var match = challengePatterns[i].exec(line); - if (!match) - continue; - - // If there's no data after the scheme name, do nothing. - if (match[0].length == line.length) - break; - - // Ignore lines with commas, as they may contain lists of schemes, and - // the information we want to hide is Base64 encoded, so has no commas. - if (line.indexOf(',') >= 0) - break; - - // Ignore Basic and Digest authentication challenges, as they contain - // public information. - if (/^basic$/i.test(match[1]) || /^digest$/i.test(match[1])) - break; - - prefix = match[0]; - break; + /** + * Default parameter writer that outputs a visualization of field named |key| + * with value |value| to |out|. + */ + function defaultWriteParameter(key, value, out) { + if (key == 'headers' && value instanceof Array) { + out.writeArrowIndentedLines(value); + return; } - } - if (prefix) { - var suffix = line.slice(prefix.length); - // If private information has already been removed, keep the line as-is. - // This is often the case when viewing a loaded log. - if (suffix.search(/^\[[0-9]+ bytes were stripped\]$/) == -1) { - return prefix + '[' + suffix.length + ' bytes were stripped]'; + // For transferred bytes, display the bytes in hex and ASCII. + if (key == 'hex_encoded_bytes' && typeof value == 'string') { + out.writeArrowKey(key); + writeHexString(value, out); + return; } + + // Handle source_dependency entries - add link and map source type to + // string. + if (key == 'source_dependency' && typeof value == 'object') { + var link = '#events&s=' + value.id; + var valueStr = value.id + ' (' + EventSourceTypeNames[value.type] + ')'; + out.writeArrowKeyValue(key, valueStr, link); + return; + } + + if (key == 'net_error' && typeof value == 'number') { + var valueStr = value + ' (' + netErrorToString(value) + ')'; + out.writeArrowKeyValue(key, valueStr); + return; + } + + if (key == 'quic_error' && typeof value == 'number') { + var valueStr = value + ' (' + quicErrorToString(value) + ')'; + out.writeArrowKeyValue(key, valueStr); + return; + } + + if (key == 'quic_crypto_handshake_message' && typeof value == 'string') { + var lines = value.split('\n'); + out.writeArrowIndentedLines(lines); + return; + } + + if (key == 'quic_rst_stream_error' && typeof value == 'number') { + var valueStr = value + ' (' + quicRstStreamErrorToString(value) + ')'; + out.writeArrowKeyValue(key, valueStr); + return; + } + + if (key == 'load_flags' && typeof value == 'number') { + var valueStr = value + ' (' + getLoadFlagSymbolicString(value) + ')'; + out.writeArrowKeyValue(key, valueStr); + return; + } + + if (key == 'load_state' && typeof value == 'number') { + var valueStr = value + ' (' + getKeyWithValue(LoadState, value) + ')'; + out.writeArrowKeyValue(key, valueStr); + return; + } + + if (key == 'sdch_problem_code' && typeof value == 'number') { + var valueStr = value + ' (' + sdchProblemCodeToString(value) + ')'; + out.writeArrowKeyValue(key, valueStr); + return; + } + + // Otherwise just default to JSON formatting of the value. + out.writeArrowKeyValue(key, JSON.stringify(value)); } - return line; -} - -/** - * Remove debug data from HTTP/2 GOAWAY frame due to privacy considerations, see - * https://httpwg.github.io/specs/rfc7540.html#GOAWAY. - * - * Note: this logic should be kept in sync with - * net::ElideGoAwayDebugDataForNetLog in net/http/http_log_util.cc. - */ -function stripGoAwayDebugData(value) { - return '[' + value.length + ' bytes were stripped]'; -} - -/** - * If |entry| has headers, returns a copy of |entry| with all cookie and - * unencrypted login text removed. Otherwise, returns original |entry| object. - * This is needed so that JSON log dumps can be made without affecting the - * source data. Converts headers stored in objects to arrays. - */ -stripPrivacyInfo = function(entry) { - if (!entry.params) { - return entry; + /** + * Returns the set of LoadFlags that make up the integer |loadFlag|. + * For example: getLoadFlagSymbolicString( + */ + function getLoadFlagSymbolicString(loadFlag) { + return getSymbolicString( + loadFlag, LoadFlag, getKeyWithValue(LoadFlag, loadFlag)); } - if (entry.type == EventType.HTTP2_SESSION_GOAWAY && - entry.params.debug_data != undefined) { - // Duplicate the top level object, and |entry.params|. All other fields are - // just pointers to the original values, as they won't be modified, other - // than |entry.params.debug_data|. + /** + * Returns the set of CertStatusFlags that make up the integer + * |certStatusFlag| + */ + function getCertStatusFlagSymbolicString(certStatusFlag) { + return getSymbolicString(certStatusFlag, CertStatusFlag, ''); + } + + /** + * Returns a string representing the flags composing the given bitmask. + */ + function getSymbolicString(bitmask, valueToName, zeroName) { + var matchingFlagNames = []; + + for (var k in valueToName) { + if (bitmask & valueToName[k]) + matchingFlagNames.push(k); + } + + // If no flags were matched, returns a special value. + if (matchingFlagNames.length == 0) + return zeroName; + + return matchingFlagNames.join(' | '); + } + + /** + * Converts an SSL version number to a textual representation. + * For instance, SSLVersionNumberToName(0x0301) returns 'TLS 1.0'. + */ + function SSLVersionNumberToName(version) { + if ((version & 0xFFFF) != version) { + // If the version number is more than 2 bytes long something is wrong. + // Print it as hex. + return 'SSL 0x' + version.toString(16); + } + + // See if it is a known TLS name. + var kTLSNames = {0x0301: 'TLS 1.0', 0x0302: 'TLS 1.1', 0x0303: 'TLS 1.2'}; + var name = kTLSNames[version]; + if (name) + return name; + + // Otherwise label it as an SSL version. + var major = (version & 0xFF00) >> 8; + var minor = version & 0x00FF; + + return 'SSL ' + major + '.' + minor; + } + + /** + * TODO(eroman): get rid of this, as it is only used by 1 callsite. + * + * Indent |lines| by |start|. + * + * For example, if |start| = ' -> ' and |lines| = ['line1', 'line2', 'line3'] + * the output will be: + * + * " -> line1\n" + + * " line2\n" + + * " line3" + */ + function indentLines(start, lines) { + return start + lines.join('\n' + makeRepeatedString(' ', start.length)); + } + + /** + * If entry.param.headers exists and is an object other than an array, + * converts + * it into an array and returns a new entry. Otherwise, just returns the + * original entry. + */ + function reformatHeaders(entry) { + // If there are no headers, or it is not an object other than an array, + // return |entry| without modification. + if (!entry.params || entry.params.headers === undefined || + typeof entry.params.headers != 'object' || + entry.params.headers instanceof Array) { + return entry; + } + + // Duplicate the top level object, and |entry.params|, so the original + // object + // will not be modified. entry = shallowCloneObject(entry); entry.params = shallowCloneObject(entry.params); - entry.params.debug_data = - stripGoAwayDebugData(entry.params.debug_data); + + // Convert headers to an array. + var headers = []; + for (var key in entry.params.headers) + headers.push(key + ': ' + entry.params.headers[key]); + entry.params.headers = headers; + return entry; } - if (entry.params.headers === undefined || - !(entry.params.headers instanceof Object)) { - return entry; - } + /** + * Removes a cookie or unencrypted login information from a single HTTP header + * line, if present, and returns the modified line. Otherwise, just returns + * the original line. + * + * Note: this logic should be kept in sync with + * net::ElideHeaderValueForNetLog in net/http/http_log_util.cc. + */ + function stripCookieOrLoginInfo(line) { + var patterns = [ + // Cookie patterns + /^set-cookie: /i, /^set-cookie2: /i, /^cookie: /i, - // Make sure entry's headers are in an array. - entry = reformatHeaders(entry); + // Unencrypted authentication patterns + /^authorization: \S*\s*/i, /^proxy-authorization: \S*\s*/i + ]; - // Duplicate the top level object, and |entry.params|. All other fields are - // just pointers to the original values, as they won't be modified, other than - // |entry.params.headers|. - entry = shallowCloneObject(entry); - entry.params = shallowCloneObject(entry.params); - - entry.params.headers = entry.params.headers.map(stripCookieOrLoginInfo); - return entry; -}; - -/** - * Outputs the request header parameters of |entry| to |out|. - */ -function writeParamsForRequestHeaders(entry, out, consumedParams) { - var params = entry.params; - - if (!(typeof params.line == 'string') || !(params.headers instanceof Array)) { - // Unrecognized params. - return; - } - - // Strip the trailing CRLF that params.line contains. - var lineWithoutCRLF = params.line.replace(/\r\n$/g, ''); - out.writeArrowIndentedLines([lineWithoutCRLF].concat(params.headers)); - - consumedParams.line = true; - consumedParams.headers = true; -} - -function writeCertificateParam( - certs_container, out, consumedParams, paramName) { - if (certs_container.certificates instanceof Array) { - var certs = certs_container.certificates.reduce( - function(previous, current) { - return previous.concat(current.split('\n')); - }, new Array()); - out.writeArrowKey(paramName); - out.writeSpaceIndentedLines(8, certs); - consumedParams[paramName] = true; - } -} - -/** - * Outputs the certificate parameters of |entry| to |out|. - */ -function writeParamsForCertificates(entry, out, consumedParams) { - writeCertificateParam(entry.params, out, consumedParams, 'certificates'); - - if (typeof(entry.params.verified_cert) == 'object') - writeCertificateParam( - entry.params.verified_cert, out, consumedParams, 'verified_cert'); - - if (typeof(entry.params.cert_status) == 'number') { - var valueStr = entry.params.cert_status + ' (' + - getCertStatusFlagSymbolicString(entry.params.cert_status) + ')'; - out.writeArrowKeyValue('cert_status', valueStr); - consumedParams.cert_status = true; - } - -} - -function writeParamsForCheckedCertificates(entry, out, consumedParams) { - if (typeof(entry.params.certificate) == 'object') - writeCertificateParam( - entry.params.certificate, out, consumedParams, 'certificate'); -} - -/** - * Outputs the SSL version fallback parameters of |entry| to |out|. - */ -function writeParamsForSSLVersionFallback(entry, out, consumedParams) { - var params = entry.params; - - if (typeof params.version_before != 'number' || - typeof params.version_after != 'number') { - // Unrecognized params. - return; - } - - var line = SSLVersionNumberToName(params.version_before) + - ' ==> ' + - SSLVersionNumberToName(params.version_after); - out.writeArrowIndentedLines([line]); - - consumedParams.version_before = true; - consumedParams.version_after = true; -} - -function writeParamsForProxyConfigChanged(entry, out, consumedParams) { - var params = entry.params; - - if (typeof params.new_config != 'object') { - // Unrecognized params. - return; - } - - if (typeof params.old_config == 'object') { - var oldConfigString = proxySettingsToString(params.old_config); - // The previous configuration may not be present in the case of - // the initial proxy settings fetch. - out.writeArrowKey('old_config'); - - out.writeSpaceIndentedLines(8, oldConfigString.split('\n')); - - consumedParams.old_config = true; - } - - var newConfigString = proxySettingsToString(params.new_config); - out.writeArrowKey('new_config'); - out.writeSpaceIndentedLines(8, newConfigString.split('\n')); - - consumedParams.new_config = true; -} - -function getTextForEvent(entry) { - var text = ''; - - if (entry.isBegin() && canCollapseBeginWithEnd(entry)) { - // Don't prefix with '+' if we are going to collapse the END event. - text = ' '; - } else if (entry.isBegin()) { - text = '+' + text; - } else if (entry.isEnd()) { - text = '-' + text; - } else { - text = ' '; - } - - text += EventTypeNames[entry.orig.type]; - return text; -} - -proxySettingsToString = function(config) { - if (!config) - return ''; - - // TODO(eroman): if |config| has unexpected properties, print it as JSON - // rather than hide them. - - function getProxyListString(proxies) { - // Older versions of Chrome would set these values as strings, whereas newer - // logs use arrays. - // TODO(eroman): This behavior changed in M27. Support for older logs can - // safely be removed circa M29. - if (Array.isArray(proxies)) { - var listString = proxies.join(', '); - if (proxies.length > 1) - return '[' + listString + ']'; - return listString; + // Prefix will hold the first part of the string that contains no private + // information. If null, no part of the string contains private + // information. + var prefix = null; + for (var i = 0; i < patterns.length; i++) { + var match = patterns[i].exec(line); + if (match != null) { + prefix = match[0]; + break; + } } - return proxies; + + // Look for authentication information from data received from the server in + // multi-round Negotiate authentication. + if (prefix === null) { + var challengePatterns = + [/^www-authenticate: (\S*)\s*/i, /^proxy-authenticate: (\S*)\s*/i]; + for (var i = 0; i < challengePatterns.length; i++) { + var match = challengePatterns[i].exec(line); + if (!match) + continue; + + // If there's no data after the scheme name, do nothing. + if (match[0].length == line.length) + break; + + // Ignore lines with commas, as they may contain lists of schemes, and + // the information we want to hide is Base64 encoded, so has no commas. + if (line.indexOf(',') >= 0) + break; + + // Ignore Basic and Digest authentication challenges, as they contain + // public information. + if (/^basic$/i.test(match[1]) || /^digest$/i.test(match[1])) + break; + + prefix = match[0]; + break; + } + } + + if (prefix) { + var suffix = line.slice(prefix.length); + // If private information has already been removed, keep the line as-is. + // This is often the case when viewing a loaded log. + if (suffix.search(/^\[[0-9]+ bytes were stripped\]$/) == -1) { + return prefix + '[' + suffix.length + ' bytes were stripped]'; + } + } + + return line; } - // The proxy settings specify up to three major fallback choices - // (auto-detect, custom pac url, or manual settings). - // We enumerate these to a list so we can later number them. - var modes = []; + /** + * Remove debug data from HTTP/2 GOAWAY frame due to privacy considerations, + * see + * https://httpwg.github.io/specs/rfc7540.html#GOAWAY. + * + * Note: this logic should be kept in sync with + * net::ElideGoAwayDebugDataForNetLog in net/http/http_log_util.cc. + */ + function stripGoAwayDebugData(value) { + return '[' + value.length + ' bytes were stripped]'; + } - // Output any automatic settings. - if (config.auto_detect) - modes.push(['Auto-detect']); - if (config.pac_url) - modes.push(['PAC script: ' + config.pac_url]); + /** + * If |entry| has headers, returns a copy of |entry| with all cookie and + * unencrypted login text removed. Otherwise, returns original |entry| + * object. + * This is needed so that JSON log dumps can be made without affecting the + * source data. Converts headers stored in objects to arrays. + */ + stripPrivacyInfo = function(entry) { + if (!entry.params) { + return entry; + } - // Output any manual settings. - if (config.single_proxy || config.proxy_per_scheme) { - var lines = []; + if (entry.type == EventType.HTTP2_SESSION_GOAWAY && + entry.params.debug_data != undefined) { + // Duplicate the top level object, and |entry.params|. All other fields + // are + // just pointers to the original values, as they won't be modified, other + // than |entry.params.debug_data|. + entry = shallowCloneObject(entry); + entry.params = shallowCloneObject(entry.params); + entry.params.debug_data = stripGoAwayDebugData(entry.params.debug_data); + return entry; + } - if (config.single_proxy) { - lines.push('Proxy server: ' + getProxyListString(config.single_proxy)); - } else if (config.proxy_per_scheme) { - for (var urlScheme in config.proxy_per_scheme) { - if (urlScheme != 'fallback') { - lines.push('Proxy server for ' + urlScheme.toUpperCase() + ': ' + - getProxyListString(config.proxy_per_scheme[urlScheme])); + if (entry.params.headers === undefined || + !(entry.params.headers instanceof Object)) { + return entry; + } + + // Make sure entry's headers are in an array. + entry = reformatHeaders(entry); + + // Duplicate the top level object, and |entry.params|. All other fields are + // just pointers to the original values, as they won't be modified, other + // than + // |entry.params.headers|. + entry = shallowCloneObject(entry); + entry.params = shallowCloneObject(entry.params); + + entry.params.headers = entry.params.headers.map(stripCookieOrLoginInfo); + return entry; + }; + + /** + * Outputs the request header parameters of |entry| to |out|. + */ + function writeParamsForRequestHeaders(entry, out, consumedParams) { + var params = entry.params; + + if (!(typeof params.line == 'string') || + !(params.headers instanceof Array)) { + // Unrecognized params. + return; + } + + // Strip the trailing CRLF that params.line contains. + var lineWithoutCRLF = params.line.replace(/\r\n$/g, ''); + out.writeArrowIndentedLines([lineWithoutCRLF].concat(params.headers)); + + consumedParams.line = true; + consumedParams.headers = true; + } + + function writeCertificateParam( + certs_container, out, consumedParams, paramName) { + if (certs_container.certificates instanceof Array) { + var certs = + certs_container.certificates.reduce(function(previous, current) { + return previous.concat(current.split('\n')); + }, new Array()); + out.writeArrowKey(paramName); + out.writeSpaceIndentedLines(8, certs); + consumedParams[paramName] = true; + } + } + + /** + * Outputs the certificate parameters of |entry| to |out|. + */ + function writeParamsForCertificates(entry, out, consumedParams) { + writeCertificateParam(entry.params, out, consumedParams, 'certificates'); + + if (typeof(entry.params.verified_cert) == 'object') + writeCertificateParam( + entry.params.verified_cert, out, consumedParams, 'verified_cert'); + + if (typeof(entry.params.cert_status) == 'number') { + var valueStr = entry.params.cert_status + ' (' + + getCertStatusFlagSymbolicString(entry.params.cert_status) + ')'; + out.writeArrowKeyValue('cert_status', valueStr); + consumedParams.cert_status = true; + } + } + + function writeParamsForCheckedCertificates(entry, out, consumedParams) { + if (typeof(entry.params.certificate) == 'object') + writeCertificateParam( + entry.params.certificate, out, consumedParams, 'certificate'); + } + + /** + * Outputs the SSL version fallback parameters of |entry| to |out|. + */ + function writeParamsForSSLVersionFallback(entry, out, consumedParams) { + var params = entry.params; + + if (typeof params.version_before != 'number' || + typeof params.version_after != 'number') { + // Unrecognized params. + return; + } + + var line = SSLVersionNumberToName(params.version_before) + ' ==> ' + + SSLVersionNumberToName(params.version_after); + out.writeArrowIndentedLines([line]); + + consumedParams.version_before = true; + consumedParams.version_after = true; + } + + function writeParamsForProxyConfigChanged(entry, out, consumedParams) { + var params = entry.params; + + if (typeof params.new_config != 'object') { + // Unrecognized params. + return; + } + + if (typeof params.old_config == 'object') { + var oldConfigString = proxySettingsToString(params.old_config); + // The previous configuration may not be present in the case of + // the initial proxy settings fetch. + out.writeArrowKey('old_config'); + + out.writeSpaceIndentedLines(8, oldConfigString.split('\n')); + + consumedParams.old_config = true; + } + + var newConfigString = proxySettingsToString(params.new_config); + out.writeArrowKey('new_config'); + out.writeSpaceIndentedLines(8, newConfigString.split('\n')); + + consumedParams.new_config = true; + } + + function getTextForEvent(entry) { + var text = ''; + + if (entry.isBegin() && canCollapseBeginWithEnd(entry)) { + // Don't prefix with '+' if we are going to collapse the END event. + text = ' '; + } else if (entry.isBegin()) { + text = '+' + text; + } else if (entry.isEnd()) { + text = '-' + text; + } else { + text = ' '; + } + + text += EventTypeNames[entry.orig.type]; + return text; + } + + proxySettingsToString = function(config) { + if (!config) + return ''; + + // TODO(eroman): if |config| has unexpected properties, print it as JSON + // rather than hide them. + + function getProxyListString(proxies) { + // Older versions of Chrome would set these values as strings, whereas + // newer + // logs use arrays. + // TODO(eroman): This behavior changed in M27. Support for older logs can + // safely be removed circa M29. + if (Array.isArray(proxies)) { + var listString = proxies.join(', '); + if (proxies.length > 1) + return '[' + listString + ']'; + return listString; + } + return proxies; + } + + // The proxy settings specify up to three major fallback choices + // (auto-detect, custom pac url, or manual settings). + // We enumerate these to a list so we can later number them. + var modes = []; + + // Output any automatic settings. + if (config.auto_detect) + modes.push(['Auto-detect']); + if (config.pac_url) + modes.push(['PAC script: ' + config.pac_url]); + + // Output any manual settings. + if (config.single_proxy || config.proxy_per_scheme) { + var lines = []; + + if (config.single_proxy) { + lines.push('Proxy server: ' + getProxyListString(config.single_proxy)); + } else if (config.proxy_per_scheme) { + for (var urlScheme in config.proxy_per_scheme) { + if (urlScheme != 'fallback') { + lines.push( + 'Proxy server for ' + urlScheme.toUpperCase() + ': ' + + getProxyListString(config.proxy_per_scheme[urlScheme])); + } + } + if (config.proxy_per_scheme.fallback) { + lines.push( + 'Proxy server for everything else: ' + + getProxyListString(config.proxy_per_scheme.fallback)); } } - if (config.proxy_per_scheme.fallback) { - lines.push('Proxy server for everything else: ' + - getProxyListString(config.proxy_per_scheme.fallback)); - } - } - // Output any proxy bypass rules. - if (config.bypass_list) { - if (config.reverse_bypass) { - lines.push('Reversed bypass list: '); - } else { - lines.push('Bypass list: '); + // Output any proxy bypass rules. + if (config.bypass_list) { + if (config.reverse_bypass) { + lines.push('Reversed bypass list: '); + } else { + lines.push('Bypass list: '); + } + + for (var i = 0; i < config.bypass_list.length; ++i) + lines.push(' ' + config.bypass_list[i]); } - for (var i = 0; i < config.bypass_list.length; ++i) - lines.push(' ' + config.bypass_list[i]); + modes.push(lines); } - modes.push(lines); - } + var result = []; + if (modes.length < 1) { + // If we didn't find any proxy settings modes, we are using DIRECT. + result.push('Use DIRECT connections.'); + } else if (modes.length == 1) { + // If there was just one mode, don't bother numbering it. + result.push(modes[0].join('\n')); + } else { + // Otherwise concatenate all of the modes into a numbered list + // (which correspond with the fallback order). + for (var i = 0; i < modes.length; ++i) + result.push(indentLines('(' + (i + 1) + ') ', modes[i])); + } - var result = []; - if (modes.length < 1) { - // If we didn't find any proxy settings modes, we are using DIRECT. - result.push('Use DIRECT connections.'); - } else if (modes.length == 1) { - // If there was just one mode, don't bother numbering it. - result.push(modes[0].join('\n')); - } else { - // Otherwise concatenate all of the modes into a numbered list - // (which correspond with the fallback order). - for (var i = 0; i < modes.length; ++i) - result.push(indentLines('(' + (i + 1) + ') ', modes[i])); - } + if (config.source != undefined && config.source != 'UNKNOWN') + result.push('Source: ' + config.source); - if (config.source != undefined && config.source != 'UNKNOWN') - result.push('Source: ' + config.source); + return result.join('\n'); + }; - return result.join('\n'); -}; - -// End of anonymous namespace. + // End of anonymous namespace. })();
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js index 33d6293..6b56557d6 100644 --- a/chrome/browser/resources/net_internals/main.js +++ b/chrome/browser/resources/net_internals/main.js
@@ -72,8 +72,8 @@ // log file). Below it we will position the main tabs and their content // area. this.topBarView_ = TopBarView.getInstance(this); - var verticalSplitView = new VerticalSplitView( - this.topBarView_, this.tabSwitcher_); + var verticalSplitView = + new VerticalSplitView(this.topBarView_, this.tabSwitcher_); superClass.call(this, verticalSplitView); @@ -325,15 +325,15 @@ */ function areValidConstants(receivedConstants) { return typeof(receivedConstants) == 'object' && - typeof(receivedConstants.logEventTypes) == 'object' && - typeof(receivedConstants.clientInfo) == 'object' && - typeof(receivedConstants.logEventPhase) == 'object' && - typeof(receivedConstants.logSourceType) == 'object' && - typeof(receivedConstants.loadFlag) == 'object' && - typeof(receivedConstants.netError) == 'object' && - typeof(receivedConstants.addressFamily) == 'object' && - typeof(receivedConstants.timeTickOffset) == 'string' && - typeof(receivedConstants.logFormatVersion) == 'number'; + typeof(receivedConstants.logEventTypes) == 'object' && + typeof(receivedConstants.clientInfo) == 'object' && + typeof(receivedConstants.logEventPhase) == 'object' && + typeof(receivedConstants.logSourceType) == 'object' && + typeof(receivedConstants.loadFlag) == 'object' && + typeof(receivedConstants.netError) == 'object' && + typeof(receivedConstants.addressFamily) == 'object' && + typeof(receivedConstants.timeTickOffset) == 'string' && + typeof(receivedConstants.logFormatVersion) == 'number'; } /**
diff --git a/chrome/browser/resources/net_internals/modules_view.js b/chrome/browser/resources/net_internals/modules_view.js index 0bf7b52..dbb0b9c 100644 --- a/chrome/browser/resources/net_internals/modules_view.js +++ b/chrome/browser/resources/net_internals/modules_view.js
@@ -25,10 +25,8 @@ // Call superclass's constructor. superClass.call(this, ModulesView.MAIN_BOX_ID); - this.serviceProvidersTbody_ = - $(ModulesView.SERVICE_PROVIDERS_TBODY_ID); - this.namespaceProvidersTbody_ = - $(ModulesView.NAMESPACE_PROVIDERS_TBODY_ID); + this.serviceProvidersTbody_ = $(ModulesView.SERVICE_PROVIDERS_TBODY_ID); + this.namespaceProvidersTbody_ = $(ModulesView.NAMESPACE_PROVIDERS_TBODY_ID); g_browser.addServiceProvidersObserver(this, false); g_browser.addExtensionInfoObserver(this, true); @@ -125,8 +123,7 @@ * Returns the type of a namespace provider as a string. */ ModulesView.getNamespaceProviderType = function(namespaceProvider) { - return tryGetValueWithKey(NAMESPACE_PROVIDER_PTYPE, - namespaceProvider.type); + return tryGetValueWithKey(NAMESPACE_PROVIDER_PTYPE, namespaceProvider.type); }; return ModulesView;
diff --git a/chrome/browser/resources/net_internals/proxy_view.js b/chrome/browser/resources/net_internals/proxy_view.js index ef9709d..582f5f9 100644 --- a/chrome/browser/resources/net_internals/proxy_view.js +++ b/chrome/browser/resources/net_internals/proxy_view.js
@@ -61,7 +61,7 @@ onLoadLogFinish: function(data) { return this.onProxySettingsChanged(data.proxySettings) && - this.onBadProxiesChanged(data.badProxies); + this.onBadProxiesChanged(data.badProxies); }, onProxySettingsChanged: function(proxySettings) { @@ -80,8 +80,8 @@ var originalStr = proxySettingsToString(original); var effectiveStr = proxySettingsToString(effective); - setNodeDisplay($(ProxyView.ORIGINAL_CONTENT_DIV_ID), - originalStr != effectiveStr); + setNodeDisplay( + $(ProxyView.ORIGINAL_CONTENT_DIV_ID), originalStr != effectiveStr); $(ProxyView.ORIGINAL_SETTINGS_DIV_ID).innerText = originalStr; $(ProxyView.EFFECTIVE_SETTINGS_DIV_ID).innerText = effectiveStr; @@ -93,8 +93,8 @@ onBadProxiesChanged: function(badProxies) { $(ProxyView.BAD_PROXIES_TBODY_ID).innerHTML = ''; - setNodeDisplay($(ProxyView.BAD_PROXIES_DIV_ID), - badProxies && badProxies.length > 0); + setNodeDisplay( + $(ProxyView.BAD_PROXIES_DIV_ID), badProxies && badProxies.length > 0); if (!badProxies) return false; @@ -130,8 +130,8 @@ // proxy settings include proxy bypasses the user may need to expand the // exclusions for host resolving. var hostResolverRules = 'MAP * ~NOTFOUND , EXCLUDE ' + socksProxy.host; - var hostResolverRulesFlag = '--host-resolver-rules="' + - hostResolverRules + '"'; + var hostResolverRulesFlag = + '--host-resolver-rules="' + hostResolverRules + '"'; // TODO(eroman): On Linux the ClientInfo.command_line is wrong in that it // doesn't include any quotes around the parameters. This means the
diff --git a/chrome/browser/resources/net_internals/resizable_vertical_split_view.js b/chrome/browser/resources/net_internals/resizable_vertical_split_view.js index 644ae9b..b63a488c8 100644 --- a/chrome/browser/resources/net_internals/resizable_vertical_split_view.js +++ b/chrome/browser/resources/net_internals/resizable_vertical_split_view.js
@@ -58,8 +58,8 @@ node.addEventListener('touchstart', this.onTouchDragSizerStart_.bind(this)); window.addEventListener('touchmove', this.onTouchDragSizer_.bind(this)); window.addEventListener('touchend', this.onTouchDragSizerEnd_.bind(this)); - window.addEventListener('touchcancel', - this.onTouchDragSizerEnd_.bind(this)); + window.addEventListener( + 'touchcancel', this.onTouchDragSizerEnd_.bind(this)); } ResizableVerticalSplitView.prototype = { @@ -97,10 +97,10 @@ // Position the boxes using calculated split points. this.leftView_.setGeometry(left, top, leftboxWidth, height); - this.sizerView_.setGeometry(this.leftView_.getRight(), top, - sizerWidth, height); - this.rightView_.setGeometry(this.sizerView_.getRight(), top, - rightboxWidth, height); + this.sizerView_.setGeometry( + this.leftView_.getRight(), top, sizerWidth, height); + this.rightView_.setGeometry( + this.sizerView_.getRight(), top, rightboxWidth, height); }, show: function(isVisible) { @@ -182,8 +182,8 @@ // Avoid shrinking the left box too much. this.leftSplit_ = Math.max(this.leftSplit_, MIN_PANEL_WIDTH); // Avoid shrinking the right box too much. - this.leftSplit_ = Math.min( - this.leftSplit_, this.getWidth() - MIN_PANEL_WIDTH); + this.leftSplit_ = + Math.min(this.leftSplit_, this.getWidth() - MIN_PANEL_WIDTH); // Force a layout with the new |leftSplit_|. this.setGeometry(
diff --git a/chrome/browser/resources/net_internals/socket_pool_wrapper.js b/chrome/browser/resources/net_internals/socket_pool_wrapper.js index 77e4933..66da89103 100644 --- a/chrome/browser/resources/net_internals/socket_pool_wrapper.js +++ b/chrome/browser/resources/net_internals/socket_pool_wrapper.js
@@ -65,9 +65,8 @@ socketPoolList.push(socketPool); if (origPool.nested_pools) { for (var i = 0; i < origPool.nested_pools.length; ++i) { - addSocketPoolsToList(socketPoolList, - origPool.nested_pools[i], - socketPool); + addSocketPoolsToList( + socketPoolList, origPool.nested_pools[i], socketPool); } } }
diff --git a/chrome/browser/resources/net_internals/source_entry.js b/chrome/browser/resources/net_internals/source_entry.js index 14e98a4..319559fb 100644 --- a/chrome/browser/resources/net_internals/source_entry.js +++ b/chrome/browser/resources/net_internals/source_entry.js
@@ -31,8 +31,7 @@ SourceEntry.prototype = { update: function(logEntry) { // Only the last event should have the same type first event, - if (!this.isInactive_ && - logEntry.phase == EventPhase.PHASE_END && + if (!this.isInactive_ && logEntry.phase == EventPhase.PHASE_END && logEntry.type == this.entries_[0].type) { this.isInactive_ = true; } @@ -201,8 +200,7 @@ } if (this.entries_[0].source.type == EventSourceType.DOWNLOAD) { // If any rename occurred, use the last name - e = this.findLastLogEntryStartByType_( - EventType.DOWNLOAD_FILE_RENAMED); + e = this.findLastLogEntryStartByType_(EventType.DOWNLOAD_FILE_RENAMED); if (e != undefined) return e; // Otherwise, if the file was opened, use that name @@ -345,10 +343,10 @@ */ createTablePrinter: function() { return createLogEntryTablePrinter( - this.entries_, - SourceTracker.getInstance().getPrivacyStripping(), + this.entries_, SourceTracker.getInstance().getPrivacyStripping(), SourceTracker.getInstance().getUseRelativeTimes() ? - timeutil.getBaseTime() : 0, + timeutil.getBaseTime() : + 0, Constants.clientInfo.numericDate); }, };
diff --git a/chrome/browser/resources/net_internals/source_filter_parser.js b/chrome/browser/resources/net_internals/source_filter_parser.js index 607161aa..723ccac7 100644 --- a/chrome/browser/resources/net_internals/source_filter_parser.js +++ b/chrome/browser/resources/net_internals/source_filter_parser.js
@@ -41,13 +41,13 @@ if (filter) { if (negated) { filter = (function(func, sourceEntry) { - return !func(sourceEntry); - }).bind(null, filter); + return !func(sourceEntry); + }).bind(null, filter); } filterFunctions.push(filter); continue; } - textFilters.push({ text: filterElement, negated: negated }); + textFilters.push({text: filterElement, negated: negated}); } // Create a single filter for all text filters, so they can share a @@ -73,7 +73,7 @@ var match = /^sort:(.*)$/.exec(filterElement); if (!match) return null; - return { method: match[1], backwards: backwards }; + return {method: match[1], backwards: backwards}; } /** @@ -85,10 +85,14 @@ if (!match) return null; if (match[1] == 'active') { - return function(sourceEntry) { return !sourceEntry.isInactive(); }; + return function(sourceEntry) { + return !sourceEntry.isInactive(); + }; } if (match[1] == 'error') { - return function(sourceEntry) { return sourceEntry.isError(); }; + return function(sourceEntry) { + return sourceEntry.isError(); + }; } return null; } @@ -149,8 +153,7 @@ while (position < filterText.length) { var nextCharacter = filterText[position]; ++position; - if (nextCharacter == '\\' && - position < filterText.length) { + if (nextCharacter == '\\' && position < filterText.length) { // If there's a backslash, skip the backslash and add the next // character to the element. filterElement += filterText[position];
diff --git a/chrome/browser/resources/net_internals/spdy_view.js b/chrome/browser/resources/net_internals/spdy_view.js index 797aeda..052421b 100644 --- a/chrome/browser/resources/net_internals/spdy_view.js +++ b/chrome/browser/resources/net_internals/spdy_view.js
@@ -42,7 +42,7 @@ onLoadLogFinish: function(data) { return this.onSpdySessionInfoChanged(data.spdySessionInfo) && - this.onSpdyStatusChanged(data.spdyStatus); + this.onSpdyStatusChanged(data.spdyStatus); }, /** @@ -52,7 +52,7 @@ onSpdySessionInfoChanged: function(spdySessionInfo) { if (!spdySessionInfo) return false; - var input = new JsEvalContext({ spdySessionInfo: spdySessionInfo }); + var input = new JsEvalContext({spdySessionInfo: spdySessionInfo}); jstProcess(input, $(SpdyView.SESSION_INFO_ID)); return true; },
diff --git a/chrome/browser/resources/net_internals/tab_switcher_view.js b/chrome/browser/resources/net_internals/tab_switcher_view.js index 8badcf0..89bb198ad 100644 --- a/chrome/browser/resources/net_internals/tab_switcher_view.js +++ b/chrome/browser/resources/net_internals/tab_switcher_view.js
@@ -70,8 +70,8 @@ // Position each of the tab's content areas. for (var tabId in this.tabIdToView_) { var view = this.tabIdToView_[tabId]; - view.setGeometry(left + tabListWidth, top, width - tabListWidth, - height); + view.setGeometry( + left + tabListWidth, top, width - tabListWidth, height); } },
diff --git a/chrome/browser/resources/net_internals/time_util.js b/chrome/browser/resources/net_internals/time_util.js index c5907ffe..095e621 100644 --- a/chrome/browser/resources/net_internals/time_util.js +++ b/chrome/browser/resources/net_internals/time_util.js
@@ -132,14 +132,12 @@ * @return {string} A string representation of |date|. */ function dateToString(date) { - var dateStr = date.getFullYear() + '-' + - zeroPad_(date.getMonth() + 1, 2) + '-' + - zeroPad_(date.getDate(), 2); + var dateStr = date.getFullYear() + '-' + zeroPad_(date.getMonth() + 1, 2) + + '-' + zeroPad_(date.getDate(), 2); var timeStr = zeroPad_(date.getHours(), 2) + ':' + - zeroPad_(date.getMinutes(), 2) + ':' + - zeroPad_(date.getSeconds(), 2) + '.' + - zeroPad_(date.getMilliseconds(), 3); + zeroPad_(date.getMinutes(), 2) + ':' + zeroPad_(date.getSeconds(), 2) + + '.' + zeroPad_(date.getMilliseconds(), 3); return dateStr + ' ' + timeStr; }
diff --git a/chrome/browser/resources/net_internals/timeline_data_series.js b/chrome/browser/resources/net_internals/timeline_data_series.js index 9a21d3c3..2820752f 100644 --- a/chrome/browser/resources/net_internals/timeline_data_series.js +++ b/chrome/browser/resources/net_internals/timeline_data_series.js
@@ -5,10 +5,7 @@ /** * Different data types that each require their own labelled axis. */ -var TimelineDataType = { - SOURCE_COUNT: 0, - BYTES_PER_SECOND: 1 -}; +var TimelineDataType = {SOURCE_COUNT: 0, BYTES_PER_SECOND: 1}; /** * A TimelineDataSeries collects an ordered series of (time, value) pairs,
diff --git a/chrome/browser/resources/net_internals/timeline_graph_view.js b/chrome/browser/resources/net_internals/timeline_graph_view.js index c151ce2..705ba85 100644 --- a/chrome/browser/resources/net_internals/timeline_graph_view.js +++ b/chrome/browser/resources/net_internals/timeline_graph_view.js
@@ -47,18 +47,14 @@ // Which side of the canvas y-axis labels should go on, for a given Graph. // TODO(mmenke): Figure out a reasonable way to handle more than 2 sets // of labels. - var LabelAlign = { - LEFT: 0, - RIGHT: 1 - }; + var LabelAlign = {LEFT: 0, RIGHT: 1}; /** * @constructor */ function TimelineGraphView(divId, canvasId, scrollbarId, scrollbarInnerId) { - this.scrollbar_ = new HorizontalScrollbarView(scrollbarId, - scrollbarInnerId, - this.onScroll_.bind(this)); + this.scrollbar_ = new HorizontalScrollbarView( + scrollbarId, scrollbarInnerId, this.onScroll_.bind(this)); // Call superclass's constructor. superClass.call(this, null, new DivView(divId), this.scrollbar_); @@ -113,10 +109,10 @@ // |height| properties, which do not take padding into account, so we // need to use them ourselves. var style = getComputedStyle(this.canvas_); - var horizontalPadding = parseInt(style.paddingRight) + - parseInt(style.paddingLeft); - var verticalPadding = parseInt(style.paddingTop) + - parseInt(style.paddingBottom); + var horizontalPadding = + parseInt(style.paddingRight) + parseInt(style.paddingLeft); + var verticalPadding = + parseInt(style.paddingTop) + parseInt(style.paddingBottom); var canvasWidth = parseInt(this.graphDiv_.style.width) - horizontalPadding; // For unknown reasons, there's an extra 3 pixels border between the @@ -267,10 +263,11 @@ onMouseWheel_: function(event) { event.preventDefault(); this.horizontalScroll_( - MOUSE_WHEEL_SCROLL_RATE * - -event.wheelDeltaX / MOUSE_WHEEL_UNITS_PER_CLICK); - this.zoom_(Math.pow(MOUSE_WHEEL_ZOOM_RATE, - -event.wheelDeltaY / MOUSE_WHEEL_UNITS_PER_CLICK)); + MOUSE_WHEEL_SCROLL_RATE * -event.wheelDeltaX / + MOUSE_WHEEL_UNITS_PER_CLICK); + this.zoom_(Math.pow( + MOUSE_WHEEL_ZOOM_RATE, + -event.wheelDeltaY / MOUSE_WHEEL_UNITS_PER_CLICK)); }, onMouseDown_: function(event) { @@ -366,8 +363,8 @@ // Layout graphs and have them draw their tick marks. for (var i = 0; i < this.graphs_.length; ++i) { - this.graphs_[i].layout(width, height, fontHeight, visibleStartTime, - this.scale_); + this.graphs_[i].layout( + width, height, fontHeight, visibleStartTime, this.scale_); this.graphs_[i].drawTicks(context); } @@ -393,18 +390,16 @@ // The desired spacing for text labels. var targetSpacing = context.measureText(sampleText).width + - LABEL_LABEL_HORIZONTAL_SPACING; + LABEL_LABEL_HORIZONTAL_SPACING; // The allowed time step values between adjacent labels. Anything much // over a couple minutes isn't terribly realistic, given how much memory // we use, and how slow a lot of the net-internals code is. var timeStepValues = [ 1000, // 1 second - 1000 * 5, - 1000 * 30, + 1000 * 5, 1000 * 30, 1000 * 60, // 1 minute - 1000 * 60 * 5, - 1000 * 60 * 30, + 1000 * 60 * 5, 1000 * 60 * 30, 1000 * 60 * 60, // 1 hour 1000 * 60 * 60 * 5 ];
diff --git a/chrome/browser/resources/net_internals/timeline_view.js b/chrome/browser/resources/net_internals/timeline_view.js index 083000b..afffe1b 100644 --- a/chrome/browser/resources/net_internals/timeline_view.js +++ b/chrome/browser/resources/net_internals/timeline_view.js
@@ -20,10 +20,8 @@ assertFirstConstructorCall(TimelineView); this.graphView_ = new TimelineGraphView( - TimelineView.GRAPH_DIV_ID, - TimelineView.GRAPH_CANVAS_ID, - TimelineView.SCROLLBAR_DIV_ID, - TimelineView.SCROLLBAR_INNER_DIV_ID); + TimelineView.GRAPH_DIV_ID, TimelineView.GRAPH_CANVAS_ID, + TimelineView.SCROLLBAR_DIV_ID, TimelineView.SCROLLBAR_INNER_DIV_ID); // Call superclass's constructor. @@ -74,8 +72,7 @@ TimelineView.DNS_JOBS_ID = 'timeline-view-dns-jobs'; TimelineView.BYTES_RECEIVED_ID = 'timeline-view-bytes-received'; TimelineView.BYTES_SENT_ID = 'timeline-view-bytes-sent'; - TimelineView.DISK_CACHE_BYTES_READ_ID = - 'timeline-view-disk-cache-bytes-read'; + TimelineView.DISK_CACHE_BYTES_READ_ID = 'timeline-view-disk-cache-bytes-read'; TimelineView.DISK_CACHE_BYTES_WRITTEN_ID = 'timeline-view-disk-cache-bytes-written'; @@ -178,8 +175,8 @@ dataSeries.setColor(getComputedStyle(listItem).color); this.updateDataSeriesVisibility_(dataSeries, listItem, checkBox); - checkBox.onclick = this.dataSeriesClicked_.bind(this, dataSeries, - listItem, checkBox); + checkBox.onclick = + this.dataSeriesClicked_.bind(this, dataSeries, listItem, checkBox); }, /** @@ -190,41 +187,42 @@ this.graphRangeInitialized_ = false; this.dataSeries_ = []; - this.addDataSeries_(new SourceCountDataSeries( - EventSourceType.SOCKET, - EventType.SOCKET_ALIVE), - TimelineView.OPEN_SOCKETS_ID); + this.addDataSeries_( + new SourceCountDataSeries( + EventSourceType.SOCKET, EventType.SOCKET_ALIVE), + TimelineView.OPEN_SOCKETS_ID); - this.addDataSeries_(new SocketsInUseDataSeries(), - TimelineView.IN_USE_SOCKETS_ID); + this.addDataSeries_( + new SocketsInUseDataSeries(), TimelineView.IN_USE_SOCKETS_ID); - this.addDataSeries_(new SourceCountDataSeries( - EventSourceType.URL_REQUEST, - EventType.REQUEST_ALIVE), - TimelineView.URL_REQUESTS_ID); + this.addDataSeries_( + new SourceCountDataSeries( + EventSourceType.URL_REQUEST, EventType.REQUEST_ALIVE), + TimelineView.URL_REQUESTS_ID); - this.addDataSeries_(new SourceCountDataSeries( - EventSourceType.HOST_RESOLVER_IMPL_JOB, - EventType.HOST_RESOLVER_IMPL_JOB), - TimelineView.DNS_JOBS_ID); + this.addDataSeries_( + new SourceCountDataSeries( + EventSourceType.HOST_RESOLVER_IMPL_JOB, + EventType.HOST_RESOLVER_IMPL_JOB), + TimelineView.DNS_JOBS_ID); - this.addDataSeries_(new NetworkTransferRateDataSeries( - EventType.SOCKET_BYTES_RECEIVED, - EventType.UDP_BYTES_RECEIVED), - TimelineView.BYTES_RECEIVED_ID); + this.addDataSeries_( + new NetworkTransferRateDataSeries( + EventType.SOCKET_BYTES_RECEIVED, EventType.UDP_BYTES_RECEIVED), + TimelineView.BYTES_RECEIVED_ID); - this.addDataSeries_(new NetworkTransferRateDataSeries( - EventType.SOCKET_BYTES_SENT, - EventType.UDP_BYTES_SENT), - TimelineView.BYTES_SENT_ID); + this.addDataSeries_( + new NetworkTransferRateDataSeries( + EventType.SOCKET_BYTES_SENT, EventType.UDP_BYTES_SENT), + TimelineView.BYTES_SENT_ID); - this.addDataSeries_(new DiskCacheTransferRateDataSeries( - EventType.ENTRY_READ_DATA), - TimelineView.DISK_CACHE_BYTES_READ_ID); + this.addDataSeries_( + new DiskCacheTransferRateDataSeries(EventType.ENTRY_READ_DATA), + TimelineView.DISK_CACHE_BYTES_READ_ID); - this.addDataSeries_(new DiskCacheTransferRateDataSeries( - EventType.ENTRY_WRITE_DATA), - TimelineView.DISK_CACHE_BYTES_WRITTEN_ID); + this.addDataSeries_( + new DiskCacheTransferRateDataSeries(EventType.ENTRY_WRITE_DATA), + TimelineView.DISK_CACHE_BYTES_WRITTEN_ID); this.graphView_.setDataSeries(this.dataSeries_); }, @@ -279,8 +277,8 @@ var shouldCollapse = toggle.className == 'timeline-view-rotateleft'; setNodeDisplay($(TimelineView.SELECTION_UL_ID), !shouldCollapse); - toggle.className = shouldCollapse ? - 'timeline-view-rotateright' : 'timeline-view-rotateleft'; + toggle.className = shouldCollapse ? 'timeline-view-rotateright' : + 'timeline-view-rotateleft'; // Figure out the appropriate width for the selection div. var newWidth; @@ -295,8 +293,8 @@ this.leftView_.setGeometry(0, 0, newWidth, 100); // Force a re-layout now that the left view has changed width. - this.setGeometry(this.getLeft(), this.getTop(), this.getWidth(), - this.getHeight()); + this.setGeometry( + this.getLeft(), this.getTop(), this.getWidth(), this.getHeight()); } };
diff --git a/chrome/browser/resources/net_internals/top_mid_bottom_view.js b/chrome/browser/resources/net_internals/top_mid_bottom_view.js index 586482d1..a4df556 100644 --- a/chrome/browser/resources/net_internals/top_mid_bottom_view.js +++ b/chrome/browser/resources/net_internals/top_mid_bottom_view.js
@@ -61,11 +61,11 @@ // Position the boxes using calculated split points. if (this.topView_) this.topView_.setGeometry(left, top, width, topbarHeight); - this.midView_.setGeometry(left, top + topbarHeight, width, - middleboxHeight); + this.midView_.setGeometry( + left, top + topbarHeight, width, middleboxHeight); if (this.bottomView_) { - this.bottomView_.setGeometry(left, top + topbarHeight + middleboxHeight, - width, bottombarHeight); + this.bottomView_.setGeometry( + left, top + topbarHeight + middleboxHeight, width, bottombarHeight); } },
diff --git a/chrome/browser/resources/net_internals/util.js b/chrome/browser/resources/net_internals/util.js index 0702958..fa92b3c7 100644 --- a/chrome/browser/resources/net_internals/util.js +++ b/chrome/browser/resources/net_internals/util.js
@@ -164,8 +164,9 @@ function assertFirstConstructorCall(ctor) { // This is the variable which is set by cr.addSingletonGetter(). if (ctor.hasCreateFirstInstance_) { - throw Error('The class ' + ctor.name + ' is a singleton, and should ' + - 'only be accessed using ' + ctor.name + '.getInstance().'); + throw Error( + 'The class ' + ctor.name + ' is a singleton, and should ' + + 'only be accessed using ' + ctor.name + '.getInstance().'); } ctor.hasCreateFirstInstance_ = true; }
diff --git a/chrome/browser/resources/net_internals/view.js b/chrome/browser/resources/net_internals/view.js index 05e538f..dd0be15 100644 --- a/chrome/browser/resources/net_internals/view.js +++ b/chrome/browser/resources/net_internals/view.js
@@ -82,8 +82,7 @@ * values. It's included separately so most views don't have to depend on * its specifics. */ - onLoadLogStart: function(polledData, tabData, logDump) { - }, + onLoadLogStart: function(polledData, tabData, logDump) {}, /** * Called as the final step of loading a log file. Arguments are the same @@ -193,8 +192,9 @@ }, resetGeometry: function() { - this.setGeometry(0, 0, document.documentElement.clientWidth, - document.documentElement.clientHeight); + this.setGeometry( + 0, 0, document.documentElement.clientWidth, + document.documentElement.clientHeight); } };
diff --git a/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp b/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp index 54926e6..a27381e 100644 --- a/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/internet_page/compiled_resources2.gyp
@@ -76,6 +76,7 @@ { 'target_name': 'network_proxy', 'dependencies': [ + '../compiled_resources2.gyp:route', '../controls/compiled_resources2.gyp:settings_checkbox', '../prefs/compiled_resources2.gyp:prefs_behavior', '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types',
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.html b/chrome/browser/resources/settings/internet_page/network_proxy.html index 2314d795..8952fa51 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy.html +++ b/chrome/browser/resources/settings/internet_page/network_proxy.html
@@ -91,8 +91,8 @@ <div class="start">$i18n{networkProxyConnectionType}</div> <div class="md-select-wrapper"> <select id="proxyType" class="md-select" on-change="onTypeChange_" - value="[[proxy.Type]]" - disabled="[[!isProxyEditable_(networkProperties, editable, + value="[[proxy_.Type]]" + disabled="[[!isEditable_('Type', networkProperties, editable, useSharedProxies_)]]"> <template is="dom-repeat" items="[[proxyTypes_]]"> <option value="[[item]]">[[getProxyTypeDesc_(item)]]</option> @@ -104,81 +104,76 @@ <!-- Autoconfiguration (PAC) --> <div class="settings-box continuation indent" - hidden$="[[!matches_(proxy.Type, ProxySettingsType_.PAC)]]"> + hidden$="[[!matches_(proxy_.Type, ProxySettingsType_.PAC)]]"> <div>$i18n{networkProxyAutoConfig}</div> - <paper-input no-label-float class="middle" value="{{proxy.PAC}}" - disabled="[[!isEditable_(networkProperties.ProxySettings.PAC, + <paper-input no-label-float class="middle flex" value="{{proxy_.PAC}}" + disabled="[[!isEditable_('PAC', networkProperties, editable, useSharedProxies_)]]" - on-blur="onProxyInputChange_"> + on-blur="onPACChange_"> </paper-input> </div> <!-- Web Proxy Auto Discovery (WPAD) --> <div class="settings-box continuation indent" - hidden$="[[!matches_(proxy.Type, ProxySettingsType_.WPAD)]]"> + hidden$="[[!matches_(proxy_.Type, ProxySettingsType_.WPAD)]]"> <div>$i18n{networkSectionWpad}</div> - <div class="middle">[[WPAD]]</div> + <div class="middle flex">[[WPAD_]]</div> </div> <!-- Manual --> <div id="proxyDiv" class="settings-box continuation single-column indent" - hidden$="[[!matches_(proxy.Type, ProxySettingsType_.MANUAL)]]"> + hidden$="[[!matches_(proxy_.Type, ProxySettingsType_.MANUAL)]]"> <paper-checkbox checked="{{useSameProxy_}}" - disabled="[[!isProxyEditable_(networkProperties, editable, - useSharedProxies_)]]"> + disabled="[[!isEditable_('Type', networkProperties, editable, + useSharedProxies_)]]"> $i18n{networkProxyUseSame} </paper-checkbox> <div hidden$="[[!useSameProxy_]]" class="layout vertical"> <network-proxy-input on-proxy-change="onProxyInputChange_" - editable="[[isEditable_( - networkProperties.ProxySettings.Manual.HTTPProxy.Host, + editable="[[isEditable_('Manual.HTTPProxy.Host', networkProperties, editable, useSharedProxies_)]]" - value="{{proxy.Manual.HTTPProxy}}" + value="{{proxy_.Manual.HTTPProxy}}" label="$i18n{networkProxy}"> </network-proxy-input> </div> <div hidden$="[[useSameProxy_]]" class="layout vertical"> <network-proxy-input on-proxy-change="onProxyInputChange_" - editable="[[isEditable_( - networkProperties.ProxySettings.Manual.HTTPProxy.Host, + editable="[[isEditable_('Manual.HTTPProxy.Host', networkProperties, editable, useSharedProxies_)]]" - value="{{proxy.Manual.HTTPProxy}}" + value="{{proxy_.Manual.HTTPProxy}}" label="$i18n{networkProxyHttp}"> </network-proxy-input> <network-proxy-input on-proxy-change="onProxyInputChange_" - editable="[[isEditable_( - networkProperties.ProxySettings.Manual.SecureHTTPProxy.Host, - editable, useSharedProxies_)]]" - value="{{proxy.Manual.SecureHTTPProxy}}" + editable="[[isEditable_('Manual.SecureHTTPProxy.Host', + networkProperties, editable, useSharedProxies_)]]" + value="{{proxy_.Manual.SecureHTTPProxy}}" label="$i18n{networkProxyShttp}"> </network-proxy-input> <network-proxy-input on-proxy-change="onProxyInputChange_" - editable="[[isEditable_( - networkProperties.ProxySettings.Manual.FTPProxy.Host, + editable="[[isEditable_('Manual.FTPProxy.Host', networkProperties, editable, useSharedProxies_)]]" - value="{{proxy.Manual.FTPProxy}}" + value="{{proxy_.Manual.FTPProxy}}" label="$i18n{networkProxyFtp}"> </network-proxy-input> <network-proxy-input on-proxy-change="onProxyInputChange_" - editable="[[isEditable_( - networkProperties.ProxySettings.Manual.SOCKS.Host, + editable="[[isEditable_('Manual.SOCKS.Host', networkProperties, editable, useSharedProxies_)]]" - value="{{proxy.Manual.SOCKS}}" + value="{{proxy_.Manual.SOCKS}}" label="$i18n{networkProxySocks}"> </network-proxy-input> </div> <div id="exceptionsDiv" - hidden="[[!isProxyEditable_(networkProperties, editable, + hidden="[[!isEditable_('Type', networkProperties, editable, useSharedProxies_)]]"> <div>$i18n{networkProxyExceptionList}</div> <network-proxy-exclusions on-proxy-change="onProxyExclusionsChange_" - exclusions="{{proxy.ExcludeDomains}}"> + exclusions="{{proxy_.ExcludeDomains}}"> </network-proxy-exclusions> <div class="layout horizontal"> <paper-input-container no-label-float class="flex"> @@ -189,6 +184,13 @@ </paper-button> </div> </div> + + <paper-button id="saveManualProxy" + on-tap="onSaveProxyTap_" class="action-button" + disabled="[[!isSaveManualProxyEnabled_(networkProperties, + proxyModified_, proxy_.*)]]"> + $i18n{save} + </paper-button> </div> <!-- Confirm Allow shared proxies dialog -->
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.js b/chrome/browser/resources/settings/internet_page/network_proxy.js index e3defda..01a2a08 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy.js +++ b/chrome/browser/resources/settings/internet_page/network_proxy.js
@@ -9,7 +9,12 @@ Polymer({ is: 'network-proxy', - behaviors: [CrPolicyNetworkBehavior, I18nBehavior, PrefsBehavior], + behaviors: [ + CrPolicyNetworkBehavior, + I18nBehavior, + PrefsBehavior, + settings.RouteObserverBehavior, + ], properties: { /** @@ -30,17 +35,20 @@ /** * UI visible / edited proxy configuration. - * @type {!CrOnc.ProxySettings} + * @private {!CrOnc.ProxySettings} */ - proxy: { + proxy_: { type: Object, value: function() { return this.createDefaultProxySettings_(); }, }, - /** The Web Proxy Auto Discovery URL extracted from networkProperties. */ - WPAD: { + /** + * The Web Proxy Auto Discovery URL extracted from networkProperties. + * @private + */ + WPAD_: { type: String, value: '', }, @@ -113,14 +121,24 @@ savedExcludeDomains_: undefined, /** - * Set to true the first time we receive a manual proxy. Used to set the - * initial |useSameProxy_| value. + * Set to true while modifying proxy values so that an update does not + * override the edited values. * @private {boolean} */ - receivedManualProxy_: false, + proxyModified_: false, + + /** @protected settings.RouteObserverBehavior */ + currentRouteChanged: function(newRoute) { + this.proxyModified_ = false; + this.proxy_ = this.createDefaultProxySettings_(); + if (newRoute == settings.Route.NETWORK_DETAIL) + this.updateProxy_(); + }, /** @private */ networkPropertiesChanged_: function() { + if (this.proxyModified_) + return; // Ignore update. this.updateProxy_(); }, @@ -149,23 +167,28 @@ CrOnc.getActiveValue(proxySettings.Type)); if (proxySettings.Manual) { proxy.Manual.HTTPProxy = /** @type {!CrOnc.ProxyLocation|undefined} */ ( - CrOnc.getSimpleActiveProperties(proxySettings.Manual.HTTPProxy)); + CrOnc.getSimpleActiveProperties( + proxySettings.Manual.HTTPProxy)) || + {Host: '', Port: 80}; proxy.Manual.SecureHTTPProxy = /** @type {!CrOnc.ProxyLocation|undefined} */ ( CrOnc.getSimpleActiveProperties( - proxySettings.Manual.SecureHTTPProxy)); - proxy.Manual.FTPProxy = /** @type {!CrOnc.ProxyLocation|undefined} */ ( - CrOnc.getSimpleActiveProperties(proxySettings.Manual.FTPProxy)); - proxy.Manual.SOCKS = /** @type {!CrOnc.ProxyLocation|undefined} */ ( - CrOnc.getSimpleActiveProperties(proxySettings.Manual.SOCKS)); - if (!this.receivedManualProxy_) { - let json_http = JSON.stringify(proxy.Manual.HTTPProxy); - this.useSameProxy_ = - json_http == JSON.stringify(proxy.Manual.SecureHTTPProxy) && - json_http == JSON.stringify(proxy.Manual.FTPProxy) && - json_http == JSON.stringify(proxy.Manual.SOCKS); - this.receivedManualProxy_ = true; - } + proxySettings.Manual.SecureHTTPProxy)) || + proxy.Manual.HTTPProxy; + proxy.Manual.FTPProxy = + /** @type {!CrOnc.ProxyLocation|undefined} */ ( + CrOnc.getSimpleActiveProperties( + proxySettings.Manual.FTPProxy)) || + proxy.Manual.HTTPProxy; + proxy.Manual.SOCKS = + /** @type {!CrOnc.ProxyLocation|undefined} */ ( + CrOnc.getSimpleActiveProperties(proxySettings.Manual.SOCKS)) || + proxy.Manual.HTTPProxy; + let json_http = JSON.stringify(proxy.Manual.HTTPProxy); + this.useSameProxy_ = + json_http == JSON.stringify(proxy.Manual.SecureHTTPProxy) && + json_http == JSON.stringify(proxy.Manual.FTPProxy) && + json_http == JSON.stringify(proxy.Manual.SOCKS); } if (proxySettings.ExcludeDomains) { proxy.ExcludeDomains = /** @type {!Array<string>|undefined} */ ( @@ -181,7 +204,7 @@ // Set the Web Proxy Auto Discovery URL. var ipv4 = CrOnc.getIPConfigForType(this.networkProperties, CrOnc.IPType.IPV4); - this.WPAD = (ipv4 && ipv4.WebProxyAutoDiscoveryUrl) || ''; + this.WPAD_ = (ipv4 && ipv4.WebProxyAutoDiscoveryUrl) || ''; this.setProxyAsync_(proxy); }, @@ -191,17 +214,16 @@ * @private */ setProxyAsync_: function(proxy) { - // Set this.proxy after dom-repeat has been stamped. + // Set this.proxy_ after dom-repeat has been stamped. this.async(function() { - this.proxy = proxy; + this.proxy_ = proxy; + this.proxyModified_ = false; }.bind(this)); }, /** @private */ useSameProxyChanged_: function() { - if (!this.receivedManualProxy_) - return; - this.sendProxyChange_(); + this.proxyModified_ = true; }, /** @private */ @@ -234,32 +256,34 @@ * @private */ sendProxyChange_: function() { - if (this.proxy.Type == CrOnc.ProxySettingsType.MANUAL) { - var proxy = - /** @type {!CrOnc.ProxySettings} */ (Object.assign({}, this.proxy)); - var defaultProxy = proxy.Manual.HTTPProxy; + if (this.proxy_.Type == CrOnc.ProxySettingsType.MANUAL) { + let proxy = + /** @type {!CrOnc.ProxySettings} */ (Object.assign({}, this.proxy_)); + let manual = proxy.Manual; + let defaultProxy = manual.HTTPProxy; if (!defaultProxy || !defaultProxy.Host) return; - if (this.useSameProxy_ || !proxy.Manual.SecureHTTPProxy) { + if (this.useSameProxy_ || !this.get('SecureHTTPProxy.Host', manual)) { proxy.Manual.SecureHTTPProxy = /** @type {!CrOnc.ProxyLocation} */ ( Object.assign({}, defaultProxy)); } - if (this.useSameProxy_ || !proxy.Manual.FTPProxy) { + if (this.useSameProxy_ || !this.get('FTPProxy.Host', manual)) { proxy.Manual.FTPProxy = /** @type {!CrOnc.ProxyLocation} */ ( Object.assign({}, defaultProxy)); } - if (this.useSameProxy_ || !proxy.Manual.SOCKS) { + if (this.useSameProxy_ || !this.get('SOCKS.Host', manual)) { proxy.Manual.SOCKS = /** @type {!CrOnc.ProxyLocation} */ ( Object.assign({}, defaultProxy)); } this.savedManual_ = Object.assign({}, proxy.Manual); this.savedExcludeDomains_ = proxy.ExcludeDomains; - this.proxy = proxy; - } else if (this.proxy.Type == CrOnc.ProxySettingsType.PAC) { - if (!this.proxy.PAC) + this.proxy_ = proxy; + } else if (this.proxy_.Type == CrOnc.ProxySettingsType.PAC) { + if (!this.proxy_.PAC) return; } - this.fire('proxy-change', {field: 'ProxySettings', value: this.proxy}); + this.fire('proxy-change', {field: 'ProxySettings', value: this.proxy_}); + this.proxyModified_ = false; }, /** @@ -271,17 +295,21 @@ let target = /** @type {!HTMLSelectElement} */ (event.target); var type = /** @type {chrome.networkingPrivate.ProxySettingsType} */ ( target.value); - this.set('proxy.Type', type); + this.set('proxy_.Type', type); + if (type == CrOnc.ProxySettingsType.MANUAL) + this.proxyModified_ = true; + else + this.sendProxyChange_(); + }, + + /** @private */ + onPACChange_: function() { this.sendProxyChange_(); }, - /** - * Event triggered when a proxy value changes. - * @param {Event} event The proxy value change event. - * @private - */ - onProxyInputChange_: function(event) { - this.sendProxyChange_(); + /** @private */ + onProxyInputChange_: function() { + this.proxyModified_ = true; }, /** @@ -293,10 +321,10 @@ var value = this.$.proxyExclusion.value; if (!value) return; - this.push('proxy.ExcludeDomains', value); + this.push('proxy_.ExcludeDomains', value); // Clear input. this.$.proxyExclusion.value = ''; - this.sendProxyChange_(); + this.proxyModified_ = true; }, /** @@ -305,6 +333,11 @@ * @private */ onProxyExclusionsChange_: function(event) { + this.proxyModified_ = true; + }, + + /** @private */ + onSaveProxyTap_: function() { this.sendProxyChange_(); }, @@ -361,14 +394,30 @@ }, /** - * @param {!CrOnc.ManagedProperty|undefined} property - * @return {boolean} Whether the property setting is enforced. + * @param {string} propertyName + * @return {boolean} Whether the named property setting is editable. * @private */ - isEditable_: function(property) { - return this.editable && !this.isNetworkPolicyEnforced(property) && - !this.isExtensionControlled(property) && - (!this.isShared_() || this.useSharedProxies_); + isEditable_: function(propertyName) { + if (!this.editable || (this.isShared_() && !this.useSharedProxies_)) + return false; + if (!this.networkProperties.hasOwnProperty('ProxySettings')) + return true; // No proxy settings defined, so not enforced. + let property = /** @type {!CrOnc.ManagedProperty|undefined} */ ( + this.get('ProxySettings.' + propertyName, this.networkProperties)); + if (!property) + return true; + return this.isPropertyEditable_(property); + }, + + /** + * @param {!CrOnc.ManagedProperty|undefined} property + * @return {boolean} Whether |property| is editable. + * @private + */ + isPropertyEditable_: function(property) { + return !this.isNetworkPolicyEnforced(property) && + !this.isExtensionControlled(property); }, /** @@ -381,15 +430,13 @@ }, /** - * Used to check the editable state for proxy related UI that may or may - * not be directly controlled by a policy. We use the enforced state of the - * 'ProxySettings.Type' property for these controls. - * @return {boolean} Whether the proxy control is editable. + * @return {boolean} * @private */ - isProxyEditable_: function() { - let property = this.getProxySettingsTypeProperty_(); - return !property || this.isEditable_(property); + isSaveManualProxyEnabled_: function() { + if (!this.proxyModified_) + return false; + return !!this.get('HTTPProxy.Host', this.proxy_.Manual); }, /**
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy_input.html b/chrome/browser/resources/settings/internet_page/network_proxy_input.html index a9d4ab63..ba549f0 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy_input.html +++ b/chrome/browser/resources/settings/internet_page/network_proxy_input.html
@@ -19,13 +19,13 @@ <div class="layout horizontal center"> <div class="flex">[[label]]</div> <paper-input-container no-label-float> - <input is="iron-input" bind-value="{{value.Host}}" disabled="[[!editable]]" - on-blur="onValueChange_"> + <input is="iron-input" bind-value="{{value.Host}}" + disabled="[[!editable]]" on-change="onValueChange_"> </paper-input-container> <div>$i18n{networkProxyPort}</div> <paper-input-container no-label-float id="port"> - <input is="iron-input" bind-value="{{value.Port}}" disabled="[[!editable]]" - on-blur="onValueChange_"> + <input is="iron-input" bind-value="{{value.Port}}" + disabled="[[!editable]]" on-change="onValueChange_"> </paper-input-container> </div> </template>
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index d124f5a5..151e732 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -286,7 +286,6 @@ SafeBrowsingService::SafeBrowsingService() : services_delegate_(ServicesDelegate::Create(this)), - enabled_(false), enabled_by_prefs_(false), enabled_v4_only_(safe_browsing::V4FeatureList::IsV4OnlyEnabled()) {} @@ -393,6 +392,8 @@ return url_request_context_getter_; } +// TODO(ntfschr): componentize this once BaseSafeBrowsingUIManager contains a +// SafeBrowsingService const scoped_refptr<SafeBrowsingUIManager>& SafeBrowsingService::ui_manager() const { return ui_manager_; @@ -463,6 +464,8 @@ #endif } +// TODO(ntfschr): componentize this once BaseSafeBrowsingUIManager contains a +// SafeBrowsingService SafeBrowsingUIManager* SafeBrowsingService::CreateUIManager() { return new SafeBrowsingUIManager(this); }
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h index 666d7aa..d036c6c 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.h +++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -13,15 +13,11 @@ #include <string> #include "base/callback.h" -#include "base/callback_list.h" #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/observer_list.h" #include "base/sequenced_task_runner_helpers.h" #include "chrome/browser/safe_browsing/services_delegate.h" -#include "components/safe_browsing_db/util.h" -#include "content/public/browser/browser_thread.h" +#include "components/safe_browsing/base_safe_browsing_service.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -63,9 +59,7 @@ // the heavylifting of safebrowsing service. Both of these managers stay // alive until SafeBrowsingService is destroyed, however, they are disabled // permanently when Shutdown method is called. -class SafeBrowsingService : public base::RefCountedThreadSafe< - SafeBrowsingService, - content::BrowserThread::DeleteOnUIThread>, +class SafeBrowsingService : public BaseSafeBrowsingService, public content::NotificationObserver { public: // Makes the passed |factory| the factory used to instanciate @@ -82,10 +76,10 @@ static SafeBrowsingService* CreateSafeBrowsingService(); // Called on the UI thread to initialize the service. - void Initialize(); + void Initialize() override; // Called on the main thread to let us know that the io_thread is going away. - void ShutDown(); + void ShutDown() override; // Called on UI thread to decide if the download file's sha256 hash // should be calculated for safebrowsing. @@ -100,12 +94,6 @@ // Returns the client_name field for both V3 and V4 protocol manager configs. std::string GetProtocolConfigClientName() const; - // Get current enabled status. Must be called on IO thread. - bool enabled() const { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - return enabled_; - } - // Whether the service is enabled by the current set of profiles. bool enabled_by_prefs() const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -122,13 +110,14 @@ return services_delegate_->GetDownloadService(); } - scoped_refptr<net::URLRequestContextGetter> url_request_context(); + scoped_refptr<net::URLRequestContextGetter> url_request_context() override; const scoped_refptr<SafeBrowsingUIManager>& ui_manager() const; // This returns either the v3 or the v4 database manager, depending on // the experiment settings. - const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager() const; + const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager() + const override; scoped_refptr<SafeBrowsingNavigationObserverManager> navigation_observer_manager(); @@ -186,7 +175,7 @@ ~SafeBrowsingService() override; - virtual SafeBrowsingDatabaseManager* CreateDatabaseManager(); + SafeBrowsingDatabaseManager* CreateDatabaseManager() override; virtual SafeBrowsingUIManager* CreateUIManager(); @@ -201,8 +190,6 @@ private: friend class SafeBrowsingServiceFactoryImpl; - friend struct content::BrowserThread::DeleteOnThread< - content::BrowserThread::UI>; friend class base::DeleteHelper<SafeBrowsingService>; friend class SafeBrowsingServerTest; friend class SafeBrowsingServiceTest; @@ -269,10 +256,6 @@ // Provides phishing and malware statistics. Accessed on IO thread. std::unique_ptr<SafeBrowsingPingManager> ping_manager_; - // Whether the service is running. 'enabled_' is used by SafeBrowsingService - // on the IO thread during normal operations. - bool enabled_; - // Whether SafeBrowsing is enabled by the current set of profiles. // Accessed on UI thread. bool enabled_by_prefs_;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index e09d6330..822d5fc 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1460,8 +1460,6 @@ "views/bookmarks/bookmark_editor_view.cc", "views/bookmarks/bookmark_editor_view.h", "views/browser_dialogs_views_mac.cc", - "views/chooser_content_view.cc", - "views/chooser_content_view.h", "views/chrome_browser_main_extra_parts_views.cc", "views/chrome_browser_main_extra_parts_views.h", "views/chrome_constrained_window_views_client.cc", @@ -1474,6 +1472,8 @@ "views/content_setting_bubble_contents.h", "views/cookie_info_view.cc", "views/cookie_info_view.h", + "views/device_chooser_content_view.cc", + "views/device_chooser_content_view.h", "views/exclusive_access_bubble_views.cc", "views/exclusive_access_bubble_views.h", "views/exclusive_access_bubble_views_context.h", @@ -2552,8 +2552,6 @@ "cocoa/bubble_view.mm", "cocoa/certificate_viewer_mac_cocoa.h", "cocoa/certificate_viewer_mac_cocoa.mm", - "cocoa/chooser_content_view_cocoa.h", - "cocoa/chooser_content_view_cocoa.mm", "cocoa/chrome_browser_window.h", "cocoa/chrome_browser_window.mm", "cocoa/chrome_event_processing_window.h", @@ -2602,6 +2600,8 @@ "cocoa/custom_frame_view.mm", "cocoa/dev_tools_controller.h", "cocoa/dev_tools_controller.mm", + "cocoa/device_chooser_content_view_cocoa.h", + "cocoa/device_chooser_content_view_cocoa.mm", "cocoa/download/background_theme.h", "cocoa/download/background_theme.mm", "cocoa/download/download_danger_prompt_impl.cc",
diff --git a/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc index 6c8161f..567ad4e 100644 --- a/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc
@@ -110,8 +110,11 @@ void AppShortcutLauncherItemController::Launch(ash::LaunchSource source, int event_flags) { - launcher_controller()->LaunchAppWithLaunchId(app_id(), launch_id(), source, - event_flags); + // Launching an app replaces shortcut item controller to app controller. As + // result app_id_, launch_id_ are deleted during this call. Use local copies + // to prevent crash condition. + launcher_controller()->LaunchAppWithLaunchId( + std::string(app_id()), std::string(launch_id()), source, event_flags); } ash::ShelfItemDelegate::PerformedAction
diff --git a/chrome/browser/ui/bluetooth/bluetooth_chooser_desktop.h b/chrome/browser/ui/bluetooth/bluetooth_chooser_desktop.h index 7e81053..cbfb5d3 100644 --- a/chrome/browser/ui/bluetooth/bluetooth_chooser_desktop.h +++ b/chrome/browser/ui/bluetooth/bluetooth_chooser_desktop.h
@@ -31,7 +31,7 @@ void RemoveDevice(const std::string& device_id) override; private: - // Weak. ChooserContentView[Cocoa] owns it. + // Weak. DeviceChooserContentView[Cocoa] owns it. BluetoothChooserController* bluetooth_chooser_controller_; DISALLOW_COPY_AND_ASSIGN(BluetoothChooserDesktop);
diff --git a/chrome/browser/ui/bluetooth/chrome_extension_bluetooth_chooser.h b/chrome/browser/ui/bluetooth/chrome_extension_bluetooth_chooser.h index 9c1fe1f8..e0f7962 100644 --- a/chrome/browser/ui/bluetooth/chrome_extension_bluetooth_chooser.h +++ b/chrome/browser/ui/bluetooth/chrome_extension_bluetooth_chooser.h
@@ -38,7 +38,7 @@ void RemoveDevice(const std::string& device_id) override; private: - // Weak. ChooserContentView[Cocoa] owns it. + // Weak. DeviceChooserContentView[Cocoa] owns it. BluetoothChooserController* bluetooth_chooser_controller_; std::unique_ptr<ChromeExtensionChooserDialog> chooser_dialog_;
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index d7691bc5..0504425 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -184,6 +184,10 @@ // being sent to the renderer, which causes the transition to be janky. BOOL blockLayoutSubviews_; + // Set when AppKit invokes -windowWillClose: to protect against possible + // crashes. See http://crbug.com/671213. + BOOL didWindowWillClose_; + // The Extension Command Registry used to determine which keyboard events to // handle. std::unique_ptr<ExtensionKeybindingRegistryCocoa>
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 159c1e3..3b1bfa8f 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -19,6 +19,7 @@ #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_shutdown.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/extensions/extension_commands_global_registry.h" #include "chrome/browser/permissions/permission_request_manager.h" @@ -55,13 +56,13 @@ #import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" #import "chrome/browser/ui/cocoa/framed_browser_window.h" +#import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_controller.h" +#import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_visibility_lock_controller.h" #include "chrome/browser/ui/cocoa/fullscreen_low_power_coordinator.h" #import "chrome/browser/ui/cocoa/fullscreen_window.h" #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" -#import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" -#import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_visibility_lock_controller.h" -#import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_controller.h" #include "chrome/browser/ui/cocoa/l10n_util.h" +#import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" #import "chrome/browser/ui/cocoa/profiles/avatar_base_controller.h" #import "chrome/browser/ui/cocoa/profiles/avatar_button_controller.h" #import "chrome/browser/ui/cocoa/profiles/avatar_icon_controller.h" @@ -510,14 +511,11 @@ - (void)destroyBrowser { [NSApp removeWindowsItem:[self window]]; - // We need the window to go away now. - // We can't actually use |-autorelease| here because there's an embedded - // run loop in the |-performClose:| which contains its own autorelease pool. - // Instead call it after a zero-length delay, which gets us back to the main - // event loop. - [self performSelector:@selector(autorelease) - withObject:nil - afterDelay:0]; + // This is invoked from chrome::SessionEnding() which will terminate the + // process without spinning another RunLoop. So no need to perform an + // autorelease. Note this is currently controlled by an experiment. See + // features::kDesktopFastShutdown in chrome/browser/features.cc. + DCHECK_EQ(browser_shutdown::GetShutdownType(), browser_shutdown::END_SESSION); } // Called when the window meets the criteria to be closed (ie, @@ -525,13 +523,26 @@ // semantics of BrowserWindow::Close() and not call the Browser's dtor directly // from this method. - (void)windowWillClose:(NSNotification*)notification { + // Speculative fix for http://crbug.com/671213. It seems possible that AppKit + // may invoke -windowWillClose: twice under rare conditions. That would cause + // the logic below to post a second -autorelease, resulting in a double free. + // (Well, actually, a zombie access when the closure tries to call release on + // the strongly captured |self| pointer). + DCHECK(!didWindowWillClose_) << "If hit, please update crbug.com/671213."; + if (didWindowWillClose_) + return; + + didWindowWillClose_ = YES; + DCHECK_EQ([notification object], [self window]); DCHECK(browser_->tab_strip_model()->empty()); [savedRegularWindow_ close]; + // We delete statusBubble here because we need to kill off the dependency // that its window has on our window before our window goes away. delete statusBubble_; statusBubble_ = NULL; + // We can't actually use |-autorelease| here because there's an embedded // run loop in the |-performClose:| which contains its own autorelease pool. // Instead call it after a zero-length delay, which gets us back to the main
diff --git a/chrome/browser/ui/cocoa/chooser_content_view_cocoa.h b/chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.h similarity index 93% rename from chrome/browser/ui/cocoa/chooser_content_view_cocoa.h rename to chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.h index 434b310c..1179bbef 100644 --- a/chrome/browser/ui/cocoa/chooser_content_view_cocoa.h +++ b/chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_COCOA_CHOOSER_CONTENT_VIEW_COCOA_H_ -#define CHROME_BROWSER_UI_COCOA_CHOOSER_CONTENT_VIEW_COCOA_H_ +#ifndef CHROME_BROWSER_UI_COCOA_DEVICE_CHOOSER_CONTENT_VIEW_COCOA_H_ +#define CHROME_BROWSER_UI_COCOA_DEVICE_CHOOSER_CONTENT_VIEW_COCOA_H_ #import <Cocoa/Cocoa.h> @@ -16,7 +16,7 @@ @class SpinnerView; // A chooser content view class that user can select an option. -@interface ChooserContentViewCocoa : NSView { +@interface DeviceChooserContentViewCocoa : NSView { @private base::scoped_nsobject<NSTextField> titleView_; base::scoped_nsobject<NSButton> adapterOffHelpButton_; @@ -136,4 +136,4 @@ @end -#endif // CHROME_BROWSER_UI_COCOA_CHOOSER_CONTENT_VIEW_COCOA_H_ +#endif // CHROME_BROWSER_UI_COCOA_DEVICE_CHOOSER_CONTENT_VIEW_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm b/chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.mm similarity index 98% rename from chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm rename to chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.mm index 0c3db026..3c15014 100644 --- a/chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm +++ b/chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "chrome/browser/ui/cocoa/chooser_content_view_cocoa.h" +#import "chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.h" #include <algorithm> @@ -389,12 +389,8 @@ [table_view_ selectRowIndexes:selected_rows byExtendingSelection:NO]; } -@implementation ChooserContentViewCocoa +@implementation DeviceChooserContentViewCocoa -// TODO(juncai): restructure this function to be some smaller methods to -// create the pieces for the view. By doing so, the methods that calculate -// the frame and origins can be moved into those methods, rather than as -// helper functions. - (instancetype)initWithChooserTitle:(NSString*)chooserTitle chooserController: (std::unique_ptr<ChooserController>)chooserController {
diff --git a/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller.h b/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller.h index c9d5570d..ef9ca9b 100644 --- a/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller.h +++ b/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller.h
@@ -11,15 +11,16 @@ #include "base/mac/scoped_nsobject.h" -@class ChooserContentViewCocoa; class ChooserController; class ChooserDialogCocoa; +@class DeviceChooserContentViewCocoa; // Displays a chooser dialog, and notifies the ChooserController // of the selected option. @interface ChooserDialogCocoaController : NSViewController<NSTableViewDataSource, NSTableViewDelegate> { - base::scoped_nsobject<ChooserContentViewCocoa> chooserContentView_; + base::scoped_nsobject<DeviceChooserContentViewCocoa> + deviceChooserContentView_; NSTableView* tableView_; // Weak. NSButton* connectButton_; // Weak. NSButton* cancelButton_; // Weak. @@ -40,8 +41,8 @@ // Called when the "Cancel" button is pressed. - (void)onCancel:(id)sender; -// Gets the |chooserContentView_|. For testing only. -- (ChooserContentViewCocoa*)chooserContentView; +// Gets the |deviceChooserContentView_|. For testing only. +- (DeviceChooserContentViewCocoa*)deviceChooserContentView; @end
diff --git a/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller.mm b/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller.mm index 73f7caf..32281bf3 100644 --- a/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller.mm
@@ -6,7 +6,7 @@ #include "base/strings/sys_string_conversions.h" #include "chrome/browser/chooser_controller/chooser_controller.h" -#import "chrome/browser/ui/cocoa/chooser_content_view_cocoa.h" +#import "chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.h" #import "chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa.h" @implementation ChooserDialogCocoaController @@ -21,13 +21,13 @@ chooserDialogCocoa_ = chooserDialogCocoa; base::string16 chooserTitle = chooserController->GetTitle(); - chooserContentView_.reset([[ChooserContentViewCocoa alloc] + deviceChooserContentView_.reset([[DeviceChooserContentViewCocoa alloc] initWithChooserTitle:base::SysUTF16ToNSString(chooserTitle) chooserController:std::move(chooserController)]); - tableView_ = [chooserContentView_ tableView]; - connectButton_ = [chooserContentView_ connectButton]; - cancelButton_ = [chooserContentView_ cancelButton]; + tableView_ = [deviceChooserContentView_ tableView]; + connectButton_ = [deviceChooserContentView_ connectButton]; + cancelButton_ = [deviceChooserContentView_ cancelButton]; [connectButton_ setTarget:self]; [connectButton_ setAction:@selector(onConnect:)]; @@ -35,20 +35,20 @@ [cancelButton_ setAction:@selector(onCancel:)]; [tableView_ setDelegate:self]; [tableView_ setDataSource:self]; - self.view = chooserContentView_; - [chooserContentView_ updateTableView]; + self.view = deviceChooserContentView_; + [deviceChooserContentView_ updateTableView]; return self; } - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { - return [chooserContentView_ numberOfOptions]; + return [deviceChooserContentView_ numberOfOptions]; } - (NSView*)tableView:(NSTableView*)tableView viewForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { - return [chooserContentView_ createTableRowView:row].autorelease(); + return [deviceChooserContentView_ createTableRowView:row].autorelease(); } - (BOOL)tableView:(NSTableView*)aTableView @@ -58,32 +58,32 @@ } - (CGFloat)tableView:(NSTableView*)tableView heightOfRow:(NSInteger)row { - return [chooserContentView_ tableRowViewHeight:row]; + return [deviceChooserContentView_ tableRowViewHeight:row]; } - (void)tableViewSelectionDidChange:(NSNotification*)aNotification { - [chooserContentView_ updateContentRowColor]; + [deviceChooserContentView_ updateContentRowColor]; [connectButton_ setEnabled:[tableView_ numberOfSelectedRows] > 0]; } // Selection changes (while the mouse button is still down). - (void)tableViewSelectionIsChanging:(NSNotification*)aNotification { - [chooserContentView_ updateContentRowColor]; + [deviceChooserContentView_ updateContentRowColor]; [connectButton_ setEnabled:[tableView_ numberOfSelectedRows] > 0]; } - (void)onConnect:(id)sender { - [chooserContentView_ accept]; + [deviceChooserContentView_ accept]; chooserDialogCocoa_->Dismissed(); } - (void)onCancel:(id)sender { - [chooserContentView_ cancel]; + [deviceChooserContentView_ cancel]; chooserDialogCocoa_->Dismissed(); } -- (ChooserContentViewCocoa*)chooserContentView { - return chooserContentView_.get(); +- (DeviceChooserContentViewCocoa*)deviceChooserContentView { + return deviceChooserContentView_.get(); } @end
diff --git a/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller_unittest.mm index 88dbd1f..f018c1ab 100644 --- a/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa_controller_unittest.mm
@@ -11,7 +11,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chooser_controller/mock_chooser_controller.h" -#import "chrome/browser/ui/cocoa/chooser_content_view_cocoa.h" +#import "chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.h" #import "chrome/browser/ui/cocoa/extensions/chooser_dialog_cocoa.h" #include "chrome/browser/ui/cocoa/spinner_view.h" #import "chrome/browser/ui/cocoa/test/cocoa_profile_test.h" @@ -70,38 +70,40 @@ chooser_dialog_controller_ = chooser_dialog_->chooser_dialog_cocoa_controller_.get(); ASSERT_TRUE(chooser_dialog_controller_); - chooser_content_view_ = [chooser_dialog_controller_ chooserContentView]; - ASSERT_TRUE(chooser_content_view_); - adapter_off_help_button_ = [chooser_content_view_ adapterOffHelpButton]; + device_chooser_content_view_ = + [chooser_dialog_controller_ deviceChooserContentView]; + ASSERT_TRUE(device_chooser_content_view_); + adapter_off_help_button_ = + [device_chooser_content_view_ adapterOffHelpButton]; ASSERT_TRUE(adapter_off_help_button_); - table_view_ = [chooser_content_view_ tableView]; + table_view_ = [device_chooser_content_view_ tableView]; ASSERT_TRUE(table_view_); - spinner_ = [chooser_content_view_ spinner]; + spinner_ = [device_chooser_content_view_ spinner]; ASSERT_TRUE(spinner_); - connect_button_ = [chooser_content_view_ connectButton]; + connect_button_ = [device_chooser_content_view_ connectButton]; ASSERT_TRUE(connect_button_); - cancel_button_ = [chooser_content_view_ cancelButton]; + cancel_button_ = [device_chooser_content_view_ cancelButton]; ASSERT_TRUE(cancel_button_); - help_button_ = [chooser_content_view_ helpButton]; + help_button_ = [device_chooser_content_view_ helpButton]; ASSERT_TRUE(help_button_); - scanning_message_ = [chooser_content_view_ scanningMessage]; + scanning_message_ = [device_chooser_content_view_ scanningMessage]; ASSERT_TRUE(scanning_message_); - word_connector_ = [chooser_content_view_ wordConnector]; + word_connector_ = [device_chooser_content_view_ wordConnector]; ASSERT_TRUE(word_connector_); - rescan_button_ = [chooser_content_view_ rescanButton]; + rescan_button_ = [device_chooser_content_view_ rescanButton]; ASSERT_TRUE(rescan_button_); } void ExpectNoRowImage(int row) { - ASSERT_FALSE( - [chooser_content_view_ tableRowViewImage:static_cast<NSInteger>(row)]); + ASSERT_FALSE([device_chooser_content_view_ + tableRowViewImage:static_cast<NSInteger>(row)]); } void ExpectSignalStrengthLevelImageIs(int row, int expected_signal_strength_level, int expected_color) { - NSImageView* image_view = - [chooser_content_view_ tableRowViewImage:static_cast<NSInteger>(row)]; + NSImageView* image_view = [device_chooser_content_view_ + tableRowViewImage:static_cast<NSInteger>(row)]; ASSERT_TRUE(image_view); int image_id = expected_color == MockChooserController::kImageColorUnselected @@ -113,8 +115,8 @@ } void ExpectRowImageIsConnectedImage(int row, SkColor expected_color) { - NSImageView* image_view = - [chooser_content_view_ tableRowViewImage:static_cast<NSInteger>(row)]; + NSImageView* image_view = [device_chooser_content_view_ + tableRowViewImage:static_cast<NSInteger>(row)]; ASSERT_TRUE(image_view); EXPECT_TRUE(gfx::test::AreImagesEqual( gfx::Image(gfx::CreateVectorIcon(gfx::VectorIconId::BLUETOOTH_CONNECTED, @@ -124,18 +126,18 @@ void ExpectRowTextIs(int row, NSString* expected_text) { EXPECT_NSEQ(expected_text, - [[chooser_content_view_ + [[device_chooser_content_view_ tableRowViewText:static_cast<NSInteger>(row)] stringValue]); } void ExpectRowTextColorIs(int row, NSColor* expected_color) { EXPECT_NSEQ(expected_color, - [[chooser_content_view_ + [[device_chooser_content_view_ tableRowViewText:static_cast<NSInteger>(row)] textColor]); } bool IsRowPaired(int row) { - NSTextField* paired_status = [chooser_content_view_ + NSTextField* paired_status = [device_chooser_content_view_ tableRowViewPairedStatus:static_cast<NSInteger>(row)]; if (paired_status) { EXPECT_NSEQ(l10n_util::GetNSString(IDS_DEVICE_CHOOSER_PAIRED_STATUS_TEXT), @@ -149,7 +151,7 @@ void ExpectPairedTextColorIs(int row, NSColor* expected_color) { EXPECT_NSEQ( expected_color, - [[chooser_content_view_ + [[device_chooser_content_view_ tableRowViewPairedStatus:static_cast<NSInteger>(row)] textColor]); } @@ -159,7 +161,7 @@ MockChooserController* mock_chooser_controller_; ChooserDialogCocoaController* chooser_dialog_controller_; - ChooserContentViewCocoa* chooser_content_view_; + DeviceChooserContentViewCocoa* device_chooser_content_view_; NSButton* adapter_off_help_button_; NSTableView* table_view_; SpinnerView* spinner_;
diff --git a/chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm b/chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm index 2651dd3c..f8baba4 100644 --- a/chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm +++ b/chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm
@@ -18,7 +18,7 @@ #import "chrome/browser/ui/cocoa/base_bubble_controller.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/browser_window_utils.h" -#import "chrome/browser/ui/cocoa/chooser_content_view_cocoa.h" +#import "chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.h" #import "chrome/browser/ui/cocoa/info_bubble_view.h" #import "chrome/browser/ui/cocoa/info_bubble_window.h" #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" @@ -40,7 +40,8 @@ ChooserBubbleUiCocoa* bridge_; // Weak. bool buttonPressed_; - base::scoped_nsobject<ChooserContentViewCocoa> chooserContentView_; + base::scoped_nsobject<DeviceChooserContentViewCocoa> + deviceChooserContentView_; NSTableView* tableView_; // Weak. NSButton* connectButton_; // Weak. NSButton* cancelButton_; // Weak. @@ -116,13 +117,13 @@ object:[self getExpectedParentWindow]]; base::string16 chooserTitle = chooserController->GetTitle(); - chooserContentView_.reset([[ChooserContentViewCocoa alloc] + deviceChooserContentView_.reset([[DeviceChooserContentViewCocoa alloc] initWithChooserTitle:base::SysUTF16ToNSString(chooserTitle) chooserController:std::move(chooserController)]); - tableView_ = [chooserContentView_ tableView]; - connectButton_ = [chooserContentView_ connectButton]; - cancelButton_ = [chooserContentView_ cancelButton]; + tableView_ = [deviceChooserContentView_ tableView]; + connectButton_ = [deviceChooserContentView_ connectButton]; + cancelButton_ = [deviceChooserContentView_ cancelButton]; [connectButton_ setTarget:self]; [connectButton_ setAction:@selector(onConnect:)]; @@ -131,7 +132,7 @@ [tableView_ setDelegate:self]; [tableView_ setDataSource:self]; - [[[self window] contentView] addSubview:chooserContentView_.get()]; + [[[self window] contentView] addSubview:deviceChooserContentView_.get()]; } return self; @@ -143,7 +144,7 @@ name:NSWindowDidMoveNotification object:nil]; if (!buttonPressed_) - [chooserContentView_ close]; + [deviceChooserContentView_ close]; bridge_->OnBubbleClosing(); [super windowWillClose:notification]; } @@ -163,7 +164,7 @@ - (void)show { NSRect bubbleFrame = - [[self window] frameRectForContentRect:[chooserContentView_ frame]]; + [[self window] frameRectForContentRect:[deviceChooserContentView_ frame]]; if ([[self window] isVisible]) { // Unfortunately, calling -setFrame followed by -setFrameOrigin (called // within -setAnchorPoint) causes flickering. Avoid the flickering by @@ -185,13 +186,13 @@ } - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { - return [chooserContentView_ numberOfOptions]; + return [deviceChooserContentView_ numberOfOptions]; } - (NSView*)tableView:(NSTableView*)tableView viewForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { - return [chooserContentView_ createTableRowView:row].autorelease(); + return [deviceChooserContentView_ createTableRowView:row].autorelease(); } - (BOOL)tableView:(NSTableView*)aTableView @@ -201,21 +202,21 @@ } - (CGFloat)tableView:(NSTableView*)tableView heightOfRow:(NSInteger)row { - return [chooserContentView_ tableRowViewHeight:row]; + return [deviceChooserContentView_ tableRowViewHeight:row]; } - (void)updateTableView { - [chooserContentView_ updateTableView]; + [deviceChooserContentView_ updateTableView]; } - (void)tableViewSelectionDidChange:(NSNotification*)aNotification { - [chooserContentView_ updateContentRowColor]; + [deviceChooserContentView_ updateContentRowColor]; [connectButton_ setEnabled:[tableView_ numberOfSelectedRows] > 0]; } // Selection changes (while the mouse button is still down). - (void)tableViewSelectionIsChanging:(NSNotification*)aNotification { - [chooserContentView_ updateContentRowColor]; + [deviceChooserContentView_ updateContentRowColor]; [connectButton_ setEnabled:[tableView_ numberOfSelectedRows] > 0]; } @@ -272,7 +273,7 @@ - (void)onConnect:(id)sender { buttonPressed_ = true; - [chooserContentView_ accept]; + [deviceChooserContentView_ accept]; if (self.bubbleReference) self.bubbleReference->CloseBubble(BUBBLE_CLOSE_ACCEPTED); [self close]; @@ -280,7 +281,7 @@ - (void)onCancel:(id)sender { buttonPressed_ = true; - [chooserContentView_ cancel]; + [deviceChooserContentView_ cancel]; if (self.bubbleReference) self.bubbleReference->CloseBubble(BUBBLE_CLOSE_CANCELED); [self close];
diff --git a/chrome/browser/ui/views/chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc similarity index 85% rename from chrome/browser/ui/views/chooser_content_view.cc rename to chrome/browser/ui/views/device_chooser_content_view.cc index 0310f30..ea0e568 100644 --- a/chrome/browser/ui/views/chooser_content_view.cc +++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/chooser_content_view.h" +#include "chrome/browser/ui/views/device_chooser_content_view.h" #include "base/memory/ptr_util.h" #include "base/numerics/safe_conversions.h" @@ -38,7 +38,7 @@ } // namespace -ChooserContentView::ChooserContentView( +DeviceChooserContentView::DeviceChooserContentView( views::TableViewObserver* table_view_observer, std::unique_ptr<ChooserController> chooser_controller) : chooser_controller_(std::move(chooser_controller)), @@ -89,17 +89,17 @@ AddChildView(turn_adapter_off_help_); } -ChooserContentView::~ChooserContentView() { +DeviceChooserContentView::~DeviceChooserContentView() { chooser_controller_->set_view(nullptr); table_view_->set_observer(nullptr); table_view_->SetModel(nullptr); } -gfx::Size ChooserContentView::GetPreferredSize() const { +gfx::Size DeviceChooserContentView::GetPreferredSize() const { return gfx::Size(kChooserWidth, kChooserHeight); } -void ChooserContentView::Layout() { +void DeviceChooserContentView::Layout() { gfx::Rect rect(GetContentsBounds()); table_parent_->SetBoundsRect(rect); // Set the throbber in the center of the chooser. @@ -113,14 +113,14 @@ views::View::Layout(); } -int ChooserContentView::RowCount() { +int DeviceChooserContentView::RowCount() { // When there are no devices, the table contains a message saying there // are no devices, so the number of rows is always at least 1. return std::max(base::checked_cast<int>(chooser_controller_->NumOptions()), 1); } -base::string16 ChooserContentView::GetText(int row, int column_id) { +base::string16 DeviceChooserContentView::GetText(int row, int column_id) { int num_options = base::checked_cast<int>(chooser_controller_->NumOptions()); if (num_options == 0) { DCHECK_EQ(0, row); @@ -137,9 +137,9 @@ : text; } -void ChooserContentView::SetObserver(ui::TableModelObserver* observer) {} +void DeviceChooserContentView::SetObserver(ui::TableModelObserver* observer) {} -gfx::ImageSkia ChooserContentView::GetIcon(int row) { +gfx::ImageSkia DeviceChooserContentView::GetIcon(int row) { DCHECK(chooser_controller_->ShouldShowIconBeforeText()); size_t num_options = chooser_controller_->NumOptions(); @@ -168,12 +168,12 @@ kSignalStrengthLevelImageIds[level]); } -void ChooserContentView::OnOptionsInitialized() { +void DeviceChooserContentView::OnOptionsInitialized() { table_view_->OnModelChanged(); UpdateTableView(); } -void ChooserContentView::OnOptionAdded(size_t index) { +void DeviceChooserContentView::OnOptionAdded(size_t index) { table_view_->OnItemsAdded(base::checked_cast<int>(index), 1); UpdateTableView(); table_view_->SetVisible(true); @@ -181,17 +181,17 @@ throbber_->Stop(); } -void ChooserContentView::OnOptionRemoved(size_t index) { +void DeviceChooserContentView::OnOptionRemoved(size_t index) { table_view_->OnItemsRemoved(base::checked_cast<int>(index), 1); UpdateTableView(); } -void ChooserContentView::OnOptionUpdated(size_t index) { +void DeviceChooserContentView::OnOptionUpdated(size_t index) { table_view_->OnItemsChanged(base::checked_cast<int>(index), 1); UpdateTableView(); } -void ChooserContentView::OnAdapterEnabledChanged(bool enabled) { +void DeviceChooserContentView::OnAdapterEnabledChanged(bool enabled) { // No row is selected since the adapter status has changed. // This will also disable the OK button if it was enabled because // of a previously selected row. @@ -216,7 +216,7 @@ GetWidget()->GetRootView()->Layout(); } -void ChooserContentView::OnRefreshStateChanged(bool refreshing) { +void DeviceChooserContentView::OnRefreshStateChanged(bool refreshing) { if (refreshing) { // No row is selected since the chooser is refreshing. This will also // disable the OK button if it was enabled because of a previously @@ -249,9 +249,9 @@ GetWidget()->GetRootView()->Layout(); } -void ChooserContentView::StyledLabelLinkClicked(views::StyledLabel* label, - const gfx::Range& range, - int event_flags) { +void DeviceChooserContentView::StyledLabelLinkClicked(views::StyledLabel* label, + const gfx::Range& range, + int event_flags) { if (label == turn_adapter_off_help_) { chooser_controller_->OpenAdapterOffHelpUrl(); } else if (label == footnote_link_.get()) { @@ -266,23 +266,24 @@ } } -base::string16 ChooserContentView::GetWindowTitle() const { +base::string16 DeviceChooserContentView::GetWindowTitle() const { return chooser_controller_->GetTitle(); } -base::string16 ChooserContentView::GetDialogButtonLabel( +base::string16 DeviceChooserContentView::GetDialogButtonLabel( ui::DialogButton button) const { return button == ui::DIALOG_BUTTON_OK ? chooser_controller_->GetOkButtonLabel() : l10n_util::GetStringUTF16(IDS_DEVICE_CHOOSER_CANCEL_BUTTON_TEXT); } -bool ChooserContentView::IsDialogButtonEnabled(ui::DialogButton button) const { +bool DeviceChooserContentView::IsDialogButtonEnabled( + ui::DialogButton button) const { return button != ui::DIALOG_BUTTON_OK || !table_view_->selection_model().empty(); } -views::StyledLabel* ChooserContentView::footnote_link() { +views::StyledLabel* DeviceChooserContentView::footnote_link() { if (chooser_controller_->ShouldShowFootnoteView()) { footnote_link_ = base::MakeUnique<views::StyledLabel>(help_text_, this); footnote_link_->set_owned_by_client(); @@ -293,22 +294,22 @@ return footnote_link_.get(); } -void ChooserContentView::Accept() { +void DeviceChooserContentView::Accept() { std::vector<size_t> indices( table_view_->selection_model().selected_indices().begin(), table_view_->selection_model().selected_indices().end()); chooser_controller_->Select(indices); } -void ChooserContentView::Cancel() { +void DeviceChooserContentView::Cancel() { chooser_controller_->Cancel(); } -void ChooserContentView::Close() { +void DeviceChooserContentView::Close() { chooser_controller_->Close(); } -void ChooserContentView::UpdateTableView() { +void DeviceChooserContentView::UpdateTableView() { if (chooser_controller_->NumOptions() == 0) { table_view_->OnModelChanged(); table_view_->SetEnabled(false); @@ -317,7 +318,7 @@ } } -void ChooserContentView::SetGetHelpAndReScanLink() { +void DeviceChooserContentView::SetGetHelpAndReScanLink() { DCHECK(footnote_link_); footnote_link_->SetText(help_and_re_scan_text_); footnote_link_->AddStyleRange(
diff --git a/chrome/browser/ui/views/chooser_content_view.h b/chrome/browser/ui/views/device_chooser_content_view.h similarity index 69% rename from chrome/browser/ui/views/chooser_content_view.h rename to chrome/browser/ui/views/device_chooser_content_view.h index db04e60a..92b8c4d 100644 --- a/chrome/browser/ui/views/chooser_content_view.h +++ b/chrome/browser/ui/views/device_chooser_content_view.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_CHOOSER_CONTENT_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_CHOOSER_CONTENT_VIEW_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_DEVICE_CHOOSER_CONTENT_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_DEVICE_CHOOSER_CONTENT_VIEW_H_ #include <memory> @@ -24,17 +24,15 @@ // A bubble or dialog view for choosing among several options in a table. // Used for WebUSB/WebBluetooth device selection for Chrome and extensions. -// -// TODO(juncai): change ChooserContentView class name to be more specific. -// https://crbug.com/651568 -class ChooserContentView : public views::View, - public ui::TableModel, - public ChooserController::View, - public views::StyledLabelListener { +class DeviceChooserContentView : public views::View, + public ui::TableModel, + public ChooserController::View, + public views::StyledLabelListener { public: - ChooserContentView(views::TableViewObserver* table_view_observer, - std::unique_ptr<ChooserController> chooser_controller); - ~ChooserContentView() override; + DeviceChooserContentView( + views::TableViewObserver* table_view_observer, + std::unique_ptr<ChooserController> chooser_controller); + ~DeviceChooserContentView() override; // views::View: gfx::Size GetPreferredSize() const override; @@ -70,16 +68,16 @@ void SetGetHelpAndReScanLink(); private: - friend class ChooserContentViewTest; friend class ChooserDialogViewTest; - FRIEND_TEST_ALL_PREFIXES(ChooserContentViewTest, InitialState); - FRIEND_TEST_ALL_PREFIXES(ChooserContentViewTest, AdapterOnAndOffAndOn); - FRIEND_TEST_ALL_PREFIXES(ChooserContentViewTest, + friend class DeviceChooserContentViewTest; + FRIEND_TEST_ALL_PREFIXES(DeviceChooserContentViewTest, InitialState); + FRIEND_TEST_ALL_PREFIXES(DeviceChooserContentViewTest, AdapterOnAndOffAndOn); + FRIEND_TEST_ALL_PREFIXES(DeviceChooserContentViewTest, DiscoveringAndNoOptionAddedAndIdle); - FRIEND_TEST_ALL_PREFIXES(ChooserContentViewTest, + FRIEND_TEST_ALL_PREFIXES(DeviceChooserContentViewTest, DiscoveringAndOneOptionAddedAndSelectedAndIdle); - FRIEND_TEST_ALL_PREFIXES(ChooserContentViewTest, ClickRescanLink); - FRIEND_TEST_ALL_PREFIXES(ChooserContentViewTest, ClickGetHelpLink); + FRIEND_TEST_ALL_PREFIXES(DeviceChooserContentViewTest, ClickRescanLink); + FRIEND_TEST_ALL_PREFIXES(DeviceChooserContentViewTest, ClickGetHelpLink); std::unique_ptr<ChooserController> chooser_controller_; views::TableView* table_view_ = nullptr; // Weak. @@ -93,7 +91,7 @@ gfx::Range help_text_range_; gfx::Range re_scan_text_range_; - DISALLOW_COPY_AND_ASSIGN(ChooserContentView); + DISALLOW_COPY_AND_ASSIGN(DeviceChooserContentView); }; -#endif // CHROME_BROWSER_UI_VIEWS_CHOOSER_CONTENT_VIEW_H_ +#endif // CHROME_BROWSER_UI_VIEWS_DEVICE_CHOOSER_CONTENT_VIEW_H_
diff --git a/chrome/browser/ui/views/chooser_content_view_unittest.cc b/chrome/browser/ui/views/device_chooser_content_view_unittest.cc similarity index 90% rename from chrome/browser/ui/views/chooser_content_view_unittest.cc rename to chrome/browser/ui/views/device_chooser_content_view_unittest.cc index dbfd1539..047d238a 100644 --- a/chrome/browser/ui/views/chooser_content_view_unittest.cc +++ b/chrome/browser/ui/views/device_chooser_content_view_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/chooser_content_view.h" +#include "chrome/browser/ui/views/device_chooser_content_view.h" #include <memory> @@ -38,9 +38,9 @@ } // namespace -class ChooserContentViewTest : public views::ViewsTestBase { +class DeviceChooserContentViewTest : public views::ViewsTestBase { public: - ChooserContentViewTest() {} + DeviceChooserContentViewTest() {} // views::ViewsTestBase: void SetUp() override { @@ -49,23 +49,24 @@ new MockChooserController(nullptr)); mock_chooser_controller_ = mock_chooser_controller.get(); mock_table_view_observer_ = base::MakeUnique<MockTableViewObserver>(); - chooser_content_view_ = base::MakeUnique<ChooserContentView>( + device_chooser_content_view_ = base::MakeUnique<DeviceChooserContentView>( mock_table_view_observer_.get(), std::move(mock_chooser_controller)); - table_view_ = chooser_content_view_->table_view_; + table_view_ = device_chooser_content_view_->table_view_; ASSERT_TRUE(table_view_); table_model_ = table_view_->model(); ASSERT_TRUE(table_model_); - throbber_ = chooser_content_view_->throbber_; + throbber_ = device_chooser_content_view_->throbber_; ASSERT_TRUE(throbber_); - turn_adapter_off_help_ = chooser_content_view_->turn_adapter_off_help_; + turn_adapter_off_help_ = + device_chooser_content_view_->turn_adapter_off_help_; ASSERT_TRUE(turn_adapter_off_help_); - footnote_link_ = chooser_content_view_->footnote_link(); + footnote_link_ = device_chooser_content_view_->footnote_link(); ASSERT_TRUE(footnote_link_); } protected: std::unique_ptr<MockTableViewObserver> mock_table_view_observer_; - std::unique_ptr<ChooserContentView> chooser_content_view_; + std::unique_ptr<DeviceChooserContentView> device_chooser_content_view_; MockChooserController* mock_chooser_controller_ = nullptr; views::TableView* table_view_ = nullptr; ui::TableModel* table_model_ = nullptr; @@ -74,10 +75,10 @@ views::StyledLabel* footnote_link_ = nullptr; private: - DISALLOW_COPY_AND_ASSIGN(ChooserContentViewTest); + DISALLOW_COPY_AND_ASSIGN(DeviceChooserContentViewTest); }; -TEST_F(ChooserContentViewTest, InitialState) { +TEST_F(DeviceChooserContentViewTest, InitialState) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(0); EXPECT_TRUE(table_view_->visible()); @@ -94,10 +95,10 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); EXPECT_FALSE(throbber_->visible()); EXPECT_FALSE(turn_adapter_off_help_->visible()); - EXPECT_EQ(chooser_content_view_->help_text_, footnote_link_->text()); + EXPECT_EQ(device_chooser_content_view_->help_text_, footnote_link_->text()); } -TEST_F(ChooserContentViewTest, AddOption) { +TEST_F(DeviceChooserContentViewTest, AddOption) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(0); mock_chooser_controller_->OptionAdded( @@ -132,7 +133,7 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, RemoveOption) { +TEST_F(DeviceChooserContentViewTest, RemoveOption) { // Called from TableView::OnItemsRemoved(). EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); @@ -185,7 +186,7 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, UpdateOption) { +TEST_F(DeviceChooserContentViewTest, UpdateOption) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(0); mock_chooser_controller_->OptionAdded( @@ -214,7 +215,7 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, AddAndRemoveOption) { +TEST_F(DeviceChooserContentViewTest, AddAndRemoveOption) { // Called from TableView::OnItemsRemoved(). EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); @@ -244,7 +245,7 @@ EXPECT_EQ(1, table_view_->RowCount()); } -TEST_F(ChooserContentViewTest, UpdateAndRemoveTheUpdatedOption) { +TEST_F(DeviceChooserContentViewTest, UpdateAndRemoveTheUpdatedOption) { // Called from TableView::OnItemsRemoved(). EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(1); @@ -276,7 +277,7 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, SelectAndDeselectAnOption) { +TEST_F(DeviceChooserContentViewTest, SelectAndDeselectAnOption) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(4); mock_chooser_controller_->OptionAdded( @@ -312,7 +313,7 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, SelectAnOptionAndThenSelectAnotherOption) { +TEST_F(DeviceChooserContentViewTest, SelectAnOptionAndThenSelectAnotherOption) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); mock_chooser_controller_->OptionAdded( @@ -343,7 +344,7 @@ EXPECT_EQ(2, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, SelectAnOptionAndRemoveAnotherOption) { +TEST_F(DeviceChooserContentViewTest, SelectAnOptionAndRemoveAnotherOption) { // Called one time from TableView::Select() and two times from // TableView::OnItemsRemoved(). EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); @@ -380,7 +381,7 @@ EXPECT_EQ(0, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, SelectAnOptionAndRemoveTheSelectedOption) { +TEST_F(DeviceChooserContentViewTest, SelectAnOptionAndRemoveTheSelectedOption) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(2); mock_chooser_controller_->OptionAdded( @@ -408,7 +409,7 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, SelectAnOptionAndUpdateTheSelectedOption) { +TEST_F(DeviceChooserContentViewTest, SelectAnOptionAndUpdateTheSelectedOption) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(1); mock_chooser_controller_->OptionAdded( @@ -440,7 +441,7 @@ EXPECT_EQ(base::ASCIIToUTF16("c"), table_model_->GetText(2, 0)); } -TEST_F(ChooserContentViewTest, +TEST_F(DeviceChooserContentViewTest, AddAnOptionAndSelectItAndRemoveTheSelectedOption) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(2); @@ -470,7 +471,7 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); } -TEST_F(ChooserContentViewTest, AdapterOnAndOffAndOn) { +TEST_F(DeviceChooserContentViewTest, AdapterOnAndOffAndOn) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(2); mock_chooser_controller_->OnAdapterPresenceChanged( @@ -489,7 +490,7 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); EXPECT_FALSE(throbber_->visible()); EXPECT_FALSE(turn_adapter_off_help_->visible()); - EXPECT_EQ(chooser_content_view_->help_and_re_scan_text_, + EXPECT_EQ(device_chooser_content_view_->help_and_re_scan_text_, footnote_link_->text()); mock_chooser_controller_->OptionAdded( @@ -512,7 +513,7 @@ EXPECT_FALSE(table_view_->visible()); EXPECT_FALSE(throbber_->visible()); EXPECT_TRUE(turn_adapter_off_help_->visible()); - EXPECT_EQ(chooser_content_view_->help_text_, footnote_link_->text()); + EXPECT_EQ(device_chooser_content_view_->help_text_, footnote_link_->text()); mock_chooser_controller_->OnAdapterPresenceChanged( content::BluetoothChooser::AdapterPresence::POWERED_ON); @@ -527,11 +528,11 @@ EXPECT_EQ(-1, table_view_->FirstSelectedRow()); EXPECT_FALSE(throbber_->visible()); EXPECT_FALSE(turn_adapter_off_help_->visible()); - EXPECT_EQ(chooser_content_view_->help_and_re_scan_text_, + EXPECT_EQ(device_chooser_content_view_->help_and_re_scan_text_, footnote_link_->text()); } -TEST_F(ChooserContentViewTest, DiscoveringAndNoOptionAddedAndIdle) { +TEST_F(DeviceChooserContentViewTest, DiscoveringAndNoOptionAddedAndIdle) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(2); mock_chooser_controller_->OptionAdded( @@ -551,7 +552,7 @@ content::BluetoothChooser::DiscoveryState::DISCOVERING); EXPECT_FALSE(table_view_->visible()); EXPECT_TRUE(throbber_->visible()); - EXPECT_EQ(chooser_content_view_->help_and_scanning_text_, + EXPECT_EQ(device_chooser_content_view_->help_and_scanning_text_, footnote_link_->text()); mock_chooser_controller_->OnDiscoveryStateChanged( @@ -569,11 +570,12 @@ EXPECT_EQ(0UL, table_view_->selection_model().size()); EXPECT_EQ(-1, table_view_->FirstSelectedRow()); EXPECT_FALSE(throbber_->visible()); - EXPECT_EQ(chooser_content_view_->help_and_re_scan_text_, + EXPECT_EQ(device_chooser_content_view_->help_and_re_scan_text_, footnote_link_->text()); } -TEST_F(ChooserContentViewTest, DiscoveringAndOneOptionAddedAndSelectedAndIdle) { +TEST_F(DeviceChooserContentViewTest, + DiscoveringAndOneOptionAddedAndSelectedAndIdle) { EXPECT_CALL(*mock_table_view_observer_, OnSelectionChanged()).Times(3); mock_chooser_controller_->OptionAdded( @@ -603,7 +605,7 @@ EXPECT_EQ(0UL, table_view_->selection_model().size()); EXPECT_EQ(-1, table_view_->FirstSelectedRow()); EXPECT_FALSE(throbber_->visible()); - EXPECT_EQ(chooser_content_view_->help_and_scanning_text_, + EXPECT_EQ(device_chooser_content_view_->help_and_scanning_text_, footnote_link_->text()); table_view_->Select(0); EXPECT_EQ(1UL, table_view_->selection_model().size()); @@ -619,23 +621,23 @@ EXPECT_EQ(1UL, table_view_->selection_model().size()); EXPECT_EQ(0, table_view_->FirstSelectedRow()); EXPECT_FALSE(throbber_->visible()); - EXPECT_EQ(chooser_content_view_->help_and_re_scan_text_, + EXPECT_EQ(device_chooser_content_view_->help_and_re_scan_text_, footnote_link_->text()); } -TEST_F(ChooserContentViewTest, ClickAdapterOffHelpLink) { +TEST_F(DeviceChooserContentViewTest, ClickAdapterOffHelpLink) { EXPECT_CALL(*mock_chooser_controller_, OpenAdapterOffHelpUrl()).Times(1); turn_adapter_off_help_->LinkClicked(nullptr, 0); } -TEST_F(ChooserContentViewTest, ClickRescanLink) { +TEST_F(DeviceChooserContentViewTest, ClickRescanLink) { EXPECT_CALL(*mock_chooser_controller_, RefreshOptions()).Times(1); - chooser_content_view_->StyledLabelLinkClicked( - footnote_link_, chooser_content_view_->re_scan_text_range_, 0); + device_chooser_content_view_->StyledLabelLinkClicked( + footnote_link_, device_chooser_content_view_->re_scan_text_range_, 0); } -TEST_F(ChooserContentViewTest, ClickGetHelpLink) { +TEST_F(DeviceChooserContentViewTest, ClickGetHelpLink) { EXPECT_CALL(*mock_chooser_controller_, OpenHelpCenterUrl()).Times(1); - chooser_content_view_->StyledLabelLinkClicked( - footnote_link_, chooser_content_view_->help_text_range_, 0); + device_chooser_content_view_->StyledLabelLinkClicked( + footnote_link_, device_chooser_content_view_->help_text_range_, 0); }
diff --git a/chrome/browser/ui/views/extensions/chooser_dialog_view.cc b/chrome/browser/ui/views/extensions/chooser_dialog_view.cc index f0c0522c..dffa13c 100644 --- a/chrome/browser/ui/views/extensions/chooser_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/chooser_dialog_view.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/extensions/api/chrome_device_permissions_prompt.h" #include "chrome/browser/extensions/chrome_extension_chooser_dialog.h" #include "chrome/browser/extensions/device_permissions_dialog_controller.h" -#include "chrome/browser/ui/views/chooser_content_view.h" +#include "chrome/browser/ui/views/device_chooser_content_view.h" #include "components/constrained_window/constrained_window_views.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "content/public/browser/browser_thread.h" @@ -38,14 +38,14 @@ // ------------------------------------ DCHECK(chooser_controller); - chooser_content_view_ = - new ChooserContentView(this, std::move(chooser_controller)); + device_chooser_content_view_ = + new DeviceChooserContentView(this, std::move(chooser_controller)); } ChooserDialogView::~ChooserDialogView() {} base::string16 ChooserDialogView::GetWindowTitle() const { - return chooser_content_view_->GetWindowTitle(); + return device_chooser_content_view_->GetWindowTitle(); } bool ChooserDialogView::ShouldShowCloseButton() const { @@ -58,15 +58,15 @@ base::string16 ChooserDialogView::GetDialogButtonLabel( ui::DialogButton button) const { - return chooser_content_view_->GetDialogButtonLabel(button); + return device_chooser_content_view_->GetDialogButtonLabel(button); } bool ChooserDialogView::IsDialogButtonEnabled(ui::DialogButton button) const { - return chooser_content_view_->IsDialogButtonEnabled(button); + return device_chooser_content_view_->IsDialogButtonEnabled(button); } views::View* ChooserDialogView::CreateFootnoteView() { - return chooser_content_view_->footnote_link(); + return device_chooser_content_view_->footnote_link(); } views::ClientView* ChooserDialogView::CreateClientView(views::Widget* widget) { @@ -87,38 +87,39 @@ } bool ChooserDialogView::Accept() { - chooser_content_view_->Accept(); + device_chooser_content_view_->Accept(); return true; } bool ChooserDialogView::Cancel() { - chooser_content_view_->Cancel(); + device_chooser_content_view_->Cancel(); return true; } bool ChooserDialogView::Close() { - chooser_content_view_->Close(); + device_chooser_content_view_->Close(); return true; } views::View* ChooserDialogView::GetContentsView() { - return chooser_content_view_; + return device_chooser_content_view_; } views::Widget* ChooserDialogView::GetWidget() { - return chooser_content_view_->GetWidget(); + return device_chooser_content_view_->GetWidget(); } const views::Widget* ChooserDialogView::GetWidget() const { - return chooser_content_view_->GetWidget(); + return device_chooser_content_view_->GetWidget(); } void ChooserDialogView::OnSelectionChanged() { GetDialogClientView()->UpdateDialogButtons(); } -ChooserContentView* ChooserDialogView::chooser_content_view_for_test() const { - return chooser_content_view_; +DeviceChooserContentView* +ChooserDialogView::device_chooser_content_view_for_test() const { + return device_chooser_content_view_; } void ChromeExtensionChooserDialog::ShowDialogImpl(
diff --git a/chrome/browser/ui/views/extensions/chooser_dialog_view.h b/chrome/browser/ui/views/extensions/chooser_dialog_view.h index 9cf214a..231dd9f 100644 --- a/chrome/browser/ui/views/extensions/chooser_dialog_view.h +++ b/chrome/browser/ui/views/extensions/chooser_dialog_view.h
@@ -11,8 +11,8 @@ #include "ui/views/controls/table/table_view_observer.h" #include "ui/views/window/dialog_delegate.h" -class ChooserContentView; class ChooserController; +class DeviceChooserContentView; // Displays a chooser view as a modal dialog constrained // to the window/tab displaying the given web contents. @@ -47,10 +47,10 @@ // views::TableViewObserver: void OnSelectionChanged() override; - ChooserContentView* chooser_content_view_for_test() const; + DeviceChooserContentView* device_chooser_content_view_for_test() const; private: - ChooserContentView* chooser_content_view_; + DeviceChooserContentView* device_chooser_content_view_; DISALLOW_COPY_AND_ASSIGN(ChooserDialogView); };
diff --git a/chrome/browser/ui/views/extensions/chooser_dialog_view_unittest.cc b/chrome/browser/ui/views/extensions/chooser_dialog_view_unittest.cc index 9fc7868..efd22b17 100644 --- a/chrome/browser/ui/views/extensions/chooser_dialog_view_unittest.cc +++ b/chrome/browser/ui/views/extensions/chooser_dialog_view_unittest.cc
@@ -10,7 +10,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chooser_controller/mock_chooser_controller.h" -#include "chrome/browser/ui/views/chooser_content_view.h" +#include "chrome/browser/ui/views/device_chooser_content_view.h" #include "chrome/grit/generated_resources.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/l10n/l10n_util.h" @@ -36,8 +36,8 @@ std::unique_ptr<ChooserDialogView> chooser_dialog_view( new ChooserDialogView(std::move(mock_chooser_controller))); chooser_dialog_view_ = chooser_dialog_view.get(); - table_view_ = - chooser_dialog_view_->chooser_content_view_for_test()->table_view_; + table_view_ = chooser_dialog_view_->device_chooser_content_view_for_test() + ->table_view_; ASSERT_TRUE(table_view_); views::Widget::InitParams params =
diff --git a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc index a3cb6d2..497aa60f 100644 --- a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc +++ b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
@@ -227,15 +227,7 @@ EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_CLOSE_BUTTON)); } -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) -// TODO(erg): linux_aura bringup: http://crbug.com/163931 -#define MAYBE_FocusRestore DISABLED_FocusRestore -#else -#define MAYBE_FocusRestore FocusRestore -#endif - -// Flaky because the test server fails to start? See: http://crbug.com/96594. -IN_PROC_BROWSER_TEST_F(FindInPageTest, MAYBE_FocusRestore) { +IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestore) { ASSERT_TRUE(embedded_test_server()->Start()); GURL url = embedded_test_server()->GetURL("/title1.html"); @@ -351,15 +343,7 @@ EXPECT_EQ(ASCIIToUTF16("de"), GetFindBarSelectedText()); } -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) -// TODO(erg): linux_aura bringup: http://crbug.com/163931 -#define MAYBE_FocusRestoreOnTabSwitch DISABLED_FocusRestoreOnTabSwitch -#else -#define MAYBE_FocusRestoreOnTabSwitch FocusRestoreOnTabSwitch -#endif - -// Flaky because the test server fails to start? See: http://crbug.com/96594. -IN_PROC_BROWSER_TEST_F(FindInPageTest, MAYBE_FocusRestoreOnTabSwitch) { +IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestoreOnTabSwitch) { ASSERT_TRUE(embedded_test_server()->Start()); // First we navigate to our test page (tab A).
diff --git a/chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.cc b/chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.cc index 7b5128ef..9addbb1 100644 --- a/chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.cc +++ b/chrome/browser/ui/views/website_settings/chooser_bubble_ui_view.cc
@@ -14,7 +14,7 @@ #include "chrome/browser/chooser_controller/chooser_controller.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/views/chooser_content_view.h" +#include "chrome/browser/ui/views/device_chooser_content_view.h" #include "chrome/browser/ui/views/exclusive_access_bubble_views.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/top_container_view.h" @@ -72,7 +72,7 @@ void UpdateTableView() const; private: - ChooserContentView* chooser_content_view_; + DeviceChooserContentView* device_chooser_content_view_; BubbleReference bubble_reference_; DISALLOW_COPY_AND_ASSIGN(ChooserBubbleUiViewDelegate); @@ -83,7 +83,7 @@ views::BubbleBorder::Arrow anchor_arrow, std::unique_ptr<ChooserController> chooser_controller) : views::BubbleDialogDelegateView(anchor_view, anchor_arrow), - chooser_content_view_(nullptr) { + device_chooser_content_view_(nullptr) { // ------------------------------------ // | Chooser bubble title | // | -------------------------------- | @@ -99,59 +99,59 @@ // | Get help | // ------------------------------------ - chooser_content_view_ = - new ChooserContentView(this, std::move(chooser_controller)); + device_chooser_content_view_ = + new DeviceChooserContentView(this, std::move(chooser_controller)); } ChooserBubbleUiViewDelegate::~ChooserBubbleUiViewDelegate() {} base::string16 ChooserBubbleUiViewDelegate::GetWindowTitle() const { - return chooser_content_view_->GetWindowTitle(); + return device_chooser_content_view_->GetWindowTitle(); } base::string16 ChooserBubbleUiViewDelegate::GetDialogButtonLabel( ui::DialogButton button) const { - return chooser_content_view_->GetDialogButtonLabel(button); + return device_chooser_content_view_->GetDialogButtonLabel(button); } bool ChooserBubbleUiViewDelegate::IsDialogButtonEnabled( ui::DialogButton button) const { - return chooser_content_view_->IsDialogButtonEnabled(button); + return device_chooser_content_view_->IsDialogButtonEnabled(button); } views::View* ChooserBubbleUiViewDelegate::CreateFootnoteView() { - return chooser_content_view_->footnote_link(); + return device_chooser_content_view_->footnote_link(); } bool ChooserBubbleUiViewDelegate::Accept() { - chooser_content_view_->Accept(); + device_chooser_content_view_->Accept(); if (bubble_reference_) bubble_reference_->CloseBubble(BUBBLE_CLOSE_ACCEPTED); return true; } bool ChooserBubbleUiViewDelegate::Cancel() { - chooser_content_view_->Cancel(); + device_chooser_content_view_->Cancel(); if (bubble_reference_) bubble_reference_->CloseBubble(BUBBLE_CLOSE_CANCELED); return true; } bool ChooserBubbleUiViewDelegate::Close() { - chooser_content_view_->Close(); + device_chooser_content_view_->Close(); return true; } views::View* ChooserBubbleUiViewDelegate::GetContentsView() { - return chooser_content_view_; + return device_chooser_content_view_; } views::Widget* ChooserBubbleUiViewDelegate::GetWidget() { - return chooser_content_view_->GetWidget(); + return device_chooser_content_view_->GetWidget(); } const views::Widget* ChooserBubbleUiViewDelegate::GetWidget() const { - return chooser_content_view_->GetWidget(); + return device_chooser_content_view_->GetWidget(); } void ChooserBubbleUiViewDelegate::OnSelectionChanged() { @@ -177,7 +177,7 @@ } void ChooserBubbleUiViewDelegate::UpdateTableView() const { - chooser_content_view_->UpdateTableView(); + device_chooser_content_view_->UpdateTableView(); } //////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/website_settings/chooser_bubble_delegate.h b/chrome/browser/ui/website_settings/chooser_bubble_delegate.h index 6538990..e521b54 100644 --- a/chrome/browser/ui/website_settings/chooser_bubble_delegate.h +++ b/chrome/browser/ui/website_settings/chooser_bubble_delegate.h
@@ -33,9 +33,9 @@ const content::RenderFrameHost* const owning_frame_; Browser* browser_; // |chooser_controller_| is not owned by this class, it is owned by - // ChooserContentView[Cocoa]. + // DeviceChooserContentView[Cocoa]. // This field only temporarily owns the ChooserController. It is moved - // into the ChooserContentView[Cocoa] when BuildBubbleUi() is called + // into the DeviceChooserContentView[Cocoa] when BuildBubbleUi() is called // and the bubble is shown. std::unique_ptr<ChooserController> chooser_controller_;
diff --git a/chrome/renderer/autofill/DEPS b/chrome/renderer/autofill/DEPS new file mode 100644 index 0000000..d7867aa1 --- /dev/null +++ b/chrome/renderer/autofill/DEPS
@@ -0,0 +1,7 @@ +specific_include_rules = { + # TODO(estark): remove this when the Form-Not-Secure feature is fully + # launched. https://crbug.com/677295 + "password_autofill_agent_browsertest\.cc" : [ + "+components/security_state/core", + ], +} \ No newline at end of file
diff --git a/chrome/renderer/autofill/fake_content_password_manager_driver.cc b/chrome/renderer/autofill/fake_content_password_manager_driver.cc index c0fde73..01e700aa 100644 --- a/chrome/renderer/autofill/fake_content_password_manager_driver.cc +++ b/chrome/renderer/autofill/fake_content_password_manager_driver.cc
@@ -58,6 +58,12 @@ show_pw_suggestions_options_ = options; } +void FakeContentPasswordManagerDriver::ShowNotSecureWarning( + base::i18n::TextDirection text_direction, + const gfx::RectF& bounds) { + called_show_not_secure_warning_ = true; +} + void FakeContentPasswordManagerDriver::PasswordAutofillAgentConstructed() { called_agent_constructed_ = true; }
diff --git a/chrome/renderer/autofill/fake_content_password_manager_driver.h b/chrome/renderer/autofill/fake_content_password_manager_driver.h index f7314ba..4388ecd 100644 --- a/chrome/renderer/autofill/fake_content_password_manager_driver.h +++ b/chrome/renderer/autofill/fake_content_password_manager_driver.h
@@ -44,6 +44,10 @@ show_pw_suggestions_options_ = -1; } + bool called_show_not_secure_warning() const { + return called_show_not_secure_warning_; + } + bool called_password_form_submitted() const { return called_password_form_submitted_; } @@ -135,6 +139,9 @@ int options, const gfx::RectF& bounds) override; + void ShowNotSecureWarning(base::i18n::TextDirection text_direction, + const gfx::RectF& bounds) override; + void PasswordAutofillAgentConstructed() override; void RecordSavePasswordProgress(const std::string& log) override; @@ -149,6 +156,8 @@ int show_pw_suggestions_key_ = -1; base::Optional<base::string16> show_pw_suggestions_username_; int show_pw_suggestions_options_ = -1; + // Records whether ShowNotSecureWarning() gets called. + bool called_show_not_secure_warning_ = false; // Records whether PasswordFormSubmitted() gets called. bool called_password_form_submitted_ = false; // Records data received via PasswordFormSubmitted() call.
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index 106aab9a..c598b75 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -23,6 +23,7 @@ #include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form_field_prediction_map.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/security_state/core/security_state.h" #include "content/public/common/associated_interface_provider.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" @@ -351,6 +352,11 @@ password_manager::features::kFillOnAccountSelect); } + void SetHttpFormWarning() { + scoped_feature_list_.InitAndEnableFeature( + security_state::kHttpFormWarningFeature); + } + void UpdateOriginForHTML(const std::string& html) { std::string origin = "data:text/html;charset=utf-8," + html; fill_data_.origin = GURL(origin); @@ -483,6 +489,11 @@ return fake_driver_.called_show_pw_suggestions(); } + bool GetCalledShowNotSecureWarning() { + base::RunLoop().RunUntilIdle(); + return fake_driver_.called_show_not_secure_warning(); + } + void ExpectFormSubmittedWithUsernameAndPasswords( const std::string& username_value, const std::string& password_value, @@ -1356,6 +1367,30 @@ ClearUsernameAndPasswordFields(); } +// Tests that the Form Not Secure warning appears when a password form +// is autofilled when the Form Not Secure feature is enabled. +TEST_F(PasswordAutofillAgentTest, FormNotSecureWarningOnAutofill) { + SetHttpFormWarning(); + + fill_data_.show_form_not_secure_warning_on_autofill = true; + + // Simulate the browser autofilling a password form. + SimulateOnFillPasswordForm(fill_data_); + EXPECT_TRUE(GetCalledShowNotSecureWarning()); +} + +// Tests that the Form Not Secure warning does not appear when the +// PasswordFormFillData does not indicate that it should show. +TEST_F(PasswordAutofillAgentTest, FormNotSecureWarningNotShownOnAutofill) { + SetHttpFormWarning(); + + fill_data_.show_form_not_secure_warning_on_autofill = false; + + // Simulate the browser autofilling a password form. + SimulateOnFillPasswordForm(fill_data_); + EXPECT_FALSE(GetCalledShowNotSecureWarning()); +} + // Tests that there is an autosuggestion from the password manager when the // user clicks on the password field when FillOnAccountSelect is enabled. TEST_F(PasswordAutofillAgentTest,
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c045169..854518e 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4760,8 +4760,8 @@ "../browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc", "../browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc", "../browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc", - "../browser/ui/views/chooser_content_view_unittest.cc", "../browser/ui/views/confirm_bubble_views_unittest.cc", + "../browser/ui/views/device_chooser_content_view_unittest.cc", "../browser/ui/views/download/download_item_view_unittest.cc", "../browser/ui/views/extensions/chooser_dialog_view_unittest.cc", "../browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc",
diff --git a/chrome/test/data/extensions/api_test/tab_capture/fullscreen_test.js b/chrome/test/data/extensions/api_test/tab_capture/fullscreen_test.js index 00897c0..7c54fe3 100644 --- a/chrome/test/data/extensions/api_test/tab_capture/fullscreen_test.js +++ b/chrome/test/data/extensions/api_test/tab_capture/fullscreen_test.js
@@ -2,77 +2,49 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -window.addEventListener('load', () => { - // Register the fullscreen change listener. This is used to determine when to - // signal the C++ side of this test that the document has entered/exited - // fullscreen. NOTE: It's very important NOT to use the - // tabCapture.onStatusChanged listener to signal the C++ side of this test - // because sometimes the document's fullscreen state change lags behind what - // the tabCapture API knows about the browser window's fullscreen state. - // Otherwise, the C++ side of this test might proceed out-of-sync and fail. - // http://crbug.com/675851 - if (document.fullscreenEnabled) { - document.onfullscreenchange = () => { - if (document.fullscreenElement) - chrome.test.sendMessage('entered_fullscreen'); - }; - } else if (document.webkitFullscreenEnabled) { - document.onwebkitfullscreenchange = () => { - if (document.webkitFullscreenElement) - chrome.test.sendMessage('entered_fullscreen'); - }; - } else { - chrome.test.assertTrue(!'HTML5 Fullscreen API missing'); - } - - // Register an onclick listener that toggles the entire document into or - // out-of fullscreen mode. The clicks are generated by the C++ side of this - // test. - document.documentElement.onclick = () => { +window.addEventListener('load', function() { + document.body.onclick = function toggleBodyFullscreen() { if (document.fullscreenElement || document.webkitFullscreenElement) { if (document.exitFullscreen) document.exitFullscreen(); else if (document.webkitExitFullscreen) document.webkitExitFullscreen(); else - chrome.test.assertTrue(!'HTML5 Fullscreen API missing'); + chrome.test.assertTrue(!"HTML5 Fullscreen API missing"); } else { - if (document.documentElement.requestFullscreen) - document.documentElement.requestFullscreen(); - else if (document.documentElement.webkitRequestFullscreen) - document.documentElement.webkitRequestFullscreen(); + if (document.body.requestFullscreen) + document.body.requestFullscreen(); + else if (document.body.webkitRequestFullscreen) + document.body.webkitRequestFullscreen(); else - chrome.test.assertTrue(!'HTML5 Fullscreen API missing'); + chrome.test.assertTrue(!"HTML5 Fullscreen API missing"); } }; +}); - let mediaStream = null; - const events = []; +var mediaStream = null; +var events = []; - // Register the tab capture status change listener, which records the changes - // to fullscreen state according to the tab capture API implementation. Once - // there are three changes, check the results and succeed() the test. - chrome.tabCapture.onStatusChanged.addListener(info => { - if (info.status == 'active') { - events.push(info.fullscreen); - if (events.length == 3) { - mediaStream.getVideoTracks()[0].stop(); - mediaStream.getAudioTracks()[0].stop(); - chrome.test.assertFalse(events[0]); - chrome.test.assertTrue(events[1]); - chrome.test.assertFalse(events[2]); - chrome.test.succeed(); - } +chrome.tabCapture.onStatusChanged.addListener(function(info) { + if (info.status == 'active') { + events.push(info.fullscreen); + if (events.length == 3) { + chrome.test.assertFalse(events[0]); + chrome.test.assertTrue(events[1]); + chrome.test.assertFalse(events[2]); + mediaStream.getVideoTracks()[0].stop(); + mediaStream.getAudioTracks()[0].stop(); + chrome.test.succeed(); } - }); - // Now that all listeners are in-place, start tab capture. Once tab capture is - // running, notify the C++ side of this test that it may commence with the - // "fullscreen toggle mouse clicks." - chrome.tabCapture.capture({audio: true, video: true}, stream => { - chrome.test.assertTrue(!!stream); - mediaStream = stream; - chrome.test.notifyPass(); - chrome.test.sendMessage('tab_capture_started'); - }); + if (info.fullscreen) + chrome.test.sendMessage('entered_fullscreen'); + } +}); + +chrome.tabCapture.capture({audio: true, video: true}, function(stream) { + chrome.test.assertTrue(!!stream); + mediaStream = stream; + chrome.test.notifyPass(); + chrome.test.sendMessage('tab_capture_started'); });
diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java index adb7e26..56475a3 100644 --- a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java +++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java
@@ -7,7 +7,7 @@ import android.annotation.SuppressLint; import android.graphics.Typeface; import android.os.Build; -import android.support.graphics.drawable.VectorDrawableCompat; +import android.support.v7.content.res.AppCompatResources; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -72,15 +72,15 @@ assert !TextUtils.isEmpty(suggestion.getLabel()); View touchTarget; - if (!suggestion.isFillable() && suggestion.getVectorDrawableIconId() != 0) { + if (!suggestion.isFillable() && suggestion.getIconId() != 0) { touchTarget = LayoutInflater.from(getContext()).inflate( R.layout.autofill_keyboard_accessory_icon, this, false); if (separatorPosition == -1) separatorPosition = i; ImageView icon = (ImageView) touchTarget; - icon.setImageDrawable(VectorDrawableCompat.create(getResources(), - suggestion.getVectorDrawableIconId(), getContext().getTheme())); + icon.setImageDrawable( + AppCompatResources.getDrawable(getContext(), suggestion.getIconId())); icon.setContentDescription(suggestion.getLabel()); } else { touchTarget = LayoutInflater.from(getContext()).inflate( @@ -98,11 +98,11 @@ label.setTypeface(Typeface.DEFAULT_BOLD); } - if (suggestion.getVectorDrawableIconId() != 0) { + if (suggestion.getIconId() != 0) { ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds( - label, VectorDrawableCompat.create(getResources(), - suggestion.getVectorDrawableIconId(), getContext().getTheme()), - null /* top */, null /* end */, null /* bottom */); + label, + AppCompatResources.getDrawable(getContext(), suggestion.getIconId()), + null /* top */, null /* end */, null /* bottom */); } if (!TextUtils.isEmpty(suggestion.getSublabel())) {
diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java index 2262fd7..ec5efc7e 100644 --- a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java +++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java
@@ -28,11 +28,12 @@ /** * Constructs a Autofill suggestion container. + * * @param label The main label of the Autofill suggestion. * @param sublabel The describing sublabel of the Autofill suggestion. * @param iconId The resource ID for the icon associated with the suggestion, or - * {@code DropdownItem.NO_ICON} for no icon. - * @param isIconAtStart {@code true} if {@param iconId} is displayed before {@param label}. + * {@code DropdownItem.NO_ICON} for no icon. + * @param isIconAtStart {@code true} if {@code iconId} is displayed before {@code label}. * @param suggestionId The type of suggestion. * @param isDeletable Whether the item can be deleted by the user. * @param isMultilineLabel Whether the label is displayed over multiple lines. @@ -61,7 +62,7 @@ } @Override - public int getVectorDrawableIconId() { + public int getIconId() { return mIconId; }
diff --git a/components/autofill/content/common/autofill_driver.mojom b/components/autofill/content/common/autofill_driver.mojom index 8fb379d..b0da5fd 100644 --- a/components/autofill/content/common/autofill_driver.mojom +++ b/components/autofill/content/common/autofill_driver.mojom
@@ -95,6 +95,11 @@ mojo.common.mojom.String16 typed_username, int32 options, gfx.mojom.RectF bounds); + // Instructs the browser to show a popup with a warning that the form + // is not secure. The popup will use |text_direction| for displaying + // text. This popup is shown when a password form on a non-secure page is + // autofilled on page load. + ShowNotSecureWarning(TextDirection text_direction, gfx.mojom.RectF bounds); // Instructs the browser to presave the form with generated password. PresaveGeneratedPassword(PasswordForm password_form);
diff --git a/components/autofill/content/common/autofill_types.mojom b/components/autofill/content/common/autofill_types.mojom index 55a34df..3795d25 100644 --- a/components/autofill/content/common/autofill_types.mojom +++ b/components/autofill/content/common/autofill_types.mojom
@@ -146,6 +146,7 @@ array<array<string>> other_possible_usernames_values; bool wait_for_username; bool is_possible_change_password_form; + bool show_form_not_secure_warning_on_autofill; }; // autofill::PasswordFormGenerationData
diff --git a/components/autofill/content/common/autofill_types_struct_traits.cc b/components/autofill/content/common/autofill_types_struct_traits.cc index 81e2fb47..41a5bcc 100644 --- a/components/autofill/content/common/autofill_types_struct_traits.cc +++ b/components/autofill/content/common/autofill_types_struct_traits.cc
@@ -502,6 +502,8 @@ out->wait_for_username = data.wait_for_username(); out->is_possible_change_password_form = data.is_possible_change_password_form(); + out->show_form_not_secure_warning_on_autofill = + data.show_form_not_secure_warning_on_autofill(); return true; }
diff --git a/components/autofill/content/common/autofill_types_struct_traits.h b/components/autofill/content/common/autofill_types_struct_traits.h index 8e2f740..954c2e1 100644 --- a/components/autofill/content/common/autofill_types_struct_traits.h +++ b/components/autofill/content/common/autofill_types_struct_traits.h
@@ -358,6 +358,11 @@ return r.is_possible_change_password_form; } + static bool show_form_not_secure_warning_on_autofill( + const autofill::PasswordFormFillData& r) { + return r.show_form_not_secure_warning_on_autofill; + } + static bool Read(autofill::mojom::PasswordFormFillDataDataView data, autofill::PasswordFormFillData* out); };
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index 65e411aa..28340cb 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -573,6 +573,15 @@ ShowSuggestions(element, options); } +void AutofillAgent::ShowNotSecureWarning( + const blink::WebInputElement& element) { + if (is_generation_popup_possibly_visible_) + return; + HidePopup(); + password_autofill_agent_->ShowNotSecureWarning(element); + is_popup_possibly_visible_ = true; +} + void AutofillAgent::OnSamePageNavigationCompleted() { if (last_interacted_form_.isNull()) { // If no last interacted form is available (i.e., there is no form tag),
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h index 94f746d..b2718da 100644 --- a/components/autofill/content/renderer/autofill_agent.h +++ b/components/autofill/content/renderer/autofill_agent.h
@@ -83,6 +83,8 @@ int32_t key, const PasswordFormFillData& form_data) override; + void ShowNotSecureWarning(const blink::WebInputElement& element); + protected: // blink::WebAutofillClient: void didAssociateFormControlsDynamically() override;
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 9357387..8c943d20 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -886,6 +886,16 @@ element.isPasswordField()); } +void PasswordAutofillAgent::ShowNotSecureWarning( + const blink::WebInputElement& element) { + FormData form; + FormFieldData field; + form_util::FindFormAndFieldForFormControlElement(element, &form, &field); + GetPasswordManagerDriver()->ShowNotSecureWarning( + field.text_direction, + render_frame()->GetRenderView()->ElementBoundsInWindow(element)); +} + bool PasswordAutofillAgent::OriginCanAccessPasswordManager( const blink::WebSecurityOrigin& origin) { return origin.canAccessPasswordManager(); @@ -1249,12 +1259,15 @@ element.isPasswordField() ? element : web_input_to_password_info_[element].password_field; - FillFormOnPasswordReceived( - form_data, username_element, password_element, - &field_value_and_properties_map_, - base::Bind(&PasswordValueGatekeeper::RegisterElement, - base::Unretained(&gatekeeper_)), - logger.get()); + if (FillFormOnPasswordReceived( + form_data, username_element, password_element, + &field_value_and_properties_map_, + base::Bind(&PasswordValueGatekeeper::RegisterElement, + base::Unretained(&gatekeeper_)), + logger.get())) { + if (form_data.show_form_not_secure_warning_on_autofill) + autofill_agent_->ShowNotSecureWarning(username_element); + } } }
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h index f120127..b6e31cd 100644 --- a/components/autofill/content/renderer/password_autofill_agent.h +++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -94,6 +94,11 @@ bool show_all, bool generation_popup_showing); + // Shows an Autofill popup with a warning that the form is not + // secure. This is an experimental UI that is shown when a password + // field is autofilled on a non-secure page on page load. + void ShowNotSecureWarning(const blink::WebInputElement& element); + // Called when new form controls are inserted. void OnDynamicFormsSeen();
diff --git a/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc b/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc index 7c0c27e..0c514e8f 100644 --- a/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc +++ b/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc
@@ -61,6 +61,9 @@ int options, const gfx::RectF& bounds) override {} + void ShowNotSecureWarning(base::i18n::TextDirection text_direction, + const gfx::RectF& bounds) override {} + void PasswordAutofillAgentConstructed() override {} void RecordSavePasswordProgress(const std::string& log) override {
diff --git a/components/autofill/core/common/password_form_fill_data.cc b/components/autofill/core/common/password_form_fill_data.cc index b4d5fd04..014a24e 100644 --- a/components/autofill/core/common/password_form_fill_data.cc +++ b/components/autofill/core/common/password_form_fill_data.cc
@@ -23,8 +23,8 @@ PasswordFormFillData::PasswordFormFillData() : wait_for_username(false), - is_possible_change_password_form(false) { -} + is_possible_change_password_form(false), + show_form_not_secure_warning_on_autofill(false) {} PasswordFormFillData::PasswordFormFillData(const PasswordFormFillData& other) = default;
diff --git a/components/autofill/core/common/password_form_fill_data.h b/components/autofill/core/common/password_form_fill_data.h index fd0f64fe..91798eda 100644 --- a/components/autofill/core/common/password_form_fill_data.h +++ b/components/autofill/core/common/password_form_fill_data.h
@@ -75,6 +75,10 @@ // True if this form is a change password form. bool is_possible_change_password_form; + // True if a "form not secure" warning should be shown when the form is + // autofilled. + bool show_form_not_secure_warning_on_autofill; + PasswordFormFillData(); PasswordFormFillData(const PasswordFormFillData& other); ~PasswordFormFillData();
diff --git a/components/data_use_measurement/content/BUILD.gn b/components/data_use_measurement/content/BUILD.gn index 999bc02..b9c18ae 100644 --- a/components/data_use_measurement/content/BUILD.gn +++ b/components/data_use_measurement/content/BUILD.gn
@@ -10,6 +10,7 @@ deps = [ "//base", "//content/public/browser", + "//content/public/common", "//net:net", ] }
diff --git a/components/data_use_measurement/content/DEPS b/components/data_use_measurement/content/DEPS index 8c57389..8dbf71c 100644 --- a/components/data_use_measurement/content/DEPS +++ b/components/data_use_measurement/content/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+content/public/browser", + "+content/public/common", "+net", ]
diff --git a/components/data_use_measurement/content/content_url_request_classifier.cc b/components/data_use_measurement/content/content_url_request_classifier.cc index 23bbd8b..2c723b6 100644 --- a/components/data_use_measurement/content/content_url_request_classifier.cc +++ b/components/data_use_measurement/content/content_url_request_classifier.cc
@@ -4,7 +4,12 @@ #include "components/data_use_measurement/content/content_url_request_classifier.h" +#include <string> + +#include "base/strings/string_util.h" #include "content/public/browser/resource_request_info.h" +#include "content/public/common/resource_type.h" +#include "net/http/http_response_headers.h" #include "net/url_request/url_request.h" namespace data_use_measurement { @@ -26,4 +31,40 @@ return data_use_measurement::IsUserRequest(request); } +DataUseUserData::DataUseContentType ContentURLRequestClassifier::GetContentType( + const net::URLRequest& request, + const net::HttpResponseHeaders& response_headers) const { + const content::ResourceRequestInfo* request_info = + content::ResourceRequestInfo::ForRequest(&request); + std::string mime_type; + if (response_headers.GetMimeType(&mime_type)) { + if (mime_type == "text/html" && request_info && + request_info->GetResourceType() == + content::ResourceType::RESOURCE_TYPE_MAIN_FRAME) { + return DataUseUserData::MAIN_FRAME_HTML; + } else if (mime_type == "text/html") { + return DataUseUserData::NON_MAIN_FRAME_HTML; + } else if (mime_type == "text/css") { + return DataUseUserData::CSS; + } else if (base::StartsWith(mime_type, "image/", + base::CompareCase::SENSITIVE)) { + return DataUseUserData::IMAGE; + } else if (base::EndsWith(mime_type, "javascript", + base::CompareCase::SENSITIVE) || + base::EndsWith(mime_type, "ecmascript", + base::CompareCase::SENSITIVE)) { + return DataUseUserData::JAVASCRIPT; + } else if (mime_type.find("font") != std::string::npos) { + return DataUseUserData::FONT; + } else if (base::StartsWith(mime_type, "audio/", + base::CompareCase::SENSITIVE)) { + return DataUseUserData::AUDIO; + } else if (base::StartsWith(mime_type, "video/", + base::CompareCase::SENSITIVE)) { + return DataUseUserData::VIDEO; + } + } + return DataUseUserData::OTHER; +} + } // namespace data_use_measurement
diff --git a/components/data_use_measurement/content/content_url_request_classifier.h b/components/data_use_measurement/content/content_url_request_classifier.h index 2e102bb..8b978fe 100644 --- a/components/data_use_measurement/content/content_url_request_classifier.h +++ b/components/data_use_measurement/content/content_url_request_classifier.h
@@ -19,6 +19,10 @@ class ContentURLRequestClassifier : public URLRequestClassifier { public: bool IsUserRequest(const net::URLRequest& request) const override; + + DataUseUserData::DataUseContentType GetContentType( + const net::URLRequest& request, + const net::HttpResponseHeaders& response_headers) const override; }; } // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_ascriber.cc b/components/data_use_measurement/core/data_use_ascriber.cc index 48d0adf..c7c9d490 100644 --- a/components/data_use_measurement/core/data_use_ascriber.cc +++ b/components/data_use_measurement/core/data_use_ascriber.cc
@@ -10,6 +10,7 @@ #include "components/data_use_measurement/core/data_use_network_delegate.h" #include "components/data_use_measurement/core/data_use_recorder.h" #include "components/data_use_measurement/core/url_request_classifier.h" +#include "net/http/http_response_headers.h" namespace data_use_measurement {
diff --git a/components/data_use_measurement/core/data_use_measurement.cc b/components/data_use_measurement/core/data_use_measurement.cc index 6508f99..4408bc3 100644 --- a/components/data_use_measurement/core/data_use_measurement.cc +++ b/components/data_use_measurement/core/data_use_measurement.cc
@@ -103,11 +103,13 @@ // Detect if the request originated from DomainReliability. // DataUseUserData::AttachToFetcher() cannot be called from domain // reliability, since it sets userdata on URLFetcher for its purposes. - service_name = DataUseUserData::ServiceName::NOT_TAGGED; + service_name = DataUseUserData::ServiceName::DOMAIN_RELIABILITY; } data_use_user_data = new DataUseUserData(service_name, CurrentAppState()); request->SetUserData(DataUseUserData::kUserDataKey, data_use_user_data); + } else { + data_use_user_data->set_app_state(CurrentAppState()); } } @@ -119,6 +121,17 @@ ReportServicesMessageSizeUMA(request); } +void DataUseMeasurement::OnHeadersReceived( + net::URLRequest* request, + const net::HttpResponseHeaders* response_headers) { + DataUseUserData* data_use_user_data = reinterpret_cast<DataUseUserData*>( + request->GetUserData(DataUseUserData::kUserDataKey)); + if (data_use_user_data) { + data_use_user_data->set_content_type( + url_request_classifier_->GetContentType(*request, *response_headers)); + } +} + void DataUseMeasurement::OnNetworkBytesReceived(const net::URLRequest& request, int64_t bytes_received) { UMA_HISTOGRAM_COUNTS("DataUse.BytesReceived.Delegate", bytes_received); @@ -196,13 +209,22 @@ } #endif + bool is_tab_visible = false; + if (is_user_traffic) { const DataUseRecorder* recorder = ascriber_->GetDataUseRecorder(request); if (recorder) { + is_tab_visible = recorder->is_visible(); RecordTabStateHistogram(dir, new_app_state, recorder->is_visible(), bytes); } } + if (attached_service_data && dir == DOWNSTREAM && + new_app_state != DataUseUserData::UNKNOWN) { + RecordContentTypeHistogram(attached_service_data->content_type(), + is_user_traffic, new_app_state, is_tab_visible, + bytes); + } } void DataUseMeasurement::UpdateDataUsePrefs( @@ -363,4 +385,40 @@ RecordUMAHistogramCount(histogram_name, bytes); } +void DataUseMeasurement::RecordContentTypeHistogram( + DataUseUserData::DataUseContentType content_type, + bool is_user_traffic, + DataUseUserData::AppState app_state, + bool is_tab_visible, + int64_t bytes) { + if (content_type == DataUseUserData::AUDIO) { + content_type = app_state != DataUseUserData::FOREGROUND + ? DataUseUserData::AUDIO_APPBACKGROUND + : (!is_tab_visible ? DataUseUserData::AUDIO_TABBACKGROUND + : DataUseUserData::AUDIO); + } else if (content_type == DataUseUserData::VIDEO) { + content_type = app_state != DataUseUserData::FOREGROUND + ? DataUseUserData::VIDEO_APPBACKGROUND + : (!is_tab_visible ? DataUseUserData::VIDEO_TABBACKGROUND + : DataUseUserData::VIDEO); + } + // Use the more primitive STATIC_HISTOGRAM_POINTER_BLOCK macro because the + // simple UMA_HISTOGRAM_ENUMERATION macros don't expose 'AddCount'. + if (is_user_traffic) { + STATIC_HISTOGRAM_POINTER_BLOCK( + "DataUse.ContentType.UserTraffic", AddCount(content_type, bytes), + base::LinearHistogram::FactoryGet( + "DataUse.ContentType.UserTraffic", 1, DataUseUserData::TYPE_MAX, + DataUseUserData::TYPE_MAX + 1, + base::HistogramBase::kUmaTargetedHistogramFlag)); + } else { + STATIC_HISTOGRAM_POINTER_BLOCK( + "DataUse.ContentType.Services", AddCount(content_type, bytes), + base::LinearHistogram::FactoryGet( + "DataUse.ContentType.Services", 1, DataUseUserData::TYPE_MAX, + DataUseUserData::TYPE_MAX + 1, + base::HistogramBase::kUmaTargetedHistogramFlag)); + } +} + } // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_measurement.h b/components/data_use_measurement/core/data_use_measurement.h index ffd64f71..a0e4298 100644 --- a/components/data_use_measurement/core/data_use_measurement.h +++ b/components/data_use_measurement/core/data_use_measurement.h
@@ -24,6 +24,7 @@ class GURL; namespace net { +class HttpResponseHeaders; class URLRequest; } @@ -53,6 +54,10 @@ void OnBeforeRedirect(const net::URLRequest& request, const GURL& new_location); + // Called when response headers are received for |request|. + void OnHeadersReceived(net::URLRequest* request, + const net::HttpResponseHeaders* response_headers); + // Called when data is received or sent on the network, respectively. void OnNetworkBytesReceived(const net::URLRequest& request, int64_t bytes_received); @@ -137,6 +142,15 @@ bool is_tab_visible, int64_t bytes); + // Records data use histograms of user traffic and services traffic split on + // content type, AppState and TabState. + void RecordContentTypeHistogram( + DataUseUserData::DataUseContentType content_type, + bool is_user_traffic, + DataUseUserData::AppState app_state, + bool is_tab_visible, + int64_t bytes); + // Classifier for identifying if an URL request is user initiated. std::unique_ptr<URLRequestClassifier> url_request_classifier_;
diff --git a/components/data_use_measurement/core/data_use_measurement_unittest.cc b/components/data_use_measurement/core/data_use_measurement_unittest.cc index cf0827e..39429f9 100644 --- a/components/data_use_measurement/core/data_use_measurement_unittest.cc +++ b/components/data_use_measurement/core/data_use_measurement_unittest.cc
@@ -30,18 +30,33 @@ namespace data_use_measurement { -class UserRequestUserDataForTesting : public base::SupportsUserData::Data, - public URLRequestClassifier { +class TestURLRequestClassifier : public base::SupportsUserData::Data, + public URLRequestClassifier { public: static const void* const kUserDataKey; + TestURLRequestClassifier() : content_type_(DataUseUserData::OTHER) {} + bool IsUserRequest(const net::URLRequest& request) const override { return request.GetUserData(kUserDataKey) != nullptr; } static void MarkAsUserRequest(net::URLRequest* request) { - request->SetUserData(kUserDataKey, new UserRequestUserDataForTesting()); + request->SetUserData(kUserDataKey, new TestURLRequestClassifier()); } + + DataUseUserData::DataUseContentType GetContentType( + const net::URLRequest& request, + const net::HttpResponseHeaders& response_headers) const override { + return content_type_; + } + + void set_content_type(DataUseUserData::DataUseContentType content_type) { + content_type_ = content_type; + } + + private: + DataUseUserData::DataUseContentType content_type_; }; class TestDataUseAscriber : public DataUseAscriber { @@ -69,26 +84,27 @@ }; // The more usual initialization of kUserDataKey would be along the lines of -// const void* const UserRequestUserDataForTesting::kUserDataKey = -// &UserRequestUserDataForTesting::kUserDataKey; +// const void* const TestURLRequestClassifier::kUserDataKey = +// &TestURLRequestClassifier::kUserDataKey; // but lld's identical constant folding then folds that with // DataUseUserData::kUserDataKey which is initialized like that as well, and -// then UserRequestUserDataForTesting::IsUserRequest() starts classifying -// service requests as user requests. To work around this, make -// UserRequestUserDataForTesting::kUserDataKey point to an arbitrary integer +// then TestURLRequestClassifier::IsUserRequest() starts classifying service +// requests as user requests. To work around this, make +// TestURLRequestClassifier::kUserDataKey point to an arbitrary integer // instead. // TODO(thakis): If we changed lld to only ICF over code and not over data, // we could undo this again. const int kICFBuster = 12345634; // static -const void* const UserRequestUserDataForTesting::kUserDataKey = &kICFBuster; +const void* const TestURLRequestClassifier::kUserDataKey = &kICFBuster; class DataUseMeasurementTest : public testing::Test { public: DataUseMeasurementTest() - : data_use_measurement_( - base::MakeUnique<UserRequestUserDataForTesting>(), + : url_request_classifier_(new TestURLRequestClassifier()), + data_use_measurement_( + std::unique_ptr<URLRequestClassifier>(url_request_classifier_), base::Bind(&DataUseMeasurementTest::FakeDataUseforwarder, base::Unretained(this)), &ascriber_) { @@ -113,7 +129,7 @@ std::unique_ptr<net::URLRequest> request(context_->CreateRequest( GURL("http://foo.com"), net::DEFAULT_PRIORITY, &test_delegate)); if (is_user_request == kUserRequest) { - UserRequestUserDataForTesting::MarkAsUserRequest(request.get()); + TestURLRequestClassifier::MarkAsUserRequest(request.get()); } else { request->SetUserData( data_use_measurement::DataUseUserData::kUserDataKey, @@ -195,6 +211,7 @@ base::MessageLoopForIO loop_; TestDataUseAscriber ascriber_; + TestURLRequestClassifier* url_request_classifier_; DataUseMeasurement data_use_measurement_; std::unique_ptr<net::MockClientSocketFactory> socket_factory_; @@ -407,7 +424,6 @@ // First network access changes the app state to UNKNOWN and the next nextwork // access changes to BACKGROUND. data_use_measurement_.OnNetworkBytesReceived(*request, 1000); - data_use_measurement_.OnNetworkBytesReceived(*request, 1000); data_use_measurement_.OnNetworkBytesSent(*request, 100); histogram_tester.ExpectTotalCount( @@ -415,6 +431,75 @@ histogram_tester.ExpectTotalCount( "DataUse.AppTabState.Downstream.AppBackground", 1); } + +TEST_F(DataUseMeasurementTest, ContentType) { + { + base::HistogramTester histogram_tester; + std::unique_ptr<net::URLRequest> request = CreateTestRequest(kUserRequest); + data_use_measurement_.OnBeforeURLRequest(request.get()); + data_use_measurement_.OnNetworkBytesReceived(*request, 1000); + histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTraffic", + DataUseUserData::OTHER, 1000); + } + + { + base::HistogramTester histogram_tester; + std::unique_ptr<net::URLRequest> request = + CreateTestRequest(kServiceRequest); + data_use_measurement_.OnBeforeURLRequest(request.get()); + data_use_measurement_.OnNetworkBytesReceived(*request, 1000); + histogram_tester.ExpectUniqueSample("DataUse.ContentType.Services", + DataUseUserData::OTHER, 1000); + } + + // Video request in foreground. + { + base::HistogramTester histogram_tester; + std::unique_ptr<net::URLRequest> request = CreateTestRequest(kUserRequest); + + ascriber_.SetTabVisibility(true); + url_request_classifier_->set_content_type(DataUseUserData::VIDEO); + data_use_measurement_.OnBeforeURLRequest(request.get()); + data_use_measurement_.OnHeadersReceived(request.get(), nullptr); + data_use_measurement_.OnNetworkBytesReceived(*request, 1000); + + histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTraffic", + DataUseUserData::VIDEO, 1000); + } + + // Audio request from background tab. + { + base::HistogramTester histogram_tester; + std::unique_ptr<net::URLRequest> request = CreateTestRequest(kUserRequest); + ascriber_.SetTabVisibility(false); + url_request_classifier_->set_content_type(DataUseUserData::AUDIO); + data_use_measurement_.OnBeforeURLRequest(request.get()); + data_use_measurement_.OnHeadersReceived(request.get(), nullptr); + data_use_measurement_.OnNetworkBytesReceived(*request, 1000); + + histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTraffic", + DataUseUserData::AUDIO_TABBACKGROUND, + 1000); + } + + // Video request from background app. + { + base::HistogramTester histogram_tester; + std::unique_ptr<net::URLRequest> request = CreateTestRequest(kUserRequest); + url_request_classifier_->set_content_type(DataUseUserData::VIDEO); + data_use_measurement()->OnApplicationStateChangeForTesting( + base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES); + ascriber_.SetTabVisibility(false); + data_use_measurement_.OnBeforeURLRequest(request.get()); + data_use_measurement_.OnHeadersReceived(request.get(), nullptr); + data_use_measurement_.OnNetworkBytesReceived(*request, 1000); + + histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTraffic", + DataUseUserData::VIDEO_APPBACKGROUND, + 1000); + } +} + #endif } // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_network_delegate.cc b/components/data_use_measurement/core/data_use_network_delegate.cc index 87836dc..0229787 100644 --- a/components/data_use_measurement/core/data_use_network_delegate.cc +++ b/components/data_use_measurement/core/data_use_network_delegate.cc
@@ -41,6 +41,15 @@ data_use_measurement_.OnBeforeRedirect(*request, new_location); } +void DataUseNetworkDelegate::OnHeadersReceivedInternal( + net::URLRequest* request, + const net::CompletionCallback& callback, + const net::HttpResponseHeaders* original_response_headers, + scoped_refptr<net::HttpResponseHeaders>* override_response_headers, + GURL* allowed_unsafe_redirect_url) { + data_use_measurement_.OnHeadersReceived(request, original_response_headers); +} + void DataUseNetworkDelegate::OnNetworkBytesReceivedInternal( net::URLRequest* request, int64_t bytes_received) {
diff --git a/components/data_use_measurement/core/data_use_network_delegate.h b/components/data_use_measurement/core/data_use_network_delegate.h index 1aea4e6..014c683 100644 --- a/components/data_use_measurement/core/data_use_network_delegate.h +++ b/components/data_use_measurement/core/data_use_network_delegate.h
@@ -45,6 +45,13 @@ void OnBeforeRedirectInternal(net::URLRequest* request, const GURL& new_location) override; + void OnHeadersReceivedInternal( + net::URLRequest* request, + const net::CompletionCallback& callback, + const net::HttpResponseHeaders* original_response_headers, + scoped_refptr<net::HttpResponseHeaders>* override_response_headers, + GURL* allowed_unsafe_redirect_url) override; + void OnNetworkBytesReceivedInternal(net::URLRequest* request, int64_t bytes_received) override;
diff --git a/components/data_use_measurement/core/data_use_network_delegate_unittest.cc b/components/data_use_measurement/core/data_use_network_delegate_unittest.cc index 59c4554..53d585b 100644 --- a/components/data_use_measurement/core/data_use_network_delegate_unittest.cc +++ b/components/data_use_measurement/core/data_use_network_delegate_unittest.cc
@@ -21,8 +21,8 @@ namespace { -class UserRequestUserDataForTesting : public base::SupportsUserData::Data, - public URLRequestClassifier { +class TestURLRequestClassifier : public base::SupportsUserData::Data, + public URLRequestClassifier { public: static const void* const kUserDataKey; @@ -31,7 +31,13 @@ } static void MarkAsUserRequest(net::URLRequest* request) { - request->SetUserData(kUserDataKey, new UserRequestUserDataForTesting()); + request->SetUserData(kUserDataKey, new TestURLRequestClassifier()); + } + + DataUseUserData::DataUseContentType GetContentType( + const net::URLRequest& request, + const net::HttpResponseHeaders& response_headers) const override { + return DataUseUserData::OTHER; } }; @@ -54,8 +60,8 @@ }; // static -const void* const UserRequestUserDataForTesting::kUserDataKey = - &UserRequestUserDataForTesting::kUserDataKey; +const void* const TestURLRequestClassifier::kUserDataKey = + &TestURLRequestClassifier::kUserDataKey; // This function requests a URL, and makes it return a known response. If // |from_user| is true, it attaches a ResourceRequestInfo to the URLRequest, @@ -92,7 +98,7 @@ GURL("http://example.com"), net::DEFAULT_PRIORITY, &test_delegate)); if (from_user) { - UserRequestUserDataForTesting::MarkAsUserRequest(request.get()); + TestURLRequestClassifier::MarkAsUserRequest(request.get()); } else { request->SetUserData( data_use_measurement::DataUseUserData::kUserDataKey, @@ -109,11 +115,10 @@ public: DataUseNetworkDelegateTest() : context_(true), - data_use_network_delegate_( - base::MakeUnique<net::TestNetworkDelegate>(), - &test_data_use_ascriber_, - base::MakeUnique<UserRequestUserDataForTesting>(), - metrics::UpdateUsagePrefCallbackType()) { + data_use_network_delegate_(base::MakeUnique<net::TestNetworkDelegate>(), + &test_data_use_ascriber_, + base::MakeUnique<TestURLRequestClassifier>(), + metrics::UpdateUsagePrefCallbackType()) { context_.set_client_socket_factory(&mock_socket_factory_); context_.set_network_delegate(&data_use_network_delegate_); context_.Init();
diff --git a/components/data_use_measurement/core/data_use_user_data.cc b/components/data_use_measurement/core/data_use_user_data.cc index 6c968166..ae86b2e3 100644 --- a/components/data_use_measurement/core/data_use_user_data.cc +++ b/components/data_use_measurement/core/data_use_user_data.cc
@@ -29,7 +29,9 @@ } // namespace DataUseUserData::DataUseUserData(ServiceName service_name, AppState app_state) - : service_name_(service_name), app_state_(app_state) {} + : service_name_(service_name), + app_state_(app_state), + content_type_(DataUseContentType::OTHER) {} DataUseUserData::~DataUseUserData() {}
diff --git a/components/data_use_measurement/core/data_use_user_data.h b/components/data_use_measurement/core/data_use_user_data.h index cfae6b9..99ba656 100644 --- a/components/data_use_measurement/core/data_use_user_data.h +++ b/components/data_use_measurement/core/data_use_user_data.h
@@ -52,6 +52,27 @@ UPDATE_CLIENT, }; + // Data use broken by content type. This enum must remain synchronized + // with the enum of the same name in metrics/histograms/histograms.xml. + // These values are written to logs. New enum values can be added, but + // existing enums must never be renumbered or deleted and reused. + enum DataUseContentType { + OTHER = 0, + MAIN_FRAME_HTML = 1, + NON_MAIN_FRAME_HTML = 2, + CSS = 3, + IMAGE = 4, + JAVASCRIPT = 5, + FONT = 6, + AUDIO_APPBACKGROUND = 7, + AUDIO_TABBACKGROUND = 8, + AUDIO = 9, + VIDEO_APPBACKGROUND = 10, + VIDEO_TABBACKGROUND = 11, + VIDEO = 12, + TYPE_MAX = 13, + }; + // The state of the application. Only available on Android and on other // platforms it is always FOREGROUND. enum AppState { UNKNOWN, BACKGROUND, FOREGROUND }; @@ -78,6 +99,12 @@ void set_app_state(AppState app_state) { app_state_ = app_state; } + DataUseContentType content_type() { return content_type_; } + + void set_content_type(DataUseContentType content_type) { + content_type_ = content_type; + } + // The key for retrieving back this type of user data. static const void* const kUserDataKey; @@ -87,6 +114,8 @@ // App state when network access was performed for the request previously. AppState app_state_; + DataUseContentType content_type_; + DISALLOW_COPY_AND_ASSIGN(DataUseUserData); };
diff --git a/components/data_use_measurement/core/url_request_classifier.h b/components/data_use_measurement/core/url_request_classifier.h index 4714a108..00dc4108 100644 --- a/components/data_use_measurement/core/url_request_classifier.h +++ b/components/data_use_measurement/core/url_request_classifier.h
@@ -5,7 +5,10 @@ #ifndef COMPONENTS_DATA_USE_MEASUREMENT_CORE_URL_REQUEST_CLASSIFIER_H_ #define COMPONENTS_DATA_USE_MEASUREMENT_CORE_URL_REQUEST_CLASSIFIER_H_ +#include "components/data_use_measurement/core/data_use_user_data.h" + namespace net { +class HttpResponseHeaders; class URLRequest; } @@ -18,6 +21,13 @@ // Returns true if the URLRequest |request| is initiated by user traffic. virtual bool IsUserRequest(const net::URLRequest& request) const = 0; + + // Returns the content type of the URL request |request| with response headers + // |response_headers|. |is_app_foreground| and |is_tab_visible| indicate the + // current app and tab visibility state. + virtual DataUseUserData::DataUseContentType GetContentType( + const net::URLRequest& request, + const net::HttpResponseHeaders& response_headers) const = 0; }; } // namespace data_use_measurement
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc index 779bfb7..c9d7576 100644 --- a/components/password_manager/content/browser/content_password_manager_driver.cc +++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -273,6 +273,12 @@ key, text_direction, typed_username, options, bounds); } +void ContentPasswordManagerDriver::ShowNotSecureWarning( + base::i18n::TextDirection text_direction, + const gfx::RectF& bounds) { + password_autofill_manager_.OnShowNotSecureWarning(text_direction, bounds); +} + void ContentPasswordManagerDriver::PasswordAutofillAgentConstructed() { SendLoggingAvailability(); }
diff --git a/components/password_manager/content/browser/content_password_manager_driver.h b/components/password_manager/content/browser/content_password_manager_driver.h index 907f5115..ff9f01a5 100644 --- a/components/password_manager/content/browser/content_password_manager_driver.h +++ b/components/password_manager/content/browser/content_password_manager_driver.h
@@ -104,6 +104,8 @@ const base::string16& typed_username, int options, const gfx::RectF& bounds) override; + void ShowNotSecureWarning(base::i18n::TextDirection text_direction, + const gfx::RectF& bounds) override; void PasswordAutofillAgentConstructed() override; void RecordSavePasswordProgress(const std::string& log) override; void SaveGenerationFieldDetectedByClassifier(
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc index a553cea..25c1e06 100644 --- a/components/password_manager/core/browser/password_autofill_manager.cc +++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -241,6 +241,21 @@ weak_ptr_factory_.GetWeakPtr()); } +void PasswordAutofillManager::OnShowNotSecureWarning( + base::i18n::TextDirection text_direction, + const gfx::RectF& bounds) { + DCHECK(security_state::IsHttpWarningInFormEnabled()); + std::vector<autofill::Suggestion> suggestions; + autofill::Suggestion http_warning_suggestion( + l10n_util::GetStringUTF8(IDS_AUTOFILL_LOGIN_HTTP_WARNING_MESSAGE), + l10n_util::GetStringUTF8(IDS_AUTOFILL_HTTP_WARNING_LEARN_MORE), + "httpWarning", autofill::POPUP_ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE); + suggestions.insert(suggestions.begin(), http_warning_suggestion); + + autofill_client_->ShowAutofillPopup(bounds, text_direction, suggestions, + weak_ptr_factory_.GetWeakPtr()); +} + void PasswordAutofillManager::DidNavigateMainFrame() { login_to_password_info_.clear(); }
diff --git a/components/password_manager/core/browser/password_autofill_manager.h b/components/password_manager/core/browser/password_autofill_manager.h index ce34770..9e3baa5 100644 --- a/components/password_manager/core/browser/password_autofill_manager.h +++ b/components/password_manager/core/browser/password_autofill_manager.h
@@ -58,6 +58,12 @@ int options, const gfx::RectF& bounds); + // Handles a request from the renderer to show a popup with a warning + // indicating that the form is not secure, used when a password field + // is autofilled on a non-secure page load. + void OnShowNotSecureWarning(base::i18n::TextDirection text_direction, + const gfx::RectF& bounds); + // Called when main frame navigates. Not called for in-page navigations. void DidNavigateMainFrame();
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc index 8ffb581..b6d94f2 100644 --- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc +++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -587,6 +587,47 @@ testing::Mock::VerifyAndClearExpectations(client->mock_driver()); } +// Tests that a standalone Form Not Secure warning shows up in the +// autofill popup when PasswordAutofillManager::OnShowNotSecureWarning() +// is called. +TEST_F(PasswordAutofillManagerTest, ShowStandaloneNotSecureWarning) { + auto client = base::MakeUnique<TestPasswordManagerClient>(); + auto autofill_client = base::MakeUnique<MockAutofillClient>(); + InitializePasswordAutofillManager(client.get(), autofill_client.get()); + + gfx::RectF element_bounds; + autofill::PasswordFormFillData data; + data.username_field.value = test_username_; + data.password_field.value = test_password_; + data.origin = GURL("http://foo.test"); + + int dummy_key = 0; + password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); + + // String "Login not secure" shown as a warning messages if password form is + // on http sites. + const base::string16 warning_message = + l10n_util::GetStringUTF16(IDS_AUTOFILL_LOGIN_HTTP_WARNING_MESSAGE); + + SetHttpWarningEnabled(); + + auto elements = testing::ElementsAre(warning_message); + + EXPECT_CALL(*autofill_client, + ShowAutofillPopup(element_bounds, _, + SuggestionVectorValuesAre(elements), _)); + password_autofill_manager_->OnShowNotSecureWarning(base::i18n::RIGHT_TO_LEFT, + element_bounds); + + // Accepting the warning message should trigger a call to open the url and + // hide the popup. + EXPECT_CALL(*autofill_client, ShowHttpNotSecureExplanation()); + EXPECT_CALL(*autofill_client, HideAutofillPopup()); + password_autofill_manager_->DidAcceptSuggestion( + base::string16(), autofill::POPUP_ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE, + 0); +} + TEST_F(PasswordAutofillManagerTest, NonSecurePasswordFieldHttpWarningMessage) { auto client = base::MakeUnique<TestPasswordManagerClient>(); auto autofill_client = base::MakeUnique<MockAutofillClient>();
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index cf39025..4db36b9 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -39,6 +39,7 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_service.h" +#include "components/security_state/core/security_state.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -2854,4 +2855,41 @@ } } +class PasswordFormManagerFormNotSecureTest : public PasswordFormManagerTest { + public: + PasswordFormManagerFormNotSecureTest() { + scoped_feature_list_.InitAndEnableFeature( + security_state::kHttpFormWarningFeature); + } + + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Tests that PasswordFormFillData's +// |show_form_not_secure_warning_on_autofill| field is set correctly +// when processing a frame. +TEST_F(PasswordFormManagerFormNotSecureTest, + ProcessFrameSetsFormNotSecureFlag) { + autofill::PasswordFormFillData fill_data; + EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_)) + .WillOnce(SaveArg<0>(&fill_data)); + fake_form_fetcher()->SetNonFederated({saved_match()}, 0u); + EXPECT_TRUE(fill_data.show_form_not_secure_warning_on_autofill); +} + +// Tests that PasswordFormFillData's +// |show_form_not_secure_warning_on_autofill| field is *not* set when +// the feature is not enabled. +// +// TODO(estark): remove this test when the feature is fully +// launched. https://crbug.com/677295 +TEST_F(PasswordFormManagerTest, + ProcessFrameSetsFormNotSecureFlagWithoutFeature) { + autofill::PasswordFormFillData fill_data; + EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_)) + .WillOnce(SaveArg<0>(&fill_data)); + fake_form_fetcher()->SetNonFederated({saved_match()}, 0u); + EXPECT_FALSE(fill_data.show_form_not_secure_warning_on_autofill); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index e7d265a..491c5a60 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -16,6 +16,7 @@ #include "base/threading/platform_thread.h" #include "build/build_config.h" #include "components/autofill/core/browser/autofill_field.h" +#include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/common/form_data_predictions.h" #include "components/autofill/core/common/password_form_field_prediction_map.h" @@ -34,6 +35,7 @@ #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" +#include "components/security_state/core/security_state.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #if defined(OS_WIN) @@ -756,6 +758,16 @@ InitPasswordFormFillData(form_for_autofill, best_matches, &preferred_match, wait_for_username, OtherPossibleUsernamesEnabled(), &fill_data); + // Show a "Login not secure" warning if the experiment is enabled and the + // top-level page is not secure. + // TODO(estark): Verify that |origin| is the right URL to check here. + // https://crbug.com/676706 + autofill::AutofillManager* autofill_manager = + client_->GetAutofillManagerForMainFrame(); + fill_data.show_form_not_secure_warning_on_autofill = + security_state::IsHttpWarningInFormEnabled() && autofill_manager && + !autofill_manager->client()->IsContextSecure(fill_data.origin); + if (logger) logger->LogBoolean(Logger::STRING_WAIT_FOR_USERNAME, wait_for_username); UMA_HISTOGRAM_BOOLEAN(
diff --git a/components/safe_browsing/BUILD.gn b/components/safe_browsing/BUILD.gn index 8b81a6e7..efd199d8 100644 --- a/components/safe_browsing/BUILD.gn +++ b/components/safe_browsing/BUILD.gn
@@ -4,13 +4,20 @@ source_set("safe_browsing") { sources = [ + "base_safe_browsing_service.cc", + "base_safe_browsing_service.h", "base_ui_manager.cc", "base_ui_manager.h", ] deps = [ "//base:base", + "//components/safe_browsing/common:common", + "//components/safe_browsing_db:database_manager", + "//components/safe_browsing_db:remote_database_manager", + "//components/safe_browsing_db:safe_browsing_prefs", "//components/security_interstitials/content:unsafe_resource", "//content/public/browser:browser", + "//net:net", ] }
diff --git a/components/safe_browsing/DEPS b/components/safe_browsing/DEPS index 2f86b686..bf6183f 100644 --- a/components/safe_browsing/DEPS +++ b/components/safe_browsing/DEPS
@@ -2,4 +2,5 @@ "+components/safe_browsing_db", "+components/security_interstitials/content", "+content/public/browser", + "+net/url_request", ]
diff --git a/components/safe_browsing/base_safe_browsing_service.cc b/components/safe_browsing/base_safe_browsing_service.cc new file mode 100644 index 0000000..0817b18f --- /dev/null +++ b/components/safe_browsing/base_safe_browsing_service.cc
@@ -0,0 +1,80 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/safe_browsing/base_safe_browsing_service.h" + +#include <stddef.h> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/path_service.h" +#include "components/safe_browsing/common/safebrowsing_constants.h" +#include "components/safe_browsing_db/database_manager.h" +#include "components/safe_browsing_db/safe_browsing_prefs.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/resource_request_info.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_getter.h" + +#if defined(SAFE_BROWSING_DB_REMOTE) +#include "components/safe_browsing_db/remote_database_manager.h" +#endif + +using content::BrowserThread; + +namespace safe_browsing { + +BaseSafeBrowsingService::BaseSafeBrowsingService() : enabled_(false) {} + +BaseSafeBrowsingService::~BaseSafeBrowsingService() { + // We should have already been shut down. If we're still enabled, then the + // database isn't going to be closed properly, which could lead to corruption. + DCHECK(!enabled_); +} + +void BaseSafeBrowsingService::Initialize() { + // TODO(ntfschr): initialize ui_manager_ once CreateUIManager is componentized +} + +void BaseSafeBrowsingService::ShutDown() {} + +scoped_refptr<net::URLRequestContextGetter> +BaseSafeBrowsingService::url_request_context() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + return nullptr; +} + +const scoped_refptr<SafeBrowsingDatabaseManager>& +BaseSafeBrowsingService::database_manager() const { + return database_manager_; +} + +void BaseSafeBrowsingService::OnResourceRequest( + const net::URLRequest* request) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); +} + +SafeBrowsingDatabaseManager* BaseSafeBrowsingService::CreateDatabaseManager() { +// For the LocalSafeBrowsingDatabaseManager, use +// chrome/browser/safe_browsing_service +#if defined(SAFE_BROWSING_DB_REMOTE) + return new RemoteSafeBrowsingDatabaseManager(); +#else + return NULL; +#endif +} + +std::unique_ptr<BaseSafeBrowsingService::StateSubscription> +BaseSafeBrowsingService::RegisterStateCallback( + const base::Callback<void(void)>& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + return state_callback_list_.Add(callback); +} + +void BaseSafeBrowsingService::ProcessResourceRequest( + const ResourceRequestInfo& request) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} + +} // namespace safe_browsing
diff --git a/components/safe_browsing/base_safe_browsing_service.h b/components/safe_browsing/base_safe_browsing_service.h new file mode 100644 index 0000000..b0e4b034 --- /dev/null +++ b/components/safe_browsing/base_safe_browsing_service.h
@@ -0,0 +1,104 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// The Safe Browsing service is responsible for downloading anti-phishing and +// anti-malware tables and checking urls against them. + +#ifndef COMPONENTS_SAFE_BROWSING_BASE_SAFE_BROWSING_SERVICE_H_ +#define COMPONENTS_SAFE_BROWSING_BASE_SAFE_BROWSING_SERVICE_H_ + +#include <map> +#include <memory> +#include <string> + +#include "base/callback_list.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "content/public/browser/browser_thread.h" + +namespace net { +class URLRequest; +class URLRequestContextGetter; +} + +namespace safe_browsing { +struct ResourceRequestInfo; +class SafeBrowsingDatabaseManager; + +// Construction needs to happen on the main thread. +// The BaseSafeBrowsingService owns both the UI and Database managers which do +// the heavylifting of safebrowsing service. Both of these managers stay +// alive until BaseSafeBrowsingService is destroyed, however, they are disabled +// permanently when Shutdown method is called. +class BaseSafeBrowsingService : public base::RefCountedThreadSafe< + BaseSafeBrowsingService, + content::BrowserThread::DeleteOnUIThread> { + public: + // Called on the UI thread to initialize the service. + virtual void Initialize(); + + // Called on the main thread to let us know that the io_thread is going away. + virtual void ShutDown(); + + // Get current enabled status. Must be called on IO thread. + bool enabled() const { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + return enabled_; + } + + virtual scoped_refptr<net::URLRequestContextGetter> url_request_context(); + + // This returns either the v3 or the v4 database manager, depending on + // the experiment settings. + virtual const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager() + const; + + // Observes resource requests made by the renderer and reports suspicious + // activity. + void OnResourceRequest(const net::URLRequest* request); + + // Type for subscriptions to SafeBrowsing service state. + typedef base::CallbackList<void(void)>::Subscription StateSubscription; + + // Adds a listener for when SafeBrowsing preferences might have changed. To + // get the current state, the callback should call + // SafeBrowsingService::enabled_by_prefs(). Should only be called on the UI + // thread. + std::unique_ptr<StateSubscription> RegisterStateCallback( + const base::Callback<void(void)>& callback); + + protected: + // Creates the safe browsing service. Need to initialize before using. + BaseSafeBrowsingService(); + + virtual ~BaseSafeBrowsingService(); + + virtual SafeBrowsingDatabaseManager* CreateDatabaseManager(); + + // Whether the service is running. 'enabled_' is used by + // BaseSafeBrowsingService on the IO thread during normal operations. + bool enabled_; + + // The database manager handles the database and download logic. Accessed on + // both UI and IO thread. + scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; + + // Callbacks when SafeBrowsing state might have changed. + // Should only be accessed on the UI thread. + base::CallbackList<void(void)> state_callback_list_; + + private: + friend struct content::BrowserThread::DeleteOnThread< + content::BrowserThread::UI>; + friend class base::DeleteHelper<BaseSafeBrowsingService>; + + // Process the observed resource requests on the UI thread. + void ProcessResourceRequest(const ResourceRequestInfo& request); + + DISALLOW_COPY_AND_ASSIGN(BaseSafeBrowsingService); +}; + +} // namespace safe_browsing + +#endif // COMPONENTS_SAFE_BROWSING_BASE_SAFE_BROWSING_SERVICE_H_
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 9c7cd17cb0..f30a568f 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -865,11 +865,6 @@ "media/audio_stream_monitor.h", "media/capture/audio_mirroring_manager.cc", "media/capture/audio_mirroring_manager.h", - "media/capture/cursor_renderer.h", - "media/capture/cursor_renderer_aura.cc", - "media/capture/cursor_renderer_aura.h", - "media/capture/cursor_renderer_mac.h", - "media/capture/cursor_renderer_mac.mm", "media/capture/desktop_capture_device_uma_types.cc", "media/capture/desktop_capture_device_uma_types.h", "media/capture/image_capture_impl.cc", @@ -880,14 +875,6 @@ "media/capture/web_contents_audio_muter.h", "media/capture/web_contents_tracker.cc", "media/capture/web_contents_tracker.h", - "media/capture/web_contents_video_capture_device.cc", - "media/capture/web_contents_video_capture_device.h", - "media/capture/window_activity_tracker.cc", - "media/capture/window_activity_tracker.h", - "media/capture/window_activity_tracker_aura.cc", - "media/capture/window_activity_tracker_aura.h", - "media/capture/window_activity_tracker_mac.h", - "media/capture/window_activity_tracker_mac.mm", "media/cdm_registry_impl.cc", "media/cdm_registry_impl.h", "media/media_devices_permission_checker.cc", @@ -1510,26 +1497,48 @@ "//third_party/webrtc/media:rtc_media_base", "//third_party/webrtc/modules/desktop_capture:primitives", ] - if (!is_ios) { - defines += [ "ENABLE_SCREEN_CAPTURE=1" ] - } + if (is_linux || is_mac || is_win) { sources += [ "media/capture/desktop_capture_device.cc", "media/capture/desktop_capture_device.h", ] - if (use_aura) { - sources += [ - "media/capture/aura_window_capture_machine.cc", - "media/capture/aura_window_capture_machine.h", - "media/capture/desktop_capture_device_aura.cc", - "media/capture/desktop_capture_device_aura.h", - ] - } deps += [ "//third_party/webrtc/modules/desktop_capture" ] } } + # Desktop screen capture implementations that are not dependent on WebRTC. + if (is_linux || is_mac || is_win) { + defines += [ "ENABLE_SCREEN_CAPTURE=1" ] + sources += [ + "media/capture/cursor_renderer.h", + "media/capture/web_contents_video_capture_device.cc", + "media/capture/web_contents_video_capture_device.h", + "media/capture/window_activity_tracker.cc", + "media/capture/window_activity_tracker.h", + ] + if (use_aura) { + sources += [ + "media/capture/aura_window_capture_machine.cc", + "media/capture/aura_window_capture_machine.h", + "media/capture/cursor_renderer_aura.cc", + "media/capture/cursor_renderer_aura.h", + "media/capture/desktop_capture_device_aura.cc", + "media/capture/desktop_capture_device_aura.h", + "media/capture/window_activity_tracker_aura.cc", + "media/capture/window_activity_tracker_aura.h", + ] + } + if (is_mac) { + sources += [ + "media/capture/cursor_renderer_mac.h", + "media/capture/cursor_renderer_mac.mm", + "media/capture/window_activity_tracker_mac.h", + "media/capture/window_activity_tracker_mac.mm", + ] + } + } + if (is_win) { sources -= [ "device_sensors/data_fetcher_shared_memory_default.cc" ] defines += [ @@ -1788,7 +1797,10 @@ "//mojo/android:libsystem_java", "//ui/android", ] - defines += [ "APPCACHE_USE_SIMPLE_CACHE" ] + defines += [ + "APPCACHE_USE_SIMPLE_CACHE", + "ENABLE_SCREEN_CAPTURE=1", + ] libs += [ "jnigraphics" ] } else { # Not Android. @@ -1861,10 +1873,6 @@ ] } else { # Not aura. sources -= [ - "media/capture/cursor_renderer_aura.cc", - "media/capture/cursor_renderer_aura.h", - "media/capture/window_activity_tracker_aura.cc", - "media/capture/window_activity_tracker_aura.h", "renderer_host/compositor_resize_lock_aura.cc", "renderer_host/compositor_resize_lock_aura.h", "renderer_host/input/synthetic_gesture_target_aura.cc",
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc index aae4ed1d..d36e816c 100644 --- a/content/browser/media/capture/web_contents_video_capture_device.cc +++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -1,49 +1,6 @@ // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// -// Implementation notes: This needs to work on a variety of hardware -// configurations where the speed of the CPU and GPU greatly affect overall -// performance. Spanning several threads, the process of capturing has been -// split up into four conceptual stages: -// -// 1. Reserve Buffer: Before a frame can be captured, a slot in the client's -// shared-memory IPC buffer is reserved. There are only a few of these; -// when they run out, it indicates that the downstream client -- likely a -// video encoder -- is the performance bottleneck, and that the rate of -// frame capture should be throttled back. -// -// 2. Capture: A bitmap is snapshotted/copied from the RenderWidget's backing -// store. This is initiated on the UI BrowserThread, and often occurs -// asynchronously. Where supported, the GPU scales and color converts -// frames to our desired size, and the readback happens directly into the -// shared-memory buffer. But this is not always possible, particularly when -// accelerated compositing is disabled. -// -// 3. Render (if needed): If the web contents cannot be captured directly into -// our target size and color format, scaling and colorspace conversion must -// be done on the CPU. A dedicated thread is used for this operation, to -// avoid blocking the UI thread. The Render stage always reads from a -// bitmap returned by Capture, and writes into the reserved slot in the -// shared-memory buffer. -// -// 4. Deliver: The rendered video frame is returned to the client (which -// implements the VideoCaptureDevice::Client interface). Because all -// paths have written the frame into the IPC buffer, this step should -// never need to do an additional copy of the pixel data. -// -// In the best-performing case, the Render step is bypassed: Capture produces -// ready-to-Deliver frames. But when accelerated readback is not possible, the -// system is designed so that Capture and Render may run concurrently. A timing -// diagram helps illustrate this point (@30 FPS): -// -// Time: 0ms 33ms 66ms 99ms -// thread1: |-Capture-f1------v |-Capture-f2------v |-Capture-f3----v |-Capt -// thread2: |-Render-f1-----v |-Render-f2-----v |-Render-f3 -// -// In the above example, both capturing and rendering *each* take almost the -// full 33 ms available between frames, yet we see that the required throughput -// is obtained. #include "content/browser/media/capture/web_contents_video_capture_device.h" @@ -51,19 +8,14 @@ #include <algorithm> #include <memory> -#include <utility> +#include <string> #include "base/bind.h" #include "base/callback_helpers.h" #include "base/location.h" #include "base/logging.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" -#include "base/sequenced_task_runner.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread.h" -#include "base/threading/thread_checker.h" #include "base/time/time.h" #include "build/build_config.h" #include "content/browser/media/capture/cursor_renderer.h" @@ -77,16 +29,11 @@ #include "content/public/browser/render_widget_host_view_frame_subscriber.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_media_capture_id.h" -#include "media/base/bind_to_current_loop.h" #include "media/base/video_frame_metadata.h" -#include "media/base/video_util.h" #include "media/capture/content/screen_capture_device_core.h" #include "media/capture/content/thread_safe_capture_oracle.h" #include "media/capture/content/video_capture_oracle.h" #include "media/capture/video_capture_types.h" -#include "skia/ext/image_operations.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColor.h" #include "ui/base/layout.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/size_conversions.h" @@ -95,32 +42,22 @@ namespace { -enum InteractiveModeSettings { - // Minimum amount of time for which there should be no animation detected - // to consider interactive mode being active. This is to prevent very brief - // periods of animated content not being detected (due to CPU fluctations for - // example) from causing a flip-flop on interactive mode. - kMinPeriodNoAnimationMillis = 3000 -}; - -void DeleteOnWorkerThread(std::unique_ptr<base::Thread> render_thread, - const base::Closure& callback) { - render_thread.reset(); - - // After thread join call the callback on UI thread. - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); -} +// Minimum amount of time for which there should be no animation detected +// to consider interactive mode being active. This is to prevent very brief +// periods of animated content not being detected (due to CPU fluctations for +// example) from causing a flip-flop on interactive mode. +constexpr int64_t kMinPeriodNoAnimationMillis = 3000; // FrameSubscriber is a proxy to the ThreadSafeCaptureOracle that's compatible -// with RenderWidgetHostViewFrameSubscriber. We create one per event type. +// with RenderWidgetHostViewFrameSubscriber. One is created per event type. class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber { public: FrameSubscriber(media::VideoCaptureOracle::Event event_type, - const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle, + scoped_refptr<media::ThreadSafeCaptureOracle> oracle, base::WeakPtr<content::CursorRenderer> cursor_renderer, base::WeakPtr<content::WindowActivityTracker> tracker) : event_type_(event_type), - oracle_proxy_(oracle), + oracle_proxy_(std::move(oracle)), cursor_renderer_(cursor_renderer), window_activity_tracker_(tracker), weak_ptr_factory_(this) {} @@ -145,13 +82,13 @@ private: const media::VideoCaptureOracle::Event event_type_; - scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy_; + const scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy_; // We need a weak pointer since FrameSubscriber is owned externally and // may outlive the cursor renderer. - base::WeakPtr<CursorRenderer> cursor_renderer_; + const base::WeakPtr<CursorRenderer> cursor_renderer_; // We need a weak pointer since FrameSubscriber is owned externally and // may outlive the ui activity tracker. - base::WeakPtr<WindowActivityTracker> window_activity_tracker_; + const base::WeakPtr<WindowActivityTracker> window_activity_tracker_; base::WeakPtrFactory<FrameSubscriber> weak_ptr_factory_; }; @@ -162,29 +99,31 @@ // // In practice, this means (a) installing a RenderWidgetHostFrameSubscriber in // the RenderWidgetHostView, to process compositor updates, and (b) occasionally -// initiating forced, non-event-driven captures needed by downstream consumers -// that request "refresh frames" of unchanged content. +// using the capture callback to force additional captures that are needed for +// things like mouse cursor rendering updates and/or refresh frames. // // All of this happens on the UI thread, although the // RenderWidgetHostViewFrameSubscriber we install may be dispatching updates // autonomously on some other thread. class ContentCaptureSubscription { public: - typedef base::Callback<void( - const base::TimeTicks&, - const scoped_refptr<media::VideoFrame>&, - const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&)> - CaptureCallback; + using CaptureCallback = base::Callback<void( + base::TimeTicks, + scoped_refptr<media::VideoFrame>, + const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&)>; - // Create a subscription. Whenever a manual capture is required, the + // Create a subscription. Whenever a non-compositor capture is required, the // subscription will invoke |capture_callback| on the UI thread to do the // work. ContentCaptureSubscription( base::WeakPtr<RenderWidgetHostViewBase> source_view, - const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, + scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy, const CaptureCallback& capture_callback); ~ContentCaptureSubscription(); + // Called when a condition occurs that requires a refresh frame be + // captured. The subscribers will determine whether a frame was recently + // captured, or if a non-compositor initiated capture must be made. void MaybeCaptureForRefresh(); private: @@ -209,22 +148,8 @@ DISALLOW_COPY_AND_ASSIGN(ContentCaptureSubscription); }; -// Render the SkBitmap |input| into the given VideoFrame buffer |output|, then -// invoke |done_cb| to indicate success or failure. |input| is expected to be -// ARGB. |output| must be YV12 or I420. Colorspace conversion is always done. -// Scaling and letterboxing will be done as needed. -// -// This software implementation should be used only when GPU acceleration of -// these activities is not possible. This operation may be expensive (tens to -// hundreds of milliseconds), so the caller should ensure that it runs on a -// thread where such a pause would cause UI jank. -void RenderVideoFrame( - const SkBitmap& input, - const scoped_refptr<media::VideoFrame>& output, - const base::Callback<void(const gfx::Rect&, bool)>& done_cb); - // Renews capture subscriptions based on feedback from WebContentsTracker, and -// also executes copying of the backing store on the UI BrowserThread. +// also executes non-compositor-initiated frame captures. class WebContentsCaptureMachine : public media::VideoCaptureMachine { public: WebContentsCaptureMachine(int render_process_id, @@ -244,20 +169,20 @@ } void MaybeCaptureForRefresh() override; - // Starts a copy from the backing store or the composited surface. Must be run - // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation - // completes. The copy will occur to |target|. + private: + // Called for cases where events other than compositor updates require a frame + // capture from the composited surface. Must be run on the UI BrowserThread. + // |deliver_frame_cb| will be run when the operation completes. The copy will + // populate |target|. // - // This may be used as a ContentCaptureSubscription::CaptureCallback. - void Capture(const base::TimeTicks& start_time, - const scoped_refptr<media::VideoFrame>& target, + // This method is only used by a ContentCaptureSubscription::CaptureCallback. + void Capture(base::TimeTicks start_time, + scoped_refptr<media::VideoFrame> target, const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& deliver_frame_cb); - private: - bool InternalStart( - const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, - const media::VideoCaptureParams& params); + bool InternalStart(scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy, + const media::VideoCaptureParams& params); void InternalSuspend(); void InternalResume(); void InternalStop(const base::Closure& callback); @@ -267,17 +192,8 @@ // Computes the preferred size of the target RenderWidget for optimal capture. gfx::Size ComputeOptimalViewSize() const; - // Response callback for RenderWidgetHost::CopyFromBackingStore(). - void DidCopyFromBackingStore( - const base::TimeTicks& start_time, - const scoped_refptr<media::VideoFrame>& target, - const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& - deliver_frame_cb, - const SkBitmap& bitmap, - ReadbackResponse response); - // Response callback for RWHVP::CopyFromCompositingSurfaceToVideoFrame(). - void DidCopyFromCompositingSurfaceToVideoFrame( + void DidCopyToVideoFrame( const base::TimeTicks& start_time, const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& deliver_frame_cb, @@ -305,10 +221,6 @@ // option in the WebContentsVideoCaptureDevice device ID. const bool auto_throttling_enabled_; - // A dedicated worker thread on which SkBitmap->VideoFrame conversion will - // occur. Only used when this activity cannot be done on the GPU. - std::unique_ptr<base::Thread> render_thread_; - // Makes all the decisions about which frames to copy, and how. scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy_; @@ -340,15 +252,17 @@ this); media::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; + if (!oracle_proxy_->ObserveEventAndDecideCapture( + event_type_, damage_rect, present_time, storage, &capture_frame_cb)) { + return false; + } - bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture( - event_type_, damage_rect, present_time, storage, &capture_frame_cb); - - if (!capture_frame_cb.is_null()) - *deliver_frame_cb = - base::Bind(&FrameSubscriber::DidCaptureFrame, - weak_ptr_factory_.GetWeakPtr(), capture_frame_cb, *storage); - return oracle_decision; + DCHECK(*storage); + DCHECK(!capture_frame_cb.is_null()); + *deliver_frame_cb = + base::Bind(&FrameSubscriber::DidCaptureFrame, + weak_ptr_factory_.GetWeakPtr(), capture_frame_cb, *storage); + return true; } void FrameSubscriber::DidCaptureFrame( @@ -359,14 +273,12 @@ base::TimeTicks timestamp, const gfx::Rect& region_in_frame, bool success) { - // We can get a callback in the shutdown sequence for the browser main loop - // and this can result in a DCHECK failure. Avoid this by doing DCHECK only - // on success. if (success) { + // We can get a callback in the shutdown sequence for the browser main loop + // and this can result in a DCHECK failure. Avoid this by doing DCHECK only + // on success. DCHECK_CURRENTLY_ON(BrowserThread::UI); - // TODO(isheriff): Unclear if taking a snapshot of cursor here affects user - // experience in any particular scenarios. Doing it prior to capture may - // require evaluating region_in_frame in this file. + if (frame_subscriber_ && frame_subscriber_->cursor_renderer_) { CursorRenderer* cursor_renderer = frame_subscriber_->cursor_renderer_.get(); @@ -381,11 +293,9 @@ } bool FrameSubscriber::IsUserInteractingWithContent() { + bool ui_activity = window_activity_tracker_ && + window_activity_tracker_->IsUiInteractionActive(); bool interactive_mode = false; - bool ui_activity = false; - if (window_activity_tracker_) { - ui_activity = window_activity_tracker_->IsUiInteractionActive(); - } if (cursor_renderer_) { bool animation_active = (base::TimeTicks::Now() - @@ -393,7 +303,7 @@ base::TimeDelta::FromMilliseconds(kMinPeriodNoAnimationMillis); if (ui_activity && !animation_active) { interactive_mode = true; - } else if (animation_active && window_activity_tracker_.get()) { + } else if (animation_active && window_activity_tracker_) { window_activity_tracker_->Reset(); } } @@ -402,7 +312,7 @@ ContentCaptureSubscription::ContentCaptureSubscription( base::WeakPtr<RenderWidgetHostViewBase> source_view, - const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, + scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy, const CaptureCallback& capture_callback) : source_view_(source_view), capture_callback_(capture_callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -413,6 +323,10 @@ window_activity_tracker_ = WindowActivityTracker::Create(source_view_->GetNativeView()); #endif + // Subscriptions for refresh frames and mouse cursor updates. When events + // outside of the normal content change/compositing workflow occur, these + // decide whether extra frames need to be captured. Such extra frame captures + // are initiated by running the |capture_callback_|. refresh_subscriber_.reset(new FrameSubscriber( media::VideoCaptureOracle::kActiveRefreshRequest, oracle_proxy, cursor_renderer_ ? cursor_renderer_->GetWeakPtr() @@ -426,8 +340,12 @@ window_activity_tracker_ ? window_activity_tracker_->GetWeakPtr() : base::WeakPtr<WindowActivityTracker>())); - // Subscribe to compositor updates. These will be serviced directly by the - // oracle. + // Main capture path: Subscribing to compositor updates. This means that any + // time the tab content has changed and compositing has taken place, the + // RenderWidgetHostView will consult the FrameSubscriber (which consults the + // oracle) to determine whether a frame should be captured. If so, the + // RenderWidgetHostView will initiate the frame capture and NOT the + // |capture_callback_|. std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber( new FrameSubscriber( media::VideoCaptureOracle::kCompositorUpdate, oracle_proxy, @@ -437,7 +355,8 @@ : base::WeakPtr<WindowActivityTracker>())); source_view_->BeginFrameSubscription(std::move(subscriber)); - // Subscribe to mouse movement and mouse cursor update events. + // Begin monitoring for user activity that is used to signal "interactive + // content." if (window_activity_tracker_) { window_activity_tracker_->RegisterMouseInteractionObserver( base::Bind(&ContentCaptureSubscription::OnEvent, base::Unretained(this), @@ -483,79 +402,6 @@ } } -void RenderVideoFrame( - const SkBitmap& input, - const scoped_refptr<media::VideoFrame>& output, - const base::Callback<void(const gfx::Rect&, bool)>& done_cb) { - base::ScopedClosureRunner failure_handler( - base::Bind(done_cb, gfx::Rect(), false)); - - SkAutoLockPixels locker(input); - - // Sanity-check the captured bitmap. - if (input.empty() || !input.readyToDraw() || - input.colorType() != kN32_SkColorType || input.width() < 2 || - input.height() < 2) { - DVLOG(1) << "input unacceptable (size=" << input.getSize() - << ", ready=" << input.readyToDraw() - << ", colorType=" << input.colorType() << ')'; - return; - } - - // Sanity-check the output buffer. - if (output->format() != media::PIXEL_FORMAT_I420) { - NOTREACHED(); - return; - } - - // Calculate the width and height of the content region in the |output|, based - // on the aspect ratio of |input|. - const gfx::Rect region_in_frame = media::ComputeLetterboxRegion( - output->visible_rect(), gfx::Size(input.width(), input.height())); - - // Scale the bitmap to the required size, if necessary. - SkBitmap scaled_bitmap; - if (input.width() != region_in_frame.width() || - input.height() != region_in_frame.height()) { - skia::ImageOperations::ResizeMethod method; - if (input.width() < region_in_frame.width() || - input.height() < region_in_frame.height()) { - // Avoid box filtering when magnifying, because it's actually - // nearest-neighbor. - method = skia::ImageOperations::RESIZE_HAMMING1; - } else { - method = skia::ImageOperations::RESIZE_BOX; - } - - TRACE_EVENT_ASYNC_STEP_INTO0("gpu.capture", "Capture", output.get(), - "Scale"); - scaled_bitmap = skia::ImageOperations::Resize( - input, method, region_in_frame.width(), region_in_frame.height()); - } else { - scaled_bitmap = input; - } - - TRACE_EVENT_ASYNC_STEP_INTO0("gpu.capture", "Capture", output.get(), "YUV"); - { - // Align to 2x2 pixel boundaries, as required by - // media::CopyRGBToVideoFrame(). - const gfx::Rect region_in_yv12_frame( - region_in_frame.x() & ~1, region_in_frame.y() & ~1, - region_in_frame.width() & ~1, region_in_frame.height() & ~1); - if (region_in_yv12_frame.IsEmpty()) - return; - - SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); - media::CopyRGBToVideoFrame( - reinterpret_cast<uint8_t*>(scaled_bitmap.getPixels()), - scaled_bitmap.rowBytes(), region_in_yv12_frame, output.get()); - } - - // The result is now ready. - ignore_result(failure_handler.Release()); - done_cb.Run(region_in_frame, true); -} - WebContentsCaptureMachine::WebContentsCaptureMachine( int render_process_id, int main_render_frame_id, @@ -591,22 +437,15 @@ } bool WebContentsCaptureMachine::InternalStart( - const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, + scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy, const media::VideoCaptureParams& params) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(!IsStarted()); DCHECK(oracle_proxy); - oracle_proxy_ = oracle_proxy; + oracle_proxy_ = std::move(oracle_proxy); capture_params_ = params; - render_thread_.reset(new base::Thread("WebContentsVideo_RenderThread")); - if (!render_thread_->Start()) { - DVLOG(1) << "Failed to spawn render thread."; - render_thread_.reset(); - return false; - } - // Note: Creation of the first WeakPtr in the following statement will cause // IsStarted() to return true from now on. tracker_->SetResizeChangeCallback( @@ -653,7 +492,6 @@ } void WebContentsCaptureMachine::Stop(const base::Closure& callback) { - // Stops the capture machine asynchronously. BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(&WebContentsCaptureMachine::InternalStop, base::Unretained(this), callback)); @@ -662,10 +500,10 @@ void WebContentsCaptureMachine::InternalStop(const base::Closure& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!IsStarted()) { - callback.Run(); + base::ScopedClosureRunner done_runner(callback); + + if (!IsStarted()) return; - } // The following cancels any outstanding callbacks and causes IsStarted() to // return false from here onward. @@ -675,14 +513,6 @@ if (WebContents* contents = tracker_->web_contents()) contents->DecrementCapturerCount(); tracker_->Stop(); - - // The render thread cannot be stopped on the UI thread, so post a message - // to the thread pool used for blocking operations. - if (render_thread_) { - BrowserThread::PostBlockingPoolTask( - FROM_HERE, base::Bind(&DeleteOnWorkerThread, - base::Passed(&render_thread_), callback)); - } } void WebContentsCaptureMachine::MaybeCaptureForRefresh() { @@ -701,43 +531,24 @@ } void WebContentsCaptureMachine::Capture( - const base::TimeTicks& start_time, - const scoped_refptr<media::VideoFrame>& target, + base::TimeTicks start_time, + scoped_refptr<media::VideoFrame> target, const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& deliver_frame_cb) { DCHECK_CURRENTLY_ON(BrowserThread::UI); auto* const view = static_cast<RenderWidgetHostViewBase*>(tracker_->GetTargetView()); - if (!view) { + if (!view || !view->CanCopyToVideoFrame()) { deliver_frame_cb.Run(base::TimeTicks(), gfx::Rect(), false); return; } const gfx::Size view_size = view->GetViewBounds().size(); - if (view->CanCopyToVideoFrame()) { - view->CopyFromCompositingSurfaceToVideoFrame( - gfx::Rect(view_size), target, - base::Bind(&WebContentsCaptureMachine:: - DidCopyFromCompositingSurfaceToVideoFrame, - weak_ptr_factory_.GetWeakPtr(), start_time, - deliver_frame_cb)); - } else { - const gfx::Size fitted_size = - view_size.IsEmpty() - ? gfx::Size() - : media::ComputeLetterboxRegion(target->visible_rect(), view_size) - .size(); - if (auto* rwh = view->GetRenderWidgetHost()) { - rwh->CopyFromBackingStore( - gfx::Rect(), - fitted_size, // Size here is a request not always honored. - base::Bind(&WebContentsCaptureMachine::DidCopyFromBackingStore, - weak_ptr_factory_.GetWeakPtr(), start_time, target, - deliver_frame_cb), - kN32_SkColorType); - } - } + view->CopyFromCompositingSurfaceToVideoFrame( + gfx::Rect(view_size), std::move(target), + base::Bind(&WebContentsCaptureMachine::DidCopyToVideoFrame, + weak_ptr_factory_.GetWeakPtr(), start_time, deliver_frame_cb)); } gfx::Size WebContentsCaptureMachine::ComputeOptimalViewSize() const { @@ -804,31 +615,7 @@ return optimal_size; } -void WebContentsCaptureMachine::DidCopyFromBackingStore( - const base::TimeTicks& start_time, - const scoped_refptr<media::VideoFrame>& target, - const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& - deliver_frame_cb, - const SkBitmap& bitmap, - ReadbackResponse response) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - DCHECK(render_thread_); - if (response == READBACK_SUCCESS) { - TRACE_EVENT_ASYNC_STEP_INTO0("gpu.capture", "Capture", target.get(), - "Render"); - render_thread_->task_runner()->PostTask( - FROM_HERE, media::BindToCurrentLoop( - base::Bind(&RenderVideoFrame, bitmap, target, - base::Bind(deliver_frame_cb, start_time)))); - } else { - // Capture can fail due to transient issues, so just skip this frame. - DVLOG(1) << "CopyFromBackingStore failed; skipping frame."; - deliver_frame_cb.Run(start_time, gfx::Rect(), false); - } -} - -void WebContentsCaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame( +void WebContentsCaptureMachine::DidCopyToVideoFrame( const base::TimeTicks& start_time, const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& deliver_frame_cb, @@ -923,7 +710,7 @@ // Parse device_id into render_process_id and main_render_frame_id. WebContentsMediaCaptureId media_id; if (!WebContentsMediaCaptureId::Parse(device_id, &media_id)) { - return NULL; + return nullptr; } return std::unique_ptr<media::VideoCaptureDevice>(
diff --git a/content/browser/media/capture/web_contents_video_capture_device.h b/content/browser/media/capture/web_contents_video_capture_device.h index ab81c35..0446175 100644 --- a/content/browser/media/capture/web_contents_video_capture_device.h +++ b/content/browser/media/capture/web_contents_video_capture_device.h
@@ -15,9 +15,15 @@ namespace content { -// A virtualized VideoCaptureDevice that mirrors the displayed contents of a +// A virtualized VideoCaptureDevice that captures the displayed contents of a // WebContents (i.e., the composition of an entire render frame tree), producing -// a stream of video frames. +// a stream of video frames. As such, WebContentsVideoCaptureDevice is only +// supported on platforms that use the Chromium compositor, have a +// content::RenderWidgetHostView implementation that supports frame subscription +// (via BeginFrameSubscription()), and can perform read-back into +// media::VideoFrames (i.e., +// RenderWidgetHostViewBase::CopyFromCompositingSurfaceToVideoFrame() is +// functional). // // An instance is created by providing a device_id. The device_id contains // information necessary for finding a WebContents instance. From then on,
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc index 3843028..a601b05 100644 --- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc +++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -52,12 +52,14 @@ namespace content { namespace { -const int kTestWidth = 320; -const int kTestHeight = 240; -const int kTestFramesPerSecond = 20; -const float kTestDeviceScaleFactor = 2.0f; -const SkColor kNothingYet = 0xdeadbeef; -const SkColor kNotInterested = ~kNothingYet; +constexpr int kTestWidth = 320; +constexpr int kTestHeight = 240; +constexpr int kTestFramesPerSecond = 20; +constexpr float kTestDeviceScaleFactor = 2.0f; +constexpr SkColor kDrawColorNotSet = 0xcafe1950; +constexpr SkColor kWaitColorNotSet = ~kDrawColorNotSet; +constexpr SkColor kNothingYet = 0xdeadbeef; +constexpr SkColor kNotInterested = ~kNothingYet; void DeadlineExceeded(base::Closure quit_closure) { if (!base::debug::BeingDebugged()) { @@ -87,86 +89,24 @@ return SkColorSetRGB(yuv[0], yuv[1], yuv[2]); } -// Thread-safe class that controls the source pattern to be captured by the -// system under test. The lifetime of this class is greater than the lifetime -// of all objects that reference it, so it does not need to be reference -// counted. -class CaptureTestSourceController { - public: - CaptureTestSourceController() - : color_(SK_ColorMAGENTA), - copy_result_size_(kTestWidth, kTestHeight), - can_copy_to_video_frame_(true) {} +media::VideoCaptureParams DefaultCaptureParams() { + media::VideoCaptureParams capture_params; + capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); + capture_params.requested_format.frame_rate = kTestFramesPerSecond; + capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; + return capture_params; +} - void SetSolidColor(SkColor color) { - base::AutoLock guard(lock_); - color_ = color; - } - - SkColor GetSolidColor() { - base::AutoLock guard(lock_); - return color_; - } - - void SetCopyResultSize(int width, int height) { - base::AutoLock guard(lock_); - copy_result_size_ = gfx::Size(width, height); - } - - gfx::Size GetCopyResultSize() { - base::AutoLock guard(lock_); - return copy_result_size_; - } - - void SignalCopy() { - // TODO(nick): This actually should always be happening on the UI thread. - base::AutoLock guard(lock_); - if (!copy_done_.is_null()) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, copy_done_); - copy_done_.Reset(); - } - } - - void SetCanCopyToVideoFrame(bool value) { - base::AutoLock guard(lock_); - can_copy_to_video_frame_ = value; - } - - bool CanCopyToVideoFrame() { - base::AutoLock guard(lock_); - return can_copy_to_video_frame_; - } - - void WaitForNextCopy() { - { - base::AutoLock guard(lock_); - copy_done_ = base::MessageLoop::current()->QuitWhenIdleClosure(); - } - - RunCurrentLoopWithDeadline(); - } - - private: - base::Lock lock_; // Guards changes to all members. - SkColor color_; - gfx::Size copy_result_size_; - bool can_copy_to_video_frame_; - base::Closure copy_done_; - - DISALLOW_COPY_AND_ASSIGN(CaptureTestSourceController); -}; - -// A stub implementation which returns solid-color bitmaps in calls to -// CopyFromCompositingSurfaceToVideoFrame(), and which allows the video-frame -// readback path to be switched on and off. The behavior is controlled by a -// CaptureTestSourceController. +// A stub implementation which fills solid-colors into VideoFrames in calls to +// CopyFromCompositingSurfaceToVideoFrame(). The colors are changed by tests +// in-between draw events to confirm that the right frames have the right +// content and in the right sequence. class CaptureTestView : public TestRenderWidgetHostView { public: - CaptureTestView(RenderWidgetHostImpl* rwh, - CaptureTestSourceController* controller) + explicit CaptureTestView(RenderWidgetHostImpl* rwh) : TestRenderWidgetHostView(rwh), - controller_(controller), - fake_bounds_(100, 100, 100 + kTestWidth, 100 + kTestHeight) {} + fake_bounds_(100, 100, 100 + kTestWidth, 100 + kTestHeight), + yuv_color_(kDrawColorNotSet) {} ~CaptureTestView() override {} @@ -183,29 +123,30 @@ fake_bounds_ = rect; } - bool CanCopyToVideoFrame() const override { - return controller_->CanCopyToVideoFrame(); - } + bool CanCopyToVideoFrame() const override { return true; } void CopyFromCompositingSurfaceToVideoFrame( const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(const gfx::Rect&, bool)>& callback) override { - SkColor c = ConvertRgbToYuv(controller_->GetSolidColor()); - media::FillYUV( - target.get(), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); - callback.Run(gfx::Rect(), true); - controller_->SignalCopy(); + media::FillYUV(target.get(), SkColorGetR(yuv_color_), + SkColorGetG(yuv_color_), SkColorGetB(yuv_color_)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(callback, gfx::Rect(), true)); } void BeginFrameSubscription( std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override { - subscriber_.reset(subscriber.release()); + subscriber_ = std::move(subscriber); } void EndFrameSubscription() override { subscriber_.reset(); } + void SetSolidColor(SkColor rgb_color) { + yuv_color_ = ConvertRgbToYuv(rgb_color); + } + // Simulate a compositor paint event for our subscriber. void SimulateUpdate() { const base::TimeTicks present_time = base::TimeTicks::Now(); @@ -213,60 +154,19 @@ scoped_refptr<media::VideoFrame> target; if (subscriber_ && subscriber_->ShouldCaptureFrame( gfx::Rect(), present_time, &target, &callback)) { - SkColor c = ConvertRgbToYuv(controller_->GetSolidColor()); - media::FillYUV( - target.get(), SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(callback, present_time, gfx::Rect(), true)); - controller_->SignalCopy(); + CopyFromCompositingSurfaceToVideoFrame( + gfx::Rect(), target, base::Bind(callback, present_time)); } } private: std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber_; - CaptureTestSourceController* const controller_; gfx::Rect fake_bounds_; + SkColor yuv_color_; DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestView); }; -// A stub implementation which returns solid-color bitmaps in calls to -// CopyFromBackingStore(). The behavior is controlled by a -// CaptureTestSourceController. -class CaptureTestRenderWidgetHost : public RenderWidgetHostImpl { - public: - CaptureTestRenderWidgetHost(RenderWidgetHostDelegate* delegate, - RenderProcessHost* process, - int32_t routing_id, - CaptureTestSourceController* controller) - : RenderWidgetHostImpl(delegate, process, routing_id, false /* hidden */), - controller_(controller) {} - - // RenderWidgetHostImpl overrides. - void CopyFromBackingStore(const gfx::Rect& src_rect, - const gfx::Size& accelerated_dst_size, - const ReadbackRequestCallback& callback, - const SkColorType color_type) override { - gfx::Size size = controller_->GetCopyResultSize(); - SkColor color = controller_->GetSolidColor(); - - SkBitmap output; - EXPECT_TRUE(output.tryAllocN32Pixels(size.width(), size.height())); - { - SkAutoLockPixels locker(output); - output.eraseColor(color); - } - callback.Run(output, content::READBACK_SUCCESS); - controller_->SignalCopy(); - } - - private: - CaptureTestSourceController* controller_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderWidgetHost); -}; - class CaptureTestRenderViewHost : public TestRenderViewHost { public: CaptureTestRenderViewHost(SiteInstance* instance, @@ -274,21 +174,20 @@ RenderWidgetHostDelegate* widget_delegate, int32_t routing_id, int32_t main_frame_routing_id, - bool swapped_out, - CaptureTestSourceController* controller) + bool swapped_out) : TestRenderViewHost(instance, - base::MakeUnique<CaptureTestRenderWidgetHost>( + base::MakeUnique<RenderWidgetHostImpl>( widget_delegate, instance->GetProcess(), routing_id, - controller), + false /* This means: "Is not hidden." */), delegate, main_frame_routing_id, swapped_out) { // Override the default view installed by TestRenderViewHost; we need // our special subclass which has mocked-out tab capture support. RenderWidgetHostView* old_view = GetWidget()->GetView(); - GetWidget()->SetView(new CaptureTestView(GetWidget(), controller)); + GetWidget()->SetView(new CaptureTestView(GetWidget())); delete old_view; } @@ -298,10 +197,7 @@ class CaptureTestRenderViewHostFactory : public RenderViewHostFactory { public: - explicit CaptureTestRenderViewHostFactory( - CaptureTestSourceController* controller) : controller_(controller) { - RegisterFactory(this); - } + CaptureTestRenderViewHostFactory() { RegisterFactory(this); } ~CaptureTestRenderViewHostFactory() override { UnregisterFactory(); } @@ -315,13 +211,11 @@ bool swapped_out) override { return new CaptureTestRenderViewHost(instance, delegate, widget_delegate, routing_id, main_frame_routing_id, - swapped_out, controller_); + swapped_out); } private: - CaptureTestSourceController* controller_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(CaptureTestRenderViewHostFactory); + DISALLOW_COPY_AND_ASSIGN(CaptureTestRenderViewHostFactory); }; // A stub consumer of captured video frames, which checks the output of @@ -482,7 +376,7 @@ public: StubClientObserver() : error_encountered_(false), - wait_color_yuv_(0xcafe1950), + wait_color_yuv_(kWaitColorNotSet), expecting_frames_(true) { client_.reset(new StubClient( base::Bind(&StubClientObserver::DidDeliverFrame, @@ -497,12 +391,10 @@ } void SetIsExpectingFrames(bool expecting_frames) { - base::AutoLock guard(lock_); expecting_frames_ = expecting_frames; } void QuitIfConditionsMet(SkColor color, const gfx::Size& size) { - base::AutoLock guard(lock_); EXPECT_TRUE(expecting_frames_); if (error_encountered_ || wait_color_yuv_ == kNotInterested || wait_color_yuv_ == color) { @@ -515,56 +407,41 @@ // Run the current loop until the next frame is delivered. Returns the YUV // color and frame size. std::pair<SkColor, gfx::Size> WaitForNextFrame() { - { - base::AutoLock guard(lock_); - wait_color_yuv_ = kNotInterested; - error_encountered_ = false; - } + wait_color_yuv_ = kNotInterested; + error_encountered_ = false; + RunCurrentLoopWithDeadline(); - { - base::AutoLock guard(lock_); - CHECK(!error_encountered_); - return std::make_pair(last_frame_color_yuv_, last_frame_size_); - } + + CHECK(!error_encountered_); + return std::make_pair(last_frame_color_yuv_, last_frame_size_); } // Run the current loop until a frame is delivered with the |expected_color|. void WaitForNextColor(SkColor expected_color) { - { - base::AutoLock guard(lock_); - wait_color_yuv_ = ConvertRgbToYuv(expected_color); - error_encountered_ = false; - } + wait_color_yuv_ = ConvertRgbToYuv(expected_color); + error_encountered_ = false; + RunCurrentLoopWithDeadline(); - { - base::AutoLock guard(lock_); - ASSERT_FALSE(error_encountered_); - } + + ASSERT_FALSE(error_encountered_); } + // Run the current loop until an error is encountered. void WaitForError() { - { - base::AutoLock guard(lock_); - wait_color_yuv_ = kNotInterested; - error_encountered_ = false; - } + wait_color_yuv_ = kNotInterested; + error_encountered_ = false; + RunCurrentLoopWithDeadline(); - { - base::AutoLock guard(lock_); - ASSERT_TRUE(error_encountered_); - } + + ASSERT_TRUE(error_encountered_); } bool HasError() { - base::AutoLock guard(lock_); return error_encountered_; } void OnError() { - { - base::AutoLock guard(lock_); - error_encountered_ = true; - } + error_encountered_ = true; BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( &StubClientObserver::QuitIfConditionsMet, base::Unretained(this), @@ -581,7 +458,6 @@ } private: - base::Lock lock_; bool error_encountered_; SkColor wait_color_yuv_; SkColor last_frame_color_yuv_; @@ -592,17 +468,8 @@ DISALLOW_COPY_AND_ASSIGN(StubClientObserver); }; -// crbug.com/159234 -#if defined(OS_ANDROID) -#define MAYBE_WebContentsVideoCaptureDeviceTest \ - DISABLED_WebContentsVideoCaptureDeviceTest -#else -#define MAYBE_WebContentsVideoCaptureDeviceTest \ - WebContentsVideoCaptureDeviceTest -#endif // defined(OS_ANDROID) - // Test harness that sets up a minimal environment with necessary stubs. -class MAYBE_WebContentsVideoCaptureDeviceTest : public testing::Test { +class WebContentsVideoCaptureDeviceTest : public testing::Test { public: // This is public because C++ method pointer scoping rules are silly and make // this hard to use with Bind(). @@ -625,17 +492,17 @@ // TODO(nick): Sadness and woe! Much "mock-the-world" boilerplate could be // eliminated here, if only we could use RenderViewHostTestHarness. The - // catch is that we need our TestRenderViewHost to support a - // CopyFromBackingStore operation that we control. To accomplish that, + // catch is that we need to inject our CaptureTestView:: + // CopyFromCompositingSurfaceToVideoFrame() mock. To accomplish that, // either RenderViewHostTestHarness would have to support installing a // custom RenderViewHostFactory, or else we implant some kind of delegated - // CopyFromBackingStore functionality into TestRenderViewHost itself. + // CopyFromCompositingSurfaceToVideoFrame functionality into + // TestRenderViewHostView itself. render_process_host_factory_.reset(new MockRenderProcessHostFactory()); // Create our (self-registering) RVH factory, so that when we create a // WebContents, it in turn creates CaptureTestRenderViewHosts. - render_view_host_factory_.reset( - new CaptureTestRenderViewHostFactory(&controller_)); + render_view_host_factory_.reset(new CaptureTestRenderViewHostFactory()); render_frame_host_factory_.reset(new TestRenderFrameHostFactory()); browser_context_.reset(new TestBrowserContext()); @@ -657,9 +524,6 @@ void TearDown() override { // Tear down in opposite order of set-up. - // The device is destroyed asynchronously, and will notify the - // CaptureTestSourceController when it finishes destruction. - // Trigger this, and wait. if (device_) { device_->StopAndDeAllocate(); device_.reset(); @@ -682,14 +546,14 @@ } // Accessors. - CaptureTestSourceController* source() { return &controller_; } WebContents* web_contents() const { return web_contents_.get(); } + CaptureTestView* test_view() const { + return static_cast<CaptureTestView*>( + web_contents_->GetRenderViewHost()->GetWidget()->GetView()); + } media::VideoCaptureDevice* device() { return device_.get(); } - // Returns the device scale factor of the capture target's native view. This - // is necessary because, architecturally, the TestScreen implementation is - // ignored on Mac platforms (when determining the device scale factor for a - // particular window). + // Returns the device scale factor of the capture target's native view. float GetDeviceScaleFactor() const { RenderWidgetHostView* const view = web_contents_->GetRenderViewHost()->GetWidget()->GetView(); @@ -716,21 +580,17 @@ // Schedule the update to occur when the test runs the event loop (and not // before expectations have been set). - CaptureTestView* test_view = static_cast<CaptureTestView*>( - web_contents_->GetRenderViewHost()->GetWidget()->GetView()); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&CaptureTestView::SimulateUpdate, - base::Unretained(test_view))); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&CaptureTestView::SimulateUpdate, + base::Unretained(test_view()))); } void SimulateSourceSizeChange(const gfx::Size& size) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - CaptureTestView* test_view = static_cast<CaptureTestView*>( - web_contents_->GetRenderViewHost()->GetWidget()->GetView()); - test_view->SetSize(size); + auto* const view = test_view(); + view->SetSize(size); // Normally, RenderWidgetHostImpl would notify WebContentsImpl that the size - // has changed. However, in this test setup where there is no render + // has changed. However, in this test setup, where there is no render // process, we must notify WebContentsImpl directly. WebContentsImpl* const as_web_contents_impl = static_cast<WebContentsImpl*>(web_contents_.get()); @@ -788,16 +648,14 @@ private: display::test::TestScreen test_screen_; - StubClientObserver client_observer_; + TestBrowserThreadBundle thread_bundle_; - // The controller controls which pixel patterns to produce. - CaptureTestSourceController controller_; + StubClientObserver client_observer_; // Self-registering RenderProcessHostFactory. std::unique_ptr<MockRenderProcessHostFactory> render_process_host_factory_; - // Creates capture-capable RenderViewHosts whose pixel content production is - // under the control of |controller_|. + // Creates capture-capable RenderViewHosts. std::unique_ptr<CaptureTestRenderViewHostFactory> render_view_host_factory_; // Self-registering RenderFrameHostFactory. @@ -809,69 +667,55 @@ // Finally, the WebContentsVideoCaptureDevice under test. std::unique_ptr<media::VideoCaptureDevice> device_; - - TestBrowserThreadBundle thread_bundle_; }; -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, - InvalidInitialWebContentsError) { - // Before the installs itself on the UI thread up to start capturing, we'll - // delete the web contents. This should trigger an error which can happen in - // practice; we should be able to recover gracefully. +// In real-world use cases, there can exist a race condition between starting +// capture on a WebContents and having the WebContents be destroyed in the +// meantime. This tests that WebContentsVideoCaptureDevice errors-out +// gracefully. +TEST_F(WebContentsVideoCaptureDeviceTest, + SafelyStartsUpAfterWebContentsHasGone) { ResetWebContents(); - - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); + device()->AllocateAndStart(DefaultCaptureParams(), + client_observer()->PassClient()); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForError()); device()->StopAndDeAllocate(); } -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, WebContentsDestroyed) { - const float device_scale_factor = GetDeviceScaleFactor(); - const gfx::Size capture_preferred_size( - static_cast<int>(kTestWidth / device_scale_factor), - static_cast<int>(kTestHeight / device_scale_factor)); - ASSERT_NE(capture_preferred_size, web_contents()->GetPreferredSize()); - +// Tests that WebContentsVideoCaptureDevice starts, captures a frame, and then +// gracefully errors-out if the WebContents is destroyed before the device is +// stopped. +TEST_F(WebContentsVideoCaptureDeviceTest, + RunsThenErrorsOutWhenWebContentsIsDestroyed) { // We'll simulate the tab being closed after the capture pipeline is up and // running. - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); + device()->AllocateAndStart(DefaultCaptureParams(), + client_observer()->PassClient()); // Do one capture to prove the tab is initially open and being captured // normally. - source()->SetSolidColor(SK_ColorRED); + test_view()->SetSolidColor(SK_ColorRED); SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); base::RunLoop().RunUntilIdle(); - // Check that the preferred size of the WebContents matches the one provided - // by WebContentsVideoCaptureDevice. - EXPECT_EQ(capture_preferred_size, web_contents()->GetPreferredSize()); - // Post a task to close the tab. We should see an error reported to the // consumer. - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&MAYBE_WebContentsVideoCaptureDeviceTest::ResetWebContents, + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&WebContentsVideoCaptureDeviceTest::ResetWebContents, base::Unretained(this))); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForError()); device()->StopAndDeAllocate(); } -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, +// Sanity-check that starting/stopping the WebContentsVideoCaptureDevice, but +// without first returning to the event loop in-between, will behave rationally. +TEST_F(WebContentsVideoCaptureDeviceTest, StopDeviceBeforeCaptureMachineCreation) { - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); + device()->AllocateAndStart(DefaultCaptureParams(), + client_observer()->PassClient()); // Make a point of not running the UI messageloop here. device()->StopAndDeAllocate(); @@ -884,57 +728,42 @@ base::RunLoop().RunUntilIdle(); } -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, StopWithRendererWorkToDo) { - // Set up the test to use RGB captures into SkBitmaps instead of YUV captures - // into VideoFrames. - source()->SetCanCopyToVideoFrame(false); - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); - +// Tests that frames are delivered to different clients across restarts of the +// same instance. +TEST_F(WebContentsVideoCaptureDeviceTest, + DeliversToCorrectClientAcrossRestarts) { + // While the device is up-and-running, expect frame captures. + client_observer()->SetIsExpectingFrames(true); + device()->AllocateAndStart(DefaultCaptureParams(), + client_observer()->PassClient()); base::RunLoop().RunUntilIdle(); - - for (int i = 0; i < 3; ++i) - SimulateDrawEvent(); - - ASSERT_FALSE(client_observer()->HasError()); - device()->StopAndDeAllocate(); - ASSERT_FALSE(client_observer()->HasError()); - base::RunLoop().RunUntilIdle(); - ASSERT_FALSE(client_observer()->HasError()); -} - -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, DeviceRestart) { - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); - base::RunLoop().RunUntilIdle(); - source()->SetSolidColor(SK_ColorRED); - SimulateDrawEvent(); + test_view()->SetSolidColor(SK_ColorRED); SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); SimulateDrawEvent(); - SimulateDrawEvent(); - source()->SetSolidColor(SK_ColorGREEN); + test_view()->SetSolidColor(SK_ColorGREEN); SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); + SimulateDrawEvent(); device()->StopAndDeAllocate(); - // Device is stopped, but content can still be animating. + base::RunLoop().RunUntilIdle(); + + // Now that the device is stopped, expect frames are no longer captured. + client_observer()->SetIsExpectingFrames(false); SimulateDrawEvent(); SimulateDrawEvent(); base::RunLoop().RunUntilIdle(); + // Re-start the device with a different client. Only the second client should + // expect to see any frame captures. StubClientObserver observer2; - device()->AllocateAndStart(capture_params, observer2.PassClient()); - source()->SetSolidColor(SK_ColorBLUE); + observer2.SetIsExpectingFrames(true); + device()->AllocateAndStart(DefaultCaptureParams(), observer2.PassClient()); + test_view()->SetSolidColor(SK_ColorBLUE); SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(observer2.WaitForNextColor(SK_ColorBLUE)); - source()->SetSolidColor(SK_ColorYELLOW); + test_view()->SetSolidColor(SK_ColorYELLOW); SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(observer2.WaitForNextColor(SK_ColorYELLOW)); device()->StopAndDeAllocate(); @@ -944,69 +773,33 @@ // the picture emitted from the source and expect to see each delivered to the // consumer. The test will alternate between the RGB/SkBitmap and YUV/VideoFrame // capture paths. -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, GoesThroughAllTheMotions) { - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); +TEST_F(WebContentsVideoCaptureDeviceTest, GoesThroughAllTheMotions) { + device()->AllocateAndStart(DefaultCaptureParams(), + client_observer()->PassClient()); - for (int i = 0; i < 4; i++) { - const char* name = NULL; - if (i % 2) { - source()->SetCanCopyToVideoFrame(false); - name = "SkBitmap"; - } else { - source()->SetCanCopyToVideoFrame(true); - name = "VideoFrame"; - } + for (int i = 0; i < 3; i++) { + SCOPED_TRACE(base::StringPrintf("Iteration #%d", i)); - SCOPED_TRACE(base::StringPrintf("Using %s path, iteration #%d", name, i)); - - source()->SetSolidColor(SK_ColorRED); - SimulateDrawEvent(); + test_view()->SetSolidColor(SK_ColorRED); + for (int j = 0; j <= i; j++) + SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); - source()->SetSolidColor(SK_ColorGREEN); - SimulateDrawEvent(); + test_view()->SetSolidColor(SK_ColorGREEN); + for (int j = 0; j <= i; j++) + SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); - source()->SetSolidColor(SK_ColorBLUE); - SimulateDrawEvent(); + test_view()->SetSolidColor(SK_ColorBLUE); + for (int j = 0; j <= i; j++) + SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLUE)); - source()->SetSolidColor(SK_ColorBLACK); - SimulateDrawEvent(); + test_view()->SetSolidColor(SK_ColorBLACK); + for (int j = 0; j <= i; j++) + SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLACK)); } - device()->StopAndDeAllocate(); -} - -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, BadFramesGoodFrames) { - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - // 1x1 is too small to process; we intend for this to result in an error. - source()->SetCopyResultSize(1, 1); - source()->SetSolidColor(SK_ColorRED); - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); - - // These frames ought to be dropped during the Render stage. Let - // several captures to happen. - for (int i = 0; i < 3; ++i) { - SimulateDrawEvent(); - ASSERT_NO_FATAL_FAILURE(source()->WaitForNextCopy()); - } - - // Now push some good frames through; they should be processed normally. - source()->SetCopyResultSize(kTestWidth, kTestHeight); - source()->SetSolidColor(SK_ColorGREEN); - SimulateDrawEvent(); - ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); - source()->SetSolidColor(SK_ColorRED); - SimulateDrawEvent(); - ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); device()->StopAndDeAllocate(); } @@ -1014,20 +807,15 @@ // Tests that, when configured with the FIXED_ASPECT_RATIO resolution change // policy, the source size changes result in video frames of possibly varying // resolutions, but all with the same aspect ratio. -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, - VariableResolution_FixedAspectRatio) { - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; +TEST_F(WebContentsVideoCaptureDeviceTest, VariableResolution_FixedAspectRatio) { + auto capture_params = DefaultCaptureParams(); capture_params.resolution_change_policy = media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); // Source size equals maximum size. Expect delivered frames to be // kTestWidth by kTestHeight. - source()->SetSolidColor(SK_ColorRED); + test_view()->SetSolidColor(SK_ColorRED); const float device_scale_factor = GetDeviceScaleFactor(); SimulateSourceSizeChange(gfx::ConvertSizeToDIP( device_scale_factor, gfx::Size(kTestWidth, kTestHeight))); @@ -1037,7 +825,7 @@ // Source size is half in both dimensions. Expect delivered frames to be of // the same aspect ratio as kTestWidth by kTestHeight, but larger than the // half size because the minimum height is 180 lines. - source()->SetSolidColor(SK_ColorGREEN); + test_view()->SetSolidColor(SK_ColorGREEN); SimulateSourceSizeChange(gfx::ConvertSizeToDIP( device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight / 2))); SimulateDrawsUntilNewFrameSizeArrives( @@ -1045,7 +833,7 @@ // Source size changes aspect ratio. Expect delivered frames to be padded // in the horizontal dimension to preserve aspect ratio. - source()->SetSolidColor(SK_ColorBLUE); + test_view()->SetSolidColor(SK_ColorBLUE); SimulateSourceSizeChange(gfx::ConvertSizeToDIP( device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight))); SimulateDrawsUntilNewFrameSizeArrives( @@ -1053,7 +841,7 @@ // Source size changes aspect ratio again. Expect delivered frames to be // padded in the vertical dimension to preserve aspect ratio. - source()->SetSolidColor(SK_ColorBLACK); + test_view()->SetSolidColor(SK_ColorBLACK); SimulateSourceSizeChange(gfx::ConvertSizeToDIP( device_scale_factor, gfx::Size(kTestWidth, kTestHeight / 2))); SimulateDrawsUntilNewFrameSizeArrives( @@ -1065,20 +853,15 @@ // Tests that, when configured with the ANY_WITHIN_LIMIT resolution change // policy, the source size changes result in video frames of possibly varying // resolutions. -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, - VariableResolution_AnyWithinLimits) { - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; +TEST_F(WebContentsVideoCaptureDeviceTest, VariableResolution_AnyWithinLimits) { + auto capture_params = DefaultCaptureParams(); capture_params.resolution_change_policy = media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); // Source size equals maximum size. Expect delivered frames to be // kTestWidth by kTestHeight. - source()->SetSolidColor(SK_ColorRED); + test_view()->SetSolidColor(SK_ColorRED); const float device_scale_factor = GetDeviceScaleFactor(); SimulateSourceSizeChange(gfx::ConvertSizeToDIP( device_scale_factor, gfx::Size(kTestWidth, kTestHeight))); @@ -1087,7 +870,7 @@ // Source size is half in both dimensions. Expect delivered frames to also // be half in both dimensions. - source()->SetSolidColor(SK_ColorGREEN); + test_view()->SetSolidColor(SK_ColorGREEN); SimulateSourceSizeChange(gfx::ConvertSizeToDIP( device_scale_factor, gfx::Size(kTestWidth / 2, kTestHeight / 2))); SimulateDrawsUntilNewFrameSizeArrives( @@ -1096,7 +879,7 @@ // Source size changes to something arbitrary. Since the source size is // less than the maximum size, expect delivered frames to be the same size // as the source size. - source()->SetSolidColor(SK_ColorBLUE); + test_view()->SetSolidColor(SK_ColorBLUE); gfx::Size arbitrary_source_size(kTestWidth / 2 + 42, kTestHeight - 10); SimulateSourceSizeChange(gfx::ConvertSizeToDIP(device_scale_factor, arbitrary_source_size)); @@ -1105,7 +888,7 @@ // Source size changes to something arbitrary that exceeds the maximum frame // size. Since the source size exceeds the maximum size, expect delivered // frames to be downscaled. - source()->SetSolidColor(SK_ColorBLACK); + test_view()->SetSolidColor(SK_ColorBLACK); arbitrary_source_size = gfx::Size(kTestWidth * 2, kTestHeight / 2); SimulateSourceSizeChange(gfx::ConvertSizeToDIP(device_scale_factor, arbitrary_source_size)); @@ -1117,7 +900,7 @@ device()->StopAndDeAllocate(); } -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, +TEST_F(WebContentsVideoCaptureDeviceTest, ComputesStandardResolutionsForPreferredSize) { // Helper function to run the same testing procedure for multiple combinations // of |policy|, |standard_size| and |oddball_size|. @@ -1141,10 +924,8 @@ ASSERT_NE(capture_preferred_size, web_contents()->GetPreferredSize()); // Start the WebContentsVideoCaptureDevice. - media::VideoCaptureParams capture_params; + auto capture_params = DefaultCaptureParams(); capture_params.requested_format.frame_size = oddball_size; - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; capture_params.resolution_change_policy = policy; StubClientObserver unused_observer; device()->AllocateAndStart(capture_params, unused_observer.PassClient()); @@ -1212,16 +993,13 @@ } // Tests the Suspend/Resume() functionality. -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, SuspendsAndResumes) { - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); +TEST_F(WebContentsVideoCaptureDeviceTest, SuspendsAndResumes) { + device()->AllocateAndStart(DefaultCaptureParams(), + client_observer()->PassClient()); for (int i = 0; i < 3; ++i) { // Draw a RED frame and wait for a normal frame capture to occur. - source()->SetSolidColor(SK_ColorRED); + test_view()->SetSolidColor(SK_ColorRED); SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); @@ -1230,7 +1008,7 @@ device()->MaybeSuspend(); base::RunLoop().RunUntilIdle(); client_observer()->SetIsExpectingFrames(false); - source()->SetSolidColor(SK_ColorGREEN); + test_view()->SetSolidColor(SK_ColorGREEN); SimulateDrawEvent(); base::RunLoop().RunUntilIdle(); @@ -1238,7 +1016,7 @@ device()->Resume(); base::RunLoop().RunUntilIdle(); client_observer()->SetIsExpectingFrames(true); - source()->SetSolidColor(SK_ColorBLUE); + test_view()->SetSolidColor(SK_ColorBLUE); SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorBLUE)); } @@ -1247,28 +1025,25 @@ } // Tests the RequestRefreshFrame() functionality. -TEST_F(MAYBE_WebContentsVideoCaptureDeviceTest, ProvidesRefreshFrames) { - media::VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight); - capture_params.requested_format.frame_rate = kTestFramesPerSecond; - capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; - device()->AllocateAndStart(capture_params, client_observer()->PassClient()); +TEST_F(WebContentsVideoCaptureDeviceTest, ProvidesRefreshFrames) { + device()->AllocateAndStart(DefaultCaptureParams(), + client_observer()->PassClient()); // Request a refresh frame before the first frame has been drawn. This forces // a capture. - source()->SetSolidColor(SK_ColorRED); + test_view()->SetSolidColor(SK_ColorRED); SimulateRefreshFrameRequest(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); // Now, draw a frame and wait for a normal frame capture to occur. - source()->SetSolidColor(SK_ColorGREEN); + test_view()->SetSolidColor(SK_ColorGREEN); SimulateDrawEvent(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); // Now, make three more refresh frame requests. Although the source has // changed to BLUE, no draw event has occurred. Therefore, expect the refresh // frames to contain the content from the last drawn frame, which is GREEN. - source()->SetSolidColor(SK_ColorBLUE); + test_view()->SetSolidColor(SK_ColorBLUE); for (int i = 0; i < 3; ++i) { SimulateRefreshFrameRequest(); ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN));
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index a3b1f904..affcac9 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -324,7 +324,6 @@ : frame_sink_id_( ui::ContextProviderFactory::GetInstance()->AllocateFrameSinkId()), resource_manager_(root_window), - device_scale_factor_(1), window_(NULL), surface_handle_(gpu::kNullSurfaceHandle), client_(client), @@ -443,7 +442,7 @@ host_->SetFrameSinkId(frame_sink_id_); host_->GetLayerTree()->SetViewportSize(size_); SetHasTransparentBackground(false); - host_->GetLayerTree()->SetDeviceScaleFactor(device_scale_factor_); + host_->GetLayerTree()->SetDeviceScaleFactor(1); if (needs_animate_) host_->SetNeedsAnimate(); @@ -471,12 +470,6 @@ } } -void CompositorImpl::setDeviceScaleFactor(float factor) { - device_scale_factor_ = factor; - if (host_) - host_->GetLayerTree()->SetDeviceScaleFactor(factor); -} - void CompositorImpl::SetWindowBounds(const gfx::Size& size) { if (size_ == size) return;
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 506f5cca..83ff584 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -67,7 +67,6 @@ // Compositor implementation. void SetRootLayer(scoped_refptr<cc::Layer> root) override; void SetSurface(jobject surface) override; - void setDeviceScaleFactor(float factor) override; void SetWindowBounds(const gfx::Size& size) override; void SetHasTransparentBackground(bool flag) override; void SetNeedsComposite() override; @@ -142,7 +141,6 @@ gfx::Size size_; bool has_transparent_background_; - float device_scale_factor_; ANativeWindow* window_; gpu::SurfaceHandle surface_handle_;
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc index dca1d39c..6af09c0 100644 --- a/content/browser/renderer_host/media/video_capture_manager.cc +++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -661,7 +661,9 @@ DCHECK(IsOnDeviceThread()); std::unique_ptr<VideoCaptureDevice> video_capture_device; +#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) video_capture_device = WebContentsVideoCaptureDevice::Create(id); +#endif if (!video_capture_device) { device_client->OnError(FROM_HERE, "Could not create capture device"); @@ -689,6 +691,7 @@ } if (desktop_id.type == DesktopMediaID::TYPE_WEB_CONTENTS) { +#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) video_capture_device = WebContentsVideoCaptureDevice::Create(id); IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED); if (desktop_id.audio_share) { @@ -696,6 +699,7 @@ } else { IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITHOUT_AUDIO); } +#endif } else { #if defined(OS_ANDROID) video_capture_device = base::MakeUnique<ScreenCaptureDeviceAndroid>();
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_impl.cc b/content/browser/renderer_host/offscreen_canvas_surface_impl.cc index a4a88ac..045fa0b 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_impl.cc +++ b/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
@@ -45,17 +45,13 @@ } void OffscreenCanvasSurfaceImpl::OnSurfaceCreated( - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { - DCHECK_EQ(surface_id.frame_sink_id(), frame_sink_id_); + const cc::SurfaceInfo& surface_info) { + DCHECK_EQ(surface_info.id().frame_sink_id(), frame_sink_id_); if (!current_local_frame_id_.is_valid() || - surface_id.local_frame_id() != current_local_frame_id_) { - current_local_frame_id_ = surface_id.local_frame_id(); - if (client_) { - client_->OnSurfaceCreated(surface_id, frame_size.width(), - frame_size.height(), device_scale_factor); - } + surface_info.id().local_frame_id() != current_local_frame_id_) { + current_local_frame_id_ = surface_info.id().local_frame_id(); + if (client_) + client_->OnSurfaceCreated(surface_info); } }
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_impl.h b/content/browser/renderer_host/offscreen_canvas_surface_impl.h index 10ab17f..8cf437d2 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_impl.h +++ b/content/browser/renderer_host/offscreen_canvas_surface_impl.h
@@ -26,9 +26,7 @@ blink::mojom::OffscreenCanvasSurfaceClientPtr client, blink::mojom::OffscreenCanvasSurfaceRequest request); - void OnSurfaceCreated(const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor); + void OnSurfaceCreated(const cc::SurfaceInfo& surface_info); // blink::mojom::OffscreenCanvasSurface implementation. void Require(const cc::SurfaceId& surface_id,
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_manager.cc b/content/browser/renderer_host/offscreen_canvas_surface_manager.cc index c7cfad2..65ff06e 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_manager.cc +++ b/content/browser/renderer_host/offscreen_canvas_surface_manager.cc
@@ -28,15 +28,13 @@ } void OffscreenCanvasSurfaceManager::OnSurfaceCreated( - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { + const cc::SurfaceInfo& surface_info) { auto surface_iter = - registered_surface_instances_.find(surface_id.frame_sink_id()); + registered_surface_instances_.find(surface_info.id().frame_sink_id()); if (surface_iter == registered_surface_instances_.end()) return; OffscreenCanvasSurfaceImpl* surfaceImpl = surface_iter->second; - surfaceImpl->OnSurfaceCreated(surface_id, frame_size, device_scale_factor); + surfaceImpl->OnSurfaceCreated(surface_info); } void OffscreenCanvasSurfaceManager::RegisterOffscreenCanvasSurfaceInstance(
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_manager.h b/content/browser/renderer_host/offscreen_canvas_surface_manager.h index 5b557ba..e53cea70 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_manager.h +++ b/content/browser/renderer_host/offscreen_canvas_surface_manager.h
@@ -29,9 +29,7 @@ friend class OffscreenCanvasSurfaceManagerTest; // cc::SurfaceObserver implementation. - void OnSurfaceCreated(const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) override; + void OnSurfaceCreated(const cc::SurfaceInfo& surface_info) override; void OnSurfaceDamaged(const cc::SurfaceId&, bool* changed) override {} // When an OffscreenCanvasSurfaceImpl instance is destructed, it will
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_manager_unittest.cc b/content/browser/renderer_host/offscreen_canvas_surface_manager_unittest.cc index d47a516..104228e 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_manager_unittest.cc +++ b/content/browser/renderer_host/offscreen_canvas_surface_manager_unittest.cc
@@ -28,7 +28,7 @@ void OnSurfaceCreated(const cc::SurfaceId& surface_id) { OffscreenCanvasSurfaceManager::GetInstance()->OnSurfaceCreated( - surface_id, gfx::Size(10, 10), 1.0); + cc::SurfaceInfo(surface_id, 1.0f, gfx::Size(10, 10))); } protected:
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index cb19f36..a839178ca 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -259,9 +259,7 @@ class FakeSurfaceObserver : public cc::SurfaceObserver { public: - void OnSurfaceCreated(const cc::SurfaceId& surface_id, - const gfx::Size& frame, - float device_scale_factor) override {} + void OnSurfaceCreated(const cc::SurfaceInfo& surface_info) override {} void OnSurfaceDamaged(const cc::SurfaceId& id, bool* changed) override { *changed = true;
diff --git a/content/public/browser/android/compositor.h b/content/public/browser/android/compositor.h index 0b8cc876..be022bc5 100644 --- a/content/public/browser/android/compositor.h +++ b/content/public/browser/android/compositor.h
@@ -42,9 +42,6 @@ // Attaches the layer tree. virtual void SetRootLayer(scoped_refptr<cc::Layer> root) = 0; - // Set the scale factor from DIP to pixel. - virtual void setDeviceScaleFactor(float factor) = 0; - // Set the output surface bounds. virtual void SetWindowBounds(const gfx::Size& size) = 0;
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index a96612f..7f215a7ab 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -129,8 +129,8 @@ EnableCompositing(true); DCHECK(compositing_helper_.get()); - compositing_helper_->OnSetSurface(surface_id, frame_size, scale_factor, - sequence); + compositing_helper_->OnSetSurface( + cc::SurfaceInfo(surface_id, scale_factor, frame_size), sequence); } void BrowserPlugin::SendSatisfySequence(const cc::SurfaceSequence& sequence) {
diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index 3a6ec7c..dd1459c 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc
@@ -209,11 +209,10 @@ } void ChildFrameCompositingHelper::OnSetSurface( - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float scale_factor, + const cc::SurfaceInfo& surface_info, const cc::SurfaceSequence& sequence) { - surface_id_ = surface_id; + float scale_factor = surface_info.device_scale_factor(); + surface_id_ = surface_info.id(); scoped_refptr<cc::SurfaceLayer> surface_layer = cc::SurfaceLayer::Create(surface_reference_factory_); // TODO(oshima): This is a stopgap fix so that the compositor does not @@ -221,8 +220,9 @@ // Fix this in cc/. if (IsUseZoomForDSFEnabled()) scale_factor = 1.0f; - cc::SurfaceInfo info(surface_id, scale_factor, frame_size); - surface_layer->SetSurfaceInfo(info, + + surface_layer->SetSurfaceInfo(cc::SurfaceInfo(surface_info.id(), scale_factor, + surface_info.size_in_pixels()), false /* stretch_content_to_fill_bounds */); surface_layer->SetMasksToBounds(true); std::unique_ptr<cc_blink::WebLayerImpl> layer( @@ -247,7 +247,7 @@ } CheckSizeAndAdjustLayerProperties( - frame_size, scale_factor, + surface_info.size_in_pixels(), surface_info.device_scale_factor(), static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer()); }
diff --git a/content/renderer/child_frame_compositing_helper.h b/content/renderer/child_frame_compositing_helper.h index 634f4af6..aa90625 100644 --- a/content/renderer/child_frame_compositing_helper.h +++ b/content/renderer/child_frame_compositing_helper.h
@@ -24,6 +24,7 @@ struct SurfaceSequence; class Layer; +class SurfaceInfo; } namespace blink { @@ -50,9 +51,7 @@ RenderFrameProxy* render_frame_proxy); void OnContainerDestroy(); - void OnSetSurface(const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float scale_factor, + void OnSetSurface(const cc::SurfaceInfo& surface_info, const cc::SurfaceSequence& sequence); void UpdateVisibility(bool); void ChildFrameGone();
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index fbb1c17..c318049c 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -338,8 +338,8 @@ compositing_helper_ = ChildFrameCompositingHelper::CreateForRenderFrameProxy(this); } - compositing_helper_->OnSetSurface(surface_id, frame_size, scale_factor, - sequence); + compositing_helper_->OnSetSurface( + cc::SurfaceInfo(surface_id, scale_factor, frame_size), sequence); } void RenderFrameProxy::OnUpdateOpener(int opener_routing_id) {
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn index bd907a9..27cc2f86 100644 --- a/content/shell/android/BUILD.gn +++ b/content/shell/android/BUILD.gn
@@ -182,7 +182,11 @@ android_manifest_dep = ":chromium_linker_test_manifest" } - android_apk("chromium_linker_test_apk") { + _linker_test_apk_target_name = "chromium_linker_test_apk__apk" + _linker_test_apk_test_runner_target_name = + "chromium_linker_test_apk__test_runner_script" + + android_apk(_linker_test_apk_target_name) { testonly = true deps = [ ":content_shell_assets", @@ -205,6 +209,21 @@ enable_chromium_linker_tests = true } + test_runner_script(_linker_test_apk_test_runner_target_name) { + test_name = "chromium_linker_test_apk" + test_type = "linker" + apk_target = ":$_linker_test_apk_target_name" + ignore_all_data_deps = true + } + + group("chromium_linker_test_apk") { + testonly = true + deps = [ + ":$_linker_test_apk_target_name", + ":$_linker_test_apk_test_runner_target_name", + ] + } + shared_library("linker_test") { testonly = true sources = [
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index f8bfe0d..4a38768 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -480,6 +480,7 @@ "//skia", "//ui/accessibility:ax_gen", "//ui/events/blink", + "//ui/gfx:test_support", "//v8", ] @@ -1127,9 +1128,7 @@ "../browser/media/audible_metrics_unittest.cc", "../browser/media/audio_stream_monitor_unittest.cc", "../browser/media/capture/audio_mirroring_manager_unittest.cc", - "../browser/media/capture/cursor_renderer_aura_unittest.cc", "../browser/media/capture/web_contents_audio_input_stream_unittest.cc", - "../browser/media/capture/web_contents_video_capture_device_unittest.cc", "../browser/media/cdm_registry_impl_unittest.cc", "../browser/media/media_internals_unittest.cc", "../browser/media/midi_host_unittest.cc", @@ -1586,11 +1585,6 @@ deps += [ "//third_party/webrtc/modules/desktop_capture" ] } - if (is_chromeos) { - sources += - [ "../browser/media/capture/desktop_capture_device_aura_unittest.cc" ] - } - if (is_chromecast) { sources -= [ "../renderer/media/audio_track_recorder_unittest.cc", @@ -1607,6 +1601,18 @@ ] } + # Screen capture unit tests. + if (is_linux || is_mac || is_win) { + sources += [ "../browser/media/capture/web_contents_video_capture_device_unittest.cc" ] + if (use_aura) { + sources += [ "../browser/media/capture/cursor_renderer_aura_unittest.cc" ] + } + if (is_chromeos) { + sources += + [ "../browser/media/capture/desktop_capture_device_aura_unittest.cc" ] + } + } + if (is_linux) { if (use_dbus) { deps += [ "//dbus:test_support" ] @@ -1684,7 +1690,7 @@ } # Avoid windows due to non-availability of cursor resources in test. - if (!use_aura || is_win) { + if (is_win) { sources -= [ "../browser/media/capture/cursor_renderer_aura_unittest.cc" ] } if (use_aura || toolkit_views) {
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index fad81abc..fefd00e 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -53,6 +53,7 @@ #include "ui/events/blink/blink_event_util.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/icc_profile.h" +#include "ui/gfx/test/icc_profiles.h" #if defined(OS_MACOSX) #include "content/browser/frame_host/popup_menu_helper_mac.h" @@ -493,554 +494,15 @@ } gfx::ICCProfile GetTestingICCProfile(const std::string& name) { - const unsigned char rgb_profile_data[] = { - 0x00, 0x00, 0x07, 0xd8, 0x61, 0x70, 0x70, 0x6c, 0x02, 0x20, 0x00, 0x00, - 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, - 0x07, 0xd9, 0x00, 0x02, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x1a, 0x00, 0x0b, - 0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c, 0x00, 0x00, 0x00, 0x00, - 0x61, 0x70, 0x70, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x61, 0x70, 0x70, 0x6c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x6f, - 0x64, 0x73, 0x63, 0x6d, 0x00, 0x00, 0x01, 0x78, 0x00, 0x00, 0x05, 0x9c, - 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x07, 0x14, 0x00, 0x00, 0x00, 0x38, - 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x07, 0x60, 0x00, 0x00, 0x00, 0x14, - 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x07, 0x74, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x07, 0x88, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x07, 0x9c, 0x00, 0x00, 0x00, 0x0e, - 0x63, 0x68, 0x61, 0x64, 0x00, 0x00, 0x07, 0xac, 0x00, 0x00, 0x00, 0x2c, - 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x07, 0x9c, 0x00, 0x00, 0x00, 0x0e, - 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x07, 0x9c, 0x00, 0x00, 0x00, 0x0e, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x52, 0x47, 0x42, 0x20, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, - 0x69, 0x63, 0x20, 0x52, 0x47, 0x42, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6c, 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0c, 0x73, 0x6b, 0x53, 0x4b, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0x84, 0x64, 0x61, 0x44, 0x4b, - 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x01, 0xac, 0x63, 0x61, 0x45, 0x53, - 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0xda, 0x76, 0x69, 0x56, 0x4e, - 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0xfe, 0x70, 0x74, 0x42, 0x52, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x02, 0x22, 0x75, 0x6b, 0x55, 0x41, - 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x02, 0x48, 0x66, 0x72, 0x46, 0x55, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x02, 0x72, 0x68, 0x75, 0x48, 0x55, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x02, 0x9a, 0x7a, 0x68, 0x54, 0x57, - 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x02, 0xc2, 0x6e, 0x62, 0x4e, 0x4f, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x02, 0xd8, 0x63, 0x73, 0x43, 0x5a, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x02, 0xfe, 0x68, 0x65, 0x49, 0x4c, - 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x03, 0x20, 0x69, 0x74, 0x49, 0x54, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x03, 0x3e, 0x72, 0x6f, 0x52, 0x4f, - 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x03, 0x66, 0x64, 0x65, 0x44, 0x45, - 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x03, 0x8a, 0x6b, 0x6f, 0x4b, 0x52, - 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x03, 0xb6, 0x73, 0x76, 0x53, 0x45, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x02, 0xd8, 0x7a, 0x68, 0x43, 0x4e, - 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x03, 0xcc, 0x6a, 0x61, 0x4a, 0x50, - 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x03, 0xe2, 0x65, 0x6c, 0x47, 0x52, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x03, 0xfc, 0x70, 0x74, 0x50, 0x4f, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x04, 0x1e, 0x6e, 0x6c, 0x4e, 0x4c, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0x44, 0x65, 0x73, 0x45, 0x53, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x04, 0x1e, 0x74, 0x68, 0x54, 0x48, - 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x04, 0x6c, 0x74, 0x72, 0x54, 0x52, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x04, 0x90, 0x66, 0x69, 0x46, 0x49, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0xb2, 0x68, 0x72, 0x48, 0x52, - 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0xda, 0x70, 0x6c, 0x50, 0x4c, - 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x05, 0x02, 0x72, 0x75, 0x52, 0x55, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x05, 0x2e, 0x61, 0x72, 0x45, 0x47, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x05, 0x50, 0x65, 0x6e, 0x55, 0x53, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x05, 0x76, 0x00, 0x56, 0x01, 0x61, - 0x00, 0x65, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6e, - 0x00, 0xfd, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, - 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, - 0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, - 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x2d, - 0x00, 0x62, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x72, 0x00, 0x69, - 0x00, 0x76, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x65, 0x00, 0x50, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, - 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x67, 0x00, 0x65, - 0x00, 0x6e, 0x00, 0xe8, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x43, - 0x1e, 0xa5, 0x00, 0x75, 0x00, 0x20, 0x00, 0x68, 0x00, 0xec, 0x00, 0x6e, - 0x00, 0x68, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, - 0x00, 0x43, 0x00, 0x68, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x50, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, - 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x47, 0x00, 0x65, - 0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6f, - 0x04, 0x17, 0x04, 0x30, 0x04, 0x33, 0x04, 0x30, 0x04, 0x3b, 0x04, 0x4c, - 0x04, 0x3d, 0x04, 0x38, 0x04, 0x39, 0x00, 0x20, 0x04, 0x3f, 0x04, 0x40, - 0x04, 0x3e, 0x04, 0x44, 0x04, 0x30, 0x04, 0x39, 0x04, 0x3b, 0x00, 0x20, - 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, - 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x67, 0x00, 0xe9, - 0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72, 0x00, 0x69, 0x00, 0x71, 0x00, 0x75, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00, 0x56, 0x00, 0x42, 0x00, 0xc1, - 0x00, 0x6c, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6c, 0x00, 0xe1, 0x00, 0x6e, - 0x00, 0x6f, 0x00, 0x73, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, - 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, - 0x00, 0x6c, 0x90, 0x1a, 0x75, 0x28, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, - 0x00, 0x42, 0x00, 0x20, 0x82, 0x72, 0x5f, 0x69, 0x63, 0xcf, 0x8f, 0xf0, - 0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, - 0x00, 0x73, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, - 0x00, 0x2d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, - 0x00, 0x6c, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6e, - 0x00, 0xfd, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, - 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, - 0x05, 0xe4, 0x05, 0xe8, 0x05, 0xd5, 0x05, 0xe4, 0x05, 0xd9, 0x05, 0xdc, - 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x05, 0xdb, - 0x05, 0xdc, 0x05, 0xdc, 0x05, 0xd9, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, - 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x52, - 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6e, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x50, - 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, - 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x67, 0x00, 0x65, - 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x41, - 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, - 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x52, - 0x00, 0x47, 0x00, 0x42, 0x00, 0x2d, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, - 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0xc7, 0x7c, 0xbc, 0x18, 0x00, 0x20, - 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0xd5, 0x04, 0xb8, 0x5c, - 0xd3, 0x0c, 0xc7, 0x7c, 0x66, 0x6e, 0x90, 0x1a, 0x00, 0x20, 0x00, 0x52, - 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x63, 0xcf, 0x8f, 0xf0, 0x65, 0x87, - 0x4e, 0xf6, 0x4e, 0x00, 0x82, 0x2c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, - 0x00, 0x42, 0x00, 0x20, 0x30, 0xd7, 0x30, 0xed, 0x30, 0xd5, 0x30, 0xa1, - 0x30, 0xa4, 0x30, 0xeb, 0x03, 0x93, 0x03, 0xb5, 0x03, 0xbd, 0x03, 0xb9, - 0x03, 0xba, 0x03, 0xcc, 0x00, 0x20, 0x03, 0xc0, 0x03, 0xc1, 0x03, 0xbf, - 0x03, 0xc6, 0x03, 0xaf, 0x03, 0xbb, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, - 0x00, 0x42, 0x00, 0x50, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x69, - 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, - 0x00, 0x67, 0x00, 0x65, 0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72, 0x00, 0x69, - 0x00, 0x63, 0x00, 0x6f, 0x00, 0x41, 0x00, 0x6c, 0x00, 0x67, 0x00, 0x65, - 0x00, 0x6d, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x52, - 0x00, 0x47, 0x00, 0x42, 0x00, 0x2d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, - 0x00, 0x66, 0x00, 0x69, 0x00, 0x65, 0x00, 0x6c, 0x0e, 0x42, 0x0e, 0x1b, - 0x0e, 0x23, 0x0e, 0x44, 0x0e, 0x1f, 0x0e, 0x25, 0x0e, 0x4c, 0x00, 0x20, - 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x0e, 0x17, 0x0e, 0x31, - 0x0e, 0x48, 0x0e, 0x27, 0x0e, 0x44, 0x0e, 0x1b, 0x00, 0x47, 0x00, 0x65, - 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x59, 0x00, 0x6c, 0x00, 0x65, - 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x52, - 0x00, 0x47, 0x00, 0x42, 0x00, 0x2d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, - 0x00, 0x66, 0x00, 0x69, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x47, - 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x01, 0x0d, - 0x00, 0x6b, 0x00, 0x69, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, - 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, - 0x00, 0x6c, 0x00, 0x55, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x77, 0x00, 0x65, - 0x00, 0x72, 0x00, 0x73, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x6e, 0x00, 0x79, - 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, - 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x04, 0x1e, - 0x04, 0x31, 0x04, 0x49, 0x04, 0x38, 0x04, 0x39, 0x00, 0x20, 0x04, 0x3f, - 0x04, 0x40, 0x04, 0x3e, 0x04, 0x44, 0x04, 0x38, 0x04, 0x3b, 0x04, 0x4c, - 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x06, 0x45, 0x06, 0x44, - 0x06, 0x41, 0x00, 0x20, 0x06, 0x2a, 0x06, 0x39, 0x06, 0x31, 0x06, 0x4a, - 0x06, 0x41, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, - 0x06, 0x27, 0x06, 0x44, 0x06, 0x39, 0x06, 0x27, 0x06, 0x45, 0x00, 0x47, - 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, - 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x50, - 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, - 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, - 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x37, 0x20, 0x41, - 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x2c, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x72, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x00, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x52, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x01, 0x16, 0xcf, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x74, 0x4d, 0x00, 0x00, 0x3d, 0xee, 0x00, 0x00, 0x03, 0xd0, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x75, - 0x00, 0x00, 0xac, 0x73, 0x00, 0x00, 0x17, 0x34, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1a, 0x00, 0x00, 0x15, 0x9f, - 0x00, 0x00, 0xb8, 0x36, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x01, 0xcd, 0x00, 0x00, 0x73, 0x66, 0x33, 0x32, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x42, 0x00, 0x00, 0x05, 0xde, - 0xff, 0xff, 0xf3, 0x26, 0x00, 0x00, 0x07, 0x92, 0x00, 0x00, 0xfd, 0x91, - 0xff, 0xff, 0xfb, 0xa2, 0xff, 0xff, 0xfd, 0xa3, 0x00, 0x00, 0x03, 0xdc, - 0x00, 0x00, 0xc0, 0x6c - }; - - const unsigned char srgb_profile_data[] = { - 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00, 0x00, - 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, - 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, - 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, - 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x33, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x00, 0x6c, - 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x14, - 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x2c, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, - 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70, - 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, - 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x86, - 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24, - 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x14, - 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x24, - 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x0c, - 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, - 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, - 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, - 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, - 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, - 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74, 0x74, 0x2d, 0x50, - 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, - 0x6e, 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, - 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, - 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, - 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00, 0x38, 0xf5, - 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x62, 0x99, 0x00, 0x00, 0xb7, 0x85, 0x00, 0x00, 0x18, 0xda, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xa0, - 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, - 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e, - 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, - 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, - 0x31, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, - 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, - 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, - 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, - 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, - 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65, - 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, - 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x65, 0x77, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa4, 0xfe, 0x00, 0x14, 0x5f, 0x2e, - 0x00, 0x10, 0xcf, 0x14, 0x00, 0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, - 0x00, 0x03, 0x5c, 0x9e, 0x00, 0x00, 0x00, 0x01, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, - 0x00, 0x57, 0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8f, - 0x00, 0x00, 0x00, 0x02, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, - 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, - 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, - 0x00, 0x4f, 0x00, 0x54, 0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, - 0x00, 0x6d, 0x00, 0x72, 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, - 0x00, 0x8b, 0x00, 0x90, 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, - 0x00, 0xa9, 0x00, 0xae, 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, - 0x00, 0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, - 0x00, 0xe5, 0x00, 0xeb, 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, - 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, - 0x01, 0x2b, 0x01, 0x32, 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, - 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, - 0x01, 0x7c, 0x01, 0x83, 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, - 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, - 0x01, 0xd9, 0x01, 0xe1, 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, - 0x02, 0x0c, 0x02, 0x14, 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, - 0x02, 0x41, 0x02, 0x4b, 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, - 0x02, 0x7a, 0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, - 0x02, 0xb6, 0x02, 0xc1, 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, - 0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, - 0x03, 0x38, 0x03, 0x43, 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, - 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, - 0x03, 0xc7, 0x03, 0xd3, 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, - 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, - 0x04, 0x63, 0x04, 0x71, 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, - 0x04, 0xb6, 0x04, 0xc4, 0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, - 0x05, 0x0d, 0x05, 0x1c, 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, - 0x05, 0x67, 0x05, 0x77, 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, - 0x05, 0xc5, 0x05, 0xd5, 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, - 0x06, 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, - 0x06, 0x8c, 0x06, 0x9d, 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, - 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, - 0x07, 0x61, 0x07, 0x74, 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, - 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, - 0x08, 0x46, 0x08, 0x5a, 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, - 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, - 0x09, 0x3a, 0x09, 0x4f, 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, - 0x09, 0xba, 0x09, 0xcf, 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, - 0x0a, 0x3d, 0x0a, 0x54, 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, - 0x0a, 0xc5, 0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, - 0x0b, 0x51, 0x0b, 0x69, 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, - 0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, - 0x0c, 0x75, 0x0c, 0x8e, 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, - 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, - 0x0d, 0xa9, 0x0d, 0xc3, 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, - 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, - 0x0e, 0xee, 0x0f, 0x09, 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, - 0x0f, 0x96, 0x0f, 0xb3, 0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, - 0x10, 0x43, 0x10, 0x61, 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, - 0x10, 0xf5, 0x11, 0x13, 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, - 0x11, 0xaa, 0x11, 0xc9, 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, - 0x12, 0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, - 0x13, 0x23, 0x13, 0x43, 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, - 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, - 0x14, 0xad, 0x14, 0xce, 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, - 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, - 0x16, 0x49, 0x16, 0x6c, 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, - 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, - 0x17, 0xf7, 0x18, 0x1b, 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, - 0x18, 0xd5, 0x18, 0xfa, 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, - 0x19, 0xb7, 0x19, 0xdd, 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, - 0x1a, 0x9e, 0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, - 0x1b, 0x8a, 0x1b, 0xb2, 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, - 0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, - 0x1d, 0x70, 0x1d, 0x99, 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, - 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, - 0x1f, 0x69, 0x1f, 0x94, 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, - 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, - 0x21, 0x75, 0x21, 0xa1, 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, - 0x22, 0x82, 0x22, 0xaf, 0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, - 0x23, 0x94, 0x23, 0xc2, 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, - 0x24, 0xab, 0x24, 0xda, 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, - 0x25, 0xc7, 0x25, 0xf7, 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, - 0x26, 0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, - 0x28, 0x0d, 0x28, 0x3f, 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, - 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, - 0x2a, 0x68, 0x2a, 0x9b, 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, - 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, - 0x2c, 0xd7, 0x2d, 0x0c, 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, - 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, - 0x2f, 0x5a, 0x2f, 0x91, 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, - 0x30, 0xa4, 0x30, 0xdb, 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, - 0x31, 0xf2, 0x32, 0x2a, 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, - 0x33, 0x46, 0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, - 0x34, 0x9e, 0x34, 0xd8, 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, - 0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, - 0x37, 0x60, 0x37, 0x9c, 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, - 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, - 0x3a, 0x36, 0x3a, 0x74, 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, - 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, - 0x3d, 0x22, 0x3d, 0x61, 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, - 0x3e, 0xa0, 0x3e, 0xe0, 0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, - 0x40, 0x23, 0x40, 0x64, 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, - 0x41, 0xac, 0x41, 0xee, 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, - 0x43, 0x3a, 0x43, 0x7d, 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, - 0x44, 0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, - 0x46, 0x67, 0x46, 0xab, 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, - 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, - 0x49, 0xa9, 0x49, 0xf0, 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, - 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, - 0x4d, 0x02, 0x4d, 0x4a, 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, - 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, - 0x50, 0x71, 0x50, 0xbb, 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, - 0x52, 0x31, 0x52, 0x7c, 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, - 0x53, 0xf6, 0x54, 0x42, 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, - 0x55, 0xc2, 0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, - 0x57, 0x92, 0x57, 0xe0, 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, - 0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, - 0x5b, 0x45, 0x5b, 0x95, 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, - 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, - 0x5f, 0x0f, 0x5f, 0x61, 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, - 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, - 0x62, 0xf0, 0x63, 0x43, 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, - 0x64, 0xe9, 0x65, 0x3d, 0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, - 0x66, 0xe8, 0x67, 0x3d, 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, - 0x68, 0xec, 0x69, 0x43, 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, - 0x6a, 0xf7, 0x6b, 0x4f, 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, - 0x6d, 0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, - 0x6f, 0x1e, 0x6f, 0x78, 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, - 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, - 0x73, 0x5d, 0x73, 0xb8, 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, - 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, - 0x77, 0xb3, 0x78, 0x11, 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, - 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, - 0x7c, 0x21, 0x7c, 0x81, 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, - 0x7e, 0x62, 0x7e, 0xc2, 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, - 0x80, 0xa8, 0x81, 0x0a, 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, - 0x82, 0xf4, 0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, - 0x85, 0x47, 0x85, 0xab, 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, - 0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, - 0x89, 0xfe, 0x8a, 0x64, 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, - 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, - 0x8e, 0xce, 0x8f, 0x36, 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, - 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, - 0x93, 0xb6, 0x94, 0x20, 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, - 0x96, 0x34, 0x96, 0x9f, 0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, - 0x98, 0xb8, 0x99, 0x24, 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, - 0x9b, 0x42, 0x9b, 0xaf, 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, - 0x9d, 0xd2, 0x9e, 0x40, 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, - 0xa0, 0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, - 0xa3, 0x06, 0xa3, 0x76, 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, - 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, - 0xa8, 0x52, 0xa8, 0xc4, 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, - 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, - 0xad, 0xb8, 0xae, 0x2d, 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, - 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, - 0xb3, 0x38, 0xb3, 0xae, 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, - 0xb6, 0x01, 0xb6, 0x79, 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, - 0xb8, 0xd1, 0xb9, 0x4a, 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, - 0xbb, 0xa7, 0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, - 0xbe, 0x84, 0xbe, 0xff, 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, - 0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, - 0xc4, 0x51, 0xc4, 0xce, 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, - 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, - 0xca, 0x38, 0xca, 0xb7, 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, - 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, - 0xd0, 0x39, 0xd0, 0xba, 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, - 0xd3, 0x44, 0xd3, 0xc6, 0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, - 0xd6, 0x55, 0xd6, 0xd8, 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, - 0xd9, 0x6c, 0xd9, 0xf1, 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, - 0xdc, 0x8a, 0xdd, 0x10, 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, - 0xdf, 0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, - 0xe2, 0xdb, 0xe3, 0x63, 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, - 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, - 0xe9, 0x46, 0xe9, 0xd0, 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, - 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, - 0xef, 0xcc, 0xf0, 0x58, 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, - 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, - 0xf6, 0x6d, 0xf6, 0xfb, 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, - 0xf9, 0xc7, 0xfa, 0x57, 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, - 0xfd, 0x29, 0xfd, 0xba, 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff - }; - - const unsigned char colorspin_profile_data[] = { - 0x00, 0x00, 0x01, 0xea, 0x54, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, - 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x61, 0x63, 0x73, 0x70, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, - 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x74, 0x65, 0x73, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0d, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8c, - 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xa0, 0x00, 0x00, 0x00, 0x14, - 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xb4, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x77, 0x68, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x2e, - 0x69, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x52, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, - 0x00, 0x00, 0x0f, 0x95, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x26, 0x31, 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9b, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, - 0x00, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x04, 0xfc, 0x63, 0x75, 0x72, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33 - }; - - const unsigned char adobe_rgb_profile_data[] = { - 0x00, 0x00, 0x02, 0x30, 0x41, 0x44, 0x42, 0x45, 0x02, 0x10, 0x00, 0x00, - 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, - 0x07, 0xd0, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x33, 0x00, 0x3b, - 0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c, 0x00, 0x00, 0x00, 0x00, - 0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x41, 0x44, 0x42, 0x45, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, - 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x32, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x6b, - 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xc4, 0x00, 0x00, 0x00, 0x0e, - 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x00, 0x0e, - 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, 0x00, 0x0e, - 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x00, 0x14, - 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x14, - 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, - 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20, 0x41, - 0x64, 0x6f, 0x62, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, - 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, - 0x64, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x11, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x52, 0x47, - 0x42, 0x20, 0x28, 0x31, 0x39, 0x39, 0x38, 0x29, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33, 0x00, 0x00, - 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x33, 0x00, 0x00, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x33, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, 0x00, 0x00, 0x4f, 0xa5, - 0x00, 0x00, 0x04, 0xfc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, 0x00, 0x00, 0x0f, 0x95, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x31, - 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9c - }; - - const unsigned char* data = nullptr; - size_t size = 0; if (name == "genericRGB") { - data = rgb_profile_data; - size = sizeof(rgb_profile_data); + return gfx::ICCProfileForTestingGenericRGB(); } else if (name == "sRGB") { - data = srgb_profile_data; - size = sizeof(srgb_profile_data); + return gfx::ICCProfileForTestingSRGB(); } else if (name == "test" || name == "colorSpin") { - data = colorspin_profile_data; - size = sizeof(colorspin_profile_data); + return gfx::ICCProfileForTestingColorSpin(); } else if (name == "adobeRGB") { - data = adobe_rgb_profile_data; - size = sizeof(adobe_rgb_profile_data); + return gfx::ICCProfileForTestingAdobeRGB(); } - - if (data) - return gfx::ICCProfile::FromData(reinterpret_cast<const char*>(data), size); return gfx::ICCProfile(); }
diff --git a/gpu/command_buffer/tests/compressed_texture_test.cc b/gpu/command_buffer/tests/compressed_texture_test.cc index 03a31d2d..80bf37fb 100644 --- a/gpu/command_buffer/tests/compressed_texture_test.cc +++ b/gpu/command_buffer/tests/compressed_texture_test.cc
@@ -233,9 +233,9 @@ for (unsigned i = 0; i < kPaletteSize; ++i) { origin[0] = kBlockSize * i; ToRGB888(kPalette[i], expected_rgba); - EXPECT_TRUE(GLTestHelper::CheckPixels(origin[0], origin[1], - kBlockSize, kBlockSize, - 0, expected_rgba)); + EXPECT_TRUE(GLTestHelper::CheckPixels(origin[0], origin[1], kBlockSize, + kBlockSize, 0, expected_rgba, + nullptr)); } GLTestHelper::CheckGLError("CompressedTextureTest.Draw", __LINE__); }
diff --git a/gpu/command_buffer/tests/gl_apply_screen_space_antialiasing_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_apply_screen_space_antialiasing_CHROMIUM_unittest.cc index 04bb9e9..9a516a2d 100644 --- a/gpu/command_buffer/tests/gl_apply_screen_space_antialiasing_CHROMIUM_unittest.cc +++ b/gpu/command_buffer/tests/gl_apply_screen_space_antialiasing_CHROMIUM_unittest.cc
@@ -120,7 +120,7 @@ glCheckFramebufferStatus(GL_FRAMEBUFFER)); uint8_t pixels[1 * 4] = {0u, 255u, 0u, 255u}; - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels, nullptr); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); } @@ -159,7 +159,7 @@ << index; uint8_t pixels[1 * 4] = {0u, 255u, 0u, 255u}; - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels, nullptr); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); } } @@ -188,7 +188,7 @@ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); uint8_t pixels[1 * 4] = {0u, 255u, 0u, 255u}; - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels, nullptr); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); } } @@ -219,18 +219,18 @@ uint8_t transparent[4] = {0u, 0u, 0u, 0u}; uint8_t red[4] = {255u, 0u, 0u, 255u}; - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, red); - GLTestHelper::CheckPixels(0, 1, 1, 1, 0, red); - GLTestHelper::CheckPixels(0, 2, 1, 1, 0, transparent); - GLTestHelper::CheckPixels(1, 0, 1, 1, 0, red); - GLTestHelper::CheckPixels(1, 1, 1, 1, 0, transparent); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, red, nullptr); + GLTestHelper::CheckPixels(0, 1, 1, 1, 0, red, nullptr); + GLTestHelper::CheckPixels(0, 2, 1, 1, 0, transparent, nullptr); + GLTestHelper::CheckPixels(1, 0, 1, 1, 0, red, nullptr); + GLTestHelper::CheckPixels(1, 1, 1, 1, 0, transparent, nullptr); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); glApplyScreenSpaceAntialiasingCHROMIUM(); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, red); - GLTestHelper::CheckPixels(2, 2, 1, 1, 0, transparent); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, red, nullptr); + GLTestHelper::CheckPixels(2, 2, 1, 1, 0, transparent, nullptr); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); // Check if middle pixel is anti-aliased. @@ -394,9 +394,9 @@ }; glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero, nullptr)); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected, nullptr)); // Call copyTextureCHROMIUM uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u}; @@ -409,9 +409,9 @@ // test using program after glClear(GL_COLOR_BUFFER_BIT); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero, nullptr)); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected, nullptr)); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
diff --git a/gpu/command_buffer/tests/gl_bind_uniform_location_unittest.cc b/gpu/command_buffer/tests/gl_bind_uniform_location_unittest.cc index 8856500..7c02ade 100644 --- a/gpu/command_buffer/tests/gl_bind_uniform_location_unittest.cc +++ b/gpu/command_buffer/tests/gl_bind_uniform_location_unittest.cc
@@ -95,8 +95,8 @@ glDrawArrays(GL_TRIANGLES, 0, 6); static const uint8_t expected[] = {64, 128, 192, 255}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 1, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 1, + expected, nullptr)); GLTestHelper::CheckGLError("no errors", __LINE__); } @@ -262,8 +262,8 @@ glDrawArrays(GL_TRIANGLES, 0, 6); static const uint8_t expected[] = {204, 204, 204, 204}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 1, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 1, + expected, nullptr)); GLTestHelper::CheckGLError("no errors", __LINE__);
diff --git a/gpu/command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc b/gpu/command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc index ece68710..96b9fc8 100644 --- a/gpu/command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc +++ b/gpu/command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc
@@ -100,15 +100,8 @@ GLuint resolve_fbo, resolve_tex; glGenTextures(1, &resolve_tex); glBindTexture(GL_TEXTURE_2D, resolve_tex); - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - width, - height, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -150,9 +143,9 @@ const uint8_t green[] = {0, 255, 0, 255}; const uint8_t black[] = {0, 0, 0, 0}; glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo); - EXPECT_TRUE( - GLTestHelper::CheckPixels(width / 4, (3 * height) / 4, 1, 1, 0, green)); - EXPECT_TRUE(GLTestHelper::CheckPixels(width - 1, 0, 1, 1, 0, black)); + EXPECT_TRUE(GLTestHelper::CheckPixels(width / 4, (3 * height) / 4, 1, 1, 0, + green, nullptr)); + EXPECT_TRUE(GLTestHelper::CheckPixels(width - 1, 0, 1, 1, 0, black, nullptr)); } } // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_chromium_path_rendering_unittest.cc b/gpu/command_buffer/tests/gl_chromium_path_rendering_unittest.cc index 35dd0da..6481a0ba 100644 --- a/gpu/command_buffer/tests/gl_chromium_path_rendering_unittest.cc +++ b/gpu/command_buffer/tests/gl_chromium_path_rendering_unittest.cc
@@ -154,7 +154,8 @@ float fx = kFillCoords[i]; float fy = kFillCoords[i + 1]; - EXPECT_TRUE(GLTestHelper::CheckPixels(x + fx, y + fy, 1, 1, 0, kBlue)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(x + fx, y + fy, 1, 1, 0, kBlue, nullptr)); } } @@ -168,8 +169,8 @@ float bx = kBackgroundCoords[i]; float by = kBackgroundCoords[i + 1]; - EXPECT_TRUE( - GLTestHelper::CheckPixels(x + bx, y + by, 1, 1, 0, kExpectedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(x + bx, y + by, 1, 1, 0, + kExpectedColor, nullptr)); } } @@ -177,13 +178,17 @@ SCOPED_TRACE(testing::Message() << "Verifying stroke at " << x << "," << y); // Inside the stroke we should have green. const uint8_t kGreen[] = {0, 255, 0, 255}; - EXPECT_TRUE(GLTestHelper::CheckPixels(x + 50, y + 53, 1, 1, 0, kGreen)); - EXPECT_TRUE(GLTestHelper::CheckPixels(x + 26, y + 76, 1, 1, 0, kGreen)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(x + 50, y + 53, 1, 1, 0, kGreen, nullptr)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(x + 26, y + 76, 1, 1, 0, kGreen, nullptr)); // Outside the path we should have black. const uint8_t black[] = {0, 0, 0, 0}; - EXPECT_TRUE(GLTestHelper::CheckPixels(x + 10, y + 10, 1, 1, 0, black)); - EXPECT_TRUE(GLTestHelper::CheckPixels(x + 80, y + 80, 1, 1, 0, black)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(x + 10, y + 10, 1, 1, 0, black, nullptr)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(x + 80, y + 80, 1, 1, 0, black, nullptr)); } static const GLfloat kProjectionMatrix[16]; GLint color_loc_; @@ -455,8 +460,8 @@ // Make sure nothing got drawn by the drawing commands that should not produce // anything. const uint8_t black[] = {0, 0, 0, 0}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 0, black)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 0, + black, nullptr)); } TEST_F(CHROMIUMPathRenderingTest, TestUnnamedPathsErrors) { @@ -1085,8 +1090,8 @@ color[2] = 0; color[3] = 255; - EXPECT_TRUE( - GLTestHelper::CheckPixels(px + fx, py + fy, 1, 1, 2, color)); + EXPECT_TRUE(GLTestHelper::CheckPixels(px + fx, py + fy, 1, 1, 2, color, + nullptr)); } } } @@ -1185,8 +1190,8 @@ color[2] = 0; color[3] = 255; - EXPECT_TRUE( - GLTestHelper::CheckPixels(px + fx, py + fy, 1, 1, 2, color)); + EXPECT_TRUE(GLTestHelper::CheckPixels(px + fx, py + fy, 1, 1, 2, color, + nullptr)); } } } @@ -1584,8 +1589,8 @@ uint8_t color[4] = {0, 255, 0, 255}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(px + fx, py + fy, 1, 1, 2, color)); + EXPECT_TRUE(GLTestHelper::CheckPixels(px + fx, py + fy, 1, 1, 2, + color, nullptr)); } } } @@ -1678,8 +1683,8 @@ uint8_t color[4] = {0, 255, 0, 255}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(px + fx, py + fy, 1, 1, 2, color)); + EXPECT_TRUE(GLTestHelper::CheckPixels(px + fx, py + fy, 1, 1, 2, color, + nullptr)); } } }
diff --git a/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc b/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc index 6b31c9b..ff2ca79 100644 --- a/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc +++ b/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc
@@ -127,8 +127,8 @@ // Verify. const uint8_t expected[] = {255, 128, 64, 128}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, expected, + nullptr)); } TEST_P(GLClearFramebufferTest, ClearColorWithMask) { @@ -142,8 +142,8 @@ // Verify. const uint8_t expected[] = {255, 0, 0, 0}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected, + nullptr)); } // crbug.com/434094 @@ -158,8 +158,8 @@ // Verify. const uint8_t expected[] = {255, 255, 255, 255}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected, + nullptr)); glScissor(0, 0, 0, 0); glEnable(GL_SCISSOR_TEST); @@ -167,8 +167,8 @@ glClear(GL_COLOR_BUFFER_BIT); // Verify - no changes. - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected, + nullptr)); } #endif @@ -185,7 +185,7 @@ const uint8_t kRed[] = {255, 0, 0, 255}; const uint8_t kGreen[] = {0, 255, 0, 255}; EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed)); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed, nullptr)); glClearStencil(kStencilRef); glClear(GL_STENCIL_BUFFER_BIT); @@ -197,13 +197,13 @@ DrawQuad(); // Verify - stencil should have failed, so still red. EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed)); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed, nullptr)); glStencilFunc(GL_EQUAL, kStencilRef, 0xFFFFFFFF); DrawQuad(); // Verify - stencil should have passed, so green. - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kGreen)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kGreen, + nullptr)); glEnable(GL_DEPTH_TEST); glClearDepthf(0.0f); @@ -213,15 +213,15 @@ SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f); DrawQuad(); // Verify - depth test should have failed, so still green. - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kGreen)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kGreen, + nullptr)); glClearDepthf(0.9f); glClear(GL_DEPTH_BUFFER_BIT); DrawQuad(); // Verify - depth test should have passed, so red. EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed)); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed, nullptr)); } } // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc index de5244cd..56cab18 100644 --- a/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc +++ b/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc
@@ -151,7 +151,7 @@ glDrawArrays(GL_TRIANGLES, 0, 6); glFlush(); - GLTestHelper::CheckPixels(0, 0, 4, 4, 0, kCompressedImageColor); + GLTestHelper::CheckPixels(0, 0, 4, 4, 0, kCompressedImageColor, nullptr); EXPECT_TRUE(GL_NO_ERROR == glGetError()); }
diff --git a/gpu/command_buffer/tests/gl_copy_tex_image_2d_workaround_unittest.cc b/gpu/command_buffer/tests/gl_copy_tex_image_2d_workaround_unittest.cc index fc78349a..1e24863 100644 --- a/gpu/command_buffer/tests/gl_copy_tex_image_2d_workaround_unittest.cc +++ b/gpu/command_buffer/tests/gl_copy_tex_image_2d_workaround_unittest.cc
@@ -12,6 +12,8 @@ #include "base/command_line.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/stringize_macros.h" +#include "base/strings/stringprintf.h" #include "build/build_config.h" #include "gpu/command_buffer/tests/gl_manager.h" #include "gpu/command_buffer/tests/gl_test_utils.h" @@ -21,6 +23,62 @@ namespace gpu { #if defined(OS_MACOSX) +namespace { + +// clang-format off +static const char* kSimpleVertexShader = STRINGIZE( + attribute vec2 a_position; + varying vec2 v_texCoord; + void main() { + gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); + v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5; + } +); +// clang-format on + +// Generate fragment shader source for sampling out of a texture of |size| +// bound to |target|. +std::string GetFragmentShaderSource(unsigned target, const gfx::Size& size) { + // clang-format off + const char kFragmentShader[] = STRINGIZE( + uniform SamplerType u_texture; + varying vec2 v_texCoord; + void main() { + gl_FragColor = TextureLookup(u_texture, v_texCoord * TextureScale); + } + ); + const char kShaderFloatPrecision[] = STRINGIZE( + precision mediump float; + ); + // clang-format on + + switch (target) { + case GL_TEXTURE_2D: + return base::StringPrintf( + "%s\n" + "#define SamplerType sampler2D\n" + "#define TextureLookup texture2D\n" + "#define TextureScale vec2(1.0, 1.0)\n" + "%s", + kShaderFloatPrecision, kFragmentShader); + case GL_TEXTURE_RECTANGLE_ARB: + return base::StringPrintf( + "%s\n" + "#extension GL_ARB_texture_rectangle : require\n" + "#define SamplerType sampler2DRect\n" + "#define TextureLookup texture2DRect\n" + "#define TextureScale vec2(%f, %f)\n" + "%s", + kShaderFloatPrecision, static_cast<double>(size.width()), + static_cast<double>(size.height()), kFragmentShader); + default: + NOTREACHED(); + return std::string(); + } +} + +} // namespace + // A collection of tests that exercise the glCopyTexImage2D workaround. The // parameter expresses different formats of the destination texture. class GLCopyTexImage2DWorkaroundTest : public testing::TestWithParam<GLenum> { @@ -29,13 +87,13 @@ protected: void SetUp() override { - base::CommandLine command_line(0, NULL); - command_line.AppendSwitchASCII( - switches::kGpuDriverBugWorkarounds, - base::IntToString(gpu::USE_INTERMEDIARY_FOR_COPY_TEXTURE_IMAGE)); - gl_.InitializeWithCommandLine(GLManager::Options(), command_line); - gl_.set_use_iosurface_memory_buffers(true); - DCHECK(gl_.workarounds().use_intermediary_for_copy_texture_image); + base::CommandLine command_line(0, nullptr); + command_line.AppendSwitchASCII( + switches::kGpuDriverBugWorkarounds, + base::IntToString(gpu::USE_INTERMEDIARY_FOR_COPY_TEXTURE_IMAGE)); + gl_.InitializeWithCommandLine(GLManager::Options(), command_line); + gl_.set_use_iosurface_memory_buffers(true); + DCHECK(gl_.workarounds().use_intermediary_for_copy_texture_image); } void TearDown() override { @@ -108,12 +166,16 @@ EXPECT_EQ(glGetError(), GLenum(GL_NO_ERROR)); glViewport(0, 0, width, height); - GLTestHelper::DrawTextureQuad(dest_target, gfx::Size(width, height)); + std::string fragment_shader_source = + GetFragmentShaderSource(dest_target, gfx::Size(width, height)); + GLTestHelper::DrawTextureQuad(kSimpleVertexShader, + fragment_shader_source.c_str(), "a_position", + "u_texture"); // Verify. const uint8_t* expected = expectations[i]; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, + expected, nullptr)); } }
diff --git a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc index 1c005eba..364fb155 100644 --- a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc +++ b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
@@ -210,15 +210,9 @@ void SetUp() override { gl_.Initialize(GLManager::Options()); - - CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); } - void TearDown() override { - glDeleteTextures(2, textures_); - glDeleteFramebuffers(1, &framebuffer_id_); - gl_.Destroy(); - } + void TearDown() override { gl_.Destroy(); } void CreateBackingForTexture(GLenum target, GLsizei width, GLsizei height) { if (target == GL_TEXTURE_RECTANGLE_ARB) { @@ -259,8 +253,6 @@ gl_.Initialize(options); } - void TearDown() override { gl_.Destroy(); } - // If a driver isn't capable of supporting ES3 context, creating // ContextGroup will fail. Just skip the test. bool ShouldSkipTest() const { @@ -316,6 +308,7 @@ CopyType copy_type = GetParam(); uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u}; + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); @@ -343,7 +336,7 @@ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), glCheckFramebufferStatus(GL_FRAMEBUFFER)); - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels, nullptr); EXPECT_TRUE(GL_NO_ERROR == glGetError()); } @@ -494,53 +487,21 @@ glCheckFramebufferStatus(GL_FRAMEBUFFER)); glViewport(0, 0, kWidth, kHeight); + glBindTexture(GL_TEXTURE_2D, textures_[1]); std::string fragment_shader_source = GetFragmentShaderSource(dest_format_type.internal_format); - GLuint program = GLTestHelper::LoadProgram( - kSimpleVertexShaderES3, fragment_shader_source.c_str()); - EXPECT_NE(program, 0u); - GLint position_loc = glGetAttribLocation(program, "a_position"); - GLint texture_loc = glGetUniformLocation(program, "u_texture"); - ASSERT_NE(position_loc, -1); - ASSERT_NE(texture_loc, -1); - glUseProgram(program); + GLTestHelper::DrawTextureQuad(kSimpleVertexShaderES3, + fragment_shader_source.c_str(), + "a_position", "u_texture"); - GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc); - ASSERT_NE(vbo, 0u); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textures_[1]); - - glDrawArrays(GL_TRIANGLES, 0, 6); - - EXPECT_TRUE(GL_NO_ERROR == glGetError()); - - GLsizei size = kWidth * kHeight * 4; - std::unique_ptr<uint8_t[]> result(new uint8_t[size]); - glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, - result.get()); uint8_t tolerance = dest_format_type.internal_format == GL_RGBA4 ? 20 : 7; - for (GLint yy = 0; yy < kHeight; ++yy) { - for (GLint xx = 0; xx < kWidth; ++xx) { - int offset = yy * kWidth * 4 + xx * 4; - for (int jj = 0; jj < 4; ++jj) { - uint8_t actual = result[offset + jj]; - uint8_t expected = expected_color[jj]; - int diff = actual - expected; - diff = diff < 0 ? -diff : diff; - if (mask[jj] && diff > tolerance) { - EXPECT_EQ(expected, actual) - << " at " << xx << ", " << yy << " channel " << jj - << " src_internal_format: " - << gles2::GLES2Util::GetStringEnum( - src_format_type.internal_format) - << " dest_internal_format: " - << gles2::GLES2Util::GetStringEnum( - dest_format_type.internal_format); - } - } - } - } + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kWidth, kHeight, tolerance, + expected_color, mask)) + << " src_internal_format: " + << gles2::GLES2Util::GetStringEnum(src_format_type.internal_format) + << " dest_internal_format: " + << gles2::GLES2Util::GetStringEnum(dest_format_type.internal_format); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); glDeleteTextures(1, &texture); glDeleteFramebuffers(1, &framebuffer); @@ -563,10 +524,7 @@ for (auto src_internal_format : src_internal_formats) { for (auto dest_internal_format : dest_internal_formats) { - glDeleteTextures(2, textures_); - glDeleteFramebuffers(1, &framebuffer_id_); CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexStorage2DEXT(GL_TEXTURE_2D, 1, src_internal_format, 1, 1); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, @@ -599,9 +557,11 @@ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), glCheckFramebufferStatus(GL_FRAMEBUFFER)); - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels, nullptr); EXPECT_TRUE(GL_NO_ERROR == glGetError()); } + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } } } @@ -615,6 +575,7 @@ for (size_t src_index = 0; src_index < arraysize(src_formats); src_index++) { for (size_t dest_index = 0; dest_index < arraysize(dest_formats); dest_index++) { + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, src_formats[src_index], 1, 1, 0, src_formats[src_index], GL_UNSIGNED_BYTE, nullptr); @@ -636,12 +597,15 @@ EXPECT_TRUE(GL_NO_ERROR == glGetError()) << "src_index:" << src_index << " dest_index:" << dest_index; + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } } } TEST_P(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) { CopyType copy_type = GetParam(); + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -666,9 +630,12 @@ EXPECT_TRUE(GL_INVALID_OPERATION == glGetError()) << "dest_index:" << dest_index; } + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } TEST_F(GLCopyTextureCHROMIUMTest, InternalFormatTypeCombinationNotSupported) { + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -689,6 +656,8 @@ EXPECT_TRUE(GL_INVALID_OPERATION == glGetError()) << "dest_index:" << dest_index; } + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } // Test to ensure that the destination texture is redefined if the properties @@ -697,6 +666,7 @@ uint8_t pixels[4 * 4] = {255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u}; + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); @@ -745,7 +715,11 @@ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), glCheckFramebufferStatus(GL_FRAMEBUFFER)); - GLTestHelper::CheckPixels(1, 1, 1, 1, 0, &pixels[12]); + GLTestHelper::CheckPixels(1, 1, 1, 1, 0, &pixels[12], nullptr); + + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); } @@ -766,6 +740,7 @@ CopyType copy_type = GetParam(); uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u}; + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, textures_[0]); @@ -822,6 +797,9 @@ EXPECT_EQ(GL_TEXTURE1 + x, active_texture); } + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); }; @@ -831,6 +809,7 @@ CopyType copy_type = GetParam(); // Setup the texture used for the extension invocation. uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u}; + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); @@ -875,6 +854,8 @@ glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(2, texture_ids); + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); EXPECT_TRUE(GL_NO_ERROR == glGetError()); } @@ -885,6 +866,7 @@ CopyType copy_type = GetParam(); // Setup the texture used for the extension invocation. uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u}; + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); @@ -920,7 +902,7 @@ uint8_t expected_color[4] = {255u, 255u, 0, 255u}; glClearColor(1.0, 1.0, 0, 1.0); glClear(GL_COLOR_BUFFER_BIT); - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color, nullptr); if (copy_type == TexImage) { glCopyTextureCHROMIUM(textures_[0], textures_[1], GL_RGBA, @@ -934,12 +916,12 @@ EXPECT_TRUE(glIsFramebuffer(framebuffer_id)); // Ensure that reading from the framebuffer produces correct pixels. - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color, nullptr); uint8_t expected_color2[4] = {255u, 0, 255u, 255u}; glClearColor(1.0, 0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color2); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color2, nullptr); GLint bound_fbo = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo); @@ -972,13 +954,15 @@ glDeleteRenderbuffers(1, &renderbuffer_id); glDeleteTextures(1, &texture_id); glDeleteFramebuffers(1, &framebuffer_id); + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); EXPECT_TRUE(GL_NO_ERROR == glGetError()); } TEST_P(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) { CopyType copy_type = GetParam(); - // unbind the one created in setup. + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); @@ -1026,9 +1010,9 @@ 0, 0, 0, 0, }; glClear(GL_COLOR_BUFFER_BIT); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero, nullptr)); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected, nullptr)); // Call copyTextureCHROMIUM uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u}; @@ -1048,9 +1032,12 @@ // test using program after glClear(GL_COLOR_BUFFER_BIT); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero, nullptr)); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected, nullptr)); + + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); EXPECT_TRUE(GL_NO_ERROR == glGetError()); @@ -1063,6 +1050,7 @@ TEST_P(GLCopyTextureCHROMIUMTest, UninitializedSource) { CopyType copy_type = GetParam(); const GLsizei kWidth = 64, kHeight = 64; + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -1090,10 +1078,14 @@ } } + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); } TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureDimension) { + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -1125,9 +1117,13 @@ glCopySubTextureCHROMIUM(textures_[0], textures_[1], 0, 0, 1, 1, 2, 2, false, false, false); EXPECT_TRUE(glGetError() == GL_INVALID_VALUE); + + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } TEST_F(GLCopyTextureCHROMIUMTest, CopyTextureInvalidTextureIds) { + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -1151,9 +1147,13 @@ glCopyTextureCHROMIUM(textures_[0], textures_[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, false); EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureInvalidTextureIds) { + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -1177,11 +1177,15 @@ glCopySubTextureCHROMIUM(textures_[0], textures_[1], 1, 1, 0, 0, 1, 1, false, false, false); EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureOffset) { uint8_t rgba_pixels[4 * 4] = {255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u, 0u, 0u, 255u, 255u, 0u, 0u, 0u, 255u}; + CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba_pixels); @@ -1216,11 +1220,14 @@ uint8_t red[1 * 4] = {255u, 0u, 0u, 255u}; uint8_t green[1 * 4] = {0u, 255u, 0u, 255u}; uint8_t blue[1 * 4] = {0u, 0u, 255u, 255u}; - GLTestHelper::CheckPixels(0, 0, 1, 1, 0, transparent); - GLTestHelper::CheckPixels(1, 1, 1, 1, 0, red); - GLTestHelper::CheckPixels(1, 0, 1, 1, 0, green); - GLTestHelper::CheckPixels(0, 1, 1, 1, 0, blue); + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, transparent, nullptr); + GLTestHelper::CheckPixels(1, 1, 1, 1, 0, red, nullptr); + GLTestHelper::CheckPixels(1, 0, 1, 1, 0, green, nullptr); + GLTestHelper::CheckPixels(0, 1, 1, 1, 0, blue, nullptr); EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } TEST_F(GLCopyTextureCHROMIUMTest, CopyTextureBetweenTexture2DAndRectangleArb) { @@ -1252,11 +1259,6 @@ dest_index++) { GLenum dest_target = dest_targets[dest_index]; - // SetUp() sets up textures with the wrong parameters for this test, and - // TearDown() expects to successfully delete textures/framebuffers, so - // this is the right place for the delete/create calls. - glDeleteTextures(2, textures_); - glDeleteFramebuffers(1, &framebuffer_id_); CreateAndBindDestinationTextureAndFBO(dest_target); // Allocate source and destination textures. @@ -1300,7 +1302,7 @@ for (GLint y = 0; y < dest_height; ++y) { if (x < copy_region_x || x >= copy_region_x + copy_region_width || y < copy_region_y || y >= copy_region_y + copy_region_height) { - GLTestHelper::CheckPixels(x, y, 1, 1, 0, grey); + GLTestHelper::CheckPixels(x, y, 1, 1, 0, grey, nullptr); continue; } @@ -1310,9 +1312,12 @@ } else { expected_color = y < copy_region_y + 1 ? blue : white; } - GLTestHelper::CheckPixels(x, y, 1, 1, 0, expected_color); + GLTestHelper::CheckPixels(x, y, 1, 1, 0, expected_color, nullptr); } } + + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); } } }
diff --git a/gpu/command_buffer/tests/gl_cube_map_texture_unittest.cc b/gpu/command_buffer/tests/gl_cube_map_texture_unittest.cc index 96d0e463..eab89b15 100644 --- a/gpu/command_buffer/tests/gl_cube_map_texture_unittest.cc +++ b/gpu/command_buffer/tests/gl_cube_map_texture_unittest.cc
@@ -110,7 +110,7 @@ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), glCheckFramebufferStatus(GL_FRAMEBUFFER)); - GLTestHelper::CheckPixels(0, 0, width_, width_, 0, pixels_); + GLTestHelper::CheckPixels(0, 0, width_, width_, 0, pixels_, nullptr); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); }
diff --git a/gpu/command_buffer/tests/gl_ext_blend_func_extended_unittest.cc b/gpu/command_buffer/tests/gl_ext_blend_func_extended_unittest.cc index 719ce2d..236ea45 100644 --- a/gpu/command_buffer/tests/gl_ext_blend_func_extended_unittest.cc +++ b/gpu/command_buffer/tests/gl_ext_blend_func_extended_unittest.cc
@@ -187,8 +187,9 @@ GL_ONE_MINUS_SRC1_ALPHA_EXT>(kDst, kSrc, kSrc1, color); EXPECT_TRUE(GLTestHelper::CheckPixels(kWidth / 4, (3 * kHeight) / 4, 1, 1, - 1, color)); - EXPECT_TRUE(GLTestHelper::CheckPixels(kWidth - 1, 0, 1, 1, 1, color)); + 1, color, nullptr)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(kWidth - 1, 0, 1, 1, 1, color, nullptr)); } protected:
diff --git a/gpu/command_buffer/tests/gl_ext_srgb_unittest.cc b/gpu/command_buffer/tests/gl_ext_srgb_unittest.cc index 139f8e6..a576d413 100644 --- a/gpu/command_buffer/tests/gl_ext_srgb_unittest.cc +++ b/gpu/command_buffer/tests/gl_ext_srgb_unittest.cc
@@ -66,10 +66,10 @@ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), glCheckFramebufferStatus(GL_FRAMEBUFFER)); - GLTestHelper::CheckPixels(0, 0, kSubImageX, kHeight, 0, kImageColor); - GLTestHelper::CheckPixels(0, 0, kWidth, kSubImageY, 0, kImageColor); + GLTestHelper::CheckPixels(0, 0, kSubImageX, kHeight, 0, kImageColor, nullptr); + GLTestHelper::CheckPixels(0, 0, kWidth, kSubImageY, 0, kImageColor, nullptr); GLTestHelper::CheckPixels(kSubImageX, kSubImageY, kSubImageWidth, - kSubImageHeight, 0, kSubImageColor); + kSubImageHeight, 0, kSubImageColor, nullptr); } } // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc index 4804d5d..0d1df1e 100644 --- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc +++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
@@ -234,7 +234,7 @@ ASSERT_TRUE(glGetError() == GL_NO_ERROR); // Check if pixels match the values that were assigned to the mapped buffer. - GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixel); + GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixel, nullptr); EXPECT_TRUE(GL_NO_ERROR == glGetError()); // Release the image.
diff --git a/gpu/command_buffer/tests/gl_iosurface_readback_workaround_unittest.cc b/gpu/command_buffer/tests/gl_iosurface_readback_workaround_unittest.cc index ea052f0..ab176e9 100644 --- a/gpu/command_buffer/tests/gl_iosurface_readback_workaround_unittest.cc +++ b/gpu/command_buffer/tests/gl_iosurface_readback_workaround_unittest.cc
@@ -67,14 +67,14 @@ glClearColor(33.0 / 255.0, 44.0 / 255.0, 55.0 / 255.0, 66.0 / 255.0); glClear(GL_COLOR_BUFFER_BIT); const uint8_t expected[4] = {33, 44, 55, 66}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, expected, + nullptr)); glClearColor(14.0 / 255.0, 15.0 / 255.0, 16.0 / 255.0, 17.0 / 255.0); glClear(GL_COLOR_BUFFER_BIT); const uint8_t expected2[4] = {14, 15, 16, 17}; - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, expected2)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, + expected2, nullptr)); glReleaseTexImage2DCHROMIUM(source_target, image_id); glDestroyImageCHROMIUM(image_id);
diff --git a/gpu/command_buffer/tests/gl_lose_context_chromium_unittest.cc b/gpu/command_buffer/tests/gl_lose_context_chromium_unittest.cc index 92024378..9e820f3 100644 --- a/gpu/command_buffer/tests/gl_lose_context_chromium_unittest.cc +++ b/gpu/command_buffer/tests/gl_lose_context_chromium_unittest.cc
@@ -55,16 +55,18 @@ GLTestHelper::kCheckClearValue, GLTestHelper::kCheckClearValue, }; // Expect the read will fail. - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_no_draw)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_no_draw, nullptr)); gl1b_.MakeCurrent(); // Expect the read will fail. - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_no_draw)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_no_draw, nullptr)); gl2_.MakeCurrent(); uint8_t expected_draw[] = { 0, 0, 0, 0, }; // Expect the read will succeed. - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_draw)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_draw, nullptr)); } } // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc b/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc index bd32e45..873597081 100644 --- a/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc +++ b/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc
@@ -114,14 +114,14 @@ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 6); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArraysInstancedANGLE(GL_TRIANGLES, 0, 6, kPrimCount); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); glMapBufferRange(GL_ARRAY_BUFFER, 0, 6, GL_MAP_READ_BIT); GLTestHelper::CheckGLError("no errors", __LINE__); @@ -130,13 +130,13 @@ glDrawArrays(GL_TRIANGLES, 0, 6); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArraysInstancedANGLE(GL_TRIANGLES, 0, 6, kPrimCount); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); // The following test is necessary to make sure draw calls do not just check // bound buffers, but actual buffers that are attached to the enabled vertex @@ -147,13 +147,13 @@ glDrawArrays(GL_TRIANGLES, 0, 6); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArraysInstancedANGLE(GL_TRIANGLES, 0, 6, kPrimCount); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); glBindBuffer(GL_ARRAY_BUFFER, buffer); glUnmapBuffer(GL_ARRAY_BUFFER); @@ -162,14 +162,14 @@ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 6); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArraysInstancedANGLE(GL_TRIANGLES, 0, 6, kPrimCount); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); } TEST_F(ES3MapBufferRangeTest, DrawElementsAndInstanced) { @@ -195,15 +195,15 @@ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0, kPrimCount); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); glMapBufferRange(GL_ARRAY_BUFFER, 0, 6, GL_MAP_READ_BIT); GLTestHelper::CheckGLError("no errors", __LINE__); @@ -212,14 +212,14 @@ glDrawArrays(GL_TRIANGLES, 0, 6); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0, kPrimCount); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); // The following test is necessary to make sure draw calls do not just check // bound buffers, but actual buffers that are attached to the enabled vertex @@ -230,14 +230,14 @@ glDrawArrays(GL_TRIANGLES, 0, 6); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0, kPrimCount); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); @@ -247,15 +247,15 @@ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0, kPrimCount); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, 6, GL_MAP_READ_BIT); GLTestHelper::CheckGLError("no errors", __LINE__); @@ -264,14 +264,14 @@ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0, kPrimCount); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, - kBlackColor)); + kBlackColor, nullptr)); glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); GLTestHelper::CheckGLError("no errors", __LINE__); @@ -279,15 +279,15 @@ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0, kPrimCount); GLTestHelper::CheckGLError("no errors", __LINE__); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, kRedColor)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kCanvasSize, kCanvasSize, 1, + kRedColor, nullptr)); } TEST_F(ES3MapBufferRangeTest, ReadPixels) {
diff --git a/gpu/command_buffer/tests/gl_pointcoord_unittest.cc b/gpu/command_buffer/tests/gl_pointcoord_unittest.cc index 1828aff9..d0a0163 100644 --- a/gpu/command_buffer/tests/gl_pointcoord_unittest.cc +++ b/gpu/command_buffer/tests/gl_pointcoord_unittest.cc
@@ -138,7 +138,7 @@ static_cast<uint8_t>(s * 255), static_cast<uint8_t>((1 - t) * 255), 0, 255, }; - GLTestHelper::CheckPixels(xf, yf, 1, 1, 4, color); + GLTestHelper::CheckPixels(xf, yf, 1, 1, 4, color, nullptr); } } }
diff --git a/gpu/command_buffer/tests/gl_program_unittest.cc b/gpu/command_buffer/tests/gl_program_unittest.cc index b5a790e..82f9cd9e 100644 --- a/gpu/command_buffer/tests/gl_program_unittest.cc +++ b/gpu/command_buffer/tests/gl_program_unittest.cc
@@ -121,7 +121,7 @@ GLuint fs = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, f_red_shader_str); GLuint program = GLTestHelper::SetupProgram(vs, fs); glUseProgram(program); - glShaderSource(fs, 1, &f_blue_shader_str, NULL); + glShaderSource(fs, 1, &f_blue_shader_str, nullptr); glCompileShader(fs); glLinkProgram(program); // We specifically don't call UseProgram again. @@ -131,7 +131,8 @@ uint8_t expected_color[] = { 0, 0, 255, 255, }; - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color, nullptr)); GLTestHelper::CheckGLError("no errors", __LINE__); } @@ -149,7 +150,7 @@ // Compiling invalid program should fail. const char* invalid_shader_strings[] = { invalid_shader.c_str() }; GLuint vs = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vs, 1, invalid_shader_strings, NULL); + glShaderSource(vs, 1, invalid_shader_strings, nullptr); glCompileShader(vs); GLint compile_state = 0; @@ -199,7 +200,8 @@ uint8_t expected_color[] = { 0, 0, 255, 255, }; - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color, nullptr)); GLTestHelper::CheckGLError("no errors", __LINE__); }
diff --git a/gpu/command_buffer/tests/gl_stream_draw_unittest.cc b/gpu/command_buffer/tests/gl_stream_draw_unittest.cc index 9722f02..7bbae743f 100644 --- a/gpu/command_buffer/tests/gl_stream_draw_unittest.cc +++ b/gpu/command_buffer/tests/gl_stream_draw_unittest.cc
@@ -77,10 +77,12 @@ GLTestHelper::SetupUnitQuad(position_loc); GLTestHelper::SetupColorsForUnitQuad(color_loc, float_red, GL_STREAM_DRAW); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_red)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_red, nullptr)); GLTestHelper::SetupColorsForUnitQuad(color_loc, float_green, GL_STATIC_DRAW); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_green)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_green, + nullptr)); GLTestHelper::CheckGLError("no errors", __LINE__); } @@ -109,14 +111,16 @@ static GLubyte indices[] = { 0, 1, 2, 3, 4, 5, }; glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STREAM_DRAW); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, NULL); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_red)); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr); + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_red, nullptr)); GLTestHelper::SetupColorsForUnitQuad(color_loc, float_green, GL_STATIC_DRAW); glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, NULL); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_green)); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_green, + nullptr)); GLTestHelper::CheckGLError("no errors", __LINE__); } @@ -156,12 +160,13 @@ for (int ii = 0; ii < 2; ++ii) { glBindVertexArrayOES(vaos[0]); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_red)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_red, + nullptr)); glBindVertexArrayOES(vaos[1]); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_green)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize, kSize, 0, expected_green, + nullptr)); } GLTestHelper::CheckGLError("no errors", __LINE__);
diff --git a/gpu/command_buffer/tests/gl_test_utils.cc b/gpu/command_buffer/tests/gl_test_utils.cc index f10a919..6fc8ff8 100644 --- a/gpu/command_buffer/tests/gl_test_utils.cc +++ b/gpu/command_buffer/tests/gl_test_utils.cc
@@ -11,9 +11,6 @@ #include <memory> #include <string> -#include "base/logging.h" -#include "base/strings/stringize_macros.h" -#include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" @@ -22,54 +19,6 @@ const uint8_t GLTestHelper::kCheckClearValue; #endif -// Compiles a fragment shader for sampling out of a texture of |size| bound to -// |target| and checks for compilation errors. -GLuint LoadFragmentShader(unsigned target, const gfx::Size& size) { - // clang-format off - const char kFragmentShader[] = STRINGIZE( - uniform SamplerType u_texture; - varying vec2 v_texCoord; - void main() { - gl_FragColor = TextureLookup(u_texture, v_texCoord * TextureScale); - } - ); - const char kShaderFloatPrecision[] = STRINGIZE( - precision mediump float; - ); - // clang-format on - - switch (target) { - case GL_TEXTURE_2D: - return GLTestHelper::LoadShader( - GL_FRAGMENT_SHADER, - base::StringPrintf("%s\n" - "#define SamplerType sampler2D\n" - "#define TextureLookup texture2D\n" - "#define TextureScale vec2(1.0, 1.0)\n" - "%s", - kShaderFloatPrecision, - kFragmentShader) - .c_str()); - case GL_TEXTURE_RECTANGLE_ARB: - return GLTestHelper::LoadShader( - GL_FRAGMENT_SHADER, - base::StringPrintf("%s\n" - "#extension GL_ARB_texture_rectangle : require\n" - "#define SamplerType sampler2DRect\n" - "#define TextureLookup texture2DRect\n" - "#define TextureScale vec2(%f, %f)\n" - "%s", - kShaderFloatPrecision, - static_cast<double>(size.width()), - static_cast<double>(size.height()), - kFragmentShader) - .c_str()); - default: - NOTREACHED(); - return 0; - } -} - bool GLTestHelper::HasExtension(const char* extension) { // Pad with an extra space to ensure that |extension| is not a substring of // another extension. @@ -214,7 +163,8 @@ GLsizei width, GLsizei height, GLint tolerance, - const uint8_t* color) { + const uint8_t* color, + const uint8_t* mask) { GLsizei size = width * height * 4; std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]); memset(pixels.get(), kCheckClearValue, size); @@ -228,7 +178,7 @@ uint8_t expected = color[jj]; int diff = actual - expected; diff = diff < 0 ? -diff: diff; - if (diff > tolerance) { + if ((!mask || mask[jj]) && diff > tolerance) { EXPECT_EQ(expected, actual) << " at " << (xx + x) << ", " << (yy + y) << " channel " << jj; ++bad_count; @@ -327,39 +277,26 @@ return true; } -void GLTestHelper::DrawTextureQuad(GLenum target, const gfx::Size& size) { - // clang-format off - const char kVertexShader[] = STRINGIZE( - attribute vec2 a_position; - varying vec2 v_texCoord; - void main() { - gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); - v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5; - } - ); - // clang-format on - - // Setup program. - GLuint vertex_shader = - GLTestHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); - GLuint fragment_shader = LoadFragmentShader(target, size); - GLuint program = GLTestHelper::SetupProgram(vertex_shader, fragment_shader); +void GLTestHelper::DrawTextureQuad(const char* vertex_src, + const char* fragment_src, + const char* position_name, + const char* sampler_name) { + GLuint program = GLTestHelper::LoadProgram(vertex_src, fragment_src); EXPECT_NE(program, 0u); glUseProgram(program); - GLint position_loc = glGetAttribLocation(program, "a_position"); - GLint sampler_location = glGetUniformLocation(program, "u_texture"); + GLint position_loc = glGetAttribLocation(program, position_name); + GLint sampler_location = glGetUniformLocation(program, sampler_name); ASSERT_NE(position_loc, -1); ASSERT_NE(sampler_location, -1); GLuint vertex_buffer = GLTestHelper::SetupUnitQuad(position_loc); ASSERT_NE(vertex_buffer, 0u); + glActiveTexture(GL_TEXTURE0); glUniform1i(sampler_location, 0); glDrawArrays(GL_TRIANGLES, 0, 6); - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); glDeleteProgram(program); glDeleteBuffers(1, &vertex_buffer); }
diff --git a/gpu/command_buffer/tests/gl_test_utils.h b/gpu/command_buffer/tests/gl_test_utils.h index d4292248..e89fbfb 100644 --- a/gpu/command_buffer/tests/gl_test_utils.h +++ b/gpu/command_buffer/tests/gl_test_utils.h
@@ -12,10 +12,6 @@ #include <vector> -namespace gfx { -class Size; -} // namespace gfx - class GLTestHelper { public: static const uint8_t kCheckClearValue = 123u; @@ -59,17 +55,23 @@ GLint location, const GLfloat color[4], GLenum usage); // Checks an area of pixels for a color. + // If mask is nullptr, compare all color channels; otherwise, compare the + // channels whose corresponding mask bit is true. static bool CheckPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLint tolerance, - const uint8_t* color); + const uint8_t* color, + const uint8_t* mask); // Uses ReadPixels to save an area of the current FBO/Backbuffer. static bool SaveBackbufferAsBMP(const char* filename, int width, int height); - static void DrawTextureQuad(GLenum target, const gfx::Size& size); + static void DrawTextureQuad(const char* vertex_src, + const char* fragment_src, + const char* position_name, + const char* sampler_name); }; #endif // GPU_COMMAND_BUFFER_TESTS_GL_TEST_UTILS_H_
diff --git a/gpu/command_buffer/tests/gl_texture_storage_unittest.cc b/gpu/command_buffer/tests/gl_texture_storage_unittest.cc index 7803bfb..703baff6 100644 --- a/gpu/command_buffer/tests/gl_texture_storage_unittest.cc +++ b/gpu/command_buffer/tests/gl_texture_storage_unittest.cc
@@ -64,7 +64,7 @@ 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, source_pixels); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 2, 2, 0, source_pixels)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 2, 2, 0, source_pixels, nullptr)); } TEST_F(TextureStorageTest, IsImmutable) { @@ -145,14 +145,8 @@ EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - 4, 4, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); }
diff --git a/gpu/command_buffer/tests/gl_unittest.cc b/gpu/command_buffer/tests/gl_unittest.cc index 8a713fcc..cd9373e 100644 --- a/gpu/command_buffer/tests/gl_unittest.cc +++ b/gpu/command_buffer/tests/gl_unittest.cc
@@ -32,7 +32,7 @@ uint8_t expected[] = { 0, 255, 0, 255, }; - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected, nullptr)); GLTestHelper::CheckGLError("no errors", __LINE__); } @@ -61,7 +61,7 @@ uint8_t expected[] = { 0, 255, 0, 255, }; - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 16, 16, 0, expected)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 16, 16, 0, expected, nullptr)); glDeleteFramebuffers(1, &fbo); glDeleteTextures(1, &tex); GLTestHelper::CheckGLError("no errors", __LINE__); @@ -92,12 +92,13 @@ }; glClearColor(0.5f, 0.0f, 1.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 1, expected_clear)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 1, expected_clear, nullptr)); uint8_t expected_draw[] = { 0, 255, 0, 255, }; glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_draw)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_draw, nullptr)); } TEST_F(GLTest, FeatureFlagsMatchCapabilities) {
diff --git a/gpu/command_buffer/tests/gl_virtual_contexts_unittest.cc b/gpu/command_buffer/tests/gl_virtual_contexts_unittest.cc index d161ff6..f02ba16 100644 --- a/gpu/command_buffer/tests/gl_virtual_contexts_unittest.cc +++ b/gpu/command_buffer/tests/gl_virtual_contexts_unittest.cc
@@ -141,7 +141,8 @@ }; glClearColor(0.5f, 0.0f, 1.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, size, size, 1, expected_clear)); + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, size, size, 1, expected_clear, nullptr)); glDrawArrays(GL_TRIANGLES, 0, 6); } @@ -179,8 +180,8 @@ const TestInfo& test = tests[ii]; GLManager* gl_manager = test.manager; gl_manager->MakeCurrent(); - EXPECT_TRUE(GLTestHelper::CheckPixels( - 0, 0, test.size, test.size, 0, test.color)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, test.size, test.size, 0, + test.color, nullptr)); } for (int ii = 0; ii < kNumTests; ++ii) { @@ -212,15 +213,16 @@ gl1_.MakeCurrent(); // Test to ensure that vao1 is still the active VAO for this context. glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed, + nullptr)); glFinish(); GLTestHelper::CheckGLError("no errors", __LINE__); gl2_.MakeCurrent(); // Test to ensure that vao2 is still the active VAO for this context. glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen, + nullptr)); glFinish(); GLTestHelper::CheckGLError("no errors", __LINE__); } @@ -249,7 +251,8 @@ glBindVertexArrayOES(0); glBindVertexArrayOES(vao1); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed, + nullptr)); glFinish(); GLTestHelper::CheckGLError("no errors", __LINE__); @@ -259,8 +262,8 @@ glBindVertexArrayOES(0); glBindVertexArrayOES(vao2); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen, + nullptr)); glFinish(); GLTestHelper::CheckGLError("no errors", __LINE__); @@ -287,7 +290,8 @@ gl1_.MakeCurrent(); // Test to ensure that default VAO on gl1_ is still valid. glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed, + nullptr)); glFinish(); gl2_.MakeCurrent(); @@ -296,8 +300,8 @@ // bound during the context switch. glBindVertexArrayOES(0); glDrawArrays(GL_TRIANGLES, 0, 6); - EXPECT_TRUE( - GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen)); + EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen, + nullptr)); glFinish(); GLTestHelper::CheckGLError("no errors", __LINE__);
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index ab706bc..f7a0435 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -205,6 +205,8 @@ "web_state/ui/crw_swipe_recognizer_provider.h", "web_state/ui/crw_touch_tracking_recognizer.h", "web_state/ui/crw_touch_tracking_recognizer.mm", + "web_state/ui/crw_wk_navigation_states.h", + "web_state/ui/crw_wk_navigation_states.mm", "web_thread_impl.cc", "web_thread_impl.h", "web_view_creation_util.mm", @@ -537,6 +539,7 @@ "web_state/ui/crw_web_controller_container_view_unittest.mm", "web_state/ui/crw_web_controller_observer_unittest.mm", "web_state/ui/crw_web_controller_unittest.mm", + "web_state/ui/crw_wk_navigation_states_unittest.mm", "web_state/ui/crw_wk_script_message_router_unittest.mm", "web_state/ui/web_view_js_utils_unittest.mm", "web_state/ui/wk_back_forward_list_item_holder_unittest.mm",
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index c7340ba..7aabe25b 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -88,6 +88,7 @@ #import "ios/web/web_state/ui/crw_swipe_recognizer_provider.h" #import "ios/web/web_state/ui/crw_web_controller.h" #import "ios/web/web_state/ui/crw_web_controller_container_view.h" +#import "ios/web/web_state/ui/crw_wk_navigation_states.h" #import "ios/web/web_state/ui/crw_wk_script_message_router.h" #import "ios/web/web_state/ui/wk_back_forward_list_item_holder.h" #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h" @@ -448,8 +449,9 @@ base::scoped_nsobject<CRWWebControllerPendingNavigationInfo> _pendingNavigationInfo; - // The WKNavigation for the most recent load request. - base::scoped_nsobject<WKNavigation> _latestWKNavigation; + // Holds all WKNavigation objects and their states which are currently in + // flight. + base::scoped_nsobject<CRWWKNavigationStates> _navigationStates; // The WKNavigation captured when |stopLoading| was called. Used for reporting // WebController.EmptyNavigationManagerCausedByStopLoading UMA metric which @@ -1049,6 +1051,7 @@ initWithBrowserState:browserState]); _certVerificationErrors.reset( new CertVerificationErrorsCacheType(kMaxCertErrorsCount)); + _navigationStates.reset([[CRWWKNavigationStates alloc] init]); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange) @@ -3586,14 +3589,6 @@ if (web::GetWebClient()->IsAppSpecificURL(errorURL)) return NO; - if (self.sessionController.pendingEntryIndex != -1 && - ![self isLoadRequestPendingForURL:errorURL]) { - // Do not cancel the load if there is a pending back forward navigation for - // another URL (Back forward happened in the middle of WKWebView - // navigation). - return NO; - } - // Don't cancel NSURLErrorCancelled errors originating from navigation // as the WKWebView will automatically retry these loads. WKWebViewErrorSource source = WKWebViewErrorSourceFromError(error); @@ -4831,7 +4826,8 @@ } - (void)loadRequest:(NSMutableURLRequest*)request { - _latestWKNavigation.reset([[_webView loadRequest:request] retain]); + [_navigationStates setState:web::WKNavigationState::REQUESTED + forNavigation:[_webView loadRequest:request]]; } - (void)loadPOSTRequest:(NSMutableURLRequest*)request { @@ -4864,7 +4860,10 @@ [self ensureWebViewCreated]; DCHECK(_webView) << "_webView null while trying to load HTML"; } - [_webView loadHTMLString:HTML baseURL:net::NSURLWithGURL(URL)]; + WKNavigation* navigation = + [_webView loadHTMLString:HTML baseURL:net::NSURLWithGURL(URL)]; + [_navigationStates setState:web::WKNavigationState::REQUESTED + forNavigation:navigation]; } - (void)loadHTML:(NSString*)HTML forAppSpecificURL:(const GURL&)URL { @@ -4877,7 +4876,7 @@ } - (void)stopLoading { - _stoppedWKNavigation.reset(_latestWKNavigation); + _stoppedWKNavigation.reset([_navigationStates lastAddedNavigation]); base::RecordAction(UserMetricsAction("Stop")); // Discard the pending and transient entried before notifying the tab model @@ -5140,6 +5139,9 @@ // superclass, and wire these up to the remaining methods. - (void)webView:(WKWebView*)webView didStartProvisionalNavigation:(WKNavigation*)navigation { + [_navigationStates setState:web::WKNavigationState::STARTED + forNavigation:navigation]; + GURL webViewURL = net::GURLWithNSURL(webView.URL); if (webViewURL.is_empty()) { // May happen on iOS9, however in didCommitNavigation: callback the URL @@ -5176,11 +5178,13 @@ // Ensure the URL is registered and loadPhase is as expected. DCHECK(_lastRegisteredRequestURL == webViewURL); DCHECK(self.loadPhase == web::LOAD_REQUESTED); - _latestWKNavigation.reset([navigation retain]); } - (void)webView:(WKWebView*)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation*)navigation { + [_navigationStates setState:web::WKNavigationState::REDIRECTED + forNavigation:navigation]; + [self registerLoadRequest:net::GURLWithNSURL(webView.URL) referrer:[self currentReferrer] transition:ui::PAGE_TRANSITION_SERVER_REDIRECT]; @@ -5189,10 +5193,13 @@ - (void)webView:(WKWebView*)webView didFailProvisionalNavigation:(WKNavigation*)navigation withError:(NSError*)error { + [_navigationStates setState:web::WKNavigationState::PROVISIONALY_FAILED + forNavigation:navigation]; + // Ignore provisional navigation failure if a new navigation has been started, // for example, if a page is reloaded after the start of the provisional // load but before the load has been committed. - if (![_latestWKNavigation isEqual:navigation]) { + if (![[_navigationStates lastAddedNavigation] isEqual:navigation]) { return; } @@ -5240,8 +5247,12 @@ // this CHECK once there is at least one crash on this line (which means that // |didStartProvisionalNavigation| did not call |registerLoadRequest| and it // should be fixed. - CHECK([self currentSessionEntry] || - ![_latestWKNavigation isEqual:navigation]); + CHECK([self currentSessionEntry] || !navigation || + [_navigationStates stateForNavigation:navigation] == + web::WKNavigationState::STARTED); + + [_navigationStates setState:web::WKNavigationState::COMMITTED + forNavigation:navigation]; DCHECK_EQ(_webView, webView); _certVerificationErrors->Clear(); @@ -5302,6 +5313,9 @@ - (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation { + [_navigationStates setState:web::WKNavigationState::FINISHED + forNavigation:navigation]; + DCHECK(!_isHalted); // Trigger JavaScript driven post-document-load-completion tasks. // TODO(crbug.com/546350): Investigate using @@ -5314,6 +5328,9 @@ - (void)webView:(WKWebView*)webView didFailNavigation:(WKNavigation*)navigation withError:(NSError*)error { + [_navigationStates setState:web::WKNavigationState::FAILED + forNavigation:navigation]; + [self handleLoadError:WKWebViewErrorWithSource(error, NAVIGATION) inMainFrame:YES]; _certVerificationErrors->Clear(); @@ -5681,12 +5698,16 @@ referrer:[self currentSessionEntryReferrer] transition:[self currentTransition]]; if (navigationURL == net::GURLWithNSURL([_webView URL])) { - [_webView reload]; + [_navigationStates setState:web::WKNavigationState::REQUESTED + forNavigation:[_webView reload]]; } else { // |didCommitNavigation:| may not be called for fast navigation, so update // the navigation type now as it is already known. holder->set_navigation_type(WKNavigationTypeBackForward); - [_webView goToBackForwardListItem:holder->back_forward_list_item()]; + WKNavigation* navigation = + [_webView goToBackForwardListItem:holder->back_forward_list_item()]; + [_navigationStates setState:web::WKNavigationState::REQUESTED + forNavigation:navigation]; } };
diff --git a/ios/web/web_state/ui/crw_wk_navigation_states.h b/ios/web/web_state/ui/crw_wk_navigation_states.h new file mode 100644 index 0000000..1059189 --- /dev/null +++ b/ios/web/web_state/ui/crw_wk_navigation_states.h
@@ -0,0 +1,63 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_WEB_WEB_STATE_UI_CRW_WK_NAVIGATION_STATES_H_ +#define IOS_WEB_WEB_STATE_UI_CRW_WK_NAVIGATION_STATES_H_ + +#import <Foundation/Foundation.h> +#import <WebKit/WebKit.h> + +namespace web { + +// State of in-flight WKNavigation objects. +enum class WKNavigationState : int { + // Navigation does not exist. + NONE = 0, + // WKNavigation returned from |loadRequest:|, |goToBackForwardListItem:|, + // |loadFileURL:allowingReadAccessToURL:|, |loadHTMLString:baseURL:|, + // |loadData:MIMEType:characterEncodingName:baseURL:|, |goBack|, |goForward|, + // |reload| or |reloadFromOrigin|. + REQUESTED, + // WKNavigation passed to |webView:didStartProvisionalNavigation:|. + STARTED, + // WKNavigation passed to + // |webView:didReceiveServerRedirectForProvisionalNavigation:|. + REDIRECTED, + // WKNavigation passed to |webView:didFailProvisionalNavigation:|. + PROVISIONALY_FAILED, + // WKNavigation passed to |webView:didCommitNavigation:|. + COMMITTED, + // WKNavigation passed to |webView:didFinishNavigation:|. + FINISHED, + // WKNavigation passed to |webView:didFailNavigation:withError:|. + FAILED, +}; + +} // namespace web + +// Stores states for WKNavigation objects. Allows lookign up for last added +// navigation object. +@interface CRWWKNavigationStates : NSObject + +// Adds a new navigation if it was not added yet. If navigation was already +// added then updates state for existing navigation. Updating state does not +// affect the result of |lastAddedNavigation| method. New added navigations +// should have WKNavigationState::REQUESTED, WKNavigationState::STARTED or +// WKNavigationState::COMMITTED state. Passed |navigation| will be help as weak +// reference and will not be retained. No-op if |navigation| is null. +- (void)setState:(web::WKNavigationState)state + forNavigation:(WKNavigation*)navigation; + +// WKNavigation which was added the most recently via |setState:forNavigation:|. +// Updating navigation state via |setState:forNavigation:| does not change the +// last added navigation. Returns nil if there are no stored navigations. +- (WKNavigation*)lastAddedNavigation; + +// Returns state of the given navigation or WKNavigationState::NONE if +// navigation does not exist. +- (web::WKNavigationState)stateForNavigation:(WKNavigation*)navigation; + +@end + +#endif // IOS_WEB_WEB_STATE_UI_CRW_WK_NAVIGATION_STATES_H_
diff --git a/ios/web/web_state/ui/crw_wk_navigation_states.mm b/ios/web/web_state/ui/crw_wk_navigation_states.mm new file mode 100644 index 0000000..2f0a5175 --- /dev/null +++ b/ios/web/web_state/ui/crw_wk_navigation_states.mm
@@ -0,0 +1,113 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/web_state/ui/crw_wk_navigation_states.h" + +#include "base/logging.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// Holds a pair of state and creation order index. +@interface CRWWKNavigationsStateRecord : NSObject +// Navigation state. +@property(nonatomic, assign) web::WKNavigationState state; +// Numerical index representing creation order (smaller index denotes earlier +// navigations). +@property(nonatomic, assign, readonly) NSUInteger index; + +- (instancetype)init NS_UNAVAILABLE; + +// Initializes record with state and index values. +- (instancetype)initWithState:(web::WKNavigationState)state + index:(NSUInteger)index NS_DESIGNATED_INITIALIZER; + +@end + +@implementation CRWWKNavigationsStateRecord +@synthesize state = _state; +@synthesize index = _index; + +- (NSString*)description { + return [NSString stringWithFormat:@"state: %d, index: %ld", _state, + static_cast<long>(_index)]; +} + +- (instancetype)initWithState:(web::WKNavigationState)state + index:(NSUInteger)index { + if ((self = [super init])) { + _state = state; + _index = index; + } + return self; +} + +@end + +@interface CRWWKNavigationStates () { + NSMapTable* _records; + NSUInteger _lastStateIndex; +} +@end + +@implementation CRWWKNavigationStates + +- (instancetype)init { + if ((self = [super init])) { + _records = [NSMapTable weakToStrongObjectsMapTable]; + } + return self; +} + +- (NSString*)description { + return [NSString stringWithFormat:@"records: %@, lastAddedNavigation: %@", + _records, self.lastAddedNavigation]; +} + +- (void)setState:(web::WKNavigationState)state + forNavigation:(WKNavigation*)navigation { + if (!navigation) { + // WKWebView may call WKNavigationDelegate callbacks with nil + // |WKNavigation|. TODO(crbug.com/677354): Remove this once WKWebView bug + // is fixed. + return; + } + + CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation]; + if (!record) { + DCHECK(state == web::WKNavigationState::REQUESTED || + state == web::WKNavigationState::STARTED || + state == web::WKNavigationState::COMMITTED); + record = + [[CRWWKNavigationsStateRecord alloc] initWithState:state + index:++_lastStateIndex]; + } else { + DCHECK( + record.state < state || + (record.state == state && state == web::WKNavigationState::REDIRECTED)); + record.state = state; + } + [_records setObject:record forKey:navigation]; +} + +- (WKNavigation*)lastAddedNavigation { + WKNavigation* result = nil; + NSUInteger lastAddedIndex = 0; // record indices start with 1. + for (WKNavigation* navigation in _records) { + CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation]; + if (lastAddedIndex < record.index) { + result = navigation; + lastAddedIndex = record.index; + } + } + return result; +} + +- (web::WKNavigationState)stateForNavigation:(WKNavigation*)navigation { + CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation]; + return record.state; +} + +@end
diff --git a/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm b/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm new file mode 100644 index 0000000..955a20b --- /dev/null +++ b/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm
@@ -0,0 +1,59 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/web_state/ui/crw_wk_navigation_states.h" + +#import <WebKit/WebKit.h> + +#import "base/mac/scoped_nsobject.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace web { + +// Test fixture for CRWWKNavigationStates testing. +class CRWWKNavigationStatesTest : public PlatformTest { + protected: + CRWWKNavigationStatesTest() + : navigation1_(static_cast<WKNavigation*>([[NSObject alloc] init])), + navigation2_(static_cast<WKNavigation*>([[NSObject alloc] init])), + states_([[CRWWKNavigationStates alloc] init]) {} + + protected: + base::scoped_nsobject<WKNavigation> navigation1_; + base::scoped_nsobject<WKNavigation> navigation2_; + base::scoped_nsobject<CRWWKNavigationStates> states_; +}; + +// Tests |lastAddedNavigation| method. +TEST_F(CRWWKNavigationStatesTest, LastAddedNavigation) { + // navigation_1 is the only navigation and it is the latest. + [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation1_]; + EXPECT_EQ(navigation1_, [states_ lastAddedNavigation]); + + // navigation_2 is added later and hence the latest. + [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation2_]; + EXPECT_EQ(navigation2_, [states_ lastAddedNavigation]); + + // Updating state for existing navigation does not make it the latest. + [states_ setState:WKNavigationState::STARTED forNavigation:navigation1_]; + EXPECT_EQ(navigation2_, [states_ lastAddedNavigation]); +} + +// Tests |stateForNavigation:| method. +TEST_F(CRWWKNavigationStatesTest, StateForNavigation) { + [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation1_]; + EXPECT_EQ(WKNavigationState::REQUESTED, + [states_ stateForNavigation:navigation1_]); + + [states_ setState:WKNavigationState::REQUESTED forNavigation:navigation2_]; + EXPECT_EQ(WKNavigationState::REQUESTED, + [states_ stateForNavigation:navigation2_]); + + [states_ setState:WKNavigationState::STARTED forNavigation:navigation1_]; + EXPECT_EQ(WKNavigationState::STARTED, + [states_ stateForNavigation:navigation1_]); +} + +} // namespace web
diff --git a/mash/simple_wm/simple_wm.cc b/mash/simple_wm/simple_wm.cc index 92c0f6b5..66f0a3b5 100644 --- a/mash/simple_wm/simple_wm.cc +++ b/mash/simple_wm/simple_wm.cc
@@ -19,7 +19,7 @@ #include "ui/views/widget/native_widget_aura.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" -#include "ui/wm/core/default_activation_client.h" +#include "ui/wm/core/focus_controller.h" namespace simple_wm { @@ -341,6 +341,9 @@ DISALLOW_COPY_AND_ASSIGN(DisplayLayoutManager); }; +//////////////////////////////////////////////////////////////////////////////// +// SimpleWM, public: + SimpleWM::SimpleWM() {} SimpleWM::~SimpleWM() { @@ -355,6 +358,9 @@ display::Screen::SetScreenInstance(nullptr); } +//////////////////////////////////////////////////////////////////////////////// +// SimpleWM, service_manager::Service implementation: + void SimpleWM::OnStart() { CHECK(!started_); started_ = true; @@ -380,6 +386,9 @@ return true; } +//////////////////////////////////////////////////////////////////////////////// +// SimpleWM, aura::WindowTreeClientDelegate implementation: + void SimpleWM::OnEmbed( std::unique_ptr<aura::WindowTreeHostMus> window_tree_host) { // WindowTreeClients configured as the window manager should never get @@ -411,6 +420,9 @@ return &property_converter_; } +//////////////////////////////////////////////////////////////////////////////// +// SimpleWM, aura::WindowManagerDelegate implementation: + void SimpleWM::SetWindowManagerClient( aura::WindowManagerClient* client) { window_manager_client_ = client; @@ -515,8 +527,10 @@ frame_decoration_values->max_title_bar_button_width = 0; window_manager_client_->SetFrameDecorationValues( std::move(frame_decoration_values)); - new wm::DefaultActivationClient(display_root_); - aura::client::SetFocusClient(display_root_, &focus_client_); + focus_controller_ = base::MakeUnique<wm::FocusController>(this); + aura::client::SetFocusClient(display_root_, focus_controller_.get()); + aura::client::SetActivationClient(display_root_, focus_controller_.get()); + display_root_->AddPreTargetHandler(focus_controller_.get()); } void SimpleWM::OnWmDisplayRemoved( @@ -543,6 +557,29 @@ const gfx::Insets& insets, const std::vector<gfx::Rect>& additional_client_areas) {} +//////////////////////////////////////////////////////////////////////////////// +// SimpleWM, wm::BaseFocusRules implementation: + +bool SimpleWM::SupportsChildActivation(aura::Window* window) const { + return window == window_root_; +} + +bool SimpleWM::IsWindowConsideredVisibleForActivation( + aura::Window* window) const { + if (window->IsVisible()) + return true; + + ui::WindowShowState show_state = + window->GetProperty(aura::client::kShowStateKey); + if (show_state == ui::SHOW_STATE_MINIMIZED) + return true; + + return window->TargetVisibility(); +} + +//////////////////////////////////////////////////////////////////////////////// +// SimpleWM, private: + SimpleWM::FrameView* SimpleWM::GetFrameViewForClientWindow( aura::Window* client_window) { auto it = client_window_to_frame_view_.find(client_window);
diff --git a/mash/simple_wm/simple_wm.h b/mash/simple_wm/simple_wm.h index e6be287c..16a9e5ac 100644 --- a/mash/simple_wm/simple_wm.h +++ b/mash/simple_wm/simple_wm.h
@@ -23,9 +23,9 @@ #include "ui/aura/mus/window_tree_client.h" #include "ui/aura/mus/window_tree_client_delegate.h" #include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/test/test_focus_client.h" #include "ui/aura/window.h" #include "ui/display/display.h" +#include "ui/wm/core/base_focus_rules.h" #include "ui/wm/core/capture_controller.h" #include "ui/wm/core/wm_state.h" @@ -37,11 +37,16 @@ class AuraInit; } +namespace wm { +class FocusController; +} + namespace simple_wm { class SimpleWM : public service_manager::Service, public aura::WindowTreeClientDelegate, - public aura::WindowManagerDelegate { + public aura::WindowManagerDelegate, + public wm::BaseFocusRules { public: SimpleWM(); ~SimpleWM() override; @@ -96,15 +101,20 @@ const gfx::Insets& insets, const std::vector<gfx::Rect>& additional_client_areas) override; + // wm::BaseFocusRules: + bool SupportsChildActivation(aura::Window* window) const override; + bool IsWindowConsideredVisibleForActivation( + aura::Window* window) const override; + FrameView* GetFrameViewForClientWindow(aura::Window* client_window); void OnWindowListViewItemActivated(aura::Window* index); std::unique_ptr<views::AuraInit> aura_init_; - ::wm::WMState wm_state_; + wm::WMState wm_state_; std::unique_ptr<display::ScreenBase> screen_; aura::PropertyConverter property_converter_; - aura::test::TestFocusClient focus_client_; + std::unique_ptr<wm::FocusController> focus_controller_; std::unique_ptr<aura::WindowTreeHostMus> window_tree_host_; aura::Window* display_root_ = nullptr; aura::Window* window_root_ = nullptr;
diff --git a/media/base/audio_codecs.cc b/media/base/audio_codecs.cc index 8aaa24f..09b19100 100644 --- a/media/base/audio_codecs.cc +++ b/media/base/audio_codecs.cc
@@ -52,9 +52,9 @@ AudioCodec StringToAudioCodec(const std::string& codec_id) { if (codec_id == "aac") return kCodecAAC; - if (codec_id == "ac-3" || codec_id == "mp4a.A5") + if (codec_id == "ac-3" || codec_id == "mp4a.A5" || codec_id == "mp4a.a5") return kCodecAC3; - if (codec_id == "ec-3" || codec_id == "mp4a.A6") + if (codec_id == "ec-3" || codec_id == "mp4a.A6" || codec_id == "mp4a.a6") return kCodecEAC3; if (codec_id == "mp3") return kCodecMP3;
diff --git a/services/navigation/view_impl.cc b/services/navigation/view_impl.cc index 812bb60b..578cb90 100644 --- a/services/navigation/view_impl.cc +++ b/services/navigation/view_impl.cc
@@ -20,7 +20,6 @@ #include "ui/aura/mus/window_tree_client.h" #include "ui/aura/mus/window_tree_host_mus.h" #include "ui/views/controls/webview/webview.h" -#include "ui/views/mus/native_widget_mus.h" #include "ui/views/widget/widget.h" #include "url/gurl.h"
diff --git a/services/ui/public/cpp/surface_id_handler.h b/services/ui/public/cpp/surface_id_handler.h index 509edf7f..3c272a1 100644 --- a/services/ui/public/cpp/surface_id_handler.h +++ b/services/ui/public/cpp/surface_id_handler.h
@@ -8,22 +8,14 @@ #include "cc/surfaces/surface_id.h" #include "ui/gfx/geometry/size.h" +namespace cc { +class SurfaceInfo; +} + namespace ui { class Window; -// Holds information about the current surface held by a Window. -// |surface_id| uniquely identifies the surface in the display -// compositor. -// |frame_size| is the size of the frame held by the surface. -// |device_scale_factor| is the scale factor that the frame was -// renderered for. -struct SurfaceInfo { - cc::SurfaceId surface_id; - gfx::Size frame_size; - float device_scale_factor; -}; - class SurfaceIdHandler { public: // Called when a child window allocates a new surface ID. @@ -32,7 +24,7 @@ // |surface_info| will refer to a null pointer. virtual void OnChildWindowSurfaceChanged( Window* window, - std::unique_ptr<SurfaceInfo>* surface_info) = 0; + const cc::SurfaceInfo& surface_info) = 0; }; } // namespace ui
diff --git a/services/ui/public/cpp/window.cc b/services/ui/public/cpp/window.cc index 80778029..828967c 100644 --- a/services/ui/public/cpp/window.cc +++ b/services/ui/public/cpp/window.cc
@@ -544,8 +544,8 @@ transient_parent_->LocalRemoveTransientWindow(this); // Return the surface reference if there is one. - if (surface_info_) - LocalSetSurfaceId(nullptr); + if (surface_info_.id().is_valid()) + LocalSetSurfaceInfo(cc::SurfaceInfo()); // Remove transient children. while (!transient_children_.empty()) { @@ -809,11 +809,10 @@ observer.OnWindowSharedPropertyChanged(this, name, old_value_ptr, value); } -void Window::LocalSetSurfaceId(std::unique_ptr<SurfaceInfo> surface_info) { - if (surface_info_) { - const cc::SurfaceId& existing_surface_id = surface_info_->surface_id; - cc::SurfaceId new_surface_id = - surface_info ? surface_info->surface_id : cc::SurfaceId(); +void Window::LocalSetSurfaceInfo(const cc::SurfaceInfo& surface_info) { + if (surface_info_.id().is_valid()) { + const cc::SurfaceId& existing_surface_id = surface_info_.id(); + const cc::SurfaceId& new_surface_id = surface_info.id(); if (existing_surface_id.is_valid() && existing_surface_id != new_surface_id) { // TODO(kylechar): Start return reference here? @@ -821,9 +820,9 @@ } if (parent_ && parent_->surface_id_handler_) { parent_->surface_id_handler_->OnChildWindowSurfaceChanged(this, - &surface_info); + surface_info); } - surface_info_ = std::move(surface_info); + surface_info_ = surface_info; } void Window::NotifyWindowStackingChanged() {
diff --git a/services/ui/public/cpp/window.h b/services/ui/public/cpp/window.h index 015540c..a5e80925 100644 --- a/services/ui/public/cpp/window.h +++ b/services/ui/public/cpp/window.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/observer_list.h" +#include "cc/surfaces/surface_info.h" #include "mojo/public/cpp/bindings/array.h" #include "services/service_manager/public/interfaces/interface_provider.mojom.h" #include "services/ui/common/types.h" @@ -319,7 +320,7 @@ void LocalSetPredefinedCursor(mojom::Cursor cursor_id); void LocalSetSharedProperty(const std::string& name, const std::vector<uint8_t>* data); - void LocalSetSurfaceId(std::unique_ptr<SurfaceInfo> surface_info); + void LocalSetSurfaceInfo(const cc::SurfaceInfo& surface_info); // Notifies this winodw that its stacking position has changed. void NotifyWindowStackingChanged(); @@ -405,7 +406,7 @@ std::map<const void*, Value> prop_map_; - std::unique_ptr<SurfaceInfo> surface_info_; + cc::SurfaceInfo surface_info_; DISALLOW_COPY_AND_ASSIGN(Window); };
diff --git a/services/ui/public/cpp/window_private.h b/services/ui/public/cpp/window_private.h index c64b9770..f1bd9499 100644 --- a/services/ui/public/cpp/window_private.h +++ b/services/ui/public/cpp/window_private.h
@@ -88,8 +88,8 @@ const std::vector<uint8_t>* data) { window_->LocalSetSharedProperty(name, data); } - void LocalSetSurfaceId(std::unique_ptr<SurfaceInfo> surface_info) { - window_->LocalSetSurfaceId(std::move(surface_info)); + void LocalSetSurfaceInfo(const cc::SurfaceInfo& surface_info) { + window_->LocalSetSurfaceInfo(surface_info); } void NotifyWindowStackingChanged() { window_->NotifyWindowStackingChanged(); }
diff --git a/services/ui/public/cpp/window_tree_client.cc b/services/ui/public/cpp/window_tree_client.cc index 2dbd61d..ecbc628 100644 --- a/services/ui/public/cpp/window_tree_client.cc +++ b/services/ui/public/cpp/window_tree_client.cc
@@ -1140,17 +1140,11 @@ void WindowTreeClient::OnWindowSurfaceChanged( Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { + const cc::SurfaceInfo& surface_info) { Window* window = GetWindowByServerId(window_id); if (!window) return; - std::unique_ptr<SurfaceInfo> surface_info(base::MakeUnique<SurfaceInfo>()); - surface_info->surface_id = surface_id; - surface_info->frame_size = frame_size; - surface_info->device_scale_factor = device_scale_factor; - WindowPrivate(window).LocalSetSurfaceId(std::move(surface_info)); + WindowPrivate(window).LocalSetSurfaceInfo(surface_info); } void WindowTreeClient::OnDragDropStart(
diff --git a/services/ui/public/cpp/window_tree_client.h b/services/ui/public/cpp/window_tree_client.h index b2ba684c..06c33e82 100644 --- a/services/ui/public/cpp/window_tree_client.h +++ b/services/ui/public/cpp/window_tree_client.h
@@ -30,7 +30,6 @@ namespace gfx { class Insets; -class Size; } namespace service_manager { @@ -331,9 +330,7 @@ void OnWindowPredefinedCursorChanged(Id window_id, mojom::Cursor cursor) override; void OnWindowSurfaceChanged(Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) override; + const cc::SurfaceInfo& surface_info) override; void OnDragDropStart( const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data) override;
diff --git a/services/ui/public/interfaces/window_tree.mojom b/services/ui/public/interfaces/window_tree.mojom index 9380cee..1ea9a310 100644 --- a/services/ui/public/interfaces/window_tree.mojom +++ b/services/ui/public/interfaces/window_tree.mojom
@@ -4,8 +4,7 @@ module ui.mojom; -import "cc/ipc/surface_id.mojom"; -import "cc/ipc/surface_sequence.mojom"; +import "cc/ipc/surface_info.mojom"; import "cc/ipc/mojo_compositor_frame_sink.mojom"; import "services/ui/public/interfaces/cursor.mojom"; import "services/ui/public/interfaces/event_matcher.mojom"; @@ -434,9 +433,7 @@ // TODO(fsamuel): Surface IDs should be passed to parents directly instead of // going through the window server. http://crbug.com/655231 OnWindowSurfaceChanged(uint32 window_id, - cc.mojom.SurfaceId surface_id, - gfx.mojom.Size frame_size, - float device_scale_factor); + cc.mojom.SurfaceInfo surface_info); // Called when the mouse cursor enters a window on this connection for the // first time, providing a list of available mime types. We want to send this
diff --git a/services/ui/surfaces/display_compositor.cc b/services/ui/surfaces/display_compositor.cc index ea6184e..80faca0 100644 --- a/services/ui/surfaces/display_compositor.cc +++ b/services/ui/surfaces/display_compositor.cc
@@ -251,23 +251,22 @@ return reference_manager_->GetRootSurfaceId(); } -void DisplayCompositor::OnSurfaceCreated(const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { +void DisplayCompositor::OnSurfaceCreated(const cc::SurfaceInfo& surface_info) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_GT(device_scale_factor, 0.0f); + DCHECK_GT(surface_info.device_scale_factor(), 0.0f); // We can get into a situation where multiple CompositorFrames arrive for a // CompositorFrameSink before the DisplayCompositorClient can add any // references for the frame. When the second frame with a new size arrives, // the first will be destroyed and then if there are no references it will be // deleted during surface GC. A temporary reference, removed when a real // reference is received, is added to prevent this from happening. - reference_manager_->AddSurfaceReference(GetRootSurfaceId(), surface_id); - temp_references_[surface_id.frame_sink_id()].push_back( - surface_id.local_frame_id()); + reference_manager_->AddSurfaceReference(GetRootSurfaceId(), + surface_info.id()); + temp_references_[surface_info.id().frame_sink_id()].push_back( + surface_info.id().local_frame_id()); if (client_) - client_->OnSurfaceCreated(surface_id, frame_size, device_scale_factor); + client_->OnSurfaceCreated(surface_info); } void DisplayCompositor::OnSurfaceDamaged(const cc::SurfaceId& surface_id,
diff --git a/services/ui/surfaces/display_compositor.h b/services/ui/surfaces/display_compositor.h index b570400..fca74d8 100644 --- a/services/ui/surfaces/display_compositor.h +++ b/services/ui/surfaces/display_compositor.h
@@ -120,9 +120,7 @@ const cc::SurfaceId& GetRootSurfaceId() const; // cc::SurfaceObserver implementation. - void OnSurfaceCreated(const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) override; + void OnSurfaceCreated(const cc::SurfaceInfo& surface_info) override; void OnSurfaceDamaged(const cc::SurfaceId& surface_id, bool* changed) override;
diff --git a/services/ui/surfaces/display_compositor_unittest.cc b/services/ui/surfaces/display_compositor_unittest.cc index c3dc07b4..23d32a5 100644 --- a/services/ui/surfaces/display_compositor_unittest.cc +++ b/services/ui/surfaces/display_compositor_unittest.cc
@@ -72,12 +72,10 @@ got_root_surface_id_ = true; } - void OnSurfaceCreated(const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) override { + void OnSurfaceCreated(const cc::SurfaceInfo& surface_info) override { EXPECT_TRUE(got_root_surface_id_); AddEvent(base::StringPrintf("OnSurfaceCreated(%s)", - SurfaceIdString(surface_id).c_str())); + SurfaceIdString(surface_info.id()).c_str())); } mojo::Binding<cc::mojom::DisplayCompositorClient> binding_; @@ -193,7 +191,8 @@ TEST_F(DisplayCompositorTest, AddSurfaceThenReference) { const cc::SurfaceId parent_id = MakeSurfaceId(1, 1, 1); const cc::SurfaceId surface_id = MakeSurfaceId(2, 1, 1); - surface_observer()->OnSurfaceCreated(surface_id, gfx::Size(1, 1), 1.0f); + surface_observer()->OnSurfaceCreated( + cc::SurfaceInfo(surface_id, 1.0f, gfx::Size(1, 1))); RunUntilIdle(); // Client should get OnSurfaceCreated call and temporary reference added. @@ -212,7 +211,8 @@ TEST_F(DisplayCompositorTest, AddSurfaceThenRootReference) { const cc::SurfaceId surface_id = MakeSurfaceId(1, 1, 1); - surface_observer()->OnSurfaceCreated(surface_id, gfx::Size(1, 1), 1.0f); + surface_observer()->OnSurfaceCreated( + cc::SurfaceInfo(surface_id, 1.0f, gfx::Size(1, 1))); RunUntilIdle(); // Temporary reference should be added. @@ -234,8 +234,10 @@ const cc::SurfaceId surface_id2 = MakeSurfaceId(3, 1, 1); // Add two surfaces with different FrameSinkIds. - surface_observer()->OnSurfaceCreated(surface_id1, gfx::Size(1, 1), 1.0f); - surface_observer()->OnSurfaceCreated(surface_id2, gfx::Size(1, 1), 1.0f); + surface_observer()->OnSurfaceCreated( + cc::SurfaceInfo(surface_id1, 1.0f, gfx::Size(1, 1))); + surface_observer()->OnSurfaceCreated( + cc::SurfaceInfo(surface_id2, 1.0f, gfx::Size(1, 1))); RunUntilIdle(); // Temporary reference should be added for both surfaces. @@ -259,8 +261,10 @@ // Add two surfaces that have the same FrameSinkId. This would happen when a // client submits two CFs before parent submits a new CF. - surface_observer()->OnSurfaceCreated(surface_id1, gfx::Size(1, 1), 1.0f); - surface_observer()->OnSurfaceCreated(surface_id2, gfx::Size(1, 1), 1.0f); + surface_observer()->OnSurfaceCreated( + cc::SurfaceInfo(surface_id1, 1.0f, gfx::Size(1, 1))); + surface_observer()->OnSurfaceCreated( + cc::SurfaceInfo(surface_id2, 1.0f, gfx::Size(1, 1))); RunUntilIdle(); // Client should get OnSurfaceCreated call and temporary reference added for
diff --git a/services/ui/ws/frame_generator_unittest.cc b/services/ui/ws/frame_generator_unittest.cc index cb27ab19..49c4a98 100644 --- a/services/ui/ws/frame_generator_unittest.cc +++ b/services/ui/ws/frame_generator_unittest.cc
@@ -34,12 +34,13 @@ window->GetOrCreateCompositorFrameSinkManager(); compositor_frame_sink_manager->SetLatestSurfaceInfo( mojom::CompositorFrameSinkType::DEFAULT, - cc::SurfaceId( - cc::FrameSinkId( - WindowIdToTransportId(window->id()), - static_cast<uint32_t>(mojom::CompositorFrameSinkType::DEFAULT)), - cc::LocalFrameId(1u, kArbitraryToken)), - gfx::Size(100, 100)); + cc::SurfaceInfo( + cc::SurfaceId( + cc::FrameSinkId(WindowIdToTransportId(window->id()), + static_cast<uint32_t>( + mojom::CompositorFrameSinkType::DEFAULT)), + cc::LocalFrameId(1u, kArbitraryToken)), + 1.0f, gfx::Size(100, 100))); } } // namespace @@ -125,12 +126,13 @@ // that this creates an extra SharedQuadState in the CompositorFrame. child_window.GetOrCreateCompositorFrameSinkManager()->SetLatestSurfaceInfo( mojom::CompositorFrameSinkType::UNDERLAY, - cc::SurfaceId( - cc::FrameSinkId( - WindowIdToTransportId(child_window.id()), - static_cast<uint32_t>(mojom::CompositorFrameSinkType::UNDERLAY)), - cc::LocalFrameId(1u, kArbitraryToken)), - gfx::Size(100, 100)); + cc::SurfaceInfo( + cc::SurfaceId( + cc::FrameSinkId(WindowIdToTransportId(child_window.id()), + static_cast<uint32_t>( + mojom::CompositorFrameSinkType::UNDERLAY)), + cc::LocalFrameId(1u, kArbitraryToken)), + 1.0f, gfx::Size(100, 100))); render_pass = cc::RenderPass::Create(); DrawWindowTree(render_pass.get());
diff --git a/services/ui/ws/server_window_compositor_frame_sink_manager.cc b/services/ui/ws/server_window_compositor_frame_sink_manager.cc index d1014ea..7480c7f 100644 --- a/services/ui/ws/server_window_compositor_frame_sink_manager.cc +++ b/services/ui/ws/server_window_compositor_frame_sink_manager.cc
@@ -94,7 +94,7 @@ if (it == type_to_compositor_frame_sink_map_.end()) return gfx::Size(); - return it->second.latest_submitted_frame_size; + return it->second.latest_submitted_surface_info.size_in_pixels(); } cc::SurfaceId ServerWindowCompositorFrameSinkManager::GetLatestSurfaceId( @@ -103,16 +103,14 @@ if (it == type_to_compositor_frame_sink_map_.end()) return cc::SurfaceId(); - return it->second.latest_submitted_surface_id; + return it->second.latest_submitted_surface_info.id(); } void ServerWindowCompositorFrameSinkManager::SetLatestSurfaceInfo( mojom::CompositorFrameSinkType type, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size) { + const cc::SurfaceInfo& surface_info) { CompositorFrameSinkData& data = type_to_compositor_frame_sink_map_[type]; - data.latest_submitted_surface_id = surface_id; - data.latest_submitted_frame_size = frame_size; + data.latest_submitted_surface_info = surface_info; } void ServerWindowCompositorFrameSinkManager::OnRootChanged( @@ -136,10 +134,10 @@ auto iter = type_to_compositor_frame_sink_map_.find(type); if (iter == type_to_compositor_frame_sink_map_.end()) return false; - if (iter->second.latest_submitted_frame_size.IsEmpty()) + if (iter->second.latest_submitted_surface_info.size_in_pixels().IsEmpty()) return false; const gfx::Size& latest_submitted_frame_size = - iter->second.latest_submitted_frame_size; + iter->second.latest_submitted_surface_info.size_in_pixels(); return latest_submitted_frame_size.width() >= window_->bounds().width() && latest_submitted_frame_size.height() >= window_->bounds().height(); } @@ -196,12 +194,12 @@ CompositorFrameSinkData::CompositorFrameSinkData( CompositorFrameSinkData&& other) - : latest_submitted_surface_id(other.latest_submitted_surface_id), + : latest_submitted_surface_info(other.latest_submitted_surface_info), compositor_frame_sink(std::move(other.compositor_frame_sink)) {} CompositorFrameSinkData& CompositorFrameSinkData::operator=( CompositorFrameSinkData&& other) { - latest_submitted_surface_id = other.latest_submitted_surface_id; + latest_submitted_surface_info = other.latest_submitted_surface_info; compositor_frame_sink = std::move(other.compositor_frame_sink); return *this; }
diff --git a/services/ui/ws/server_window_compositor_frame_sink_manager.h b/services/ui/ws/server_window_compositor_frame_sink_manager.h index f71a76b..8ca40a34 100644 --- a/services/ui/ws/server_window_compositor_frame_sink_manager.h +++ b/services/ui/ws/server_window_compositor_frame_sink_manager.h
@@ -29,8 +29,7 @@ CompositorFrameSinkData& operator=(CompositorFrameSinkData&& other); - cc::SurfaceId latest_submitted_surface_id; - gfx::Size latest_submitted_frame_size; + cc::SurfaceInfo latest_submitted_surface_info; cc::mojom::MojoCompositorFrameSinkPrivatePtr compositor_frame_sink; cc::mojom::MojoCompositorFrameSinkPrivateRequest pending_compositor_frame_sink_request; @@ -83,8 +82,7 @@ gfx::Size GetLatestFrameSize(mojom::CompositorFrameSinkType type) const; cc::SurfaceId GetLatestSurfaceId(mojom::CompositorFrameSinkType type) const; void SetLatestSurfaceInfo(mojom::CompositorFrameSinkType type, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size); + const cc::SurfaceInfo& surface_info); void OnRootChanged(ServerWindow* old_root, ServerWindow* new_root);
diff --git a/services/ui/ws/test_change_tracker.cc b/services/ui/ws/test_change_tracker.cc index 5c7e4d4..1e7e0f3 100644 --- a/services/ui/ws/test_change_tracker.cc +++ b/services/ui/ws/test_change_tracker.cc
@@ -426,15 +426,13 @@ void TestChangeTracker::OnWindowSurfaceChanged( Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { + const cc::SurfaceInfo& surface_info) { Change change; change.type = CHANGE_TYPE_SURFACE_CHANGED; change.window_id = window_id; - change.surface_id = surface_id; - change.frame_size = frame_size; - change.device_scale_factor = device_scale_factor; + change.surface_id = surface_info.id(); + change.frame_size = surface_info.size_in_pixels(); + change.device_scale_factor = surface_info.device_scale_factor(); AddChange(change); }
diff --git a/services/ui/ws/test_change_tracker.h b/services/ui/ws/test_change_tracker.h index 3601fca2..6e99670 100644 --- a/services/ui/ws/test_change_tracker.h +++ b/services/ui/ws/test_change_tracker.h
@@ -174,9 +174,7 @@ mojom::WindowDataPtr window_data, bool drawn); void OnWindowSurfaceChanged(Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor); + const cc::SurfaceInfo& surface_info); private: void AddChange(const Change& change);
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc index f11d843..947f089 100644 --- a/services/ui/ws/test_utils.cc +++ b/services/ui/ws/test_utils.cc
@@ -371,9 +371,7 @@ void TestWindowTreeClient::OnWindowSurfaceChanged( Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) {} + const cc::SurfaceInfo& surface_info) {} void TestWindowTreeClient::OnDragDropStart( const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data) {}
diff --git a/services/ui/ws/test_utils.h b/services/ui/ws/test_utils.h index 9cafaa9..5f5cb30 100644 --- a/services/ui/ws/test_utils.h +++ b/services/ui/ws/test_utils.h
@@ -443,9 +443,7 @@ void OnWindowPredefinedCursorChanged(uint32_t window_id, mojom::Cursor cursor_id) override; void OnWindowSurfaceChanged(Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) override; + const cc::SurfaceInfo& surface_info) override; void OnDragDropStart( const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data) override;
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index 3f14290f..651eb15 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -765,14 +765,12 @@ delegate_->StartDisplayInit(); } -void WindowServer::OnSurfaceCreated(const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { +void WindowServer::OnSurfaceCreated(const cc::SurfaceInfo& surface_info) { WindowId window_id( - WindowIdFromTransportId(surface_id.frame_sink_id().client_id())); + WindowIdFromTransportId(surface_info.id().frame_sink_id().client_id())); mojom::CompositorFrameSinkType compositor_frame_sink_type( static_cast<mojom::CompositorFrameSinkType>( - surface_id.frame_sink_id().sink_id())); + surface_info.id().frame_sink_id().sink_id())); ServerWindow* window = GetWindow(window_id); // If the window doesn't have a parent then we have nothing to propagate. if (!window) @@ -782,14 +780,14 @@ // DisplayCompositorFrameSink may submit a CompositorFrame without // creating a CompositorFrameSinkManager. window->GetOrCreateCompositorFrameSinkManager()->SetLatestSurfaceInfo( - compositor_frame_sink_type, surface_id, frame_size); + compositor_frame_sink_type, surface_info); // FrameGenerator will add an appropriate reference for the new surface. DCHECK(display_manager_->GetDisplayContaining(window)); display_manager_->GetDisplayContaining(window) ->platform_display() ->GetFrameGenerator() - ->OnSurfaceCreated(surface_id, window); + ->OnSurfaceCreated(surface_info.id(), window); // This is only used for testing to observe that a window has a // CompositorFrame. @@ -803,10 +801,8 @@ return; } WindowTree* window_tree = GetTreeWithId(window->parent()->id().client_id); - if (window_tree) { - window_tree->ProcessWindowSurfaceChanged(window, surface_id, frame_size, - device_scale_factor); - } + if (window_tree) + window_tree->ProcessWindowSurfaceChanged(window, surface_info); } void WindowServer::OnDisplayCompositorCreated(
diff --git a/services/ui/ws/window_server.h b/services/ui/ws/window_server.h index 9945f0b1..da21f65 100644 --- a/services/ui/ws/window_server.h +++ b/services/ui/ws/window_server.h
@@ -328,9 +328,7 @@ void OnGpuServiceInitialized() override; // cc::mojom::DisplayCompositorClient: - void OnSurfaceCreated(const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) override; + void OnSurfaceCreated(const cc::SurfaceInfo& surface_info) override; void OnDisplayCompositorCreated( const cc::SurfaceId& root_surface_id) override;
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc index a9d098e..4fdd82c 100644 --- a/services/ui/ws/window_tree.cc +++ b/services/ui/ws/window_tree.cc
@@ -783,10 +783,9 @@ transient_client_window_id.id); } -void WindowTree::ProcessWindowSurfaceChanged(ServerWindow* window, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { +void WindowTree::ProcessWindowSurfaceChanged( + ServerWindow* window, + const cc::SurfaceInfo& surface_info) { ServerWindow* parent_window = window->parent(); ClientWindowId client_window_id, parent_client_window_id; if (!IsWindowKnown(window, &client_window_id) || @@ -795,8 +794,7 @@ return; } - client()->OnWindowSurfaceChanged(client_window_id.id, surface_id, frame_size, - device_scale_factor); + client()->OnWindowSurfaceChanged(client_window_id.id, surface_info); } void WindowTree::SendToPointerWatcher(const ui::Event& event,
diff --git a/services/ui/ws/window_tree.h b/services/ui/ws/window_tree.h index 0331e1b..acf63c55 100644 --- a/services/ui/ws/window_tree.h +++ b/services/ui/ws/window_tree.h
@@ -258,9 +258,7 @@ const ServerWindow* transient_window, bool originated_change); void ProcessWindowSurfaceChanged(ServerWindow* window, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor); + const cc::SurfaceInfo& surface_info); // Sends this event to the client if it matches an active pointer watcher. // |target_window| is the target of the event, and may be null or not known
diff --git a/services/ui/ws/window_tree_client_unittest.cc b/services/ui/ws/window_tree_client_unittest.cc index 24f6657..b051a4b 100644 --- a/services/ui/ws/window_tree_client_unittest.cc +++ b/services/ui/ws/window_tree_client_unittest.cc
@@ -383,11 +383,8 @@ } void OnWindowSurfaceChanged(Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) override { - tracker_.OnWindowSurfaceChanged(window_id, surface_id, frame_size, - device_scale_factor); + const cc::SurfaceInfo& surface_info) override { + tracker_.OnWindowSurfaceChanged(window_id, surface_info); } void OnDragEnter(uint32_t window,
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 8057a263..73d3a37 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -402,12 +402,6 @@ "test": "url_unittests" }, { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "views_aura_mus_unittests" - }, - { "args": [ "--override-use-gl-with-osmesa-for-tests" ], @@ -417,9 +411,6 @@ "test": "views_mus_interactive_ui_tests" }, { - "args": [ - "--override-use-gl-with-osmesa-for-tests" - ], "swarming": { "can_use_on_swarming_builders": false },
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 9eb52c84..a523231d 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -12876,7 +12876,7 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "views_aura_mus_unittests" + "test": "views_mus_unittests" } ] }, @@ -12914,12 +12914,6 @@ "can_use_on_swarming_builders": false }, "test": "views_mus_interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": false - }, - "test": "views_mus_unittests" } ] },
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index fa85b29..84215c51 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -3347,18 +3347,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "views_mus_interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_mus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "views_unittests" }, {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 8b21a0a..67280c5 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -947,10 +947,6 @@ "label": "//url:url_unittests", "type": "console_test_launcher", }, - "views_aura_mus_unittests": { - "label": "//ui/views/mus:views_aura_mus_unittests", - "type": "windowed_test_launcher", - }, "views_mus_interactive_ui_tests": { "label": "//ui/views/mus:views_mus_interactive_ui_tests", "type": "windowed_test_launcher",
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 4f016c92..b092fd8 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2416,7 +2416,7 @@ "experiments": [ { "name": "Enabled", - "enable_features": [ + "disable_features": [ "VrShell" ] }
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index dc6ef62..62816af 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -83,7 +83,6 @@ Bug(none) broadcastchannel/blobs.html [ Pass Failure ] Bug(none) compositing/3d-cube.html [ Failure ] Bug(none) compositing/absolute-inside-out-of-view-fixed.html [ Failure ] -crbug.com/668342 compositing/always-composite-fixed-position-when-descendants-composite.html [ Failure ] Bug(none) compositing/animation/hidden-composited.html [ Failure ] Bug(none) compositing/backface-visibility/backface-visibility-image.html [ Failure ] Bug(none) compositing/backface-visibility/backface-visibility-webgl.html [ Failure ] @@ -542,7 +541,6 @@ Bug(none) fast/canvas/canvas-composite-video.html [ Failure ] Bug(none) fast/canvas/canvas-css-clip-path.html [ Failure ] Bug(none) fast/canvas/webgl/pixelated.html [ Failure ] -crbug.com/668342 fast/clip/010.html [ Failure ] Bug(none) fast/clip/nestedTransparencyClip.html [ Failure ] Bug(none) fast/clip/outline-overflowClip.html [ Failure ] Bug(none) fast/clip/overflow-border-radius-clip.html [ Failure ] @@ -2217,10 +2215,10 @@ # transforms/transform-overflow.html # Subpixel adjustments due to differences in compositing -crbug.com/668342 fast/pagination/auto-height-with-break.html [ Failure ] -crbug.com/668342 svg/custom/non-scaling-stroke-update.svg [ Failure ] -crbug.com/668342 fast/css/transform-default-parameter.html [ Failure ] -crbug.com/668342 svg/custom/use-css-events.svg [ Failure ] -crbug.com/668342 svg/text/text-layout-crash.html [ Failure ] -crbug.com/668342 fast/multicol/span/invalid-spanner-in-transform.html [ Failure ] -crbug.com/668342 images/color-profile-iframe.html [ Failure ] +Bug(none) fast/pagination/auto-height-with-break.html [ Failure ] +Bug(none) svg/custom/non-scaling-stroke-update.svg [ Failure ] +Bug(none) fast/css/transform-default-parameter.html [ Failure ] +Bug(none) svg/custom/use-css-events.svg [ Failure ] +Bug(none) svg/text/text-layout-crash.html [ Failure ] +Bug(none) fast/multicol/span/invalid-spanner-in-transform.html [ Failure ] +Bug(none) images/color-profile-iframe.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 42adfe5..f814331 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -100,6 +100,10 @@ # individually listed tests. crbug.com/646176 virtual/spinvalidation/ [ Skip ] crbug.com/646176 virtual/spinvalidation/paint/invalidation/ [ Pass ] +# Skip the base tests when SlimmingPaintInvalidation is enabled for experimental +# to avoid rebaselining test expectations when switching back and forth the +# flag. These tests are still run in virtual/spinvalidation suite. +crbug.com/646176 paint/invalidation/ [ Skip ] crbug.com/646176 virtual/spinvalidation/compositing/overflow/scroller-with-border-radius.html [ Pass ] crbug.com/646176 virtual/spinvalidation/fast/dynamic/static-to-relative-with-absolute-child.html [ Pass ] @@ -778,7 +782,6 @@ crbug.com/248938 virtual/threaded/animations/dynamic-stylesheet-loading.html [ Pass Failure Timeout ] crbug.com/248938 virtual/threaded/transitions/change-duration-during-transition.html [ Pass Failure ] crbug.com/248938 virtual/threaded/transitions/transition-end-event-nested.html [ Pass Failure ] -crbug.com/248938 virtual/threaded/animations/display-none-terminates-animation.html [ Pass Failure ] crbug.com/638693 virtual/threaded/animations/display-inline-style-adjust.html [ Pass Crash Failure ] crbug.com/421283 fast/html/marquee-scrollamount.html [ Pass Failure ] crbug.com/248938 virtual/threaded/transitions/transition-end-event-rendering.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/animations/display-none-terminates-animation.html b/third_party/WebKit/LayoutTests/animations/display-none-terminates-animation.html index 666ca19..b81ef27 100644 --- a/third_party/WebKit/LayoutTests/animations/display-none-terminates-animation.html +++ b/third_party/WebKit/LayoutTests/animations/display-none-terminates-animation.html
@@ -44,7 +44,7 @@ log('INFO: Start event fired'); target.removeEventListener('animationstart', onStart); requestAnimationFrame(function() { - setTimeout(setDisplayNone, 100); + setTimeout(setDisplayNone, 300); }); } @@ -53,7 +53,7 @@ leftPropertyWhenSetDisplayNone = getComputedStyle(target).left; target.style.display = 'none'; requestAnimationFrame(function() { - setTimeout(setDisplayBlock, 100); + requestAnimationFrame(setDisplayBlock); }); }
diff --git a/third_party/WebKit/LayoutTests/custom-properties/registered-property-cssom.html b/third_party/WebKit/LayoutTests/custom-properties/registered-property-cssom.html new file mode 100644 index 0000000..8118465 --- /dev/null +++ b/third_party/WebKit/LayoutTests/custom-properties/registered-property-cssom.html
@@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<style> +#inner { + --length: 10px; + --color: red; +} +#outer { + --color: blue; +} +</style> + +<div id=inner></div> + +<script> +var computedStyle = getComputedStyle(inner); +var inlineStyle = inner.style; +var sheetStyle = document.styleSheets[0].cssRules[0].style; + +test(function() { + // Nothing registered yet, whatever you specify works + assert_equals(computedStyle.getPropertyValue('--length'), ' 10px'); + assert_equals(computedStyle.getPropertyValue('--color'), ' red'); + + inlineStyle.setProperty('--length', '5'); + inlineStyle.setProperty('--color', 'hello'); + + assert_equals(inlineStyle.getPropertyValue('--length'), '5'); + assert_equals(inlineStyle.getPropertyValue('--color'), 'hello'); + assert_equals(computedStyle.getPropertyValue('--length'), '5'); + assert_equals(computedStyle.getPropertyValue('--color'), 'hello'); +}, "CSSOM setters function as expected for unregistered properties"); + +CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: '0px'}); +CSS.registerProperty({name: '--color', syntax: '<color>', initialValue: 'white', inherits: true}); + +test(function() { + assert_equals(inlineStyle.getPropertyValue('--length'), '5'); + assert_equals(inlineStyle.getPropertyValue('--color'), 'hello'); + assert_equals(computedStyle.getPropertyValue('--length'), '0px'); + assert_equals(computedStyle.getPropertyValue('--color'), 'white'); +}, "Formerly valid values are still readable from inline styles but are computed as the unset value"); + +test(function() { + inlineStyle.setProperty('--length', 'hi'); + inlineStyle.setProperty('--color', '20'); + assert_equals(inlineStyle.getPropertyValue('--length'), '5'); + assert_equals(inlineStyle.getPropertyValue('--color'), 'hello'); +}, "Values not matching the registered type can't be set"); + +test(function() { + inlineStyle.removeProperty('--length'); + inlineStyle.setProperty('--color', ''); + assert_equals(inlineStyle.getPropertyValue('--length'), ''); + assert_equals(inlineStyle.getPropertyValue('--color'), ''); + assert_equals(computedStyle.getPropertyValue('--length'), '10px'); + assert_equals(computedStyle.getPropertyValue('--color'), 'red'); +}, "Values can be removed from inline styles"); + +test(function() { + sheetStyle.setProperty('--length', 'banana'); // Invalid, no change + assert_equals(computedStyle.getPropertyValue('--length'), '10px'); + sheetStyle.setProperty('--length', '20px'); + assert_equals(computedStyle.getPropertyValue('--length'), '20px'); +}, "Stylesheets can be modified by CSSOM"); + +test(function() { + inlineStyle.setProperty('--length', '30px'); + inlineStyle.setProperty('--color', 'pink'); + assert_equals(inlineStyle.getPropertyValue('--length'), '30px'); + assert_equals(inlineStyle.getPropertyValue('--color'), 'pink'); + assert_equals(computedStyle.getPropertyValue('--length'), '30px'); + assert_equals(computedStyle.getPropertyValue('--color'), 'pink'); +}, "Valid values can be set on inline styles"); +</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt index 3e02050..3fe90b6 100644 --- a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt +++ b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt
@@ -10,7 +10,7 @@ FAIL [[Delete]] Should throw on cross-origin objects assert_throws: Can't delete cross-origin indexed property function "function () { delete C[0]; }" did not throw FAIL [[DefineOwnProperty]] Should throw for cross-origin objects assert_throws: Can't define cross-origin value property length function "function () { Object.defineProperty(obj, prop, valueDesc); }" did not throw FAIL [[Enumerate]] should return an empty iterator assert_unreached: Shouldn't have been able to enumerate stop on cross-origin Window Reached unreachable code -FAIL [[OwnPropertyKeys]] should return all properties from cross-origin objects assert_array_equals: Object.getOwnPropertyNames() gives the right answer for cross-origin Window lengths differ, expected 870 got 13 +FAIL [[OwnPropertyKeys]] should return all properties from cross-origin objects assert_array_equals: Object.getOwnPropertyNames() gives the right answer for cross-origin Window lengths differ, expected 871 got 13 PASS A and B jointly observe the same identity for cross-origin Window and Location PASS Cross-origin functions get local Function.prototype FAIL Cross-origin Window accessors get local Function.prototype Cannot read property 'name' of undefined
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/stable/webexposed/global-interface-listing-expected.txt new file mode 100644 index 0000000..cbe49a8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -0,0 +1,7680 @@ +CONSOLE WARNING: line 94: 'webkitURL' is deprecated. Please use 'URL' instead. +This test documents all interface attributes and methods on the global window object and element instances. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +[INTERFACES] +interface AnalyserNode : AudioNode + attribute @@toStringTag + getter fftSize + getter frequencyBinCount + getter maxDecibels + getter minDecibels + getter smoothingTimeConstant + method constructor + method getByteFrequencyData + method getByteTimeDomainData + method getFloatFrequencyData + method getFloatTimeDomainData + setter fftSize + setter maxDecibels + setter minDecibels + setter smoothingTimeConstant +interface AnimationEvent : Event + attribute @@toStringTag + getter animationName + getter elapsedTime + method constructor +interface AppBannerPromptResult + attribute @@toStringTag + getter outcome + getter platform + method constructor +interface ApplicationCache : EventTarget + attribute @@toStringTag + attribute CHECKING + attribute DOWNLOADING + attribute IDLE + attribute OBSOLETE + attribute UNCACHED + attribute UPDATEREADY + getter oncached + getter onchecking + getter ondownloading + getter onerror + getter onnoupdate + getter onobsolete + getter onprogress + getter onupdateready + getter status + method abort + method constructor + method swapCache + method update + setter oncached + setter onchecking + setter ondownloading + setter onerror + setter onnoupdate + setter onobsolete + setter onprogress + setter onupdateready +interface ApplicationCacheErrorEvent : Event + attribute @@toStringTag + getter message + getter reason + getter status + getter url + method constructor +interface Attr : Node + attribute @@toStringTag + getter localName + getter name + getter namespaceURI + getter ownerElement + getter prefix + getter specified + getter value + method constructor + setter value +interface Audio + method constructor +interface AudioBuffer + attribute @@toStringTag + getter duration + getter length + getter numberOfChannels + getter sampleRate + method constructor + method copyFromChannel + method copyToChannel + method getChannelData +interface AudioBufferSourceNode : AudioScheduledSourceNode + attribute @@toStringTag + getter buffer + getter detune + getter loop + getter loopEnd + getter loopStart + getter playbackRate + method constructor + method start + setter buffer + setter loop + setter loopEnd + setter loopStart +interface AudioContext : BaseAudioContext + attribute @@toStringTag + method close + method constructor + method getOutputTimestamp + method suspend +interface AudioDestinationNode : AudioNode + attribute @@toStringTag + getter maxChannelCount + method constructor +interface AudioListener + attribute @@toStringTag + getter forwardX + getter forwardY + getter forwardZ + getter positionX + getter positionY + getter positionZ + getter upX + getter upY + getter upZ + method constructor + method setOrientation + method setPosition +interface AudioNode : EventTarget + attribute @@toStringTag + getter channelCount + getter channelCountMode + getter channelInterpretation + getter context + getter numberOfInputs + getter numberOfOutputs + method connect + method constructor + method disconnect + setter channelCount + setter channelCountMode + setter channelInterpretation +interface AudioParam + attribute @@toStringTag + getter defaultValue + getter maxValue + getter minValue + getter value + method cancelScheduledValues + method constructor + method exponentialRampToValueAtTime + method linearRampToValueAtTime + method setTargetAtTime + method setValueAtTime + method setValueCurveAtTime + setter value +interface AudioProcessingEvent : Event + attribute @@toStringTag + getter inputBuffer + getter outputBuffer + getter playbackTime + method constructor +interface AudioScheduledSourceNode : AudioNode + attribute @@toStringTag + getter onended + method constructor + method start + method stop + setter onended +interface BarProp + attribute @@toStringTag + getter visible + method constructor +interface BaseAudioContext : EventTarget + attribute @@toStringTag + getter currentTime + getter destination + getter listener + getter onstatechange + getter sampleRate + getter state + method constructor + method createAnalyser + method createBiquadFilter + method createBuffer + method createBufferSource + method createChannelMerger + method createChannelSplitter + method createConstantSource + method createConvolver + method createDelay + method createDynamicsCompressor + method createGain + method createIIRFilter + method createMediaElementSource + method createMediaStreamDestination + method createMediaStreamSource + method createOscillator + method createPanner + method createPeriodicWave + method createScriptProcessor + method createStereoPanner + method createWaveShaper + method decodeAudioData + method resume + setter onstatechange +interface BatteryManager : EventTarget + attribute @@toStringTag + getter charging + getter chargingTime + getter dischargingTime + getter level + getter onchargingchange + getter onchargingtimechange + getter ondischargingtimechange + getter onlevelchange + method constructor + setter onchargingchange + setter onchargingtimechange + setter ondischargingtimechange + setter onlevelchange +interface BeforeInstallPromptEvent : Event + attribute @@toStringTag + getter platforms + getter userChoice + method constructor + method prompt +interface BeforeUnloadEvent : Event + attribute @@toStringTag + getter returnValue + method constructor + setter returnValue +interface BiquadFilterNode : AudioNode + attribute @@toStringTag + getter Q + getter detune + getter frequency + getter gain + getter type + method constructor + method getFrequencyResponse + setter type +interface Blob + attribute @@toStringTag + getter size + getter type + method constructor + method slice +interface BlobEvent : Event + attribute @@toStringTag + getter data + method constructor +interface BroadcastChannel : EventTarget + attribute @@toStringTag + getter name + getter onmessage + method close + method constructor + method postMessage + setter onmessage +interface ByteLengthQueuingStrategy + method constructor + method size +interface CDATASection : Text + attribute @@toStringTag + method constructor +interface CSS + static method escape + static method supports + attribute @@toStringTag + method constructor +interface CSSConditionRule : CSSGroupingRule + attribute @@toStringTag + getter conditionText + method constructor +interface CSSFontFaceRule : CSSRule + attribute @@toStringTag + getter style + method constructor +interface CSSGroupingRule : CSSRule + attribute @@toStringTag + getter cssRules + method constructor + method deleteRule + method insertRule +interface CSSImportRule : CSSRule + attribute @@toStringTag + getter href + getter media + getter styleSheet + method constructor +interface CSSKeyframeRule : CSSRule + attribute @@toStringTag + getter keyText + getter style + method constructor + setter keyText +interface CSSKeyframesRule : CSSRule + attribute @@toStringTag + getter cssRules + getter name + method appendRule + method constructor + method deleteRule + method findRule + setter name +interface CSSMediaRule : CSSConditionRule + attribute @@toStringTag + getter media + method constructor +interface CSSNamespaceRule : CSSRule + attribute @@toStringTag + getter namespaceURI + getter prefix + method constructor +interface CSSPageRule : CSSRule + attribute @@toStringTag + getter selectorText + getter style + method constructor + setter selectorText +interface CSSRule + attribute @@toStringTag + attribute CHARSET_RULE + attribute FONT_FACE_RULE + attribute IMPORT_RULE + attribute KEYFRAMES_RULE + attribute KEYFRAME_RULE + attribute MEDIA_RULE + attribute NAMESPACE_RULE + attribute PAGE_RULE + attribute STYLE_RULE + attribute SUPPORTS_RULE + attribute WEBKIT_KEYFRAMES_RULE + attribute WEBKIT_KEYFRAME_RULE + getter cssText + getter parentRule + getter parentStyleSheet + getter type + method constructor + setter cssText +interface CSSRuleList + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item +interface CSSStyleDeclaration + attribute @@toStringTag + getter cssFloat + getter cssText + getter length + getter parentRule + method @@iterator + method constructor + method getPropertyPriority + method getPropertyValue + method item + method removeProperty + method setProperty + setter cssFloat + setter cssText +interface CSSStyleRule : CSSRule + attribute @@toStringTag + getter selectorText + getter style + method constructor + setter selectorText + setter style +interface CSSStyleSheet : StyleSheet + attribute @@toStringTag + getter cssRules + getter ownerRule + getter rules + method addRule + method constructor + method deleteRule + method insertRule + method removeRule +interface CSSSupportsRule : CSSConditionRule + attribute @@toStringTag + method constructor +interface CSSViewportRule : CSSRule + attribute @@toStringTag + getter style + method constructor +interface Cache + attribute @@toStringTag + method add + method addAll + method constructor + method delete + method keys + method match + method matchAll + method put +interface CacheStorage + attribute @@toStringTag + method constructor + method delete + method has + method keys + method match + method open +interface CanvasCaptureMediaStreamTrack : MediaStreamTrack + attribute @@toStringTag + getter canvas + method constructor + method requestFrame +interface CanvasGradient + attribute @@toStringTag + method addColorStop + method constructor +interface CanvasPattern + attribute @@toStringTag + method constructor +interface CanvasRenderingContext2D + attribute @@toStringTag + getter canvas + getter fillStyle + getter filter + getter font + getter globalAlpha + getter globalCompositeOperation + getter imageSmoothingEnabled + getter imageSmoothingQuality + getter lineCap + getter lineDashOffset + getter lineJoin + getter lineWidth + getter miterLimit + getter shadowBlur + getter shadowColor + getter shadowOffsetX + getter shadowOffsetY + getter strokeStyle + getter textAlign + getter textBaseline + method arc + method arcTo + method beginPath + method bezierCurveTo + method clearRect + method clip + method closePath + method constructor + method createImageData + method createLinearGradient + method createPattern + method createRadialGradient + method drawFocusIfNeeded + method drawImage + method ellipse + method fill + method fillRect + method fillText + method getContextAttributes + method getImageData + method getLineDash + method isPointInPath + method isPointInStroke + method lineTo + method measureText + method moveTo + method putImageData + method quadraticCurveTo + method rect + method resetTransform + method restore + method rotate + method save + method scale + method setLineDash + method setTransform + method stroke + method strokeRect + method strokeText + method transform + method translate + setter fillStyle + setter filter + setter font + setter globalAlpha + setter globalCompositeOperation + setter imageSmoothingEnabled + setter imageSmoothingQuality + setter lineCap + setter lineDashOffset + setter lineJoin + setter lineWidth + setter miterLimit + setter shadowBlur + setter shadowColor + setter shadowOffsetX + setter shadowOffsetY + setter strokeStyle + setter textAlign + setter textBaseline +interface ChannelMergerNode : AudioNode + attribute @@toStringTag + method constructor +interface ChannelSplitterNode : AudioNode + attribute @@toStringTag + method constructor +interface CharacterData : Node + attribute @@toStringTag + attribute @@unscopables + getter data + getter length + getter nextElementSibling + getter previousElementSibling + method after + method appendData + method before + method constructor + method deleteData + method insertData + method remove + method replaceData + method replaceWith + method substringData + setter data +interface ClientRect + attribute @@toStringTag + getter bottom + getter height + getter left + getter right + getter top + getter width + method constructor +interface ClientRectList + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item +interface ClipboardEvent : Event + attribute @@toStringTag + getter clipboardData + method constructor +interface CloseEvent : Event + attribute @@toStringTag + getter code + getter reason + getter wasClean + method constructor +interface Comment : CharacterData + attribute @@toStringTag + method constructor +interface CompositionEvent : UIEvent + attribute @@toStringTag + getter data + method constructor + method initCompositionEvent +interface ConstantSourceNode : AudioScheduledSourceNode + attribute @@toStringTag + getter offset + method constructor +interface ConvolverNode : AudioNode + attribute @@toStringTag + getter buffer + getter normalize + method constructor + setter buffer + setter normalize +interface CountQueuingStrategy + method constructor + method size +interface Credential + attribute @@toStringTag + getter id + getter type + method constructor +interface CredentialsContainer + attribute @@toStringTag + method constructor + method get + method requireUserMediation + method store +interface Crypto + attribute @@toStringTag + getter subtle + method constructor + method getRandomValues +interface CryptoKey + attribute @@toStringTag + getter algorithm + getter extractable + getter type + getter usages + method constructor +interface CustomElementRegistry + attribute @@toStringTag + method constructor + method define + method get + method whenDefined +interface CustomEvent : Event + attribute @@toStringTag + getter detail + method constructor + method initCustomEvent +interface DOMError + attribute @@toStringTag + getter message + getter name + method constructor +interface DOMException + attribute @@toStringTag + attribute ABORT_ERR + attribute DATA_CLONE_ERR + attribute DOMSTRING_SIZE_ERR + attribute HIERARCHY_REQUEST_ERR + attribute INDEX_SIZE_ERR + attribute INUSE_ATTRIBUTE_ERR + attribute INVALID_ACCESS_ERR + attribute INVALID_CHARACTER_ERR + attribute INVALID_MODIFICATION_ERR + attribute INVALID_NODE_TYPE_ERR + attribute INVALID_STATE_ERR + attribute NAMESPACE_ERR + attribute NETWORK_ERR + attribute NOT_FOUND_ERR + attribute NOT_SUPPORTED_ERR + attribute NO_DATA_ALLOWED_ERR + attribute NO_MODIFICATION_ALLOWED_ERR + attribute QUOTA_EXCEEDED_ERR + attribute SECURITY_ERR + attribute SYNTAX_ERR + attribute TIMEOUT_ERR + attribute TYPE_MISMATCH_ERR + attribute URL_MISMATCH_ERR + attribute VALIDATION_ERR + attribute WRONG_DOCUMENT_ERR + getter code + getter message + getter name + method constructor + method toString +interface DOMImplementation + attribute @@toStringTag + method constructor + method createDocument + method createDocumentType + method createHTMLDocument + method hasFeature +interface DOMParser + attribute @@toStringTag + method constructor + method parseFromString +interface DOMStringList + attribute @@toStringTag + getter length + method @@iterator + method constructor + method contains + method item +interface DOMStringMap + attribute @@toStringTag + method constructor +interface DOMTokenList + attribute @@toStringTag + getter length + getter value + method @@iterator + method add + method constructor + method contains + method entries + method forEach + method item + method keys + method remove + method supports + method toString + method toggle + method values + setter value +interface DataTransfer + attribute @@toStringTag + getter dropEffect + getter effectAllowed + getter files + getter items + getter types + method clearData + method constructor + method getData + method setData + method setDragImage + setter dropEffect + setter effectAllowed +interface DataTransferItem + attribute @@toStringTag + getter kind + getter type + method constructor + method getAsFile + method getAsString + method webkitGetAsEntry +interface DataTransferItemList + attribute @@toStringTag + getter length + method @@iterator + method add + method clear + method constructor + method remove +interface DataView + attribute @@toStringTag + getter buffer + getter byteLength + getter byteOffset + method constructor + method getFloat32 + method getFloat64 + method getInt16 + method getInt32 + method getInt8 + method getUint16 + method getUint32 + method getUint8 + method setFloat32 + method setFloat64 + method setInt16 + method setInt32 + method setInt8 + method setUint16 + method setUint32 + method setUint8 +interface DelayNode : AudioNode + attribute @@toStringTag + getter delayTime + method constructor +interface DeviceMotionEvent : Event + attribute @@toStringTag + getter acceleration + getter accelerationIncludingGravity + getter interval + getter rotationRate + method constructor + method initDeviceMotionEvent +interface DeviceOrientationEvent : Event + attribute @@toStringTag + getter absolute + getter alpha + getter beta + getter gamma + method constructor + method initDeviceOrientationEvent +interface Document : Node + attribute @@toStringTag + attribute @@unscopables + getter URL + getter activeElement + getter anchors + getter applets + getter body + getter characterSet + getter charset + getter childElementCount + getter children + getter compatMode + getter contentType + getter cookie + getter currentScript + getter defaultView + getter designMode + getter dir + getter doctype + getter documentElement + getter documentURI + getter domain + getter embeds + getter firstElementChild + getter fonts + getter forms + getter head + getter hidden + getter images + getter implementation + getter inputEncoding + getter lastElementChild + getter lastModified + getter links + getter onabort + getter onauxclick + getter onbeforecopy + getter onbeforecut + getter onbeforepaste + getter onblur + getter oncancel + getter oncanplay + getter oncanplaythrough + getter onchange + getter onclick + getter onclose + getter oncontextmenu + getter oncopy + getter oncuechange + getter oncut + getter ondblclick + getter ondrag + getter ondragend + getter ondragenter + getter ondragleave + getter ondragover + getter ondragstart + getter ondrop + getter ondurationchange + getter onemptied + getter onended + getter onerror + getter onfocus + getter ongotpointercapture + getter oninput + getter oninvalid + getter onkeydown + getter onkeypress + getter onkeyup + getter onload + getter onloadeddata + getter onloadedmetadata + getter onloadstart + getter onlostpointercapture + getter onmousedown + getter onmouseenter + getter onmouseleave + getter onmousemove + getter onmouseout + getter onmouseover + getter onmouseup + getter onmousewheel + getter onpaste + getter onpause + getter onplay + getter onplaying + getter onpointercancel + getter onpointerdown + getter onpointerenter + getter onpointerleave + getter onpointerlockchange + getter onpointerlockerror + getter onpointermove + getter onpointerout + getter onpointerover + getter onpointerup + getter onprogress + getter onratechange + getter onreadystatechange + getter onreset + getter onresize + getter onscroll + getter onsearch + getter onseeked + getter onseeking + getter onselect + getter onselectionchange + getter onselectstart + getter onshow + getter onstalled + getter onsubmit + getter onsuspend + getter ontimeupdate + getter ontoggle + getter ontouchcancel + getter ontouchend + getter ontouchmove + getter ontouchstart + getter onvolumechange + getter onwaiting + getter onwebkitfullscreenchange + getter onwebkitfullscreenerror + getter onwheel + getter origin + getter plugins + getter pointerLockElement + getter preferredStylesheetSet + getter readyState + getter referrer + getter rootElement + getter scripts + getter scrollingElement + getter selectedStylesheetSet + getter styleSheets + getter title + getter visibilityState + getter webkitCurrentFullScreenElement + getter webkitFullscreenElement + getter webkitFullscreenEnabled + getter webkitHidden + getter webkitIsFullScreen + getter webkitVisibilityState + getter xmlEncoding + getter xmlStandalone + getter xmlVersion + method adoptNode + method append + method caretRangeFromPoint + method close + method constructor + method createAttribute + method createAttributeNS + method createCDATASection + method createComment + method createDocumentFragment + method createElement + method createElementNS + method createEvent + method createExpression + method createNSResolver + method createNodeIterator + method createProcessingInstruction + method createRange + method createTextNode + method createTouch + method createTouchList + method createTreeWalker + method elementFromPoint + method elementsFromPoint + method evaluate + method execCommand + method exitPointerLock + method getElementById + method getElementsByClassName + method getElementsByName + method getElementsByTagName + method getElementsByTagNameNS + method getSelection + method hasFocus + method importNode + method open + method prepend + method queryCommandEnabled + method queryCommandIndeterm + method queryCommandState + method queryCommandSupported + method queryCommandValue + method querySelector + method querySelectorAll + method registerElement + method webkitCancelFullScreen + method webkitExitFullscreen + method write + method writeln + setter body + setter cookie + setter designMode + setter dir + setter domain + setter onabort + setter onauxclick + setter onbeforecopy + setter onbeforecut + setter onbeforepaste + setter onblur + setter oncancel + setter oncanplay + setter oncanplaythrough + setter onchange + setter onclick + setter onclose + setter oncontextmenu + setter oncopy + setter oncuechange + setter oncut + setter ondblclick + setter ondrag + setter ondragend + setter ondragenter + setter ondragleave + setter ondragover + setter ondragstart + setter ondrop + setter ondurationchange + setter onemptied + setter onended + setter onerror + setter onfocus + setter ongotpointercapture + setter oninput + setter oninvalid + setter onkeydown + setter onkeypress + setter onkeyup + setter onload + setter onloadeddata + setter onloadedmetadata + setter onloadstart + setter onlostpointercapture + setter onmousedown + setter onmouseenter + setter onmouseleave + setter onmousemove + setter onmouseout + setter onmouseover + setter onmouseup + setter onmousewheel + setter onpaste + setter onpause + setter onplay + setter onplaying + setter onpointercancel + setter onpointerdown + setter onpointerenter + setter onpointerleave + setter onpointerlockchange + setter onpointerlockerror + setter onpointermove + setter onpointerout + setter onpointerover + setter onpointerup + setter onprogress + setter onratechange + setter onreadystatechange + setter onreset + setter onresize + setter onscroll + setter onsearch + setter onseeked + setter onseeking + setter onselect + setter onselectionchange + setter onselectstart + setter onshow + setter onstalled + setter onsubmit + setter onsuspend + setter ontimeupdate + setter ontoggle + setter ontouchcancel + setter ontouchend + setter ontouchmove + setter ontouchstart + setter onvolumechange + setter onwaiting + setter onwebkitfullscreenchange + setter onwebkitfullscreenerror + setter onwheel + setter selectedStylesheetSet + setter title + setter xmlStandalone + setter xmlVersion +interface DocumentFragment : Node + attribute @@toStringTag + attribute @@unscopables + getter childElementCount + getter children + getter firstElementChild + getter lastElementChild + method append + method constructor + method getElementById + method prepend + method querySelector + method querySelectorAll +interface DocumentType : Node + attribute @@toStringTag + attribute @@unscopables + getter name + getter publicId + getter systemId + method after + method before + method constructor + method remove + method replaceWith +interface DragEvent : MouseEvent + attribute @@toStringTag + getter dataTransfer + method constructor +interface DynamicsCompressorNode : AudioNode + attribute @@toStringTag + getter attack + getter knee + getter ratio + getter reduction + getter release + getter threshold + method constructor +interface Element : Node + attribute @@toStringTag + attribute @@unscopables + getter assignedSlot + getter attributes + getter childElementCount + getter children + getter classList + getter className + getter clientHeight + getter clientLeft + getter clientTop + getter clientWidth + getter firstElementChild + getter id + getter innerHTML + getter lastElementChild + getter localName + getter namespaceURI + getter nextElementSibling + getter onbeforecopy + getter onbeforecut + getter onbeforepaste + getter oncopy + getter oncut + getter onpaste + getter onsearch + getter onselectstart + getter onwebkitfullscreenchange + getter onwebkitfullscreenerror + getter onwheel + getter outerHTML + getter prefix + getter previousElementSibling + getter scrollHeight + getter scrollLeft + getter scrollTop + getter scrollWidth + getter shadowRoot + getter slot + getter tagName + method after + method animate + method append + method attachShadow + method before + method closest + method constructor + method createShadowRoot + method getAttribute + method getAttributeNS + method getAttributeNode + method getAttributeNodeNS + method getBoundingClientRect + method getClientRects + method getDestinationInsertionPoints + method getElementsByClassName + method getElementsByTagName + method getElementsByTagNameNS + method hasAttribute + method hasAttributeNS + method hasAttributes + method hasPointerCapture + method insertAdjacentElement + method insertAdjacentHTML + method insertAdjacentText + method matches + method prepend + method querySelector + method querySelectorAll + method releasePointerCapture + method remove + method removeAttribute + method removeAttributeNS + method removeAttributeNode + method replaceWith + method requestPointerLock + method scrollIntoView + method scrollIntoViewIfNeeded + method setAttribute + method setAttributeNS + method setAttributeNode + method setAttributeNodeNS + method setPointerCapture + method webkitMatchesSelector + method webkitRequestFullScreen + method webkitRequestFullscreen + setter classList + setter className + setter id + setter innerHTML + setter onbeforecopy + setter onbeforecut + setter onbeforepaste + setter oncopy + setter oncut + setter onpaste + setter onsearch + setter onselectstart + setter onwebkitfullscreenchange + setter onwebkitfullscreenerror + setter onwheel + setter outerHTML + setter scrollLeft + setter scrollTop + setter slot +interface ErrorEvent : Event + attribute @@toStringTag + getter colno + getter error + getter filename + getter lineno + getter message + method constructor +interface Event + attribute @@toStringTag + attribute AT_TARGET + attribute BUBBLING_PHASE + attribute CAPTURING_PHASE + attribute NONE + getter bubbles + getter cancelBubble + getter cancelable + getter composed + getter currentTarget + getter defaultPrevented + getter eventPhase + getter path + getter returnValue + getter srcElement + getter target + getter timeStamp + getter type + method composedPath + method constructor + method initEvent + method preventDefault + method stopImmediatePropagation + method stopPropagation + setter cancelBubble + setter returnValue +interface EventSource : EventTarget + attribute @@toStringTag + attribute CLOSED + attribute CONNECTING + attribute OPEN + getter onerror + getter onmessage + getter onopen + getter readyState + getter url + getter withCredentials + method close + method constructor + setter onerror + setter onmessage + setter onopen +interface EventTarget + attribute @@toStringTag + method addEventListener + method constructor + method dispatchEvent + method removeEventListener +interface FederatedCredential : SiteBoundCredential + attribute @@toStringTag + getter protocol + getter provider + method constructor +interface File : Blob + attribute @@toStringTag + getter lastModified + getter lastModifiedDate + getter name + getter webkitRelativePath + method constructor +interface FileList + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item +interface FileReader : EventTarget + attribute @@toStringTag + attribute DONE + attribute EMPTY + attribute LOADING + getter error + getter onabort + getter onerror + getter onload + getter onloadend + getter onloadstart + getter onprogress + getter readyState + getter result + method abort + method constructor + method readAsArrayBuffer + method readAsBinaryString + method readAsDataURL + method readAsText + setter onabort + setter onerror + setter onload + setter onloadend + setter onloadstart + setter onprogress +interface FocusEvent : UIEvent + attribute @@toStringTag + getter relatedTarget + method constructor +interface FontFace + attribute @@toStringTag + getter family + getter featureSettings + getter loaded + getter status + getter stretch + getter style + getter unicodeRange + getter variant + getter weight + method constructor + method load + setter family + setter featureSettings + setter stretch + setter style + setter unicodeRange + setter variant + setter weight +interface FormData + attribute @@toStringTag + method @@iterator + method append + method constructor + method delete + method entries + method forEach + method get + method getAll + method has + method keys + method set + method values +interface GainNode : AudioNode + attribute @@toStringTag + getter gain + method constructor +interface Gamepad + attribute @@toStringTag + getter axes + getter buttons + getter connected + getter id + getter index + getter mapping + getter timestamp + method constructor +interface GamepadButton + attribute @@toStringTag + getter pressed + getter value + method constructor +interface GamepadEvent : Event + attribute @@toStringTag + getter gamepad + method constructor +interface HTMLAllCollection + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item + method namedItem +interface HTMLAnchorElement : HTMLElement + attribute @@toStringTag + getter charset + getter coords + getter download + getter hash + getter host + getter hostname + getter href + getter hreflang + getter name + getter origin + getter password + getter pathname + getter ping + getter port + getter protocol + getter referrerPolicy + getter rel + getter rev + getter search + getter shape + getter target + getter text + getter type + getter username + method constructor + method toString + setter charset + setter coords + setter download + setter hash + setter host + setter hostname + setter href + setter hreflang + setter name + setter password + setter pathname + setter ping + setter port + setter protocol + setter referrerPolicy + setter rel + setter rev + setter search + setter shape + setter target + setter text + setter type + setter username +interface HTMLAreaElement : HTMLElement + attribute @@toStringTag + getter alt + getter coords + getter download + getter hash + getter host + getter hostname + getter href + getter noHref + getter origin + getter password + getter pathname + getter ping + getter port + getter protocol + getter referrerPolicy + getter rel + getter search + getter shape + getter target + getter username + method constructor + method toString + setter alt + setter coords + setter download + setter hash + setter host + setter hostname + setter href + setter noHref + setter password + setter pathname + setter ping + setter port + setter protocol + setter referrerPolicy + setter rel + setter search + setter shape + setter target + setter username +interface HTMLAudioElement : HTMLMediaElement + attribute @@toStringTag + method constructor +interface HTMLBRElement : HTMLElement + attribute @@toStringTag + getter clear + method constructor + setter clear +interface HTMLBaseElement : HTMLElement + attribute @@toStringTag + getter href + getter target + method constructor + setter href + setter target +interface HTMLBodyElement : HTMLElement + attribute @@toStringTag + getter aLink + getter background + getter bgColor + getter link + getter onbeforeunload + getter onblur + getter onerror + getter onfocus + getter onhashchange + getter onlanguagechange + getter onload + getter onmessage + getter onoffline + getter ononline + getter onpagehide + getter onpageshow + getter onpopstate + getter onrejectionhandled + getter onresize + getter onscroll + getter onstorage + getter onunhandledrejection + getter onunload + getter text + getter vLink + method constructor + setter aLink + setter background + setter bgColor + setter link + setter onbeforeunload + setter onblur + setter onerror + setter onfocus + setter onhashchange + setter onlanguagechange + setter onload + setter onmessage + setter onoffline + setter ononline + setter onpagehide + setter onpageshow + setter onpopstate + setter onrejectionhandled + setter onresize + setter onscroll + setter onstorage + setter onunhandledrejection + setter onunload + setter text + setter vLink +interface HTMLButtonElement : HTMLElement + attribute @@toStringTag + getter autofocus + getter disabled + getter form + getter formAction + getter formEnctype + getter formMethod + getter formNoValidate + getter formTarget + getter labels + getter name + getter type + getter validationMessage + getter validity + getter value + getter willValidate + method checkValidity + method constructor + method reportValidity + method setCustomValidity + setter autofocus + setter disabled + setter formAction + setter formEnctype + setter formMethod + setter formNoValidate + setter formTarget + setter name + setter type + setter value +interface HTMLCanvasElement : HTMLElement + attribute @@toStringTag + getter height + getter width + method captureStream + method constructor + method getContext + method toBlob + method toDataURL + setter height + setter width +interface HTMLCollection + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item + method namedItem +interface HTMLContentElement : HTMLElement + attribute @@toStringTag + getter select + method constructor + method getDistributedNodes + setter select +interface HTMLDListElement : HTMLElement + attribute @@toStringTag + getter compact + method constructor + setter compact +interface HTMLDataListElement : HTMLElement + attribute @@toStringTag + getter options + method constructor +interface HTMLDetailsElement : HTMLElement + attribute @@toStringTag + getter open + method constructor + setter open +interface HTMLDialogElement : HTMLElement + attribute @@toStringTag + getter open + getter returnValue + method close + method constructor + method show + method showModal + setter open + setter returnValue +interface HTMLDirectoryElement : HTMLElement + attribute @@toStringTag + getter compact + method constructor + setter compact +interface HTMLDivElement : HTMLElement + attribute @@toStringTag + getter align + method constructor + setter align +interface HTMLDocument : Document + attribute @@toStringTag + getter alinkColor + getter all + getter bgColor + getter fgColor + getter linkColor + getter vlinkColor + method captureEvents + method clear + method constructor + method releaseEvents + setter alinkColor + setter all + setter bgColor + setter fgColor + setter linkColor + setter vlinkColor +interface HTMLElement : Element + attribute @@toStringTag + getter accessKey + getter contentEditable + getter dataset + getter dir + getter draggable + getter hidden + getter innerText + getter isContentEditable + getter lang + getter offsetHeight + getter offsetLeft + getter offsetParent + getter offsetTop + getter offsetWidth + getter onabort + getter onauxclick + getter onblur + getter oncancel + getter oncanplay + getter oncanplaythrough + getter onchange + getter onclick + getter onclose + getter oncontextmenu + getter oncuechange + getter ondblclick + getter ondrag + getter ondragend + getter ondragenter + getter ondragleave + getter ondragover + getter ondragstart + getter ondrop + getter ondurationchange + getter onemptied + getter onended + getter onerror + getter onfocus + getter ongotpointercapture + getter oninput + getter oninvalid + getter onkeydown + getter onkeypress + getter onkeyup + getter onload + getter onloadeddata + getter onloadedmetadata + getter onloadstart + getter onlostpointercapture + getter onmousedown + getter onmouseenter + getter onmouseleave + getter onmousemove + getter onmouseout + getter onmouseover + getter onmouseup + getter onmousewheel + getter onpause + getter onplay + getter onplaying + getter onpointercancel + getter onpointerdown + getter onpointerenter + getter onpointerleave + getter onpointermove + getter onpointerout + getter onpointerover + getter onpointerup + getter onprogress + getter onratechange + getter onreset + getter onresize + getter onscroll + getter onseeked + getter onseeking + getter onselect + getter onshow + getter onstalled + getter onsubmit + getter onsuspend + getter ontimeupdate + getter ontoggle + getter ontouchcancel + getter ontouchend + getter ontouchmove + getter ontouchstart + getter onvolumechange + getter onwaiting + getter outerText + getter spellcheck + getter style + getter tabIndex + getter title + getter translate + getter webkitdropzone + method blur + method click + method constructor + method focus + setter accessKey + setter contentEditable + setter dir + setter draggable + setter hidden + setter innerText + setter lang + setter onabort + setter onauxclick + setter onblur + setter oncancel + setter oncanplay + setter oncanplaythrough + setter onchange + setter onclick + setter onclose + setter oncontextmenu + setter oncuechange + setter ondblclick + setter ondrag + setter ondragend + setter ondragenter + setter ondragleave + setter ondragover + setter ondragstart + setter ondrop + setter ondurationchange + setter onemptied + setter onended + setter onerror + setter onfocus + setter ongotpointercapture + setter oninput + setter oninvalid + setter onkeydown + setter onkeypress + setter onkeyup + setter onload + setter onloadeddata + setter onloadedmetadata + setter onloadstart + setter onlostpointercapture + setter onmousedown + setter onmouseenter + setter onmouseleave + setter onmousemove + setter onmouseout + setter onmouseover + setter onmouseup + setter onmousewheel + setter onpause + setter onplay + setter onplaying + setter onpointercancel + setter onpointerdown + setter onpointerenter + setter onpointerleave + setter onpointermove + setter onpointerout + setter onpointerover + setter onpointerup + setter onprogress + setter onratechange + setter onreset + setter onresize + setter onscroll + setter onseeked + setter onseeking + setter onselect + setter onshow + setter onstalled + setter onsubmit + setter onsuspend + setter ontimeupdate + setter ontoggle + setter ontouchcancel + setter ontouchend + setter ontouchmove + setter ontouchstart + setter onvolumechange + setter onwaiting + setter outerText + setter spellcheck + setter style + setter tabIndex + setter title + setter translate + setter webkitdropzone +interface HTMLEmbedElement : HTMLElement + attribute @@toStringTag + getter align + getter height + getter name + getter src + getter type + getter width + method constructor + method getSVGDocument + setter align + setter height + setter name + setter src + setter type + setter width +interface HTMLFieldSetElement : HTMLElement + attribute @@toStringTag + getter disabled + getter elements + getter form + getter name + getter type + getter validationMessage + getter validity + getter willValidate + method checkValidity + method constructor + method reportValidity + method setCustomValidity + setter disabled + setter name +interface HTMLFontElement : HTMLElement + attribute @@toStringTag + getter color + getter face + getter size + method constructor + setter color + setter face + setter size +interface HTMLFormControlsCollection : HTMLCollection + attribute @@toStringTag + method constructor + method namedItem +interface HTMLFormElement : HTMLElement + attribute @@toStringTag + getter acceptCharset + getter action + getter autocomplete + getter elements + getter encoding + getter enctype + getter length + getter method + getter name + getter noValidate + getter target + method @@iterator + method checkValidity + method constructor + method reportValidity + method reset + method submit + setter acceptCharset + setter action + setter autocomplete + setter encoding + setter enctype + setter method + setter name + setter noValidate + setter target +interface HTMLFrameElement : HTMLElement + attribute @@toStringTag + getter contentDocument + getter contentWindow + getter frameBorder + getter longDesc + getter marginHeight + getter marginWidth + getter name + getter noResize + getter scrolling + getter src + method constructor + setter frameBorder + setter longDesc + setter marginHeight + setter marginWidth + setter name + setter noResize + setter scrolling + setter src +interface HTMLFrameSetElement : HTMLElement + attribute @@toStringTag + getter cols + getter onbeforeunload + getter onblur + getter onerror + getter onfocus + getter onhashchange + getter onlanguagechange + getter onload + getter onmessage + getter onoffline + getter ononline + getter onpagehide + getter onpageshow + getter onpopstate + getter onrejectionhandled + getter onresize + getter onscroll + getter onstorage + getter onunhandledrejection + getter onunload + getter rows + method constructor + setter cols + setter onbeforeunload + setter onblur + setter onerror + setter onfocus + setter onhashchange + setter onlanguagechange + setter onload + setter onmessage + setter onoffline + setter ononline + setter onpagehide + setter onpageshow + setter onpopstate + setter onrejectionhandled + setter onresize + setter onscroll + setter onstorage + setter onunhandledrejection + setter onunload + setter rows +interface HTMLHRElement : HTMLElement + attribute @@toStringTag + getter align + getter color + getter noShade + getter size + getter width + method constructor + setter align + setter color + setter noShade + setter size + setter width +interface HTMLHeadElement : HTMLElement + attribute @@toStringTag + method constructor +interface HTMLHeadingElement : HTMLElement + attribute @@toStringTag + getter align + method constructor + setter align +interface HTMLHtmlElement : HTMLElement + attribute @@toStringTag + getter version + method constructor + setter version +interface HTMLIFrameElement : HTMLElement + attribute @@toStringTag + getter align + getter allowFullscreen + getter contentDocument + getter contentWindow + getter frameBorder + getter height + getter longDesc + getter marginHeight + getter marginWidth + getter name + getter referrerPolicy + getter sandbox + getter scrolling + getter src + getter srcdoc + getter width + method constructor + method getSVGDocument + setter align + setter allowFullscreen + setter frameBorder + setter height + setter longDesc + setter marginHeight + setter marginWidth + setter name + setter referrerPolicy + setter sandbox + setter scrolling + setter src + setter srcdoc + setter width +interface HTMLImageElement : HTMLElement + attribute @@toStringTag + getter align + getter alt + getter border + getter complete + getter crossOrigin + getter currentSrc + getter height + getter hspace + getter isMap + getter longDesc + getter lowsrc + getter name + getter naturalHeight + getter naturalWidth + getter referrerPolicy + getter sizes + getter src + getter srcset + getter useMap + getter vspace + getter width + getter x + getter y + method constructor + setter align + setter alt + setter border + setter crossOrigin + setter height + setter hspace + setter isMap + setter longDesc + setter lowsrc + setter name + setter referrerPolicy + setter sizes + setter src + setter srcset + setter useMap + setter vspace + setter width +interface HTMLInputElement : HTMLElement + attribute @@toStringTag + getter accept + getter align + getter alt + getter autocapitalize + getter autocomplete + getter autofocus + getter checked + getter defaultChecked + getter defaultValue + getter dirName + getter disabled + getter files + getter form + getter formAction + getter formEnctype + getter formMethod + getter formNoValidate + getter formTarget + getter height + getter incremental + getter indeterminate + getter labels + getter list + getter max + getter maxLength + getter min + getter minLength + getter multiple + getter name + getter pattern + getter placeholder + getter readOnly + getter required + getter selectionDirection + getter selectionEnd + getter selectionStart + getter size + getter src + getter step + getter type + getter useMap + getter validationMessage + getter validity + getter value + getter valueAsDate + getter valueAsNumber + getter webkitEntries + getter webkitdirectory + getter width + getter willValidate + method checkValidity + method constructor + method reportValidity + method select + method setCustomValidity + method setRangeText + method setSelectionRange + method stepDown + method stepUp + setter accept + setter align + setter alt + setter autocapitalize + setter autocomplete + setter autofocus + setter checked + setter defaultChecked + setter defaultValue + setter dirName + setter disabled + setter files + setter formAction + setter formEnctype + setter formMethod + setter formNoValidate + setter formTarget + setter height + setter incremental + setter indeterminate + setter max + setter maxLength + setter min + setter minLength + setter multiple + setter name + setter pattern + setter placeholder + setter readOnly + setter required + setter selectionDirection + setter selectionEnd + setter selectionStart + setter size + setter src + setter step + setter type + setter useMap + setter value + setter valueAsDate + setter valueAsNumber + setter webkitdirectory + setter width +interface HTMLLIElement : HTMLElement + attribute @@toStringTag + getter type + getter value + method constructor + setter type + setter value +interface HTMLLabelElement : HTMLElement + attribute @@toStringTag + getter control + getter form + getter htmlFor + method constructor + setter htmlFor +interface HTMLLegendElement : HTMLElement + attribute @@toStringTag + getter align + getter form + method constructor + setter align +interface HTMLLinkElement : HTMLElement + attribute @@toStringTag + getter as + getter charset + getter crossOrigin + getter disabled + getter href + getter hreflang + getter import + getter integrity + getter media + getter rel + getter relList + getter rev + getter sheet + getter sizes + getter target + getter type + method constructor + setter as + setter charset + setter crossOrigin + setter disabled + setter href + setter hreflang + setter integrity + setter media + setter rel + setter relList + setter rev + setter sizes + setter target + setter type +interface HTMLMapElement : HTMLElement + attribute @@toStringTag + getter areas + getter name + method constructor + setter name +interface HTMLMarqueeElement : HTMLElement + attribute @@toStringTag + getter behavior + getter bgColor + getter direction + getter height + getter hspace + getter loop + getter scrollAmount + getter scrollDelay + getter trueSpeed + getter vspace + getter width + method constructor + method start + method stop + setter behavior + setter bgColor + setter direction + setter height + setter hspace + setter loop + setter scrollAmount + setter scrollDelay + setter trueSpeed + setter vspace + setter width +interface HTMLMediaElement : HTMLElement + attribute @@toStringTag + attribute HAVE_CURRENT_DATA + attribute HAVE_ENOUGH_DATA + attribute HAVE_FUTURE_DATA + attribute HAVE_METADATA + attribute HAVE_NOTHING + attribute NETWORK_EMPTY + attribute NETWORK_IDLE + attribute NETWORK_LOADING + attribute NETWORK_NO_SOURCE + getter autoplay + getter buffered + getter controls + getter crossOrigin + getter currentSrc + getter currentTime + getter defaultMuted + getter defaultPlaybackRate + getter disableRemotePlayback + getter duration + getter ended + getter error + getter loop + getter mediaKeys + getter muted + getter networkState + getter onencrypted + getter onwaitingforkey + getter paused + getter playbackRate + getter played + getter preload + getter readyState + getter remote + getter seekable + getter seeking + getter sinkId + getter src + getter srcObject + getter textTracks + getter volume + getter webkitAudioDecodedByteCount + getter webkitVideoDecodedByteCount + method addTextTrack + method canPlayType + method constructor + method load + method pause + method play + method setMediaKeys + method setSinkId + setter autoplay + setter controls + setter crossOrigin + setter currentTime + setter defaultMuted + setter defaultPlaybackRate + setter disableRemotePlayback + setter loop + setter muted + setter onencrypted + setter onwaitingforkey + setter playbackRate + setter preload + setter src + setter srcObject + setter volume +interface HTMLMenuElement : HTMLElement + attribute @@toStringTag + getter compact + method constructor + setter compact +interface HTMLMetaElement : HTMLElement + attribute @@toStringTag + getter content + getter httpEquiv + getter name + getter scheme + method constructor + setter content + setter httpEquiv + setter name + setter scheme +interface HTMLMeterElement : HTMLElement + attribute @@toStringTag + getter high + getter labels + getter low + getter max + getter min + getter optimum + getter value + method constructor + setter high + setter low + setter max + setter min + setter optimum + setter value +interface HTMLModElement : HTMLElement + attribute @@toStringTag + getter cite + getter dateTime + method constructor + setter cite + setter dateTime +interface HTMLOListElement : HTMLElement + attribute @@toStringTag + getter compact + getter reversed + getter start + getter type + method constructor + setter compact + setter reversed + setter start + setter type +interface HTMLObjectElement : HTMLElement + attribute @@toStringTag + getter align + getter archive + getter border + getter code + getter codeBase + getter codeType + getter contentDocument + getter contentWindow + getter data + getter declare + getter form + getter height + getter hspace + getter name + getter standby + getter type + getter useMap + getter validationMessage + getter validity + getter vspace + getter width + getter willValidate + method checkValidity + method constructor + method getSVGDocument + method reportValidity + method setCustomValidity + setter align + setter archive + setter border + setter code + setter codeBase + setter codeType + setter data + setter declare + setter height + setter hspace + setter name + setter standby + setter type + setter useMap + setter vspace + setter width +interface HTMLOptGroupElement : HTMLElement + attribute @@toStringTag + getter disabled + getter label + method constructor + setter disabled + setter label +interface HTMLOptionElement : HTMLElement + attribute @@toStringTag + getter defaultSelected + getter disabled + getter form + getter index + getter label + getter selected + getter text + getter value + method constructor + setter defaultSelected + setter disabled + setter label + setter selected + setter text + setter value +interface HTMLOptionsCollection : HTMLCollection + attribute @@toStringTag + getter length + getter selectedIndex + method @@iterator + method add + method constructor + method namedItem + method remove + setter length + setter selectedIndex +interface HTMLOutputElement : HTMLElement + attribute @@toStringTag + getter defaultValue + getter form + getter htmlFor + getter labels + getter name + getter type + getter validationMessage + getter validity + getter value + getter willValidate + method checkValidity + method constructor + method reportValidity + method setCustomValidity + setter defaultValue + setter htmlFor + setter name + setter value +interface HTMLParagraphElement : HTMLElement + attribute @@toStringTag + getter align + method constructor + setter align +interface HTMLParamElement : HTMLElement + attribute @@toStringTag + getter name + getter type + getter value + getter valueType + method constructor + setter name + setter type + setter value + setter valueType +interface HTMLPictureElement : HTMLElement + attribute @@toStringTag + method constructor +interface HTMLPreElement : HTMLElement + attribute @@toStringTag + getter width + method constructor + setter width +interface HTMLProgressElement : HTMLElement + attribute @@toStringTag + getter labels + getter max + getter position + getter value + method constructor + setter max + setter value +interface HTMLQuoteElement : HTMLElement + attribute @@toStringTag + getter cite + method constructor + setter cite +interface HTMLScriptElement : HTMLElement + attribute @@toStringTag + getter async + getter charset + getter crossOrigin + getter defer + getter event + getter htmlFor + getter integrity + getter src + getter text + getter type + method constructor + setter async + setter charset + setter crossOrigin + setter defer + setter event + setter htmlFor + setter integrity + setter src + setter text + setter type +interface HTMLSelectElement : HTMLElement + attribute @@toStringTag + getter autofocus + getter disabled + getter form + getter labels + getter length + getter multiple + getter name + getter options + getter required + getter selectedIndex + getter selectedOptions + getter size + getter type + getter validationMessage + getter validity + getter value + getter willValidate + method @@iterator + method add + method checkValidity + method constructor + method item + method namedItem + method remove + method reportValidity + method setCustomValidity + setter autofocus + setter disabled + setter length + setter multiple + setter name + setter required + setter selectedIndex + setter size + setter value +interface HTMLShadowElement : HTMLElement + attribute @@toStringTag + method constructor + method getDistributedNodes +interface HTMLSlotElement : HTMLElement + attribute @@toStringTag + getter name + method assignedNodes + method constructor + setter name +interface HTMLSourceElement : HTMLElement + attribute @@toStringTag + getter media + getter sizes + getter src + getter srcset + getter type + method constructor + setter media + setter sizes + setter src + setter srcset + setter type +interface HTMLSpanElement : HTMLElement + attribute @@toStringTag + method constructor +interface HTMLStyleElement : HTMLElement + attribute @@toStringTag + getter disabled + getter media + getter sheet + getter type + method constructor + setter disabled + setter media + setter type +interface HTMLTableCaptionElement : HTMLElement + attribute @@toStringTag + getter align + method constructor + setter align +interface HTMLTableCellElement : HTMLElement + attribute @@toStringTag + getter abbr + getter align + getter axis + getter bgColor + getter cellIndex + getter ch + getter chOff + getter colSpan + getter headers + getter height + getter noWrap + getter rowSpan + getter scope + getter vAlign + getter width + method constructor + setter abbr + setter align + setter axis + setter bgColor + setter ch + setter chOff + setter colSpan + setter headers + setter height + setter noWrap + setter rowSpan + setter scope + setter vAlign + setter width +interface HTMLTableColElement : HTMLElement + attribute @@toStringTag + getter align + getter ch + getter chOff + getter span + getter vAlign + getter width + method constructor + setter align + setter ch + setter chOff + setter span + setter vAlign + setter width +interface HTMLTableElement : HTMLElement + attribute @@toStringTag + getter align + getter bgColor + getter border + getter caption + getter cellPadding + getter cellSpacing + getter frame + getter rows + getter rules + getter summary + getter tBodies + getter tFoot + getter tHead + getter width + method constructor + method createCaption + method createTBody + method createTFoot + method createTHead + method deleteCaption + method deleteRow + method deleteTFoot + method deleteTHead + method insertRow + setter align + setter bgColor + setter border + setter caption + setter cellPadding + setter cellSpacing + setter frame + setter rules + setter summary + setter tFoot + setter tHead + setter width +interface HTMLTableRowElement : HTMLElement + attribute @@toStringTag + getter align + getter bgColor + getter cells + getter ch + getter chOff + getter rowIndex + getter sectionRowIndex + getter vAlign + method constructor + method deleteCell + method insertCell + setter align + setter bgColor + setter ch + setter chOff + setter vAlign +interface HTMLTableSectionElement : HTMLElement + attribute @@toStringTag + getter align + getter ch + getter chOff + getter rows + getter vAlign + method constructor + method deleteRow + method insertRow + setter align + setter ch + setter chOff + setter vAlign +interface HTMLTemplateElement : HTMLElement + attribute @@toStringTag + getter content + method constructor +interface HTMLTextAreaElement : HTMLElement + attribute @@toStringTag + getter autocapitalize + getter autofocus + getter cols + getter defaultValue + getter dirName + getter disabled + getter form + getter labels + getter maxLength + getter minLength + getter name + getter placeholder + getter readOnly + getter required + getter rows + getter selectionDirection + getter selectionEnd + getter selectionStart + getter textLength + getter type + getter validationMessage + getter validity + getter value + getter willValidate + getter wrap + method checkValidity + method constructor + method reportValidity + method select + method setCustomValidity + method setRangeText + method setSelectionRange + setter autocapitalize + setter autofocus + setter cols + setter defaultValue + setter dirName + setter disabled + setter maxLength + setter minLength + setter name + setter placeholder + setter readOnly + setter required + setter rows + setter selectionDirection + setter selectionEnd + setter selectionStart + setter value + setter wrap +interface HTMLTitleElement : HTMLElement + attribute @@toStringTag + getter text + method constructor + setter text +interface HTMLTrackElement : HTMLElement + attribute @@toStringTag + attribute ERROR + attribute LOADED + attribute LOADING + attribute NONE + getter default + getter kind + getter label + getter readyState + getter src + getter srclang + getter track + method constructor + setter default + setter kind + setter label + setter src + setter srclang +interface HTMLUListElement : HTMLElement + attribute @@toStringTag + getter compact + getter type + method constructor + setter compact + setter type +interface HTMLUnknownElement : HTMLElement + attribute @@toStringTag + method constructor +interface HTMLVideoElement : HTMLMediaElement + attribute @@toStringTag + getter height + getter poster + getter videoHeight + getter videoWidth + getter webkitDecodedFrameCount + getter webkitDisplayingFullscreen + getter webkitDroppedFrameCount + getter webkitSupportsFullscreen + getter width + method constructor + method webkitEnterFullScreen + method webkitEnterFullscreen + method webkitExitFullScreen + method webkitExitFullscreen + setter height + setter poster + setter width +interface HashChangeEvent : Event + attribute @@toStringTag + getter newURL + getter oldURL + method constructor +interface Headers + attribute @@toStringTag + method @@iterator + method append + method constructor + method delete + method entries + method forEach + method get + method getAll + method has + method keys + method set + method values +interface History + attribute @@toStringTag + getter length + getter scrollRestoration + getter state + method back + method constructor + method forward + method go + method pushState + method replaceState + setter scrollRestoration +interface IDBCursor + attribute @@toStringTag + getter direction + getter key + getter primaryKey + getter source + method advance + method constructor + method continue + method delete + method update +interface IDBCursorWithValue : IDBCursor + attribute @@toStringTag + getter value + method constructor +interface IDBDatabase : EventTarget + attribute @@toStringTag + getter name + getter objectStoreNames + getter onabort + getter onclose + getter onerror + getter onversionchange + getter version + method close + method constructor + method createObjectStore + method deleteObjectStore + method transaction + setter onabort + setter onclose + setter onerror + setter onversionchange +interface IDBFactory + attribute @@toStringTag + method cmp + method constructor + method deleteDatabase + method open + method webkitGetDatabaseNames +interface IDBIndex + attribute @@toStringTag + getter keyPath + getter multiEntry + getter name + getter objectStore + getter unique + method constructor + method count + method get + method getAll + method getAllKeys + method getKey + method openCursor + method openKeyCursor + setter name +interface IDBKeyRange + static method bound + static method lowerBound + static method only + static method upperBound + attribute @@toStringTag + getter lower + getter lowerOpen + getter upper + getter upperOpen + method constructor + method includes +interface IDBObjectStore + attribute @@toStringTag + getter autoIncrement + getter indexNames + getter keyPath + getter name + getter transaction + method add + method clear + method constructor + method count + method createIndex + method delete + method deleteIndex + method get + method getAll + method getAllKeys + method index + method openCursor + method openKeyCursor + method put + setter name +interface IDBOpenDBRequest : IDBRequest + attribute @@toStringTag + getter onblocked + getter onupgradeneeded + method constructor + setter onblocked + setter onupgradeneeded +interface IDBRequest : EventTarget + attribute @@toStringTag + getter error + getter onerror + getter onsuccess + getter readyState + getter result + getter source + getter transaction + method constructor + setter onerror + setter onsuccess +interface IDBTransaction : EventTarget + attribute @@toStringTag + getter db + getter error + getter mode + getter objectStoreNames + getter onabort + getter oncomplete + getter onerror + method abort + method constructor + method objectStore + setter onabort + setter oncomplete + setter onerror +interface IDBVersionChangeEvent : Event + attribute @@toStringTag + getter dataLoss + getter dataLossMessage + getter newVersion + getter oldVersion + method constructor +interface IIRFilterNode : AudioNode + attribute @@toStringTag + method constructor + method getFrequencyResponse +interface IdleDeadline + attribute @@toStringTag + getter didTimeout + method constructor + method timeRemaining +interface Image + method constructor +interface ImageBitmap + attribute @@toStringTag + getter height + getter width + method close + method constructor +interface ImageBitmapRenderingContext + attribute @@toStringTag + getter canvas + method constructor + method transferFromImageBitmap +interface ImageData + attribute @@toStringTag + getter height + getter width + method constructor +interface InputDeviceCapabilities + attribute @@toStringTag + getter firesTouchEvents + method constructor +interface IntersectionObserver + attribute @@toStringTag + getter root + getter rootMargin + getter thresholds + method constructor + method disconnect + method observe + method takeRecords + method unobserve +interface IntersectionObserverEntry + attribute @@toStringTag + getter boundingClientRect + getter intersectionRatio + getter intersectionRect + getter rootBounds + getter target + getter time + method constructor +interface KeyboardEvent : UIEvent + attribute @@toStringTag + attribute DOM_KEY_LOCATION_LEFT + attribute DOM_KEY_LOCATION_NUMPAD + attribute DOM_KEY_LOCATION_RIGHT + attribute DOM_KEY_LOCATION_STANDARD + getter altKey + getter charCode + getter code + getter ctrlKey + getter isComposing + getter key + getter keyCode + getter location + getter metaKey + getter repeat + getter shiftKey + getter which + method constructor + method getModifierState + method initKeyboardEvent +interface Location + attribute @@toStringTag + method constructor +interface MIDIAccess : EventTarget + attribute @@toStringTag + getter inputs + getter onstatechange + getter outputs + getter sysexEnabled + method constructor + setter onstatechange +interface MIDIConnectionEvent : Event + attribute @@toStringTag + getter port + method constructor +interface MIDIInput : MIDIPort + attribute @@toStringTag + getter onmidimessage + method constructor + setter onmidimessage +interface MIDIInputMap + attribute @@toStringTag + getter size + method @@iterator + method constructor + method entries + method forEach + method get + method has + method keys + method values +interface MIDIMessageEvent : Event + attribute @@toStringTag + getter data + method constructor +interface MIDIOutput : MIDIPort + attribute @@toStringTag + method constructor + method send +interface MIDIOutputMap + attribute @@toStringTag + getter size + method @@iterator + method constructor + method entries + method forEach + method get + method has + method keys + method values +interface MIDIPort : EventTarget + attribute @@toStringTag + getter connection + getter id + getter manufacturer + getter name + getter onstatechange + getter state + getter type + getter version + method close + method constructor + method open + setter onstatechange +interface MediaDeviceInfo + attribute @@toStringTag + getter deviceId + getter groupId + getter kind + getter label + method constructor + method toJSON +interface MediaDevices : EventTarget + attribute @@toStringTag + getter ondevicechange + method constructor + method enumerateDevices + method getSupportedConstraints + method getUserMedia + setter ondevicechange +interface MediaElementAudioSourceNode : AudioSourceNode + attribute @@toStringTag + getter mediaElement + method constructor +interface MediaEncryptedEvent : Event + attribute @@toStringTag + getter initData + getter initDataType + method constructor +interface MediaError + attribute @@toStringTag + attribute MEDIA_ERR_ABORTED + attribute MEDIA_ERR_DECODE + attribute MEDIA_ERR_NETWORK + attribute MEDIA_ERR_SRC_NOT_SUPPORTED + getter code + method constructor +interface MediaKeyMessageEvent : Event + attribute @@toStringTag + getter message + getter messageType + method constructor +interface MediaKeySession : EventTarget + attribute @@toStringTag + getter closed + getter expiration + getter keyStatuses + getter onkeystatuseschange + getter onmessage + getter sessionId + method close + method constructor + method generateRequest + method load + method remove + method update + setter onkeystatuseschange + setter onmessage +interface MediaKeyStatusMap + attribute @@toStringTag + getter size + method @@iterator + method constructor + method entries + method forEach + method get + method has + method keys + method values +interface MediaKeySystemAccess + attribute @@toStringTag + getter keySystem + method constructor + method createMediaKeys + method getConfiguration +interface MediaKeys + attribute @@toStringTag + method constructor + method createSession + method setServerCertificate +interface MediaList + attribute @@toStringTag + getter length + getter mediaText + method @@iterator + method appendMedium + method constructor + method deleteMedium + method item + setter mediaText +interface MediaQueryList : EventTarget + attribute @@toStringTag + getter matches + getter media + getter onchange + method addListener + method constructor + method removeListener + setter onchange +interface MediaQueryListEvent : Event + attribute @@toStringTag + getter matches + getter media + method constructor +interface MediaRecorder : EventTarget + static method isTypeSupported + attribute @@toStringTag + getter audioBitsPerSecond + getter ignoreMutedMedia + getter mimeType + getter ondataavailable + getter onerror + getter onpause + getter onresume + getter onstart + getter onstop + getter state + getter stream + getter videoBitsPerSecond + method constructor + method pause + method requestData + method resume + method start + method stop + setter ignoreMutedMedia + setter ondataavailable + setter onerror + setter onpause + setter onresume + setter onstart + setter onstop +interface MediaSource : EventTarget + static method isTypeSupported + attribute @@toStringTag + getter activeSourceBuffers + getter duration + getter onsourceclose + getter onsourceended + getter onsourceopen + getter readyState + getter sourceBuffers + method addSourceBuffer + method constructor + method endOfStream + method removeSourceBuffer + setter duration + setter onsourceclose + setter onsourceended + setter onsourceopen +interface MediaStream : EventTarget + attribute @@toStringTag + getter active + getter id + getter onactive + getter onaddtrack + getter oninactive + getter onremovetrack + method addTrack + method clone + method constructor + method getAudioTracks + method getTrackById + method getTracks + method getVideoTracks + method removeTrack + setter onactive + setter onaddtrack + setter oninactive + setter onremovetrack +interface MediaStreamAudioDestinationNode : AudioNode + attribute @@toStringTag + getter stream + method constructor +interface MediaStreamAudioSourceNode : AudioSourceNode + attribute @@toStringTag + getter mediaStream + method constructor +interface MediaStreamEvent : Event + attribute @@toStringTag + getter stream + method constructor +interface MediaStreamTrack : EventTarget + attribute @@toStringTag + getter enabled + getter id + getter kind + getter label + getter muted + getter onended + getter onmute + getter onunmute + getter readyState + getter remote + method clone + method constructor + method getConstraints + method stop + setter enabled + setter onended + setter onmute + setter onunmute +interface MediaStreamTrackEvent : Event + attribute @@toStringTag + getter track + method constructor +interface MessageChannel + attribute @@toStringTag + getter port1 + getter port2 + method constructor +interface MessageEvent : Event + attribute @@toStringTag + getter data + getter lastEventId + getter origin + getter ports + getter source + method constructor + method initMessageEvent +interface MessagePort : EventTarget + attribute @@toStringTag + getter onmessage + method close + method constructor + method postMessage + method start + setter onmessage +interface MimeType + attribute @@toStringTag + getter description + getter enabledPlugin + getter suffixes + getter type + method constructor +interface MimeTypeArray + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item + method namedItem +interface MouseEvent : UIEvent + attribute @@toStringTag + getter altKey + getter button + getter buttons + getter clientX + getter clientY + getter ctrlKey + getter fromElement + getter layerX + getter layerY + getter metaKey + getter movementX + getter movementY + getter offsetX + getter offsetY + getter pageX + getter pageY + getter relatedTarget + getter screenX + getter screenY + getter shiftKey + getter toElement + getter which + getter x + getter y + method constructor + method getModifierState + method initMouseEvent +interface MutationEvent : Event + attribute @@toStringTag + attribute ADDITION + attribute MODIFICATION + attribute REMOVAL + getter attrChange + getter attrName + getter newValue + getter prevValue + getter relatedNode + method constructor + method initMutationEvent +interface MutationObserver + attribute @@toStringTag + method constructor + method disconnect + method observe + method takeRecords +interface MutationRecord + attribute @@toStringTag + getter addedNodes + getter attributeName + getter attributeNamespace + getter nextSibling + getter oldValue + getter previousSibling + getter removedNodes + getter target + getter type + method constructor +interface NamedNodeMap + attribute @@toStringTag + getter length + method @@iterator + method constructor + method getNamedItem + method getNamedItemNS + method item + method removeNamedItem + method removeNamedItemNS + method setNamedItem + method setNamedItemNS +interface Navigator + attribute @@toStringTag + getter appCodeName + getter appName + getter appVersion + getter cookieEnabled + getter credentials + getter doNotTrack + getter geolocation + getter hardwareConcurrency + getter language + getter languages + getter maxTouchPoints + getter mediaDevices + getter mimeTypes + getter onLine + getter permissions + getter platform + getter plugins + getter presentation + getter product + getter productSub + getter serviceWorker + getter storage + getter userAgent + getter vendor + getter vendorSub + getter webkitPersistentStorage + getter webkitTemporaryStorage + method constructor + method getBattery + method getGamepads + method getUserMedia + method javaEnabled + method registerProtocolHandler + method requestMIDIAccess + method requestMediaKeySystemAccess + method sendBeacon + method unregisterProtocolHandler + method vibrate + method webkitGetUserMedia +interface Node : EventTarget + attribute @@toStringTag + attribute ATTRIBUTE_NODE + attribute CDATA_SECTION_NODE + attribute COMMENT_NODE + attribute DOCUMENT_FRAGMENT_NODE + attribute DOCUMENT_NODE + attribute DOCUMENT_POSITION_CONTAINED_BY + attribute DOCUMENT_POSITION_CONTAINS + attribute DOCUMENT_POSITION_DISCONNECTED + attribute DOCUMENT_POSITION_FOLLOWING + attribute DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + attribute DOCUMENT_POSITION_PRECEDING + attribute DOCUMENT_TYPE_NODE + attribute ELEMENT_NODE + attribute ENTITY_NODE + attribute ENTITY_REFERENCE_NODE + attribute NOTATION_NODE + attribute PROCESSING_INSTRUCTION_NODE + attribute TEXT_NODE + getter baseURI + getter childNodes + getter firstChild + getter isConnected + getter lastChild + getter nextSibling + getter nodeName + getter nodeType + getter nodeValue + getter ownerDocument + getter parentElement + getter parentNode + getter previousSibling + getter textContent + method appendChild + method cloneNode + method compareDocumentPosition + method constructor + method contains + method getRootNode + method hasChildNodes + method insertBefore + method isDefaultNamespace + method isEqualNode + method isSameNode + method lookupNamespaceURI + method lookupPrefix + method normalize + method removeChild + method replaceChild + setter nodeValue + setter textContent +interface NodeFilter + attribute @@toStringTag + attribute FILTER_ACCEPT + attribute FILTER_REJECT + attribute FILTER_SKIP + attribute SHOW_ALL + attribute SHOW_ATTRIBUTE + attribute SHOW_CDATA_SECTION + attribute SHOW_COMMENT + attribute SHOW_DOCUMENT + attribute SHOW_DOCUMENT_FRAGMENT + attribute SHOW_DOCUMENT_TYPE + attribute SHOW_ELEMENT + attribute SHOW_ENTITY + attribute SHOW_ENTITY_REFERENCE + attribute SHOW_NOTATION + attribute SHOW_PROCESSING_INSTRUCTION + attribute SHOW_TEXT + method acceptNode + method constructor +interface NodeIterator + attribute @@toStringTag + getter filter + getter pointerBeforeReferenceNode + getter referenceNode + getter root + getter whatToShow + method constructor + method detach + method nextNode + method previousNode +interface NodeList + attribute @@toStringTag + getter length + method @@iterator + method constructor + method entries + method forEach + method item + method keys + method values +interface Notification : EventTarget + static getter maxActions + static getter permission + static method requestPermission + attribute @@toStringTag + getter actions + getter badge + getter body + getter data + getter dir + getter icon + getter image + getter lang + getter onclick + getter onclose + getter onerror + getter onshow + getter renotify + getter requireInteraction + getter silent + getter tag + getter timestamp + getter title + getter vibrate + method close + method constructor + setter onclick + setter onclose + setter onerror + setter onshow +interface OfflineAudioCompletionEvent : Event + attribute @@toStringTag + getter renderedBuffer + method constructor +interface OfflineAudioContext : BaseAudioContext + attribute @@toStringTag + getter length + getter oncomplete + method constructor + method startRendering + method suspend + setter oncomplete +interface Option + method constructor +interface OscillatorNode : AudioScheduledSourceNode + attribute @@toStringTag + getter detune + getter frequency + getter type + method constructor + method setPeriodicWave + setter type +interface PageTransitionEvent : Event + attribute @@toStringTag + getter persisted + method constructor +interface PannerNode : AudioNode + attribute @@toStringTag + getter coneInnerAngle + getter coneOuterAngle + getter coneOuterGain + getter distanceModel + getter maxDistance + getter orientationX + getter orientationY + getter orientationZ + getter panningModel + getter positionX + getter positionY + getter positionZ + getter refDistance + getter rolloffFactor + method constructor + method setOrientation + method setPosition + setter coneInnerAngle + setter coneOuterAngle + setter coneOuterGain + setter distanceModel + setter maxDistance + setter panningModel + setter refDistance + setter rolloffFactor +interface PasswordCredential : SiteBoundCredential + attribute @@toStringTag + getter additionalData + getter idName + getter passwordName + method constructor + setter additionalData + setter idName + setter passwordName +interface Path2D + attribute @@toStringTag + method arc + method arcTo + method bezierCurveTo + method closePath + method constructor + method ellipse + method lineTo + method moveTo + method quadraticCurveTo + method rect +interface Performance : EventTarget + attribute @@toStringTag + getter memory + getter navigation + getter onresourcetimingbufferfull + getter onwebkitresourcetimingbufferfull + getter timing + method clearMarks + method clearMeasures + method clearResourceTimings + method constructor + method getEntries + method getEntriesByName + method getEntriesByType + method mark + method measure + method now + method setResourceTimingBufferSize + method toJSON + method webkitClearResourceTimings + method webkitSetResourceTimingBufferSize + setter onresourcetimingbufferfull + setter onwebkitresourcetimingbufferfull +interface PerformanceEntry + attribute @@toStringTag + getter duration + getter entryType + getter name + getter startTime + method constructor + method toJSON +interface PerformanceMark : PerformanceEntry + attribute @@toStringTag + method constructor +interface PerformanceMeasure : PerformanceEntry + attribute @@toStringTag + method constructor +interface PerformanceNavigation + attribute @@toStringTag + attribute TYPE_BACK_FORWARD + attribute TYPE_NAVIGATE + attribute TYPE_RELOAD + attribute TYPE_RESERVED + getter redirectCount + getter type + method constructor + method toJSON +interface PerformanceObserver + attribute @@toStringTag + method constructor + method disconnect + method observe +interface PerformanceObserverEntryList + attribute @@toStringTag + method constructor + method getEntries + method getEntriesByName + method getEntriesByType +interface PerformanceResourceTiming : PerformanceEntry + attribute @@toStringTag + getter connectEnd + getter connectStart + getter decodedBodySize + getter domainLookupEnd + getter domainLookupStart + getter encodedBodySize + getter fetchStart + getter initiatorType + getter redirectEnd + getter redirectStart + getter requestStart + getter responseEnd + getter responseStart + getter secureConnectionStart + getter transferSize + getter workerStart + method constructor +interface PerformanceTiming + attribute @@toStringTag + getter connectEnd + getter connectStart + getter domComplete + getter domContentLoadedEventEnd + getter domContentLoadedEventStart + getter domInteractive + getter domLoading + getter domainLookupEnd + getter domainLookupStart + getter fetchStart + getter loadEventEnd + getter loadEventStart + getter navigationStart + getter redirectEnd + getter redirectStart + getter requestStart + getter responseEnd + getter responseStart + getter secureConnectionStart + getter unloadEventEnd + getter unloadEventStart + method constructor + method toJSON +interface PeriodicWave + attribute @@toStringTag + method constructor +interface PermissionStatus : EventTarget + attribute @@toStringTag + getter onchange + getter state + method constructor + setter onchange +interface Permissions + attribute @@toStringTag + method constructor + method query +interface Plugin + attribute @@toStringTag + getter description + getter filename + getter length + getter name + method @@iterator + method constructor + method item + method namedItem +interface PluginArray + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item + method namedItem + method refresh +interface PointerEvent : MouseEvent + attribute @@toStringTag + getter height + getter isPrimary + getter pointerId + getter pointerType + getter pressure + getter tiltX + getter tiltY + getter width + method constructor +interface PopStateEvent : Event + attribute @@toStringTag + getter state + method constructor +interface Presentation + attribute @@toStringTag + getter defaultRequest + method constructor + setter defaultRequest +interface PresentationAvailability : EventTarget + attribute @@toStringTag + getter onchange + getter value + method constructor + setter onchange +interface PresentationConnection : EventTarget + attribute @@toStringTag + getter binaryType + getter id + getter onclose + getter onconnect + getter onmessage + getter onterminate + getter state + method close + method constructor + method send + method terminate + setter binaryType + setter onclose + setter onconnect + setter onmessage + setter onterminate +interface PresentationConnectionAvailableEvent : Event + attribute @@toStringTag + getter connection + method constructor +interface PresentationConnectionCloseEvent : Event + attribute @@toStringTag + getter message + getter reason + method constructor +interface PresentationRequest : EventTarget + attribute @@toStringTag + getter onconnectionavailable + method constructor + method getAvailability + method reconnect + method start + setter onconnectionavailable +interface ProcessingInstruction : CharacterData + attribute @@toStringTag + getter sheet + getter target + method constructor +interface ProgressEvent : Event + attribute @@toStringTag + getter lengthComputable + getter loaded + getter total + method constructor +interface PromiseRejectionEvent : Event + attribute @@toStringTag + getter promise + getter reason + method constructor +interface PushManager + attribute @@toStringTag + method constructor + method getSubscription + method permissionState + method subscribe +interface PushSubscription + attribute @@toStringTag + getter endpoint + getter options + method constructor + method getKey + method toJSON + method unsubscribe +interface PushSubscriptionOptions + attribute @@toStringTag + getter applicationServerKey + getter userVisibleOnly + method constructor +interface RTCCertificate + attribute @@toStringTag + getter expires + method constructor +interface RTCDataChannel : EventTarget + attribute @@toStringTag + getter binaryType + getter bufferedAmount + getter bufferedAmountLowThreshold + getter id + getter label + getter maxRetransmitTime + getter maxRetransmits + getter negotiated + getter onbufferedamountlow + getter onclose + getter onerror + getter onmessage + getter onopen + getter ordered + getter protocol + getter readyState + getter reliable + method close + method constructor + method send + setter binaryType + setter bufferedAmountLowThreshold + setter onbufferedamountlow + setter onclose + setter onerror + setter onmessage + setter onopen +interface RTCDataChannelEvent : Event + attribute @@toStringTag + getter channel + method constructor +interface RTCIceCandidate + attribute @@toStringTag + getter candidate + getter sdpMLineIndex + getter sdpMid + method constructor + method toJSON + setter candidate + setter sdpMLineIndex + setter sdpMid +interface RTCPeerConnection : EventTarget + static method generateCertificate + attribute @@toStringTag + getter iceConnectionState + getter iceGatheringState + getter localDescription + getter onaddstream + getter ondatachannel + getter onicecandidate + getter oniceconnectionstatechange + getter onnegotiationneeded + getter onremovestream + getter onsignalingstatechange + getter remoteDescription + getter signalingState + method addIceCandidate + method addStream + method close + method constructor + method createAnswer + method createDTMFSender + method createDataChannel + method createOffer + method getLocalStreams + method getRemoteStreams + method getStats + method getStreamById + method removeStream + method setLocalDescription + method setRemoteDescription + method updateIce + setter onaddstream + setter ondatachannel + setter onicecandidate + setter oniceconnectionstatechange + setter onnegotiationneeded + setter onremovestream + setter onsignalingstatechange +interface RTCPeerConnectionIceEvent : Event + attribute @@toStringTag + getter candidate + method constructor +interface RTCSessionDescription + attribute @@toStringTag + getter sdp + getter type + method constructor + method toJSON + setter sdp + setter type +interface RadioNodeList : NodeList + attribute @@toStringTag + getter value + method constructor + setter value +interface Range + attribute @@toStringTag + attribute END_TO_END + attribute END_TO_START + attribute START_TO_END + attribute START_TO_START + getter collapsed + getter commonAncestorContainer + getter endContainer + getter endOffset + getter startContainer + getter startOffset + method cloneContents + method cloneRange + method collapse + method compareBoundaryPoints + method comparePoint + method constructor + method createContextualFragment + method deleteContents + method detach + method expand + method extractContents + method getBoundingClientRect + method getClientRects + method insertNode + method intersectsNode + method isPointInRange + method selectNode + method selectNodeContents + method setEnd + method setEndAfter + method setEndBefore + method setStart + method setStartAfter + method setStartBefore + method surroundContents + method toString +interface ReadableStream + getter locked + method cancel + method constructor + method getReader + method tee +interface RemotePlayback : EventTarget + attribute @@toStringTag + getter onconnect + getter onconnecting + getter ondisconnect + getter state + method cancelWatchAvailability + method constructor + method prompt + method watchAvailability + setter onconnect + setter onconnecting + setter ondisconnect +interface Request + attribute @@toStringTag + getter bodyUsed + getter credentials + getter headers + getter integrity + getter method + getter mode + getter redirect + getter referrer + getter referrerPolicy + getter url + method arrayBuffer + method blob + method clone + method constructor + method json + method text +interface Response + static method error + static method redirect + attribute @@toStringTag + getter body + getter bodyUsed + getter headers + getter ok + getter redirected + getter status + getter statusText + getter type + getter url + method arrayBuffer + method blob + method clone + method constructor + method json + method text +interface SVGAElement : SVGGraphicsElement + attribute @@toStringTag + getter href + getter target + method constructor +interface SVGAngle + attribute @@toStringTag + attribute SVG_ANGLETYPE_DEG + attribute SVG_ANGLETYPE_GRAD + attribute SVG_ANGLETYPE_RAD + attribute SVG_ANGLETYPE_UNKNOWN + attribute SVG_ANGLETYPE_UNSPECIFIED + getter unitType + getter value + getter valueAsString + getter valueInSpecifiedUnits + method constructor + method convertToSpecifiedUnits + method newValueSpecifiedUnits + setter value + setter valueAsString + setter valueInSpecifiedUnits +interface SVGAnimateElement : SVGAnimationElement + attribute @@toStringTag + method constructor +interface SVGAnimateMotionElement : SVGAnimationElement + attribute @@toStringTag + method constructor +interface SVGAnimateTransformElement : SVGAnimationElement + attribute @@toStringTag + method constructor +interface SVGAnimatedAngle + attribute @@toStringTag + getter animVal + getter baseVal + method constructor +interface SVGAnimatedBoolean + attribute @@toStringTag + getter animVal + getter baseVal + method constructor + setter baseVal +interface SVGAnimatedEnumeration + attribute @@toStringTag + getter animVal + getter baseVal + method constructor + setter baseVal +interface SVGAnimatedInteger + attribute @@toStringTag + getter animVal + getter baseVal + method constructor + setter baseVal +interface SVGAnimatedLength + attribute @@toStringTag + getter animVal + getter baseVal + method constructor +interface SVGAnimatedLengthList + attribute @@toStringTag + getter animVal + getter baseVal + method constructor +interface SVGAnimatedNumber + attribute @@toStringTag + getter animVal + getter baseVal + method constructor + setter baseVal +interface SVGAnimatedNumberList + attribute @@toStringTag + getter animVal + getter baseVal + method constructor +interface SVGAnimatedPreserveAspectRatio + attribute @@toStringTag + getter animVal + getter baseVal + method constructor +interface SVGAnimatedRect + attribute @@toStringTag + getter animVal + getter baseVal + method constructor +interface SVGAnimatedString + attribute @@toStringTag + getter animVal + getter baseVal + method constructor + setter baseVal +interface SVGAnimatedTransformList + attribute @@toStringTag + getter animVal + getter baseVal + method constructor +interface SVGAnimationElement : SVGElement + attribute @@toStringTag + getter onbegin + getter onend + getter onrepeat + getter requiredExtensions + getter requiredFeatures + getter systemLanguage + getter targetElement + method beginElement + method beginElementAt + method constructor + method endElement + method endElementAt + method getCurrentTime + method getSimpleDuration + method getStartTime + setter onbegin + setter onend + setter onrepeat +interface SVGCircleElement : SVGGeometryElement + attribute @@toStringTag + getter cx + getter cy + getter r + method constructor +interface SVGClipPathElement : SVGGraphicsElement + attribute @@toStringTag + getter clipPathUnits + method constructor +interface SVGComponentTransferFunctionElement : SVGElement + attribute @@toStringTag + attribute SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE + attribute SVG_FECOMPONENTTRANSFER_TYPE_GAMMA + attribute SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY + attribute SVG_FECOMPONENTTRANSFER_TYPE_LINEAR + attribute SVG_FECOMPONENTTRANSFER_TYPE_TABLE + attribute SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN + getter amplitude + getter exponent + getter intercept + getter offset + getter slope + getter tableValues + getter type + method constructor +interface SVGDefsElement : SVGGraphicsElement + attribute @@toStringTag + method constructor +interface SVGDescElement : SVGElement + attribute @@toStringTag + method constructor +interface SVGDiscardElement : SVGElement + attribute @@toStringTag + method constructor +interface SVGElement : Element + attribute @@toStringTag + getter className + getter dataset + getter onabort + getter onauxclick + getter onblur + getter oncancel + getter oncanplay + getter oncanplaythrough + getter onchange + getter onclick + getter onclose + getter oncontextmenu + getter oncuechange + getter ondblclick + getter ondrag + getter ondragend + getter ondragenter + getter ondragleave + getter ondragover + getter ondragstart + getter ondrop + getter ondurationchange + getter onemptied + getter onended + getter onerror + getter onfocus + getter ongotpointercapture + getter oninput + getter oninvalid + getter onkeydown + getter onkeypress + getter onkeyup + getter onload + getter onloadeddata + getter onloadedmetadata + getter onloadstart + getter onlostpointercapture + getter onmousedown + getter onmouseenter + getter onmouseleave + getter onmousemove + getter onmouseout + getter onmouseover + getter onmouseup + getter onmousewheel + getter onpause + getter onplay + getter onplaying + getter onpointercancel + getter onpointerdown + getter onpointerenter + getter onpointerleave + getter onpointermove + getter onpointerout + getter onpointerover + getter onpointerup + getter onprogress + getter onratechange + getter onreset + getter onresize + getter onscroll + getter onseeked + getter onseeking + getter onselect + getter onshow + getter onstalled + getter onsubmit + getter onsuspend + getter ontimeupdate + getter ontoggle + getter ontouchcancel + getter ontouchend + getter ontouchmove + getter ontouchstart + getter onvolumechange + getter onwaiting + getter ownerSVGElement + getter style + getter tabIndex + getter viewportElement + method blur + method constructor + method focus + setter onabort + setter onauxclick + setter onblur + setter oncancel + setter oncanplay + setter oncanplaythrough + setter onchange + setter onclick + setter onclose + setter oncontextmenu + setter oncuechange + setter ondblclick + setter ondrag + setter ondragend + setter ondragenter + setter ondragleave + setter ondragover + setter ondragstart + setter ondrop + setter ondurationchange + setter onemptied + setter onended + setter onerror + setter onfocus + setter ongotpointercapture + setter oninput + setter oninvalid + setter onkeydown + setter onkeypress + setter onkeyup + setter onload + setter onloadeddata + setter onloadedmetadata + setter onloadstart + setter onlostpointercapture + setter onmousedown + setter onmouseenter + setter onmouseleave + setter onmousemove + setter onmouseout + setter onmouseover + setter onmouseup + setter onmousewheel + setter onpause + setter onplay + setter onplaying + setter onpointercancel + setter onpointerdown + setter onpointerenter + setter onpointerleave + setter onpointermove + setter onpointerout + setter onpointerover + setter onpointerup + setter onprogress + setter onratechange + setter onreset + setter onresize + setter onscroll + setter onseeked + setter onseeking + setter onselect + setter onshow + setter onstalled + setter onsubmit + setter onsuspend + setter ontimeupdate + setter ontoggle + setter ontouchcancel + setter ontouchend + setter ontouchmove + setter ontouchstart + setter onvolumechange + setter onwaiting + setter style + setter tabIndex +interface SVGEllipseElement : SVGGeometryElement + attribute @@toStringTag + getter cx + getter cy + getter rx + getter ry + method constructor +interface SVGFEBlendElement : SVGElement + attribute @@toStringTag + attribute SVG_FEBLEND_MODE_DARKEN + attribute SVG_FEBLEND_MODE_LIGHTEN + attribute SVG_FEBLEND_MODE_MULTIPLY + attribute SVG_FEBLEND_MODE_NORMAL + attribute SVG_FEBLEND_MODE_SCREEN + attribute SVG_FEBLEND_MODE_UNKNOWN + getter height + getter in1 + getter in2 + getter mode + getter result + getter width + getter x + getter y + method constructor +interface SVGFEColorMatrixElement : SVGElement + attribute @@toStringTag + attribute SVG_FECOLORMATRIX_TYPE_HUEROTATE + attribute SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA + attribute SVG_FECOLORMATRIX_TYPE_MATRIX + attribute SVG_FECOLORMATRIX_TYPE_SATURATE + attribute SVG_FECOLORMATRIX_TYPE_UNKNOWN + getter height + getter in1 + getter result + getter type + getter values + getter width + getter x + getter y + method constructor +interface SVGFEComponentTransferElement : SVGElement + attribute @@toStringTag + getter height + getter in1 + getter result + getter width + getter x + getter y + method constructor +interface SVGFECompositeElement : SVGElement + attribute @@toStringTag + attribute SVG_FECOMPOSITE_OPERATOR_ARITHMETIC + attribute SVG_FECOMPOSITE_OPERATOR_ATOP + attribute SVG_FECOMPOSITE_OPERATOR_IN + attribute SVG_FECOMPOSITE_OPERATOR_OUT + attribute SVG_FECOMPOSITE_OPERATOR_OVER + attribute SVG_FECOMPOSITE_OPERATOR_UNKNOWN + attribute SVG_FECOMPOSITE_OPERATOR_XOR + getter height + getter in1 + getter in2 + getter k1 + getter k2 + getter k3 + getter k4 + getter operator + getter result + getter width + getter x + getter y + method constructor +interface SVGFEConvolveMatrixElement : SVGElement + attribute @@toStringTag + attribute SVG_EDGEMODE_DUPLICATE + attribute SVG_EDGEMODE_NONE + attribute SVG_EDGEMODE_UNKNOWN + attribute SVG_EDGEMODE_WRAP + getter bias + getter divisor + getter edgeMode + getter height + getter in1 + getter kernelMatrix + getter kernelUnitLengthX + getter kernelUnitLengthY + getter orderX + getter orderY + getter preserveAlpha + getter result + getter targetX + getter targetY + getter width + getter x + getter y + method constructor +interface SVGFEDiffuseLightingElement : SVGElement + attribute @@toStringTag + getter diffuseConstant + getter height + getter in1 + getter kernelUnitLengthX + getter kernelUnitLengthY + getter result + getter surfaceScale + getter width + getter x + getter y + method constructor +interface SVGFEDisplacementMapElement : SVGElement + attribute @@toStringTag + attribute SVG_CHANNEL_A + attribute SVG_CHANNEL_B + attribute SVG_CHANNEL_G + attribute SVG_CHANNEL_R + attribute SVG_CHANNEL_UNKNOWN + getter height + getter in1 + getter in2 + getter result + getter scale + getter width + getter x + getter xChannelSelector + getter y + getter yChannelSelector + method constructor +interface SVGFEDistantLightElement : SVGElement + attribute @@toStringTag + getter azimuth + getter elevation + method constructor +interface SVGFEDropShadowElement : SVGElement + attribute @@toStringTag + getter dx + getter dy + getter height + getter in1 + getter result + getter stdDeviationX + getter stdDeviationY + getter width + getter x + getter y + method constructor + method setStdDeviation +interface SVGFEFloodElement : SVGElement + attribute @@toStringTag + getter height + getter result + getter width + getter x + getter y + method constructor +interface SVGFEFuncAElement : SVGComponentTransferFunctionElement + attribute @@toStringTag + method constructor +interface SVGFEFuncBElement : SVGComponentTransferFunctionElement + attribute @@toStringTag + method constructor +interface SVGFEFuncGElement : SVGComponentTransferFunctionElement + attribute @@toStringTag + method constructor +interface SVGFEFuncRElement : SVGComponentTransferFunctionElement + attribute @@toStringTag + method constructor +interface SVGFEGaussianBlurElement : SVGElement + attribute @@toStringTag + getter height + getter in1 + getter result + getter stdDeviationX + getter stdDeviationY + getter width + getter x + getter y + method constructor + method setStdDeviation +interface SVGFEImageElement : SVGElement + attribute @@toStringTag + getter height + getter href + getter preserveAspectRatio + getter result + getter width + getter x + getter y + method constructor +interface SVGFEMergeElement : SVGElement + attribute @@toStringTag + getter height + getter result + getter width + getter x + getter y + method constructor +interface SVGFEMergeNodeElement : SVGElement + attribute @@toStringTag + getter in1 + method constructor +interface SVGFEMorphologyElement : SVGElement + attribute @@toStringTag + attribute SVG_MORPHOLOGY_OPERATOR_DILATE + attribute SVG_MORPHOLOGY_OPERATOR_ERODE + attribute SVG_MORPHOLOGY_OPERATOR_UNKNOWN + getter height + getter in1 + getter operator + getter radiusX + getter radiusY + getter result + getter width + getter x + getter y + method constructor +interface SVGFEOffsetElement : SVGElement + attribute @@toStringTag + getter dx + getter dy + getter height + getter in1 + getter result + getter width + getter x + getter y + method constructor +interface SVGFEPointLightElement : SVGElement + attribute @@toStringTag + getter x + getter y + getter z + method constructor +interface SVGFESpecularLightingElement : SVGElement + attribute @@toStringTag + getter height + getter in1 + getter kernelUnitLengthX + getter kernelUnitLengthY + getter result + getter specularConstant + getter specularExponent + getter surfaceScale + getter width + getter x + getter y + method constructor +interface SVGFESpotLightElement : SVGElement + attribute @@toStringTag + getter limitingConeAngle + getter pointsAtX + getter pointsAtY + getter pointsAtZ + getter specularExponent + getter x + getter y + getter z + method constructor +interface SVGFETileElement : SVGElement + attribute @@toStringTag + getter height + getter in1 + getter result + getter width + getter x + getter y + method constructor +interface SVGFETurbulenceElement : SVGElement + attribute @@toStringTag + attribute SVG_STITCHTYPE_NOSTITCH + attribute SVG_STITCHTYPE_STITCH + attribute SVG_STITCHTYPE_UNKNOWN + attribute SVG_TURBULENCE_TYPE_FRACTALNOISE + attribute SVG_TURBULENCE_TYPE_TURBULENCE + attribute SVG_TURBULENCE_TYPE_UNKNOWN + getter baseFrequencyX + getter baseFrequencyY + getter height + getter numOctaves + getter result + getter seed + getter stitchTiles + getter type + getter width + getter x + getter y + method constructor +interface SVGFilterElement : SVGElement + attribute @@toStringTag + getter filterUnits + getter height + getter href + getter primitiveUnits + getter width + getter x + getter y + method constructor +interface SVGForeignObjectElement : SVGGraphicsElement + attribute @@toStringTag + getter height + getter width + getter x + getter y + method constructor +interface SVGGElement : SVGGraphicsElement + attribute @@toStringTag + method constructor +interface SVGGeometryElement : SVGGraphicsElement + attribute @@toStringTag + getter pathLength + method constructor + method getPointAtLength + method getTotalLength + method isPointInFill + method isPointInStroke +interface SVGGradientElement : SVGElement + attribute @@toStringTag + attribute SVG_SPREADMETHOD_PAD + attribute SVG_SPREADMETHOD_REFLECT + attribute SVG_SPREADMETHOD_REPEAT + attribute SVG_SPREADMETHOD_UNKNOWN + getter gradientTransform + getter gradientUnits + getter href + getter spreadMethod + method constructor +interface SVGGraphicsElement : SVGElement + attribute @@toStringTag + getter farthestViewportElement + getter nearestViewportElement + getter requiredExtensions + getter requiredFeatures + getter systemLanguage + getter transform + method constructor + method getBBox + method getCTM + method getScreenCTM +interface SVGImageElement : SVGGraphicsElement + attribute @@toStringTag + getter height + getter href + getter preserveAspectRatio + getter width + getter x + getter y + method constructor +interface SVGLength + attribute @@toStringTag + attribute SVG_LENGTHTYPE_CM + attribute SVG_LENGTHTYPE_EMS + attribute SVG_LENGTHTYPE_EXS + attribute SVG_LENGTHTYPE_IN + attribute SVG_LENGTHTYPE_MM + attribute SVG_LENGTHTYPE_NUMBER + attribute SVG_LENGTHTYPE_PC + attribute SVG_LENGTHTYPE_PERCENTAGE + attribute SVG_LENGTHTYPE_PT + attribute SVG_LENGTHTYPE_PX + attribute SVG_LENGTHTYPE_UNKNOWN + getter unitType + getter value + getter valueAsString + getter valueInSpecifiedUnits + method constructor + method convertToSpecifiedUnits + method newValueSpecifiedUnits + setter value + setter valueAsString + setter valueInSpecifiedUnits +interface SVGLengthList + attribute @@toStringTag + getter length + getter numberOfItems + method @@iterator + method appendItem + method clear + method constructor + method getItem + method initialize + method insertItemBefore + method removeItem + method replaceItem +interface SVGLineElement : SVGGeometryElement + attribute @@toStringTag + getter x1 + getter x2 + getter y1 + getter y2 + method constructor +interface SVGLinearGradientElement : SVGGradientElement + attribute @@toStringTag + getter x1 + getter x2 + getter y1 + getter y2 + method constructor +interface SVGMPathElement : SVGElement + attribute @@toStringTag + getter href + method constructor +interface SVGMarkerElement : SVGElement + attribute @@toStringTag + attribute SVG_MARKERUNITS_STROKEWIDTH + attribute SVG_MARKERUNITS_UNKNOWN + attribute SVG_MARKERUNITS_USERSPACEONUSE + attribute SVG_MARKER_ORIENT_ANGLE + attribute SVG_MARKER_ORIENT_AUTO + attribute SVG_MARKER_ORIENT_UNKNOWN + getter markerHeight + getter markerUnits + getter markerWidth + getter orientAngle + getter orientType + getter preserveAspectRatio + getter refX + getter refY + getter viewBox + method constructor + method setOrientToAngle + method setOrientToAuto +interface SVGMaskElement : SVGElement + attribute @@toStringTag + getter height + getter maskContentUnits + getter maskUnits + getter requiredExtensions + getter requiredFeatures + getter systemLanguage + getter width + getter x + getter y + method constructor +interface SVGMatrix + attribute @@toStringTag + getter a + getter b + getter c + getter d + getter e + getter f + method constructor + method flipX + method flipY + method inverse + method multiply + method rotate + method rotateFromVector + method scale + method scaleNonUniform + method skewX + method skewY + method translate + setter a + setter b + setter c + setter d + setter e + setter f +interface SVGMetadataElement : SVGElement + attribute @@toStringTag + method constructor +interface SVGNumber + attribute @@toStringTag + getter value + method constructor + setter value +interface SVGNumberList + attribute @@toStringTag + getter length + getter numberOfItems + method @@iterator + method appendItem + method clear + method constructor + method getItem + method initialize + method insertItemBefore + method removeItem + method replaceItem +interface SVGPathElement : SVGGeometryElement + attribute @@toStringTag + method constructor + method getPathSegAtLength +interface SVGPatternElement : SVGElement + attribute @@toStringTag + getter height + getter href + getter patternContentUnits + getter patternTransform + getter patternUnits + getter preserveAspectRatio + getter requiredExtensions + getter requiredFeatures + getter systemLanguage + getter viewBox + getter width + getter x + getter y + method constructor +interface SVGPoint + attribute @@toStringTag + getter x + getter y + method constructor + method matrixTransform + setter x + setter y +interface SVGPointList + attribute @@toStringTag + getter length + getter numberOfItems + method @@iterator + method appendItem + method clear + method constructor + method getItem + method initialize + method insertItemBefore + method removeItem + method replaceItem +interface SVGPolygonElement : SVGGeometryElement + attribute @@toStringTag + getter animatedPoints + getter points + method constructor +interface SVGPolylineElement : SVGGeometryElement + attribute @@toStringTag + getter animatedPoints + getter points + method constructor +interface SVGPreserveAspectRatio + attribute @@toStringTag + attribute SVG_MEETORSLICE_MEET + attribute SVG_MEETORSLICE_SLICE + attribute SVG_MEETORSLICE_UNKNOWN + attribute SVG_PRESERVEASPECTRATIO_NONE + attribute SVG_PRESERVEASPECTRATIO_UNKNOWN + attribute SVG_PRESERVEASPECTRATIO_XMAXYMAX + attribute SVG_PRESERVEASPECTRATIO_XMAXYMID + attribute SVG_PRESERVEASPECTRATIO_XMAXYMIN + attribute SVG_PRESERVEASPECTRATIO_XMIDYMAX + attribute SVG_PRESERVEASPECTRATIO_XMIDYMID + attribute SVG_PRESERVEASPECTRATIO_XMIDYMIN + attribute SVG_PRESERVEASPECTRATIO_XMINYMAX + attribute SVG_PRESERVEASPECTRATIO_XMINYMID + attribute SVG_PRESERVEASPECTRATIO_XMINYMIN + getter align + getter meetOrSlice + method constructor + setter align + setter meetOrSlice +interface SVGRadialGradientElement : SVGGradientElement + attribute @@toStringTag + getter cx + getter cy + getter fr + getter fx + getter fy + getter r + method constructor +interface SVGRect + attribute @@toStringTag + getter height + getter width + getter x + getter y + method constructor + setter height + setter width + setter x + setter y +interface SVGRectElement : SVGGeometryElement + attribute @@toStringTag + getter height + getter rx + getter ry + getter width + getter x + getter y + method constructor +interface SVGSVGElement : SVGGraphicsElement + attribute @@toStringTag + attribute SVG_ZOOMANDPAN_DISABLE + attribute SVG_ZOOMANDPAN_MAGNIFY + attribute SVG_ZOOMANDPAN_UNKNOWN + getter currentScale + getter currentTranslate + getter height + getter preserveAspectRatio + getter viewBox + getter width + getter x + getter y + getter zoomAndPan + method animationsPaused + method checkEnclosure + method checkIntersection + method constructor + method createSVGAngle + method createSVGLength + method createSVGMatrix + method createSVGNumber + method createSVGPoint + method createSVGRect + method createSVGTransform + method createSVGTransformFromMatrix + method deselectAll + method forceRedraw + method getCurrentTime + method getElementById + method getEnclosureList + method getIntersectionList + method pauseAnimations + method setCurrentTime + method suspendRedraw + method unpauseAnimations + method unsuspendRedraw + method unsuspendRedrawAll + setter currentScale + setter zoomAndPan +interface SVGScriptElement : SVGElement + attribute @@toStringTag + getter href + getter type + method constructor + setter type +interface SVGSetElement : SVGAnimationElement + attribute @@toStringTag + method constructor +interface SVGStopElement : SVGElement + attribute @@toStringTag + getter offset + method constructor +interface SVGStringList + attribute @@toStringTag + getter length + getter numberOfItems + method @@iterator + method appendItem + method clear + method constructor + method getItem + method initialize + method insertItemBefore + method removeItem + method replaceItem +interface SVGStyleElement : SVGElement + attribute @@toStringTag + getter disabled + getter media + getter sheet + getter title + getter type + method constructor + setter disabled + setter media + setter title + setter type +interface SVGSwitchElement : SVGGraphicsElement + attribute @@toStringTag + method constructor +interface SVGSymbolElement : SVGElement + attribute @@toStringTag + getter preserveAspectRatio + getter viewBox + method constructor +interface SVGTSpanElement : SVGTextPositioningElement + attribute @@toStringTag + method constructor +interface SVGTextContentElement : SVGGraphicsElement + attribute @@toStringTag + attribute LENGTHADJUST_SPACING + attribute LENGTHADJUST_SPACINGANDGLYPHS + attribute LENGTHADJUST_UNKNOWN + getter lengthAdjust + getter textLength + method constructor + method getCharNumAtPosition + method getComputedTextLength + method getEndPositionOfChar + method getExtentOfChar + method getNumberOfChars + method getRotationOfChar + method getStartPositionOfChar + method getSubStringLength + method selectSubString +interface SVGTextElement : SVGTextPositioningElement + attribute @@toStringTag + method constructor +interface SVGTextPathElement : SVGTextContentElement + attribute @@toStringTag + attribute TEXTPATH_METHODTYPE_ALIGN + attribute TEXTPATH_METHODTYPE_STRETCH + attribute TEXTPATH_METHODTYPE_UNKNOWN + attribute TEXTPATH_SPACINGTYPE_AUTO + attribute TEXTPATH_SPACINGTYPE_EXACT + attribute TEXTPATH_SPACINGTYPE_UNKNOWN + getter href + getter method + getter spacing + getter startOffset + method constructor +interface SVGTextPositioningElement : SVGTextContentElement + attribute @@toStringTag + getter dx + getter dy + getter rotate + getter x + getter y + method constructor +interface SVGTitleElement : SVGElement + attribute @@toStringTag + method constructor +interface SVGTransform + attribute @@toStringTag + attribute SVG_TRANSFORM_MATRIX + attribute SVG_TRANSFORM_ROTATE + attribute SVG_TRANSFORM_SCALE + attribute SVG_TRANSFORM_SKEWX + attribute SVG_TRANSFORM_SKEWY + attribute SVG_TRANSFORM_TRANSLATE + attribute SVG_TRANSFORM_UNKNOWN + getter angle + getter matrix + getter type + method constructor + method setMatrix + method setRotate + method setScale + method setSkewX + method setSkewY + method setTranslate +interface SVGTransformList + attribute @@toStringTag + getter length + getter numberOfItems + method @@iterator + method appendItem + method clear + method consolidate + method constructor + method createSVGTransformFromMatrix + method getItem + method initialize + method insertItemBefore + method removeItem + method replaceItem +interface SVGUnitTypes + attribute @@toStringTag + attribute SVG_UNIT_TYPE_OBJECTBOUNDINGBOX + attribute SVG_UNIT_TYPE_UNKNOWN + attribute SVG_UNIT_TYPE_USERSPACEONUSE + method constructor +interface SVGUseElement : SVGGraphicsElement + attribute @@toStringTag + getter height + getter href + getter width + getter x + getter y + method constructor +interface SVGViewElement : SVGElement + attribute @@toStringTag + attribute SVG_ZOOMANDPAN_DISABLE + attribute SVG_ZOOMANDPAN_MAGNIFY + attribute SVG_ZOOMANDPAN_UNKNOWN + getter preserveAspectRatio + getter viewBox + getter zoomAndPan + method constructor + setter zoomAndPan +interface Screen + attribute @@toStringTag + getter availHeight + getter availLeft + getter availTop + getter availWidth + getter colorDepth + getter height + getter orientation + getter pixelDepth + getter width + method constructor +interface ScreenOrientation : EventTarget + attribute @@toStringTag + getter angle + getter onchange + getter type + method constructor + method lock + method unlock + setter onchange +interface ScriptProcessorNode : AudioNode + attribute @@toStringTag + getter bufferSize + getter onaudioprocess + method constructor + setter onaudioprocess +interface SecurityPolicyViolationEvent : Event + attribute @@toStringTag + getter blockedURI + getter columnNumber + getter disposition + getter documentURI + getter effectiveDirective + getter lineNumber + getter originalPolicy + getter referrer + getter sourceFile + getter statusCode + getter violatedDirective + method constructor +interface Selection + attribute @@toStringTag + getter anchorNode + getter anchorOffset + getter baseNode + getter baseOffset + getter extentNode + getter extentOffset + getter focusNode + getter focusOffset + getter isCollapsed + getter rangeCount + getter type + method addRange + method collapse + method collapseToEnd + method collapseToStart + method constructor + method containsNode + method deleteFromDocument + method empty + method extend + method getRangeAt + method modify + method removeAllRanges + method selectAllChildren + method setBaseAndExtent + method setPosition + method toString +interface ServiceWorker : EventTarget + attribute @@toStringTag + getter onerror + getter onstatechange + getter scriptURL + getter state + method constructor + method postMessage + setter onerror + setter onstatechange +interface ServiceWorkerContainer : EventTarget + attribute @@toStringTag + getter controller + getter oncontrollerchange + getter onmessage + getter ready + method constructor + method getRegistration + method getRegistrations + method register + setter oncontrollerchange + setter onmessage +interface ServiceWorkerRegistration : EventTarget + attribute @@toStringTag + getter active + getter installing + getter onupdatefound + getter pushManager + getter scope + getter sync + getter waiting + method constructor + method getNotifications + method showNotification + method unregister + method update + setter onupdatefound +interface ShadowRoot : DocumentFragment + attribute @@toStringTag + getter activeElement + getter delegatesFocus + getter host + getter innerHTML + getter mode + getter olderShadowRoot + getter pointerLockElement + getter styleSheets + method cloneNode + method constructor + method elementFromPoint + method elementsFromPoint + method getSelection + setter innerHTML +interface SharedWorker : EventTarget + attribute @@toStringTag + getter onerror + getter port + getter workerStart + method constructor + setter onerror +interface SiteBoundCredential : Credential + attribute @@toStringTag + getter iconURL + getter name + method constructor +interface SourceBuffer : EventTarget + attribute @@toStringTag + getter appendWindowEnd + getter appendWindowStart + getter buffered + getter mode + getter onabort + getter onerror + getter onupdate + getter onupdateend + getter onupdatestart + getter timestampOffset + getter updating + method abort + method appendBuffer + method constructor + method remove + setter appendWindowEnd + setter appendWindowStart + setter mode + setter onabort + setter onerror + setter onupdate + setter onupdateend + setter onupdatestart + setter timestampOffset +interface SourceBufferList : EventTarget + attribute @@toStringTag + getter length + getter onaddsourcebuffer + getter onremovesourcebuffer + method @@iterator + method constructor + setter onaddsourcebuffer + setter onremovesourcebuffer +interface SpeechSynthesisEvent : Event + attribute @@toStringTag + getter charIndex + getter elapsedTime + getter name + getter utterance + method constructor +interface SpeechSynthesisUtterance : EventTarget + attribute @@toStringTag + getter lang + getter onboundary + getter onend + getter onerror + getter onmark + getter onpause + getter onresume + getter onstart + getter pitch + getter rate + getter text + getter voice + getter volume + method constructor + setter lang + setter onboundary + setter onend + setter onerror + setter onmark + setter onpause + setter onresume + setter onstart + setter pitch + setter rate + setter text + setter voice + setter volume +interface StereoPannerNode : AudioNode + attribute @@toStringTag + getter pan + method constructor +interface Storage + attribute @@toStringTag + getter length + method clear + method constructor + method getItem + method key + method removeItem + method setItem +interface StorageEvent : Event + attribute @@toStringTag + getter key + getter newValue + getter oldValue + getter storageArea + getter url + method constructor + method initStorageEvent +interface StorageManager + attribute @@toStringTag + method constructor + method persist + method persisted +interface StyleSheet + attribute @@toStringTag + getter disabled + getter href + getter media + getter ownerNode + getter parentStyleSheet + getter title + getter type + method constructor + setter disabled +interface StyleSheetList + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item +interface SubtleCrypto + attribute @@toStringTag + method constructor + method decrypt + method deriveBits + method deriveKey + method digest + method encrypt + method exportKey + method generateKey + method importKey + method sign + method unwrapKey + method verify + method wrapKey +interface SyncManager + attribute @@toStringTag + method constructor + method getTags + method register +interface Text : CharacterData + attribute @@toStringTag + getter assignedSlot + getter wholeText + method constructor + method getDestinationInsertionPoints + method splitText +interface TextDecoder + attribute @@toStringTag + getter encoding + getter fatal + getter ignoreBOM + method constructor + method decode +interface TextEncoder + attribute @@toStringTag + getter encoding + method constructor + method encode +interface TextEvent : UIEvent + attribute @@toStringTag + getter data + method constructor + method initTextEvent +interface TextMetrics + attribute @@toStringTag + getter width + method constructor +interface TextTrack : EventTarget + attribute @@toStringTag + getter activeCues + getter cues + getter id + getter kind + getter label + getter language + getter mode + getter oncuechange + method addCue + method constructor + method removeCue + setter mode + setter oncuechange +interface TextTrackCue : EventTarget + attribute @@toStringTag + getter endTime + getter id + getter onenter + getter onexit + getter pauseOnExit + getter startTime + getter track + method constructor + setter endTime + setter id + setter onenter + setter onexit + setter pauseOnExit + setter startTime +interface TextTrackCueList + attribute @@toStringTag + getter length + method @@iterator + method constructor + method getCueById +interface TextTrackList : EventTarget + attribute @@toStringTag + getter length + getter onaddtrack + getter onchange + getter onremovetrack + method @@iterator + method constructor + method getTrackById + setter onaddtrack + setter onchange + setter onremovetrack +interface TimeRanges + attribute @@toStringTag + getter length + method constructor + method end + method start +interface Touch + attribute @@toStringTag + getter clientX + getter clientY + getter force + getter identifier + getter pageX + getter pageY + getter radiusX + getter radiusY + getter rotationAngle + getter screenX + getter screenY + getter target + method constructor +interface TouchEvent : UIEvent + attribute @@toStringTag + getter altKey + getter changedTouches + getter ctrlKey + getter metaKey + getter shiftKey + getter targetTouches + getter touches + method constructor +interface TouchList + attribute @@toStringTag + getter length + method @@iterator + method constructor + method item +interface TrackEvent : Event + attribute @@toStringTag + getter track + method constructor +interface TransitionEvent : Event + attribute @@toStringTag + getter elapsedTime + getter propertyName + getter pseudoElement + method constructor +interface TreeWalker + attribute @@toStringTag + getter currentNode + getter filter + getter root + getter whatToShow + method constructor + method firstChild + method lastChild + method nextNode + method nextSibling + method parentNode + method previousNode + method previousSibling + setter currentNode +interface UIEvent : Event + attribute @@toStringTag + getter detail + getter sourceCapabilities + getter view + getter which + method constructor + method initUIEvent +interface URL + static method createObjectURL + static method revokeObjectURL + attribute @@toStringTag + getter hash + getter host + getter hostname + getter href + getter origin + getter password + getter pathname + getter port + getter protocol + getter search + getter searchParams + getter username + method constructor + method toString + setter hash + setter host + setter hostname + setter href + setter password + setter pathname + setter port + setter protocol + setter search + setter username +interface URLSearchParams + attribute @@toStringTag + method @@iterator + method append + method constructor + method delete + method entries + method forEach + method get + method getAll + method has + method keys + method set + method toString + method values +interface VTTCue : TextTrackCue + attribute @@toStringTag + getter align + getter line + getter position + getter size + getter snapToLines + getter text + getter vertical + method constructor + method getCueAsHTML + setter align + setter line + setter position + setter size + setter snapToLines + setter text + setter vertical +interface ValidityState + attribute @@toStringTag + getter badInput + getter customError + getter patternMismatch + getter rangeOverflow + getter rangeUnderflow + getter stepMismatch + getter tooLong + getter tooShort + getter typeMismatch + getter valid + getter valueMissing + method constructor +interface WaveShaperNode : AudioNode + attribute @@toStringTag + getter curve + getter oversample + method constructor + setter curve + setter oversample +interface WebGL2RenderingContext + attribute @@toStringTag + attribute ACTIVE_ATTRIBUTES + attribute ACTIVE_TEXTURE + attribute ACTIVE_UNIFORMS + attribute ACTIVE_UNIFORM_BLOCKS + attribute ALIASED_LINE_WIDTH_RANGE + attribute ALIASED_POINT_SIZE_RANGE + attribute ALPHA + attribute ALPHA_BITS + attribute ALREADY_SIGNALED + attribute ALWAYS + attribute ANY_SAMPLES_PASSED + attribute ANY_SAMPLES_PASSED_CONSERVATIVE + attribute ARRAY_BUFFER + attribute ARRAY_BUFFER_BINDING + attribute ATTACHED_SHADERS + attribute BACK + attribute BLEND + attribute BLEND_COLOR + attribute BLEND_DST_ALPHA + attribute BLEND_DST_RGB + attribute BLEND_EQUATION + attribute BLEND_EQUATION_ALPHA + attribute BLEND_EQUATION_RGB + attribute BLEND_SRC_ALPHA + attribute BLEND_SRC_RGB + attribute BLUE_BITS + attribute BOOL + attribute BOOL_VEC2 + attribute BOOL_VEC3 + attribute BOOL_VEC4 + attribute BROWSER_DEFAULT_WEBGL + attribute BUFFER_SIZE + attribute BUFFER_USAGE + attribute BYTE + attribute CCW + attribute CLAMP_TO_EDGE + attribute COLOR + attribute COLOR_ATTACHMENT0 + attribute COLOR_ATTACHMENT1 + attribute COLOR_ATTACHMENT10 + attribute COLOR_ATTACHMENT11 + attribute COLOR_ATTACHMENT12 + attribute COLOR_ATTACHMENT13 + attribute COLOR_ATTACHMENT14 + attribute COLOR_ATTACHMENT15 + attribute COLOR_ATTACHMENT2 + attribute COLOR_ATTACHMENT3 + attribute COLOR_ATTACHMENT4 + attribute COLOR_ATTACHMENT5 + attribute COLOR_ATTACHMENT6 + attribute COLOR_ATTACHMENT7 + attribute COLOR_ATTACHMENT8 + attribute COLOR_ATTACHMENT9 + attribute COLOR_BUFFER_BIT + attribute COLOR_CLEAR_VALUE + attribute COLOR_WRITEMASK + attribute COMPARE_REF_TO_TEXTURE + attribute COMPILE_STATUS + attribute COMPRESSED_TEXTURE_FORMATS + attribute CONDITION_SATISFIED + attribute CONSTANT_ALPHA + attribute CONSTANT_COLOR + attribute CONTEXT_LOST_WEBGL + attribute COPY_READ_BUFFER + attribute COPY_READ_BUFFER_BINDING + attribute COPY_WRITE_BUFFER + attribute COPY_WRITE_BUFFER_BINDING + attribute CULL_FACE + attribute CULL_FACE_MODE + attribute CURRENT_PROGRAM + attribute CURRENT_QUERY + attribute CURRENT_VERTEX_ATTRIB + attribute CW + attribute DECR + attribute DECR_WRAP + attribute DELETE_STATUS + attribute DEPTH + attribute DEPTH24_STENCIL8 + attribute DEPTH32F_STENCIL8 + attribute DEPTH_ATTACHMENT + attribute DEPTH_BITS + attribute DEPTH_BUFFER_BIT + attribute DEPTH_CLEAR_VALUE + attribute DEPTH_COMPONENT + attribute DEPTH_COMPONENT16 + attribute DEPTH_COMPONENT24 + attribute DEPTH_COMPONENT32F + attribute DEPTH_FUNC + attribute DEPTH_RANGE + attribute DEPTH_STENCIL + attribute DEPTH_STENCIL_ATTACHMENT + attribute DEPTH_TEST + attribute DEPTH_WRITEMASK + attribute DITHER + attribute DONT_CARE + attribute DRAW_BUFFER0 + attribute DRAW_BUFFER1 + attribute DRAW_BUFFER10 + attribute DRAW_BUFFER11 + attribute DRAW_BUFFER12 + attribute DRAW_BUFFER13 + attribute DRAW_BUFFER14 + attribute DRAW_BUFFER15 + attribute DRAW_BUFFER2 + attribute DRAW_BUFFER3 + attribute DRAW_BUFFER4 + attribute DRAW_BUFFER5 + attribute DRAW_BUFFER6 + attribute DRAW_BUFFER7 + attribute DRAW_BUFFER8 + attribute DRAW_BUFFER9 + attribute DRAW_FRAMEBUFFER + attribute DRAW_FRAMEBUFFER_BINDING + attribute DST_ALPHA + attribute DST_COLOR + attribute DYNAMIC_COPY + attribute DYNAMIC_DRAW + attribute DYNAMIC_READ + attribute ELEMENT_ARRAY_BUFFER + attribute ELEMENT_ARRAY_BUFFER_BINDING + attribute EQUAL + attribute FASTEST + attribute FLOAT + attribute FLOAT_32_UNSIGNED_INT_24_8_REV + attribute FLOAT_MAT2 + attribute FLOAT_MAT2x3 + attribute FLOAT_MAT2x4 + attribute FLOAT_MAT3 + attribute FLOAT_MAT3x2 + attribute FLOAT_MAT3x4 + attribute FLOAT_MAT4 + attribute FLOAT_MAT4x2 + attribute FLOAT_MAT4x3 + attribute FLOAT_VEC2 + attribute FLOAT_VEC3 + attribute FLOAT_VEC4 + attribute FRAGMENT_SHADER + attribute FRAGMENT_SHADER_DERIVATIVE_HINT + attribute FRAMEBUFFER + attribute FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE + attribute FRAMEBUFFER_ATTACHMENT_BLUE_SIZE + attribute FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING + attribute FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE + attribute FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE + attribute FRAMEBUFFER_ATTACHMENT_GREEN_SIZE + attribute FRAMEBUFFER_ATTACHMENT_OBJECT_NAME + attribute FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + attribute FRAMEBUFFER_ATTACHMENT_RED_SIZE + attribute FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE + attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE + attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER + attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL + attribute FRAMEBUFFER_BINDING + attribute FRAMEBUFFER_COMPLETE + attribute FRAMEBUFFER_DEFAULT + attribute FRAMEBUFFER_INCOMPLETE_ATTACHMENT + attribute FRAMEBUFFER_INCOMPLETE_DIMENSIONS + attribute FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + attribute FRAMEBUFFER_INCOMPLETE_MULTISAMPLE + attribute FRAMEBUFFER_UNSUPPORTED + attribute FRONT + attribute FRONT_AND_BACK + attribute FRONT_FACE + attribute FUNC_ADD + attribute FUNC_REVERSE_SUBTRACT + attribute FUNC_SUBTRACT + attribute GENERATE_MIPMAP_HINT + attribute GEQUAL + attribute GREATER + attribute GREEN_BITS + attribute HALF_FLOAT + attribute HIGH_FLOAT + attribute HIGH_INT + attribute IMPLEMENTATION_COLOR_READ_FORMAT + attribute IMPLEMENTATION_COLOR_READ_TYPE + attribute INCR + attribute INCR_WRAP + attribute INT + attribute INTERLEAVED_ATTRIBS + attribute INT_2_10_10_10_REV + attribute INT_SAMPLER_2D + attribute INT_SAMPLER_2D_ARRAY + attribute INT_SAMPLER_3D + attribute INT_SAMPLER_CUBE + attribute INT_VEC2 + attribute INT_VEC3 + attribute INT_VEC4 + attribute INVALID_ENUM + attribute INVALID_FRAMEBUFFER_OPERATION + attribute INVALID_INDEX + attribute INVALID_OPERATION + attribute INVALID_VALUE + attribute INVERT + attribute KEEP + attribute LEQUAL + attribute LESS + attribute LINEAR + attribute LINEAR_MIPMAP_LINEAR + attribute LINEAR_MIPMAP_NEAREST + attribute LINES + attribute LINE_LOOP + attribute LINE_STRIP + attribute LINE_WIDTH + attribute LINK_STATUS + attribute LOW_FLOAT + attribute LOW_INT + attribute LUMINANCE + attribute LUMINANCE_ALPHA + attribute MAX + attribute MAX_3D_TEXTURE_SIZE + attribute MAX_ARRAY_TEXTURE_LAYERS + attribute MAX_CLIENT_WAIT_TIMEOUT_WEBGL + attribute MAX_COLOR_ATTACHMENTS + attribute MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS + attribute MAX_COMBINED_TEXTURE_IMAGE_UNITS + attribute MAX_COMBINED_UNIFORM_BLOCKS + attribute MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS + attribute MAX_CUBE_MAP_TEXTURE_SIZE + attribute MAX_DRAW_BUFFERS + attribute MAX_ELEMENTS_INDICES + attribute MAX_ELEMENTS_VERTICES + attribute MAX_ELEMENT_INDEX + attribute MAX_FRAGMENT_INPUT_COMPONENTS + attribute MAX_FRAGMENT_UNIFORM_BLOCKS + attribute MAX_FRAGMENT_UNIFORM_COMPONENTS + attribute MAX_FRAGMENT_UNIFORM_VECTORS + attribute MAX_PROGRAM_TEXEL_OFFSET + attribute MAX_RENDERBUFFER_SIZE + attribute MAX_SAMPLES + attribute MAX_SERVER_WAIT_TIMEOUT + attribute MAX_TEXTURE_IMAGE_UNITS + attribute MAX_TEXTURE_LOD_BIAS + attribute MAX_TEXTURE_SIZE + attribute MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS + attribute MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS + attribute MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS + attribute MAX_UNIFORM_BLOCK_SIZE + attribute MAX_UNIFORM_BUFFER_BINDINGS + attribute MAX_VARYING_COMPONENTS + attribute MAX_VARYING_VECTORS + attribute MAX_VERTEX_ATTRIBS + attribute MAX_VERTEX_OUTPUT_COMPONENTS + attribute MAX_VERTEX_TEXTURE_IMAGE_UNITS + attribute MAX_VERTEX_UNIFORM_BLOCKS + attribute MAX_VERTEX_UNIFORM_COMPONENTS + attribute MAX_VERTEX_UNIFORM_VECTORS + attribute MAX_VIEWPORT_DIMS + attribute MEDIUM_FLOAT + attribute MEDIUM_INT + attribute MIN + attribute MIN_PROGRAM_TEXEL_OFFSET + attribute MIRRORED_REPEAT + attribute NEAREST + attribute NEAREST_MIPMAP_LINEAR + attribute NEAREST_MIPMAP_NEAREST + attribute NEVER + attribute NICEST + attribute NONE + attribute NOTEQUAL + attribute NO_ERROR + attribute OBJECT_TYPE + attribute ONE + attribute ONE_MINUS_CONSTANT_ALPHA + attribute ONE_MINUS_CONSTANT_COLOR + attribute ONE_MINUS_DST_ALPHA + attribute ONE_MINUS_DST_COLOR + attribute ONE_MINUS_SRC_ALPHA + attribute ONE_MINUS_SRC_COLOR + attribute OUT_OF_MEMORY + attribute PACK_ALIGNMENT + attribute PACK_ROW_LENGTH + attribute PACK_SKIP_PIXELS + attribute PACK_SKIP_ROWS + attribute PIXEL_PACK_BUFFER + attribute PIXEL_PACK_BUFFER_BINDING + attribute PIXEL_UNPACK_BUFFER + attribute PIXEL_UNPACK_BUFFER_BINDING + attribute POINTS + attribute POLYGON_OFFSET_FACTOR + attribute POLYGON_OFFSET_FILL + attribute POLYGON_OFFSET_UNITS + attribute QUERY_RESULT + attribute QUERY_RESULT_AVAILABLE + attribute R11F_G11F_B10F + attribute R16F + attribute R16I + attribute R16UI + attribute R32F + attribute R32I + attribute R32UI + attribute R8 + attribute R8I + attribute R8UI + attribute R8_SNORM + attribute RASTERIZER_DISCARD + attribute READ_BUFFER + attribute READ_FRAMEBUFFER + attribute READ_FRAMEBUFFER_BINDING + attribute RED + attribute RED_BITS + attribute RED_INTEGER + attribute RENDERBUFFER + attribute RENDERBUFFER_ALPHA_SIZE + attribute RENDERBUFFER_BINDING + attribute RENDERBUFFER_BLUE_SIZE + attribute RENDERBUFFER_DEPTH_SIZE + attribute RENDERBUFFER_GREEN_SIZE + attribute RENDERBUFFER_HEIGHT + attribute RENDERBUFFER_INTERNAL_FORMAT + attribute RENDERBUFFER_RED_SIZE + attribute RENDERBUFFER_SAMPLES + attribute RENDERBUFFER_STENCIL_SIZE + attribute RENDERBUFFER_WIDTH + attribute RENDERER + attribute REPEAT + attribute REPLACE + attribute RG + attribute RG16F + attribute RG16I + attribute RG16UI + attribute RG32F + attribute RG32I + attribute RG32UI + attribute RG8 + attribute RG8I + attribute RG8UI + attribute RG8_SNORM + attribute RGB + attribute RGB10_A2 + attribute RGB10_A2UI + attribute RGB16F + attribute RGB16I + attribute RGB16UI + attribute RGB32F + attribute RGB32I + attribute RGB32UI + attribute RGB565 + attribute RGB5_A1 + attribute RGB8 + attribute RGB8I + attribute RGB8UI + attribute RGB8_SNORM + attribute RGB9_E5 + attribute RGBA + attribute RGBA16F + attribute RGBA16I + attribute RGBA16UI + attribute RGBA32F + attribute RGBA32I + attribute RGBA32UI + attribute RGBA4 + attribute RGBA8 + attribute RGBA8I + attribute RGBA8UI + attribute RGBA8_SNORM + attribute RGBA_INTEGER + attribute RGB_INTEGER + attribute RG_INTEGER + attribute SAMPLER_2D + attribute SAMPLER_2D_ARRAY + attribute SAMPLER_2D_ARRAY_SHADOW + attribute SAMPLER_2D_SHADOW + attribute SAMPLER_3D + attribute SAMPLER_BINDING + attribute SAMPLER_CUBE + attribute SAMPLER_CUBE_SHADOW + attribute SAMPLES + attribute SAMPLE_ALPHA_TO_COVERAGE + attribute SAMPLE_BUFFERS + attribute SAMPLE_COVERAGE + attribute SAMPLE_COVERAGE_INVERT + attribute SAMPLE_COVERAGE_VALUE + attribute SCISSOR_BOX + attribute SCISSOR_TEST + attribute SEPARATE_ATTRIBS + attribute SHADER_TYPE + attribute SHADING_LANGUAGE_VERSION + attribute SHORT + attribute SIGNALED + attribute SIGNED_NORMALIZED + attribute SRC_ALPHA + attribute SRC_ALPHA_SATURATE + attribute SRC_COLOR + attribute SRGB + attribute SRGB8 + attribute SRGB8_ALPHA8 + attribute STATIC_COPY + attribute STATIC_DRAW + attribute STATIC_READ + attribute STENCIL + attribute STENCIL_ATTACHMENT + attribute STENCIL_BACK_FAIL + attribute STENCIL_BACK_FUNC + attribute STENCIL_BACK_PASS_DEPTH_FAIL + attribute STENCIL_BACK_PASS_DEPTH_PASS + attribute STENCIL_BACK_REF + attribute STENCIL_BACK_VALUE_MASK + attribute STENCIL_BACK_WRITEMASK + attribute STENCIL_BITS + attribute STENCIL_BUFFER_BIT + attribute STENCIL_CLEAR_VALUE + attribute STENCIL_FAIL + attribute STENCIL_FUNC + attribute STENCIL_INDEX + attribute STENCIL_INDEX8 + attribute STENCIL_PASS_DEPTH_FAIL + attribute STENCIL_PASS_DEPTH_PASS + attribute STENCIL_REF + attribute STENCIL_TEST + attribute STENCIL_VALUE_MASK + attribute STENCIL_WRITEMASK + attribute STREAM_COPY + attribute STREAM_DRAW + attribute STREAM_READ + attribute SUBPIXEL_BITS + attribute SYNC_CONDITION + attribute SYNC_FENCE + attribute SYNC_FLAGS + attribute SYNC_FLUSH_COMMANDS_BIT + attribute SYNC_GPU_COMMANDS_COMPLETE + attribute SYNC_STATUS + attribute TEXTURE + attribute TEXTURE0 + attribute TEXTURE1 + attribute TEXTURE10 + attribute TEXTURE11 + attribute TEXTURE12 + attribute TEXTURE13 + attribute TEXTURE14 + attribute TEXTURE15 + attribute TEXTURE16 + attribute TEXTURE17 + attribute TEXTURE18 + attribute TEXTURE19 + attribute TEXTURE2 + attribute TEXTURE20 + attribute TEXTURE21 + attribute TEXTURE22 + attribute TEXTURE23 + attribute TEXTURE24 + attribute TEXTURE25 + attribute TEXTURE26 + attribute TEXTURE27 + attribute TEXTURE28 + attribute TEXTURE29 + attribute TEXTURE3 + attribute TEXTURE30 + attribute TEXTURE31 + attribute TEXTURE4 + attribute TEXTURE5 + attribute TEXTURE6 + attribute TEXTURE7 + attribute TEXTURE8 + attribute TEXTURE9 + attribute TEXTURE_2D + attribute TEXTURE_2D_ARRAY + attribute TEXTURE_3D + attribute TEXTURE_BASE_LEVEL + attribute TEXTURE_BINDING_2D + attribute TEXTURE_BINDING_2D_ARRAY + attribute TEXTURE_BINDING_3D + attribute TEXTURE_BINDING_CUBE_MAP + attribute TEXTURE_COMPARE_FUNC + attribute TEXTURE_COMPARE_MODE + attribute TEXTURE_CUBE_MAP + attribute TEXTURE_CUBE_MAP_NEGATIVE_X + attribute TEXTURE_CUBE_MAP_NEGATIVE_Y + attribute TEXTURE_CUBE_MAP_NEGATIVE_Z + attribute TEXTURE_CUBE_MAP_POSITIVE_X + attribute TEXTURE_CUBE_MAP_POSITIVE_Y + attribute TEXTURE_CUBE_MAP_POSITIVE_Z + attribute TEXTURE_IMMUTABLE_FORMAT + attribute TEXTURE_IMMUTABLE_LEVELS + attribute TEXTURE_MAG_FILTER + attribute TEXTURE_MAX_LEVEL + attribute TEXTURE_MAX_LOD + attribute TEXTURE_MIN_FILTER + attribute TEXTURE_MIN_LOD + attribute TEXTURE_WRAP_R + attribute TEXTURE_WRAP_S + attribute TEXTURE_WRAP_T + attribute TIMEOUT_EXPIRED + attribute TIMEOUT_IGNORED + attribute TRANSFORM_FEEDBACK + attribute TRANSFORM_FEEDBACK_ACTIVE + attribute TRANSFORM_FEEDBACK_BINDING + attribute TRANSFORM_FEEDBACK_BUFFER + attribute TRANSFORM_FEEDBACK_BUFFER_BINDING + attribute TRANSFORM_FEEDBACK_BUFFER_MODE + attribute TRANSFORM_FEEDBACK_BUFFER_SIZE + attribute TRANSFORM_FEEDBACK_BUFFER_START + attribute TRANSFORM_FEEDBACK_PAUSED + attribute TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN + attribute TRANSFORM_FEEDBACK_VARYINGS + attribute TRIANGLES + attribute TRIANGLE_FAN + attribute TRIANGLE_STRIP + attribute UNIFORM_ARRAY_STRIDE + attribute UNIFORM_BLOCK_ACTIVE_UNIFORMS + attribute UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES + attribute UNIFORM_BLOCK_BINDING + attribute UNIFORM_BLOCK_DATA_SIZE + attribute UNIFORM_BLOCK_INDEX + attribute UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER + attribute UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER + attribute UNIFORM_BUFFER + attribute UNIFORM_BUFFER_BINDING + attribute UNIFORM_BUFFER_OFFSET_ALIGNMENT + attribute UNIFORM_BUFFER_SIZE + attribute UNIFORM_BUFFER_START + attribute UNIFORM_IS_ROW_MAJOR + attribute UNIFORM_MATRIX_STRIDE + attribute UNIFORM_OFFSET + attribute UNIFORM_SIZE + attribute UNIFORM_TYPE + attribute UNPACK_ALIGNMENT + attribute UNPACK_COLORSPACE_CONVERSION_WEBGL + attribute UNPACK_FLIP_Y_WEBGL + attribute UNPACK_IMAGE_HEIGHT + attribute UNPACK_PREMULTIPLY_ALPHA_WEBGL + attribute UNPACK_ROW_LENGTH + attribute UNPACK_SKIP_IMAGES + attribute UNPACK_SKIP_PIXELS + attribute UNPACK_SKIP_ROWS + attribute UNSIGNALED + attribute UNSIGNED_BYTE + attribute UNSIGNED_INT + attribute UNSIGNED_INT_10F_11F_11F_REV + attribute UNSIGNED_INT_24_8 + attribute UNSIGNED_INT_2_10_10_10_REV + attribute UNSIGNED_INT_5_9_9_9_REV + attribute UNSIGNED_INT_SAMPLER_2D + attribute UNSIGNED_INT_SAMPLER_2D_ARRAY + attribute UNSIGNED_INT_SAMPLER_3D + attribute UNSIGNED_INT_SAMPLER_CUBE + attribute UNSIGNED_INT_VEC2 + attribute UNSIGNED_INT_VEC3 + attribute UNSIGNED_INT_VEC4 + attribute UNSIGNED_NORMALIZED + attribute UNSIGNED_SHORT + attribute UNSIGNED_SHORT_4_4_4_4 + attribute UNSIGNED_SHORT_5_5_5_1 + attribute UNSIGNED_SHORT_5_6_5 + attribute VALIDATE_STATUS + attribute VENDOR + attribute VERSION + attribute VERTEX_ARRAY_BINDING + attribute VERTEX_ATTRIB_ARRAY_BUFFER_BINDING + attribute VERTEX_ATTRIB_ARRAY_DIVISOR + attribute VERTEX_ATTRIB_ARRAY_ENABLED + attribute VERTEX_ATTRIB_ARRAY_INTEGER + attribute VERTEX_ATTRIB_ARRAY_NORMALIZED + attribute VERTEX_ATTRIB_ARRAY_POINTER + attribute VERTEX_ATTRIB_ARRAY_SIZE + attribute VERTEX_ATTRIB_ARRAY_STRIDE + attribute VERTEX_ATTRIB_ARRAY_TYPE + attribute VERTEX_SHADER + attribute VIEWPORT + attribute WAIT_FAILED + attribute ZERO + getter canvas + getter drawingBufferHeight + getter drawingBufferWidth + method activeTexture + method attachShader + method beginQuery + method beginTransformFeedback + method bindAttribLocation + method bindBuffer + method bindBufferBase + method bindBufferRange + method bindFramebuffer + method bindRenderbuffer + method bindSampler + method bindTexture + method bindTransformFeedback + method bindVertexArray + method blendColor + method blendEquation + method blendEquationSeparate + method blendFunc + method blendFuncSeparate + method blitFramebuffer + method bufferData + method bufferSubData + method checkFramebufferStatus + method clear + method clearBufferfi + method clearBufferfv + method clearBufferiv + method clearBufferuiv + method clearColor + method clearDepth + method clearStencil + method clientWaitSync + method colorMask + method compileShader + method compressedTexImage2D + method compressedTexImage3D + method compressedTexSubImage2D + method compressedTexSubImage3D + method constructor + method copyBufferSubData + method copyTexImage2D + method copyTexSubImage2D + method copyTexSubImage3D + method createBuffer + method createFramebuffer + method createProgram + method createQuery + method createRenderbuffer + method createSampler + method createShader + method createTexture + method createTransformFeedback + method createVertexArray + method cullFace + method deleteBuffer + method deleteFramebuffer + method deleteProgram + method deleteQuery + method deleteRenderbuffer + method deleteSampler + method deleteShader + method deleteSync + method deleteTexture + method deleteTransformFeedback + method deleteVertexArray + method depthFunc + method depthMask + method depthRange + method detachShader + method disable + method disableVertexAttribArray + method drawArrays + method drawArraysInstanced + method drawBuffers + method drawElements + method drawElementsInstanced + method drawRangeElements + method enable + method enableVertexAttribArray + method endQuery + method endTransformFeedback + method fenceSync + method finish + method flush + method framebufferRenderbuffer + method framebufferTexture2D + method framebufferTextureLayer + method frontFace + method generateMipmap + method getActiveAttrib + method getActiveUniform + method getActiveUniformBlockName + method getActiveUniformBlockParameter + method getActiveUniforms + method getAttachedShaders + method getAttribLocation + method getBufferParameter + method getBufferSubData + method getContextAttributes + method getError + method getExtension + method getFragDataLocation + method getFramebufferAttachmentParameter + method getIndexedParameter + method getInternalformatParameter + method getParameter + method getProgramInfoLog + method getProgramParameter + method getQuery + method getQueryParameter + method getRenderbufferParameter + method getSamplerParameter + method getShaderInfoLog + method getShaderParameter + method getShaderPrecisionFormat + method getShaderSource + method getSupportedExtensions + method getSyncParameter + method getTexParameter + method getTransformFeedbackVarying + method getUniform + method getUniformBlockIndex + method getUniformIndices + method getUniformLocation + method getVertexAttrib + method getVertexAttribOffset + method hint + method invalidateFramebuffer + method invalidateSubFramebuffer + method isBuffer + method isContextLost + method isEnabled + method isFramebuffer + method isProgram + method isQuery + method isRenderbuffer + method isSampler + method isShader + method isSync + method isTexture + method isTransformFeedback + method isVertexArray + method lineWidth + method linkProgram + method pauseTransformFeedback + method pixelStorei + method polygonOffset + method readBuffer + method readPixels + method renderbufferStorage + method renderbufferStorageMultisample + method resumeTransformFeedback + method sampleCoverage + method samplerParameterf + method samplerParameteri + method scissor + method shaderSource + method stencilFunc + method stencilFuncSeparate + method stencilMask + method stencilMaskSeparate + method stencilOp + method stencilOpSeparate + method texImage2D + method texImage3D + method texParameterf + method texParameteri + method texStorage2D + method texStorage3D + method texSubImage2D + method texSubImage3D + method transformFeedbackVaryings + method uniform1f + method uniform1fv + method uniform1i + method uniform1iv + method uniform1ui + method uniform1uiv + method uniform2f + method uniform2fv + method uniform2i + method uniform2iv + method uniform2ui + method uniform2uiv + method uniform3f + method uniform3fv + method uniform3i + method uniform3iv + method uniform3ui + method uniform3uiv + method uniform4f + method uniform4fv + method uniform4i + method uniform4iv + method uniform4ui + method uniform4uiv + method uniformBlockBinding + method uniformMatrix2fv + method uniformMatrix2x3fv + method uniformMatrix2x4fv + method uniformMatrix3fv + method uniformMatrix3x2fv + method uniformMatrix3x4fv + method uniformMatrix4fv + method uniformMatrix4x2fv + method uniformMatrix4x3fv + method useProgram + method validateProgram + method vertexAttrib1f + method vertexAttrib1fv + method vertexAttrib2f + method vertexAttrib2fv + method vertexAttrib3f + method vertexAttrib3fv + method vertexAttrib4f + method vertexAttrib4fv + method vertexAttribDivisor + method vertexAttribI4i + method vertexAttribI4iv + method vertexAttribI4ui + method vertexAttribI4uiv + method vertexAttribIPointer + method vertexAttribPointer + method viewport + method waitSync +interface WebGLActiveInfo + attribute @@toStringTag + getter name + getter size + getter type + method constructor +interface WebGLBuffer + attribute @@toStringTag + method constructor +interface WebGLContextEvent : Event + attribute @@toStringTag + getter statusMessage + method constructor +interface WebGLFramebuffer + attribute @@toStringTag + method constructor +interface WebGLProgram + attribute @@toStringTag + method constructor +interface WebGLQuery + attribute @@toStringTag + method constructor +interface WebGLRenderbuffer + attribute @@toStringTag + method constructor +interface WebGLRenderingContext + attribute @@toStringTag + attribute ACTIVE_ATTRIBUTES + attribute ACTIVE_TEXTURE + attribute ACTIVE_UNIFORMS + attribute ALIASED_LINE_WIDTH_RANGE + attribute ALIASED_POINT_SIZE_RANGE + attribute ALPHA + attribute ALPHA_BITS + attribute ALWAYS + attribute ARRAY_BUFFER + attribute ARRAY_BUFFER_BINDING + attribute ATTACHED_SHADERS + attribute BACK + attribute BLEND + attribute BLEND_COLOR + attribute BLEND_DST_ALPHA + attribute BLEND_DST_RGB + attribute BLEND_EQUATION + attribute BLEND_EQUATION_ALPHA + attribute BLEND_EQUATION_RGB + attribute BLEND_SRC_ALPHA + attribute BLEND_SRC_RGB + attribute BLUE_BITS + attribute BOOL + attribute BOOL_VEC2 + attribute BOOL_VEC3 + attribute BOOL_VEC4 + attribute BROWSER_DEFAULT_WEBGL + attribute BUFFER_SIZE + attribute BUFFER_USAGE + attribute BYTE + attribute CCW + attribute CLAMP_TO_EDGE + attribute COLOR_ATTACHMENT0 + attribute COLOR_BUFFER_BIT + attribute COLOR_CLEAR_VALUE + attribute COLOR_WRITEMASK + attribute COMPILE_STATUS + attribute COMPRESSED_TEXTURE_FORMATS + attribute CONSTANT_ALPHA + attribute CONSTANT_COLOR + attribute CONTEXT_LOST_WEBGL + attribute CULL_FACE + attribute CULL_FACE_MODE + attribute CURRENT_PROGRAM + attribute CURRENT_VERTEX_ATTRIB + attribute CW + attribute DECR + attribute DECR_WRAP + attribute DELETE_STATUS + attribute DEPTH_ATTACHMENT + attribute DEPTH_BITS + attribute DEPTH_BUFFER_BIT + attribute DEPTH_CLEAR_VALUE + attribute DEPTH_COMPONENT + attribute DEPTH_COMPONENT16 + attribute DEPTH_FUNC + attribute DEPTH_RANGE + attribute DEPTH_STENCIL + attribute DEPTH_STENCIL_ATTACHMENT + attribute DEPTH_TEST + attribute DEPTH_WRITEMASK + attribute DITHER + attribute DONT_CARE + attribute DST_ALPHA + attribute DST_COLOR + attribute DYNAMIC_DRAW + attribute ELEMENT_ARRAY_BUFFER + attribute ELEMENT_ARRAY_BUFFER_BINDING + attribute EQUAL + attribute FASTEST + attribute FLOAT + attribute FLOAT_MAT2 + attribute FLOAT_MAT3 + attribute FLOAT_MAT4 + attribute FLOAT_VEC2 + attribute FLOAT_VEC3 + attribute FLOAT_VEC4 + attribute FRAGMENT_SHADER + attribute FRAMEBUFFER + attribute FRAMEBUFFER_ATTACHMENT_OBJECT_NAME + attribute FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE + attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL + attribute FRAMEBUFFER_BINDING + attribute FRAMEBUFFER_COMPLETE + attribute FRAMEBUFFER_INCOMPLETE_ATTACHMENT + attribute FRAMEBUFFER_INCOMPLETE_DIMENSIONS + attribute FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + attribute FRAMEBUFFER_UNSUPPORTED + attribute FRONT + attribute FRONT_AND_BACK + attribute FRONT_FACE + attribute FUNC_ADD + attribute FUNC_REVERSE_SUBTRACT + attribute FUNC_SUBTRACT + attribute GENERATE_MIPMAP_HINT + attribute GEQUAL + attribute GREATER + attribute GREEN_BITS + attribute HIGH_FLOAT + attribute HIGH_INT + attribute IMPLEMENTATION_COLOR_READ_FORMAT + attribute IMPLEMENTATION_COLOR_READ_TYPE + attribute INCR + attribute INCR_WRAP + attribute INT + attribute INT_VEC2 + attribute INT_VEC3 + attribute INT_VEC4 + attribute INVALID_ENUM + attribute INVALID_FRAMEBUFFER_OPERATION + attribute INVALID_OPERATION + attribute INVALID_VALUE + attribute INVERT + attribute KEEP + attribute LEQUAL + attribute LESS + attribute LINEAR + attribute LINEAR_MIPMAP_LINEAR + attribute LINEAR_MIPMAP_NEAREST + attribute LINES + attribute LINE_LOOP + attribute LINE_STRIP + attribute LINE_WIDTH + attribute LINK_STATUS + attribute LOW_FLOAT + attribute LOW_INT + attribute LUMINANCE + attribute LUMINANCE_ALPHA + attribute MAX_COMBINED_TEXTURE_IMAGE_UNITS + attribute MAX_CUBE_MAP_TEXTURE_SIZE + attribute MAX_FRAGMENT_UNIFORM_VECTORS + attribute MAX_RENDERBUFFER_SIZE + attribute MAX_TEXTURE_IMAGE_UNITS + attribute MAX_TEXTURE_SIZE + attribute MAX_VARYING_VECTORS + attribute MAX_VERTEX_ATTRIBS + attribute MAX_VERTEX_TEXTURE_IMAGE_UNITS + attribute MAX_VERTEX_UNIFORM_VECTORS + attribute MAX_VIEWPORT_DIMS + attribute MEDIUM_FLOAT + attribute MEDIUM_INT + attribute MIRRORED_REPEAT + attribute NEAREST + attribute NEAREST_MIPMAP_LINEAR + attribute NEAREST_MIPMAP_NEAREST + attribute NEVER + attribute NICEST + attribute NONE + attribute NOTEQUAL + attribute NO_ERROR + attribute ONE + attribute ONE_MINUS_CONSTANT_ALPHA + attribute ONE_MINUS_CONSTANT_COLOR + attribute ONE_MINUS_DST_ALPHA + attribute ONE_MINUS_DST_COLOR + attribute ONE_MINUS_SRC_ALPHA + attribute ONE_MINUS_SRC_COLOR + attribute OUT_OF_MEMORY + attribute PACK_ALIGNMENT + attribute POINTS + attribute POLYGON_OFFSET_FACTOR + attribute POLYGON_OFFSET_FILL + attribute POLYGON_OFFSET_UNITS + attribute RED_BITS + attribute RENDERBUFFER + attribute RENDERBUFFER_ALPHA_SIZE + attribute RENDERBUFFER_BINDING + attribute RENDERBUFFER_BLUE_SIZE + attribute RENDERBUFFER_DEPTH_SIZE + attribute RENDERBUFFER_GREEN_SIZE + attribute RENDERBUFFER_HEIGHT + attribute RENDERBUFFER_INTERNAL_FORMAT + attribute RENDERBUFFER_RED_SIZE + attribute RENDERBUFFER_STENCIL_SIZE + attribute RENDERBUFFER_WIDTH + attribute RENDERER + attribute REPEAT + attribute REPLACE + attribute RGB + attribute RGB565 + attribute RGB5_A1 + attribute RGBA + attribute RGBA4 + attribute SAMPLER_2D + attribute SAMPLER_CUBE + attribute SAMPLES + attribute SAMPLE_ALPHA_TO_COVERAGE + attribute SAMPLE_BUFFERS + attribute SAMPLE_COVERAGE + attribute SAMPLE_COVERAGE_INVERT + attribute SAMPLE_COVERAGE_VALUE + attribute SCISSOR_BOX + attribute SCISSOR_TEST + attribute SHADER_TYPE + attribute SHADING_LANGUAGE_VERSION + attribute SHORT + attribute SRC_ALPHA + attribute SRC_ALPHA_SATURATE + attribute SRC_COLOR + attribute STATIC_DRAW + attribute STENCIL_ATTACHMENT + attribute STENCIL_BACK_FAIL + attribute STENCIL_BACK_FUNC + attribute STENCIL_BACK_PASS_DEPTH_FAIL + attribute STENCIL_BACK_PASS_DEPTH_PASS + attribute STENCIL_BACK_REF + attribute STENCIL_BACK_VALUE_MASK + attribute STENCIL_BACK_WRITEMASK + attribute STENCIL_BITS + attribute STENCIL_BUFFER_BIT + attribute STENCIL_CLEAR_VALUE + attribute STENCIL_FAIL + attribute STENCIL_FUNC + attribute STENCIL_INDEX + attribute STENCIL_INDEX8 + attribute STENCIL_PASS_DEPTH_FAIL + attribute STENCIL_PASS_DEPTH_PASS + attribute STENCIL_REF + attribute STENCIL_TEST + attribute STENCIL_VALUE_MASK + attribute STENCIL_WRITEMASK + attribute STREAM_DRAW + attribute SUBPIXEL_BITS + attribute TEXTURE + attribute TEXTURE0 + attribute TEXTURE1 + attribute TEXTURE10 + attribute TEXTURE11 + attribute TEXTURE12 + attribute TEXTURE13 + attribute TEXTURE14 + attribute TEXTURE15 + attribute TEXTURE16 + attribute TEXTURE17 + attribute TEXTURE18 + attribute TEXTURE19 + attribute TEXTURE2 + attribute TEXTURE20 + attribute TEXTURE21 + attribute TEXTURE22 + attribute TEXTURE23 + attribute TEXTURE24 + attribute TEXTURE25 + attribute TEXTURE26 + attribute TEXTURE27 + attribute TEXTURE28 + attribute TEXTURE29 + attribute TEXTURE3 + attribute TEXTURE30 + attribute TEXTURE31 + attribute TEXTURE4 + attribute TEXTURE5 + attribute TEXTURE6 + attribute TEXTURE7 + attribute TEXTURE8 + attribute TEXTURE9 + attribute TEXTURE_2D + attribute TEXTURE_BINDING_2D + attribute TEXTURE_BINDING_CUBE_MAP + attribute TEXTURE_CUBE_MAP + attribute TEXTURE_CUBE_MAP_NEGATIVE_X + attribute TEXTURE_CUBE_MAP_NEGATIVE_Y + attribute TEXTURE_CUBE_MAP_NEGATIVE_Z + attribute TEXTURE_CUBE_MAP_POSITIVE_X + attribute TEXTURE_CUBE_MAP_POSITIVE_Y + attribute TEXTURE_CUBE_MAP_POSITIVE_Z + attribute TEXTURE_MAG_FILTER + attribute TEXTURE_MIN_FILTER + attribute TEXTURE_WRAP_S + attribute TEXTURE_WRAP_T + attribute TRIANGLES + attribute TRIANGLE_FAN + attribute TRIANGLE_STRIP + attribute UNPACK_ALIGNMENT + attribute UNPACK_COLORSPACE_CONVERSION_WEBGL + attribute UNPACK_FLIP_Y_WEBGL + attribute UNPACK_PREMULTIPLY_ALPHA_WEBGL + attribute UNSIGNED_BYTE + attribute UNSIGNED_INT + attribute UNSIGNED_SHORT + attribute UNSIGNED_SHORT_4_4_4_4 + attribute UNSIGNED_SHORT_5_5_5_1 + attribute UNSIGNED_SHORT_5_6_5 + attribute VALIDATE_STATUS + attribute VENDOR + attribute VERSION + attribute VERTEX_ATTRIB_ARRAY_BUFFER_BINDING + attribute VERTEX_ATTRIB_ARRAY_ENABLED + attribute VERTEX_ATTRIB_ARRAY_NORMALIZED + attribute VERTEX_ATTRIB_ARRAY_POINTER + attribute VERTEX_ATTRIB_ARRAY_SIZE + attribute VERTEX_ATTRIB_ARRAY_STRIDE + attribute VERTEX_ATTRIB_ARRAY_TYPE + attribute VERTEX_SHADER + attribute VIEWPORT + attribute ZERO + getter canvas + getter drawingBufferHeight + getter drawingBufferWidth + method activeTexture + method attachShader + method bindAttribLocation + method bindBuffer + method bindFramebuffer + method bindRenderbuffer + method bindTexture + method blendColor + method blendEquation + method blendEquationSeparate + method blendFunc + method blendFuncSeparate + method bufferData + method bufferSubData + method checkFramebufferStatus + method clear + method clearColor + method clearDepth + method clearStencil + method colorMask + method compileShader + method compressedTexImage2D + method compressedTexSubImage2D + method constructor + method copyTexImage2D + method copyTexSubImage2D + method createBuffer + method createFramebuffer + method createProgram + method createRenderbuffer + method createShader + method createTexture + method cullFace + method deleteBuffer + method deleteFramebuffer + method deleteProgram + method deleteRenderbuffer + method deleteShader + method deleteTexture + method depthFunc + method depthMask + method depthRange + method detachShader + method disable + method disableVertexAttribArray + method drawArrays + method drawElements + method enable + method enableVertexAttribArray + method finish + method flush + method framebufferRenderbuffer + method framebufferTexture2D + method frontFace + method generateMipmap + method getActiveAttrib + method getActiveUniform + method getAttachedShaders + method getAttribLocation + method getBufferParameter + method getContextAttributes + method getError + method getExtension + method getFramebufferAttachmentParameter + method getParameter + method getProgramInfoLog + method getProgramParameter + method getRenderbufferParameter + method getShaderInfoLog + method getShaderParameter + method getShaderPrecisionFormat + method getShaderSource + method getSupportedExtensions + method getTexParameter + method getUniform + method getUniformLocation + method getVertexAttrib + method getVertexAttribOffset + method hint + method isBuffer + method isContextLost + method isEnabled + method isFramebuffer + method isProgram + method isRenderbuffer + method isShader + method isTexture + method lineWidth + method linkProgram + method pixelStorei + method polygonOffset + method readPixels + method renderbufferStorage + method sampleCoverage + method scissor + method shaderSource + method stencilFunc + method stencilFuncSeparate + method stencilMask + method stencilMaskSeparate + method stencilOp + method stencilOpSeparate + method texImage2D + method texParameterf + method texParameteri + method texSubImage2D + method uniform1f + method uniform1fv + method uniform1i + method uniform1iv + method uniform2f + method uniform2fv + method uniform2i + method uniform2iv + method uniform3f + method uniform3fv + method uniform3i + method uniform3iv + method uniform4f + method uniform4fv + method uniform4i + method uniform4iv + method uniformMatrix2fv + method uniformMatrix3fv + method uniformMatrix4fv + method useProgram + method validateProgram + method vertexAttrib1f + method vertexAttrib1fv + method vertexAttrib2f + method vertexAttrib2fv + method vertexAttrib3f + method vertexAttrib3fv + method vertexAttrib4f + method vertexAttrib4fv + method vertexAttribPointer + method viewport +interface WebGLSampler + attribute @@toStringTag + method constructor +interface WebGLShader + attribute @@toStringTag + method constructor +interface WebGLShaderPrecisionFormat + attribute @@toStringTag + getter precision + getter rangeMax + getter rangeMin + method constructor +interface WebGLSync + attribute @@toStringTag + method constructor +interface WebGLTexture + attribute @@toStringTag + method constructor +interface WebGLTransformFeedback + attribute @@toStringTag + method constructor +interface WebGLUniformLocation + attribute @@toStringTag + method constructor +interface WebGLVertexArrayObject + attribute @@toStringTag + method constructor +interface WebKitAnimationEvent : Event + attribute @@toStringTag + getter animationName + getter elapsedTime + method constructor +interface WebKitCSSMatrix + attribute @@toStringTag + getter a + getter b + getter c + getter d + getter e + getter f + getter m11 + getter m12 + getter m13 + getter m14 + getter m21 + getter m22 + getter m23 + getter m24 + getter m31 + getter m32 + getter m33 + getter m34 + getter m41 + getter m42 + getter m43 + getter m44 + method constructor + method inverse + method multiply + method rotate + method rotateAxisAngle + method scale + method setMatrixValue + method skewX + method skewY + method toString + method translate + setter a + setter b + setter c + setter d + setter e + setter f + setter m11 + setter m12 + setter m13 + setter m14 + setter m21 + setter m22 + setter m23 + setter m24 + setter m31 + setter m32 + setter m33 + setter m34 + setter m41 + setter m42 + setter m43 + setter m44 +interface WebKitMutationObserver + attribute @@toStringTag + method constructor + method disconnect + method observe + method takeRecords +interface WebKitTransitionEvent : Event + attribute @@toStringTag + getter elapsedTime + getter propertyName + getter pseudoElement + method constructor +interface WebSocket : EventTarget + attribute @@toStringTag + attribute CLOSED + attribute CLOSING + attribute CONNECTING + attribute OPEN + getter binaryType + getter bufferedAmount + getter extensions + getter onclose + getter onerror + getter onmessage + getter onopen + getter protocol + getter readyState + getter url + method close + method constructor + method send + setter binaryType + setter onclose + setter onerror + setter onmessage + setter onopen +interface WheelEvent : MouseEvent + attribute @@toStringTag + attribute DOM_DELTA_LINE + attribute DOM_DELTA_PAGE + attribute DOM_DELTA_PIXEL + getter deltaMode + getter deltaX + getter deltaY + getter deltaZ + getter wheelDelta + getter wheelDeltaX + getter wheelDeltaY + method constructor +interface Window : EventTarget + attribute @@toStringTag + attribute PERSISTENT + attribute TEMPORARY + method constructor +interface Worker : EventTarget + attribute @@toStringTag + getter onerror + getter onmessage + method constructor + method postMessage + method terminate + setter onerror + setter onmessage +interface XMLDocument : Document + attribute @@toStringTag + method constructor +interface XMLHttpRequest : XMLHttpRequestEventTarget + attribute @@toStringTag + attribute DONE + attribute HEADERS_RECEIVED + attribute LOADING + attribute OPENED + attribute UNSENT + getter onreadystatechange + getter readyState + getter response + getter responseText + getter responseType + getter responseURL + getter responseXML + getter status + getter statusText + getter timeout + getter upload + getter withCredentials + method abort + method constructor + method getAllResponseHeaders + method getResponseHeader + method open + method overrideMimeType + method send + method setRequestHeader + setter onreadystatechange + setter responseType + setter timeout + setter withCredentials +interface XMLHttpRequestEventTarget : EventTarget + attribute @@toStringTag + getter onabort + getter onerror + getter onload + getter onloadend + getter onloadstart + getter onprogress + getter ontimeout + method constructor + setter onabort + setter onerror + setter onload + setter onloadend + setter onloadstart + setter onprogress + setter ontimeout +interface XMLHttpRequestUpload : XMLHttpRequestEventTarget + attribute @@toStringTag + method constructor +interface XMLSerializer + attribute @@toStringTag + method constructor + method serializeToString +interface XPathEvaluator + attribute @@toStringTag + method constructor + method createExpression + method createNSResolver + method evaluate +interface XPathExpression + attribute @@toStringTag + method constructor + method evaluate +interface XPathResult + attribute @@toStringTag + attribute ANY_TYPE + attribute ANY_UNORDERED_NODE_TYPE + attribute BOOLEAN_TYPE + attribute FIRST_ORDERED_NODE_TYPE + attribute NUMBER_TYPE + attribute ORDERED_NODE_ITERATOR_TYPE + attribute ORDERED_NODE_SNAPSHOT_TYPE + attribute STRING_TYPE + attribute UNORDERED_NODE_ITERATOR_TYPE + attribute UNORDERED_NODE_SNAPSHOT_TYPE + getter booleanValue + getter invalidIteratorState + getter numberValue + getter resultType + getter singleNodeValue + getter snapshotLength + getter stringValue + method constructor + method iterateNext + method snapshotItem +interface XSLTProcessor + attribute @@toStringTag + method clearParameters + method constructor + method getParameter + method importStylesheet + method removeParameter + method reset + method setParameter + method transformToDocument + method transformToFragment +interface webkitMediaStream : EventTarget + attribute @@toStringTag + getter active + getter id + getter onactive + getter onaddtrack + getter oninactive + getter onremovetrack + method addTrack + method clone + method constructor + method getAudioTracks + method getTrackById + method getTracks + method getVideoTracks + method removeTrack + setter onactive + setter onaddtrack + setter oninactive + setter onremovetrack +interface webkitRTCPeerConnection : EventTarget + static method generateCertificate + attribute @@toStringTag + getter iceConnectionState + getter iceGatheringState + getter localDescription + getter onaddstream + getter ondatachannel + getter onicecandidate + getter oniceconnectionstatechange + getter onnegotiationneeded + getter onremovestream + getter onsignalingstatechange + getter remoteDescription + getter signalingState + method addIceCandidate + method addStream + method close + method constructor + method createAnswer + method createDTMFSender + method createDataChannel + method createOffer + method getLocalStreams + method getRemoteStreams + method getStats + method getStreamById + method removeStream + method setLocalDescription + method setRemoteDescription + method updateIce + setter onaddstream + setter ondatachannel + setter onicecandidate + setter oniceconnectionstatechange + setter onnegotiationneeded + setter onremovestream + setter onsignalingstatechange +interface webkitSpeechGrammar + attribute @@toStringTag + getter src + getter weight + method constructor + setter src + setter weight +interface webkitSpeechGrammarList + attribute @@toStringTag + getter length + method @@iterator + method addFromString + method addFromUri + method constructor + method item +interface webkitSpeechRecognition : EventTarget + attribute @@toStringTag + getter continuous + getter grammars + getter interimResults + getter lang + getter maxAlternatives + getter onaudioend + getter onaudiostart + getter onend + getter onerror + getter onnomatch + getter onresult + getter onsoundend + getter onsoundstart + getter onspeechend + getter onspeechstart + getter onstart + method abort + method constructor + method start + method stop + setter continuous + setter grammars + setter interimResults + setter lang + setter maxAlternatives + setter onaudioend + setter onaudiostart + setter onend + setter onerror + setter onnomatch + setter onresult + setter onsoundend + setter onsoundstart + setter onspeechend + setter onspeechstart + setter onstart +interface webkitSpeechRecognitionError : Event + attribute @@toStringTag + getter error + getter message + method constructor +interface webkitSpeechRecognitionEvent : Event + attribute @@toStringTag + getter emma + getter interpretation + getter resultIndex + getter results + method constructor +interface webkitURL + static method createObjectURL + static method revokeObjectURL + attribute @@toStringTag + getter hash + getter host + getter hostname + getter href + getter origin + getter password + getter pathname + getter port + getter protocol + getter search + getter searchParams + getter username + method constructor + method toString + setter hash + setter host + setter hostname + setter href + setter password + setter pathname + setter port + setter protocol + setter search + setter username +[GLOBAL OBJECT] + attribute GCController + attribute accessibilityController + attribute chrome + attribute closed + attribute console + attribute eventSender + attribute frames + attribute gamepadController + attribute internals + attribute layoutTestController + attribute length + attribute location + attribute mojo + attribute opener + attribute parent + attribute propertyNamesInGlobal + attribute self + attribute testRunner + attribute textInputController + attribute top + attribute window + getter applicationCache + getter caches + getter clientInformation + getter crypto + getter customElements + getter defaultStatus + getter defaultstatus + getter devicePixelRatio + getter document + getter event + getter external + getter frameElement + getter history + getter indexedDB + getter innerHeight + getter innerWidth + getter isSecureContext + getter localStorage + getter locationbar + getter menubar + getter name + getter navigator + getter offscreenBuffering + getter onabort + getter onanimationend + getter onanimationiteration + getter onanimationstart + getter onauxclick + getter onbeforeunload + getter onblur + getter oncancel + getter oncanplay + getter oncanplaythrough + getter onchange + getter onclick + getter onclose + getter oncontextmenu + getter oncuechange + getter ondblclick + getter ondevicemotion + getter ondeviceorientation + getter ondeviceorientationabsolute + getter ondrag + getter ondragend + getter ondragenter + getter ondragleave + getter ondragover + getter ondragstart + getter ondrop + getter ondurationchange + getter onemptied + getter onended + getter onerror + getter onfocus + getter ongotpointercapture + getter onhashchange + getter oninput + getter oninvalid + getter onkeydown + getter onkeypress + getter onkeyup + getter onlanguagechange + getter onload + getter onloadeddata + getter onloadedmetadata + getter onloadstart + getter onlostpointercapture + getter onmessage + getter onmousedown + getter onmouseenter + getter onmouseleave + getter onmousemove + getter onmouseout + getter onmouseover + getter onmouseup + getter onmousewheel + getter onoffline + getter ononline + getter onpagehide + getter onpageshow + getter onpause + getter onplay + getter onplaying + getter onpointercancel + getter onpointerdown + getter onpointerenter + getter onpointerleave + getter onpointermove + getter onpointerout + getter onpointerover + getter onpointerup + getter onpopstate + getter onprogress + getter onratechange + getter onrejectionhandled + getter onreset + getter onresize + getter onscroll + getter onsearch + getter onseeked + getter onseeking + getter onselect + getter onshow + getter onstalled + getter onstorage + getter onsubmit + getter onsuspend + getter ontimeupdate + getter ontoggle + getter ontouchcancel + getter ontouchend + getter ontouchmove + getter ontouchstart + getter ontransitionend + getter onunhandledrejection + getter onunload + getter onvolumechange + getter onwaiting + getter onwebkitanimationend + getter onwebkitanimationiteration + getter onwebkitanimationstart + getter onwebkittransitionend + getter onwheel + getter outerHeight + getter outerWidth + getter pageXOffset + getter pageYOffset + getter performance + getter personalbar + getter screen + getter screenLeft + getter screenTop + getter screenX + getter screenY + getter scrollX + getter scrollY + getter scrollbars + getter sessionStorage + getter speechSynthesis + getter status + getter statusbar + getter styleMedia + getter toolbar + getter webkitStorageInfo + method alert + method atob + method blur + method btoa + method cancelAnimationFrame + method cancelIdleCallback + method captureEvents + method clearInterval + method clearTimeout + method close + method confirm + method createImageBitmap + method fetch + method find + method focus + method gc + method getComputedStyle + method getMatchedCSSRules + method getSelection + method matchMedia + method moveBy + method moveTo + method open + method openDatabase + method postMessage + method print + method prompt + method releaseEvents + method requestAnimationFrame + method requestIdleCallback + method resizeBy + method resizeTo + method scroll + method scrollBy + method scrollTo + method setInterval + method setTimeout + method stop + method webkitCancelAnimationFrame + method webkitRequestAnimationFrame + method webkitRequestFileSystem + method webkitResolveLocalFileSystemURL + setter clientInformation + setter defaultStatus + setter defaultstatus + setter devicePixelRatio + setter event + setter external + setter innerHeight + setter innerWidth + setter locationbar + setter menubar + setter name + setter offscreenBuffering + setter onabort + setter onanimationend + setter onanimationiteration + setter onanimationstart + setter onauxclick + setter onbeforeunload + setter onblur + setter oncancel + setter oncanplay + setter oncanplaythrough + setter onchange + setter onclick + setter onclose + setter oncontextmenu + setter oncuechange + setter ondblclick + setter ondevicemotion + setter ondeviceorientation + setter ondeviceorientationabsolute + setter ondrag + setter ondragend + setter ondragenter + setter ondragleave + setter ondragover + setter ondragstart + setter ondrop + setter ondurationchange + setter onemptied + setter onended + setter onerror + setter onfocus + setter ongotpointercapture + setter onhashchange + setter oninput + setter oninvalid + setter onkeydown + setter onkeypress + setter onkeyup + setter onlanguagechange + setter onload + setter onloadeddata + setter onloadedmetadata + setter onloadstart + setter onlostpointercapture + setter onmessage + setter onmousedown + setter onmouseenter + setter onmouseleave + setter onmousemove + setter onmouseout + setter onmouseover + setter onmouseup + setter onmousewheel + setter onoffline + setter ononline + setter onpagehide + setter onpageshow + setter onpause + setter onplay + setter onplaying + setter onpointercancel + setter onpointerdown + setter onpointerenter + setter onpointerleave + setter onpointermove + setter onpointerout + setter onpointerover + setter onpointerup + setter onpopstate + setter onprogress + setter onratechange + setter onrejectionhandled + setter onreset + setter onresize + setter onscroll + setter onsearch + setter onseeked + setter onseeking + setter onselect + setter onshow + setter onstalled + setter onstorage + setter onsubmit + setter onsuspend + setter ontimeupdate + setter ontoggle + setter ontouchcancel + setter ontouchend + setter ontouchmove + setter ontouchstart + setter ontransitionend + setter onunhandledrejection + setter onunload + setter onvolumechange + setter onwaiting + setter onwebkitanimationend + setter onwebkitanimationiteration + setter onwebkitanimationstart + setter onwebkittransitionend + setter onwheel + setter outerHeight + setter outerWidth + setter pageXOffset + setter pageYOffset + setter performance + setter personalbar + setter screen + setter screenLeft + setter screenTop + setter screenX + setter screenY + setter scrollX + setter scrollY + setter scrollbars + setter status + setter statusbar + setter toolbar +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt index 81547ce..cbe49a8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -90,23 +90,20 @@ method copyFromChannel method copyToChannel method getChannelData -interface AudioBufferSourceNode : AudioSourceNode +interface AudioBufferSourceNode : AudioScheduledSourceNode attribute @@toStringTag getter buffer getter detune getter loop getter loopEnd getter loopStart - getter onended getter playbackRate method constructor method start - method stop setter buffer setter loop setter loopEnd setter loopStart - setter onended interface AudioContext : BaseAudioContext attribute @@toStringTag method close @@ -165,6 +162,13 @@ getter outputBuffer getter playbackTime method constructor +interface AudioScheduledSourceNode : AudioNode + attribute @@toStringTag + getter onended + method constructor + method start + method stop + setter onended interface BarProp attribute @@toStringTag getter visible @@ -551,14 +555,10 @@ getter data method constructor method initCompositionEvent -interface ConstantSourceNode : AudioSourceNode +interface ConstantSourceNode : AudioScheduledSourceNode attribute @@toStringTag getter offset - getter onended method constructor - method start - method stop - setter onended interface ConvolverNode : AudioNode attribute @@toStringTag getter buffer @@ -3613,17 +3613,13 @@ setter oncomplete interface Option method constructor -interface OscillatorNode : AudioSourceNode +interface OscillatorNode : AudioScheduledSourceNode attribute @@toStringTag getter detune getter frequency - getter onended getter type method constructor method setPeriodicWave - method start - method stop - setter onended setter type interface PageTransitionEvent : Event attribute @@toStringTag
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt index f51814d..49a5ead 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -90,23 +90,20 @@ method copyFromChannel method copyToChannel method getChannelData -interface AudioBufferSourceNode : AudioSourceNode +interface AudioBufferSourceNode : AudioScheduledSourceNode attribute @@toStringTag getter buffer getter detune getter loop getter loopEnd getter loopStart - getter onended getter playbackRate method constructor method start - method stop setter buffer setter loop setter loopEnd setter loopStart - setter onended interface AudioContext : BaseAudioContext attribute @@toStringTag method close @@ -165,6 +162,13 @@ getter outputBuffer getter playbackTime method constructor +interface AudioScheduledSourceNode : AudioNode + attribute @@toStringTag + getter onended + method constructor + method start + method stop + setter onended interface BarProp attribute @@toStringTag getter visible @@ -612,14 +616,10 @@ getter data method constructor method initCompositionEvent -interface ConstantSourceNode : AudioSourceNode +interface ConstantSourceNode : AudioScheduledSourceNode attribute @@toStringTag getter offset - getter onended method constructor - method start - method stop - setter onended interface ConvolverNode : AudioNode attribute @@toStringTag getter buffer @@ -3675,17 +3675,13 @@ setter oncomplete interface Option method constructor -interface OscillatorNode : AudioSourceNode +interface OscillatorNode : AudioScheduledSourceNode attribute @@toStringTag getter detune getter frequency - getter onended getter type method constructor method setPeriodicWave - method start - method stop - setter onended setter type interface PageTransitionEvent : Event attribute @@toStringTag
diff --git a/third_party/WebKit/LayoutTests/webaudio/Analyser/realtimeanalyser-basic-expected.txt b/third_party/WebKit/LayoutTests/webaudio/Analyser/realtimeanalyser-basic-expected.txt deleted file mode 100644 index 8ac523a..0000000 --- a/third_party/WebKit/LayoutTests/webaudio/Analyser/realtimeanalyser-basic-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -Basic tests for AnalyserNode. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -PASS AnalyserNode has one input. -PASS AnalyserNode has one output. -PASS minDecibels default value is -100. -PASS maxDecibels default value is -30. -PASS smoothingTimeConstant default value is 0.8. -PASS minDecibels value is set to -50.333333333333336. -PASS maxDecibels value is set to -40.333333333333336. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/webaudio/Analyser/realtimeanalyser-basic.html b/third_party/WebKit/LayoutTests/webaudio/Analyser/realtimeanalyser-basic.html index b790bb2..49322d2 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Analyser/realtimeanalyser-basic.html +++ b/third_party/WebKit/LayoutTests/webaudio/Analyser/realtimeanalyser-basic.html
@@ -1,75 +1,55 @@ <!DOCTYPE html> <html> <head> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> +<script src="../resources/audit.js"></script> </head> <body> -<div id="description"></div> -<div id="console"></div> <script> -description("Basic tests for AnalyserNode."); var context = 0; -function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } +var audit = Audit.createTaskRunner(); - window.jsTestIsAsync = true; - +audit.define("Basic AnalyserNode test", function (task, should) { context = new AudioContext(); var analyser = context.createAnalyser(); - if (analyser.numberOfInputs === 1) - testPassed("AnalyserNode has one input."); - else - testFailed("AnalyserNode should have one input, not " + analyser.numberOfInputs + "."); + should(analyser.numberOfInputs, "Number of inputs for AnalyserNode") + .beEqualTo(1); - if (analyser.numberOfOutputs === 1) - testPassed("AnalyserNode has one output."); - else - testFailed("AnalyserNode should have one output."); + should(analyser.numberOfOutputs, "Number of outputs for AnalyserNode") + .beEqualTo(1); - if (analyser.minDecibels === -100) - testPassed("minDecibels default value is -100."); - else - testFailed("minDecibels default value should be -100."); + should(analyser.minDecibels, "Default minDecibels value") + .beEqualTo(-100); - if (analyser.maxDecibels === -30) - testPassed("maxDecibels default value is -30."); - else - testFailed("maxDecibels default value should be -30."); + should(analyser.maxDecibels, "Default maxDecibels value") + .beEqualTo(-30); - if (analyser.smoothingTimeConstant === 0.8) - testPassed("smoothingTimeConstant default value is 0.8."); - else - testFailed("smoothingTimeConstant default value should be 0.8."); - + should(analyser.smoothingTimeConstant, "Default smoothingTimeConstant value") + .beEqualTo(0.8); + var expectedValue = -50 - (1/3); analyser.minDecibels = expectedValue; - if (analyser.minDecibels === expectedValue) - testPassed("minDecibels value is set to " + expectedValue + ".") - else - testFailed("minDecibels value should be set to " + expectedValue + ", not " + analyser.minDecibels + "."); + + should(analyser.minDecibels, "node.minDecibels = " + expectedValue) + .beEqualTo(expectedValue); expectedValue = -40 - (1/3); analyser.maxDecibels = expectedValue; - if (analyser.maxDecibels === expectedValue) - testPassed("maxDecibels value is set to " + expectedValue + ".") - else - testFailed("maxDecibels value should be set to " + expectedValue + ", not " + analyser.maxDecibels + "."); - finishJSTest(); -} + should(analyser.maxDecibels, "node.maxDecibels = " + expectedValue) + .beEqualTo(expectedValue); -runTest(); + task.done(); +}); +audit.run(); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/audio-scheduled-source-basic.html b/third_party/WebKit/LayoutTests/webaudio/audio-scheduled-source-basic.html new file mode 100644 index 0000000..5fa8268 --- /dev/null +++ b/third_party/WebKit/LayoutTests/webaudio/audio-scheduled-source-basic.html
@@ -0,0 +1,69 @@ +<!doctype html> +<html> + <head> + <title>Test AudioScheduledSourceNode</title> + <script src="../resources/testharness.js"></script> + <script src="../resources/testharnessreport.js"></script> + <script src="resources/audit.js"></script> + </head> + + <body> + <script> + var context = new AudioContext(); + + var audit = Audit.createTaskRunner(); + + audit.define("construction", function (task, should) { + task.describe("Construct AudioScheduledSourceNode"); + should(function () { + return new AudioScheduledSourceNode(context); + }, "new AudioScheduledSourceNode(c)").throw("TypeError"); + + task.done(); + }); + + audit.define("properties", function (task, should) { + task.describe("Test properties on derived nodes"); + var expectedProperties = ["start", "stop", "onended"]; + + // AudioScheduledSourceNode must have these properties. + for (p in expectedProperties) { + should(AudioScheduledSourceNode.prototype.hasOwnProperty( + expectedProperties[p]), + "AudioScheduledSourceNode." + expectedProperties[p]) + .beTrue(); + } + + // ConstantSource and Oscillator must not + var nodes = ["ConstantSourceNode", "OscillatorNode"]; + for (n in nodes) { + for (p in expectedProperties) { + should(window[nodes[n]].prototype.hasOwnProperty( + expectedProperties[p]), + nodes[n] + "." + expectedProperties[p]) + .beFalse(); + } + } + + // AudioBufferSourceNode has it's own start method, but should not have + // the others. + for (p in expectedProperties) { + if (expectedProperties[p] !== "start") { + should(AudioBufferSourceNode.prototype.hasOwnProperty( + expectedProperties[p]), + "AudioBufferSourceNode." + expectedProperties[p]) + .beFalse(); + } + } + + should(AudioBufferSourceNode.prototype.hasOwnProperty("start"), + "AudioBufferSourceNode.start") + .beTrue(); + + task.done(); + }); + + audit.run(); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt index 50f0802..0924a86 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt
@@ -107,10 +107,10 @@ PASS source.start(1, 1, -1) threw exception InvalidStateError: Failed to execute 'start' on 'AudioBufferSourceNode': The duration provided (-1) is less than the minimum bound (0).. PASS source.start(1, 1, -Number.MIN_VALUE) threw exception InvalidStateError: Failed to execute 'start' on 'AudioBufferSourceNode': The duration provided (-4.94066e-324) is less than the minimum bound (0).. PASS source.start() did not throw exception. -PASS source.stop(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'stop' on 'AudioBufferSourceNode': The stop time provided (-4.94066e-324) is less than the minimum bound (0).. -PASS source.stop(Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.stop(-Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioBufferSourceNode': The provided double value is non-finite.. -PASS source.stop(NaN) threw exception TypeError: Failed to execute 'stop' on 'AudioBufferSourceNode': The provided double value is non-finite.. +PASS source.stop(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The stop time provided (-4.94066e-324) is less than the minimum bound (0).. +PASS source.stop(Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. +PASS source.stop(-Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. +PASS source.stop(NaN) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. PASS source.stop() did not throw exception. PASS source = context.createBufferSource() did not throw exception. PASS source.buffer = buffer did not throw exception. @@ -122,7 +122,7 @@ PASS source.start() did not throw exception. PASS source = context.createBufferSource() did not throw exception. PASS source.buffer = buffer did not throw exception. -PASS source.stop() threw exception InvalidStateError: Failed to execute 'stop' on 'AudioBufferSourceNode': cannot call stop without calling start first.. +PASS source.stop() threw exception InvalidStateError: Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first.. PASS source = context.createBufferSource() did not throw exception. PASS source.buffer = buffer did not throw exception. PASS source.start() did not throw exception. @@ -132,18 +132,18 @@ PASS source.start() did not throw exception. PASS source.stop() did not throw exception. PASS source = context.createOscillator() did not throw exception. -PASS source.start(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'start' on 'OscillatorNode': The start time provided (-4.94066e-324) is less than the minimum bound (0).. -PASS source.start(Infinity) threw exception TypeError: Failed to execute 'start' on 'OscillatorNode': The provided double value is non-finite.. -PASS source.start(-Infinity) threw exception TypeError: Failed to execute 'start' on 'OscillatorNode': The provided double value is non-finite.. -PASS source.start(NaN) threw exception TypeError: Failed to execute 'start' on 'OscillatorNode': The provided double value is non-finite.. +PASS source.start(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'start' on 'AudioScheduledSourceNode': The start time provided (-4.94066e-324) is less than the minimum bound (0).. +PASS source.start(Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.. +PASS source.start(-Infinity) threw exception TypeError: Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.. +PASS source.start(NaN) threw exception TypeError: Failed to execute 'start' on 'AudioScheduledSourceNode': The provided double value is non-finite.. PASS source.start() did not throw exception. -PASS source.stop(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'stop' on 'OscillatorNode': The stop time provided (-4.94066e-324) is less than the minimum bound (0).. -PASS source.stop(Infinity) threw exception TypeError: Failed to execute 'stop' on 'OscillatorNode': The provided double value is non-finite.. -PASS source.stop(-Infinity) threw exception TypeError: Failed to execute 'stop' on 'OscillatorNode': The provided double value is non-finite.. -PASS source.stop(NaN) threw exception TypeError: Failed to execute 'stop' on 'OscillatorNode': The provided double value is non-finite.. +PASS source.stop(-Number.MIN_VALUE) threw exception InvalidAccessError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The stop time provided (-4.94066e-324) is less than the minimum bound (0).. +PASS source.stop(Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. +PASS source.stop(-Infinity) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. +PASS source.stop(NaN) threw exception TypeError: Failed to execute 'stop' on 'AudioScheduledSourceNode': The provided double value is non-finite.. PASS source.stop() did not throw exception. PASS osc = context.createOscillator() did not throw exception. -PASS osc.stop() threw exception InvalidStateError: Failed to execute 'stop' on 'OscillatorNode': cannot call stop without calling start first.. +PASS osc.stop() threw exception InvalidStateError: Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first.. PASS osc1 = context.createOscillator() did not throw exception. PASS osc1.start() did not throw exception. PASS osc1.stop() did not throw exception.
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 2ee1e54..6afc7a9f 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -155,23 +155,20 @@ method copyFromChannel method copyToChannel method getChannelData -interface AudioBufferSourceNode : AudioSourceNode +interface AudioBufferSourceNode : AudioScheduledSourceNode attribute @@toStringTag getter buffer getter detune getter loop getter loopEnd getter loopStart - getter onended getter playbackRate method constructor method start - method stop setter buffer setter loop setter loopEnd setter loopStart - setter onended interface AudioContext : BaseAudioContext attribute @@toStringTag method close @@ -230,6 +227,13 @@ getter outputBuffer getter playbackTime method constructor +interface AudioScheduledSourceNode : AudioNode + attribute @@toStringTag + getter onended + method constructor + method start + method stop + setter onended interface AudioTrack attribute @@toStringTag getter enabled @@ -902,14 +906,10 @@ method terminate setter onerror setter onmessage -interface ConstantSourceNode : AudioSourceNode +interface ConstantSourceNode : AudioScheduledSourceNode attribute @@toStringTag getter offset - getter onended method constructor - method start - method stop - setter onended interface ConvolverNode : AudioNode attribute @@toStringTag getter buffer @@ -4431,17 +4431,13 @@ setter strokeStyle interface Option method constructor -interface OscillatorNode : AudioSourceNode +interface OscillatorNode : AudioScheduledSourceNode attribute @@toStringTag getter detune getter frequency - getter onended getter type method constructor method setPeriodicWave - method start - method stop - setter onended setter type interface PageTransitionEvent : Event attribute @@toStringTag
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8CSSStyleDeclarationCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8CSSStyleDeclarationCustom.cpp index 14e7e7f1..0eaf581 100644 --- a/third_party/WebKit/Source/bindings/core/v8/custom/V8CSSStyleDeclarationCustom.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8CSSStyleDeclarationCustom.cpp
@@ -229,7 +229,7 @@ info.GetIsolate(), ExceptionState::SetterContext, "CSSStyleDeclaration", getPropertyName(resolveCSSPropertyID(unresolvedProperty))); impl->setPropertyInternal(unresolvedProperty, String(), propertyValue, false, - exceptionState); + nullptr, exceptionState); v8SetReturnValue(info, value); }
diff --git a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py index aeba875..96f60c5 100755 --- a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py +++ b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
@@ -104,6 +104,13 @@ type_path = property['field_storage_type'] type_name = type_path.split('/')[-1] + # For now, the getter name should match the field name. Later, getter names + # will start with an uppercase letter, so if they conflict with the type name, + # add 'get' to the front. + getter_method_name = property_name_lower + if type_name == property_name: + getter_method_name = 'get' + property_name + assert property['initial_keyword'] is not None, \ ('MakeComputedStyleBase requires an initial keyword for keyword_only values, none specified ' 'for property ' + property['name']) @@ -139,7 +146,7 @@ storage_type_path=type_path, size=int(math.ceil(bits_needed)), default_value=default_value, - getter_method_name=property_name_lower, + getter_method_name=getter_method_name, setter_method_name='set' + property_name, initial_method_name='initial' + property_name, resetter_method_name='reset' + property_name,
diff --git a/third_party/WebKit/Source/core/animation/AnimationTimeline.h b/third_party/WebKit/Source/core/animation/AnimationTimeline.h index 534d9fe5..e49f50d 100644 --- a/third_party/WebKit/Source/core/animation/AnimationTimeline.h +++ b/third_party/WebKit/Source/core/animation/AnimationTimeline.h
@@ -36,6 +36,7 @@ #include "core/animation/Animation.h" #include "core/animation/EffectModel.h" #include "core/dom/Element.h" +#include "core/dom/TaskRunnerHelper.h" #include "platform/Timer.h" #include "platform/animation/CompositorAnimationTimeline.h" #include "platform/heap/Handle.h" @@ -138,7 +139,10 @@ public: AnimationTimelineTiming(AnimationTimeline* timeline) : m_timeline(timeline), - m_timer(this, &AnimationTimelineTiming::timerFired) { + m_timer(TaskRunnerHelper::get(TaskType::UnspecedTimer, + timeline->document()), + this, + &AnimationTimelineTiming::timerFired) { DCHECK(m_timeline); } @@ -151,7 +155,7 @@ private: Member<AnimationTimeline> m_timeline; - Timer<AnimationTimelineTiming> m_timer; + TaskRunnerTimer<AnimationTimelineTiming> m_timer; }; friend class AnimationAnimationTimelineTest;
diff --git a/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h b/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h index 82e14763..22fd6c5 100644 --- a/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h +++ b/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h
@@ -33,6 +33,7 @@ #include "core/CoreExport.h" #include "core/animation/Animation.h" +#include "core/dom/TaskRunnerHelper.h" #include "platform/Timer.h" #include "platform/heap/Handle.h" #include "wtf/Vector.h" @@ -47,8 +48,10 @@ class CORE_EXPORT CompositorPendingAnimations final : public GarbageCollectedFinalized<CompositorPendingAnimations> { public: - CompositorPendingAnimations() - : m_timer(this, &CompositorPendingAnimations::timerFired), + explicit CompositorPendingAnimations(Document& document) + : m_timer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &document), + this, + &CompositorPendingAnimations::timerFired), m_compositorGroup(1) {} void add(Animation*); @@ -65,7 +68,7 @@ HeapVector<Member<Animation>> m_pending; HeapVector<Member<Animation>> m_waitingForCompositorAnimationStart; - Timer<CompositorPendingAnimations> m_timer; + TaskRunnerTimer<CompositorPendingAnimations> m_timer; int m_compositorGroup; };
diff --git a/third_party/WebKit/Source/core/animation/EffectInput.cpp b/third_party/WebKit/Source/core/animation/EffectInput.cpp index 5109041b..fca7e3a 100644 --- a/third_party/WebKit/Source/core/animation/EffectInput.cpp +++ b/third_party/WebKit/Source/core/animation/EffectInput.cpp
@@ -95,8 +95,9 @@ if (cssProperty != CSSPropertyInvalid) { MutableStylePropertySet::SetResult setResult = cssProperty == CSSPropertyVariable - ? keyframe.setCSSPropertyValue(AtomicString(property), value, - styleSheetContents) + ? keyframe.setCSSPropertyValue( + AtomicString(property), element.document().propertyRegistry(), + value, styleSheetContents) : keyframe.setCSSPropertyValue(cssProperty, value, styleSheetContents); if (!setResult.didParse && executionContext) {
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp index d4c8d72..420eafc 100644 --- a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp +++ b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
@@ -24,10 +24,11 @@ MutableStylePropertySet::SetResult StringKeyframe::setCSSPropertyValue( const AtomicString& propertyName, + const PropertyRegistry* registry, const String& value, StyleSheetContents* styleSheetContents) { bool isAnimationTainted = true; - return m_cssPropertyMap->setProperty(propertyName, value, false, + return m_cssPropertyMap->setProperty(propertyName, registry, value, false, styleSheetContents, isAnimationTainted); }
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.h b/third_party/WebKit/Source/core/animation/StringKeyframe.h index d4cd862..d60c92da 100644 --- a/third_party/WebKit/Source/core/animation/StringKeyframe.h +++ b/third_party/WebKit/Source/core/animation/StringKeyframe.h
@@ -24,6 +24,7 @@ MutableStylePropertySet::SetResult setCSSPropertyValue( const AtomicString& propertyName, + const PropertyRegistry*, const String& value, StyleSheetContents*); MutableStylePropertySet::SetResult setCSSPropertyValue(CSSPropertyID,
diff --git a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp index 560cdf9..58fc779 100644 --- a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp +++ b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
@@ -515,7 +515,8 @@ return false; } -void CSSComputedStyleDeclaration::setProperty(const String& name, +void CSSComputedStyleDeclaration::setProperty(const ExecutionContext*, + const String& name, const String&, const String&, ExceptionState& exceptionState) { @@ -555,6 +556,7 @@ const String&, const String&, bool, + const ExecutionContext*, ExceptionState& exceptionState) { // TODO(leviw): This code is currently unreachable, but shouldn't be. exceptionState.throwDOMException(
diff --git a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h index 9a67d5d..e66487b 100644 --- a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h +++ b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h
@@ -87,7 +87,8 @@ String getPropertyPriority(const String& propertyName) override; String getPropertyShorthand(const String& propertyName) override; bool isPropertyImplicit(const String& propertyName) override; - void setProperty(const String& propertyName, + void setProperty(const ExecutionContext*, + const String& propertyName, const String& value, const String& priority, ExceptionState&) override; @@ -104,6 +105,7 @@ const String& customPropertyName, const String& value, bool important, + const ExecutionContext*, ExceptionState&) override; bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const override;
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in index 08076e6..a7fda17e 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.in +++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -179,7 +179,7 @@ -webkit-locale inherited, font, custom_value text-orientation inherited, custom_value, type_name=TextOrientation -webkit-text-orientation inherited, custom_value, type_name=TextOrientation -writing-mode inherited, custom_value, type_name=WritingMode +writing-mode inherited, custom_value, type_name=WritingMode, keyword_only, keywords=[horizontal-tb|vertical-rl|vertical-lr], initial_keyword=horizontal-tb, field_storage_type=platform/text/WritingMode -webkit-writing-mode inherited, custom_value, type_name=WritingMode text-rendering inherited, font, type_name=TextRenderingMode zoom custom_all
diff --git a/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h b/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h index e86d46f..bc136ce 100644 --- a/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h +++ b/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h
@@ -34,6 +34,7 @@ class CSSStyleSheet; class CSSValue; class ExceptionState; +class ExecutionContext; class CORE_EXPORT CSSStyleDeclaration : public GarbageCollectedFinalized<CSSStyleDeclaration>, @@ -47,7 +48,7 @@ virtual CSSRule* parentRule() const = 0; String cssFloat() { return getPropertyValueInternal(CSSPropertyFloat); } void setCSSFloat(const String& value, ExceptionState& exceptionState) { - setPropertyInternal(CSSPropertyFloat, String(), value, false, + setPropertyInternal(CSSPropertyFloat, String(), value, false, nullptr, exceptionState); } virtual String cssText() const = 0; @@ -58,7 +59,8 @@ virtual String getPropertyPriority(const String& propertyName) = 0; virtual String getPropertyShorthand(const String& propertyName) = 0; virtual bool isPropertyImplicit(const String& propertyName) = 0; - virtual void setProperty(const String& propertyName, + virtual void setProperty(const ExecutionContext*, + const String& propertyName, const String& value, const String& priority, ExceptionState&) = 0; @@ -78,6 +80,7 @@ const String& propertyValue, const String& value, bool important, + const ExecutionContext*, ExceptionState&) = 0; virtual bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const = 0;
diff --git a/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl b/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl index 630aea050..4621a07 100644 --- a/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl +++ b/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl
@@ -31,7 +31,7 @@ DOMString getPropertyPriority(DOMString property); // TODO(foolip): The value and priority arguments should have // [TreatNullAs=EmptyString] and should not be nullable. - [CEReactions, RaisesException] void setProperty(DOMString property, DOMString? value, optional DOMString? priority = null); + [CallWith=ExecutionContext, CEReactions, RaisesException] void setProperty(DOMString property, DOMString? value, optional DOMString? priority = null); // void setPropertyValue(DOMString property, [TreatNullAs=EmptyString] DOMString value); // void setPropertyPriority(DOMString property, [TreatNullAs=EmptyString] DOMString priority); [CEReactions, RaisesException] DOMString removeProperty(DOMString property);
diff --git a/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp b/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp index c119692..46c90a4 100644 --- a/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp +++ b/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp
@@ -46,8 +46,9 @@ MutableStylePropertySet* dummyStyle = MutableStylePropertySet::create(HTMLStandardMode); bool isAnimationTainted = false; - return CSSParser::parseValueForCustomProperty( - dummyStyle, "--valid", value, false, nullptr, isAnimationTainted) + return CSSParser::parseValueForCustomProperty(dummyStyle, "--valid", + nullptr, value, false, + nullptr, isAnimationTainted) .didParse; }
diff --git a/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp b/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp index 59fd3ae..e740ba1 100644 --- a/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp +++ b/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp
@@ -235,6 +235,7 @@ } void AbstractPropertySetCSSStyleDeclaration::setProperty( + const ExecutionContext* executionContext, const String& propertyName, const String& value, const String& priority, @@ -248,7 +249,7 @@ return; setPropertyInternal(propertyID, propertyName, value, important, - exceptionState); + executionContext, exceptionState); } String AbstractPropertySetCSSStyleDeclaration::removeProperty( @@ -298,18 +299,24 @@ const String& customPropertyName, const String& value, bool important, + const ExecutionContext* executionContext, ExceptionState&) { StyleAttributeMutationScope mutationScope(this); willMutate(); bool didChange = false; if (unresolvedProperty == CSSPropertyVariable) { + AtomicString atomicName(customPropertyName); + + DCHECK(executionContext); + const PropertyRegistry* registry = + toDocument(executionContext)->propertyRegistry(); + bool isAnimationTainted = isKeyframeStyle(); - didChange = - propertySet() - .setProperty(AtomicString(customPropertyName), value, important, - contextStyleSheet(), isAnimationTainted) - .didChange; + didChange = propertySet() + .setProperty(atomicName, registry, value, important, + contextStyleSheet(), isAnimationTainted) + .didChange; } else { didChange = propertySet() .setProperty(unresolvedProperty, value, important,
diff --git a/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h b/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h index ebd03ac9..d35e397 100644 --- a/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h +++ b/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h
@@ -53,7 +53,8 @@ String getPropertyPriority(const String& propertyName) final; String getPropertyShorthand(const String& propertyName) final; bool isPropertyImplicit(const String& propertyName) final; - void setProperty(const String& propertyName, + void setProperty(const ExecutionContext*, + const String& propertyName, const String& value, const String& priority, ExceptionState&) final; @@ -70,6 +71,7 @@ const String& customPropertyName, const String& value, bool important, + const ExecutionContext*, ExceptionState&) final; bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const final;
diff --git a/third_party/WebKit/Source/core/css/StylePropertySet.cpp b/third_party/WebKit/Source/core/css/StylePropertySet.cpp index 3f1e388..2446f3f 100644 --- a/third_party/WebKit/Source/core/css/StylePropertySet.cpp +++ b/third_party/WebKit/Source/core/css/StylePropertySet.cpp
@@ -322,6 +322,7 @@ MutableStylePropertySet::SetResult MutableStylePropertySet::setProperty( const AtomicString& customPropertyName, + const PropertyRegistry* registry, const String& value, bool important, StyleSheetContents* contextStyleSheet, @@ -331,9 +332,9 @@ bool didChange = removeProperty(customPropertyName); return MutableStylePropertySet::SetResult{didParse, didChange}; } - return CSSParser::parseValueForCustomProperty(this, customPropertyName, value, - important, contextStyleSheet, - isAnimationTainted); + return CSSParser::parseValueForCustomProperty( + this, customPropertyName, registry, value, important, contextStyleSheet, + isAnimationTainted); } void MutableStylePropertySet::setProperty(CSSPropertyID propertyID,
diff --git a/third_party/WebKit/Source/core/css/StylePropertySet.h b/third_party/WebKit/Source/core/css/StylePropertySet.h index edf15327..f4a3bbd7 100644 --- a/third_party/WebKit/Source/core/css/StylePropertySet.h +++ b/third_party/WebKit/Source/core/css/StylePropertySet.h
@@ -38,6 +38,7 @@ class CSSStyleDeclaration; class ImmutableStylePropertySet; class MutableStylePropertySet; +class PropertyRegistry; class StyleSheetContents; class CORE_EXPORT StylePropertySet @@ -234,6 +235,7 @@ bool important = false, StyleSheetContents* contextStyleSheet = 0); SetResult setProperty(const AtomicString& customPropertyName, + const PropertyRegistry*, const String& value, bool important, StyleSheetContents* contextStyleSheet,
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSParser.cpp index a6f4e2c..b0c557b 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSParser.cpp
@@ -109,6 +109,7 @@ MutableStylePropertySet::SetResult CSSParser::parseValueForCustomProperty( MutableStylePropertySet* declaration, const AtomicString& propertyName, + const PropertyRegistry* registry, const String& value, bool important, StyleSheetContents* styleSheet, @@ -125,8 +126,9 @@ context = styleSheet->parserContext(); context.setMode(parserMode); } - return CSSParserImpl::parseVariableValue( - declaration, propertyName, value, important, context, isAnimationTainted); + return CSSParserImpl::parseVariableValue(declaration, propertyName, registry, + value, important, context, + isAnimationTainted); } ImmutableStylePropertySet* CSSParser::parseCustomPropertySet(
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParser.h b/third_party/WebKit/Source/core/css/parser/CSSParser.h index 7c30d08..2c67b87 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParser.h +++ b/third_party/WebKit/Source/core/css/parser/CSSParser.h
@@ -57,6 +57,7 @@ static MutableStylePropertySet::SetResult parseValueForCustomProperty( MutableStylePropertySet*, const AtomicString& propertyName, + const PropertyRegistry*, const String& value, bool important, StyleSheetContents*,
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp index 1e64f1bbf..56c252ed 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
@@ -8,6 +8,7 @@ #include "core/css/CSSCustomPropertyDeclaration.h" #include "core/css/CSSKeyframesRule.h" #include "core/css/CSSStyleSheet.h" +#include "core/css/PropertyRegistry.h" #include "core/css/StyleRuleImport.h" #include "core/css/StyleRuleKeyframe.h" #include "core/css/StyleRuleNamespace.h" @@ -68,6 +69,7 @@ MutableStylePropertySet::SetResult CSSParserImpl::parseVariableValue( MutableStylePropertySet* declaration, const AtomicString& propertyName, + const PropertyRegistry* registry, const String& value, bool important, const CSSParserContext& context, @@ -79,6 +81,17 @@ bool didParse = false; bool didChange = false; if (!parser.m_parsedProperties.isEmpty()) { + if (registry) { + const PropertyRegistry::Registration* registration = + registry->registration(propertyName); + // TODO(timloh): This is a bit wasteful, we parse the registered property + // to validate but throw away the result. + if (registration && + !registration->syntax().parse(tokenizer.tokenRange(), + isAnimationTainted)) { + return MutableStylePropertySet::SetResult{didParse, didChange}; + } + } didParse = true; didChange = declaration->addParsedProperties(parser.m_parsedProperties); }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h index d15da94..219ab0d 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h +++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h
@@ -66,6 +66,7 @@ static MutableStylePropertySet::SetResult parseVariableValue( MutableStylePropertySet*, const AtomicString& propertyName, + const PropertyRegistry*, const String&, bool important, const CSSParserContext&,
diff --git a/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp b/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp index c81f41d..259dfd10 100644 --- a/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp +++ b/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp
@@ -35,6 +35,7 @@ #include "core/dom/Document.h" #include "core/dom/ExecutionContext.h" #include "core/dom/StyleEngine.h" +#include "core/dom/TaskRunnerHelper.h" #include "core/frame/LocalFrame.h" #include "core/loader/FrameLoaderClient.h" #include "core/style/StyleRareNonInheritedData.h" @@ -47,6 +48,7 @@ CSSSelectorWatch::CSSSelectorWatch(Document& document) : m_document(document), m_callbackSelectorChangeTimer( + TaskRunnerHelper::get(TaskType::UnspecedTimer, &document), this, &CSSSelectorWatch::callbackSelectorChangeTimerFired), m_timerExpirations(0) {}
diff --git a/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h b/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h index e7aec51..d4261e220 100644 --- a/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h +++ b/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
@@ -80,7 +80,7 @@ HashSet<String> m_addedSelectors; HashSet<String> m_removedSelectors; - Timer<CSSSelectorWatch> m_callbackSelectorChangeTimer; + TaskRunnerTimer<CSSSelectorWatch> m_callbackSelectorChangeTimer; // When an element is reparented, the new location's style is evaluated after // the expriation of the relayout timer. We don't want to send redundant
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 5270a912..8cc5f7d6 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -482,7 +482,7 @@ this, &Document::elementDataCacheClearTimerFired), m_timeline(DocumentTimeline::create(this)), - m_compositorPendingAnimations(new CompositorPendingAnimations()), + m_compositorPendingAnimations(new CompositorPendingAnimations(*this)), m_templateDocumentHost(nullptr), m_didAssociateFormControlsTimer( TaskRunnerHelper::get(TaskType::UnspecedLoading, this), @@ -6449,6 +6449,10 @@ return m_propertyRegistry; } +const PropertyRegistry* Document::propertyRegistry() const { + return const_cast<Document*>(this)->propertyRegistry(); +} + void Document::incrementPasswordCount() { ++m_passwordCount; if (isSecureContext() || m_passwordCount != 1) {
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index d7adbbb..b6d44994 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1295,6 +1295,7 @@ void maybeRecordLoadReason(WouldLoadReason); WouldLoadReason wouldLoadReason() { return m_wouldLoadReason; } + const PropertyRegistry* propertyRegistry() const; PropertyRegistry* propertyRegistry(); // Indicates whether the user has interacted with this particular Document.
diff --git a/third_party/WebKit/Source/core/editing/VisiblePositionTest.cpp b/third_party/WebKit/Source/core/editing/VisiblePositionTest.cpp index 84464d11..b1a6cc0 100644 --- a/third_party/WebKit/Source/core/editing/VisiblePositionTest.cpp +++ b/third_party/WebKit/Source/core/editing/VisiblePositionTest.cpp
@@ -89,13 +89,14 @@ Position position(paragraph->firstChild(), 1); VisiblePosition visiblePosition1 = createVisiblePosition(position); - div->style()->setProperty("color", "red", "important", ASSERT_NO_EXCEPTION); + div->style()->setProperty(nullptr, "color", "red", "important", + ASSERT_NO_EXCEPTION); EXPECT_FALSE(visiblePosition1.isValid()); updateAllLifecyclePhases(); VisiblePosition visiblePosition2 = createVisiblePosition(position); - div->style()->setProperty("display", "none", "important", + div->style()->setProperty(nullptr, "display", "none", "important", ASSERT_NO_EXCEPTION); EXPECT_FALSE(visiblePosition2.isValid());
diff --git a/third_party/WebKit/Source/core/editing/commands/RemoveCSSPropertyCommand.cpp b/third_party/WebKit/Source/core/editing/commands/RemoveCSSPropertyCommand.cpp index 99183c7..80ebee59c 100644 --- a/third_party/WebKit/Source/core/editing/commands/RemoveCSSPropertyCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/RemoveCSSPropertyCommand.cpp
@@ -57,12 +57,12 @@ // script. Setting to null string removes the property. We don't have internal // version of removeProperty. m_element->style()->setPropertyInternal(m_property, String(), String(), false, - IGNORE_EXCEPTION); + nullptr, IGNORE_EXCEPTION); } void RemoveCSSPropertyCommand::doUnapply() { - m_element->style()->setPropertyInternal(m_property, String(), m_oldValue, - m_important, IGNORE_EXCEPTION); + m_element->style()->setPropertyInternal( + m_property, String(), m_oldValue, m_important, nullptr, IGNORE_EXCEPTION); } DEFINE_TRACE(RemoveCSSPropertyCommand) {
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp index 13c1cbd..7ce49a30 100644 --- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -687,13 +687,17 @@ // Mutate using the CSSOM wrapper so we get the same event behavior as a // script. - if (isEnclosingBlock(element)) - element->style()->setPropertyInternal( - CSSPropertyDisplay, String(), "inline", false, IGNORE_EXCEPTION); + if (isEnclosingBlock(element)) { + element->style()->setPropertyInternal(CSSPropertyDisplay, String(), + "inline", false, nullptr, + IGNORE_EXCEPTION); + } if (element->layoutObject() && - element->layoutObject()->style()->isFloating()) + element->layoutObject()->style()->isFloating()) { element->style()->setPropertyInternal(CSSPropertyFloat, String(), - "none", false, IGNORE_EXCEPTION); + "none", false, nullptr, + IGNORE_EXCEPTION); + } } } }
diff --git a/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp b/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp index 6423c14..b3911cc 100644 --- a/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp
@@ -359,11 +359,11 @@ } if (isHorizontal()) { - m_mover->style()->setProperty("width", "-webkit-max-content", "important", - ASSERT_NO_EXCEPTION); + m_mover->style()->setProperty(nullptr, "width", "-webkit-max-content", + "important", ASSERT_NO_EXCEPTION); } else { - m_mover->style()->setProperty("height", "-webkit-max-content", "important", - ASSERT_NO_EXCEPTION); + m_mover->style()->setProperty(nullptr, "height", "-webkit-max-content", + "important", ASSERT_NO_EXCEPTION); } CSSStyleDeclaration* moverStyle = document().domWindow()->getComputedStyle(m_mover, String()); @@ -374,11 +374,9 @@ metrics.marqueeHeight = marqueeStyle->getPropertyValue("height").toDouble(); if (isHorizontal()) { - m_mover->style()->setProperty("width", "", "important", - ASSERT_NO_EXCEPTION); + m_mover->style()->removeProperty("width", ASSERT_NO_EXCEPTION); } else { - m_mover->style()->setProperty("height", "", "important", - ASSERT_NO_EXCEPTION); + m_mover->style()->removeProperty("height", ASSERT_NO_EXCEPTION); } return metrics;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp index af1227e..fc61883 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
@@ -118,8 +118,8 @@ CSSStyleRule* rule = toCSSStyleRule(styleSheet->item(0)); CSSStyleDeclaration* style = rule->style(); DummyExceptionStateForTesting exceptionState; - style->setProperty(longhand, newValue, style->getPropertyPriority(longhand), - exceptionState); + style->setProperty(nullptr, longhand, newValue, + style->getPropertyPriority(longhand), exceptionState); return style->getPropertyValue(shorthand); }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp index 7a7d3894..d5748a61 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -1753,6 +1753,15 @@ addStyleRelatedMainThreadScrollingReasons( MainThreadScrollingReason::kHasOpacity); } + if (layer->compositesWithTransform()) { + addStyleRelatedMainThreadScrollingReasons( + MainThreadScrollingReason::kHasTransform); + } + if (!layer->backgroundIsKnownToBeOpaqueInRect( + toLayoutBox(layer->layoutObject())->paddingBoxRect())) { + addStyleRelatedMainThreadScrollingReasons( + MainThreadScrollingReason::kBackgroundNotOpaqueInRect); + } return false; }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index 4c749de..db2929cb 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -813,7 +813,7 @@ textAlign() != other.textAlign() || textTransform() != other.textTransform() || direction() != other.direction() || whiteSpace() != other.whiteSpace() || - m_inheritedData.m_writingMode != other.m_inheritedData.m_writingMode) + getWritingMode() != other.getWritingMode()) return true; if (m_nonInheritedData.m_overflowX != other.m_nonInheritedData.m_overflowX ||
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index f2bca7d9..4ed124a 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -201,8 +201,7 @@ return (m_hasSimpleUnderline == other.m_hasSimpleUnderline) && (m_cursorStyle == other.m_cursorStyle) && (m_rtlOrdering == other.m_rtlOrdering) && - (m_insideLink == other.m_insideLink) && - (m_writingMode == other.m_writingMode); + (m_insideLink == other.m_insideLink); } bool operator!=(const InheritedData& other) const { @@ -212,15 +211,10 @@ unsigned m_hasSimpleUnderline : 1; // True if 'underline solid' is the only // text decoration on this element. unsigned m_cursorStyle : 6; // ECursor - // 32 bits // non CSS2 inherited unsigned m_rtlOrdering : 1; // EOrder unsigned m_insideLink : 2; // EInsideLink - - // CSS Text Layout Module Level 3: Vertical writing support - unsigned m_writingMode : 2; // WritingMode - // 42 bits } m_inheritedData; // don't inherit @@ -313,7 +307,6 @@ m_inheritedData.m_cursorStyle = static_cast<unsigned>(initialCursor()); m_inheritedData.m_rtlOrdering = static_cast<unsigned>(initialRTLOrdering()); m_inheritedData.m_insideLink = NotInsideLink; - m_inheritedData.m_writingMode = static_cast<unsigned>(initialWritingMode()); m_nonInheritedData.m_effectiveDisplay = m_nonInheritedData.m_originalDisplay = @@ -2192,15 +2185,6 @@ } void setLineBreak(LineBreak b) { SET_VAR(m_rareInheritedData, lineBreak, b); } - // writing-mode (aka -webkit-writing-mode, -epub-writing-mode) - static WritingMode initialWritingMode() { return WritingMode::HorizontalTb; } - WritingMode getWritingMode() const { - return static_cast<WritingMode>(m_inheritedData.m_writingMode); - } - void setWritingMode(WritingMode v) { - m_inheritedData.m_writingMode = static_cast<unsigned>(v); - } - // Text emphasis properties. static TextEmphasisFill initialTextEmphasisFill() { return TextEmphasisFillFilled;
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js index 4830cc7..ab85581 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js
@@ -5,9 +5,13 @@ * @unrestricted */ Accessibility.AXTreePane = class extends Accessibility.AccessibilitySubPane { - constructor() { + /** + * @param {!Accessibility.AccessibilitySidebarView} axSidebarView + */ + constructor(axSidebarView) { super(Common.UIString('Accessibility Tree')); + this._axSidebarView = axSidebarView; this._treeOutline = this.createTreeOutline(); this.element.classList.add('accessibility-computed'); @@ -77,6 +81,21 @@ } /** + * @param {!Accessibility.AccessibilityNode} axNode + */ + setSelectedNode(axNode) { + if (axNode.parentNode()) { + Common.Revealer.reveal(axNode.deferredDOMNode()); + } else { + // Only set the node for the accessibility panel, not the Elements tree. + var axSidebarView = this._axSidebarView; + axNode.deferredDOMNode().resolve((node) => { + axSidebarView.setNode(node); + }); + } + } + + /** * @param {boolean} selectedByUser */ setSelectedByUser(selectedByUser) { @@ -137,7 +156,7 @@ */ _handleMouseDown(event) { this._treePane.setSelectedByUser(true); - Common.Revealer.reveal(this._axNode.deferredDOMNode()); + this._treePane.setSelectedNode(this._axNode); } }; @@ -205,7 +224,7 @@ inspectDOMNode() { this._treePane.setSelectedByUser(true); - Common.Revealer.reveal(this._axNode.deferredDOMNode()); + this._treePane.setSelectedNode(this._axNode); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js index bac6c27..7e5c82ed 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
@@ -10,7 +10,7 @@ this._node = null; this._axNode = null; this._sidebarPaneStack = UI.viewManager.createStackLocation(); - this._treeSubPane = new Accessibility.AXTreePane(); + this._treeSubPane = new Accessibility.AXTreePane(this); this._sidebarPaneStack.showView(this._treeSubPane); this._ariaSubPane = new Accessibility.ARIAAttributesPane(); this._sidebarPaneStack.showView(this._ariaSubPane); @@ -29,6 +29,14 @@ } /** + * @param {?SDK.DOMNode} node + */ + setNode(node) { + this._node = node; + this.update(); + } + + /** * @param {?Accessibility.AccessibilityNode} axNode */ accessibilityNodeCallback(axNode) { @@ -98,8 +106,7 @@ } _pullNode() { - this._node = UI.context.flavor(SDK.DOMNode); - this.update(); + this.setNode(UI.context.flavor(SDK.DOMNode)); } /**
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni index 6aee552..7cc1858 100644 --- a/third_party/WebKit/Source/modules/modules_idl_files.gni +++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -279,6 +279,7 @@ "webaudio/AudioNode.idl", "webaudio/AudioParam.idl", "webaudio/AudioProcessingEvent.idl", + "webaudio/AudioScheduledSourceNode.idl", "webaudio/AudioSourceNode.idl", "webaudio/AudioWorkletGlobalScope.idl", "webaudio/BaseAudioContext.idl",
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.cpp b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.cpp index 4826d3d..4241c6b7 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.cpp
@@ -605,7 +605,7 @@ // If looping was ever done (m_didSetLooping = true), give up. We can't // easily determine how long we looped so we don't know the actual duration // thus far, so don't try to do anything fancy. - if (!m_didSetLooping && buffer() && isPlayingOrScheduled() && + if (!didSetLooping() && buffer() && isPlayingOrScheduled() && m_minPlaybackRate > 0) { // Adjust the duration to include the playback rate. Only need to account // for rate < 1 which makes the sound last longer. For rate >= 1, the
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.h b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.h index 16b15388..2d2739a 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.h
@@ -83,7 +83,7 @@ bool loop() const { return m_isLooping; } void setLoop(bool looping) { m_isLooping = looping; - m_didSetLooping = m_didSetLooping || looping; + setDidSetLooping(looping); } // Loop times in seconds. @@ -133,6 +133,12 @@ RefPtr<AudioParamHandler> m_playbackRate; RefPtr<AudioParamHandler> m_detune; + bool didSetLooping() const { return acquireLoad(&m_didSetLooping); } + void setDidSetLooping(bool loop) { + bool newLooping = didSetLooping() || loop; + releaseStore(&m_didSetLooping, newLooping); + } + // If m_isLooping is false, then this node will be done playing and become // inactive after it reaches the end of the sample data in the buffer. If // true, it will wrap around to the start of the buffer each time it reaches @@ -140,7 +146,7 @@ bool m_isLooping; // True if the source .loop attribute was ever set. - bool m_didSetLooping; + int m_didSetLooping; double m_loopStart; double m_loopEnd;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.idl b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.idl index b2454cb3..269553eb 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.idl
@@ -29,9 +29,10 @@ Constructor(BaseAudioContext context, optional AudioBufferSourceOptions options), RaisesException=Constructor, ActiveScriptWrappable, + DependentLifetime, Measure ] -interface AudioBufferSourceNode : AudioSourceNode { +interface AudioBufferSourceNode : AudioScheduledSourceNode { [RaisesException=Setter] attribute AudioBuffer buffer; readonly attribute AudioParam playbackRate; @@ -41,8 +42,6 @@ attribute double loopStart; attribute double loopEnd; - [RaisesException] void start(optional double when, optional double grainOffset, optional double grainDuration); - [RaisesException] void stop(optional double when); + [RaisesException] void start(optional double when = 0, optional double grainOffset, optional double grainDuration); - attribute EventHandler onended; };
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.cpp b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.cpp index 0ce6f640..5146ef3 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.cpp
@@ -237,7 +237,7 @@ // ---------------------------------------------------------------- AudioScheduledSourceNode::AudioScheduledSourceNode(BaseAudioContext& context) - : AudioSourceNode(context) {} + : AudioNode(context) {} AudioScheduledSourceHandler& AudioScheduledSourceNode::audioScheduledSourceHandler() const {
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.h b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.h index ac491cb8..f56919f 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.h
@@ -30,7 +30,7 @@ #define AudioScheduledSourceNode_h #include "bindings/core/v8/ActiveScriptWrappable.h" -#include "modules/webaudio/AudioSourceNode.h" +#include "modules/webaudio/AudioNode.h" namespace blink { @@ -125,9 +125,10 @@ }; class AudioScheduledSourceNode - : public AudioSourceNode, + : public AudioNode, public ActiveScriptWrappable<AudioScheduledSourceNode> { USING_GARBAGE_COLLECTED_MIXIN(AudioScheduledSourceNode); + DEFINE_WRAPPERTYPEINFO(); public: void start(ExceptionState&); @@ -141,7 +142,7 @@ // ScriptWrappable: bool hasPendingActivity() const final; - DEFINE_INLINE_VIRTUAL_TRACE() { AudioSourceNode::trace(visitor); } + DEFINE_INLINE_VIRTUAL_TRACE() { AudioNode::trace(visitor); } protected: explicit AudioScheduledSourceNode(BaseAudioContext&);
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.idl b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.idl new file mode 100644 index 0000000..adc0ab90 --- /dev/null +++ b/third_party/WebKit/Source/modules/webaudio/AudioScheduledSourceNode.idl
@@ -0,0 +1,14 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// See https://webaudio.github.io/web-audio-api/ +[ + ActiveScriptWrappable, + DependentLifetime +] +interface AudioScheduledSourceNode : AudioNode { + [RaisesException] void start(optional double when); + [RaisesException] void stop(optional double when); + attribute EventHandler onended; +};
diff --git a/third_party/WebKit/Source/modules/webaudio/ConstantSourceNode.idl b/third_party/WebKit/Source/modules/webaudio/ConstantSourceNode.idl index e99a9ccc..b281ad2c6 100644 --- a/third_party/WebKit/Source/modules/webaudio/ConstantSourceNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/ConstantSourceNode.idl
@@ -7,11 +7,9 @@ Constructor(BaseAudioContext context, optional ConstantSourceOptions options), RaisesException=Constructor, ActiveScriptWrappable, + DependentLifetime, Measure ] -interface ConstantSourceNode : AudioSourceNode { +interface ConstantSourceNode : AudioScheduledSourceNode { readonly attribute AudioParam offset; - [RaisesException] void start(optional double when); - [RaisesException] void stop(optional double when); - attribute EventHandler onended; };
diff --git a/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp index d1b7bee0..7cf0fd3 100644 --- a/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp
@@ -78,9 +78,9 @@ float hardwareSampleRate = AudioDestination::hardwareSampleRate(); VLOG(1) << ">>>> hardwareSampleRate = " << hardwareSampleRate; - m_destination = AudioDestination::create( - *this, m_inputDeviceId, m_numberOfInputChannels, channelCount(), - hardwareSampleRate, context()->getSecurityOrigin()); + m_destination = + AudioDestination::create(*this, channelCount(), hardwareSampleRate, + context()->getSecurityOrigin()); } void DefaultAudioDestinationHandler::startRendering() {
diff --git a/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl b/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl index 117e4ddb..1f3e3052 100644 --- a/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl +++ b/third_party/WebKit/Source/modules/webaudio/OscillatorNode.idl
@@ -36,20 +36,14 @@ [ Constructor(BaseAudioContext context, optional OscillatorOptions options), RaisesException=Constructor, - ActiveScriptWrappable, Measure ] -interface OscillatorNode : AudioSourceNode { +interface OscillatorNode : AudioScheduledSourceNode { [RaisesException=Setter] attribute OscillatorType type; readonly attribute AudioParam frequency; // in Hertz readonly attribute AudioParam detune; // in Cents - [RaisesException] void start(optional double when); - [RaisesException] void stop(optional double when); - void setPeriodicWave(PeriodicWave periodicWave); - - attribute EventHandler onended; };
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 6935bf30..995b3f9 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1906,6 +1906,7 @@ ":blink_common", ":platform", "//third_party/WebKit/Source/wtf", + "//ui/gfx:test_support", ] configs += [
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in index 1e60d01..81891910 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -222,7 +222,7 @@ ShapeDetection status=experimental SharedArrayBuffer SharedWorker status=stable -SlimmingPaintInvalidation implied_by=SlimmingPaintV2 +SlimmingPaintInvalidation implied_by=SlimmingPaintV2, status=experimental SlimmingPaintV2 SlimmingPaintStrictCullRectClipping // Used as argument in attribute of stable-release functions/interfaces where
diff --git a/third_party/WebKit/Source/platform/audio/AudioDestination.cpp b/third_party/WebKit/Source/platform/audio/AudioDestination.cpp index 7244418..dcf0ea58 100644 --- a/third_party/WebKit/Source/platform/audio/AudioDestination.cpp +++ b/third_party/WebKit/Source/platform/audio/AudioDestination.cpp
@@ -29,7 +29,6 @@ #include "platform/audio/AudioDestination.h" #include "platform/Histogram.h" -#include "platform/audio/AudioFIFO.h" #include "platform/audio/AudioPullFIFO.h" #include "platform/audio/AudioUtilities.h" #include "platform/weborigin/SecurityOrigin.h" @@ -40,138 +39,71 @@ namespace blink { -// Size of the FIFO -const size_t fifoSize = 8192; +// FIFO Size. +// +// TODO(hongchan): This was estimated based on the largest callback buffer size +// that we would ever need. The current UMA stats indicates that this is, in +// fact, probably too small. There are Android devices out there with a size of +// 8000 or so. We might need to make this larger. See: crbug.com/670747 +const size_t kFIFOSize = 8192; -// Factory method: Chromium-implementation std::unique_ptr<AudioDestination> AudioDestination::create( AudioIOCallback& callback, - const String& inputDeviceId, - unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate, PassRefPtr<SecurityOrigin> securityOrigin) { return WTF::wrapUnique(new AudioDestination( - callback, inputDeviceId, numberOfInputChannels, numberOfOutputChannels, - sampleRate, std::move(securityOrigin))); + callback, numberOfOutputChannels, sampleRate, std::move(securityOrigin))); } AudioDestination::AudioDestination(AudioIOCallback& callback, - const String& inputDeviceId, - unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate, PassRefPtr<SecurityOrigin> securityOrigin) - : m_callback(callback), - m_numberOfOutputChannels(numberOfOutputChannels), - m_renderBus(AudioBus::create(numberOfOutputChannels, - AudioUtilities::kRenderQuantumFrames, - false)), + : m_numberOfOutputChannels(numberOfOutputChannels), m_sampleRate(sampleRate), m_isPlaying(false), - m_framesElapsed(0), - m_outputPosition() { - // Histogram for audioHardwareBufferSize - DEFINE_STATIC_LOCAL(SparseHistogram, hardwareBufferSizeHistogram, - ("WebAudio.AudioDestination.HardwareBufferSize")); - // Histogram for the actual callback size used. Typically, this is the same - // as audioHardwareBufferSize, but can be adjusted depending on some - // heuristics below. - DEFINE_STATIC_LOCAL(SparseHistogram, callbackBufferSizeHistogram, - ("WebAudio.AudioDestination.CallbackBufferSize")); + m_callback(callback), + m_outputBus(AudioBus::create(numberOfOutputChannels, + AudioUtilities::kRenderQuantumFrames, + false)), + m_framesElapsed(0) { + // Calculate the optimum buffer size first. + if (calculateBufferSize()) { + // Create WebAudioDevice. blink::WebAudioDevice is designed to support the + // local input (e.g. loopback from OS audio system), but Chromium's media + // renderer does not support it currently. Thus, we use zero for the number + // of input channels. + m_webAudioDevice = WTF::wrapUnique(Platform::current()->createAudioDevice( + m_callbackBufferSize, 0, numberOfOutputChannels, sampleRate, this, + String(), std::move(securityOrigin))); + DCHECK(m_webAudioDevice); - // Use the optimal buffer size recommended by the audio backend. - size_t recommendedHardwareBufferSize = - Platform::current()->audioHardwareBufferSize(); - m_callbackBufferSize = recommendedHardwareBufferSize; - -#if OS(ANDROID) - // The optimum low-latency hardware buffer size is usually too small on - // Android for WebAudio to render without glitching. So, if it is small, use - // a larger size. If it was already large, use the requested size. - // - // Since WebAudio renders in 128-frame blocks, the small buffer sizes (144 - // for a Galaxy Nexus), cause significant processing jitter. Sometimes - // multiple blocks will processed, but other times will not be since the FIFO - // can satisfy the request. By using a larger callbackBufferSize, we smooth - // out the jitter. - const size_t kSmallBufferSize = 1024; - const size_t kDefaultCallbackBufferSize = 2048; - - if (m_callbackBufferSize <= kSmallBufferSize) - m_callbackBufferSize = kDefaultCallbackBufferSize; - - LOG(INFO) << "audioHardwareBufferSize = " << recommendedHardwareBufferSize; - LOG(INFO) << "callbackBufferSize = " << m_callbackBufferSize; -#endif - - // Quick exit if the requested size is too large. - DCHECK_LE(m_callbackBufferSize + AudioUtilities::kRenderQuantumFrames, - fifoSize); - if (m_callbackBufferSize + AudioUtilities::kRenderQuantumFrames > fifoSize) - return; - - m_audioDevice = WTF::wrapUnique(Platform::current()->createAudioDevice( - m_callbackBufferSize, numberOfInputChannels, numberOfOutputChannels, - sampleRate, this, inputDeviceId, std::move(securityOrigin))); - ASSERT(m_audioDevice); - - // Record the sizes if we successfully created an output device. - hardwareBufferSizeHistogram.sample(recommendedHardwareBufferSize); - callbackBufferSizeHistogram.sample(m_callbackBufferSize); - - // Create a FIFO to handle the possibility of the callback size - // not being a multiple of the render size. If the FIFO already - // contains enough data, the data will be provided directly. - // Otherwise, the FIFO will call the provider enough times to - // satisfy the request for data. - m_fifo = - WTF::wrapUnique(new AudioPullFIFO(*this, numberOfOutputChannels, fifoSize, - AudioUtilities::kRenderQuantumFrames)); + // Create a FIFO. + m_fifo = WTF::wrapUnique( + new AudioPullFIFO(*this, numberOfOutputChannels, kFIFOSize, + AudioUtilities::kRenderQuantumFrames)); + } else { + NOTREACHED(); + } } AudioDestination::~AudioDestination() { stop(); } -void AudioDestination::start() { - if (!m_isPlaying && m_audioDevice) { - m_audioDevice->start(); - m_isPlaying = true; - } -} - -void AudioDestination::stop() { - if (m_isPlaying && m_audioDevice) { - m_audioDevice->stop(); - m_isPlaying = false; - } -} - -float AudioDestination::hardwareSampleRate() { - return static_cast<float>(Platform::current()->audioHardwareSampleRate()); -} - -unsigned long AudioDestination::maxChannelCount() { - return static_cast<float>(Platform::current()->audioHardwareOutputChannels()); -} - -void AudioDestination::render(const WebVector<float*>& audioData, +void AudioDestination::render(const WebVector<float*>& destinationData, size_t numberOfFrames, double delay, double delayTimestamp, size_t priorFramesSkipped) { - bool isNumberOfChannelsGood = audioData.size() == m_numberOfOutputChannels; - if (!isNumberOfChannelsGood) { - ASSERT_NOT_REACHED(); + DCHECK_EQ(destinationData.size(), m_numberOfOutputChannels); + if (destinationData.size() != m_numberOfOutputChannels) return; - } - bool isBufferSizeGood = numberOfFrames == m_callbackBufferSize; - if (!isBufferSizeGood) { - ASSERT_NOT_REACHED(); + DCHECK_EQ(numberOfFrames, m_callbackBufferSize); + if (numberOfFrames != m_callbackBufferSize) return; - } m_framesElapsed -= std::min(m_framesElapsed, priorFramesSkipped); double outputPosition = @@ -180,18 +112,20 @@ m_outputPosition.timestamp = delayTimestamp; m_outputPositionReceivedTimestamp = base::TimeTicks::Now(); + // Associate the destination data array with the output bus then fill the + // FIFO. for (unsigned i = 0; i < m_numberOfOutputChannels; ++i) - m_renderBus->setChannelMemory(i, audioData[i], numberOfFrames); - - m_fifo->consume(m_renderBus.get(), numberOfFrames); + m_outputBus->setChannelMemory(i, destinationData[i], numberOfFrames); + m_fifo->consume(m_outputBus.get(), numberOfFrames); m_framesElapsed += numberOfFrames; } -void AudioDestination::provideInput(AudioBus* bus, size_t framesToProcess) { +void AudioDestination::provideInput(AudioBus* outputBus, + size_t framesToProcess) { AudioIOPosition outputPosition = m_outputPosition; - // If platfrom buffer is more than two times longer than |framesToProcess| + // If platform buffer is more than two times longer than |framesToProcess| // we do not want output position to get stuck so we promote it // using the elapsed time from the moment it was initially obtained. if (m_callbackBufferSize > framesToProcess * 2) { @@ -206,7 +140,81 @@ if (outputPosition.position < 0.0) outputPosition.position = 0.0; - m_callback.render(nullptr, bus, framesToProcess, outputPosition); + // To fill the FIFO, start the render call chain of the destination node. + m_callback.render(nullptr, outputBus, framesToProcess, outputPosition); +} + +void AudioDestination::start() { + if (m_webAudioDevice && !m_isPlaying) { + m_webAudioDevice->start(); + m_isPlaying = true; + } +} + +void AudioDestination::stop() { + if (m_webAudioDevice && m_isPlaying) { + m_webAudioDevice->stop(); + m_isPlaying = false; + } +} + +size_t AudioDestination::hardwareBufferSize() { + return Platform::current()->audioHardwareBufferSize(); +} + +float AudioDestination::hardwareSampleRate() { + return static_cast<float>(Platform::current()->audioHardwareSampleRate()); +} + +unsigned long AudioDestination::maxChannelCount() { + return static_cast<unsigned long>( + Platform::current()->audioHardwareOutputChannels()); +} + +bool AudioDestination::calculateBufferSize() { + // Use the optimal buffer size recommended by the audio backend. + size_t recommendedHardwareBufferSize = hardwareBufferSize(); + m_callbackBufferSize = recommendedHardwareBufferSize; + +#if OS(ANDROID) + // The optimum low-latency hardware buffer size is usually too small on + // Android for WebAudio to render without glitching. So, if it is small, use a + // larger size. If it was already large, use the requested size. + // + // Since WebAudio renders in 128-frame blocks, the small buffer sizes (144 for + // a Galaxy Nexus), cause significant processing jitter. Sometimes multiple + // blocks will processed, but other times will not be since the FIFO can + // satisfy the request. By using a larger callbackBufferSize, we smooth out + // the jitter. + const size_t kSmallBufferSize = 1024; + const size_t kDefaultCallbackBufferSize = 2048; + + if (m_callbackBufferSize <= kSmallBufferSize) + m_callbackBufferSize = kDefaultCallbackBufferSize; + + LOG(INFO) << "audioHardwareBufferSize = " << recommendedHardwareBufferSize; + LOG(INFO) << "callbackBufferSize = " << m_callbackBufferSize; +#endif + + // Histogram for audioHardwareBufferSize + DEFINE_STATIC_LOCAL(SparseHistogram, hardwareBufferSizeHistogram, + ("WebAudio.AudioDestination.HardwareBufferSize")); + + // Histogram for the actual callback size used. Typically, this is the same + // as audioHardwareBufferSize, but can be adjusted depending on some + // heuristics below. + DEFINE_STATIC_LOCAL(SparseHistogram, callbackBufferSizeHistogram, + ("WebAudio.AudioDestination.CallbackBufferSize")); + + // Record the sizes if we successfully created an output device. + hardwareBufferSizeHistogram.sample(recommendedHardwareBufferSize); + callbackBufferSizeHistogram.sample(m_callbackBufferSize); + + // Check if the requested buffer size is too large. + bool isBufferSizeValid = + m_callbackBufferSize + AudioUtilities::kRenderQuantumFrames <= kFIFOSize; + DCHECK(isBufferSizeValid); + return isBufferSizeValid; } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/audio/AudioDestination.h b/third_party/WebKit/Source/platform/audio/AudioDestination.h index f1d13c3..d0e35b8 100644 --- a/third_party/WebKit/Source/platform/audio/AudioDestination.h +++ b/third_party/WebKit/Source/platform/audio/AudioDestination.h
@@ -36,7 +36,6 @@ #include "public/platform/WebVector.h" #include "wtf/Allocator.h" #include "wtf/Noncopyable.h" -#include "wtf/PassRefPtr.h" #include "wtf/text/WTFString.h" #include <memory> @@ -45,8 +44,10 @@ class AudioPullFIFO; class SecurityOrigin; -// An AudioDestination using Chromium's audio system - +// The AudioDestination class is an audio sink interface between the media +// renderer and the Blink's WebAudio module. It has a FIFO to adapt the +// different processing block sizes of WebAudio renderer and actual hardware +// audio callback. class PLATFORM_EXPORT AudioDestination : public WebAudioDevice::RenderCallback, public AudioSourceProvider { USING_FAST_MALLOC(AudioDestination); @@ -54,66 +55,61 @@ public: AudioDestination(AudioIOCallback&, - const String& inputDeviceId, - unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate, PassRefPtr<SecurityOrigin>); ~AudioDestination() override; - // Pass in (numberOfInputChannels > 0) if live/local audio input is desired. - // Port-specific device identification information for live/local input - // streams can be passed in the inputDeviceId. static std::unique_ptr<AudioDestination> create( AudioIOCallback&, - const String& inputDeviceId, - unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate, PassRefPtr<SecurityOrigin>); - virtual void start(); - virtual void stop(); - bool isPlaying() { return m_isPlaying; } - - float sampleRate() const { return m_sampleRate; } - - // WebAudioDevice::RenderCallback - void render(const WebVector<float*>& audioData, + // The actual render function (WebAudioDevice::RenderCallback) isochronously + // invoked by the media renderer. + void render(const WebVector<float*>& destinationData, size_t numberOfFrames, double delay, double delayTimestamp, size_t priorFramesSkipped) override; - // AudioSourceProvider - void provideInput(AudioBus*, size_t framesToProcess) override; + // AudioSourceProvider (FIFO) + void provideInput(AudioBus* outputBus, size_t framesToProcess) override; - static float hardwareSampleRate(); + virtual void start(); + virtual void stop(); size_t callbackBufferSize() const { return m_callbackBufferSize; } + float sampleRate() const { return m_sampleRate; } + bool isPlaying() { return m_isPlaying; } - // maxChannelCount() returns the total number of output channels of the audio - // hardware. A value of 0 indicates that the number of channels cannot be - // configured and that only stereo (2-channel) destinations can be created. - // The numberOfOutputChannels parameter of AudioDestination::create() is - // allowed to be a value: 1 <= numberOfOutputChannels <= maxChannelCount(), - // or if maxChannelCount() equals 0, then numberOfOutputChannels must be 2. + // The information from the actual audio hardware. (via Platform::current) + static float hardwareSampleRate(); static unsigned long maxChannelCount(); private: - AudioIOCallback& m_callback; + std::unique_ptr<WebAudioDevice> m_webAudioDevice; unsigned m_numberOfOutputChannels; - RefPtr<AudioBus> m_renderBus; + size_t m_callbackBufferSize; float m_sampleRate; bool m_isPlaying; - std::unique_ptr<WebAudioDevice> m_audioDevice; - size_t m_callbackBufferSize; + // The render callback function of WebAudio engine. (i.e. DestinationNode) + AudioIOCallback& m_callback; + + RefPtr<AudioBus> m_outputBus; std::unique_ptr<AudioPullFIFO> m_fifo; size_t m_framesElapsed; AudioIOPosition m_outputPosition; base::TimeTicks m_outputPositionReceivedTimestamp; + + // Calculate the optimum buffer size for a given platform. Return false if the + // buffer size calculation fails. + bool calculateBufferSize(); + + size_t hardwareBufferSize(); }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasSurfaceLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/CanvasSurfaceLayerBridge.cpp index 028055ba6..3351fcd 100644 --- a/third_party/WebKit/Source/platform/graphics/CanvasSurfaceLayerBridge.cpp +++ b/third_party/WebKit/Source/platform/graphics/CanvasSurfaceLayerBridge.cpp
@@ -84,42 +84,36 @@ GraphicsLayer::registerContentsLayer(m_webLayer.get()); } -void CanvasSurfaceLayerBridge::OnSurfaceCreated(const cc::SurfaceId& surfaceId, - int32_t width, - int32_t height, - float deviceScaleFactor) { - if (!m_currentSurfaceId.is_valid() && surfaceId.is_valid()) { +void CanvasSurfaceLayerBridge::OnSurfaceCreated( + const cc::SurfaceInfo& surfaceInfo) { + if (!m_currentSurfaceId.is_valid() && surfaceInfo.id().is_valid()) { // First time a SurfaceId is received - m_currentSurfaceId = surfaceId; + m_currentSurfaceId = surfaceInfo.id(); GraphicsLayer::unregisterContentsLayer(m_webLayer.get()); m_webLayer->removeFromParent(); scoped_refptr<cc::SurfaceLayer> surfaceLayer = cc::SurfaceLayer::Create(m_refFactory); - cc::SurfaceInfo info(surfaceId, deviceScaleFactor, - gfx::Size(width, height)); surfaceLayer->SetSurfaceInfo( - info, true /* scale layer bounds with surface size */); + surfaceInfo, true /* scale layer bounds with surface size */); m_CCLayer = surfaceLayer; m_webLayer = Platform::current()->compositorSupport()->createLayerFromCCLayer( m_CCLayer.get()); GraphicsLayer::registerContentsLayer(m_webLayer.get()); - } else if (m_currentSurfaceId != surfaceId) { + } else if (m_currentSurfaceId != surfaceInfo.id()) { // A different SurfaceId is received, prompting change to existing // SurfaceLayer - m_currentSurfaceId = surfaceId; - cc::SurfaceInfo info(m_currentSurfaceId, deviceScaleFactor, - gfx::Size(width, height)); + m_currentSurfaceId = surfaceInfo.id(); cc::SurfaceLayer* surfaceLayer = static_cast<cc::SurfaceLayer*>(m_CCLayer.get()); surfaceLayer->SetSurfaceInfo( - info, true /* scale layer bounds with surface size */); + surfaceInfo, true /* scale layer bounds with surface size */); } m_observer->OnWebLayerReplaced(); - m_CCLayer->SetBounds(gfx::Size(width, height)); + m_CCLayer->SetBounds(surfaceInfo.size_in_pixels()); } void CanvasSurfaceLayerBridge::satisfyCallback(
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasSurfaceLayerBridge.h b/third_party/WebKit/Source/platform/graphics/CanvasSurfaceLayerBridge.h index 7636462..89a473a 100644 --- a/third_party/WebKit/Source/platform/graphics/CanvasSurfaceLayerBridge.h +++ b/third_party/WebKit/Source/platform/graphics/CanvasSurfaceLayerBridge.h
@@ -16,6 +16,7 @@ namespace cc { class Layer; +class SurfaceInfo; } // namespace cc namespace blink { @@ -40,10 +41,7 @@ const cc::FrameSinkId& getFrameSinkId() const { return m_frameSinkId; } // Implementation of mojom::blink::OffscreenCanvasSurfaceClient - void OnSurfaceCreated(const cc::SurfaceId&, - int32_t width, - int32_t height, - float deviceScaleFactor) override; + void OnSurfaceCreated(const cc::SurfaceInfo&) override; void satisfyCallback(const cc::SurfaceSequence&); void requireCallback(const cc::SurfaceId&, const cc::SurfaceSequence&);
diff --git a/third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp b/third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp index 7c38c7d2..466ef4b 100644 --- a/third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp +++ b/third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp
@@ -21,6 +21,7 @@ #include "platform/SharedBuffer.h" #include "platform/image-decoders/ImageDecoder.h" #include "public/platform/Platform.h" +#include "ui/gfx/test/icc_profiles.h" #include "wtf/PassRefPtr.h" #include "wtf/PtrUtil.h" #include <memory> @@ -175,62 +176,6 @@ #endif -void getScreenColorProfile(WebVector<char>* profile) { - static unsigned char profileData[] = { - 0x00, 0x00, 0x01, 0xea, 0x54, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, - 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x61, 0x63, 0x73, 0x70, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, - 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x74, 0x65, 0x73, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0d, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8c, - 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xa0, 0x00, 0x00, 0x00, 0x14, - 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xb4, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x77, 0x68, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x2e, - 0x69, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x52, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, - 0x00, 0x00, 0x0f, 0x95, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x26, 0x31, 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9b, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, - 0x00, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x04, 0xfc, 0x63, 0x75, 0x72, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33}; - - static struct WhackedColorProfile { - char* data() { return reinterpret_cast<char*>(profileData); } - - const size_t profileSize = 490u; - - size_t size() { return profileSize; } - - } screenProfile; - - profile->assign(screenProfile.data(), screenProfile.size()); -} - PassRefPtr<SharedBuffer> readFile(const char* fileName) { FILE* fp = fopen(fileName, "rb"); if (!fp) { @@ -310,9 +255,8 @@ if (argc >= 2 && strcmp(argv[1], "--color-correct") == 0) { applyColorCorrection = (--argc, ++argv, true); - WebVector<char> profile; - getScreenColorProfile(&profile); // Returns a color spin color profile. - ColorBehavior::setGlobalTargetColorProfile(profile); + gfx::ICCProfile profile = gfx::ICCProfileForTestingColorSpin(); + ColorBehavior::setGlobalTargetColorProfile(profile.GetData()); } if (argc < 2) {
diff --git a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp index 5a51b96..10551bd 100644 --- a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp +++ b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
@@ -113,6 +113,9 @@ return webViewImpl()->layerTreeView(); } + void styleRelatedMainThreadScrollingReasonTest(const std::string&, + const uint32_t); + protected: std::string m_baseURL; FrameTestHelpers::TestWebViewClient m_mockWebViewClient; @@ -1029,51 +1032,70 @@ MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); } -TEST_F(ScrollingCoordinatorTest, StyleRelatedMainThreadScrollingReason) { - registerMockedHttpURLLoad("two_transparent_scrollable_area.html"); - navigateTo(m_baseURL + "two_transparent_scrollable_area.html"); - webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); - forceFullCompositingUpdate(); +class StyleRelatedMainThreadScrollingReasonTest + : public ScrollingCoordinatorTest { + protected: + StyleRelatedMainThreadScrollingReasonTest() { + registerMockedHttpURLLoad("two_scrollable_area.html"); + navigateTo(m_baseURL + "two_scrollable_area.html"); + } + void testStyle(const std::string& target, const uint32_t reason) { + webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); + Document* document = frame()->document(); + Element* container = document->getElementById("scroller1"); + container->setAttribute("class", target.c_str(), ASSERT_NO_EXCEPTION); + container = document->getElementById("scroller2"); + container->setAttribute("class", target.c_str(), ASSERT_NO_EXCEPTION); + forceFullCompositingUpdate(); - FrameView* frameView = frame()->view(); - ASSERT_TRUE(frameView); - ASSERT_TRUE(frameView->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasOpacity); + FrameView* frameView = frame()->view(); + ASSERT_TRUE(frameView); + ASSERT_TRUE(frameView->mainThreadScrollingReasons() & reason); - // Remove opacity from one of the scrollers. - // Still need to scroll on main thread. - Document* document = frame()->document(); - Element* container = document->getElementById("scroller1"); - DCHECK(container); + // Remove the target attribute from one of the scrollers. + // Still need to scroll on main thread. + container = document->getElementById("scroller1"); + DCHECK(container); - container->removeAttribute("class"); - forceFullCompositingUpdate(); + container->removeAttribute("class"); + forceFullCompositingUpdate(); - ASSERT_TRUE(frameView->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasOpacity); + ASSERT_TRUE(frameView->mainThreadScrollingReasons() & reason); - // Remove opacity from the other scroller would lead to - // scroll on impl. - container = document->getElementById("scroller2"); - DCHECK(container); + // Remove attribute from the other scroller would lead to + // scroll on impl. + container = document->getElementById("scroller2"); + DCHECK(container); - container->removeAttribute("class"); - forceFullCompositingUpdate(); + container->removeAttribute("class"); + forceFullCompositingUpdate(); - ASSERT_FALSE(frameView->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasOpacity); + ASSERT_FALSE(frameView->mainThreadScrollingReasons() & reason); - // Add opacity would again lead to scroll on main thread - container->setAttribute("class", "transparent", ASSERT_NO_EXCEPTION); - forceFullCompositingUpdate(); + // Add target attribute would again lead to scroll on main thread + container->setAttribute("class", target.c_str(), ASSERT_NO_EXCEPTION); + forceFullCompositingUpdate(); - ASSERT_TRUE(frameView->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasOpacity); + ASSERT_TRUE(frameView->mainThreadScrollingReasons() & reason); - webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(true); - forceFullCompositingUpdate(); + webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(true); + forceFullCompositingUpdate(); - ASSERT_FALSE(frameView->mainThreadScrollingReasons()); + ASSERT_FALSE(frameView->mainThreadScrollingReasons()); + } +}; + +TEST_F(StyleRelatedMainThreadScrollingReasonTest, TransparentTest) { + testStyle("transparent", MainThreadScrollingReason::kHasOpacity); +} + +TEST_F(StyleRelatedMainThreadScrollingReasonTest, TransformTest) { + testStyle("transform", MainThreadScrollingReason::kHasTransform); +} + +TEST_F(StyleRelatedMainThreadScrollingReasonTest, BackgroundNotOpaqueTest) { + testStyle("background-not-opaque", + MainThreadScrollingReason::kBackgroundNotOpaqueInRect); } } // namespace blink
diff --git a/third_party/WebKit/Source/web/tests/data/two_transparent_scrollable_area.html b/third_party/WebKit/Source/web/tests/data/two_scrollable_area.html similarity index 66% rename from third_party/WebKit/Source/web/tests/data/two_transparent_scrollable_area.html rename to third_party/WebKit/Source/web/tests/data/two_scrollable_area.html index 1bfbde4..291863c 100644 --- a/third_party/WebKit/Source/web/tests/data/two_transparent_scrollable_area.html +++ b/third_party/WebKit/Source/web/tests/data/two_scrollable_area.html
@@ -5,6 +5,14 @@ opacity: 0.5; } +.transform { + transform: scale(0.8); +} + +.background-not-opaque { + background: rgba(255, 0, 0, 0.5); +} + .content { height: 500px; } @@ -21,9 +29,9 @@ } </style> -<div id="scroller1" class="transparent"> +<div id="scroller1"> <div class="content"></div> </div> -<div id="scroller2" class="transparent"> +<div id="scroller2"> <div class="content"></div> </div>
diff --git a/third_party/WebKit/public/blink_typemaps.gni b/third_party/WebKit/public/blink_typemaps.gni index dcc117e..862f4ca7 100644 --- a/third_party/WebKit/public/blink_typemaps.gni +++ b/third_party/WebKit/public/blink_typemaps.gni
@@ -9,5 +9,6 @@ "//cc/ipc/local_frame_id.typemap", "//cc/ipc/returned_resource.typemap", "//cc/ipc/surface_id.typemap", + "//cc/ipc/surface_info.typemap", "//cc/ipc/surface_sequence.typemap", ]
diff --git a/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom b/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom index ecc7f3d5..2eaca70e 100644 --- a/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom +++ b/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom
@@ -8,6 +8,7 @@ import "cc/ipc/frame_sink_id.mojom"; import "cc/ipc/mojo_compositor_frame_sink.mojom"; import "cc/ipc/surface_id.mojom"; +import "cc/ipc/surface_info.mojom"; import "cc/ipc/surface_sequence.mojom"; interface OffscreenCanvasSurface { @@ -17,10 +18,7 @@ interface OffscreenCanvasSurfaceClient { // TODO(fsamuel, xlai): Replace this with DisplayCompositorClient - OnSurfaceCreated(cc.mojom.SurfaceId surface_id, - int32 width, - int32 height, - float device_scale_factor); + OnSurfaceCreated(cc.mojom.SurfaceInfo surface_info); }; interface OffscreenCanvasSurfaceFactory {
diff --git a/tools/grit/grit/format/html_inline.py b/tools/grit/grit/format/html_inline.py index c18fd77..e8cf22d 100755 --- a/tools/grit/grit/format/html_inline.py +++ b/tools/grit/grit/format/html_inline.py
@@ -34,7 +34,7 @@ # Matches beginning of an "if" block with trailing spaces. _BEGIN_IF_BLOCK = lazy_re.compile( - '<if [^>]*?expr="(?P<expression>[^"]*)"[^>]*?>\s*') + '<if [^>]*?expr=("(?P<expr1>[^">]*)"|\'(?P<expr2>[^\'>]*)\')[^>]*?>\s*') # Matches ending of an "if" block with preceding spaces. _END_IF_BLOCK = lazy_re.compile('\s*</if>') @@ -44,7 +44,8 @@ '<link rel="stylesheet"[^>]+?href="(?P<filename>[^"]*)".*?>(\s*</link>)?', re.DOTALL) _INCLUDE_RE = lazy_re.compile( - '<include[^>]+?src="(?P<filename>[^"\']*)".*?>(\s*</include>)?', + '<include[^>]+?src=("(?P<file1>[^">]*)"|\'(?P<file2>[^\'>]*)\').*?>' + + '(\s*</include>)?', re.DOTALL) _SRC_RE = lazy_re.compile( r'<(?!script)(?:[^>]+?\s)src=(?P<quote>")(?!\[\[|{{)(?P<filename>[^"\']*)\1', @@ -168,7 +169,8 @@ filename_expansion_function=filename_expansion_function) def GetFilepath(src_match, base_path = input_filepath): - filename = src_match.group('filename') + matches = src_match.groupdict().iteritems() + filename = [v for k, v in matches if k.startswith('file') and v][0] if filename.find(':') != -1: # filename is probably a URL, which we don't want to bother inlining @@ -180,8 +182,9 @@ return os.path.normpath(os.path.join(base_path, filename)) def IsConditionSatisfied(src_match): - expression = src_match.group('expression') - return grd_node is None or grd_node.EvaluateCondition(expression) + expr1 = src_match.group('expr1') or '' + expr2 = src_match.group('expr2') or '' + return grd_node is None or grd_node.EvaluateCondition(expr1 + expr2) def CheckConditionalElements(str): """Helper function to conditionally inline inner elements"""
diff --git a/tools/grit/grit/format/html_inline_unittest.py b/tools/grit/grit/format/html_inline_unittest.py index 16674cf..c236f4f 100755 --- a/tools/grit/grit/format/html_inline_unittest.py +++ b/tools/grit/grit/format/html_inline_unittest.py
@@ -34,7 +34,7 @@ href="really-long-long-long-long-long-test.css"> </head> <body> - <include src="test.html"> + <include src='test.html'> <include src="really-long-long-long-long-long-test-file-omg-so-long.html"> <iron-icon src="[[icon]]"></iron-icon><!-- Should be ignored. --> @@ -90,6 +90,9 @@ <if expr="lang == 'fr'"> bonjour </if> + <if expr='lang == "de"'> + hallo + </if> </if> </html> ''', @@ -397,6 +400,8 @@ > </include> <img src="img1.png"> + <include src='single-double-quotes.html"></include> + <include src="double-single-quotes.html'></include> </html> ''', 'style1.css': '''h1 {}''', @@ -419,6 +424,8 @@ <h2></h2> <h2></h2> <img src="data:image/png;base64,YWJj"> + <include src='single-double-quotes.html"></include> + <include src="double-single-quotes.html'></include> </html> '''
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 4e22c18..c22577d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -9504,6 +9504,26 @@ <summary>Count of total bytes sent by the Chrome on the network.</summary> </histogram> +<histogram name="DataUse.ContentType.Services" enum="DataUseContentType" + units="bytes"> + <owner>rajendrant@chromium.org</owner> + <owner>bengr@chromium.org</owner> + <summary> + Data use of Chrome services traffic by different content types. Recorded + when network bytes are received by Chrome. + </summary> +</histogram> + +<histogram name="DataUse.ContentType.UserTraffic" enum="DataUseContentType" + units="bytes"> + <owner>rajendrant@chromium.org</owner> + <owner>bengr@chromium.org</owner> + <summary> + Data use of user traffic by different content types. Recorded when network + bytes are received by Chrome. + </summary> +</histogram> + <histogram name="DataUse.MessageSize" units="bytes"> <owner>amohammadkhan@chromium.org</owner> <owner>bengr@chromium.org</owner> @@ -81654,6 +81674,22 @@ <int value="8" label="Data use tracking ended dialog opted out"/> </enum> +<enum name="DataUseContentType" type="int"> + <int value="0" label="Other"/> + <int value="1" label="Mainframe HTML"/> + <int value="2" label="Non Mainframe HTML"/> + <int value="3" label="CSS"/> + <int value="4" label="Image"/> + <int value="5" label="Javascript"/> + <int value="6" label="Font"/> + <int value="7" label="Audio - App in background"/> + <int value="8" label="Audio - Tab in background"/> + <int value="9" label="Audio - Tab in foreground"/> + <int value="10" label="Video - App in background"/> + <int value="11" label="Video - Tab in background"/> + <int value="12" label="Video - Tab in foreground"/> +</enum> + <enum name="DataUseServices" type="int"> <int value="0" label="Not Tagged"/> <int value="1" label="Suggestions"/> @@ -94720,6 +94756,8 @@ <int value="15" label="Has sticky position objects"/> <int value="16" label="Requires hit testing on custom scrollbars"/> <int value="17" label="Has opacity"/> + <int value="18" label="Has transform"/> + <int value="19" label="Background not opaque in rect"/> </enum> <enum name="MakeChromeDefaultResult" type="int">
diff --git a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java index 92a7f57..ce74633 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java +++ b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
@@ -7,7 +7,7 @@ import android.content.Context; import android.graphics.Color; import android.graphics.Typeface; -import android.support.graphics.drawable.VectorDrawableCompat; +import android.support.v7.content.res.AppCompatResources; import android.text.TextUtils; import android.util.TypedValue; import android.view.LayoutInflater; @@ -173,11 +173,10 @@ } ImageView iconView = item.isIconAtStart() ? iconViewStart : iconViewEnd; - if (item.getVectorDrawableIconId() == DropdownItem.NO_ICON) { + if (item.getIconId() == DropdownItem.NO_ICON) { iconView.setVisibility(View.GONE); } else { - iconView.setImageDrawable(VectorDrawableCompat.create(mContext.getResources(), - item.getVectorDrawableIconId(), mContext.getTheme())); + iconView.setImageDrawable(AppCompatResources.getDrawable(mContext, item.getIconId())); iconView.setVisibility(View.VISIBLE); }
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItem.java b/ui/android/java/src/org/chromium/ui/DropdownItem.java index 740a370..d28db1d 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownItem.java +++ b/ui/android/java/src/org/chromium/ui/DropdownItem.java
@@ -20,9 +20,9 @@ */ String getSublabel(); /** - * Returns the vector drawable id of the icon that should be shown in the dropdown, or NO_ICON. + * Returns the drawable id of the icon that should be shown in the dropdown, or NO_ICON. */ - int getVectorDrawableIconId(); + int getIconId(); /** * Returns true if the item should be enabled in the dropdown. */
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItemBase.java b/ui/android/java/src/org/chromium/ui/DropdownItemBase.java index f268209..9a0c7658 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownItemBase.java +++ b/ui/android/java/src/org/chromium/ui/DropdownItemBase.java
@@ -20,7 +20,7 @@ } @Override - public int getVectorDrawableIconId() { + public int getIconId() { return NO_ICON; }
diff --git a/ui/app_list/views/search_result_container_view.h b/ui/app_list/views/search_result_container_view.h index 8c941a8a..fc57192 100644 --- a/ui/app_list/views/search_result_container_view.h +++ b/ui/app_list/views/search_result_container_view.h
@@ -48,6 +48,7 @@ bool IsValidSelectionIndex(int index) const; int num_results() const { return num_results_; } + void set_num_results(int num_results) { num_results_ = num_results; } void set_container_score(double score) { container_score_ = score; } double container_score() const { return container_score_; }
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc index 0bac15b..8df6a7a 100644 --- a/ui/app_list/views/start_page_view.cc +++ b/ui/app_list/views/start_page_view.cc
@@ -190,7 +190,7 @@ delete search_result_tile_views_[i]; search_result_tile_views_.clear(); RemoveChildView(all_apps_button_); - CreateAppsGrid(std::min(kNumStartPageTiles, display_results.size())); + CreateAppsGrid(display_results.size()); } // Update the tile item results. @@ -211,10 +211,10 @@ void StartPageView::StartPageTilesContainer::UpdateSelectedIndex( int old_selected, int new_selected) { - if (old_selected >= 0) + if (old_selected >= 0 && old_selected < num_results()) GetTileItemView(old_selected)->SetSelected(false); - if (new_selected >= 0) + if (new_selected >= 0 && new_selected < num_results()) GetTileItemView(new_selected)->SetSelected(true); } @@ -360,8 +360,8 @@ custom_page_view->SetVisible( app_list_main_view_->ShouldShowCustomLauncherPage()); } - tiles_container_->Update(); tiles_container_->ClearSelectedIndex(); + tiles_container_->set_num_results(tiles_container_->Update()); custom_launcher_page_background_->SetSelected(false); }
diff --git a/ui/aura/mus/DEPS b/ui/aura/mus/DEPS index d5c7f53a..8fe8d6d1 100644 --- a/ui/aura/mus/DEPS +++ b/ui/aura/mus/DEPS
@@ -4,6 +4,7 @@ "+cc/output/compositor_frame_sink.h", "+cc/scheduler/begin_frame_source.h", "+cc/surfaces/surface_id_allocator.h", + "+cc/surfaces/surface_info.h", "+cc/surfaces/surface_manager.h", "+gpu/command_buffer/client/gpu_memory_buffer_manager.h", "+gpu/ipc/client/gpu_channel_host.h",
diff --git a/ui/aura/mus/surface_id_handler.h b/ui/aura/mus/surface_id_handler.h index 01e4e64..4f5c8d34 100644 --- a/ui/aura/mus/surface_id_handler.h +++ b/ui/aura/mus/surface_id_handler.h
@@ -8,22 +8,14 @@ #include "cc/surfaces/surface_id.h" #include "ui/gfx/geometry/size.h" +namespace cc { +class SurfaceInfo; +} + namespace aura { class Window; -// Holds information about the current surface held by a Window. -// |surface_id| uniquely identifies the surface in the display -// compositor. -// |frame_size| is the size of the frame held by the surface. -// |device_scale_factor| is the scale factor that the frame was -// renderered for. -struct SurfaceInfo { - cc::SurfaceId surface_id; - gfx::Size frame_size; - float device_scale_factor; -}; - class SurfaceIdHandler { public: // Called when a child window allocates a new surface ID. @@ -32,7 +24,7 @@ // |surface_info| will refer to a null pointer. virtual void OnChildWindowSurfaceChanged( Window* window, - std::unique_ptr<SurfaceInfo>* surface_info) = 0; + const cc::SurfaceInfo& surface_info) = 0; }; } // namespace aura
diff --git a/ui/aura/mus/window_mus.h b/ui/aura/mus/window_mus.h index 107d11a7..f88d042 100644 --- a/ui/aura/mus/window_mus.h +++ b/ui/aura/mus/window_mus.h
@@ -14,6 +14,10 @@ #include "ui/aura/aura_export.h" #include "ui/aura/mus/mus_types.h" +namespace cc { +class SurfaceInfo; +} + namespace gfx { class Rect; } @@ -26,7 +30,6 @@ namespace aura { -struct SurfaceInfo; class Window; class WindowTreeClient; @@ -79,8 +82,8 @@ virtual void SetPredefinedCursorFromServer(ui::mojom::Cursor cursor) = 0; virtual void SetPropertyFromServer(const std::string& property_name, const std::vector<uint8_t>* data) = 0; - virtual void SetSurfaceIdFromServer( - std::unique_ptr<SurfaceInfo> surface_info) = 0; + virtual void SetSurfaceInfoFromServer( + const cc::SurfaceInfo& surface_info) = 0; // The window was deleted on the server side. DestroyFromServer() should // result in deleting |this|. virtual void DestroyFromServer() = 0;
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc index 52480e7..305fcfc 100644 --- a/ui/aura/mus/window_port_mus.cc +++ b/ui/aura/mus/window_port_mus.cc
@@ -32,8 +32,8 @@ : WindowMus(window_mus_type), window_tree_client_(client) {} WindowPortMus::~WindowPortMus() { - if (surface_info_) - SetSurfaceIdFromServer(nullptr); + if (surface_info_.id().is_valid()) + SetSurfaceInfoFromServer(cc::SurfaceInfo()); // DESTROY is only scheduled from DestroyFromServer(), meaning if DESTROY is // present then the server originated the change. @@ -244,12 +244,11 @@ property_data); } -void WindowPortMus::SetSurfaceIdFromServer( - std::unique_ptr<SurfaceInfo> surface_info) { - if (surface_info_) { - const cc::SurfaceId& existing_surface_id = surface_info_->surface_id; - cc::SurfaceId new_surface_id = - surface_info ? surface_info->surface_id : cc::SurfaceId(); +void WindowPortMus::SetSurfaceInfoFromServer( + const cc::SurfaceInfo& surface_info) { + if (surface_info_.id().is_valid()) { + const cc::SurfaceId& existing_surface_id = surface_info_.id(); + const cc::SurfaceId& new_surface_id = surface_info.id(); if (existing_surface_id.is_valid() && existing_surface_id != new_surface_id) { // TODO(kylechar): Start return reference here? @@ -258,9 +257,9 @@ WindowPortMus* parent = Get(window_->parent()); if (parent && parent->surface_id_handler_) { parent->surface_id_handler_->OnChildWindowSurfaceChanged(window_, - &surface_info); + surface_info); } - surface_info_ = std::move(surface_info); + surface_info_ = surface_info; } void WindowPortMus::DestroyFromServer() {
diff --git a/ui/aura/mus/window_port_mus.h b/ui/aura/mus/window_port_mus.h index 89bfad4c..fd598d0f5 100644 --- a/ui/aura/mus/window_port_mus.h +++ b/ui/aura/mus/window_port_mus.h
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/macros.h" +#include "cc/surfaces/surface_info.h" #include "services/ui/public/interfaces/cursor.mojom.h" #include "services/ui/public/interfaces/window_tree.mojom.h" #include "services/ui/public/interfaces/window_tree_constants.mojom.h" @@ -209,8 +210,7 @@ void SetPropertyFromServer( const std::string& property_name, const std::vector<uint8_t>* property_data) override; - void SetSurfaceIdFromServer( - std::unique_ptr<SurfaceInfo> surface_info) override; + void SetSurfaceInfoFromServer(const cc::SurfaceInfo& surface_info) override; void DestroyFromServer() override; void AddTransientChildFromServer(WindowMus* child) override; void RemoveTransientChildFromServer(WindowMus* child) override; @@ -247,7 +247,7 @@ ServerChanges server_changes_; SurfaceIdHandler* surface_id_handler_ = nullptr; - std::unique_ptr<SurfaceInfo> surface_info_; + cc::SurfaceInfo surface_info_; ui::mojom::Cursor predefined_cursor_ = ui::mojom::Cursor::CURSOR_NULL;
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index 41475ee..e9d1c07 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -1222,17 +1222,11 @@ void WindowTreeClient::OnWindowSurfaceChanged( Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) { + const cc::SurfaceInfo& surface_info) { WindowMus* window = GetWindowByServerId(window_id); if (!window) return; - std::unique_ptr<SurfaceInfo> surface_info(base::MakeUnique<SurfaceInfo>()); - surface_info->surface_id = surface_id; - surface_info->frame_size = frame_size; - surface_info->device_scale_factor = device_scale_factor; - window->SetSurfaceIdFromServer(std::move(surface_info)); + window->SetSurfaceInfoFromServer(surface_info); } void WindowTreeClient::OnDragDropStart(
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h index cc23a42..07ce813 100644 --- a/ui/aura/mus/window_tree_client.h +++ b/ui/aura/mus/window_tree_client.h
@@ -342,9 +342,7 @@ void OnWindowPredefinedCursorChanged(Id window_id, ui::mojom::Cursor cursor) override; void OnWindowSurfaceChanged(Id window_id, - const cc::SurfaceId& surface_id, - const gfx::Size& frame_size, - float device_scale_factor) override; + const cc::SurfaceInfo& surface_info) override; void OnDragDropStart( const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data) override;
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 5e75ecfc..b9ea357 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -545,6 +545,8 @@ "test/fontconfig_util_linux.h", "test/gfx_util.cc", "test/gfx_util.h", + "test/icc_profiles.cc", + "test/icc_profiles.h", "test/ui_cocoa_test_helper.h", "test/ui_cocoa_test_helper.mm", ] @@ -628,7 +630,6 @@ "geometry/vector2d_unittest.cc", "geometry/vector3d_unittest.cc", "icc_profile_unittest.cc", - "icc_profile_unittest.h", "image/image_mac_unittest.mm", "image/image_util_unittest.cc", "mac/coordinate_conversion_unittest.mm",
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc index 507d2853..8d3b4c1 100644 --- a/ui/gfx/color_space.cc +++ b/ui/gfx/color_space.cc
@@ -154,10 +154,6 @@ return false; } -sk_sp<SkColorSpace> ColorSpace::ToSkColorSpace() const { - return sk_color_space_; -} - ColorSpace ColorSpace::FromSkColorSpace( const sk_sp<SkColorSpace>& sk_color_space) { if (!sk_color_space)
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h index e05fbc3..c9e9038 100644 --- a/ui/gfx/color_space.h +++ b/ui/gfx/color_space.h
@@ -162,7 +162,7 @@ bool operator<(const ColorSpace& other) const; // Note that this may return nullptr. - sk_sp<SkColorSpace> ToSkColorSpace() const; + const sk_sp<SkColorSpace>& ToSkColorSpace() const { return sk_color_space_; } static ColorSpace FromSkColorSpace(const sk_sp<SkColorSpace>& sk_color_space); private:
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index 2a50939..dbe1829d 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -7,7 +7,7 @@ #include "ui/gfx/color_space.h" #include "ui/gfx/color_transform.h" #include "ui/gfx/icc_profile.h" -#include "ui/gfx/icc_profile_unittest.h" +#include "ui/gfx/test/icc_profiles.h" #include "ui/gfx/transform.h" namespace gfx {
diff --git a/ui/gfx/icc_profile_unittest.cc b/ui/gfx/icc_profile_unittest.cc index 2968597d..73fcea94 100644 --- a/ui/gfx/icc_profile_unittest.cc +++ b/ui/gfx/icc_profile_unittest.cc
@@ -6,317 +6,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/color_space.h" #include "ui/gfx/icc_profile.h" +#include "ui/gfx/test/icc_profiles.h" namespace gfx { -ICCProfile ICCProfileForTestingSRGB() { - const unsigned char srgb_icc_data[] = { - 0x00, 0x00, 0x0b, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, - 0x07, 0xd9, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x15, 0x00, 0x24, 0x00, 0x1f, - 0x61, 0x63, 0x73, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x00, 0x00, 0x00, 0x00, - 0x12, 0xe2, 0xc7, 0xe9, 0xc6, 0x02, 0x6e, 0x10, 0x5e, 0xdb, 0x15, 0x15, - 0x9c, 0x6f, 0x26, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00, 0x00, 0x79, - 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c, - 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c, - 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c, - 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x09, 0xe0, 0x00, 0x00, 0x00, 0x88, - 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x0a, 0x68, 0x00, 0x00, 0x00, 0x14, - 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x0a, 0x7c, 0x00, 0x00, 0x00, 0x14, - 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x0a, 0x90, 0x00, 0x00, 0x00, 0x24, - 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x0a, 0xb4, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x0a, 0xc8, 0x00, 0x00, 0x00, 0x14, - 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x0a, 0xdc, 0x00, 0x00, 0x00, 0x0c, - 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x87, - 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x0b, 0x70, 0x00, 0x00, 0x00, 0x14, - 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x0b, 0x84, 0x00, 0x00, 0x00, 0x37, - 0x63, 0x68, 0x61, 0x64, 0x00, 0x00, 0x0b, 0xbc, 0x00, 0x00, 0x00, 0x2c, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, - 0x36, 0x2d, 0x32, 0x2d, 0x31, 0x20, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x20, - 0x73, 0x63, 0x61, 0x6c, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xcf, - 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19, - 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, - 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54, - 0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72, - 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00, 0x90, - 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae, - 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00, 0xc6, 0x00, 0xcb, - 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb, - 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0d, - 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, - 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59, - 0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, - 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1, - 0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, - 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14, - 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b, - 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x84, - 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1, - 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, 0x02, 0xf5, 0x03, 0x00, - 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43, - 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a, - 0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, - 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20, - 0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, - 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4, - 0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c, - 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77, - 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5, - 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37, - 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d, - 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, 0x06, 0xf5, 0x07, 0x07, - 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, - 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5, - 0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, - 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2, - 0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, - 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf, - 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54, - 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5, 0x0a, 0xdc, - 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69, - 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, 0x0b, 0xe1, 0x0b, 0xf9, - 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e, - 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26, - 0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, - 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64, - 0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, - 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3, - 0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61, - 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11, 0x13, - 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9, - 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84, - 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43, - 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, 0x13, 0xe5, 0x14, 0x06, - 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, - 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b, - 0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, - 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41, - 0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, - 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa, - 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd, - 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e, 0x1a, 0xc5, - 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2, - 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, 0x1c, 0x7b, 0x1c, 0xa3, - 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99, - 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94, - 0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, - 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98, - 0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, - 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf, - 0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2, - 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24, 0xda, - 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7, - 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26, 0xe8, 0x27, 0x18, - 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f, - 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6b, - 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, - 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1, - 0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, - 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c, - 0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, - 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb, - 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a, - 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46, 0x33, 0x7f, - 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8, - 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, 0x35, 0xfd, 0x36, 0x37, - 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c, - 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05, - 0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, - 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8, - 0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, - 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0, - 0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64, - 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41, 0xee, - 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d, - 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44, 0xce, 0x45, 0x12, - 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab, - 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, 0x48, 0x05, 0x48, 0x4b, - 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, - 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a, - 0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, - 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00, - 0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, - 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c, - 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42, - 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2, 0x56, 0x0f, - 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0, - 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, 0x59, 0x69, 0x59, 0xb8, - 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95, - 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78, - 0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, - 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f, - 0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, - 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d, - 0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d, - 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69, 0x43, - 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f, - 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d, 0x08, 0x6d, 0x60, - 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78, - 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, 0x71, 0x3a, 0x71, 0x95, - 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, - 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1, - 0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, - 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46, - 0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, - 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2, - 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a, - 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4, 0x83, 0x57, - 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab, - 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, 0x87, 0x9f, 0x88, 0x04, - 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64, - 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca, - 0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, - 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8, - 0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, - 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f, - 0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24, - 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b, 0xaf, - 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40, - 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0, 0x69, 0xa0, 0xd8, - 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76, - 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, 0xa5, 0xa9, 0xa6, 0x1a, - 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, - 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75, - 0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, - 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea, - 0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, - 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79, - 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a, - 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7, 0xbc, 0x21, - 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff, - 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, 0xc1, 0x67, 0xc1, 0xe3, - 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce, - 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf, - 0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, - 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5, - 0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, - 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6, - 0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8, - 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9, 0xf1, - 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10, - 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf, 0xaf, 0xe0, 0x36, - 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63, - 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, 0xe6, 0x0d, 0xe6, 0x96, - 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, - 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11, - 0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, - 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7, - 0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, - 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57, - 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba, - 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff, 0x64, 0x65, 0x73, 0x63, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20, - 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2d, 0x31, 0x20, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x43, 0x6f, - 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x53, 0x70, 0x61, 0x63, 0x65, 0x20, 0x2d, - 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, - 0x00, 0x00, 0xb7, 0x85, 0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x87, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, - 0x00, 0x00, 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x73, 0x69, 0x67, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x64, 0x65, 0x73, 0x63, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e, - 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, - 0x2d, 0x32, 0x2d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x74, 0x65, 0x78, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x43, 0x6f, - 0x6e, 0x73, 0x6f, 0x72, 0x74, 0x69, 0x75, 0x6d, 0x2c, 0x20, 0x32, 0x30, - 0x30, 0x39, 0x00, 0x00, 0x73, 0x66, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x0c, 0x44, 0x00, 0x00, 0x05, 0xdf, 0xff, 0xff, 0xf3, 0x26, - 0x00, 0x00, 0x07, 0x94, 0x00, 0x00, 0xfd, 0x8f, 0xff, 0xff, 0xfb, 0xa1, - 0xff, 0xff, 0xfd, 0xa2, 0x00, 0x00, 0x03, 0xdb, 0x00, 0x00, 0xc0, 0x75}; - return ICCProfile::FromData(reinterpret_cast<const char*>(srgb_icc_data), - arraysize(srgb_icc_data)); -} - -ICCProfile ICCProfileForTestingColorSpin() { - const unsigned char color_spin_icc_data[] = { - 0x00, 0x00, 0x01, 0xea, 0x54, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, - 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x61, 0x63, 0x73, 0x70, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, - 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x74, 0x65, 0x73, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0d, - 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8c, - 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xa0, 0x00, 0x00, 0x00, 0x14, - 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xb4, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, 0x00, 0x14, - 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, - 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x77, 0x68, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x2e, - 0x69, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x52, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, - 0x00, 0x00, 0x0f, 0x95, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x26, 0x31, 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9b, - 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, - 0x00, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x04, 0xfc, 0x63, 0x75, 0x72, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33}; - return ICCProfile::FromData( - reinterpret_cast<const char*>(color_spin_icc_data), - arraysize(color_spin_icc_data)); -} - TEST(ICCProfile, Conversions) { ICCProfile icc_profile = ICCProfileForTestingColorSpin(); ColorSpace color_space_from_icc_profile = icc_profile.GetColorSpace();
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc index c12d803..78bc651 100644 --- a/ui/gfx/render_text.cc +++ b/ui/gfx/render_text.cc
@@ -423,6 +423,7 @@ // static constexpr base::char16 RenderText::kPasswordReplacementChar; +constexpr bool RenderText::kDragToEndIfOutsideVerticalBounds; RenderText::~RenderText() { } @@ -815,8 +816,13 @@ } VisualCursorDirection RenderText::GetVisualDirectionOfLogicalEnd() { - return GetDisplayTextDirection() == base::i18n::LEFT_TO_RIGHT ? - CURSOR_RIGHT : CURSOR_LEFT; + return GetDisplayTextDirection() == base::i18n::LEFT_TO_RIGHT ? CURSOR_RIGHT + : CURSOR_LEFT; +} + +VisualCursorDirection RenderText::GetVisualDirectionOfLogicalBeginning() { + return GetDisplayTextDirection() == base::i18n::RIGHT_TO_LEFT ? CURSOR_RIGHT + : CURSOR_LEFT; } SizeF RenderText::GetStringSizeF() { @@ -894,7 +900,7 @@ // TODO(ckocagil): Support multiline. This function should return the height // of the line the cursor is on. |GetStringSize()| now returns // the multiline size, eliminate its use here. - + DCHECK(!multiline_); EnsureLayout(); size_t caret_pos = caret.caret_pos(); DCHECK(IsValidLogicalIndex(caret_pos)); @@ -962,6 +968,11 @@ sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD); } +std::vector<Rect> RenderText::GetSubstringBoundsForTesting( + const gfx::Range& range) { + return GetSubstringBounds(range); +} + const Vector2d& RenderText::GetUpdatedDisplayOffset() { UpdateCachedBoundsAndOffset(); return display_offset_; @@ -1004,12 +1015,15 @@ } Vector2d RenderText::GetLineOffset(size_t line_number) { + EnsureLayout(); Vector2d offset = display_rect().OffsetFromOrigin(); // TODO(ckocagil): Apply the display offset for multiline scrolling. - if (!multiline()) + if (!multiline()) { offset.Add(GetUpdatedDisplayOffset()); - else + } else { + DCHECK_LT(line_number, lines().size()); offset.Add(Vector2d(0, lines_[line_number].preceding_heights)); + } offset.Add(GetAlignmentOffset(line_number)); return offset; } @@ -1105,6 +1119,29 @@ return SelectionModel(0, CURSOR_BACKWARD); } +SelectionModel RenderText::LineSelectionModel(size_t line_index, + VisualCursorDirection direction) { + const internal::Line& line = lines()[line_index]; + if (line.segments.empty()) { + // Only the last line can be empty. + DCHECK_EQ(lines().size() - 1, line_index); + return EdgeSelectionModel(GetVisualDirectionOfLogicalEnd()); + } + + size_t max_index = 0; + size_t min_index = text().length(); + for (const auto& segment : line.segments) { + min_index = std::min<size_t>(min_index, segment.char_range.GetMin()); + max_index = std::max<size_t>(max_index, segment.char_range.GetMax()); + } + + return direction == GetVisualDirectionOfLogicalEnd() + ? SelectionModel(DisplayIndexToTextIndex(max_index), + CURSOR_FORWARD) + : SelectionModel(DisplayIndexToTextIndex(min_index), + CURSOR_BACKWARD); +} + void RenderText::SetSelectionModel(const SelectionModel& model) { DCHECK_LE(model.selection().GetMax(), text().length()); selection_model_ = model; @@ -1213,11 +1250,6 @@ composition_and_selection_styles_applied_ = false; } -Point RenderText::ToTextPoint(const Point& point) { - return point - GetLineOffset(0); - // TODO(ckocagil): Convert multiline view space points to text space. -} - Point RenderText::ToViewPoint(const Point& point) { if (!multiline()) return point + GetLineOffset(0); @@ -1228,41 +1260,13 @@ size_t line = 0; for (; line < lines_.size() && x > lines_[line].size.width(); ++line) x -= lines_[line].size.width(); + + // If |point| is outside the text space, clip it to the end of the last line. + if (line == lines_.size()) + x = lines_[--line].size.width(); return Point(x, point.y()) + GetLineOffset(line); } -std::vector<Rect> RenderText::TextBoundsToViewBounds(const Range& x) { - std::vector<Rect> rects; - - if (!multiline()) { - rects.push_back(Rect(ToViewPoint(Point(x.GetMin(), 0)), - Size(x.length(), GetStringSize().height()))); - return rects; - } - - EnsureLayout(); - - // Each line segment keeps its position in text coordinates. Traverse all line - // segments and if the segment intersects with the given range, add the view - // rect corresponding to the intersection to |rects|. - for (size_t line = 0; line < lines_.size(); ++line) { - int line_x = 0; - const Vector2d offset = GetLineOffset(line); - for (size_t i = 0; i < lines_[line].segments.size(); ++i) { - const internal::LineSegment* segment = &lines_[line].segments[i]; - const Range intersection = segment->x_range.Intersect(x).Ceil(); - if (!intersection.is_empty()) { - Rect rect(line_x + intersection.start() - segment->x_range.start(), - 0, intersection.length(), lines_[line].size.height()); - rects.push_back(rect + offset); - } - line_x += segment->x_range.length(); - } - } - - return rects; -} - HorizontalAlignment RenderText::GetCurrentHorizontalAlignment() { if (horizontal_alignment_ != ALIGN_TO_HEAD) return horizontal_alignment_;
diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h index 7e0b483..44ec0770 100644 --- a/ui/gfx/render_text.h +++ b/ui/gfx/render_text.h
@@ -209,14 +209,17 @@ // for rendering and translation between logical and visual data. class GFX_EXPORT RenderText { public: -// The character used for displaying obscured text. -// TODO(benrg): GTK uses the first of U+25CF, U+2022, U+2731, U+273A, '*' -// that's available in the font (find_invisible_char() in gtkentry.c). -// Use a bullet character on Mac. #if defined(OS_MACOSX) + // The character used for displaying obscured text. Use a bullet character on + // Mac. static constexpr base::char16 kPasswordReplacementChar = 0x2022; + + // On Mac, while selecting text if the cursor is outside the vertical text + // bounds, drag to the end of the text. + static constexpr bool kDragToEndIfOutsideVerticalBounds = true; #else static constexpr base::char16 kPasswordReplacementChar = '*'; + static constexpr bool kDragToEndIfOutsideVerticalBounds = false; #endif virtual ~RenderText(); @@ -412,10 +415,11 @@ } base::i18n::TextDirection GetDisplayTextDirection(); - // Returns the visual movement direction corresponding to the logical end - // of the text, considering only the dominant direction returned by - // |GetDisplayTextDirection()|, not the direction of a particular run. + // Returns the visual movement direction corresponding to the logical + // end/beginning of the text, considering only the dominant direction returned + // by |GetDisplayTextDirection()|, not the direction of a particular run. VisualCursorDirection GetVisualDirectionOfLogicalEnd(); + VisualCursorDirection GetVisualDirectionOfLogicalBeginning(); // Returns the text used to display, which may be obscured, truncated or // elided. The subclass may compute elided text on the fly, or use @@ -473,6 +477,7 @@ // is longer than the textfield. Subsequent text, cursor, or bounds changes // may invalidate returned values. Note that |caret| must be placed at // grapheme boundary, i.e. caret.caret_pos() must be a cursorable position. + // TODO(crbug.com/248597): Add multiline support. Rect GetCursorBounds(const SelectionModel& caret, bool insert_mode); // Compute the current cursor bounds, panning the text to show the cursor in @@ -503,6 +508,9 @@ // chosen. virtual std::vector<FontSpan> GetFontSpansForTesting() = 0; + // Helper function to be used in tests for retrieving the substring bounds. + std::vector<Rect> GetSubstringBoundsForTesting(const gfx::Range& range); + // Gets the horizontal bounds (relative to the left of the text, not the view) // of the glyph starting at |index|. If the glyph is RTL then the returned // Range will have is_reversed() true. (This does not return a Rect because a @@ -591,10 +599,15 @@ const SelectionModel& selection, VisualCursorDirection direction) = 0; - // Get the SelectionModels corresponding to visual text ends. + // Get the selection model corresponding to visual text ends. // The returned value represents a cursor/caret position without a selection. SelectionModel EdgeSelectionModel(VisualCursorDirection direction); + // Get the selection model corresponding to visual text ends for |line_index|. + // The returned value represents a cursor/caret position without a selection. + SelectionModel LineSelectionModel(size_t line_index, + gfx::VisualCursorDirection direction); + // Sets the selection model, the argument is assumed to be valid. virtual void SetSelectionModel(const SelectionModel& model); @@ -640,14 +653,10 @@ void ApplyCompositionAndSelectionStyles(); void UndoCompositionAndSelectionStyles(); - // Convert points from the text space to the view space and back. Handles the - // display area, display offset, application LTR/RTL mode and multiline. - Point ToTextPoint(const Point& point); + // Convert points from the text space to the view space. Handles the display + // area, display offset, application LTR/RTL mode and multiline. Point ToViewPoint(const Point& point); - // Convert a text space x-coordinate range to rects in view space. - std::vector<Rect> TextBoundsToViewBounds(const Range& x); - // Get the alignment, resolving ALIGN_TO_HEAD with the current text direction. HorizontalAlignment GetCurrentHorizontalAlignment();
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc index e543bc5..5b25f5b9 100644 --- a/ui/gfx/render_text_harfbuzz.cc +++ b/ui/gfx/render_text_harfbuzz.cc
@@ -291,8 +291,15 @@ if (!word_segments.empty() && text_[word_segments.back().char_range.start()] == '\n') { new_line = true; - word_width -= word_segments.back().width(); - word_segments.pop_back(); + + // Since the line should at least contain some information regarding the + // text range it corresponds to, don't pop the newline segment, if it's + // the only segment in the line. This ensures that every line has a non- + // empty segments vector (except the last in some cases). + if (word_segments.size() != 1u || available_width_ != max_width_) { + word_width -= word_segments.back().width(); + word_segments.pop_back(); + } } // If the word is not the first word in the line and it can't fit into @@ -647,7 +654,7 @@ } RangeF TextRunHarfBuzz::GetGraphemeBounds(RenderTextHarfBuzz* render_text, - size_t text_index) { + size_t text_index) const { DCHECK_LT(text_index, range.end()); if (glyph_count == 0) return RangeF(preceding_run_widths, preceding_run_widths + width); @@ -697,6 +704,19 @@ preceding_run_widths + cluster_end_x); } +float TextRunHarfBuzz::GetGraphemeWidthForCharRange( + RenderTextHarfBuzz* render_text, + const Range& char_range) const { + if (char_range.is_empty()) + return 0; + DCHECK(!char_range.is_reversed()); + DCHECK(range.Contains(char_range)); + size_t left_index = is_rtl ? char_range.end() - 1 : char_range.start(); + size_t right_index = is_rtl ? char_range.start() : char_range.end() - 1; + return GetGraphemeBounds(render_text, right_index).GetMax() - + GetGraphemeBounds(render_text, left_index).GetMin(); +} + SkScalar TextRunHarfBuzz::GetGlyphWidthForCharRange( const Range& char_range) const { if (char_range.is_empty()) @@ -815,39 +835,74 @@ return total_size_; } -SelectionModel RenderTextHarfBuzz::FindCursorPosition(const Point& point) { +SelectionModel RenderTextHarfBuzz::FindCursorPosition(const Point& view_point) { EnsureLayout(); + DCHECK(!lines().empty()); - int x = ToTextPoint(point).x(); - float offset = 0; - size_t run_index = GetRunContainingXCoord(x, &offset); + int line_index = GetLineContainingYCoord((view_point - GetLineOffset(0)).y()); + // Clip line index to a valid value in case kDragToEndIfOutsideVerticalBounds + // is false. Else, drag to end. + if (line_index < 0) { + if (RenderText::kDragToEndIfOutsideVerticalBounds) + return EdgeSelectionModel(GetVisualDirectionOfLogicalBeginning()); + else + line_index = 0; + } + if (line_index >= static_cast<int>(lines().size())) { + if (RenderText::kDragToEndIfOutsideVerticalBounds) + return EdgeSelectionModel(GetVisualDirectionOfLogicalEnd()); + else + line_index = lines().size() - 1; + } + const internal::Line& line = lines()[line_index]; - internal::TextRunList* run_list = GetRunList(); - if (run_index >= run_list->size()) - return EdgeSelectionModel((x < 0) ? CURSOR_LEFT : CURSOR_RIGHT); - const internal::TextRunHarfBuzz& run = *run_list->runs()[run_index]; + float point_offset_relative_segment = 0; + const int segment_index = GetLineSegmentContainingXCoord( + line, (view_point - GetLineOffset(line_index)).x(), + &point_offset_relative_segment); + if (segment_index < 0) + return LineSelectionModel(line_index, CURSOR_LEFT); + if (segment_index >= static_cast<int>(line.segments.size())) + return LineSelectionModel(line_index, CURSOR_RIGHT); + const internal::LineSegment& segment = line.segments[segment_index]; + + const internal::TextRunHarfBuzz& run = *GetRunList()->runs()[segment.run]; + const size_t segment_min_glyph_index = + run.CharRangeToGlyphRange(segment.char_range).GetMin(); + const float segment_offset_relative_run = + segment_min_glyph_index != 0 + ? SkScalarToFloat(run.positions[segment_min_glyph_index].x()) + : 0; + const float point_offset_relative_run = + point_offset_relative_segment + segment_offset_relative_run; + + // TODO(crbug.com/676287): Use offset within the glyph to return the correct + // grapheme position within a multi-grapheme glyph. for (size_t i = 0; i < run.glyph_count; ++i) { - const SkScalar end = - i + 1 == run.glyph_count ? run.width : run.positions[i + 1].x(); - const SkScalar middle = (end + run.positions[i].x()) / 2; - - if (offset < middle) { - return SelectionModel(DisplayIndexToTextIndex( - run.glyph_to_char[i] + (run.is_rtl ? 1 : 0)), - (run.is_rtl ? CURSOR_BACKWARD : CURSOR_FORWARD)); + const float end = i + 1 == run.glyph_count + ? run.width + : SkScalarToFloat(run.positions[i + 1].x()); + const float middle = (end + SkScalarToFloat(run.positions[i].x())) / 2; + const size_t index = DisplayIndexToTextIndex(run.glyph_to_char[i]); + if (point_offset_relative_run < middle) { + return run.is_rtl ? SelectionModel( + IndexOfAdjacentGrapheme(index, CURSOR_FORWARD), + CURSOR_BACKWARD) + : SelectionModel(index, CURSOR_FORWARD); } - if (offset < end) { - return SelectionModel(DisplayIndexToTextIndex( - run.glyph_to_char[i] + (run.is_rtl ? 0 : 1)), - (run.is_rtl ? CURSOR_FORWARD : CURSOR_BACKWARD)); + if (point_offset_relative_run < end) { + return run.is_rtl ? SelectionModel(index, CURSOR_FORWARD) + : SelectionModel( + IndexOfAdjacentGrapheme(index, CURSOR_FORWARD), + CURSOR_BACKWARD); } } - return EdgeSelectionModel(CURSOR_RIGHT); + + return LineSelectionModel(line_index, CURSOR_RIGHT); } bool RenderTextHarfBuzz::IsSelectionSupported() const { - // TODO(karandeepb): Support multi-line text selection. - return !multiline(); + return true; } std::vector<RenderText::FontSpan> RenderTextHarfBuzz::GetFontSpansForTesting() { @@ -1012,49 +1067,52 @@ std::vector<Rect> RenderTextHarfBuzz::GetSubstringBounds(const Range& range) { DCHECK(!update_display_run_list_); DCHECK(Range(0, text().length()).Contains(range)); - Range layout_range(TextIndexToDisplayIndex(range.start()), - TextIndexToDisplayIndex(range.end())); - DCHECK(Range(0, GetDisplayText().length()).Contains(layout_range)); + const size_t start = + IsValidCursorIndex(range.GetMin()) + ? range.GetMin() + : IndexOfAdjacentGrapheme(range.GetMin(), CURSOR_BACKWARD); + const size_t end = + IsValidCursorIndex(range.GetMax()) + ? range.GetMax() + : IndexOfAdjacentGrapheme(range.GetMax(), CURSOR_FORWARD); + Range display_range(TextIndexToDisplayIndex(start), + TextIndexToDisplayIndex(end)); + DCHECK(Range(0, GetDisplayText().length()).Contains(display_range)); std::vector<Rect> rects; - if (layout_range.is_empty()) + if (display_range.is_empty()) return rects; - std::vector<Range> bounds; internal::TextRunList* run_list = GetRunList(); + for (size_t line_index = 0; line_index < lines().size(); ++line_index) { + const internal::Line& line = lines()[line_index]; + // Only the last line can be empty. + DCHECK(!line.segments.empty() || (line_index == lines().size() - 1)); - // Add a Range for each run/selection intersection. - for (size_t i = 0; i < run_list->size(); ++i) { - internal::TextRunHarfBuzz* run = - run_list->runs()[run_list->visual_to_logical(i)]; - Range intersection = run->range.Intersect(layout_range); - if (!intersection.IsValid()) - continue; - DCHECK(!intersection.is_reversed()); - const size_t left_index = - run->is_rtl ? intersection.end() - 1 : intersection.start(); - const Range leftmost_character_x = - run->GetGraphemeBounds(this, left_index).Round(); - const size_t right_index = - run->is_rtl ? intersection.start() : intersection.end() - 1; - const Range rightmost_character_x = - run->GetGraphemeBounds(this, right_index).Round(); - Range range_x(leftmost_character_x.start(), rightmost_character_x.end()); - DCHECK(!range_x.is_reversed()); - if (range_x.is_empty()) - continue; - - // Union this with the last range if they're adjacent. - DCHECK(bounds.empty() || bounds.back().GetMax() <= range_x.GetMin()); - if (!bounds.empty() && bounds.back().GetMax() == range_x.GetMin()) { - range_x = Range(bounds.back().GetMin(), range_x.GetMax()); - bounds.pop_back(); + float line_x = 0; + for (const internal::LineSegment& segment : line.segments) { + const Range intersection = segment.char_range.Intersect(display_range); + DCHECK(!intersection.is_reversed()); + if (!intersection.is_empty()) { + const internal::TextRunHarfBuzz& run = *run_list->runs()[segment.run]; + float width = SkScalarToFloat( + run.GetGraphemeWidthForCharRange(this, intersection)); + float x = line_x; + if (run.is_rtl) { + x += SkScalarToFloat(run.GetGraphemeWidthForCharRange( + this, gfx::Range(intersection.end(), segment.char_range.end()))); + } else { + x += SkScalarToFloat(run.GetGraphemeWidthForCharRange( + this, + gfx::Range(segment.char_range.start(), intersection.start()))); + } + int end_x = std::ceil(x + width); + int start_x = std::ceil(x); + gfx::Rect rect(start_x, 0, end_x - start_x, line.size.height()); + rects.push_back(rect + GetLineOffset(line_index)); + } + line_x += segment.width(); } - bounds.push_back(range_x); - } - for (Range& bound : bounds) { - std::vector<Rect> current_rects = TextBoundsToViewBounds(bound); - rects.insert(rects.end(), current_rects.begin(), current_rects.end()); } return rects; } @@ -1229,23 +1287,41 @@ return run_list->size(); } -size_t RenderTextHarfBuzz::GetRunContainingXCoord(float x, - float* offset) const { - DCHECK(!update_display_run_list_); - const internal::TextRunList* run_list = GetRunList(); - if (x < 0) - return run_list->size(); - // Find the text run containing the argument point (assumed already offset). - float current_x = 0; - for (size_t i = 0; i < run_list->size(); ++i) { - size_t run = run_list->visual_to_logical(i); - current_x += run_list->runs()[run]->width; - if (x < current_x) { - *offset = x - (current_x - run_list->runs()[run]->width); - return run; - } +int RenderTextHarfBuzz::GetLineContainingYCoord(float text_y) { + if (text_y < 0) + return -1; + + for (size_t i = 0; i < lines().size(); i++) { + const internal::Line& line = lines()[i]; + + if (text_y <= line.size.height()) + return i; + text_y -= line.size.height(); } - return run_list->size(); + + return lines().size(); +} + +int RenderTextHarfBuzz::GetLineSegmentContainingXCoord( + const internal::Line& line, + float line_x, + float* offset_relative_segment) { + DCHECK(offset_relative_segment); + + *offset_relative_segment = 0; + if (line_x < 0) + return -1; + for (size_t i = 0; i < line.segments.size(); i++) { + const internal::LineSegment& segment = line.segments[i]; + + // segment.x_range is not used because it is in text space. + if (line_x < segment.width()) { + *offset_relative_segment = line_x; + return i; + } + line_x -= segment.width(); + } + return line.segments.size(); } SelectionModel RenderTextHarfBuzz::FirstSelectionModelInsideRun(
diff --git a/ui/gfx/render_text_harfbuzz.h b/ui/gfx/render_text_harfbuzz.h index d349525..fd345d2 100644 --- a/ui/gfx/render_text_harfbuzz.h +++ b/ui/gfx/render_text_harfbuzz.h
@@ -53,10 +53,13 @@ void GetClusterAt(size_t pos, Range* chars, Range* glyphs) const; // Returns the grapheme bounds at |text_index|. Handles multi-grapheme glyphs. - RangeF GetGraphemeBounds(RenderTextHarfBuzz* render_text, size_t text_index); + RangeF GetGraphemeBounds(RenderTextHarfBuzz* render_text, + size_t text_index) const; - // Returns whether the given shaped run contains any missing glyphs. - bool HasMissingGlyphs() const; + // Returns the width of the given |char_range| handling grapheme boundaries + // within glyphs. + float GetGraphemeWidthForCharRange(RenderTextHarfBuzz* render_text, + const Range& char_range) const; // Returns the glyph width for the given character range. |char_range| is in // text-space (0 corresponds to |GetDisplayText()[0]|). @@ -193,7 +196,20 @@ // Return the run index that contains the argument; or the length of the // |runs_| vector if argument exceeds the text length or width. size_t GetRunContainingCaret(const SelectionModel& caret); - size_t GetRunContainingXCoord(float x, float* offset) const; + + // Returns the line index for the given argument. |text_y| is relative to + // the text bounds. Returns -1 if |text_y| is above the text and + // lines().size() if |text_y| is below it. + int GetLineContainingYCoord(float text_y); + + // Returns the line segment index for the |line|, |text_x| pair. |text_x| is + // relative to text in the given line. Returns -1 if |text_x| is to the left + // of text in the line and |line|.segments.size() if it's to the right. + // |offset_relative_segment| will contain the offset of |text_x| relative to + // the start of the segment it is contained in. + int GetLineSegmentContainingXCoord(const internal::Line& line, + float text_x, + float* offset_relative_segment); // Given a |run|, returns the SelectionModel that contains the logical first // or last caret position inside (not at a boundary of) the run.
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index c51ef30..3657ef0 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc
@@ -10,6 +10,7 @@ #include <algorithm> #include <memory> +#include <numeric> #include "base/format_macros.h" #include "base/i18n/break_iterator.h" @@ -472,6 +473,12 @@ } #endif + Rect GetSelectionBoundsUnion() { + const std::vector<Rect> bounds = + render_text_->GetSubstringBoundsForTesting(render_text_->selection()); + return std::accumulate(bounds.begin(), bounds.end(), Rect(), UnionRects); + } + Canvas* canvas() { return &canvas_; } TestSkiaTextRenderer* renderer() { return &renderer_; } test::RenderTextTestApi* test_api() { return test_api_.get(); }; @@ -514,6 +521,10 @@ return GetRenderTextHarfBuzz()->ShapeRunWithFont(text, font, params, run); } + int GetCursorYForTesting(int line_num = 0) { + return GetRenderText()->GetLineOffset(line_num).y() + 1; + } + private: DISALLOW_COPY_AND_ASSIGN(RenderTextHarfBuzzTest); }; @@ -788,10 +799,14 @@ // FindCursorPosition() should not return positions between a surrogate pair. render_text->SetDisplayRect(Rect(0, 0, 20, 20)); - EXPECT_EQ(render_text->FindCursorPosition(Point(0, 0)).caret_pos(), 0U); - EXPECT_EQ(render_text->FindCursorPosition(Point(20, 0)).caret_pos(), 2U); + const int cursor_y = GetCursorYForTesting(); + EXPECT_EQ(render_text->FindCursorPosition(Point(0, cursor_y)).caret_pos(), + 0U); + EXPECT_EQ(render_text->FindCursorPosition(Point(20, cursor_y)).caret_pos(), + 2U); for (int x = -1; x <= 20; ++x) { - SelectionModel selection = render_text->FindCursorPosition(Point(x, 0)); + SelectionModel selection = + render_text->FindCursorPosition(Point(x, cursor_y)); EXPECT_TRUE(selection.caret_pos() == 0U || selection.caret_pos() == 2U); } @@ -1653,10 +1668,21 @@ // (code point) has unique bounds, so mid-glyph cursoring should be possible. render_text->SetFontList(FontList("Meiryo UI, 12px")); render_text->SetText(WideToUTF16(L"ff ffi")); + render_text->SetDisplayRect(gfx::Rect(100, 100)); + test_api()->EnsureLayout(); EXPECT_EQ(0U, render_text->cursor_position()); + + gfx::Rect last_selection_bounds = GetSelectionBoundsUnion(); for (size_t i = 0; i < render_text->text().length(); ++i) { - render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); + render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_RETAIN); EXPECT_EQ(i + 1, render_text->cursor_position()); + + // Verify the selection bounds also increase and that the correct bounds are + // returned even when the grapheme boundary lies within a glyph. + const gfx::Rect selection_bounds = GetSelectionBoundsUnion(); + EXPECT_GT(selection_bounds.right(), last_selection_bounds.right()); + EXPECT_EQ(selection_bounds.x(), last_selection_bounds.x()); + last_selection_bounds = selection_bounds; } EXPECT_EQ(6U, render_text->cursor_position()); } @@ -1754,6 +1780,7 @@ const base::string16 cases[] = { kHindi, kThai }; RenderText* render_text = GetRenderText(); + render_text->SetDisplayRect(Rect(100, 1000)); for (size_t i = 0; i < arraysize(cases); i++) { SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i)); render_text->SetText(cases[i]); @@ -1762,8 +1789,17 @@ EXPECT_TRUE(render_text->SelectRange(Range(2, 1))); EXPECT_EQ(Range(2, 1), render_text->selection()); EXPECT_EQ(1U, render_text->cursor_position()); + + // Verify that the selection bounds extend over the entire grapheme, even if + // the selection is set amid the grapheme. + test_api()->EnsureLayout(); + const gfx::Rect mid_grapheme_bounds = GetSelectionBoundsUnion(); + render_text->SelectAll(false); + EXPECT_EQ(GetSelectionBoundsUnion(), mid_grapheme_bounds); + // Although selection bounds may be set within a multi-character grapheme, // cursor movement (e.g. via arrow key) should avoid those indices. + EXPECT_TRUE(render_text->SelectRange(Range(2, 1))); render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE); EXPECT_EQ(0U, render_text->cursor_position()); render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); @@ -1783,11 +1819,86 @@ const Range range(render_text->GetGlyphBounds(j)); // Test a point just inside the leading edge of the glyph bounds. int x = range.is_reversed() ? range.GetMax() - 1 : range.GetMin() + 1; - EXPECT_EQ(j, render_text->FindCursorPosition(Point(x, 0)).caret_pos()); + EXPECT_EQ( + j, render_text->FindCursorPosition(Point(x, GetCursorYForTesting())) + .caret_pos()); } } } +// Tests that FindCursorPosition behaves correctly for multi-line text. +TEST_P(RenderTextHarfBuzzTest, FindCursorPositionMultiline) { + const wchar_t* kTestStrings[] = {L"abc def", + L"\x5d0\x5d1\x5d2 \x5d3\x5d4\x5d5" /*rtl*/}; + + SetGlyphWidth(5); + RenderText* render_text = GetRenderText(); + render_text->SetDisplayRect(Rect(25, 1000)); + render_text->SetMultiline(true); + + for (size_t i = 0; i < arraysize(kTestStrings); i++) { + render_text->SetText(WideToUTF16(kTestStrings[i])); + test_api()->EnsureLayout(); + EXPECT_EQ(2u, test_api()->lines().size()); + + const bool is_ltr = + render_text->GetDisplayTextDirection() == base::i18n::LEFT_TO_RIGHT; + for (size_t j = 0; j < render_text->text().length(); ++j) { + SCOPED_TRACE(base::StringPrintf( + "Testing index %" PRIuS " for case %" PRIuS "", j, i)); + render_text->SelectRange(Range(j, j + 1)); + + // Test a point inside the leading edge of the glyph bounds. + const Rect bounds = GetSelectionBoundsUnion(); + const Point cursor_position(is_ltr ? bounds.x() + 1 : bounds.right() - 1, + bounds.y() + 1); + + const SelectionModel model = + render_text->FindCursorPosition(cursor_position); + EXPECT_EQ(j, model.caret_pos()); + EXPECT_EQ(CURSOR_FORWARD, model.caret_affinity()); + } + } +} + +// Ensure FindCursorPosition returns positions only at valid grapheme +// boundaries. +TEST_P(RenderTextHarfBuzzTest, FindCursorPosition_GraphemeBoundaries) { + struct { + base::string16 text; + std::set<size_t> expected_cursor_positions; + } cases[] = { + // LTR 2-character grapheme, LTR abc, LTR 2-character grapheme. + {WideToUTF16(L"\x0915\x093f" + L"abc" + L"\x0915\x093f"), + {0, 2, 3, 4, 5, 7}}, + // LTR ab, LTR 2-character grapheme, LTR cd. + {WideToUTF16(L"ab" + L"\x0915\x093f" + L"cd"), + {0, 1, 2, 4, 5, 6}}, + // LTR ab, surrogate pair composed of two 16 bit characters, LTR cd. + {UTF8ToUTF16("ab" + "\xF0\x9D\x84\x9E" + "cd"), + {0, 1, 2, 4, 5, 6}}}; + + RenderText* render_text = GetRenderText(); + render_text->SetDisplayRect(gfx::Rect(100, 30)); + for (size_t i = 0; i < arraysize(cases); i++) { + SCOPED_TRACE(base::StringPrintf("Testing case %" PRIuS "", i)); + render_text->SetText(cases[i].text); + test_api()->EnsureLayout(); + std::set<size_t> obtained_cursor_positions; + size_t cursor_y = GetCursorYForTesting(); + for (int x = -5; x < 105; x++) + obtained_cursor_positions.insert( + render_text->FindCursorPosition(gfx::Point(x, cursor_y)).caret_pos()); + EXPECT_EQ(cases[i].expected_cursor_positions, obtained_cursor_positions); + } +} + TEST_P(RenderTextTest, EdgeSelectionModels) { // Simple Latin text. const base::string16 kLatin = WideToUTF16(L"abc"); @@ -2863,12 +2974,12 @@ // Ranges of the characters on each line preceding the newline. const Range line_char_ranges[3]; } kTestStrings[] = { - {L"abc\ndef", 2ul, { Range(0, 3), Range(4, 7), Range::InvalidRange() } }, - {L"a \n b ", 2ul, { Range(0, 2), Range(3, 6), Range::InvalidRange() } }, - {L"ab\n", 2ul, { Range(0, 2), Range(), Range::InvalidRange() } }, - {L"a\n\nb", 3ul, { Range(0, 1), Range(), Range(3, 4) } }, - {L"\nab", 2ul, { Range(), Range(1, 3), Range::InvalidRange() } }, - {L"\n", 2ul, { Range(), Range(), Range::InvalidRange() } }, + {L"abc\ndef", 2ul, {Range(0, 3), Range(4, 7), Range::InvalidRange()}}, + {L"a \n b ", 2ul, {Range(0, 2), Range(3, 6), Range::InvalidRange()}}, + {L"ab\n", 2ul, {Range(0, 2), Range(), Range::InvalidRange()}}, + {L"a\n\nb", 3ul, {Range(0, 1), Range(2, 3), Range(3, 4)}}, + {L"\nab", 2ul, {Range(0, 1), Range(1, 3), Range::InvalidRange()}}, + {L"\n", 2ul, {Range(0, 1), Range(), Range::InvalidRange()}}, }; RenderText* render_text = GetRenderText(); @@ -3898,6 +4009,7 @@ render_text->ApplyStyle(ITALIC, true, Range(3, 8)); render_text->ApplyStyle(DIAGONAL_STRIKE, true, Range(5, 7)); render_text->ApplyStyle(STRIKE, true, Range(1, 7)); + const int cursor_y = GetCursorYForTesting(); const std::vector<RenderText::FontSpan> font_spans = render_text->GetFontSpansForTesting(); @@ -3931,14 +4043,14 @@ { SCOPED_TRACE(base::StringPrintf("Query to the left of text bounds")); EXPECT_TRUE(render_text->GetDecoratedWordAtPoint( - Point(-5, 5), &decorated_word, &baseline_point)); + Point(-5, cursor_y), &decorated_word, &baseline_point)); VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word); EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point)); } { SCOPED_TRACE(base::StringPrintf("Query to the right of text bounds")); EXPECT_TRUE(render_text->GetDecoratedWordAtPoint( - Point(105, 5), &decorated_word, &baseline_point)); + Point(105, cursor_y), &decorated_word, &baseline_point)); VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word); EXPECT_TRUE(left_glyph_word_2.Contains(baseline_point)); } @@ -3982,6 +4094,7 @@ render_text->ApplyStyle(ITALIC, true, Range(0, 3)); render_text->ApplyStyle(DIAGONAL_STRIKE, true, Range(0, 2)); render_text->ApplyStyle(STRIKE, true, Range(2, 5)); + const int cursor_y = GetCursorYForTesting(); const std::vector<RenderText::FontSpan> font_spans = render_text->GetFontSpansForTesting(); @@ -4014,14 +4127,14 @@ { SCOPED_TRACE(base::StringPrintf("Query to the left of text bounds")); EXPECT_TRUE(render_text->GetDecoratedWordAtPoint( - Point(-5, 5), &decorated_word, &baseline_point)); + Point(-5, cursor_y), &decorated_word, &baseline_point)); VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word); EXPECT_TRUE(left_glyph_word_2.Contains(baseline_point)); } { SCOPED_TRACE(base::StringPrintf("Query to the right of text bounds")); EXPECT_TRUE(render_text->GetDecoratedWordAtPoint( - Point(105, 5), &decorated_word, &baseline_point)); + Point(105, cursor_y), &decorated_word, &baseline_point)); VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word); EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point)); } @@ -4076,6 +4189,82 @@ &baseline_point)); } +// Tests text selection made at end points of individual lines of multiline +// text. +TEST_P(RenderTextHarfBuzzTest, LineEndSelections) { + const wchar_t* const ltr = L"abc\n\ndef"; + const wchar_t* const rtl = L"\x5d0\x5d1\x5d2\n\n\x5d3\x5d4\x5d5"; + const int left_x = -100; + const int right_x = 200; + struct { + const wchar_t* const text; + const int line_num; + const int x; + const wchar_t* const selected_text; + } cases[] = { + {ltr, 1, left_x, L"abc\n"}, + {ltr, 1, right_x, L"abc\n\n"}, + {ltr, 2, left_x, L"abc\n\n"}, + {ltr, 2, right_x, ltr}, + + {rtl, 1, left_x, L"\x5d0\x5d1\x5d2\n\n"}, + {rtl, 1, right_x, L"\x5d0\x5d1\x5d2\n"}, + {rtl, 2, left_x, rtl}, + {rtl, 2, right_x, L"\x5d0\x5d1\x5d2\n\n"}, + }; + + RenderText* render_text = GetRenderText(); + render_text->SetMultiline(true); + render_text->SetDisplayRect(Rect(200, 1000)); + + for (size_t i = 0; i < arraysize(cases); i++) { + SCOPED_TRACE(base::StringPrintf("Testing case %" PRIuS "", i)); + render_text->SetText(WideToUTF16(cases[i].text)); + test_api()->EnsureLayout(); + + EXPECT_EQ(3u, test_api()->lines().size()); + // Position the cursor at the logical beginning of text. + render_text->SelectRange(Range(0)); + + render_text->MoveCursorTo( + Point(cases[i].x, GetCursorYForTesting(cases[i].line_num)), true); + EXPECT_EQ(WideToUTF16(cases[i].selected_text), + GetSelectedText(render_text)); + } +} + +// Tests that GetSubstringBounds returns the correct bounds for multiline text. +TEST_P(RenderTextHarfBuzzTest, GetSubstringBoundsMultiline) { + RenderText* render_text = GetRenderText(); + render_text->SetMultiline(true); + render_text->SetDisplayRect(Rect(200, 1000)); + render_text->SetText(WideToUTF16(L"abc\n\ndef")); + test_api()->EnsureLayout(); + + const std::vector<Range> line_char_range = {Range(0, 3), Range(4, 5), + Range(5, 8)}; + + // Test bounds for individual lines. + EXPECT_EQ(3u, test_api()->lines().size()); + Rect expected_total_bounds; + for (size_t i = 0; i < test_api()->lines().size(); i++) { + SCOPED_TRACE(base::StringPrintf("Testing bounds for line %" PRIuS "", i)); + const internal::Line& line = test_api()->lines()[i]; + const Size line_size(std::ceil(line.size.width()), + std::ceil(line.size.height())); + const Rect expected_line_bounds = + render_text->GetLineOffset(i) + Rect(line_size); + expected_total_bounds.Union(expected_line_bounds); + + render_text->SelectRange(line_char_range[i]); + EXPECT_EQ(expected_line_bounds, GetSelectionBoundsUnion()); + } + + // Test complete bounds. + render_text->SelectAll(false); + EXPECT_EQ(expected_total_bounds, GetSelectionBoundsUnion()); +} + // Prefix for test instantiations intentionally left blank since each test // fixture class has a single parameterization. #if defined(OS_MACOSX)
diff --git a/ui/gfx/test/icc_profiles.cc b/ui/gfx/test/icc_profiles.cc new file mode 100644 index 0000000..3ce6917 --- /dev/null +++ b/ui/gfx/test/icc_profiles.cc
@@ -0,0 +1,561 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/test/icc_profiles.h" + +namespace gfx { + +namespace { + +const unsigned char generic_rgb_profile_data[] = { + 0x00, 0x00, 0x07, 0xd8, 0x61, 0x70, 0x70, 0x6c, 0x02, 0x20, 0x00, 0x00, + 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, + 0x07, 0xd9, 0x00, 0x02, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x1a, 0x00, 0x0b, + 0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x70, 0x70, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x61, 0x70, 0x70, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x6f, + 0x64, 0x73, 0x63, 0x6d, 0x00, 0x00, 0x01, 0x78, 0x00, 0x00, 0x05, 0x9c, + 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x07, 0x14, 0x00, 0x00, 0x00, 0x38, + 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x00, 0x14, + 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x07, 0x60, 0x00, 0x00, 0x00, 0x14, + 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x07, 0x74, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x07, 0x88, 0x00, 0x00, 0x00, 0x14, + 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x07, 0x9c, 0x00, 0x00, 0x00, 0x0e, + 0x63, 0x68, 0x61, 0x64, 0x00, 0x00, 0x07, 0xac, 0x00, 0x00, 0x00, 0x2c, + 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x07, 0x9c, 0x00, 0x00, 0x00, 0x0e, + 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x07, 0x9c, 0x00, 0x00, 0x00, 0x0e, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x52, 0x47, 0x42, 0x20, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x69, 0x63, 0x20, 0x52, 0x47, 0x42, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6c, 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0c, 0x73, 0x6b, 0x53, 0x4b, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0x84, 0x64, 0x61, 0x44, 0x4b, + 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x01, 0xac, 0x63, 0x61, 0x45, 0x53, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0xda, 0x76, 0x69, 0x56, 0x4e, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0xfe, 0x70, 0x74, 0x42, 0x52, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x02, 0x22, 0x75, 0x6b, 0x55, 0x41, + 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x02, 0x48, 0x66, 0x72, 0x46, 0x55, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x02, 0x72, 0x68, 0x75, 0x48, 0x55, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x02, 0x9a, 0x7a, 0x68, 0x54, 0x57, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x02, 0xc2, 0x6e, 0x62, 0x4e, 0x4f, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x02, 0xd8, 0x63, 0x73, 0x43, 0x5a, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x02, 0xfe, 0x68, 0x65, 0x49, 0x4c, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x03, 0x20, 0x69, 0x74, 0x49, 0x54, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x03, 0x3e, 0x72, 0x6f, 0x52, 0x4f, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x03, 0x66, 0x64, 0x65, 0x44, 0x45, + 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x03, 0x8a, 0x6b, 0x6f, 0x4b, 0x52, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x03, 0xb6, 0x73, 0x76, 0x53, 0x45, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x02, 0xd8, 0x7a, 0x68, 0x43, 0x4e, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x03, 0xcc, 0x6a, 0x61, 0x4a, 0x50, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x03, 0xe2, 0x65, 0x6c, 0x47, 0x52, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x03, 0xfc, 0x70, 0x74, 0x50, 0x4f, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x04, 0x1e, 0x6e, 0x6c, 0x4e, 0x4c, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0x44, 0x65, 0x73, 0x45, 0x53, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x04, 0x1e, 0x74, 0x68, 0x54, 0x48, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x04, 0x6c, 0x74, 0x72, 0x54, 0x52, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x04, 0x90, 0x66, 0x69, 0x46, 0x49, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0xb2, 0x68, 0x72, 0x48, 0x52, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x04, 0xda, 0x70, 0x6c, 0x50, 0x4c, + 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x05, 0x02, 0x72, 0x75, 0x52, 0x55, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x05, 0x2e, 0x61, 0x72, 0x45, 0x47, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x05, 0x50, 0x65, 0x6e, 0x55, 0x53, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x05, 0x76, 0x00, 0x56, 0x01, 0x61, + 0x00, 0x65, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6e, + 0x00, 0xfd, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, + 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, + 0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, + 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x2d, + 0x00, 0x62, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6b, 0x00, 0x72, 0x00, 0x69, + 0x00, 0x76, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x65, 0x00, 0x50, + 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, + 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x67, 0x00, 0x65, + 0x00, 0x6e, 0x00, 0xe8, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x43, + 0x1e, 0xa5, 0x00, 0x75, 0x00, 0x20, 0x00, 0x68, 0x00, 0xec, 0x00, 0x6e, + 0x00, 0x68, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, + 0x00, 0x43, 0x00, 0x68, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x50, + 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, + 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x47, 0x00, 0x65, + 0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6f, + 0x04, 0x17, 0x04, 0x30, 0x04, 0x33, 0x04, 0x30, 0x04, 0x3b, 0x04, 0x4c, + 0x04, 0x3d, 0x04, 0x38, 0x04, 0x39, 0x00, 0x20, 0x04, 0x3f, 0x04, 0x40, + 0x04, 0x3e, 0x04, 0x44, 0x04, 0x30, 0x04, 0x39, 0x04, 0x3b, 0x00, 0x20, + 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, + 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x67, 0x00, 0xe9, + 0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72, 0x00, 0x69, 0x00, 0x71, 0x00, 0x75, + 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00, 0x56, 0x00, 0x42, 0x00, 0xc1, + 0x00, 0x6c, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6c, 0x00, 0xe1, 0x00, 0x6e, + 0x00, 0x6f, 0x00, 0x73, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, + 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, + 0x00, 0x6c, 0x90, 0x1a, 0x75, 0x28, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, + 0x00, 0x42, 0x00, 0x20, 0x82, 0x72, 0x5f, 0x69, 0x63, 0xcf, 0x8f, 0xf0, + 0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, + 0x00, 0x73, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, + 0x00, 0x2d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, + 0x00, 0x6c, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6e, + 0x00, 0xfd, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, + 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, + 0x05, 0xe4, 0x05, 0xe8, 0x05, 0xd5, 0x05, 0xe4, 0x05, 0xd9, 0x05, 0xdc, + 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x05, 0xdb, + 0x05, 0xdc, 0x05, 0xdc, 0x05, 0xd9, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, + 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x52, + 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6e, + 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x50, + 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, + 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x67, 0x00, 0x65, + 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x41, + 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, + 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x52, + 0x00, 0x47, 0x00, 0x42, 0x00, 0x2d, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, + 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0xc7, 0x7c, 0xbc, 0x18, 0x00, 0x20, + 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0xd5, 0x04, 0xb8, 0x5c, + 0xd3, 0x0c, 0xc7, 0x7c, 0x66, 0x6e, 0x90, 0x1a, 0x00, 0x20, 0x00, 0x52, + 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x63, 0xcf, 0x8f, 0xf0, 0x65, 0x87, + 0x4e, 0xf6, 0x4e, 0x00, 0x82, 0x2c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, + 0x00, 0x42, 0x00, 0x20, 0x30, 0xd7, 0x30, 0xed, 0x30, 0xd5, 0x30, 0xa1, + 0x30, 0xa4, 0x30, 0xeb, 0x03, 0x93, 0x03, 0xb5, 0x03, 0xbd, 0x03, 0xb9, + 0x03, 0xba, 0x03, 0xcc, 0x00, 0x20, 0x03, 0xc0, 0x03, 0xc1, 0x03, 0xbf, + 0x03, 0xc6, 0x03, 0xaf, 0x03, 0xbb, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, + 0x00, 0x42, 0x00, 0x50, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x69, + 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, + 0x00, 0x67, 0x00, 0x65, 0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72, 0x00, 0x69, + 0x00, 0x63, 0x00, 0x6f, 0x00, 0x41, 0x00, 0x6c, 0x00, 0x67, 0x00, 0x65, + 0x00, 0x6d, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x52, + 0x00, 0x47, 0x00, 0x42, 0x00, 0x2d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, + 0x00, 0x66, 0x00, 0x69, 0x00, 0x65, 0x00, 0x6c, 0x0e, 0x42, 0x0e, 0x1b, + 0x0e, 0x23, 0x0e, 0x44, 0x0e, 0x1f, 0x0e, 0x25, 0x0e, 0x4c, 0x00, 0x20, + 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x0e, 0x17, 0x0e, 0x31, + 0x0e, 0x48, 0x0e, 0x27, 0x0e, 0x44, 0x0e, 0x1b, 0x00, 0x47, 0x00, 0x65, + 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, + 0x00, 0x42, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, + 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x59, 0x00, 0x6c, 0x00, 0x65, + 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x52, + 0x00, 0x47, 0x00, 0x42, 0x00, 0x2d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, + 0x00, 0x66, 0x00, 0x69, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x47, + 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x01, 0x0d, + 0x00, 0x6b, 0x00, 0x69, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, + 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, + 0x00, 0x6c, 0x00, 0x55, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x77, 0x00, 0x65, + 0x00, 0x72, 0x00, 0x73, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x6e, 0x00, 0x79, + 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, + 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x04, 0x1e, + 0x04, 0x31, 0x04, 0x49, 0x04, 0x38, 0x04, 0x39, 0x00, 0x20, 0x04, 0x3f, + 0x04, 0x40, 0x04, 0x3e, 0x04, 0x44, 0x04, 0x38, 0x04, 0x3b, 0x04, 0x4c, + 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x06, 0x45, 0x06, 0x44, + 0x06, 0x41, 0x00, 0x20, 0x06, 0x2a, 0x06, 0x39, 0x06, 0x31, 0x06, 0x4a, + 0x06, 0x41, 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, + 0x06, 0x27, 0x06, 0x44, 0x06, 0x39, 0x06, 0x27, 0x06, 0x45, 0x00, 0x47, + 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, + 0x00, 0x20, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, 0x00, 0x50, + 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, + 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x37, 0x20, 0x41, + 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x2c, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x00, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x52, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x16, 0xcf, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x74, 0x4d, 0x00, 0x00, 0x3d, 0xee, 0x00, 0x00, 0x03, 0xd0, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x75, + 0x00, 0x00, 0xac, 0x73, 0x00, 0x00, 0x17, 0x34, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1a, 0x00, 0x00, 0x15, 0x9f, + 0x00, 0x00, 0xb8, 0x36, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0xcd, 0x00, 0x00, 0x73, 0x66, 0x33, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x42, 0x00, 0x00, 0x05, 0xde, + 0xff, 0xff, 0xf3, 0x26, 0x00, 0x00, 0x07, 0x92, 0x00, 0x00, 0xfd, 0x91, + 0xff, 0xff, 0xfb, 0xa2, 0xff, 0xff, 0xfd, 0xa3, 0x00, 0x00, 0x03, 0xdc, + 0x00, 0x00, 0xc0, 0x6c}; + +const unsigned char srgb_profile_data[] = { + 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00, 0x00, + 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, + 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, + 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x33, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x00, 0x6c, + 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14, + 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x14, + 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x2c, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, + 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70, + 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, + 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x86, + 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24, + 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x14, + 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x24, + 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x0c, + 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, + 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, + 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, + 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74, 0x74, 0x2d, 0x50, + 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, + 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, + 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, + 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00, 0x38, 0xf5, + 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x62, 0x99, 0x00, 0x00, 0xb7, 0x85, 0x00, 0x00, 0x18, 0xda, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xa0, + 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, + 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e, + 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, + 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, + 0x31, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, + 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, + 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, + 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, + 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, + 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65, + 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, + 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x65, 0x77, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa4, 0xfe, 0x00, 0x14, 0x5f, 0x2e, + 0x00, 0x10, 0xcf, 0x14, 0x00, 0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, + 0x00, 0x03, 0x5c, 0x9e, 0x00, 0x00, 0x00, 0x01, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x57, 0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8f, + 0x00, 0x00, 0x00, 0x02, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, + 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, + 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, + 0x00, 0x4f, 0x00, 0x54, 0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, + 0x00, 0x6d, 0x00, 0x72, 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, + 0x00, 0x8b, 0x00, 0x90, 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, + 0x00, 0xa9, 0x00, 0xae, 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, + 0x00, 0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, + 0x00, 0xe5, 0x00, 0xeb, 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, + 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, + 0x01, 0x2b, 0x01, 0x32, 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, + 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, + 0x01, 0x7c, 0x01, 0x83, 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, + 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, + 0x01, 0xd9, 0x01, 0xe1, 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, + 0x02, 0x0c, 0x02, 0x14, 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, + 0x02, 0x41, 0x02, 0x4b, 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, + 0x02, 0x7a, 0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, + 0x02, 0xb6, 0x02, 0xc1, 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, + 0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, + 0x03, 0x38, 0x03, 0x43, 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, + 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, + 0x03, 0xc7, 0x03, 0xd3, 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, + 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, + 0x04, 0x63, 0x04, 0x71, 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, + 0x04, 0xb6, 0x04, 0xc4, 0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, + 0x05, 0x0d, 0x05, 0x1c, 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, + 0x05, 0x67, 0x05, 0x77, 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, + 0x05, 0xc5, 0x05, 0xd5, 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, + 0x06, 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, + 0x06, 0x8c, 0x06, 0x9d, 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, + 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, + 0x07, 0x61, 0x07, 0x74, 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, + 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, + 0x08, 0x46, 0x08, 0x5a, 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, + 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, + 0x09, 0x3a, 0x09, 0x4f, 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, + 0x09, 0xba, 0x09, 0xcf, 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, + 0x0a, 0x3d, 0x0a, 0x54, 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, + 0x0a, 0xc5, 0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, + 0x0b, 0x51, 0x0b, 0x69, 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, + 0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, + 0x0c, 0x75, 0x0c, 0x8e, 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, + 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, + 0x0d, 0xa9, 0x0d, 0xc3, 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, + 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, + 0x0e, 0xee, 0x0f, 0x09, 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, + 0x0f, 0x96, 0x0f, 0xb3, 0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, + 0x10, 0x43, 0x10, 0x61, 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, + 0x10, 0xf5, 0x11, 0x13, 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, + 0x11, 0xaa, 0x11, 0xc9, 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, + 0x12, 0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, + 0x13, 0x23, 0x13, 0x43, 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, + 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, + 0x14, 0xad, 0x14, 0xce, 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, + 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, + 0x16, 0x49, 0x16, 0x6c, 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, + 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, + 0x17, 0xf7, 0x18, 0x1b, 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, + 0x18, 0xd5, 0x18, 0xfa, 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, + 0x19, 0xb7, 0x19, 0xdd, 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, + 0x1a, 0x9e, 0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, + 0x1b, 0x8a, 0x1b, 0xb2, 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, + 0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, + 0x1d, 0x70, 0x1d, 0x99, 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, + 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, + 0x1f, 0x69, 0x1f, 0x94, 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, + 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, + 0x21, 0x75, 0x21, 0xa1, 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, + 0x22, 0x82, 0x22, 0xaf, 0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, + 0x23, 0x94, 0x23, 0xc2, 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, + 0x24, 0xab, 0x24, 0xda, 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, + 0x25, 0xc7, 0x25, 0xf7, 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, + 0x26, 0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, + 0x28, 0x0d, 0x28, 0x3f, 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, + 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, + 0x2a, 0x68, 0x2a, 0x9b, 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, + 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, + 0x2c, 0xd7, 0x2d, 0x0c, 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, + 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, + 0x2f, 0x5a, 0x2f, 0x91, 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, + 0x30, 0xa4, 0x30, 0xdb, 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, + 0x31, 0xf2, 0x32, 0x2a, 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, + 0x33, 0x46, 0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, + 0x34, 0x9e, 0x34, 0xd8, 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, + 0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, + 0x37, 0x60, 0x37, 0x9c, 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, + 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, + 0x3a, 0x36, 0x3a, 0x74, 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, + 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, + 0x3d, 0x22, 0x3d, 0x61, 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, + 0x3e, 0xa0, 0x3e, 0xe0, 0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, + 0x40, 0x23, 0x40, 0x64, 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, + 0x41, 0xac, 0x41, 0xee, 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, + 0x43, 0x3a, 0x43, 0x7d, 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, + 0x44, 0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, + 0x46, 0x67, 0x46, 0xab, 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, + 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, + 0x49, 0xa9, 0x49, 0xf0, 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, + 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, + 0x4d, 0x02, 0x4d, 0x4a, 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, + 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, + 0x50, 0x71, 0x50, 0xbb, 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, + 0x52, 0x31, 0x52, 0x7c, 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, + 0x53, 0xf6, 0x54, 0x42, 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, + 0x55, 0xc2, 0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, + 0x57, 0x92, 0x57, 0xe0, 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, + 0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, + 0x5b, 0x45, 0x5b, 0x95, 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, + 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, + 0x5f, 0x0f, 0x5f, 0x61, 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, + 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, + 0x62, 0xf0, 0x63, 0x43, 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, + 0x64, 0xe9, 0x65, 0x3d, 0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, + 0x66, 0xe8, 0x67, 0x3d, 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, + 0x68, 0xec, 0x69, 0x43, 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, + 0x6a, 0xf7, 0x6b, 0x4f, 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, + 0x6d, 0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, + 0x6f, 0x1e, 0x6f, 0x78, 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, + 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, + 0x73, 0x5d, 0x73, 0xb8, 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, + 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, + 0x77, 0xb3, 0x78, 0x11, 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, + 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, + 0x7c, 0x21, 0x7c, 0x81, 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, + 0x7e, 0x62, 0x7e, 0xc2, 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, + 0x80, 0xa8, 0x81, 0x0a, 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, + 0x82, 0xf4, 0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, + 0x85, 0x47, 0x85, 0xab, 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, + 0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, + 0x89, 0xfe, 0x8a, 0x64, 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, + 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, + 0x8e, 0xce, 0x8f, 0x36, 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, + 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, + 0x93, 0xb6, 0x94, 0x20, 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, + 0x96, 0x34, 0x96, 0x9f, 0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, + 0x98, 0xb8, 0x99, 0x24, 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, + 0x9b, 0x42, 0x9b, 0xaf, 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, + 0x9d, 0xd2, 0x9e, 0x40, 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, + 0xa0, 0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, + 0xa3, 0x06, 0xa3, 0x76, 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, + 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, + 0xa8, 0x52, 0xa8, 0xc4, 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, + 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, + 0xad, 0xb8, 0xae, 0x2d, 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, + 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, + 0xb3, 0x38, 0xb3, 0xae, 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, + 0xb6, 0x01, 0xb6, 0x79, 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, + 0xb8, 0xd1, 0xb9, 0x4a, 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, + 0xbb, 0xa7, 0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, + 0xbe, 0x84, 0xbe, 0xff, 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, + 0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, + 0xc4, 0x51, 0xc4, 0xce, 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, + 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, + 0xca, 0x38, 0xca, 0xb7, 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, + 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, + 0xd0, 0x39, 0xd0, 0xba, 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, + 0xd3, 0x44, 0xd3, 0xc6, 0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, + 0xd6, 0x55, 0xd6, 0xd8, 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, + 0xd9, 0x6c, 0xd9, 0xf1, 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, + 0xdc, 0x8a, 0xdd, 0x10, 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, + 0xdf, 0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, + 0xe2, 0xdb, 0xe3, 0x63, 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, + 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, + 0xe9, 0x46, 0xe9, 0xd0, 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, + 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, + 0xef, 0xcc, 0xf0, 0x58, 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, + 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, + 0xf6, 0x6d, 0xf6, 0xfb, 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, + 0xf9, 0xc7, 0xfa, 0x57, 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, + 0xfd, 0x29, 0xfd, 0xba, 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff}; + +const unsigned char colorspin_profile_data[] = { + 0x00, 0x00, 0x01, 0xea, 0x54, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x63, 0x73, 0x70, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x74, 0x65, 0x73, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0d, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8c, + 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x00, 0x14, + 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xa0, 0x00, 0x00, 0x00, 0x14, + 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xb4, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x00, 0x00, 0x14, + 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, + 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, + 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x0e, + 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x77, 0x68, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x2e, + 0x69, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x52, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, + 0x00, 0x00, 0x0f, 0x95, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x26, 0x31, 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9b, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, + 0x00, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x04, 0xfc, 0x63, 0x75, 0x72, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33}; + +const unsigned char adobe_rgb_profile_data[] = { + 0x00, 0x00, 0x02, 0x30, 0x41, 0x44, 0x42, 0x45, 0x02, 0x10, 0x00, 0x00, + 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, + 0x07, 0xd0, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x33, 0x00, 0x3b, + 0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c, 0x00, 0x00, 0x00, 0x00, + 0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x41, 0x44, 0x42, 0x45, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x32, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x6b, + 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x14, + 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xc4, 0x00, 0x00, 0x00, 0x0e, + 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x00, 0x0e, + 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, 0x00, 0x0e, + 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x00, 0x14, + 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x14, + 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20, 0x41, + 0x64, 0x6f, 0x62, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, + 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x52, 0x47, + 0x42, 0x20, 0x28, 0x31, 0x39, 0x39, 0x38, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33, 0x00, 0x00, + 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x33, 0x00, 0x00, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x33, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, 0x00, 0x00, 0x4f, 0xa5, + 0x00, 0x00, 0x04, 0xfc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, 0x00, 0x00, 0x0f, 0x95, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x31, + 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9c}; +} + +ICCProfile ICCProfileForTestingAdobeRGB() { + return ICCProfile::FromData( + reinterpret_cast<const char*>(adobe_rgb_profile_data), + arraysize(adobe_rgb_profile_data)); +} + +ICCProfile ICCProfileForTestingGenericRGB() { + return ICCProfile::FromData( + reinterpret_cast<const char*>(generic_rgb_profile_data), + arraysize(generic_rgb_profile_data)); +} + +ICCProfile ICCProfileForTestingSRGB() { + return ICCProfile::FromData(reinterpret_cast<const char*>(srgb_profile_data), + arraysize(srgb_profile_data)); +} + +ICCProfile ICCProfileForTestingColorSpin() { + return ICCProfile::FromData( + reinterpret_cast<const char*>(colorspin_profile_data), + arraysize(colorspin_profile_data)); +} + +} // namespace gfx
diff --git a/ui/gfx/icc_profile_unittest.h b/ui/gfx/test/icc_profiles.h similarity index 69% rename from ui/gfx/icc_profile_unittest.h rename to ui/gfx/test/icc_profiles.h index 3cf671d..5eb9bd3 100644 --- a/ui/gfx/icc_profile_unittest.h +++ b/ui/gfx/test/icc_profiles.h
@@ -2,9 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ui/gfx/icc_profile.h" + namespace gfx { -ICCProfile ICCProfileForTestingSRGB(); +ICCProfile ICCProfileForTestingAdobeRGB(); ICCProfile ICCProfileForTestingColorSpin(); +ICCProfile ICCProfileForTestingGenericRGB(); +ICCProfile ICCProfileForTestingSRGB(); } // namespace gfx
diff --git a/ui/views/accessible_pane_view_unittest.cc b/ui/views/accessible_pane_view_unittest.cc index 8de1a83..4473d8c4 100644 --- a/ui/views/accessible_pane_view_unittest.cc +++ b/ui/views/accessible_pane_view_unittest.cc
@@ -137,7 +137,7 @@ EXPECT_EQ(test_view_bar->child_button(), test_view_bar->GetWidget()->GetFocusManager()->GetFocusedView()); - if (!IsMus() && !IsAuraMusClient()) { + if (!IsMus()) { // Deactivate() is only reliable on Ash. On Windows it uses // ::GetNextWindow() to simply activate another window, and which one is not // predictable. On Mac, Deactivate() is not implemented. Note that
diff --git a/ui/views/controls/button/custom_button_unittest.cc b/ui/views/controls/button/custom_button_unittest.cc index 14256415..7fca6911 100644 --- a/ui/views/controls/button/custom_button_unittest.cc +++ b/ui/views/controls/button/custom_button_unittest.cc
@@ -221,24 +221,21 @@ aura::test::TestCursorClient cursor_client( widget()->GetNativeView()->GetRootWindow()); - // Mus doesn't support disabling mouse events. https://crbug.com/618321 - if (!IsMus()) { - // In Aura views, no new hover effects are invoked if mouse events - // are disabled. - cursor_client.DisableMouseEvents(); + // In Aura views, no new hover effects are invoked if mouse events + // are disabled. + cursor_client.DisableMouseEvents(); - button()->SetEnabled(false); - EXPECT_EQ(CustomButton::STATE_DISABLED, button()->state()); + button()->SetEnabled(false); + EXPECT_EQ(CustomButton::STATE_DISABLED, button()->state()); - button()->SetEnabled(true); - EXPECT_EQ(CustomButton::STATE_NORMAL, button()->state()); + button()->SetEnabled(true); + EXPECT_EQ(CustomButton::STATE_NORMAL, button()->state()); - button()->SetVisible(false); - EXPECT_EQ(CustomButton::STATE_NORMAL, button()->state()); + button()->SetVisible(false); + EXPECT_EQ(CustomButton::STATE_NORMAL, button()->state()); - button()->SetVisible(true); - EXPECT_EQ(CustomButton::STATE_NORMAL, button()->state()); - } + button()->SetVisible(true); + EXPECT_EQ(CustomButton::STATE_NORMAL, button()->state()); #endif // !defined(OS_MACOSX) || defined(USE_AURA) }
diff --git a/ui/views/controls/button/menu_button_unittest.cc b/ui/views/controls/button/menu_button_unittest.cc index fe43c7a..adb1a6d 100644 --- a/ui/views/controls/button/menu_button_unittest.cc +++ b/ui/views/controls/button/menu_button_unittest.cc
@@ -342,15 +342,10 @@ // Test that the MenuButton stays pressed while there are any PressedLocks. TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) { - // Hovered-state is not updated under mus when EventGenerator send a - // mouse-move event. https://crbug.com/615033 - if (IsMus()) - return; - // Similarly for aura-mus-client the location of the cursor is not updated by // EventGenerator so that IsMouseHovered() checks the wrong thing. // https://crbug.com/615033. - if (IsAuraMusClient()) + if (IsMus()) return; CreateMenuButtonWithNoListener(); @@ -541,13 +536,9 @@ // Tests that the MenuButton does not become pressed if it can be dragged, and a // DragDropClient is processing the events. TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) { - // The test uses drag-n-drop, which isn't yet supported on mus. - // https://crbug.com/614037. - if (IsMus()) - return; // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; TestMenuButtonListener menu_button_listener; CreateMenuButtonWithMenuButtonListener(&menu_button_listener); @@ -571,14 +562,10 @@ // Tests if the listener is notified correctly when a gesture tap happens on a // MenuButton that has a MenuButtonListener. TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) { - // Hovered-state is not updated under mus when EventGenerator send a - // mouse-move event. https://crbug.com/615033 - if (IsMus()) - return; // Similarly for aura-mus-client the location of the cursor is not updated by // EventGenerator so that IsMouseHovered() checks the wrong thing. // https://crbug.com/615033. - if (IsAuraMusClient()) + if (IsMus()) return; TestMenuButtonListener menu_button_listener; CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc index ce7ee024..9b04c091 100644 --- a/ui/views/controls/label.cc +++ b/ui/views/controls/label.cc
@@ -175,8 +175,6 @@ if (render_text_->MultilineSupported()) render_text_->SetMultiline(multi_line); render_text_->SetReplaceNewlineCharsWithSymbols(!multi_line); - if (multi_line) - SetSelectable(false); ResetLayout(); } @@ -250,7 +248,7 @@ } bool Label::IsSelectionSupported() const { - return !multi_line() && !obscured() && render_text_->IsSelectionSupported(); + return !obscured() && render_text_->IsSelectionSupported(); } bool Label::SetSelectable(bool value) {
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h index fbf67e7..6293cff50 100644 --- a/ui/views/controls/label.h +++ b/ui/views/controls/label.h
@@ -147,6 +147,13 @@ // Get the text as displayed to the user, respecting the obscured flag. base::string16 GetDisplayTextForTesting(); + // Returns true if the label can be made selectable. For example, links do not + // support text selection. + // Subclasses should override this function in case they want to selectively + // support text selection. If a subclass stops supporting text selection, it + // should call SetSelectable(false). + virtual bool IsSelectionSupported() const; + // Returns true if the label is selectable. Default is false. bool selectable() const { return !!selection_controller_; } @@ -195,13 +202,6 @@ SkColor disabled_color() const { return actual_disabled_color_; } - // Returns true if the label can be made selectable. For example, links do not - // support text selection. - // Subclasses should override this function in case they want to selectively - // support text selection. If a subclass stops supporting text selection, it - // should call SetSelectable(false). - virtual bool IsSelectionSupported() const; - // View: void OnBoundsChanged(const gfx::Rect& previous_bounds) override; void VisibilityChanged(View* starting_from, bool is_visible) override;
diff --git a/ui/views/controls/label_unittest.cc b/ui/views/controls/label_unittest.cc index e8fa4f9..094c336 100644 --- a/ui/views/controls/label_unittest.cc +++ b/ui/views/controls/label_unittest.cc
@@ -28,6 +28,7 @@ #include "ui/views/widget/widget.h" using base::ASCIIToUTF16; +using base::WideToUTF16; #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16) @@ -179,12 +180,30 @@ label()->OnMouseDragged(drag); } - gfx::Point GetCursorPoint(int cursor_pos) { - return label() - ->GetRenderTextForSelectionController() - ->GetCursorBounds(gfx::SelectionModel(cursor_pos, gfx::CURSOR_FORWARD), - false) - .origin(); + // Used to force layout on the underlying RenderText instance. + void SimulatePaint() { + gfx::Canvas canvas; + label()->OnPaint(&canvas); + } + + gfx::Point GetCursorPoint(int index) { + SimulatePaint(); + gfx::RenderText* render_text = + label()->GetRenderTextForSelectionController(); + const std::vector<gfx::Rect> bounds = + render_text->GetSubstringBoundsForTesting(gfx::Range(index, index + 1)); + DCHECK_EQ(1u, bounds.size()); + + const bool rtl = + render_text->GetDisplayTextDirection() == base::i18n::RIGHT_TO_LEFT; + // Return Point corresponding to the leading edge of the character. + return gfx::Point(rtl ? bounds[0].right() - 1 : bounds[0].x() + 1, + bounds[0].y() + bounds[0].height() / 2); + } + + size_t GetLineCount() { + SimulatePaint(); + return label()->GetRenderTextForSelectionController()->GetNumLines(); } base::string16 GetSelectedText() { return label()->GetSelectedText(); } @@ -820,13 +839,9 @@ ASSERT_TRUE(label()->SetSelectable(true)); EXPECT_TRUE(label()->selectable()); - // Verify that making a label multiline causes the label to not support text + // Verify that making a label multiline still causes the label to support text // selection. label()->SetMultiLine(true); - EXPECT_FALSE(label()->selectable()); - - label()->SetMultiLine(false); - ASSERT_TRUE(label()->SetSelectable(true)); EXPECT_TRUE(label()->selectable()); // Verify that obscuring the label text causes the label to not support text @@ -886,19 +901,19 @@ label()->SizeToPreferredSize(); ASSERT_TRUE(label()->SetSelectable(true)); - PerformClick(gfx::Point()); + PerformClick(GetCursorPoint(0)); EXPECT_TRUE(GetSelectedText().empty()); // Double clicking should select the word under cursor. - PerformClick(gfx::Point(), ui::EF_IS_DOUBLE_CLICK); + PerformClick(GetCursorPoint(0), ui::EF_IS_DOUBLE_CLICK); EXPECT_STR_EQ("Label", GetSelectedText()); // Triple clicking should select all the text. - PerformClick(gfx::Point()); + PerformClick(GetCursorPoint(0)); EXPECT_EQ(label()->text(), GetSelectedText()); // Clicking again should alternate to double click. - PerformClick(gfx::Point()); + PerformClick(GetCursorPoint(0)); EXPECT_STR_EQ("Label", GetSelectedText()); // Clicking at another location should clear the selection. @@ -915,20 +930,83 @@ ASSERT_TRUE(label()->SetSelectable(true)); PerformMousePress(GetCursorPoint(5)); - PerformMouseDragTo(gfx::Point()); + PerformMouseDragTo(GetCursorPoint(0)); EXPECT_STR_EQ("Label", GetSelectedText()); PerformMouseDragTo(GetCursorPoint(8)); EXPECT_STR_EQ(" mo", GetSelectedText()); - PerformMouseDragTo(gfx::Point(200, 0)); - PerformMouseRelease(gfx::Point(200, 0)); + PerformMouseDragTo(gfx::Point(200, GetCursorPoint(0).y())); + PerformMouseRelease(gfx::Point(200, GetCursorPoint(0).y())); EXPECT_STR_EQ(" mouse drag", GetSelectedText()); event_generator()->PressKey(ui::VKEY_C, kControlCommandModifier); EXPECT_STR_EQ(" mouse drag", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE)); } +TEST_F(LabelSelectionTest, MouseDragMultilineLTR) { + label()->SetMultiLine(true); + label()->SetText(ASCIIToUTF16("abcd\nefgh")); + label()->SizeToPreferredSize(); + ASSERT_TRUE(label()->SetSelectable(true)); + ASSERT_EQ(2u, GetLineCount()); + + PerformMousePress(GetCursorPoint(2)); + PerformMouseDragTo(GetCursorPoint(0)); + EXPECT_STR_EQ("ab", GetSelectedText()); + + PerformMouseDragTo(GetCursorPoint(7)); + EXPECT_STR_EQ("cd\nef", GetSelectedText()); + + PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y())); + EXPECT_STR_EQ("cd\n", GetSelectedText()); + + PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y())); + EXPECT_STR_EQ("cd\nefgh", GetSelectedText()); + + PerformMouseDragTo(gfx::Point(GetCursorPoint(3).x(), -5)); + EXPECT_STR_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "ab" : "c", + GetSelectedText()); + + PerformMouseDragTo(gfx::Point(GetCursorPoint(7).x(), 100)); + EXPECT_STR_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "cd\nefgh" + : "cd\nef", + GetSelectedText()); +} + +TEST_F(LabelSelectionTest, MouseDragMultilineRTL) { + label()->SetMultiLine(true); + label()->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\n\x5d3\x5d4\x5d5")); + label()->SizeToPreferredSize(); + ASSERT_TRUE(label()->SetSelectable(true)); + ASSERT_EQ(2u, GetLineCount()); + + PerformMousePress(GetCursorPoint(1)); + PerformMouseDragTo(GetCursorPoint(0)); + EXPECT_EQ(WideToUTF16(L"\x5d0"), GetSelectedText()); + + PerformMouseDragTo(GetCursorPoint(6)); + EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4"), GetSelectedText()); + + PerformMouseDragTo(gfx::Point(-5, GetCursorPoint(6).y())); + EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4\x5d5"), GetSelectedText()); + + PerformMouseDragTo(gfx::Point(100, GetCursorPoint(6).y())); + EXPECT_EQ(WideToUTF16(L"\x5d1\x5d2\n"), GetSelectedText()); + + PerformMouseDragTo(gfx::Point(GetCursorPoint(2).x(), -5)); + EXPECT_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds + ? WideToUTF16(L"\x5d0") + : WideToUTF16(L"\x5d1"), + GetSelectedText()); + + PerformMouseDragTo(gfx::Point(GetCursorPoint(6).x(), 100)); + EXPECT_EQ(gfx::RenderText::kDragToEndIfOutsideVerticalBounds + ? WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4\x5d5") + : WideToUTF16(L"\x5d1\x5d2\n\x5d3\x5d4"), + GetSelectedText()); +} + // Verify the initially selected word on a double click, remains selected on // mouse dragging. TEST_F(LabelSelectionTest, MouseDragWord) { @@ -940,11 +1018,11 @@ PerformMousePress(GetCursorPoint(8), ui::EF_IS_DOUBLE_CLICK); EXPECT_STR_EQ("drag", GetSelectedText()); - PerformMouseDragTo(gfx::Point()); + PerformMouseDragTo(GetCursorPoint(0)); EXPECT_STR_EQ("Label drag", GetSelectedText()); - PerformMouseDragTo(gfx::Point(200, 0)); - PerformMouseRelease(gfx::Point(200, 0)); + PerformMouseDragTo(gfx::Point(200, GetCursorPoint(0).y())); + PerformMouseRelease(gfx::Point(200, GetCursorPoint(0).y())); EXPECT_STR_EQ("drag word", GetSelectedText()); } @@ -963,8 +1041,8 @@ // Verify text selection using the mouse updates the selection clipboard. PerformMousePress(GetCursorPoint(5)); - PerformMouseDragTo(gfx::Point()); - PerformMouseRelease(gfx::Point()); + PerformMouseDragTo(GetCursorPoint(0)); + PerformMouseRelease(GetCursorPoint(0)); EXPECT_STR_EQ("Label", GetSelectedText()); EXPECT_STR_EQ("Label", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION)); }
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc index 406e309c..804313f 100644 --- a/ui/views/controls/menu/menu_controller_unittest.cc +++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -1427,12 +1427,6 @@ // crash. TEST_F(MenuControllerTest, MenuControllerReplacedDuringDrag) { // TODO: this test wedges with aura-mus-client. http://crbug.com/664280. - if (IsAuraMusClient()) - return; - - // This test creates two native widgets, but expects the child native widget - // to be able to reach up and use the parent native widget's aura - // objects. https://crbug.com/614037 if (IsMus()) return; @@ -1450,12 +1444,6 @@ // destroys the Widget used for drag-and-drop, thereby ending the drag. TEST_F(MenuControllerTest, CancelAllDuringDrag) { // TODO: this test wedges with aura-mus-client. http://crbug.com/664280. - if (IsAuraMusClient()) - return; - - // This test creates two native widgets, but expects the child native widget - // to be able to reach up and use the parent native widget's aura - // objects. https://crbug.com/614037 if (IsMus()) return;
diff --git a/ui/views/controls/menu/menu_runner_unittest.cc b/ui/views/controls/menu/menu_runner_unittest.cc index 689f86ff..3551e11 100644 --- a/ui/views/controls/menu/menu_runner_unittest.cc +++ b/ui/views/controls/menu/menu_runner_unittest.cc
@@ -108,7 +108,7 @@ TEST_F(MenuRunnerTest, AsynchronousKeyEventHandling) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; InitMenuRunner(MenuRunner::ASYNC); @@ -132,7 +132,7 @@ TEST_F(MenuRunnerTest, LatinMnemonic) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; InitMenuRunner(MenuRunner::ASYNC); @@ -157,7 +157,7 @@ TEST_F(MenuRunnerTest, NonLatinMnemonic) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; InitMenuRunner(MenuRunner::ASYNC); @@ -242,7 +242,7 @@ std::unique_ptr<ui::test::EventGenerator> EventGeneratorForWidget( Widget* widget) { return base::MakeUnique<ui::test::EventGenerator>( - IsMus() || IsAuraMusClient() ? widget->GetNativeWindow() : GetContext(), + IsMus() ? widget->GetNativeWindow() : GetContext(), widget->GetNativeWindow()); }
diff --git a/ui/views/controls/native/native_view_host_aura_unittest.cc b/ui/views/controls/native/native_view_host_aura_unittest.cc index 41692732..a0833e02 100644 --- a/ui/views/controls/native/native_view_host_aura_unittest.cc +++ b/ui/views/controls/native/native_view_host_aura_unittest.cc
@@ -269,7 +269,7 @@ DestroyHost(); DestroyTopLevel(); - if (!IsMus() && !IsAuraMusClient()) { + if (!IsMus()) { // The window is detached, so no longer associated with any Widget // hierarchy. The root window still owns it, but the test harness checks // for orphaned windows during TearDown().
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index 5a20610c..858e7d5 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -598,6 +598,10 @@ gfx::SelectionModel(cursor_pos, gfx::CURSOR_FORWARD), false).x(); } + int GetCursorYForTesting() { + return test_api_->GetRenderText()->GetLineOffset(0).y() + 1; + } + // Get the current cursor bounds. gfx::Rect GetCursorBounds() { return test_api_->GetRenderText()->GetUpdatedCursorBounds(); @@ -1391,7 +1395,7 @@ // Test if clicking on textfield view sets the focus. widget_->GetFocusManager()->AdvanceFocus(true); EXPECT_EQ(3, GetFocusedView()->id()); - MoveMouseTo(gfx::Point()); + MoveMouseTo(gfx::Point(0, GetCursorYForTesting())); ClickLeftMouseButton(); EXPECT_EQ(1, GetFocusedView()->id()); @@ -1443,7 +1447,7 @@ textfield_->SetText(ASCIIToUTF16("hello world")); // Test for double click. - MoveMouseTo(gfx::Point()); + MoveMouseTo(gfx::Point(0, GetCursorYForTesting())); ClickLeftMouseButton(); EXPECT_TRUE(textfield_->GetSelectedText().empty()); ClickLeftMouseButton(ui::EF_IS_DOUBLE_CLICK); @@ -1466,13 +1470,14 @@ // Verify right clicking within the selection does not alter the selection. textfield_->SelectRange(gfx::Range(1, 5)); EXPECT_STR_EQ("ello", textfield_->GetSelectedText()); - MoveMouseTo(gfx::Point(GetCursorPositionX(3), 0)); + const int cursor_y = GetCursorYForTesting(); + MoveMouseTo(gfx::Point(GetCursorPositionX(3), cursor_y)); ClickRightMouseButton(); EXPECT_STR_EQ("ello", textfield_->GetSelectedText()); // Verify right clicking outside the selection, selects the word under the // cursor on platforms where this is expected. - MoveMouseTo(gfx::Point(GetCursorPositionX(8), 0)); + MoveMouseTo(gfx::Point(GetCursorPositionX(8), cursor_y)); const char* expected_right_click = PlatformStyle::kSelectWordOnRightClick ? "world" : "ello"; ClickRightMouseButton(); @@ -1484,15 +1489,16 @@ textfield_->SetText(ASCIIToUTF16("hello world")); const int kStart = GetCursorPositionX(5); const int kEnd = 500; - gfx::Point start_point(kStart, 0); - gfx::Point end_point(kEnd, 0); + const int cursor_y = GetCursorYForTesting(); + gfx::Point start_point(kStart, cursor_y); + gfx::Point end_point(kEnd, cursor_y); MoveMouseTo(start_point); PressLeftMouseButton(); EXPECT_TRUE(textfield_->GetSelectedText().empty()); // Check that dragging left selects the beginning of the string. - DragMouseTo(gfx::Point()); + DragMouseTo(gfx::Point(0, cursor_y)); base::string16 text_left = textfield_->GetSelectedText(); EXPECT_STR_EQ("hello", text_left); @@ -1508,7 +1514,7 @@ // Check that dragging from beyond the text length works too. MoveMouseTo(end_point); PressLeftMouseButton(); - DragMouseTo(gfx::Point()); + DragMouseTo(gfx::Point(0, cursor_y)); ReleaseLeftMouseButton(); EXPECT_EQ(textfield_->text(), textfield_->GetSelectedText()); } @@ -1520,13 +1526,13 @@ InitTextfield(); textfield_->SetText(ASCIIToUTF16("hello world")); const base::string16 expected_up = base::ASCIIToUTF16( - PlatformStyle::kTextDragVerticallyDragsToEnd ? "hello" : "lo"); + gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? "hello" : "lo"); const base::string16 expected_down = base::ASCIIToUTF16( - PlatformStyle::kTextDragVerticallyDragsToEnd ? " world" : " w"); + gfx::RenderText::kDragToEndIfOutsideVerticalBounds ? " world" : " w"); const int kStartX = GetCursorPositionX(5); const int kDownX = GetCursorPositionX(7); const int kUpX = GetCursorPositionX(3); - gfx::Point start_point(kStartX, 0); + gfx::Point start_point(kStartX, GetCursorYForTesting()); gfx::Point down_point(kDownX, 500); gfx::Point up_point(kUpX, -500); @@ -1612,7 +1618,7 @@ ui::OSExchangeData data; const gfx::Range kStringRange(6, 12); textfield_->SelectRange(kStringRange); - const gfx::Point kStringPoint(GetCursorPositionX(9), 0); + const gfx::Point kStringPoint(GetCursorPositionX(9), GetCursorYForTesting()); textfield_->WriteDragDataForView(NULL, kStringPoint, &data); EXPECT_TRUE(data.GetString(&string)); EXPECT_EQ(textfield_->GetSelectedText(), string); @@ -1651,6 +1657,7 @@ TEST_F(TextfieldTest, DragAndDrop_ToTheRight) { InitTextfield(); textfield_->SetText(ASCIIToUTF16("hello world")); + const int cursor_y = GetCursorYForTesting(); base::string16 string; ui::OSExchangeData data; @@ -1660,7 +1667,7 @@ // Start dragging "ello". textfield_->SelectRange(gfx::Range(1, 5)); - gfx::Point point(GetCursorPositionX(3), 0); + gfx::Point point(GetCursorPositionX(3), cursor_y); MoveMouseTo(point); PressLeftMouseButton(); EXPECT_TRUE(textfield_->CanStartDragForView(textfield_, point, point)); @@ -1675,7 +1682,7 @@ EXPECT_TRUE(format_types.empty()); // Drop "ello" after "w". - const gfx::Point kDropPoint(GetCursorPositionX(7), 0); + const gfx::Point kDropPoint(GetCursorPositionX(7), cursor_y); EXPECT_TRUE(textfield_->CanDrop(data)); ui::DropTargetEvent drop_a(data, kDropPoint, kDropPoint, operations); EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnDragUpdated(drop_a)); @@ -1701,6 +1708,7 @@ TEST_F(TextfieldTest, DragAndDrop_ToTheLeft) { InitTextfield(); textfield_->SetText(ASCIIToUTF16("hello world")); + const int cursor_y = GetCursorYForTesting(); base::string16 string; ui::OSExchangeData data; @@ -1710,7 +1718,7 @@ // Start dragging " worl". textfield_->SelectRange(gfx::Range(5, 10)); - gfx::Point point(GetCursorPositionX(7), 0); + gfx::Point point(GetCursorPositionX(7), cursor_y); MoveMouseTo(point); PressLeftMouseButton(); EXPECT_TRUE(textfield_->CanStartDragForView(textfield_, point, gfx::Point())); @@ -1726,7 +1734,7 @@ // Drop " worl" after "h". EXPECT_TRUE(textfield_->CanDrop(data)); - gfx::Point drop_point(GetCursorPositionX(1), 0); + gfx::Point drop_point(GetCursorPositionX(1), cursor_y); ui::DropTargetEvent drop_a(data, drop_point, drop_point, operations); EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnDragUpdated(drop_a)); EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnPerformDrop(drop_a)); @@ -1751,22 +1759,23 @@ TEST_F(TextfieldTest, DragAndDrop_Canceled) { InitTextfield(); textfield_->SetText(ASCIIToUTF16("hello world")); + const int cursor_y = GetCursorYForTesting(); // Start dragging "worl". textfield_->SelectRange(gfx::Range(6, 10)); - gfx::Point point(GetCursorPositionX(8), 0); + gfx::Point point(GetCursorPositionX(8), cursor_y); MoveMouseTo(point); PressLeftMouseButton(); ui::OSExchangeData data; textfield_->WriteDragDataForView(nullptr, point, &data); EXPECT_TRUE(textfield_->CanDrop(data)); // Drag the text over somewhere valid, outside the current selection. - gfx::Point drop_point(GetCursorPositionX(2), 0); + gfx::Point drop_point(GetCursorPositionX(2), cursor_y); ui::DropTargetEvent drop(data, drop_point, drop_point, ui::DragDropTypes::DRAG_MOVE); EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnDragUpdated(drop)); // "Cancel" the drag, via move and release over the selection, and OnDragDone. - gfx::Point drag_point(GetCursorPositionX(9), 0); + gfx::Point drag_point(GetCursorPositionX(9), cursor_y); DragMouseTo(drag_point); ReleaseLeftMouseButton(); EXPECT_EQ(ASCIIToUTF16("hello world"), textfield_->text()); @@ -2629,10 +2638,11 @@ TEST_F(TextfieldTest, SelectionClipboard) { InitTextfield(); textfield_->SetText(ASCIIToUTF16("0123")); - gfx::Point point_1(GetCursorPositionX(1), 0); - gfx::Point point_2(GetCursorPositionX(2), 0); - gfx::Point point_3(GetCursorPositionX(3), 0); - gfx::Point point_4(GetCursorPositionX(4), 0); + const int cursor_y = GetCursorYForTesting(); + gfx::Point point_1(GetCursorPositionX(1), cursor_y); + gfx::Point point_2(GetCursorPositionX(2), cursor_y); + gfx::Point point_3(GetCursorPositionX(3), cursor_y); + gfx::Point point_4(GetCursorPositionX(4), cursor_y); // Text selected by the mouse should be placed on the selection clipboard. ui::MouseEvent press(ui::ET_MOUSE_PRESSED, point_1, point_1, @@ -2730,7 +2740,7 @@ // Double and triple clicking should update the clipboard contents. textfield_->SetText(ASCIIToUTF16("ab cd ef")); - gfx::Point word(GetCursorPositionX(4), 0); + gfx::Point word(GetCursorPositionX(4), cursor_y); ui::MouseEvent press_word(ui::ET_MOUSE_PRESSED, word, word, ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); @@ -2815,7 +2825,7 @@ // Ensure the textfield will provide selected text for drag data. textfield_->SelectRange(gfx::Range(6, 12)); - const gfx::Point kStringPoint(GetCursorPositionX(9), 0); + const gfx::Point kStringPoint(GetCursorPositionX(9), GetCursorYForTesting()); // Enable touch-drag-drop to make long press effective. base::CommandLine::ForCurrentProcess()->AppendSwitch(
diff --git a/ui/views/corewm/tooltip_controller_unittest.cc b/ui/views/corewm/tooltip_controller_unittest.cc index f41136c5..72209dd 100644 --- a/ui/views/corewm/tooltip_controller_unittest.cc +++ b/ui/views/corewm/tooltip_controller_unittest.cc
@@ -88,7 +88,7 @@ // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; aura::Window* root_window = GetContext(); @@ -112,7 +112,7 @@ } void TearDown() override { - if (!IsAuraMusClient()) { + if (!IsMus()) { #if defined(OS_CHROMEOS) aura::Window* root_window = GetContext(); root_window->RemovePreTargetHandler(controller_.get()); @@ -181,7 +181,7 @@ TEST_F(TooltipControllerTest, ViewTooltip) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); @@ -211,9 +211,9 @@ #if defined(OS_CHROMEOS) // crbug.com/664370. TEST_F(TooltipControllerTest, MaxWidth) { - // TODO: these tests use GetContext(). That should go away for aura-mus - // client. http://crbug.com/663781. - if (IsAuraMusClient() || IsMus()) + // TODO: these tests use GetContext(). That should go away for mus client. + // http://crbug.com/663781. + if (IsMus()) return; base::string16 text = base::ASCIIToUTF16( @@ -238,7 +238,7 @@ TEST_F(TooltipControllerTest, TooltipsInMultipleViews) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); @@ -278,7 +278,7 @@ TEST_F(TooltipControllerTest, EnableOrDisableTooltips) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); @@ -309,7 +309,7 @@ TEST_F(TooltipControllerTest, DontShowEmptyTooltips) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; view_->set_tooltip_text(ASCIIToUTF16(" ")); @@ -325,7 +325,7 @@ TEST_F(TooltipControllerTest, TooltipHidesOnKeyPressAndStaysHiddenUntilChange) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 1")); @@ -379,7 +379,7 @@ TEST_F(TooltipControllerTest, TooltipHidesOnTimeoutAndStaysHiddenUntilChange) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text for view 1")); @@ -433,7 +433,7 @@ TEST_F(TooltipControllerTest, HideOnExit) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); @@ -454,7 +454,7 @@ TEST_F(TooltipControllerTest, ReshowOnClickAfterEnterExit) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; // Owned by |view_|. @@ -517,7 +517,7 @@ TooltipControllerTest::SetUp(); // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; aura::client::SetScreenPositionClient(GetRootWindow(), @@ -525,7 +525,7 @@ } void TearDown() override { - if (!IsAuraMusClient()) + if (!IsMus()) aura::client::SetScreenPositionClient(GetRootWindow(), NULL); TooltipControllerTest::TearDown(); } @@ -542,7 +542,7 @@ TEST_F(TooltipControllerCaptureTest, DISABLED_CloseOnCaptureLost) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; view_->GetWidget()->SetCapture(view_); @@ -574,9 +574,9 @@ // Verifies the correct window is found for tooltips when there is a capture. TEST_F(TooltipControllerCaptureTest, MAYBE_Capture) { // Currently, capture in one test affects capture in other tests. - // TODO: these tests use GetContext(). That should go away for aura-mus - // client. http://crbug.com/663781. - if (IsMus() || IsAuraMusClient()) + // TODO: these tests use GetContext(). That should go away for mus client. + // http://crbug.com/663781. + if (IsMus()) return; const base::string16 tooltip_text(ASCIIToUTF16("1")); @@ -742,8 +742,8 @@ // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) - return; + if (IsMus()) + return; aura::Window* root_window = GetContext(); new wm::DefaultActivationClient(root_window); @@ -766,7 +766,7 @@ } void TearDown() override { - if (!IsAuraMusClient()) { + if (!IsMus()) { GetRootWindow()->RemovePreTargetHandler(controller_.get()); aura::client::SetTooltipClient(GetRootWindow(), NULL); @@ -803,7 +803,7 @@ TEST_F(TooltipControllerTest3, TooltipPositionChangesOnTwoViewsWithSameLabel) { // TODO: these tests use GetContext(). That should go away for aura-mus // client. http://crbug.com/663781. - if (IsAuraMusClient()) + if (IsMus()) return; // Owned by |view_|.
diff --git a/ui/views/event_monitor_unittest.cc b/ui/views/event_monitor_unittest.cc index 10b0a504..d930215 100644 --- a/ui/views/event_monitor_unittest.cc +++ b/ui/views/event_monitor_unittest.cc
@@ -21,7 +21,7 @@ widget_ = CreateTopLevelNativeWidget(); widget_->SetSize(gfx::Size(100, 100)); widget_->Show(); - if (IsMus() || IsAuraMusClient()) { + if (IsMus()) { generator_.reset( new ui::test::EventGenerator(widget_->GetNativeWindow())); } else {
diff --git a/ui/views/examples/label_example.cc b/ui/views/examples/label_example.cc index 4255e716..b285bb8 100644 --- a/ui/views/examples/label_example.cc +++ b/ui/views/examples/label_example.cc
@@ -115,8 +115,10 @@ label->SetBorder(CreateSolidBorder(20, SK_ColorRED)); container->AddChildView(label); - label = new Label(ASCIIToUTF16("A label supporting text selection.")); + label = new Label( + ASCIIToUTF16("A multiline label...\n\n...which supports text selection")); label->SetSelectable(true); + label->SetMultiLine(true); container->AddChildView(label); AddCustomLabel(container); @@ -132,6 +134,8 @@ shadows.push_back(gfx::ShadowValue(gfx::Vector2d(2, 2), 0, SK_ColorGRAY)); } custom_label_->SetShadows(shadows); + } else if (button == selectable_) { + custom_label_->SetSelectable(selectable_->checked()); } custom_label_->parent()->parent()->Layout(); custom_label_->SchedulePaint(); @@ -186,6 +190,8 @@ 0, GridLayout::USE_PREF, 0, 0); column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, GridLayout::USE_PREF, 0, 0); + column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, + GridLayout::USE_PREF, 0, 0); layout->StartRow(0, 1); multiline_ = new Checkbox(base::ASCIIToUTF16("Multiline")); multiline_->set_listener(this); @@ -193,6 +199,9 @@ shadows_ = new Checkbox(base::ASCIIToUTF16("Shadows")); shadows_->set_listener(this); layout->AddView(shadows_); + selectable_ = new Checkbox(base::ASCIIToUTF16("Selectable")); + selectable_->set_listener(this); + layout->AddView(selectable_); layout->AddPaddingRow(0, 8); column_set = layout->AddColumnSet(2); @@ -205,6 +214,10 @@ custom_label_->SetText(textfield_->text()); layout->AddView(custom_label_); + // Disable the text selection checkbox if |custom_label_| does not support + // text selection. + selectable_->SetEnabled(custom_label_->IsSelectionSupported()); + container->AddChildView(control_container); }
diff --git a/ui/views/examples/label_example.h b/ui/views/examples/label_example.h index 80b0d9f8..87e8e2f 100644 --- a/ui/views/examples/label_example.h +++ b/ui/views/examples/label_example.h
@@ -58,6 +58,7 @@ std::vector<std::unique_ptr<ExampleComboboxModel>> example_combobox_models_; Checkbox* multiline_; Checkbox* shadows_; + Checkbox* selectable_; Label* custom_label_; DISALLOW_COPY_AND_ASSIGN(LabelExample);
diff --git a/ui/views/focus/focus_manager_unittest.cc b/ui/views/focus/focus_manager_unittest.cc index b1f5225..26f1f658 100644 --- a/ui/views/focus/focus_manager_unittest.cc +++ b/ui/views/focus/focus_manager_unittest.cc
@@ -125,7 +125,7 @@ // TODO: this test ends up calling focus on the aura::Window associated with // the Widget and expecting that to change activation. This should work for // aura-mus-client as well. http://crbug.com/664261. - if (IsAuraMusClient()) + if (IsMus()) return; // First, ensure the simulator is aware of the Widget created in SetUp() being @@ -856,9 +856,6 @@ // Verifies focus wrapping happens in the same widget. TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) { - // Mus doesn't support child Widgets well yet. https://crbug.com/612820 - if (IsMus()) - return; // Add |widget_view| as a child of the Widget. View* widget_view = new View; widget_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
diff --git a/ui/views/mus/BUILD.gn b/ui/views/mus/BUILD.gn index cbc99f3..c6dd151e 100644 --- a/ui/views/mus/BUILD.gn +++ b/ui/views/mus/BUILD.gn
@@ -19,37 +19,19 @@ "clipboard_mus.h", "desktop_window_tree_host_mus.cc", "desktop_window_tree_host_mus.h", - "drag_drop_client_mus.cc", - "drag_drop_client_mus.h", - "drop_target_mus.cc", - "drop_target_mus.h", - "input_method_mus.cc", - "input_method_mus.h", "mus_client.cc", "mus_client.h", "mus_client_observer.h", "mus_export.h", - "native_widget_mus.cc", - "native_widget_mus.h", - "pointer_watcher_event_router.cc", - "pointer_watcher_event_router.h", "pointer_watcher_event_router2.cc", "pointer_watcher_event_router2.h", "screen_mus.cc", "screen_mus.h", "screen_mus_delegate.h", - "surface_context_factory.cc", - "surface_context_factory.h", - "text_input_client_impl.cc", - "text_input_client_impl.h", - "window_manager_connection.cc", - "window_manager_connection.h", "window_manager_constants_converters.cc", "window_manager_constants_converters.h", "window_manager_frame_values.cc", "window_manager_frame_values.h", - "window_tree_host_mus.cc", - "window_tree_host_mus.h", ] defines = [ "VIEWS_MUS_IMPLEMENTATION" ] @@ -129,10 +111,10 @@ testonly = true sources = [ - "../test/native_widget_factory_mus.cc", + "../test/native_widget_factory_aura_mus.cc", "test_utils.h", - "views_mus_test_suite.cc", - "views_mus_test_suite.h", + "views_aura_mus_test_suite.cc", + "views_aura_mus_test_suite.h", ] deps = [ @@ -144,6 +126,7 @@ "//services/ui/common:mus_common", "//testing/gtest", "//ui/aura", + "//ui/aura:test_support", "//ui/gl:test_support", "//ui/resources", "//ui/resources:ui_test_pak", @@ -160,12 +143,10 @@ testonly = true sources = [ - "input_method_mus_unittest.cc", - "native_widget_mus_unittest.cc", - "pointer_watcher_event_router_unittest.cc", - "run_all_unittests_mus.cc", + "desktop_window_tree_host_mus_unittest.cc", + "pointer_watcher_event_router2_unittest.cc", + "run_all_unittests_aura_mus.cc", "screen_mus_unittest.cc", - "window_manager_connection_unittest.cc", ] configs += [ "//build/config:precompiled_headers" ] @@ -179,9 +160,6 @@ "//cc", "//net", "//services/service_manager/background:main", # Provides main(). - "//services/ui/public/cpp", - "//services/ui/public/cpp:internal_or_test", - "//services/ui/public/cpp/tests:unittest_support", "//services/ui/public/interfaces", "//skia", "//testing/gtest", @@ -241,118 +219,6 @@ } } -static_library("test_support_aura_mus") { - testonly = true - - sources = [ - "../test/native_widget_factory_aura_mus.cc", - "test_utils.h", - "views_aura_mus_test_suite.cc", - "views_aura_mus_test_suite.h", - ] - - deps = [ - ":mus", - "//base", - "//base/test:test_support", - "//services/service_manager/background:lib", - "//services/service_manager/public/cpp:sources", - "//services/ui/common:mus_common", - "//testing/gtest", - "//ui/aura", - "//ui/aura:test_support", - "//ui/gl:test_support", - "//ui/resources", - "//ui/resources:ui_test_pak", - "//ui/views", - "//ui/views:test_support_internal", - ] - - data_deps = [ - "//ui/resources:ui_test_pak_data", - ] -} - -test("views_aura_mus_unittests") { - testonly = true - - sources = [ - "desktop_window_tree_host_mus_unittest.cc", - "pointer_watcher_event_router2_unittest.cc", - "run_all_unittests_aura_mus.cc", - "screen_mus_unittest.cc", - ] - - configs += [ "//build/config:precompiled_headers" ] - - deps = [ - ":mus", - ":test_support_aura_mus", - "//base", - "//base:i18n", - "//base/test:test_support", - "//cc", - "//net", - "//services/service_manager/background:main", # Provides main(). - "//services/ui/public/interfaces", - "//skia", - "//testing/gtest", - "//third_party/icu", - "//ui/accessibility", - "//ui/aura", - "//ui/aura:test_support", - "//ui/base", - "//ui/base:test_support", - "//ui/base/ime", - "//ui/compositor:test_support", - "//ui/events:dom_keycode_converter", - "//ui/events:events_base", - "//ui/events:test_support", - "//ui/events/platform", - "//ui/gfx:test_support", - "//ui/gfx/geometry", - "//ui/native_theme", - "//ui/strings", - "//ui/touch_selection", - "//ui/views", - "//ui/views:test_support_internal", - "//ui/views:views_unittests_sources", - "//ui/wm", - "//url", - ] - - data_deps = [ - ":unittests_aura_manifest", - "//services/ui/ime/test_ime_driver", - "//services/ui/test_wm", - ] - - if (is_win) { - deps += [ - "//build/win:default_exe_manifest", - "//third_party/iaccessible2", - "//third_party/wtl", - ] - libs = [ - "imm32.lib", - "oleacc.lib", - "comctl32.lib", - ] - } - - if (use_x11) { - configs += [ - "//build/config/linux:x11", - "//build/config/linux:xext", - ] - deps += [ - "//ui/events/devices", - "//ui/events/platform/x11", - "//ui/gfx/x", - ] - } -} - # Tests that must run sequentially because they access system-wide features # like capture. test("views_mus_interactive_ui_tests") { @@ -407,11 +273,6 @@ source = "unittests_manifest.json" } -service_manifest("unittests_aura_manifest") { - name = "views_aura_mus_unittests" - source = "unittests_aura_manifest.json" -} - service_manifest("interactive_ui_tests_manifest") { name = "views_mus_interactive_ui_tests" source = "interactive_ui_tests_manifest.json"
diff --git a/ui/views/mus/clipboard_unittest.cc b/ui/views/mus/clipboard_unittest.cc index b2825977..3c69dcd 100644 --- a/ui/views/mus/clipboard_unittest.cc +++ b/ui/views/mus/clipboard_unittest.cc
@@ -7,7 +7,7 @@ #include "base/message_loop/message_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/platform/platform_event_source.h" -#include "ui/views/mus/window_manager_connection.h" +#include "ui/views/mus/mus_client.h" #include "ui/views/test/scoped_views_test_helper.h" namespace ui { @@ -24,7 +24,7 @@ clipboard_to_test_(Clipboard::GetForCurrentThread()) { // If we don't have a window manager connection, we will get the default // platform clipboard instead. - EXPECT_TRUE(views::WindowManagerConnection::Exists()); + EXPECT_TRUE(views::MusClient::Exists()); } ~ForwardingTestingClipboard() override {
diff --git a/ui/views/mus/drag_drop_client_mus.cc b/ui/views/mus/drag_drop_client_mus.cc deleted file mode 100644 index 0fa21ad9..0000000 --- a/ui/views/mus/drag_drop_client_mus.cc +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/drag_drop_client_mus.h" - -#include <map> -#include <string> -#include <vector> - -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "services/ui/public/cpp/window.h" -#include "ui/aura/mus/os_exchange_data_provider_mus.h" -#include "ui/aura/window.h" - -namespace views { -namespace { - -DragDropClientMus* current_dragging_client = nullptr; - -} // namespace - -DragDropClientMus::DragDropClientMus(ui::Window* ui_window) - : ui_window_(ui_window) {} - -DragDropClientMus::~DragDropClientMus() {} - -int DragDropClientMus::StartDragAndDrop( - const ui::OSExchangeData& data, - aura::Window* root_window, - aura::Window* source_window, - const gfx::Point& screen_location, - int drag_operations, - ui::DragDropTypes::DragEventSource source) { - std::map<std::string, std::vector<uint8_t>> drag_data = - static_cast<const aura::OSExchangeDataProviderMus&>(data.provider()) - .GetData(); - - // TODO(erg): Right now, I'm passing the cursor_location, but maybe I want to - // pass OSExchangeData::GetDragImageOffset() instead? - - bool success = false; - gfx::Point cursor_location = screen_location; - uint32_t action_taken = ui::mojom::kDropEffectNone; - current_dragging_client = this; - ui_window_->PerformDragDrop( - drag_data, drag_operations, cursor_location, - *data.provider().GetDragImage().bitmap(), - base::Bind(&DragDropClientMus::OnMoveLoopEnd, base::Unretained(this), - &success, &action_taken)); - - base::MessageLoop* loop = base::MessageLoop::current(); - base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop); - base::RunLoop run_loop; - - runloop_quit_closure_ = run_loop.QuitClosure(); - run_loop.Run(); - current_dragging_client = nullptr; - - return action_taken; -} - -void DragDropClientMus::DragCancel() { - ui_window_->CancelDragDrop(); -} - -bool DragDropClientMus::IsDragDropInProgress() { - return !!current_dragging_client; -} - -void DragDropClientMus::OnMoveLoopEnd(bool* out_success, - uint32_t* out_action, - bool in_success, - uint32_t in_action) { - *out_success = in_success; - *out_action = in_action; - runloop_quit_closure_.Run(); -} - -} // namespace views
diff --git a/ui/views/mus/drag_drop_client_mus.h b/ui/views/mus/drag_drop_client_mus.h deleted file mode 100644 index 641d084..0000000 --- a/ui/views/mus/drag_drop_client_mus.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_DRAG_DROP_CLIENT_MUS_H_ -#define UI_VIEWS_MUS_DRAG_DROP_CLIENT_MUS_H_ - -#include "base/callback.h" -#include "ui/aura/client/drag_drop_client.h" -#include "ui/base/dragdrop/drag_drop_types.h" - -namespace aura { -class Window; -} - -namespace ui { -class OSExchangeData; -class Window; -} - -namespace views { - -// An aura client object that translates aura dragging methods to their -// remote ui::Window equivalents. -class DragDropClientMus : public aura::client::DragDropClient { - public: - DragDropClientMus(ui::Window* ui_window); - ~DragDropClientMus() override; - - // Overridden from aura::client::DragDropClient: - int StartDragAndDrop(const ui::OSExchangeData& data, - aura::Window* root_window, - aura::Window* source_window, - const gfx::Point& screen_location, - int drag_operations, - ui::DragDropTypes::DragEventSource source) override; - void DragCancel() override; - bool IsDragDropInProgress() override; - - private: - // Callback for StartDragAndDrop(). - void OnMoveLoopEnd(bool* out_success, - uint32_t* out_action, - bool in_success, - uint32_t in_action); - - ui::Window* ui_window_; - - base::Closure runloop_quit_closure_; - - DISALLOW_COPY_AND_ASSIGN(DragDropClientMus); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_DRAG_DROP_CLIENT_MUS_H_
diff --git a/ui/views/mus/drop_target_mus.cc b/ui/views/mus/drop_target_mus.cc deleted file mode 100644 index cab87aa..0000000 --- a/ui/views/mus/drop_target_mus.cc +++ /dev/null
@@ -1,147 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/drop_target_mus.h" - -#include <map> -#include <string> -#include <utility> -#include <vector> - -#include "base/memory/ptr_util.h" -#include "services/ui/public/interfaces/window_tree_constants.mojom.h" -#include "ui/aura/client/drag_drop_client.h" -#include "ui/aura/client/drag_drop_delegate.h" -#include "ui/aura/mus/os_exchange_data_provider_mus.h" -#include "ui/aura/window.h" -#include "ui/aura/window_tree_host.h" -#include "ui/base/dragdrop/drag_drop_types.h" -#include "ui/base/dragdrop/drop_target_event.h" - -namespace views { - -static_assert(ui::DragDropTypes::DRAG_NONE == ui::mojom::kDropEffectNone, - "Drag constants must be the same"); -static_assert(ui::DragDropTypes::DRAG_MOVE == ui::mojom::kDropEffectMove, - "Drag constants must be the same"); -static_assert(ui::DragDropTypes::DRAG_COPY == ui::mojom::kDropEffectCopy, - "Drag constants must be the same"); -static_assert(ui::DragDropTypes::DRAG_LINK == ui::mojom::kDropEffectLink, - "Drag constants must be the same"); - -DropTargetMus::DropTargetMus(aura::Window* root_window) - : root_window_(root_window), target_window_(nullptr) {} - -DropTargetMus::~DropTargetMus() {} - -void DropTargetMus::Translate(uint32_t key_state, - const gfx::Point& screen_location, - uint32_t effect, - std::unique_ptr<ui::DropTargetEvent>* event, - aura::client::DragDropDelegate** delegate) { - gfx::Point location = screen_location; - gfx::Point root_location = location; - root_window_->GetHost()->ConvertScreenInPixelsToDIP(&root_location); - aura::Window* target_window = - root_window_->GetEventHandlerForPoint(root_location); - bool target_window_changed = false; - if (target_window != target_window_) { - if (target_window_) - NotifyDragExited(); - target_window_ = target_window; - if (target_window_) - target_window_->AddObserver(this); - target_window_changed = true; - } - *delegate = nullptr; - if (!target_window_) - return; - *delegate = aura::client::GetDragDropDelegate(target_window_); - if (!*delegate) - return; - - location = root_location; - aura::Window::ConvertPointToTarget(root_window_, target_window_, &location); - *event = base::MakeUnique<ui::DropTargetEvent>( - *(os_exchange_data_.get()), location, root_location, effect); - (*event)->set_flags(key_state); - if (target_window_changed) - (*delegate)->OnDragEntered(*event->get()); -} - -void DropTargetMus::NotifyDragExited() { - if (!target_window_) - return; - - aura::client::DragDropDelegate* delegate = - aura::client::GetDragDropDelegate(target_window_); - if (delegate) - delegate->OnDragExited(); - - target_window_->RemoveObserver(this); - target_window_ = nullptr; -} - -void DropTargetMus::OnDragDropStart( - std::map<std::string, std::vector<uint8_t>> mime_data) { - // We store the mime data here because we need to access it during each phase - // of the drag, but we also don't move the data cross-process multiple times. - os_exchange_data_ = base::MakeUnique<ui::OSExchangeData>( - base::MakeUnique<aura::OSExchangeDataProviderMus>(std::move(mime_data))); -} - -uint32_t DropTargetMus::OnDragEnter(uint32_t key_state, - const gfx::Point& position, - uint32_t effect_bitmask) { - std::unique_ptr<ui::DropTargetEvent> event; - aura::client::DragDropDelegate* delegate = nullptr; - // Translate will call OnDragEntered. - Translate(key_state, position, effect_bitmask, &event, &delegate); - return ui::mojom::kDropEffectNone; -} - -uint32_t DropTargetMus::OnDragOver(uint32_t key_state, - const gfx::Point& position, - uint32_t effect) { - int drag_operation = ui::DragDropTypes::DRAG_NONE; - std::unique_ptr<ui::DropTargetEvent> event; - aura::client::DragDropDelegate* delegate = nullptr; - - Translate(key_state, position, effect, &event, &delegate); - if (delegate) - drag_operation = delegate->OnDragUpdated(*event); - return drag_operation; -} - -void DropTargetMus::OnDragLeave() { - NotifyDragExited(); -} - -uint32_t DropTargetMus::OnCompleteDrop(uint32_t key_state, - const gfx::Point& position, - uint32_t effect) { - int drag_operation = ui::DragDropTypes::DRAG_NONE; - std::unique_ptr<ui::DropTargetEvent> event; - aura::client::DragDropDelegate* delegate = nullptr; - Translate(key_state, position, effect, &event, &delegate); - if (delegate) - drag_operation = delegate->OnPerformDrop(*event); - if (target_window_) { - target_window_->RemoveObserver(this); - target_window_ = nullptr; - } - - return drag_operation; -} - -void DropTargetMus::OnDragDropDone() { - os_exchange_data_.reset(); -} - -void DropTargetMus::OnWindowDestroyed(aura::Window* window) { - DCHECK_EQ(window, target_window_); - target_window_ = nullptr; -} - -} // namespace views
diff --git a/ui/views/mus/drop_target_mus.h b/ui/views/mus/drop_target_mus.h deleted file mode 100644 index 24a4715..0000000 --- a/ui/views/mus/drop_target_mus.h +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_DROP_TARGET_MUS_H_ -#define UI_VIEWS_MUS_DROP_TARGET_MUS_H_ - -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "services/ui/public/cpp/window_drop_target.h" -#include "ui/aura/window_observer.h" - -namespace aura { -class Window; - -namespace client { -class DragDropDelegate; -} -} - -namespace ui { -class DropTargetEvent; -class OSExchangeData; -} - -namespace views { - -// An adapter class which takes signals from mus' WindowDropTarget, performs -// targeting on the underlying aura::Window tree, and dispatches them to the -// aura DragDropDelegate of the targeted aura::Window. -class DropTargetMus : public ui::WindowDropTarget, public aura::WindowObserver { - public: - explicit DropTargetMus(aura::Window* root_window); - ~DropTargetMus() override; - - private: - // Common functionality for the WindowDropTarget methods to translate from - // mus data types to Aura ones. This method takes in mus messages and - // performs the common tasks of keeping track of which aura window (along - // with enter/leave messages at that layer), doing coordinate translation, - // and creation of ui layer event objects that get dispatched to aura/views. - void Translate(uint32_t key_state, - const gfx::Point& screen_location, - uint32_t effect_bitmask, - std::unique_ptr<ui::DropTargetEvent>* event, - aura::client::DragDropDelegate** delegate); - - void NotifyDragExited(); - - // Overridden from ui::WindowDropTarget: - void OnDragDropStart( - std::map<std::string, std::vector<uint8_t>> mime_data) override; - uint32_t OnDragEnter(uint32_t key_state, - const gfx::Point& position, - uint32_t effect_bitmask) override; - uint32_t OnDragOver(uint32_t key_state, - const gfx::Point& position, - uint32_t effect_bitmask) override; - void OnDragLeave() override; - uint32_t OnCompleteDrop(uint32_t key_state, - const gfx::Point& position, - uint32_t effect_bitmask) override; - void OnDragDropDone() override; - - // Overridden from aura::WindowObserver: - void OnWindowDestroyed(aura::Window* window) override; - - // The root window associated with this drop target. - aura::Window* root_window_; - - // The Aura window that is currently under the cursor. We need to manually - // keep track of this because mus will only call our drag enter method once - // when the user enters the associated mus::Window. But inside mus there - // could be multiple aura windows, so we need to generate drag enter events - // for them. - aura::Window* target_window_; - - // The entire drag data payload. We receive this during the drag enter event - // and cache it so we don't send this multiple times. We reset this value on - // leave or drop. - std::unique_ptr<ui::OSExchangeData> os_exchange_data_; - - DISALLOW_COPY_AND_ASSIGN(DropTargetMus); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_DROP_TARGET_MUS_H_
diff --git a/ui/views/mus/input_method_mus.cc b/ui/views/mus/input_method_mus.cc deleted file mode 100644 index 1344e74e..0000000 --- a/ui/views/mus/input_method_mus.cc +++ /dev/null
@@ -1,165 +0,0 @@ -// Copyright (c) 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/input_method_mus.h" - -#include <utility> - -#include "base/memory/ptr_util.h" -#include "services/ui/public/cpp/window.h" -#include "services/ui/public/interfaces/constants.mojom.h" -#include "services/ui/public/interfaces/ime/ime.mojom.h" -#include "ui/base/ime/text_input_client.h" -#include "ui/events/event.h" -#include "ui/platform_window/mojo/ime_type_converters.h" -#include "ui/platform_window/mojo/text_input_state.mojom.h" -#include "ui/views/mus/text_input_client_impl.h" - -using ui::mojom::EventResult; - -namespace views { - -//////////////////////////////////////////////////////////////////////////////// -// InputMethodMus, public: - -InputMethodMus::InputMethodMus(ui::internal::InputMethodDelegate* delegate, - ui::Window* window) - : window_(window) { - SetDelegate(delegate); -} - -InputMethodMus::~InputMethodMus() {} - -void InputMethodMus::Init(service_manager::Connector* connector) { - connector->ConnectToInterface(ui::mojom::kServiceName, &ime_server_); -} - -void InputMethodMus::DispatchKeyEvent( - ui::KeyEvent* event, - std::unique_ptr<base::Callback<void(EventResult)>> ack_callback) { - DCHECK(event->type() == ui::ET_KEY_PRESSED || - event->type() == ui::ET_KEY_RELEASED); - - // If no text input client, do nothing. - if (!GetTextInputClient()) { - ignore_result(DispatchKeyEventPostIME(event)); - if (ack_callback) { - ack_callback->Run(event->handled() ? EventResult::HANDLED - : EventResult::UNHANDLED); - } - return; - } - - // IME driver will notify us whether it handled the event or not by calling - // ProcessKeyEventCallback(), in which we will run the |ack_callback| to tell - // the window server if client handled the event or not. - input_method_->ProcessKeyEvent( - ui::Event::Clone(*event), - base::Bind(&InputMethodMus::ProcessKeyEventCallback, - base::Unretained(this), *event, Passed(&ack_callback))); -} - -//////////////////////////////////////////////////////////////////////////////// -// InputMethodMus, ui::InputMethod implementation: - -void InputMethodMus::OnFocus() { - InputMethodBase::OnFocus(); - UpdateTextInputType(); -} - -void InputMethodMus::OnBlur() { - InputMethodBase::OnBlur(); - UpdateTextInputType(); -} - -bool InputMethodMus::OnUntranslatedIMEMessage(const base::NativeEvent& event, - NativeEventResult* result) { - // This method is not called on non-Windows platforms. See the comments for - // ui::InputMethod::OnUntranslatedIMEMessage(). - return false; -} - -void InputMethodMus::DispatchKeyEvent(ui::KeyEvent* event) { - DispatchKeyEvent(event, nullptr); -} - -void InputMethodMus::OnTextInputTypeChanged(const ui::TextInputClient* client) { - if (IsTextInputClientFocused(client)) - UpdateTextInputType(); - InputMethodBase::OnTextInputTypeChanged(client); - - if (input_method_) { - input_method_->OnTextInputTypeChanged( - static_cast<ui::mojom::TextInputType>(client->GetTextInputType())); - } -} - -void InputMethodMus::OnCaretBoundsChanged(const ui::TextInputClient* client) { - if (input_method_) - input_method_->OnCaretBoundsChanged(client->GetCaretBounds()); -} - -void InputMethodMus::CancelComposition(const ui::TextInputClient* client) { - if (input_method_) - input_method_->CancelComposition(); -} - -void InputMethodMus::OnInputLocaleChanged() { - // TODO(moshayedi): crbug.com/637418. Not supported in ChromeOS. Investigate - // whether we want to support this or not. -} - -bool InputMethodMus::IsCandidatePopupOpen() const { - // TODO(moshayedi): crbug.com/637416. Implement this properly when we have a - // mean for displaying candidate list popup. - return false; -} - -void InputMethodMus::OnDidChangeFocusedClient( - ui::TextInputClient* focused_before, - ui::TextInputClient* focused) { - InputMethodBase::OnDidChangeFocusedClient(focused_before, focused); - UpdateTextInputType(); - - text_input_client_ = base::MakeUnique<TextInputClientImpl>(focused); - ime_server_->StartSession(text_input_client_->CreateInterfacePtrAndBind(), - MakeRequest(&input_method_)); -} - -void InputMethodMus::UpdateTextInputType() { - ui::TextInputType type = GetTextInputType(); - mojo::TextInputStatePtr state = mojo::TextInputState::New(); - state->type = mojo::ConvertTo<mojo::TextInputType>(type); - if (window_) { - if (type != ui::TEXT_INPUT_TYPE_NONE) - window_->SetImeVisibility(true, std::move(state)); - else - window_->SetTextInputState(std::move(state)); - } -} - -void InputMethodMus::ProcessKeyEventCallback( - const ui::KeyEvent& event, - std::unique_ptr<base::Callback<void(EventResult)>> ack_callback, - bool handled) { - EventResult event_result; - if (!handled) { - // If not handled by IME, try dispatching the event to delegate to see if - // any client-side post-ime processing needs to be done. This includes cases - // like backspace, return key, etc. - std::unique_ptr<ui::Event> event_clone = ui::Event::Clone(event); - ignore_result(DispatchKeyEventPostIME(event_clone->AsKeyEvent())); - event_result = - event_clone->handled() ? EventResult::HANDLED : EventResult::UNHANDLED; - } else { - event_result = EventResult::HANDLED; - } - // |ack_callback| can be null if the standard form of DispatchKeyEvent() is - // called instead of the version which provides a callback. In mus+ash we - // use the version with callback, but some unittests use the standard form. - if (ack_callback) - ack_callback->Run(event_result); -} - -} // namespace views
diff --git a/ui/views/mus/input_method_mus.h b/ui/views/mus/input_method_mus.h deleted file mode 100644 index e681794..0000000 --- a/ui/views/mus/input_method_mus.h +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright (c) 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_INPUT_METHOD_MUS_H_ -#define UI_VIEWS_MUS_INPUT_METHOD_MUS_H_ - -#include "base/macros.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/ui/public/interfaces/ime/ime.mojom.h" -#include "ui/base/ime/input_method_base.h" -#include "ui/views/mus/mus_export.h" - -namespace ui { -class Window; -namespace mojom { -enum class EventResult; -} // namespace mojom -} // namespace ui - -namespace views { - -class TextInputClientImpl; - -class VIEWS_MUS_EXPORT InputMethodMus : public ui::InputMethodBase { - public: - InputMethodMus(ui::internal::InputMethodDelegate* delegate, - ui::Window* window); - ~InputMethodMus() override; - - void Init(service_manager::Connector* connector); - void DispatchKeyEvent( - ui::KeyEvent* event, - std::unique_ptr<base::Callback<void(ui::mojom::EventResult)>> - ack_callback); - - // Overridden from ui::InputMethod: - void OnFocus() override; - void OnBlur() override; - bool OnUntranslatedIMEMessage(const base::NativeEvent& event, - NativeEventResult* result) override; - void DispatchKeyEvent(ui::KeyEvent* event) override; - void OnTextInputTypeChanged(const ui::TextInputClient* client) override; - void OnCaretBoundsChanged(const ui::TextInputClient* client) override; - void CancelComposition(const ui::TextInputClient* client) override; - void OnInputLocaleChanged() override; - bool IsCandidatePopupOpen() const override; - - private: - friend TextInputClientImpl; - - // Overridden from ui::InputMethodBase: - void OnDidChangeFocusedClient(ui::TextInputClient* focused_before, - ui::TextInputClient* focused) override; - - void UpdateTextInputType(); - void ProcessKeyEventCallback( - const ui::KeyEvent& event, - std::unique_ptr<base::Callback<void(ui::mojom::EventResult)>> - ack_callback, - bool handled); - - // The toplevel window which is not owned by this class. This may be null - // for tests. - ui::Window* window_; - - ui::mojom::IMEServerPtr ime_server_; - ui::mojom::InputMethodPtr input_method_; - std::unique_ptr<TextInputClientImpl> text_input_client_; - - DISALLOW_COPY_AND_ASSIGN(InputMethodMus); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_INPUT_METHOD_MUS_H_
diff --git a/ui/views/mus/input_method_mus_unittest.cc b/ui/views/mus/input_method_mus_unittest.cc deleted file mode 100644 index 5ce1d360..0000000 --- a/ui/views/mus/input_method_mus_unittest.cc +++ /dev/null
@@ -1,98 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/input_method_mus.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/ime/dummy_text_input_client.h" -#include "ui/base/ime/input_method_delegate.h" -#include "ui/events/event.h" -#include "ui/views/mus/window_manager_connection.h" -#include "ui/views/test/scoped_views_test_helper.h" - -namespace views { -namespace { - -class TestInputMethodDelegate : public ui::internal::InputMethodDelegate { - public: - TestInputMethodDelegate() {} - ~TestInputMethodDelegate() override {} - - // ui::internal::InputMethodDelegate: - ui::EventDispatchDetails DispatchKeyEventPostIME( - ui::KeyEvent* key_event) override { - return ui::EventDispatchDetails(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(TestInputMethodDelegate); -}; - -class TestTextInputClient : public ui::DummyTextInputClient { - public: - TestTextInputClient() {} - ~TestTextInputClient() override {} - - ui::KeyEvent* WaitUntilInputReceieved() { - run_loop_ = base::MakeUnique<base::RunLoop>(); - run_loop_->Run(); - run_loop_.reset(); - - return received_event_->AsKeyEvent(); - } - - // ui::DummyTextInputClient: - void InsertChar(const ui::KeyEvent& event) override { - received_event_ = ui::Event::Clone(event); - run_loop_->Quit(); - } - - private: - std::unique_ptr<base::RunLoop> run_loop_; - std::unique_ptr<ui::Event> received_event_; - - DISALLOW_COPY_AND_ASSIGN(TestTextInputClient); -}; - -} // namespace - -class InputMethodMusTest : public testing::Test { - public: - InputMethodMusTest() : message_loop_(base::MessageLoop::TYPE_UI) {} - ~InputMethodMusTest() override {} - - service_manager::Connector* connector() { - return WindowManagerConnection::Get()->connector(); - } - - private: - base::MessageLoop message_loop_; - ScopedViewsTestHelper helper_; - - DISALLOW_COPY_AND_ASSIGN(InputMethodMusTest); -}; - -TEST_F(InputMethodMusTest, DispatchKeyEvent) { - TestInputMethodDelegate input_method_delegate; - InputMethodMus input_method(&input_method_delegate, nullptr); - input_method.Init(connector()); - - TestTextInputClient text_input_client; - input_method.SetFocusedTextInputClient(&text_input_client); - - ui::KeyEvent key_event('A', ui::VKEY_A, 0); - input_method.DispatchKeyEvent(&key_event); - - ui::KeyEvent* received_event = text_input_client.WaitUntilInputReceieved(); - EXPECT_EQ(ui::ET_KEY_PRESSED, received_event->type()); - EXPECT_TRUE(received_event->is_char()); - EXPECT_EQ(key_event.GetCharacter(), received_event->GetCharacter()); -} - -} // namespace views
diff --git a/ui/views/mus/interactive_ui_tests_mus.cc b/ui/views/mus/interactive_ui_tests_mus.cc index 4181166..ff14190 100644 --- a/ui/views/mus/interactive_ui_tests_mus.cc +++ b/ui/views/mus/interactive_ui_tests_mus.cc
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/views/mus/views_mus_test_suite.h" +#include "ui/views/mus/views_aura_mus_test_suite.h" int MasterProcessMain(int argc, char** argv) { - return views::ViewsMusTestSuite(argc, argv).RunTestsSerially(); + return views::ViewsAuraMusTestSuite(argc, argv).RunTestsSerially(); }
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc deleted file mode 100644 index 7b6d929..0000000 --- a/ui/views/mus/native_widget_mus.cc +++ /dev/null
@@ -1,1589 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This has to be before any other includes, else default is picked up. -// See base/logging for details on this. -#define NOTIMPLEMENTED_POLICY 5 - -#include "ui/views/mus/native_widget_mus.h" - -#include <map> -#include <utility> -#include <vector> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "services/ui/public/cpp/property_type_converters.h" -#include "services/ui/public/cpp/window.h" -#include "services/ui/public/cpp/window_observer.h" -#include "services/ui/public/cpp/window_property.h" -#include "services/ui/public/cpp/window_tree_client.h" -#include "services/ui/public/interfaces/cursor.mojom.h" -#include "services/ui/public/interfaces/window_manager.mojom.h" -#include "services/ui/public/interfaces/window_manager_constants.mojom.h" -#include "services/ui/public/interfaces/window_tree.mojom.h" -#include "ui/aura/client/default_capture_client.h" -#include "ui/aura/client/window_parenting_client.h" -#include "ui/aura/layout_manager.h" -#include "ui/aura/mus/mus_util.h" -#include "ui/aura/mus/property_converter.h" -#include "ui/aura/window.h" -#include "ui/aura/window_property.h" -#include "ui/base/hit_test.h" -#include "ui/display/display.h" -#include "ui/display/screen.h" -#include "ui/events/event.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/geometry/dip_util.h" -#include "ui/gfx/path.h" -#include "ui/native_theme/native_theme.h" -#include "ui/platform_window/platform_window_delegate.h" -#include "ui/views/corewm/tooltip.h" -#include "ui/views/corewm/tooltip_aura.h" -#include "ui/views/corewm/tooltip_controller.h" -#include "ui/views/drag_utils.h" -#include "ui/views/mus/drag_drop_client_mus.h" -#include "ui/views/mus/drop_target_mus.h" -#include "ui/views/mus/input_method_mus.h" -#include "ui/views/mus/window_manager_connection.h" -#include "ui/views/mus/window_manager_constants_converters.h" -#include "ui/views/mus/window_manager_frame_values.h" -#include "ui/views/mus/window_tree_host_mus.h" -#include "ui/views/widget/drop_helper.h" -#include "ui/views/widget/native_widget_aura.h" -#include "ui/views/widget/tooltip_manager_aura.h" -#include "ui/views/widget/widget_delegate.h" -#include "ui/views/window/custom_frame_view.h" -#include "ui/wm/core/base_focus_rules.h" -#include "ui/wm/core/capture_controller.h" -#include "ui/wm/core/cursor_manager.h" -#include "ui/wm/core/default_screen_position_client.h" -#include "ui/wm/core/focus_controller.h" -#include "ui/wm/core/native_cursor_manager.h" - -DECLARE_WINDOW_PROPERTY_TYPE(ui::Window*); - -using PrimitiveType = aura::PropertyConverter::PrimitiveType; -using ui::mojom::EventResult; - -namespace views { -namespace { - -DEFINE_WINDOW_PROPERTY_KEY(ui::Window*, kMusWindow, nullptr); - -MUS_DEFINE_WINDOW_PROPERTY_KEY(NativeWidgetMus*, kNativeWidgetMusKey, nullptr); - -// This ensures that only the top-level aura Window can be activated. -class FocusRulesImpl : public wm::BaseFocusRules { - public: - explicit FocusRulesImpl(aura::Window* root) : root_(root) {} - ~FocusRulesImpl() override {} - - bool SupportsChildActivation(aura::Window* window) const override { - return root_ == window; - } - - private: - aura::Window* root_; - - DISALLOW_COPY_AND_ASSIGN(FocusRulesImpl); -}; - -// This makes sure that an aura::Window focused (or activated) through the -// aura::client::FocusClient (or ActivationClient) focuses (or activates) the -// corresponding ui::Window too. -class FocusControllerMus : public wm::FocusController { - public: - explicit FocusControllerMus(wm::FocusRules* rules) : FocusController(rules) {} - ~FocusControllerMus() override {} - - private: - void FocusWindow(aura::Window* window) override { - FocusController::FocusWindow(window); - if (window) { - ui::Window* mus_window = window->GetRootWindow()->GetProperty(kMusWindow); - if (mus_window) - mus_window->SetFocus(); - } - } - - DISALLOW_COPY_AND_ASSIGN(FocusControllerMus); -}; - -class ContentWindowLayoutManager : public aura::LayoutManager { - public: - ContentWindowLayoutManager(aura::Window* outer, aura::Window* inner) - : outer_(outer), inner_(inner) {} - ~ContentWindowLayoutManager() override {} - - private: - // aura::LayoutManager: - void OnWindowResized() override { inner_->SetBounds(outer_->bounds()); } - void OnWindowAddedToLayout(aura::Window* child) override { - OnWindowResized(); - } - void OnWillRemoveWindowFromLayout(aura::Window* child) override {} - void OnWindowRemovedFromLayout(aura::Window* child) override {} - void OnChildWindowVisibilityChanged(aura::Window* child, - bool visible) override {} - void SetChildBounds(aura::Window* child, - const gfx::Rect& requested_bounds) override { - SetChildBoundsDirect(child, requested_bounds); - } - - aura::Window* outer_; - aura::Window* inner_; - - DISALLOW_COPY_AND_ASSIGN(ContentWindowLayoutManager); -}; - -class NativeWidgetMusWindowParentingClient - : public aura::client::WindowParentingClient { - public: - explicit NativeWidgetMusWindowParentingClient(aura::Window* root_window) - : root_window_(root_window) { - aura::client::SetWindowParentingClient(root_window_, this); - } - ~NativeWidgetMusWindowParentingClient() override { - aura::client::SetWindowParentingClient(root_window_, nullptr); - } - - // Overridden from client::WindowParentingClient: - aura::Window* GetDefaultParent(aura::Window* context, - aura::Window* window, - const gfx::Rect& bounds) override { - return root_window_; - } - - private: - aura::Window* root_window_; - - DISALLOW_COPY_AND_ASSIGN(NativeWidgetMusWindowParentingClient); -}; - -// A screen position client that applies the offset of the ui::Window. -class ScreenPositionClientMus : public wm::DefaultScreenPositionClient { - public: - explicit ScreenPositionClientMus(ui::Window* mus_window) - : mus_window_(mus_window) {} - ~ScreenPositionClientMus() override {} - - // wm::DefaultScreenPositionClient: - void ConvertPointToScreen(const aura::Window* window, - gfx::Point* point) override { - wm::DefaultScreenPositionClient::ConvertPointToScreen(window, point); - gfx::Rect mus_bounds = mus_window_->GetBoundsInRoot(); - point->Offset(-mus_bounds.x(), -mus_bounds.y()); - } - void ConvertPointFromScreen(const aura::Window* window, - gfx::Point* point) override { - gfx::Rect mus_bounds = mus_window_->GetBoundsInRoot(); - point->Offset(mus_bounds.x(), mus_bounds.y()); - wm::DefaultScreenPositionClient::ConvertPointFromScreen(window, point); - } - - private: - ui::Window* mus_window_; - - DISALLOW_COPY_AND_ASSIGN(ScreenPositionClientMus); -}; - -class NativeCursorManagerMus : public wm::NativeCursorManager { - public: - explicit NativeCursorManagerMus(ui::Window* mus_window) - : mus_window_(mus_window) {} - ~NativeCursorManagerMus() override {} - - // wm::NativeCursorManager: - void SetDisplay(const display::Display& display, - wm::NativeCursorManagerDelegate* delegate) override { - // We ignore this entirely, as cursor are set on the client. - } - - void SetCursor(gfx::NativeCursor cursor, - wm::NativeCursorManagerDelegate* delegate) override { - mus_window_->SetPredefinedCursor(ui::mojom::Cursor(cursor.native_type())); - delegate->CommitCursor(cursor); - } - - void SetVisibility(bool visible, - wm::NativeCursorManagerDelegate* delegate) override { - delegate->CommitVisibility(visible); - - if (visible) - SetCursor(delegate->GetCursor(), delegate); - else - mus_window_->SetPredefinedCursor(ui::mojom::Cursor::NONE); - } - - void SetCursorSet(ui::CursorSetType cursor_set, - wm::NativeCursorManagerDelegate* delegate) override { - // TODO(erg): For now, ignore the difference between SET_NORMAL and - // SET_LARGE here. This feels like a thing that mus should decide instead. - // - // Also, it's NOTIMPLEMENTED() in the desktop version!? Including not - // acknowledging the call in the delegate. - NOTIMPLEMENTED(); - } - - void SetMouseEventsEnabled( - bool enabled, - wm::NativeCursorManagerDelegate* delegate) override { - // TODO(erg): How do we actually implement this? - // - // Mouse event dispatch is potentially done in a different process, - // definitely in a different mojo service. Each app is fairly locked down. - delegate->CommitMouseEventsEnabled(enabled); - NOTIMPLEMENTED(); - } - - private: - ui::Window* mus_window_; - - DISALLOW_COPY_AND_ASSIGN(NativeCursorManagerMus); -}; - -// As the window manager renderers the non-client decorations this class does -// very little but honor the client area insets from the window manager. -class ClientSideNonClientFrameView : public NonClientFrameView { - public: - explicit ClientSideNonClientFrameView(views::Widget* widget) - : widget_(widget) {} - ~ClientSideNonClientFrameView() override {} - - private: - // Returns the default values of client area insets from the window manager. - static gfx::Insets GetDefaultWindowManagerInsets(bool is_maximized) { - const WindowManagerFrameValues& values = - WindowManagerFrameValues::instance(); - return is_maximized ? values.maximized_insets : values.normal_insets; - } - - // NonClientFrameView: - gfx::Rect GetBoundsForClientView() const override { - gfx::Rect result(GetLocalBounds()); - if (widget_->IsFullscreen()) - return result; - result.Inset(GetDefaultWindowManagerInsets(widget_->IsMaximized())); - return result; - } - gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const override { - if (widget_->IsFullscreen()) - return client_bounds; - - const gfx::Insets insets( - GetDefaultWindowManagerInsets(widget_->IsMaximized())); - return gfx::Rect(client_bounds.x() - insets.left(), - client_bounds.y() - insets.top(), - client_bounds.width() + insets.width(), - client_bounds.height() + insets.height()); - } - int NonClientHitTest(const gfx::Point& point) override { return HTNOWHERE; } - void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override { - // The window manager provides the shape; do nothing. - } - void ResetWindowControls() override { - // TODO(sky): push to wm? - } - - // These have no implementation. The Window Manager handles the actual - // rendering of the icon/title. See NonClientFrameViewMash. The values - // associated with these methods are pushed to the server by the way of - // NativeWidgetMus functions. - void UpdateWindowIcon() override {} - void UpdateWindowTitle() override {} - void SizeConstraintsChanged() override {} - - gfx::Size GetPreferredSize() const override { - return widget_->non_client_view() - ->GetWindowBoundsForClientBounds( - gfx::Rect(widget_->client_view()->GetPreferredSize())) - .size(); - } - gfx::Size GetMinimumSize() const override { - return widget_->non_client_view() - ->GetWindowBoundsForClientBounds( - gfx::Rect(widget_->client_view()->GetMinimumSize())) - .size(); - } - gfx::Size GetMaximumSize() const override { - gfx::Size max_size = widget_->client_view()->GetMaximumSize(); - gfx::Size converted_size = - widget_->non_client_view() - ->GetWindowBoundsForClientBounds(gfx::Rect(max_size)) - .size(); - return gfx::Size(max_size.width() == 0 ? 0 : converted_size.width(), - max_size.height() == 0 ? 0 : converted_size.height()); - } - - views::Widget* widget_; - - DISALLOW_COPY_AND_ASSIGN(ClientSideNonClientFrameView); -}; - -// Handles acknowledgment of an input event, either immediately when a nested -// message loop starts, or upon destruction. -class EventAckHandler : public base::MessageLoop::NestingObserver { - public: - explicit EventAckHandler( - std::unique_ptr<base::Callback<void(EventResult)>> ack_callback) - : ack_callback_(std::move(ack_callback)) { - DCHECK(ack_callback_); - base::MessageLoop::current()->AddNestingObserver(this); - } - - ~EventAckHandler() override { - base::MessageLoop::current()->RemoveNestingObserver(this); - if (ack_callback_) { - ack_callback_->Run(handled_ ? EventResult::HANDLED - : EventResult::UNHANDLED); - } - } - - void set_handled(bool handled) { handled_ = handled; } - - // base::MessageLoop::NestingObserver: - void OnBeginNestedMessageLoop() override { - // Acknowledge the event immediately if a nested message loop starts. - // Otherwise we appear unresponsive for the life of the nested message loop. - if (ack_callback_) { - ack_callback_->Run(EventResult::HANDLED); - ack_callback_.reset(); - } - } - - private: - std::unique_ptr<base::Callback<void(EventResult)>> ack_callback_; - bool handled_ = false; - - DISALLOW_COPY_AND_ASSIGN(EventAckHandler); -}; - -void OnMoveLoopEnd(bool* out_success, - base::Closure quit_closure, - bool in_success) { - *out_success = in_success; - quit_closure.Run(); -} - -ui::mojom::ShowState GetShowState(const ui::Window* window) { - if (!window || - !window->HasSharedProperty( - ui::mojom::WindowManager::kShowState_Property)) { - return ui::mojom::ShowState::DEFAULT; - } - - return static_cast<ui::mojom::ShowState>( - window->GetSharedProperty<PrimitiveType>( - ui::mojom::WindowManager::kShowState_Property)); -} - -// Set the app or window icon property for the window. -void SetIconProperty(ui::Window* window, - const char* const property, - const gfx::ImageSkia& icon) { - // TODO(crbug.com/667566): Support additional scales or gfx::Image[Skia]. - SkBitmap bitmap = icon.GetRepresentation(1.f).sk_bitmap(); - if (!bitmap.isNull()) - window->SetSharedProperty<SkBitmap>(property, bitmap); - else if (window->HasSharedProperty(property)) - window->ClearSharedProperty(property); -} - -// Helper function to get the device_scale_factor() of the display::Display -// nearest to |window|. -float ScaleFactorForDisplay(aura::Window* window) { - return display::Screen::GetScreen() - ->GetDisplayNearestWindow(window) - .device_scale_factor(); -} - -} // namespace - -class NativeWidgetMus::MusWindowObserver : public ui::WindowObserver { - public: - explicit MusWindowObserver(NativeWidgetMus* native_widget_mus) - : native_widget_mus_(native_widget_mus), - show_state_(ui::mojom::ShowState::DEFAULT) { - mus_window()->AddObserver(this); - } - - ~MusWindowObserver() override { - mus_window()->RemoveObserver(this); - } - - // ui::WindowObserver: - void OnWindowVisibilityChanging(ui::Window* window, bool visible) override { - native_widget_mus_->OnMusWindowVisibilityChanging(window, visible); - } - void OnWindowVisibilityChanged(ui::Window* window, bool visible) override { - native_widget_mus_->OnMusWindowVisibilityChanged(window, visible); - } - void OnWindowPredefinedCursorChanged(ui::Window* window, - ui::mojom::Cursor cursor) override { - DCHECK_EQ(window, mus_window()); - native_widget_mus_->set_last_cursor(cursor); - } - void OnWindowSharedPropertyChanged( - ui::Window* window, - const std::string& name, - const std::vector<uint8_t>* old_data, - const std::vector<uint8_t>* new_data) override { - if (name != ui::mojom::WindowManager::kShowState_Property) - return; - const ui::mojom::ShowState show_state = GetShowState(window); - if (show_state == show_state_) - return; - show_state_ = show_state; - ui::PlatformWindowState state = ui::PLATFORM_WINDOW_STATE_UNKNOWN; - switch (show_state_) { - case ui::mojom::ShowState::MINIMIZED: - state = ui::PLATFORM_WINDOW_STATE_MINIMIZED; - break; - case ui::mojom::ShowState::MAXIMIZED: - state = ui::PLATFORM_WINDOW_STATE_MAXIMIZED; - break; - case ui::mojom::ShowState::DEFAULT: - case ui::mojom::ShowState::INACTIVE: - case ui::mojom::ShowState::NORMAL: - case ui::mojom::ShowState::DOCKED: - // TODO(sky): support docked. - state = ui::PLATFORM_WINDOW_STATE_NORMAL; - break; - case ui::mojom::ShowState::FULLSCREEN: - state = ui::PLATFORM_WINDOW_STATE_FULLSCREEN; - break; - } - platform_window_delegate()->OnWindowStateChanged(state); - } - void OnWindowDestroyed(ui::Window* window) override { - DCHECK_EQ(mus_window(), window); - platform_window_delegate()->OnClosed(); - } - void OnWindowBoundsChanging(ui::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) override { - DCHECK_EQ(window, mus_window()); - window_tree_host()->SetBoundsInPixels(gfx::ConvertRectToPixel( - ScaleFactorForDisplay(aura_window()), new_bounds)); - } - void OnWindowFocusChanged(ui::Window* gained_focus, - ui::Window* lost_focus) override { - if (gained_focus == mus_window()) - platform_window_delegate()->OnActivationChanged(true); - else if (lost_focus == mus_window()) - platform_window_delegate()->OnActivationChanged(false); - } - void OnRequestClose(ui::Window* window) override { - platform_window_delegate()->OnCloseRequest(); - } - - private: - ui::Window* mus_window() { return native_widget_mus_->window(); } - aura::Window* aura_window() { return native_widget_mus_->aura_window(); } - WindowTreeHostMus* window_tree_host() { - return native_widget_mus_->window_tree_host(); - } - ui::PlatformWindowDelegate* platform_window_delegate() { - return native_widget_mus_->window_tree_host(); - } - - NativeWidgetMus* native_widget_mus_; - ui::mojom::ShowState show_state_; - - DISALLOW_COPY_AND_ASSIGN(MusWindowObserver); -}; - -class NativeWidgetMus::MusCaptureClient - : public aura::client::DefaultCaptureClient { - public: - MusCaptureClient(aura::Window* root_window, - aura::Window* aura_window, - ui::Window* mus_window) - : aura::client::DefaultCaptureClient(root_window), - aura_window_(aura_window), - mus_window_(mus_window) {} - ~MusCaptureClient() override {} - - // aura::client::DefaultCaptureClient: - void SetCapture(aura::Window* window) override { - aura::client::DefaultCaptureClient::SetCapture(window); - if (aura_window_ == window) - mus_window_->SetCapture(); - } - void ReleaseCapture(aura::Window* window) override { - aura::client::DefaultCaptureClient::ReleaseCapture(window); - if (aura_window_ == window) - mus_window_->ReleaseCapture(); - } - - private: - aura::Window* aura_window_; - ui::Window* mus_window_; - - DISALLOW_COPY_AND_ASSIGN(MusCaptureClient); -}; - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetMus, public: - -NativeWidgetMus::NativeWidgetMus( - internal::NativeWidgetDelegate* delegate, - ui::Window* window, - ui::mojom::CompositorFrameSinkType compositor_frame_sink_type) - : window_(window), - last_cursor_(ui::mojom::Cursor::CURSOR_NULL), - native_widget_delegate_(delegate), - compositor_frame_sink_type_(compositor_frame_sink_type), - show_state_before_fullscreen_(ui::mojom::ShowState::DEFAULT), - ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), - content_(new aura::Window(this)), - last_drop_operation_(ui::DragDropTypes::DRAG_NONE), - close_widget_factory_(this) { - window_->set_input_event_handler(this); - mus_window_observer_ = base::MakeUnique<MusWindowObserver>(this); - - // TODO(fsamuel): Figure out lifetime of |window_|. - aura::SetMusWindow(content_, window_); - window->SetLocalProperty(kNativeWidgetMusKey, this); - window_tree_host_ = base::MakeUnique<WindowTreeHostMus>(this, window_); - input_method_ = - base::MakeUnique<InputMethodMus>(window_tree_host_.get(), window_); - window_tree_host_->SetSharedInputMethod(input_method_.get()); -} - -NativeWidgetMus::~NativeWidgetMus() { - if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) { - DCHECK(!window_); - delete native_widget_delegate_; - } else { - if (window_) - window_->set_input_event_handler(nullptr); - CloseNow(); - } -} - -// static -void NativeWidgetMus::NotifyFrameChanged(ui::WindowTreeClient* client) { - for (ui::Window* window : client->GetRoots()) { - NativeWidgetMus* native_widget = - window->GetLocalProperty(kNativeWidgetMusKey); - if (native_widget && native_widget->GetWidget()->non_client_view()) { - native_widget->GetWidget()->non_client_view()->Layout(); - native_widget->GetWidget()->non_client_view()->SchedulePaint(); - native_widget->UpdateClientArea(); - native_widget->UpdateHitTestMask(); - } - } -} - -// static -NativeWidgetMus* NativeWidgetMus::GetForWindow(ui::Window* window) { - DCHECK(window); - NativeWidgetMus* native_widget = - window->GetLocalProperty(kNativeWidgetMusKey); - return native_widget; -} - -// static -Widget* NativeWidgetMus::GetWidgetForWindow(ui::Window* window) { - NativeWidgetMus* native_widget = GetForWindow(window); - if (!native_widget) - return nullptr; - return native_widget->GetWidget(); -} - -aura::Window* NativeWidgetMus::GetRootWindow() { - return window_tree_host_->window(); -} - -void NativeWidgetMus::OnPlatformWindowClosed() { - native_widget_delegate_->OnNativeWidgetDestroying(); - - tooltip_manager_.reset(); - if (tooltip_controller_.get()) { - window_tree_host_->window()->RemovePreTargetHandler( - tooltip_controller_.get()); - aura::client::SetTooltipClient(window_tree_host_->window(), NULL); - tooltip_controller_.reset(); - } - - window_parenting_client_.reset(); // Uses |content_|. - capture_client_.reset(); // Uses |content_|. - - window_tree_host_->RemoveObserver(this); - window_tree_host_.reset(); - - cursor_manager_.reset(); // Uses |window_|. - - mus_window_observer_.reset(nullptr); - - window_ = nullptr; - content_ = nullptr; - - native_widget_delegate_->OnNativeWidgetDestroyed(); - if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) - delete this; -} - -void NativeWidgetMus::OnActivationChanged(bool active) { - if (!native_widget_delegate_) - return; - if (active) { - native_widget_delegate_->OnNativeFocus(); - GetWidget()->GetFocusManager()->RestoreFocusedView(); - } else { - native_widget_delegate_->OnNativeBlur(); - GetWidget()->GetFocusManager()->StoreFocusedView(true); - } - native_widget_delegate_->OnNativeWidgetActivationChanged(active); -} - -void NativeWidgetMus::UpdateClientArea() { - if (is_parallel_widget_in_window_manager()) - return; - - NonClientView* non_client_view = - native_widget_delegate_->AsWidget()->non_client_view(); - if (!non_client_view || !non_client_view->client_view()) - return; - - const gfx::Rect client_area_rect(non_client_view->client_view()->bounds()); - window_->SetClientArea(gfx::Insets( - client_area_rect.y(), client_area_rect.x(), - non_client_view->bounds().height() - client_area_rect.bottom(), - non_client_view->bounds().width() - client_area_rect.right())); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetMus, private: - -// static -void NativeWidgetMus::ConfigurePropertiesForNewWindow( - const Widget::InitParams& init_params, - std::map<std::string, std::vector<uint8_t>>* properties) { - properties->insert(init_params.mus_properties.begin(), - init_params.mus_properties.end()); - if (!init_params.bounds.IsEmpty()) { - (*properties)[ui::mojom::WindowManager::kBounds_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>(init_params.bounds); - } - if (!init_params.name.empty()) { - (*properties)[ui::mojom::WindowManager::kName_Property] = - mojo::ConvertTo<std::vector<uint8_t>>(init_params.name); - } - (*properties)[ui::mojom::WindowManager::kAlwaysOnTop_Property] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<PrimitiveType>(init_params.keep_on_top)); - - (*properties)[ui::mojom::WindowManager::kWindowType_InitProperty] = - mojo::ConvertTo<std::vector<uint8_t>>( - static_cast<int32_t>(init_params.type)); - - if (!Widget::RequiresNonClientView(init_params.type)) - return; - - if (init_params.delegate) { - if (properties->count(ui::mojom::WindowManager::kResizeBehavior_Property) == - 0) { - (*properties)[ui::mojom::WindowManager::kResizeBehavior_Property] = - mojo::ConvertTo<std::vector<uint8_t>>(static_cast<PrimitiveType>( - init_params.delegate->GetResizeBehavior())); - } - - // TODO(crbug.com/667566): Support additional scales or gfx::Image[Skia]. - gfx::ImageSkia app_icon = init_params.delegate->GetWindowAppIcon(); - SkBitmap app_bitmap = app_icon.GetRepresentation(1.f).sk_bitmap(); - if (!app_bitmap.isNull()) { - (*properties)[ui::mojom::WindowManager::kAppIcon_Property] = - mojo::ConvertTo<std::vector<uint8_t>>(app_bitmap); - } - // TODO(crbug.com/667566): Support additional scales or gfx::Image[Skia]. - gfx::ImageSkia window_icon = init_params.delegate->GetWindowIcon(); - SkBitmap window_bitmap = window_icon.GetRepresentation(1.f).sk_bitmap(); - if (!window_bitmap.isNull()) { - (*properties)[ui::mojom::WindowManager::kWindowIcon_Property] = - mojo::ConvertTo<std::vector<uint8_t>>(window_bitmap); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetMus, internal::NativeWidgetPrivate implementation: - -NonClientFrameView* NativeWidgetMus::CreateNonClientFrameView() { - return new ClientSideNonClientFrameView(GetWidget()); -} - -void NativeWidgetMus::InitNativeWidget(const Widget::InitParams& params) { - NativeWidgetAura::RegisterNativeWidgetForWindow(this, content_); - aura::Window* hosted_window = window_tree_host_->window(); - - ownership_ = params.ownership; - window_->SetCanFocus(params.activatable == - Widget::InitParams::ACTIVATABLE_YES); - window_->SetCanAcceptEvents(params.accept_events); - - window_tree_host_->AddObserver(this); - window_tree_host_->InitHost(); - window_tree_host_->window()->Show(); - hosted_window->SetProperty(kMusWindow, window_); - - // TODO(moshayedi): crbug.com/641039. Investigate whether there are any cases - // where we need input method but don't have the WindowManagerConnection here. - if (WindowManagerConnection::Exists()) - input_method_->Init(WindowManagerConnection::Get()->connector()); - - focus_client_ = - base::MakeUnique<FocusControllerMus>(new FocusRulesImpl(hosted_window)); - - aura::client::SetFocusClient(hosted_window, focus_client_.get()); - aura::client::SetActivationClient(hosted_window, focus_client_.get()); - screen_position_client_ = base::MakeUnique<ScreenPositionClientMus>(window_); - aura::client::SetScreenPositionClient(hosted_window, - screen_position_client_.get()); - - drag_drop_client_ = base::MakeUnique<DragDropClientMus>(window_); - aura::client::SetDragDropClient(hosted_window, drag_drop_client_.get()); - drop_target_ = base::MakeUnique<DropTargetMus>(content_); - window_->SetCanAcceptDrops(drop_target_.get()); - drop_helper_ = base::MakeUnique<DropHelper>(GetWidget()->GetRootView()); - aura::client::SetDragDropDelegate(content_, this); - - if (params.type != Widget::InitParams::TYPE_TOOLTIP) { - tooltip_manager_ = base::MakeUnique<TooltipManagerAura>(GetWidget()); - tooltip_controller_ = base::MakeUnique<corewm::TooltipController>( - base::MakeUnique<corewm::TooltipAura>()); - aura::client::SetTooltipClient(window_tree_host_->window(), - tooltip_controller_.get()); - window_tree_host_->window()->AddPreTargetHandler(tooltip_controller_.get()); - } - - // TODO(erg): Remove this check when ash/mus/move_event_handler.cc's - // direct usage of ui::Window::SetPredefinedCursor() is switched to a - // private method on WindowManagerClient. - if (!is_parallel_widget_in_window_manager()) { - cursor_manager_ = base::MakeUnique<wm::CursorManager>( - base::MakeUnique<NativeCursorManagerMus>(window_)); - aura::client::SetCursorClient(hosted_window, cursor_manager_.get()); - } - - window_parenting_client_ = - base::MakeUnique<NativeWidgetMusWindowParentingClient>(hosted_window); - hosted_window->AddPreTargetHandler(focus_client_.get()); - hosted_window->SetLayoutManager( - new ContentWindowLayoutManager(hosted_window, content_)); - capture_client_ = - base::MakeUnique<MusCaptureClient>(hosted_window, content_, window_); - - content_->SetType(ui::wm::WINDOW_TYPE_NORMAL); - content_->Init(params.layer_type); - if (window_->visible()) - content_->Show(); - content_->SetTransparent(true); - content_->SetFillsBoundsCompletely(false); - content_->set_ignore_events(!params.accept_events); - hosted_window->AddChild(content_); - - ui::Window* parent_mus = params.parent_mus; - - // Set-up transiency if appropriate. - if (params.parent && !params.child) { - aura::Window* parent_root_aura = params.parent->GetRootWindow(); - ui::Window* parent_root_mus = parent_root_aura->GetProperty(kMusWindow); - if (parent_root_mus) { - parent_root_mus->AddTransientWindow(window_); - if (!parent_mus) - parent_mus = parent_root_mus; - } - } - - if (parent_mus) - parent_mus->AddChild(window_); - - // TODO(sky): deal with show state. - if (!params.bounds.size().IsEmpty()) - SetBounds(params.bounds); - - // TODO(beng): much else, see [Desktop]NativeWidgetAura. - - native_widget_delegate_->OnNativeWidgetCreated(false); -} - -void NativeWidgetMus::OnWidgetInitDone() { - // The client area is calculated from the NonClientView. During - // InitNativeWidget() the NonClientView has not been created. When this - // function is called the NonClientView has been created, so that we can - // correctly calculate the client area and push it to the ui::Window. - UpdateClientArea(); - UpdateHitTestMask(); -} - -bool NativeWidgetMus::ShouldUseNativeFrame() const { - NOTIMPLEMENTED(); - return false; -} - -bool NativeWidgetMus::ShouldWindowContentsBeTransparent() const { - NOTIMPLEMENTED(); - return true; -} - -void NativeWidgetMus::FrameTypeChanged() { - NOTIMPLEMENTED(); -} - -Widget* NativeWidgetMus::GetWidget() { - return native_widget_delegate_->AsWidget(); -} - -const Widget* NativeWidgetMus::GetWidget() const { - return native_widget_delegate_->AsWidget(); -} - -gfx::NativeView NativeWidgetMus::GetNativeView() const { - return content_; -} - -gfx::NativeWindow NativeWidgetMus::GetNativeWindow() const { - return content_; -} - -Widget* NativeWidgetMus::GetTopLevelWidget() { - return GetWidget(); -} - -const ui::Compositor* NativeWidgetMus::GetCompositor() const { - return window_tree_host_->compositor(); -} - -const ui::Layer* NativeWidgetMus::GetLayer() const { - return content_ ? content_->layer() : nullptr; -} - -void NativeWidgetMus::ReorderNativeViews() { - NOTIMPLEMENTED(); -} - -void NativeWidgetMus::ViewRemoved(View* view) { - NOTIMPLEMENTED(); -} - -// These methods are wrong in mojo. They're not usually used to associate data -// with a window; they are used to pass data from one layer to another (and in -// chrome/ to unsafely pass raw pointers around--I can only find two places -// where we do the "safe" thing and even that requires casting an integer to a -// void*). They can't be used safely in a world where we separate things with -// mojo. -// -// It's also used to communicate between views and aura; in views, we set -// properties on a widget, and read these properties directly in aura code. -void NativeWidgetMus::SetNativeWindowProperty(const char* name, void* value) { - if (content_) - content_->SetNativeWindowProperty(name, value); -} - -void* NativeWidgetMus::GetNativeWindowProperty(const char* name) const { - return content_ ? content_->GetNativeWindowProperty(name) : nullptr; -} - -TooltipManager* NativeWidgetMus::GetTooltipManager() const { - return tooltip_manager_.get(); -} - -void NativeWidgetMus::SetCapture() { - if (content_) - content_->SetCapture(); -} - -void NativeWidgetMus::ReleaseCapture() { - if (content_) - content_->ReleaseCapture(); -} - -bool NativeWidgetMus::HasCapture() const { - return content_ && content_->HasCapture(); -} - -ui::InputMethod* NativeWidgetMus::GetInputMethod() { - return window_tree_host_ ? window_tree_host_->GetInputMethod() : nullptr; -} - -void NativeWidgetMus::CenterWindow(const gfx::Size& size) { - if (is_parallel_widget_in_window_manager()) - return; - // TODO(beng): clear user-placed property and set preferred size property. - window_->SetSharedProperty<gfx::Size>( - ui::mojom::WindowManager::kPreferredSize_Property, size); - - gfx::Rect bounds = display::Screen::GetScreen() - ->GetDisplayNearestWindow(content_) - .work_area(); - bounds.ClampToCenteredSize(size); - window_->SetBounds(bounds); -} - -void NativeWidgetMus::GetWindowPlacement( - gfx::Rect* bounds, - ui::WindowShowState* maximized) const { - NOTIMPLEMENTED(); -} - -bool NativeWidgetMus::SetWindowTitle(const base::string16& title) { - if (!window_ || is_parallel_widget_in_window_manager()) - return false; - const char* kWindowTitle_Property = - ui::mojom::WindowManager::kWindowTitle_Property; - const base::string16 current_title = - window_->HasSharedProperty(kWindowTitle_Property) - ? window_->GetSharedProperty<base::string16>(kWindowTitle_Property) - : base::string16(); - if (current_title == title) - return false; - window_->SetSharedProperty<base::string16>(kWindowTitle_Property, title); - return true; -} - -void NativeWidgetMus::SetWindowIcons(const gfx::ImageSkia& window_icon, - const gfx::ImageSkia& app_icon) { - if (is_parallel_widget_in_window_manager()) - return; - - SetIconProperty(window_, ui::mojom::WindowManager::kWindowIcon_Property, - window_icon); - SetIconProperty(window_, ui::mojom::WindowManager::kAppIcon_Property, - app_icon); -} - -void NativeWidgetMus::InitModalType(ui::ModalType modal_type) { - if (modal_type != ui::MODAL_TYPE_NONE) - window_->SetModal(); -} - -gfx::Rect NativeWidgetMus::GetWindowBoundsInScreen() const { - if (!window_) - return gfx::Rect(); - - // Correct for the origin of the display. - const int64_t window_display_id = window_->GetRoot()->display_id(); - for (display::Display display : - display::Screen::GetScreen()->GetAllDisplays()) { - if (display.id() == window_display_id) { - gfx::Point display_origin = display.bounds().origin(); - gfx::Rect bounds_in_screen = window_->GetBoundsInRoot(); - bounds_in_screen.Offset(display_origin.x(), display_origin.y()); - return bounds_in_screen; - } - } - // Unknown display, assume primary display at 0,0. - return window_->GetBoundsInRoot(); -} - -gfx::Rect NativeWidgetMus::GetClientAreaBoundsInScreen() const { - // View-to-screen coordinate system transformations depend on this returning - // the full window bounds, for example View::ConvertPointToScreen(). - return GetWindowBoundsInScreen(); -} - -gfx::Rect NativeWidgetMus::GetRestoredBounds() const { - // Restored bounds should only be relevant if the window is minimized, - // maximized, fullscreen or docked. However, in some places the code expects - // GetRestoredBounds() to return the current window bounds if the window is - // not in either state. - if (IsMinimized() || IsMaximized() || IsFullscreen()) { - const char* kRestoreBounds_Property = - ui::mojom::WindowManager::kRestoreBounds_Property; - if (window_->HasSharedProperty(kRestoreBounds_Property)) - return window_->GetSharedProperty<gfx::Rect>(kRestoreBounds_Property); - } - return GetWindowBoundsInScreen(); -} - -std::string NativeWidgetMus::GetWorkspace() const { - return std::string(); -} - -void NativeWidgetMus::SetBounds(const gfx::Rect& bounds_in_screen) { - if (!(window_ && window_tree_host_)) - return; - - // TODO(jamescook): Needs something like aura::ScreenPositionClient so higher - // level code can move windows between displays. crbug.com/645291 - gfx::Point origin(bounds_in_screen.origin()); - const gfx::Point display_origin = display::Screen::GetScreen() - ->GetDisplayMatching(bounds_in_screen) - .bounds() - .origin(); - origin.Offset(-display_origin.x(), -display_origin.y()); - - gfx::Size size(bounds_in_screen.size()); - const gfx::Size min_size = GetMinimumSize(); - const gfx::Size max_size = GetMaximumSize(); - if (!max_size.IsEmpty()) - size.SetToMin(max_size); - size.SetToMax(min_size); - window_->SetBounds(gfx::Rect(origin, size)); - // Observer on |window_tree_host_| expected to synchronously update bounds. - DCHECK_EQ(gfx::ConvertRectToPixel(ScaleFactorForDisplay(content_), - window_->bounds()) - .ToString(), - window_tree_host_->GetBoundsInPixels().ToString()); -} - -void NativeWidgetMus::SetSize(const gfx::Size& size) { - if (!window_tree_host_) - return; - - gfx::Rect bounds = window_tree_host_->GetBoundsInPixels(); - SetBounds(gfx::Rect(bounds.origin(), size)); -} - -void NativeWidgetMus::StackAbove(gfx::NativeView native_view) { - NOTIMPLEMENTED(); -} - -void NativeWidgetMus::StackAtTop() { - NOTIMPLEMENTED(); -} - -void NativeWidgetMus::SetShape(std::unique_ptr<SkRegion> shape) { - NOTIMPLEMENTED(); -} - -void NativeWidgetMus::Close() { - Hide(); - if (!close_widget_factory_.HasWeakPtrs()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&NativeWidgetMus::CloseNow, - close_widget_factory_.GetWeakPtr())); - } -} - -void NativeWidgetMus::CloseNow() { - // Depending upon ownership |window_| may have been destroyed. - if (window_) - window_->Destroy(); -} - -void NativeWidgetMus::Show() { - ShowWithWindowState(ui::SHOW_STATE_NORMAL); -} - -void NativeWidgetMus::Hide() { - if (!(window_ && window_tree_host_)) - return; - - // NOTE: |window_tree_host_| and |window_| visibility is updated in - // OnMusWindowVisibilityChanged(). - window_->SetVisible(false); -} - -void NativeWidgetMus::ShowMaximizedWithBounds( - const gfx::Rect& restored_bounds) { - if (!window_) - return; - - window_->SetSharedProperty<gfx::Rect>( - ui::mojom::WindowManager::kRestoreBounds_Property, restored_bounds); - ShowWithWindowState(ui::SHOW_STATE_MAXIMIZED); -} - -void NativeWidgetMus::ShowWithWindowState(ui::WindowShowState state) { - if (!(window_ && window_tree_host_)) - return; - - // Matches NativeWidgetAura. - switch (state) { - case ui::SHOW_STATE_MAXIMIZED: - SetShowState(ui::mojom::ShowState::MAXIMIZED); - break; - case ui::SHOW_STATE_FULLSCREEN: - SetShowState(ui::mojom::ShowState::FULLSCREEN); - break; - case ui::SHOW_STATE_DOCKED: - SetShowState(ui::mojom::ShowState::DOCKED); - break; - default: - break; - } - - // NOTE: |window_tree_host_| and |window_| visibility is updated in - // OnMusWindowVisibilityChanged(). - window_->SetVisible(true); - if (native_widget_delegate_->CanActivate()) { - if (state != ui::SHOW_STATE_INACTIVE) - Activate(); - GetWidget()->SetInitialFocus(state); - } - - // Matches NativeWidgetAura. - if (state == ui::SHOW_STATE_MINIMIZED) - Minimize(); -} - -bool NativeWidgetMus::IsVisible() const { - // TODO(beng): this should probably be wired thru PlatformWindow. - return window_ && window_->visible(); -} - -void NativeWidgetMus::Activate() { - if (!window_) - return; - - static_cast<aura::client::ActivationClient*>(focus_client_.get()) - ->ActivateWindow(content_); -} - -void NativeWidgetMus::Deactivate() { - if (IsActive()) - window_->window_tree()->ClearFocus(); -} - -bool NativeWidgetMus::IsActive() const { - ui::Window* focused = - window_ ? window_->window_tree()->GetFocusedWindow() : nullptr; - return focused && window_->Contains(focused); -} - -void NativeWidgetMus::SetAlwaysOnTop(bool always_on_top) { - if (window_ && !is_parallel_widget_in_window_manager()) { - window_->SetSharedProperty<bool>( - ui::mojom::WindowManager::kAlwaysOnTop_Property, always_on_top); - } -} - -bool NativeWidgetMus::IsAlwaysOnTop() const { - return window_ && - window_->HasSharedProperty( - ui::mojom::WindowManager::kAlwaysOnTop_Property) && - window_->GetSharedProperty<bool>( - ui::mojom::WindowManager::kAlwaysOnTop_Property); -} - -void NativeWidgetMus::SetVisibleOnAllWorkspaces(bool always_visible) { - // Not needed for chromeos. -} - -bool NativeWidgetMus::IsVisibleOnAllWorkspaces() const { - return false; -} - -void NativeWidgetMus::Maximize() { - SetShowState(ui::mojom::ShowState::MAXIMIZED); -} - -void NativeWidgetMus::Minimize() { - SetShowState(ui::mojom::ShowState::MINIMIZED); -} - -bool NativeWidgetMus::IsMaximized() const { - return GetShowState(window_) == ui::mojom::ShowState::MAXIMIZED; -} - -bool NativeWidgetMus::IsMinimized() const { - return GetShowState(window_) == ui::mojom::ShowState::MINIMIZED; -} - -void NativeWidgetMus::Restore() { - SetShowState(ui::mojom::ShowState::NORMAL); -} - -void NativeWidgetMus::SetFullscreen(bool fullscreen) { - if (IsFullscreen() == fullscreen) - return; - if (fullscreen) { - show_state_before_fullscreen_ = GetShowState(window_); - SetShowState(ui::mojom::ShowState::FULLSCREEN); - } else { - switch (show_state_before_fullscreen_) { - case ui::mojom::ShowState::MAXIMIZED: - Maximize(); - break; - case ui::mojom::ShowState::MINIMIZED: - Minimize(); - break; - case ui::mojom::ShowState::DEFAULT: - case ui::mojom::ShowState::NORMAL: - case ui::mojom::ShowState::INACTIVE: - case ui::mojom::ShowState::FULLSCREEN: - case ui::mojom::ShowState::DOCKED: - // TODO(sad): This may not be sufficient. - Restore(); - break; - } - } -} - -bool NativeWidgetMus::IsFullscreen() const { - return GetShowState(window_) == ui::mojom::ShowState::FULLSCREEN; -} - -void NativeWidgetMus::SetOpacity(float opacity) { - if (window_) - window_->SetOpacity(opacity); -} - -void NativeWidgetMus::FlashFrame(bool flash_frame) { - NOTIMPLEMENTED(); -} - -void NativeWidgetMus::RunShellDrag(View* view, - const ui::OSExchangeData& data, - const gfx::Point& location, - int drag_operations, - ui::DragDropTypes::DragEventSource source) { - if (window_) - views::RunShellDrag(content_, data, location, drag_operations, source); -} - -void NativeWidgetMus::SchedulePaintInRect(const gfx::Rect& rect) { - if (content_) - content_->SchedulePaintInRect(rect); -} - -void NativeWidgetMus::SetCursor(gfx::NativeCursor cursor) { - if (!window_) - return; - - // TODO(erg): In aura, our incoming cursor is really two - // parts. cursor.native_type() is an integer for standard cursors and is all - // we support right now. If native_type() == kCursorCustom, than we should - // also send an image, but as the cursor code is currently written, the image - // is in a platform native format that's already uploaded to the window - // server. - ui::mojom::Cursor new_cursor = ui::mojom::Cursor(cursor.native_type()); - if (last_cursor_ != new_cursor) - window_->SetPredefinedCursor(new_cursor); -} - -bool NativeWidgetMus::IsMouseEventsEnabled() const { - NOTIMPLEMENTED(); - return true; -} - -void NativeWidgetMus::ClearNativeFocus() { - if (!IsActive()) - return; - ui::Window* focused = - window_ ? window_->window_tree()->GetFocusedWindow() : nullptr; - if (focused && window_->Contains(focused) && focused != window_) - window_->SetFocus(); - // Move aura-focus back to |content_|, so that the Widget still receives - // events correctly. - aura::client::GetFocusClient(content_)->ResetFocusWithinActiveWindow( - content_); -} - -gfx::Rect NativeWidgetMus::GetWorkAreaBoundsInScreen() const { - NOTIMPLEMENTED(); - return gfx::Rect(); -} - -Widget::MoveLoopResult NativeWidgetMus::RunMoveLoop( - const gfx::Vector2d& drag_offset, - Widget::MoveLoopSource source, - Widget::MoveLoopEscapeBehavior escape_behavior) { - ReleaseCapture(); - - base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); - base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop); - base::RunLoop run_loop; - - ui::mojom::MoveLoopSource mus_source = - source == Widget::MOVE_LOOP_SOURCE_MOUSE - ? ui::mojom::MoveLoopSource::MOUSE - : ui::mojom::MoveLoopSource::TOUCH; - - bool success = false; - gfx::Point cursor_location = - display::Screen::GetScreen()->GetCursorScreenPoint(); - window_->PerformWindowMove( - mus_source, cursor_location, - base::Bind(OnMoveLoopEnd, &success, run_loop.QuitClosure())); - - run_loop.Run(); - - return success ? Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED; -} - -void NativeWidgetMus::EndMoveLoop() { - window_->CancelWindowMove(); -} - -void NativeWidgetMus::SetVisibilityChangedAnimationsEnabled(bool value) { - NOTIMPLEMENTED(); -} - -void NativeWidgetMus::SetVisibilityAnimationDuration( - const base::TimeDelta& duration) { - NOTIMPLEMENTED(); -} - -void NativeWidgetMus::SetVisibilityAnimationTransition( - Widget::VisibilityTransition transition) { - NOTIMPLEMENTED(); -} - -bool NativeWidgetMus::IsTranslucentWindowOpacitySupported() const { - NOTIMPLEMENTED(); - return true; -} - -void NativeWidgetMus::OnSizeConstraintsChanged() { - if (!window_ || is_parallel_widget_in_window_manager()) - return; - - int32_t behavior = ui::mojom::kResizeBehaviorNone; - if (GetWidget()->widget_delegate()) - behavior = GetWidget()->widget_delegate()->GetResizeBehavior(); - window_->SetSharedProperty<PrimitiveType>( - ui::mojom::WindowManager::kResizeBehavior_Property, behavior); -} - -void NativeWidgetMus::RepostNativeEvent(gfx::NativeEvent native_event) { - NOTIMPLEMENTED(); -} - -std::string NativeWidgetMus::GetName() const { - return window_->GetName(); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetMus, aura::WindowDelegate implementation: - -gfx::Size NativeWidgetMus::GetMinimumSize() const { - return native_widget_delegate_->GetMinimumSize(); -} - -gfx::Size NativeWidgetMus::GetMaximumSize() const { - return native_widget_delegate_->GetMaximumSize(); -} - -void NativeWidgetMus::OnBoundsChanged(const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) { - // This is handled in OnHost{Resized,Moved}() like DesktopNativeWidgetAura - // instead of here like in NativeWidgetAura. -} - -gfx::NativeCursor NativeWidgetMus::GetCursor(const gfx::Point& point) { - return gfx::NativeCursor(); -} - -int NativeWidgetMus::GetNonClientComponent(const gfx::Point& point) const { - return native_widget_delegate_->GetNonClientComponent(point); -} - -bool NativeWidgetMus::ShouldDescendIntoChildForEventHandling( - aura::Window* child, - const gfx::Point& location) { - views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate(); - return !widget_delegate || - widget_delegate->ShouldDescendIntoChildForEventHandling(child, location); -} - -bool NativeWidgetMus::CanFocus() { - return true; -} - -void NativeWidgetMus::OnCaptureLost() { - native_widget_delegate_->OnMouseCaptureLost(); -} - -void NativeWidgetMus::OnPaint(const ui::PaintContext& context) { - native_widget_delegate_->OnNativeWidgetPaint(context); -} - -void NativeWidgetMus::OnDeviceScaleFactorChanged(float device_scale_factor) { -} - -void NativeWidgetMus::OnWindowDestroying(aura::Window* window) { -} - -void NativeWidgetMus::OnWindowDestroyed(aura::Window* window) { - // Cleanup happens in OnPlatformWindowClosed(). -} - -void NativeWidgetMus::OnWindowTargetVisibilityChanged(bool visible) { -} - -bool NativeWidgetMus::HasHitTestMask() const { - return native_widget_delegate_->HasHitTestMask(); -} - -void NativeWidgetMus::GetHitTestMask(gfx::Path* mask) const { - native_widget_delegate_->GetHitTestMask(mask); -} - -void NativeWidgetMus::SetShowState(ui::mojom::ShowState show_state) { - if (!window_) - return; - window_->SetSharedProperty<PrimitiveType>( - ui::mojom::WindowManager::kShowState_Property, - static_cast<PrimitiveType>(show_state)); -} - -void NativeWidgetMus::OnKeyEvent(ui::KeyEvent* event) { - if (event->is_char()) { - // If a ui::InputMethod object is attached to the root window, character - // events are handled inside the object and are not passed to this function. - // If such object is not attached, character events might be sent (e.g. on - // Windows). In this case, we just skip these. - return; - } - // Renderer may send a key event back to us if the key event wasn't handled, - // and the window may be invisible by that time. - if (!content_->IsVisible()) - return; - - native_widget_delegate_->OnKeyEvent(event); -} - -void NativeWidgetMus::OnMouseEvent(ui::MouseEvent* event) { - DCHECK(content_->IsVisible()); - - if (tooltip_manager_.get()) - tooltip_manager_->UpdateTooltip(); - TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget()); - - native_widget_delegate_->OnMouseEvent(event); - // WARNING: we may have been deleted. -} - -void NativeWidgetMus::OnScrollEvent(ui::ScrollEvent* event) { - if (event->type() == ui::ET_SCROLL) { - native_widget_delegate_->OnScrollEvent(event); - if (event->handled()) - return; - - // Convert unprocessed scroll events into wheel events. - ui::MouseWheelEvent mwe(*event->AsScrollEvent()); - native_widget_delegate_->OnMouseEvent(&mwe); - if (mwe.handled()) - event->SetHandled(); - } else { - native_widget_delegate_->OnScrollEvent(event); - } -} - -void NativeWidgetMus::OnGestureEvent(ui::GestureEvent* event) { - native_widget_delegate_->OnGestureEvent(event); -} - -void NativeWidgetMus::OnHostResized(const aura::WindowTreeHost* host) { - native_widget_delegate_->OnNativeWidgetSizeChanged( - host->window()->bounds().size()); - UpdateClientArea(); - UpdateHitTestMask(); -} - -void NativeWidgetMus::OnHostMovedInPixels( - const aura::WindowTreeHost* host, - const gfx::Point& new_origin_in_pixels) { - native_widget_delegate_->OnNativeWidgetMove(); -} - -void NativeWidgetMus::OnHostCloseRequested(const aura::WindowTreeHost* host) { - GetWidget()->Close(); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetMus, aura::WindowDragDropDelegate implementation: - -void NativeWidgetMus::OnDragEntered(const ui::DropTargetEvent& event) { - DCHECK(drop_helper_); - last_drop_operation_ = drop_helper_->OnDragOver( - event.data(), event.location(), event.source_operations()); -} - -int NativeWidgetMus::OnDragUpdated(const ui::DropTargetEvent& event) { - DCHECK(drop_helper_); - last_drop_operation_ = drop_helper_->OnDragOver( - event.data(), event.location(), event.source_operations()); - return last_drop_operation_; -} - -void NativeWidgetMus::OnDragExited() { - DCHECK(drop_helper_); - drop_helper_->OnDragExit(); -} - -int NativeWidgetMus::OnPerformDrop(const ui::DropTargetEvent& event) { - DCHECK(drop_helper_); - return drop_helper_->OnDrop(event.data(), event.location(), - last_drop_operation_); -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeWidgetMus, ui::InputEventHandler implementation: - -void NativeWidgetMus::OnWindowInputEvent( - ui::Window* view, - const ui::Event& event_in, - std::unique_ptr<base::Callback<void(EventResult)>>* ack_callback) { - std::unique_ptr<ui::Event> event = ui::Event::Clone(event_in); - - if (event->IsKeyEvent()) { - input_method_->DispatchKeyEvent(event->AsKeyEvent(), - std::move(*ack_callback)); - return; - } - - // Take ownership of the callback, indicating that we will handle it. - EventAckHandler ack_handler(std::move(*ack_callback)); - - // TODO(markdittmer): This should be this->OnEvent(event.get()), but that - // can't happen until IME is refactored out of in WindowTreeHostMus. - platform_window_delegate()->DispatchEvent(event.get()); - // NOTE: |this| may be deleted. - - ack_handler.set_handled(event->handled()); - // |ack_handler| acks the event on destruction if necessary. -} - -void NativeWidgetMus::OnMusWindowVisibilityChanging(ui::Window* window, - bool visible) { - if (window == window_) - native_widget_delegate_->OnNativeWidgetVisibilityChanging(visible); -} - -void NativeWidgetMus::OnMusWindowVisibilityChanged(ui::Window* window, - bool visible) { - if (window != window_) - return; - - if (visible) { - window_tree_host_->Show(); - GetNativeWindow()->Show(); - } else { - window_tree_host_->Hide(); - GetNativeWindow()->Hide(); - } - native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible); -} - -void NativeWidgetMus::UpdateHitTestMask() { - // The window manager (or other underlay window provider) is not allowed to - // set a hit test mask, as that could interfere with a client app mask. - if (is_parallel_widget_in_window_manager()) - return; - - if (!native_widget_delegate_->HasHitTestMask()) { - window_->ClearHitTestMask(); - return; - } - - gfx::Path mask_path; - native_widget_delegate_->GetHitTestMask(&mask_path); - // TODO(jamescook): Use the full path for the mask. - gfx::Rect mask_rect = - gfx::ToEnclosingRect(gfx::SkRectToRectF(mask_path.getBounds())); - window_->SetHitTestMask(mask_rect); -} - -} // namespace views
diff --git a/ui/views/mus/native_widget_mus.h b/ui/views/mus/native_widget_mus.h deleted file mode 100644 index d8126152..0000000 --- a/ui/views/mus/native_widget_mus.h +++ /dev/null
@@ -1,315 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_NATIVE_WIDGET_MUS_H_ -#define UI_VIEWS_MUS_NATIVE_WIDGET_MUS_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "services/ui/public/cpp/input_event_handler.h" -#include "services/ui/public/interfaces/window_tree.mojom.h" -#include "ui/aura/client/drag_drop_delegate.h" -#include "ui/aura/window_delegate.h" -#include "ui/aura/window_tree_host_observer.h" -#include "ui/platform_window/platform_window_delegate.h" -#include "ui/views/mus/mus_export.h" -#include "ui/views/mus/window_tree_host_mus.h" -#include "ui/views/widget/native_widget_private.h" - -namespace aura { -namespace client { -class DragDropClient; -class ScreenPositionClient; -class WindowParentingClient; -} -class Window; -} - -namespace ui { -class Window; -class WindowTreeClient; -namespace mojom { -enum class Cursor; -enum class EventResult; -} -} - -namespace ui { -class Event; -} - -namespace wm { -class CursorManager; -class FocusController; -} - -namespace views { -namespace corewm { -class TooltipController; -} -class DropHelper; -class DropTargetMus; -class InputMethodMus; -class TooltipManagerAura; - -// An implementation of NativeWidget that binds to a ui::Window. Because Aura -// is used extensively within Views code, this code uses aura and binds to the -// ui::Window via a Mus-specific aura::WindowTreeHost impl. Because the root -// aura::Window in a hierarchy is created without a delegate by the -// aura::WindowTreeHost, we must create a child aura::Window in this class -// (content_) and attach it to the root. -class VIEWS_MUS_EXPORT NativeWidgetMus - : public internal::NativeWidgetPrivate, - public aura::WindowDelegate, - public aura::WindowTreeHostObserver, - public aura::client::DragDropDelegate, - public NON_EXPORTED_BASE(ui::InputEventHandler) { - public: - NativeWidgetMus( - internal::NativeWidgetDelegate* delegate, - ui::Window* window, - ui::mojom::CompositorFrameSinkType compositor_frame_sink_type); - ~NativeWidgetMus() override; - - // Configures the set of properties supplied to the window manager when - // creating a new Window for a Widget. - static void ConfigurePropertiesForNewWindow( - const Widget::InitParams& init_params, - std::map<std::string, std::vector<uint8_t>>* properties); - - // Notifies all widgets the frame constants changed in some way. - static void NotifyFrameChanged(ui::WindowTreeClient* client); - - // Returns the native widget for a ui::Window, or null if there is none. - static NativeWidgetMus* GetForWindow(ui::Window* window); - - // Returns the widget for a ui::Window, or null if there is none. - static Widget* GetWidgetForWindow(ui::Window* window); - - ui::mojom::CompositorFrameSinkType compositor_frame_sink_type() const { - return compositor_frame_sink_type_; - } - ui::Window* window() { return window_; } - aura::Window* aura_window() { return content_; } - WindowTreeHostMus* window_tree_host() { return window_tree_host_.get(); } - - aura::Window* GetRootWindow(); - - void OnPlatformWindowClosed(); - void OnActivationChanged(bool active); - - protected: - // Updates the client area in the ui::Window. - virtual void UpdateClientArea(); - - // internal::NativeWidgetPrivate: - NonClientFrameView* CreateNonClientFrameView() override; - void InitNativeWidget(const Widget::InitParams& params) override; - void OnWidgetInitDone() override; - bool ShouldUseNativeFrame() const override; - bool ShouldWindowContentsBeTransparent() const override; - void FrameTypeChanged() override; - Widget* GetWidget() override; - const Widget* GetWidget() const override; - gfx::NativeView GetNativeView() const override; - gfx::NativeWindow GetNativeWindow() const override; - Widget* GetTopLevelWidget() override; - const ui::Compositor* GetCompositor() const override; - const ui::Layer* GetLayer() const override; - void ReorderNativeViews() override; - void ViewRemoved(View* view) override; - void SetNativeWindowProperty(const char* name, void* value) override; - void* GetNativeWindowProperty(const char* name) const override; - TooltipManager* GetTooltipManager() const override; - void SetCapture() override; - void ReleaseCapture() override; - bool HasCapture() const override; - ui::InputMethod* GetInputMethod() override; - void CenterWindow(const gfx::Size& size) override; - void GetWindowPlacement(gfx::Rect* bounds, - ui::WindowShowState* maximized) const override; - bool SetWindowTitle(const base::string16& title) override; - void SetWindowIcons(const gfx::ImageSkia& window_icon, - const gfx::ImageSkia& app_icon) override; - void InitModalType(ui::ModalType modal_type) override; - gfx::Rect GetWindowBoundsInScreen() const override; - gfx::Rect GetClientAreaBoundsInScreen() const override; - gfx::Rect GetRestoredBounds() const override; - std::string GetWorkspace() const override; - void SetBounds(const gfx::Rect& bounds_in_screen) override; - void SetSize(const gfx::Size& size) override; - void StackAbove(gfx::NativeView native_view) override; - void StackAtTop() override; - void SetShape(std::unique_ptr<SkRegion> shape) override; - void Close() override; - void CloseNow() override; - void Show() override; - void Hide() override; - void ShowMaximizedWithBounds(const gfx::Rect& restored_bounds) override; - void ShowWithWindowState(ui::WindowShowState state) override; - bool IsVisible() const override; - void Activate() override; - void Deactivate() override; - bool IsActive() const override; - void SetAlwaysOnTop(bool always_on_top) override; - bool IsAlwaysOnTop() const override; - void SetVisibleOnAllWorkspaces(bool always_visible) override; - bool IsVisibleOnAllWorkspaces() const override; - void Maximize() override; - void Minimize() override; - bool IsMaximized() const override; - bool IsMinimized() const override; - void Restore() override; - void SetFullscreen(bool fullscreen) override; - bool IsFullscreen() const override; - void SetOpacity(float opacity) override; - void FlashFrame(bool flash_frame) override; - void RunShellDrag(View* view, - const ui::OSExchangeData& data, - const gfx::Point& location, - int drag_operations, - ui::DragDropTypes::DragEventSource source) override; - void SchedulePaintInRect(const gfx::Rect& rect) override; - void SetCursor(gfx::NativeCursor cursor) override; - bool IsMouseEventsEnabled() const override; - void ClearNativeFocus() override; - gfx::Rect GetWorkAreaBoundsInScreen() const override; - Widget::MoveLoopResult RunMoveLoop( - const gfx::Vector2d& drag_offset, - Widget::MoveLoopSource source, - Widget::MoveLoopEscapeBehavior escape_behavior) override; - void EndMoveLoop() override; - void SetVisibilityChangedAnimationsEnabled(bool value) override; - void SetVisibilityAnimationDuration(const base::TimeDelta& duration) override; - void SetVisibilityAnimationTransition( - Widget::VisibilityTransition transition) override; - bool IsTranslucentWindowOpacitySupported() const override; - void OnSizeConstraintsChanged() override; - void RepostNativeEvent(gfx::NativeEvent native_event) override; - std::string GetName() const override; - - // Overridden from aura::WindowDelegate: - gfx::Size GetMinimumSize() const override; - gfx::Size GetMaximumSize() const override; - void OnBoundsChanged(const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) override; - gfx::NativeCursor GetCursor(const gfx::Point& point) override; - int GetNonClientComponent(const gfx::Point& point) const override; - bool ShouldDescendIntoChildForEventHandling( - aura::Window* child, - const gfx::Point& location) override; - bool CanFocus() override; - void OnCaptureLost() override; - void OnPaint(const ui::PaintContext& context) override; - void OnDeviceScaleFactorChanged(float device_scale_factor) override; - void OnWindowDestroying(aura::Window* window) override; - void OnWindowDestroyed(aura::Window* window) override; - void OnWindowTargetVisibilityChanged(bool visible) override; - bool HasHitTestMask() const override; - void GetHitTestMask(gfx::Path* mask) const override; - - // Overridden from ui::EventHandler: - void OnKeyEvent(ui::KeyEvent* event) override; - void OnMouseEvent(ui::MouseEvent* event) override; - void OnScrollEvent(ui::ScrollEvent* event) override; - void OnGestureEvent(ui::GestureEvent* event) override; - - // Overridden from aura::WindowTreeHostObserver: - void OnHostResized(const aura::WindowTreeHost* host) override; - void OnHostMovedInPixels(const aura::WindowTreeHost* host, - const gfx::Point& new_origin_in_pixels) override; - void OnHostCloseRequested(const aura::WindowTreeHost* host) override; - - // Overridden from aura::client::DragDropDelegate: - void OnDragEntered(const ui::DropTargetEvent& event) override; - int OnDragUpdated(const ui::DropTargetEvent& event) override; - void OnDragExited() override; - int OnPerformDrop(const ui::DropTargetEvent& event) override; - - // Overridden from ui::InputEventHandler: - void OnWindowInputEvent( - ui::Window* view, - const ui::Event& event, - std::unique_ptr<base::Callback<void(ui::mojom::EventResult)>>* - ack_callback) override; - - private: - friend class NativeWidgetMusTest; - class MusWindowObserver; - class MusCaptureClient; - - ui::PlatformWindowDelegate* platform_window_delegate() { - return window_tree_host(); - } - - // Returns true if this NativeWidgetMus exists on the window manager side - // to provide the frame decorations. - bool is_parallel_widget_in_window_manager() { - return compositor_frame_sink_type_ == - ui::mojom::CompositorFrameSinkType::UNDERLAY; - } - - void set_last_cursor(ui::mojom::Cursor cursor) { last_cursor_ = cursor; } - void SetShowState(ui::mojom::ShowState show_state); - - void OnMusWindowVisibilityChanging(ui::Window* window, bool visible); - void OnMusWindowVisibilityChanged(ui::Window* window, bool visible); - - // Propagates the widget hit test mask, if any, to the ui::Window. - // TODO(jamescook): Wire this through views::Widget so widgets can push - // updates if needed. - void UpdateHitTestMask(); - - ui::Window* window_; - ui::mojom::Cursor last_cursor_; - - internal::NativeWidgetDelegate* native_widget_delegate_; - - const ui::mojom::CompositorFrameSinkType compositor_frame_sink_type_; - ui::mojom::ShowState show_state_before_fullscreen_; - - // See class documentation for Widget in widget.h for a note about ownership. - Widget::InitParams::Ownership ownership_; - - // Functions with the same name require the ui::WindowObserver to be in - // a separate class. - std::unique_ptr<MusWindowObserver> mus_window_observer_; - - // Receives drop events for |window_|. - std::unique_ptr<DropTargetMus> drop_target_; - - // Aura configuration. - std::unique_ptr<WindowTreeHostMus> window_tree_host_; - aura::Window* content_; - std::unique_ptr<wm::FocusController> focus_client_; - std::unique_ptr<MusCaptureClient> capture_client_; - std::unique_ptr<aura::client::DragDropClient> drag_drop_client_; - std::unique_ptr<aura::client::WindowParentingClient> window_parenting_client_; - std::unique_ptr<aura::client::ScreenPositionClient> screen_position_client_; - std::unique_ptr<wm::CursorManager> cursor_manager_; - - std::unique_ptr<DropHelper> drop_helper_; - int last_drop_operation_; - - std::unique_ptr<corewm::TooltipController> tooltip_controller_; - std::unique_ptr<TooltipManagerAura> tooltip_manager_; - - std::unique_ptr<InputMethodMus> input_method_; - - base::WeakPtrFactory<NativeWidgetMus> close_widget_factory_; - - DISALLOW_COPY_AND_ASSIGN(NativeWidgetMus); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_NATIVE_WIDGET_MUS_H_
diff --git a/ui/views/mus/native_widget_mus_unittest.cc b/ui/views/mus/native_widget_mus_unittest.cc deleted file mode 100644 index d6ba944..0000000 --- a/ui/views/mus/native_widget_mus_unittest.cc +++ /dev/null
@@ -1,684 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "services/ui/public/cpp/property_type_converters.h" -#include "services/ui/public/cpp/tests/window_tree_client_private.h" -#include "services/ui/public/cpp/window.h" -#include "services/ui/public/cpp/window_observer.h" -#include "services/ui/public/cpp/window_property.h" -#include "services/ui/public/cpp/window_tree_client.h" -#include "services/ui/public/interfaces/window_manager.mojom.h" -#include "services/ui/public/interfaces/window_tree.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/aura/mus/property_converter.h" -#include "ui/aura/window.h" -#include "ui/events/event.h" -#include "ui/events/test/test_event_handler.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/path.h" -#include "ui/gfx/skia_util.h" -#include "ui/views/controls/native/native_view_host.h" -#include "ui/views/mus/native_widget_mus.h" -#include "ui/views/mus/window_manager_connection.h" -#include "ui/views/test/focus_manager_test.h" -#include "ui/views/test/views_test_base.h" -#include "ui/views/widget/widget.h" -#include "ui/views/widget/widget_delegate.h" -#include "ui/views/widget/widget_observer.h" -#include "ui/wm/public/activation_client.h" - -using ui::mojom::EventResult; - -namespace views { -namespace { - -// A view that reports any mouse press as handled. -class HandleMousePressView : public View { - public: - HandleMousePressView() {} - ~HandleMousePressView() override {} - - // View: - bool OnMousePressed(const ui::MouseEvent& event) override { return true; } - - private: - DISALLOW_COPY_AND_ASSIGN(HandleMousePressView); -}; - -// A view that deletes a widget on mouse press. -class DeleteWidgetView : public View { - public: - explicit DeleteWidgetView(std::unique_ptr<Widget>* widget_ptr) - : widget_ptr_(widget_ptr) {} - ~DeleteWidgetView() override {} - - // View: - bool OnMousePressed(const ui::MouseEvent& event) override { - widget_ptr_->reset(); - return true; - } - - private: - std::unique_ptr<Widget>* widget_ptr_; - DISALLOW_COPY_AND_ASSIGN(DeleteWidgetView); -}; - -// Returns a small colored bitmap. -SkBitmap MakeBitmap(SkColor color) { - SkBitmap bitmap; - bitmap.allocN32Pixels(8, 8); - bitmap.eraseColor(color); - return bitmap; -} - -// An observer that tracks widget activation changes. -class WidgetActivationObserver : public WidgetObserver { - public: - explicit WidgetActivationObserver(Widget* widget) : widget_(widget) { - widget_->AddObserver(this); - } - - ~WidgetActivationObserver() override { - widget_->RemoveObserver(this); - } - - const std::vector<bool>& changes() const { return changes_; } - - // WidgetObserver: - void OnWidgetActivationChanged(Widget* widget, bool active) override { - ASSERT_EQ(widget_, widget); - changes_.push_back(active); - } - - private: - Widget* widget_; - std::vector<bool> changes_; - - DISALLOW_COPY_AND_ASSIGN(WidgetActivationObserver); -}; - -// A WidgetDelegate that supplies app and window icons. -class TestWidgetDelegate : public WidgetDelegateView { - public: - explicit TestWidgetDelegate(const SkBitmap& app_icon, - const SkBitmap& window_icon) - : app_icon_(gfx::ImageSkia::CreateFrom1xBitmap(app_icon)), - window_icon_(gfx::ImageSkia::CreateFrom1xBitmap(window_icon)) {} - - ~TestWidgetDelegate() override {} - - void SetAppIcon(const SkBitmap& icon) { - app_icon_ = gfx::ImageSkia::CreateFrom1xBitmap(icon); - } - - void SetWindowIcon(const SkBitmap& icon) { - window_icon_ = gfx::ImageSkia::CreateFrom1xBitmap(icon); - } - - // views::WidgetDelegate: - gfx::ImageSkia GetWindowAppIcon() override { return app_icon_; } - gfx::ImageSkia GetWindowIcon() override { return window_icon_; } - - private: - gfx::ImageSkia app_icon_; - gfx::ImageSkia window_icon_; - - DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate); -}; - -class WidgetDelegateWithHitTestMask : public WidgetDelegateView { - public: - explicit WidgetDelegateWithHitTestMask(const gfx::Rect& mask_rect) - : mask_rect_(mask_rect) {} - - ~WidgetDelegateWithHitTestMask() override {} - - // views::WidgetDelegate: - bool WidgetHasHitTestMask() const override { return true; } - void GetWidgetHitTestMask(gfx::Path* mask) const override { - mask->addRect(gfx::RectToSkRect(mask_rect_)); - } - - private: - gfx::Rect mask_rect_; - - DISALLOW_COPY_AND_ASSIGN(WidgetDelegateWithHitTestMask); -}; - -} // namespace - -class NativeWidgetMusTest : public ViewsTestBase { - public: - NativeWidgetMusTest() {} - ~NativeWidgetMusTest() override {} - - // Creates a test widget. Takes ownership of |delegate|. - std::unique_ptr<Widget> CreateWidget(WidgetDelegate* delegate) { - std::unique_ptr<Widget> widget(new Widget()); - Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); - params.delegate = delegate; - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.bounds = initial_bounds(); - widget->Init(params); - return widget; - } - - int ack_callback_count() { return ack_callback_count_; } - - void AckCallback(ui::mojom::EventResult result) { - ack_callback_count_++; - EXPECT_EQ(ui::mojom::EventResult::HANDLED, result); - } - - // Returns a mouse pressed event inside the widget. Tests that place views - // within the widget that respond to the event must be constructed within the - // widget coordinate space such that they respond correctly. - std::unique_ptr<ui::MouseEvent> CreateMouseEvent() { - return base::MakeUnique<ui::MouseEvent>( - ui::ET_MOUSE_PRESSED, gfx::Point(50, 50), gfx::Point(50, 50), - base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); - } - - // Simulates an input event to the NativeWidget. - void OnWindowInputEvent( - NativeWidgetMus* native_widget, - const ui::Event& event, - std::unique_ptr<base::Callback<void(ui::mojom::EventResult)>>* - ack_callback) { - native_widget->OnWindowInputEvent(native_widget->window(), event, - ack_callback); - } - - protected: - gfx::Rect initial_bounds() { return gfx::Rect(10, 20, 100, 200); } - - private: - int ack_callback_count_ = 0; - - DISALLOW_COPY_AND_ASSIGN(NativeWidgetMusTest); -}; - -// Tests communication of activation and focus between Widget and -// NativeWidgetMus. -TEST_F(NativeWidgetMusTest, OnActivationChanged) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - widget->Show(); - - // Track activation, focus and blur events. - WidgetActivationObserver activation_observer(widget.get()); - TestWidgetFocusChangeListener focus_listener; - WidgetFocusManager::GetInstance()->AddFocusChangeListener(&focus_listener); - - // Deactivate the Widget, which deactivates the NativeWidgetMus. - widget->Deactivate(); - - // The widget is blurred and deactivated. - ASSERT_EQ(1u, focus_listener.focus_changes().size()); - EXPECT_EQ(nullptr, focus_listener.focus_changes()[0]); - ASSERT_EQ(1u, activation_observer.changes().size()); - EXPECT_EQ(false, activation_observer.changes()[0]); - - // Re-activate the Widget, which actives the NativeWidgetMus. - widget->Activate(); - - // The widget is focused and activated. - ASSERT_EQ(2u, focus_listener.focus_changes().size()); - EXPECT_EQ(widget->GetNativeView(), focus_listener.focus_changes()[1]); - ASSERT_EQ(2u, activation_observer.changes().size()); - EXPECT_TRUE(activation_observer.changes()[1]); - - WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(&focus_listener); -} - -// Tests that showing a non-activatable widget does not activate it. -// TODO(jamescook): Remove this test when widget_interactive_uittests.cc runs -// under mus. -TEST_F(NativeWidgetMusTest, ShowNonActivatableWidget) { - Widget widget; - WidgetActivationObserver activation_observer(&widget); - Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_BUBBLE); - params.activatable = Widget::InitParams::ACTIVATABLE_NO; - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.bounds = gfx::Rect(10, 20, 100, 200); - widget.Init(params); - widget.Show(); - - // The widget is not currently active. - EXPECT_FALSE(widget.IsActive()); - - // The widget was never active. - EXPECT_EQ(0u, activation_observer.changes().size()); -} - -// Tests that a window with app/window icons sets ui::Window icon properties. -TEST_F(NativeWidgetMusTest, AppAndWindowIcons) { - // Create a Widget with app and window icons. - SkBitmap app_icon_input = MakeBitmap(SK_ColorRED); - SkBitmap window_icon_input = MakeBitmap(SK_ColorGREEN); - std::unique_ptr<Widget> widget( - CreateWidget(new TestWidgetDelegate(app_icon_input, window_icon_input))); - - // The ui::Window has the expected icon properties. - ui::Window* window = - static_cast<NativeWidgetMus*>(widget->native_widget_private())->window(); - EXPECT_TRUE( - window->HasSharedProperty(ui::mojom::WindowManager::kAppIcon_Property)); - EXPECT_TRUE(window->HasSharedProperty( - ui::mojom::WindowManager::kWindowIcon_Property)); - SkBitmap app_icon = window->GetSharedProperty<SkBitmap>( - ui::mojom::WindowManager::kAppIcon_Property); - EXPECT_TRUE(gfx::BitmapsAreEqual(app_icon_input, app_icon)); - SkBitmap window_icon = window->GetSharedProperty<SkBitmap>( - ui::mojom::WindowManager::kWindowIcon_Property); - EXPECT_TRUE(gfx::BitmapsAreEqual(window_icon_input, window_icon)); -} - -// Tests that a window without icons does not set ui::Window icon properties. -TEST_F(NativeWidgetMusTest, NoAppNorWindowIcon) { - // Create a Widget without app or window icons, by supplying a null delegate. - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - - // The ui::Window does not have either icon property. - ui::Window* window = - static_cast<NativeWidgetMus*>(widget->native_widget_private())->window(); - EXPECT_FALSE( - window->HasSharedProperty(ui::mojom::WindowManager::kAppIcon_Property)); - EXPECT_FALSE(window->HasSharedProperty( - ui::mojom::WindowManager::kWindowIcon_Property)); -} - -// Tests that changing icons on a Widget updates ui::Window icon properties. -TEST_F(NativeWidgetMusTest, ChangeAppAndWindowIcons) { - // Create a Widget with app and window icons. - SkBitmap bitmap1 = MakeBitmap(SK_ColorRED); - TestWidgetDelegate* delegate = new TestWidgetDelegate(bitmap1, bitmap1); - std::unique_ptr<Widget> widget(CreateWidget(delegate)); - ui::Window* window = - static_cast<NativeWidgetMus*>(widget->native_widget_private())->window(); - - // Update the app icon image; verify the window has the updated icon. - SkBitmap bitmap2 = MakeBitmap(SK_ColorGREEN); - delegate->SetAppIcon(bitmap2); - widget->UpdateWindowIcon(); - SkBitmap app_icon = window->GetSharedProperty<SkBitmap>( - ui::mojom::WindowManager::kAppIcon_Property); - EXPECT_TRUE(gfx::BitmapsAreEqual(bitmap2, app_icon)); - - // Update the window icon image; verify the window has the updated icon. - SkBitmap bitmap3 = MakeBitmap(SK_ColorBLUE); - delegate->SetWindowIcon(bitmap3); - widget->UpdateWindowIcon(); - SkBitmap window_icon = window->GetSharedProperty<SkBitmap>( - ui::mojom::WindowManager::kWindowIcon_Property); - EXPECT_TRUE(gfx::BitmapsAreEqual(bitmap3, window_icon)); -} - -TEST_F(NativeWidgetMusTest, ValidLayerTree) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - View* content = new View; - content->SetPaintToLayer(true); - widget->GetContentsView()->AddChildView(content); - EXPECT_TRUE(widget->GetNativeWindow()->layer()->Contains(content->layer())); -} - -// Tests that the internal name is propagated from the Widget to the -// ui::Window. -TEST_F(NativeWidgetMusTest, GetName) { - Widget widget; - Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.name = "MyWidget"; - widget.Init(params); - ui::Window* window = - static_cast<NativeWidgetMus*>(widget.native_widget_private())->window(); - EXPECT_EQ("MyWidget", window->GetName()); -} - -// Tests that a Widget with a hit test mask propagates the mask to the -// ui::Window. -TEST_F(NativeWidgetMusTest, HitTestMask) { - gfx::Rect mask(5, 5, 10, 10); - std::unique_ptr<Widget> widget( - CreateWidget(new WidgetDelegateWithHitTestMask(mask))); - - // The window has the mask. - ui::Window* window = - static_cast<NativeWidgetMus*>(widget->native_widget_private())->window(); - ASSERT_TRUE(window->hit_test_mask()); - EXPECT_EQ(mask.ToString(), window->hit_test_mask()->ToString()); -} - -// Verifies changing the visibility of a child ui::Window doesn't change the -// visibility of the parent. -TEST_F(NativeWidgetMusTest, ChildVisibilityDoesntEffectParent) { - Widget widget; - Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - widget.Init(params); - widget.Show(); - ui::Window* window = - static_cast<NativeWidgetMus*>(widget.native_widget_private())->window(); - ASSERT_TRUE(window->visible()); - - // Create a child window, make it visible and parent it to the Widget's - // window. - ui::Window* child_window = window->window_tree()->NewWindow(); - child_window->SetVisible(true); - window->AddChild(child_window); - - // Hide the child, this should not impact the visibility of the parent. - child_window->SetVisible(false); - EXPECT_TRUE(window->visible()); -} - -// Tests that child aura::Windows cannot be activated. -TEST_F(NativeWidgetMusTest, FocusChildAuraWindow) { - Widget widget; - Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - widget.Init(params); - - View* focusable = new View; - focusable->SetFocusBehavior(View::FocusBehavior::ALWAYS); - widget.GetContentsView()->AddChildView(focusable); - - NativeViewHost* native_host = new NativeViewHost; - widget.GetContentsView()->AddChildView(native_host); - - std::unique_ptr<aura::Window> window(new aura::Window(nullptr)); - window->Init(ui::LayerType::LAYER_SOLID_COLOR); - native_host->SetBounds(5, 10, 20, 30); - native_host->Attach(window.get()); - widget.Show(); - window->Show(); - widget.SetBounds(gfx::Rect(10, 20, 30, 40)); - - // Sanity check that the |window| is a descendent of the Widget's window. - ASSERT_TRUE(widget.GetNativeView()->Contains(window->parent())); - - // Focusing the child window should not activate it. - window->Focus(); - EXPECT_TRUE(window->HasFocus()); - aura::Window* active_window = - aura::client::GetActivationClient(window.get()->GetRootWindow()) - ->GetActiveWindow(); - EXPECT_NE(window.get(), active_window); - EXPECT_EQ(widget.GetNativeView(), active_window); - - // Moving focus to a child View should move focus away from |window|, and to - // the Widget's window instead. - focusable->RequestFocus(); - EXPECT_FALSE(window->HasFocus()); - EXPECT_TRUE(widget.GetNativeView()->HasFocus()); - active_window = - aura::client::GetActivationClient(window.get()->GetRootWindow()) - ->GetActiveWindow(); - EXPECT_EQ(widget.GetNativeView(), active_window); -} - -TEST_F(NativeWidgetMusTest, WidgetReceivesEvent) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - widget->Show(); - - View* content = new HandleMousePressView; - content->SetBounds(10, 20, 90, 180); - widget->GetContentsView()->AddChildView(content); - - ui::test::TestEventHandler handler; - content->AddPreTargetHandler(&handler); - - std::unique_ptr<ui::MouseEvent> mouse = CreateMouseEvent(); - NativeWidgetMus* native_widget = - static_cast<NativeWidgetMus*>(widget->native_widget_private()); - ui::WindowTreeClientPrivate test_api(native_widget->window()); - test_api.CallOnWindowInputEvent(native_widget->window(), std::move(mouse)); - EXPECT_EQ(1, handler.num_mouse_events()); -} - -// Tests that an incoming UI event is acked with the handled status. -TEST_F(NativeWidgetMusTest, EventAcked) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - widget->Show(); - - View* content = new HandleMousePressView; - content->SetBounds(10, 20, 90, 180); - widget->GetContentsView()->AddChildView(content); - - // Dispatch an input event to the window and view. - std::unique_ptr<ui::MouseEvent> event = CreateMouseEvent(); - std::unique_ptr<base::Callback<void(EventResult)>> ack_callback( - new base::Callback<void(EventResult)>(base::Bind( - &NativeWidgetMusTest::AckCallback, base::Unretained(this)))); - OnWindowInputEvent( - static_cast<NativeWidgetMus*>(widget->native_widget_private()), - *event, - &ack_callback); - - // The test took ownership of the callback and called it. - EXPECT_FALSE(ack_callback); - EXPECT_EQ(1, ack_callback_count()); -} - -// Tests that a window that is deleted during event handling properly acks the -// event. -TEST_F(NativeWidgetMusTest, EventAckedWithWindowDestruction) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - widget->Show(); - - View* content = new DeleteWidgetView(&widget); - content->SetBounds(10, 20, 90, 180); - widget->GetContentsView()->AddChildView(content); - - // Dispatch an input event to the window and view. - std::unique_ptr<ui::MouseEvent> event = CreateMouseEvent(); - std::unique_ptr<base::Callback<void(EventResult)>> ack_callback( - new base::Callback<void(EventResult)>(base::Bind( - &NativeWidgetMusTest::AckCallback, base::Unretained(this)))); - OnWindowInputEvent( - static_cast<NativeWidgetMus*>(widget->native_widget_private()), - *event, - &ack_callback); - - // The widget was deleted. - EXPECT_FALSE(widget.get()); - - // The test took ownership of the callback and called it. - EXPECT_FALSE(ack_callback); - EXPECT_EQ(1, ack_callback_count()); -} - -TEST_F(NativeWidgetMusTest, SetAndReleaseCapture) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - widget->Show(); - View* content = new View; - widget->GetContentsView()->AddChildView(content); - internal::NativeWidgetPrivate* widget_private = - widget->native_widget_private(); - ui::Window* mus_window = - static_cast<NativeWidgetMus*>(widget_private)->window(); - EXPECT_FALSE(widget_private->HasCapture()); - EXPECT_FALSE(mus_window->HasCapture()); - - widget->SetCapture(content); - EXPECT_TRUE(widget_private->HasCapture()); - EXPECT_TRUE(mus_window->HasCapture()); - - widget->ReleaseCapture(); - EXPECT_FALSE(widget_private->HasCapture()); - EXPECT_FALSE(mus_window->HasCapture()); -} - -// Ensure that manually setting NativeWidgetMus's ui::Window bounds also -// updates its WindowTreeHost bounds. -TEST_F(NativeWidgetMusTest, SetMusWindowBounds) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - widget->Show(); - View* content = new View; - widget->GetContentsView()->AddChildView(content); - NativeWidgetMus* native_widget = - static_cast<NativeWidgetMus*>(widget->native_widget_private()); - ui::Window* mus_window = native_widget->window(); - - gfx::Rect start_bounds = initial_bounds(); - gfx::Rect end_bounds = gfx::Rect(40, 50, 60, 70); - EXPECT_NE(start_bounds, end_bounds); - - EXPECT_EQ(start_bounds, mus_window->bounds()); - EXPECT_EQ(start_bounds, - native_widget->window_tree_host()->GetBoundsInPixels()); - - mus_window->SetBounds(end_bounds); - - EXPECT_EQ(end_bounds, mus_window->bounds()); - - // Main check for this test: Setting |mus_window| bounds while bypassing - // |native_widget| must update window_tree_host bounds. - EXPECT_EQ(end_bounds, native_widget->window_tree_host()->GetBoundsInPixels()); -} - -// Verifies visibility of the aura::Window and ui::Window are updated when the -// Widget is shown/hidden. -TEST_F(NativeWidgetMusTest, TargetVisibility) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - NativeWidgetMus* native_widget = - static_cast<NativeWidgetMus*>(widget->native_widget_private()); - ui::Window* mus_window = native_widget->window(); - EXPECT_FALSE(mus_window->visible()); - EXPECT_FALSE(widget->GetNativeView()->TargetVisibility()); - - widget->Show(); - EXPECT_TRUE(mus_window->visible()); - EXPECT_TRUE(widget->GetNativeView()->TargetVisibility()); -} - -// Indirectly verifies Show() isn't invoked twice on the underlying -// aura::Window. -TEST_F(NativeWidgetMusTest, DontShowTwice) { - std::unique_ptr<Widget> widget(CreateWidget(nullptr)); - widget->GetNativeView()->layer()->SetOpacity(0.0f); - // aura::Window::Show() allows the opacity to be 0 as long as the window is - // hidden. So, as long as this only invokes aura::Window::Show() once the - // DCHECK in aura::Window::Show() won't fire. - widget->Show(); -} - -namespace { - -// See description of test for details. -class IsMaximizedObserver : public ui::WindowObserver { - public: - IsMaximizedObserver() {} - ~IsMaximizedObserver() override {} - - void set_widget(Widget* widget) { widget_ = widget; } - - bool got_change() const { return got_change_; } - - // ui::WindowObserver: - void OnWindowSharedPropertyChanged( - ui::Window* window, - const std::string& name, - const std::vector<uint8_t>* old_data, - const std::vector<uint8_t>* new_data) override { - // Expect only one change for the show state. - ASSERT_FALSE(got_change_); - got_change_ = true; - EXPECT_EQ(ui::mojom::WindowManager::kShowState_Property, name); - EXPECT_TRUE(widget_->IsMaximized()); - } - - private: - bool got_change_ = false; - Widget* widget_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(IsMaximizedObserver); -}; - -} // namespace - -// Verifies that asking for Widget::IsMaximized() from within -// OnWindowSharedPropertyChanged() returns the right thing. -TEST_F(NativeWidgetMusTest, IsMaximized) { - ASSERT_TRUE(WindowManagerConnection::Exists()); - ui::Window* window = WindowManagerConnection::Get()->NewTopLevelWindow( - std::map<std::string, std::vector<uint8_t>>()); - IsMaximizedObserver observer; - // NOTE: the order here is important, we purposefully add the - // ui::WindowObserver before creating NativeWidgetMus, which also adds its - // own observer. - window->AddObserver(&observer); - - std::unique_ptr<Widget> widget(new Widget()); - observer.set_widget(widget.get()); - Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.bounds = initial_bounds(); - params.native_widget = new NativeWidgetMus( - widget.get(), window, ui::mojom::CompositorFrameSinkType::DEFAULT); - widget->Init(params); - window->SetSharedProperty<aura::PropertyConverter::PrimitiveType>( - ui::mojom::WindowManager::kShowState_Property, - static_cast<aura::PropertyConverter::PrimitiveType>( - ui::mojom::ShowState::MAXIMIZED)); - EXPECT_TRUE(widget->IsMaximized()); -} - -// This test is to ensure that when initializing a widget with InitParams.parent -// set to another widget's aura::Window, the ui::Window of the former widget is -// added as a child to the ui::Window of the latter widget. -TEST_F(NativeWidgetMusTest, InitNativeWidgetParentsUIWindow) { - ASSERT_TRUE(WindowManagerConnection::Exists()); - - ui::Window* parent_window = WindowManagerConnection::Get()->NewTopLevelWindow( - std::map<std::string, std::vector<uint8_t>>()); - std::unique_ptr<Widget> parent_widget(new Widget()); - Widget::InitParams parent_params = - CreateParams(Widget::InitParams::TYPE_WINDOW); - parent_params.name = "Parent Widget"; - parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - parent_params.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE; - parent_params.opacity = Widget::InitParams::OPAQUE_WINDOW; - parent_params.parent = nullptr; - parent_params.bounds = initial_bounds(); - parent_params.native_widget = - new NativeWidgetMus(parent_widget.get(), parent_window, - ui::mojom::CompositorFrameSinkType::DEFAULT); - parent_widget->Init(parent_params); - - std::unique_ptr<Widget> child_widget(new Widget()); - ui::Window* child_window = parent_window->window_tree()->NewWindow(); - Widget::InitParams child_params = CreateParams(Widget::InitParams::TYPE_MENU); - child_params.parent = parent_widget->GetNativeView(); - child_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - child_params.name = "Child Widget"; - child_params.native_widget = - new NativeWidgetMus(child_widget.get(), child_window, - ui::mojom::CompositorFrameSinkType::DEFAULT); - child_widget->Init(child_params); - - EXPECT_EQ(child_window->parent(), parent_window); - - std::unique_ptr<Widget> not_child_widget(new Widget()); - ui::Window* not_child_window = parent_window->window_tree()->NewWindow(); - Widget::InitParams not_child_params = - CreateParams(Widget::InitParams::TYPE_MENU); - not_child_params.ownership = - views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - not_child_params.name = "Not Child Widget"; - not_child_params.native_widget = - new NativeWidgetMus(not_child_widget.get(), not_child_window, - ui::mojom::CompositorFrameSinkType::DEFAULT); - not_child_widget->Init(not_child_params); - - EXPECT_NE(not_child_window->parent(), parent_window); -} - -} // namespace views
diff --git a/ui/views/mus/pointer_watcher_event_router.cc b/ui/views/mus/pointer_watcher_event_router.cc deleted file mode 100644 index da3810b..0000000 --- a/ui/views/mus/pointer_watcher_event_router.cc +++ /dev/null
@@ -1,143 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/pointer_watcher_event_router.h" - -#include "services/ui/public/cpp/window.h" -#include "services/ui/public/cpp/window_tree_client.h" -#include "ui/display/screen.h" -#include "ui/events/base_event_utils.h" -#include "ui/events/event.h" -#include "ui/views/mus/native_widget_mus.h" -#include "ui/views/pointer_watcher.h" - -namespace views { -namespace { - -bool HasPointerWatcher( - base::ObserverList<views::PointerWatcher, true>* observer_list) { - return observer_list->begin() != observer_list->end(); -} - -} // namespace - -PointerWatcherEventRouter::PointerWatcherEventRouter( - ui::WindowTreeClient* client) - : window_tree_client_(client) { - client->AddObserver(this); -} - -PointerWatcherEventRouter::~PointerWatcherEventRouter() { - if (window_tree_client_) - window_tree_client_->RemoveObserver(this); -} - -void PointerWatcherEventRouter::AddPointerWatcher(PointerWatcher* watcher, - bool wants_moves) { - // Pointer watchers cannot be added multiple times. - DCHECK(!move_watchers_.HasObserver(watcher)); - DCHECK(!non_move_watchers_.HasObserver(watcher)); - if (wants_moves) { - move_watchers_.AddObserver(watcher); - if (event_types_ != EventTypes::MOVE_EVENTS) { - event_types_ = EventTypes::MOVE_EVENTS; - const bool wants_moves = true; - window_tree_client_->StartPointerWatcher(wants_moves); - } - } else { - non_move_watchers_.AddObserver(watcher); - if (event_types_ == EventTypes::NONE) { - event_types_ = EventTypes::NON_MOVE_EVENTS; - const bool wants_moves = false; - window_tree_client_->StartPointerWatcher(wants_moves); - } - } -} - -void PointerWatcherEventRouter::RemovePointerWatcher(PointerWatcher* watcher) { - if (non_move_watchers_.HasObserver(watcher)) { - non_move_watchers_.RemoveObserver(watcher); - } else { - DCHECK(move_watchers_.HasObserver(watcher)); - move_watchers_.RemoveObserver(watcher); - } - const EventTypes types = DetermineEventTypes(); - if (types == event_types_) - return; - - event_types_ = types; - switch (types) { - case EventTypes::NONE: - window_tree_client_->StopPointerWatcher(); - break; - case EventTypes::NON_MOVE_EVENTS: - window_tree_client_->StartPointerWatcher(false); - break; - case EventTypes::MOVE_EVENTS: - // It isn't possible to remove an observer and transition to wanting move - // events. This could only happen if there is a bug in the add logic. - NOTREACHED(); - break; - } -} - -void PointerWatcherEventRouter::OnPointerEventObserved( - const ui::PointerEvent& event, - ui::Window* target) { - Widget* target_widget = nullptr; - if (target) { - ui::Window* window = target; - while (window && !target_widget) { - target_widget = NativeWidgetMus::GetWidgetForWindow(target); - window = window->parent(); - } - } - - // The mojo input events type converter uses the event root_location field - // to store screen coordinates. Screen coordinates really should be returned - // separately. See http://crbug.com/608547 - gfx::Point location_in_screen = event.AsLocatedEvent()->root_location(); - for (PointerWatcher& observer : move_watchers_) - observer.OnPointerEventObserved(event, location_in_screen, target_widget); - if (event.type() != ui::ET_POINTER_MOVED) { - for (PointerWatcher& observer : non_move_watchers_) - observer.OnPointerEventObserved(event, location_in_screen, target_widget); - } -} - -PointerWatcherEventRouter::EventTypes -PointerWatcherEventRouter::DetermineEventTypes() { - if (HasPointerWatcher(&move_watchers_)) - return EventTypes::MOVE_EVENTS; - - if (HasPointerWatcher(&non_move_watchers_)) - return EventTypes::NON_MOVE_EVENTS; - - return EventTypes::NONE; -} - -void PointerWatcherEventRouter::OnWindowTreeCaptureChanged( - ui::Window* gained_capture, - ui::Window* lost_capture) { - const ui::MouseEvent mouse_event(ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(), - gfx::Point(), ui::EventTimeForNow(), 0, 0); - const ui::PointerEvent event(mouse_event); - gfx::Point location_in_screen = - display::Screen::GetScreen()->GetCursorScreenPoint(); - for (PointerWatcher& observer : move_watchers_) - observer.OnPointerEventObserved(event, location_in_screen, nullptr); - for (PointerWatcher& observer : non_move_watchers_) - observer.OnPointerEventObserved(event, location_in_screen, nullptr); -} - -void PointerWatcherEventRouter::OnDidDestroyClient( - ui::WindowTreeClient* client) { - // We expect that all observers have been removed by this time. - DCHECK_EQ(event_types_, EventTypes::NONE); - DCHECK_EQ(client, window_tree_client_); - window_tree_client_->RemoveObserver(this); - window_tree_client_ = nullptr; -} - -} // namespace views
diff --git a/ui/views/mus/pointer_watcher_event_router.h b/ui/views/mus/pointer_watcher_event_router.h deleted file mode 100644 index e75e81d..0000000 --- a/ui/views/mus/pointer_watcher_event_router.h +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_POINTER_WATCHER_EVENT_ROUTER_H_ -#define UI_VIEWS_MUS_POINTER_WATCHER_EVENT_ROUTER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/observer_list.h" -#include "services/ui/public/cpp/window_tree_client_observer.h" -#include "ui/views/mus/mus_export.h" - -namespace ui { -class PointerEvent; -class WindowTreeClient; -} - -namespace views { - -class PointerWatcher; -class PointerWatcherEventRouterTest; - -// PointerWatcherEventRouter is responsible for maintaining the list of -// PointerWatchers and notifying appropriately. It is expected the owner of -// PointerWatcherEventRouter is a WindowTreeClientDelegate and calls -// OnPointerEventObserved(). -class VIEWS_MUS_EXPORT PointerWatcherEventRouter - : public NON_EXPORTED_BASE(ui::WindowTreeClientObserver) { - public: - // Public solely for tests. - enum EventTypes { - // No PointerWatchers have been added. - NONE, - - // Used when the only PointerWatchers added do not want moves. - NON_MOVE_EVENTS, - - // Used when at least one PointerWatcher has been added that wants moves. - MOVE_EVENTS, - }; - - explicit PointerWatcherEventRouter(ui::WindowTreeClient* client); - ~PointerWatcherEventRouter() override; - - // Called by WindowTreeClientDelegate to notify PointerWatchers appropriately. - void OnPointerEventObserved(const ui::PointerEvent& event, - ui::Window* target); - - void AddPointerWatcher(PointerWatcher* watcher, bool wants_moves); - void RemovePointerWatcher(PointerWatcher* watcher); - - private: - friend class PointerWatcherEventRouterTest; - - // Determines EventTypes based on the number and type of PointerWatchers. - EventTypes DetermineEventTypes(); - - // ui::WindowTreeClientObserver: - void OnWindowTreeCaptureChanged(ui::Window* gained_capture, - ui::Window* lost_capture) override; - void OnDidDestroyClient(ui::WindowTreeClient* client) override; - - ui::WindowTreeClient* window_tree_client_; - // The true parameter to ObserverList indicates the list must be empty on - // destruction. Two sets of observers are maintained, one for observers not - // needing moves |non_move_watchers_| and |move_watchers_| for those - // observers wanting moves too. - base::ObserverList<views::PointerWatcher, true> non_move_watchers_; - base::ObserverList<views::PointerWatcher, true> move_watchers_; - - EventTypes event_types_ = EventTypes::NONE; - - DISALLOW_COPY_AND_ASSIGN(PointerWatcherEventRouter); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_POINTER_WATCHER_EVENT_ROUTER_H_
diff --git a/ui/views/mus/pointer_watcher_event_router_unittest.cc b/ui/views/mus/pointer_watcher_event_router_unittest.cc deleted file mode 100644 index 7411dbf1..0000000 --- a/ui/views/mus/pointer_watcher_event_router_unittest.cc +++ /dev/null
@@ -1,245 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/pointer_watcher_event_router.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "services/ui/public/cpp/tests/window_tree_client_private.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/events/event.h" -#include "ui/views/mus/window_manager_connection.h" -#include "ui/views/pointer_watcher.h" -#include "ui/views/test/scoped_views_test_helper.h" - -namespace views { -namespace { - -class TestPointerWatcher : public PointerWatcher { - public: - TestPointerWatcher() {} - ~TestPointerWatcher() override {} - - ui::PointerEvent* last_event_observed() { return last_event_observed_.get(); } - - void Reset() { last_event_observed_.reset(); } - - // PointerWatcher: - void OnPointerEventObserved(const ui::PointerEvent& event, - const gfx::Point& location_in_screen, - Widget* target) override { - last_event_observed_ = base::MakeUnique<ui::PointerEvent>(event); - } - - private: - std::unique_ptr<ui::PointerEvent> last_event_observed_; - - DISALLOW_COPY_AND_ASSIGN(TestPointerWatcher); -}; - -} // namespace - -class PointerWatcherEventRouterTest : public testing::Test { - public: - PointerWatcherEventRouterTest() {} - ~PointerWatcherEventRouterTest() override {} - - void OnPointerEventObserved(const ui::PointerEvent& event) { - WindowManagerConnection::Get() - ->pointer_watcher_event_router() - ->OnPointerEventObserved(event, nullptr); - } - - PointerWatcherEventRouter::EventTypes event_types() const { - return WindowManagerConnection::Get() - ->pointer_watcher_event_router() - ->event_types_; - } - - private: - DISALLOW_COPY_AND_ASSIGN(PointerWatcherEventRouterTest); -}; - -TEST_F(PointerWatcherEventRouterTest, EventTypes) { - base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); - ScopedViewsTestHelper helper; - TestPointerWatcher pointer_watcher1, pointer_watcher2; - PointerWatcherEventRouter* pointer_watcher_event_router = - WindowManagerConnection::Get()->pointer_watcher_event_router(); - ui::WindowTreeClientPrivate test_api( - WindowManagerConnection::Get()->client()); - EXPECT_FALSE(test_api.HasPointerWatcher()); - - // Start with no moves. - pointer_watcher_event_router->AddPointerWatcher(&pointer_watcher1, false); - EXPECT_EQ(PointerWatcherEventRouter::EventTypes::NON_MOVE_EVENTS, - event_types()); - EXPECT_TRUE(test_api.HasPointerWatcher()); - - // Add moves. - pointer_watcher_event_router->AddPointerWatcher(&pointer_watcher2, true); - EXPECT_EQ(PointerWatcherEventRouter::EventTypes::MOVE_EVENTS, event_types()); - EXPECT_TRUE(test_api.HasPointerWatcher()); - - // Remove no-moves. - pointer_watcher_event_router->RemovePointerWatcher(&pointer_watcher1); - EXPECT_EQ(PointerWatcherEventRouter::EventTypes::MOVE_EVENTS, event_types()); - EXPECT_TRUE(test_api.HasPointerWatcher()); - - // Remove moves. - pointer_watcher_event_router->RemovePointerWatcher(&pointer_watcher2); - EXPECT_EQ(PointerWatcherEventRouter::EventTypes::NONE, event_types()); - EXPECT_FALSE(test_api.HasPointerWatcher()); - - // Add moves. - pointer_watcher_event_router->AddPointerWatcher(&pointer_watcher2, true); - EXPECT_EQ(PointerWatcherEventRouter::EventTypes::MOVE_EVENTS, event_types()); - EXPECT_TRUE(test_api.HasPointerWatcher()); - - // Add no moves. - pointer_watcher_event_router->AddPointerWatcher(&pointer_watcher1, false); - EXPECT_EQ(PointerWatcherEventRouter::EventTypes::MOVE_EVENTS, event_types()); - EXPECT_TRUE(test_api.HasPointerWatcher()); - - // Remove moves. - pointer_watcher_event_router->RemovePointerWatcher(&pointer_watcher2); - EXPECT_EQ(PointerWatcherEventRouter::EventTypes::NON_MOVE_EVENTS, - event_types()); - EXPECT_TRUE(test_api.HasPointerWatcher()); - - // Remove no-moves. - pointer_watcher_event_router->RemovePointerWatcher(&pointer_watcher1); - EXPECT_EQ(PointerWatcherEventRouter::EventTypes::NONE, event_types()); - EXPECT_FALSE(test_api.HasPointerWatcher()); -} - -TEST_F(PointerWatcherEventRouterTest, PointerWatcherNoMove) { - base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); - ScopedViewsTestHelper helper; - ASSERT_TRUE(WindowManagerConnection::Get()); - PointerWatcherEventRouter* pointer_watcher_event_router = - WindowManagerConnection::Get()->pointer_watcher_event_router(); - ASSERT_TRUE(pointer_watcher_event_router); - - ui::PointerEvent pointer_event_down( - ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, 0, - ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), - base::TimeTicks()); - ui::PointerEvent pointer_event_up( - ui::ET_POINTER_UP, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, 0, - ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE), - base::TimeTicks()); - ui::PointerEvent pointer_event_wheel( - ui::ET_POINTER_WHEEL_CHANGED, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, - 0, ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE), - base::TimeTicks()); - ui::PointerEvent pointer_event_capture( - ui::ET_POINTER_CAPTURE_CHANGED, gfx::Point(), gfx::Point(), ui::EF_NONE, - 1, 0, ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE), - base::TimeTicks()); - - // PointerWatchers receive pointer down events. - TestPointerWatcher watcher1; - pointer_watcher_event_router->AddPointerWatcher(&watcher1, false); - OnPointerEventObserved(pointer_event_down); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // PointerWatchers receive pointer up events. - OnPointerEventObserved(pointer_event_up); - EXPECT_EQ(ui::ET_POINTER_UP, watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // PointerWatchers receive pointer wheel changed events. - OnPointerEventObserved(pointer_event_wheel); - EXPECT_EQ(ui::ET_POINTER_WHEEL_CHANGED, - watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // PointerWatchers receive pointer capture changed events. - OnPointerEventObserved(pointer_event_capture); - EXPECT_EQ(ui::ET_POINTER_CAPTURE_CHANGED, - watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // Two PointerWatchers can both receive a single observed event. - TestPointerWatcher watcher2; - pointer_watcher_event_router->AddPointerWatcher(&watcher2, false); - OnPointerEventObserved(pointer_event_down); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher2.last_event_observed()->type()); - watcher1.Reset(); - watcher2.Reset(); - - // Removing the first PointerWatcher stops sending events to it. - pointer_watcher_event_router->RemovePointerWatcher(&watcher1); - OnPointerEventObserved(pointer_event_down); - EXPECT_FALSE(watcher1.last_event_observed()); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher2.last_event_observed()->type()); - watcher1.Reset(); - watcher2.Reset(); - - // Removing the last PointerWatcher stops sending events to it. - pointer_watcher_event_router->RemovePointerWatcher(&watcher2); - OnPointerEventObserved(pointer_event_down); - EXPECT_FALSE(watcher1.last_event_observed()); - EXPECT_FALSE(watcher2.last_event_observed()); -} - -TEST_F(PointerWatcherEventRouterTest, PointerWatcherMove) { - base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); - ScopedViewsTestHelper helper; - ASSERT_TRUE(WindowManagerConnection::Get()); - PointerWatcherEventRouter* pointer_watcher_event_router = - WindowManagerConnection::Get()->pointer_watcher_event_router(); - ASSERT_TRUE(pointer_watcher_event_router); - - ui::PointerEvent pointer_event_down( - ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, 0, - ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), - base::TimeTicks()); - ui::PointerEvent pointer_event_move( - ui::ET_POINTER_MOVED, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, 0, - ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), - base::TimeTicks()); - - // PointerWatchers receive pointer down events. - TestPointerWatcher watcher1; - pointer_watcher_event_router->AddPointerWatcher(&watcher1, true); - OnPointerEventObserved(pointer_event_down); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // PointerWatchers receive pointer move events. - OnPointerEventObserved(pointer_event_move); - EXPECT_EQ(ui::ET_POINTER_MOVED, watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // Two PointerWatchers can both receive a single observed event. - TestPointerWatcher watcher2; - pointer_watcher_event_router->AddPointerWatcher(&watcher2, true); - OnPointerEventObserved(pointer_event_move); - EXPECT_EQ(ui::ET_POINTER_MOVED, watcher1.last_event_observed()->type()); - EXPECT_EQ(ui::ET_POINTER_MOVED, watcher2.last_event_observed()->type()); - watcher1.Reset(); - watcher2.Reset(); - - // Removing the first PointerWatcher stops sending events to it. - pointer_watcher_event_router->RemovePointerWatcher(&watcher1); - OnPointerEventObserved(pointer_event_move); - EXPECT_FALSE(watcher1.last_event_observed()); - EXPECT_EQ(ui::ET_POINTER_MOVED, watcher2.last_event_observed()->type()); - watcher1.Reset(); - watcher2.Reset(); - - // Removing the last PointerWatcher stops sending events to it. - pointer_watcher_event_router->RemovePointerWatcher(&watcher2); - OnPointerEventObserved(pointer_event_move); - EXPECT_FALSE(watcher1.last_event_observed()); - EXPECT_FALSE(watcher2.last_event_observed()); -} - -} // namespace views
diff --git a/ui/views/mus/screen_mus.cc b/ui/views/mus/screen_mus.cc index f9350d2a..17777aa 100644 --- a/ui/views/mus/screen_mus.cc +++ b/ui/views/mus/screen_mus.cc
@@ -12,7 +12,6 @@ #include "services/service_manager/public/cpp/connector.h" #include "services/ui/public/interfaces/constants.mojom.h" #include "ui/aura/window.h" -#include "ui/views/mus/native_widget_mus.h" #include "ui/views/mus/screen_mus_delegate.h" #include "ui/views/mus/window_manager_frame_values.h"
diff --git a/ui/views/mus/screen_mus_unittest.cc b/ui/views/mus/screen_mus_unittest.cc index 1d71fbaa..6895fbf 100644 --- a/ui/views/mus/screen_mus_unittest.cc +++ b/ui/views/mus/screen_mus_unittest.cc
@@ -7,7 +7,6 @@ #include "base/command_line.h" #include "ui/display/display_switches.h" #include "ui/display/screen.h" -#include "ui/views/mus/window_manager_connection.h" #include "ui/views/test/scoped_views_test_helper.h" #include "ui/views/test/views_test_base.h"
diff --git a/ui/views/mus/surface_context_factory.cc b/ui/views/mus/surface_context_factory.cc deleted file mode 100644 index 9a881ee8..0000000 --- a/ui/views/mus/surface_context_factory.cc +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/surface_context_factory.h" - -#include "base/memory/ptr_util.h" -#include "cc/resources/shared_bitmap_manager.h" -#include "cc/surfaces/surface_id_allocator.h" -#include "services/ui/public/cpp/gpu/gpu.h" -#include "services/ui/public/cpp/window.h" -#include "services/ui/public/cpp/window_compositor_frame_sink.h" -#include "ui/compositor/reflector.h" -#include "ui/gl/gl_bindings.h" -#include "ui/views/mus/native_widget_mus.h" - -namespace views { - -SurfaceContextFactory::SurfaceContextFactory(ui::Gpu* gpu) : gpu_(gpu) {} - -SurfaceContextFactory::~SurfaceContextFactory() {} - -void SurfaceContextFactory::CreateCompositorFrameSink( - base::WeakPtr<ui::Compositor> compositor) { - ui::Window* window = compositor->window(); - NativeWidgetMus* native_widget = NativeWidgetMus::GetForWindow(window); - ui::mojom::CompositorFrameSinkType compositor_frame_sink_type = - native_widget->compositor_frame_sink_type(); - auto compositor_frame_sink = window->RequestCompositorFrameSink( - compositor_frame_sink_type, - gpu_->CreateContextProvider(gpu_->EstablishGpuChannelSync()), - gpu_->gpu_memory_buffer_manager()); - compositor->SetCompositorFrameSink(std::move(compositor_frame_sink)); -} - -scoped_refptr<cc::ContextProvider> -SurfaceContextFactory::SharedMainThreadContextProvider() { - // NOTIMPLEMENTED(); - return nullptr; -} - -void SurfaceContextFactory::RemoveCompositor(ui::Compositor* compositor) { - // NOTIMPLEMENTED(); -} - -bool SurfaceContextFactory::DoesCreateTestContexts() { - return false; -} - -uint32_t SurfaceContextFactory::GetImageTextureTarget(gfx::BufferFormat format, - gfx::BufferUsage usage) { - // No GpuMemoryBuffer support, so just return GL_TEXTURE_2D. - return GL_TEXTURE_2D; -} - -gpu::GpuMemoryBufferManager* -SurfaceContextFactory::GetGpuMemoryBufferManager() { - return gpu_->gpu_memory_buffer_manager(); -} - -cc::TaskGraphRunner* SurfaceContextFactory::GetTaskGraphRunner() { - return raster_thread_helper_.task_graph_runner(); -} - -} // namespace views
diff --git a/ui/views/mus/surface_context_factory.h b/ui/views/mus/surface_context_factory.h deleted file mode 100644 index 3abc9c9f..0000000 --- a/ui/views/mus/surface_context_factory.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_SURFACE_CONTEXT_FACTORY_H_ -#define UI_VIEWS_MUS_SURFACE_CONTEXT_FACTORY_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "cc/surfaces/surface_manager.h" -#include "services/ui/public/cpp/raster_thread_helper.h" -#include "services/ui/public/interfaces/window_tree.mojom.h" -#include "ui/compositor/compositor.h" -#include "ui/views/mus/mus_export.h" - -namespace ui { -class Gpu; -} - -namespace views { - -class VIEWS_MUS_EXPORT SurfaceContextFactory : public ui::ContextFactory { - public: - explicit SurfaceContextFactory(ui::Gpu* gpu); - ~SurfaceContextFactory() override; - - private: - // ContextFactory: - void CreateCompositorFrameSink( - base::WeakPtr<ui::Compositor> compositor) override; - scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider() override; - void RemoveCompositor(ui::Compositor* compositor) override; - bool DoesCreateTestContexts() override; - uint32_t GetImageTextureTarget(gfx::BufferFormat format, - gfx::BufferUsage usage) override; - gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override; - cc::TaskGraphRunner* GetTaskGraphRunner() override; - void AddObserver(ui::ContextFactoryObserver* observer) override {} - void RemoveObserver(ui::ContextFactoryObserver* observer) override {} - - ui::RasterThreadHelper raster_thread_helper_; - ui::Gpu* gpu_; - - DISALLOW_COPY_AND_ASSIGN(SurfaceContextFactory); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_SURFACE_CONTEXT_FACTORY_H_
diff --git a/ui/views/mus/test_utils.h b/ui/views/mus/test_utils.h index c4d21ee8..419fee9 100644 --- a/ui/views/mus/test_utils.h +++ b/ui/views/mus/test_utils.h
@@ -7,29 +7,10 @@ #include "base/memory/ptr_util.h" #include "ui/views/mus/mus_client.h" -#include "ui/views/mus/window_manager_connection.h" namespace views { namespace test { -class WindowManagerConnectionTestApi { - public: - explicit WindowManagerConnectionTestApi(WindowManagerConnection* connection) - : connection_(connection) {} - ~WindowManagerConnectionTestApi() {} - - ui::Window* GetUiWindowAtScreenPoint(const gfx::Point& point) { - return connection_->GetUiWindowAtScreenPoint(point); - } - - ScreenMus* screen() { return connection_->screen_.get(); } - - private: - WindowManagerConnection* connection_; - - DISALLOW_COPY_AND_ASSIGN(WindowManagerConnectionTestApi); -}; - class MusClientTestApi { public: static std::unique_ptr<MusClient> Create(
diff --git a/ui/views/mus/text_input_client_impl.cc b/ui/views/mus/text_input_client_impl.cc deleted file mode 100644 index 4193e127..0000000 --- a/ui/views/mus/text_input_client_impl.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/text_input_client_impl.h" - -#include "base/strings/utf_string_conversions.h" -#include "ui/base/ime/text_input_client.h" -#include "ui/views/mus/input_method_mus.h" - -namespace views { - -TextInputClientImpl::TextInputClientImpl(ui::TextInputClient* text_input_client) - : text_input_client_(text_input_client), binding_(this) {} - -TextInputClientImpl::~TextInputClientImpl() {} - -ui::mojom::TextInputClientPtr TextInputClientImpl::CreateInterfacePtrAndBind() { - return binding_.CreateInterfacePtrAndBind(); -} - -void TextInputClientImpl::SetCompositionText( - const ui::CompositionText& composition) { - text_input_client_->SetCompositionText(composition); -} - -void TextInputClientImpl::ConfirmCompositionText() { - text_input_client_->ConfirmCompositionText(); -} - -void TextInputClientImpl::ClearCompositionText() { - text_input_client_->ClearCompositionText(); -} - -void TextInputClientImpl::InsertText(const std::string& text) { - text_input_client_->InsertText(base::UTF8ToUTF16(text)); -} - -void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) { - DCHECK(event->IsKeyEvent()); - text_input_client_->InsertChar(*event->AsKeyEvent()); -} - -} // namespace views
diff --git a/ui/views/mus/text_input_client_impl.h b/ui/views/mus/text_input_client_impl.h deleted file mode 100644 index 2531ed6..0000000 --- a/ui/views/mus/text_input_client_impl.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_TEXT_INPUT_CLIENT_IMPL_H_ -#define UI_VIEWS_MUS_TEXT_INPUT_CLIENT_IMPL_H_ - -#include "mojo/public/cpp/bindings/binding.h" -#include "services/ui/public/interfaces/ime/ime.mojom.h" -#include "ui/base/ime/composition_text.h" - -namespace ui { -class TextInputClient; -} - -namespace views { - -// TextInputClientImpl receieves updates from IME drivers over Mojo IPC, and -// notifies the underlying ui::TextInputClient accordingly. -class TextInputClientImpl : public ui::mojom::TextInputClient { - public: - explicit TextInputClientImpl(ui::TextInputClient* text_input_client); - ~TextInputClientImpl() override; - - ui::mojom::TextInputClientPtr CreateInterfacePtrAndBind(); - - private: - // ui::mojom::TextInputClient: - void SetCompositionText(const ui::CompositionText& composition) override; - void ConfirmCompositionText() override; - void ClearCompositionText() override; - void InsertText(const std::string& text) override; - void InsertChar(std::unique_ptr<ui::Event> event) override; - - ui::TextInputClient* text_input_client_; - mojo::Binding<ui::mojom::TextInputClient> binding_; - - DISALLOW_COPY_AND_ASSIGN(TextInputClientImpl); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_TEXT_INPUT_CLIENT_IMPL_H_
diff --git a/ui/views/mus/unittests_aura_manifest.json b/ui/views/mus/unittests_aura_manifest.json deleted file mode 100644 index 9e04779..0000000 --- a/ui/views/mus/unittests_aura_manifest.json +++ /dev/null
@@ -1,11 +0,0 @@ -{ - "name": "views_aura_mus_unittests", - "display_name": "Views Aura Mus Unittests", - "interface_provider_specs": { - "service_manager:connector": { - "requires": { - "*": [ "app" ] - } - } - } -}
diff --git a/ui/views/mus/views_aura_mus_test_suite.cc b/ui/views/mus/views_aura_mus_test_suite.cc index d23adc0..2be58a25 100644 --- a/ui/views/mus/views_aura_mus_test_suite.cc +++ b/ui/views/mus/views_aura_mus_test_suite.cc
@@ -195,7 +195,7 @@ ViewsAuraMusTestSuite::~ViewsAuraMusTestSuite() {} void ViewsAuraMusTestSuite::Initialize() { - PlatformTestHelper::SetIsAuraMusClient(); + PlatformTestHelper::SetIsMus(); // Let other services know that we're running in tests. Do this with a // command line flag to avoid making blocking calls to other processes for // setup for tests (e.g. to unlock the screen in the window manager).
diff --git a/ui/views/mus/views_mus_test_suite.cc b/ui/views/mus/views_mus_test_suite.cc deleted file mode 100644 index 08c0e78..0000000 --- a/ui/views/mus/views_mus_test_suite.cc +++ /dev/null
@@ -1,195 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/views_mus_test_suite.h" - -#include <memory> -#include <string> - -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/memory/ptr_util.h" -#include "base/run_loop.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/simple_thread.h" -#include "base/threading/thread.h" -#include "services/service_manager/background/background_service_manager.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/ui/common/switches.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/aura/window.h" -#include "ui/views/mus/window_manager_connection.h" -#include "ui/views/test/platform_test_helper.h" -#include "ui/views/views_delegate.h" - -namespace views { -namespace { - -void EnsureCommandLineSwitch(const std::string& name) { - base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); - if (!cmd_line->HasSwitch(name)) - cmd_line->AppendSwitch(name); -} - -class DefaultService : public service_manager::Service { - public: - DefaultService() {} - ~DefaultService() override {} - - // service_manager::Service: - bool OnConnect(const service_manager::ServiceInfo& remote_info, - service_manager::InterfaceRegistry* registry) override { - return false; - } - - private: - DISALLOW_COPY_AND_ASSIGN(DefaultService); -}; - -class PlatformTestHelperMus : public PlatformTestHelper { - public: - PlatformTestHelperMus(service_manager::Connector* connector, - const service_manager::Identity& identity) { - // It is necessary to recreate the WindowManagerConnection for each test, - // since a new MessageLoop is created for each test. - connection_ = WindowManagerConnection::Create(connector, identity); - } - ~PlatformTestHelperMus() override {} - - // PlatformTestHelper: - void SimulateNativeDestroy(Widget* widget) override { - delete widget->GetNativeView(); - } - - private: - std::unique_ptr<WindowManagerConnection> connection_; - - DISALLOW_COPY_AND_ASSIGN(PlatformTestHelperMus); -}; - -std::unique_ptr<PlatformTestHelper> CreatePlatformTestHelper( - const service_manager::Identity& identity, - const base::Callback<service_manager::Connector*(void)>& callback) { - return base::MakeUnique<PlatformTestHelperMus>(callback.Run(), identity); -} - -} // namespace - -class ServiceManagerConnection { - public: - ServiceManagerConnection() - : thread_("Persistent service_manager connections") { - base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - base::Thread::Options options; - thread_.StartWithOptions(options); - thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&ServiceManagerConnection::SetUpConnections, - base::Unretained(this), &wait)); - wait.Wait(); - - // WindowManagerConnection cannot be created from here yet, although the - // connector and identity are available at this point. This is because - // WindowManagerConnection needs a ViewsDelegate and a MessageLoop to have - // been installed first. So delay the creation until the necessary - // dependencies have been met. - PlatformTestHelper::set_factory( - base::Bind(&CreatePlatformTestHelper, service_manager_identity_, - base::Bind(&ServiceManagerConnection::GetConnector, - base::Unretained(this)))); - } - - ~ServiceManagerConnection() { - base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&ServiceManagerConnection::TearDownConnections, - base::Unretained(this), &wait)); - wait.Wait(); - } - - private: - service_manager::Connector* GetConnector() { - service_manager_connector_.reset(); - base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&ServiceManagerConnection::CloneConnector, - base::Unretained(this), &wait)); - wait.Wait(); - DCHECK(service_manager_connector_); - return service_manager_connector_.get(); - } - - void CloneConnector(base::WaitableEvent* wait) { - service_manager_connector_ = context_->connector()->Clone(); - wait->Signal(); - } - - void SetUpConnections(base::WaitableEvent* wait) { - background_service_manager_ = - base::MakeUnique<service_manager::BackgroundServiceManager>(); - background_service_manager_->Init(nullptr); - context_ = - base::MakeUnique<service_manager::ServiceContext>( - base::MakeUnique<DefaultService>(), - background_service_manager_->CreateServiceRequest(GetTestName())); - - // ui/views/mus requires a WindowManager running, so launch test_wm. - service_manager::Connector* connector = context_->connector(); - connector->Connect("test_wm"); - service_manager_connector_ = connector->Clone(); - service_manager_identity_ = context_->identity(); - wait->Signal(); - } - - void TearDownConnections(base::WaitableEvent* wait) { - context_.reset(); - wait->Signal(); - } - - // Returns the name of the test executable, e.g. - // "views_mus_unittests". - std::string GetTestName() { - base::FilePath executable = base::CommandLine::ForCurrentProcess() - ->GetProgram() - .BaseName() - .RemoveExtension(); - return std::string("") + executable.MaybeAsASCII(); - } - - base::Thread thread_; - std::unique_ptr<service_manager::BackgroundServiceManager> - background_service_manager_; - std::unique_ptr<service_manager::ServiceContext> context_; - std::unique_ptr<service_manager::Connector> service_manager_connector_; - service_manager::Identity service_manager_identity_; - - DISALLOW_COPY_AND_ASSIGN(ServiceManagerConnection); -}; - -ViewsMusTestSuite::ViewsMusTestSuite(int argc, char** argv) - : ViewsTestSuite(argc, argv) {} - -ViewsMusTestSuite::~ViewsMusTestSuite() {} - -void ViewsMusTestSuite::Initialize() { - PlatformTestHelper::SetIsMus(); - // Let other services know that we're running in tests. Do this with a - // command line flag to avoid making blocking calls to other processes for - // setup for tests (e.g. to unlock the screen in the window manager). - EnsureCommandLineSwitch(ui::switches::kUseTestConfig); - - ViewsTestSuite::Initialize(); - service_manager_connections_ = base::MakeUnique<ServiceManagerConnection>(); -} - -void ViewsMusTestSuite::Shutdown() { - service_manager_connections_.reset(); - ViewsTestSuite::Shutdown(); -} - -} // namespace views
diff --git a/ui/views/mus/views_mus_test_suite.h b/ui/views/mus/views_mus_test_suite.h deleted file mode 100644 index 2bfd313..0000000 --- a/ui/views/mus/views_mus_test_suite.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_VIEWS_MUS_TEST_SUITE_H_ -#define UI_VIEWS_MUS_VIEWS_MUS_TEST_SUITE_H_ - -#include <memory> - -#include "base/macros.h" -#include "ui/views/views_test_suite.h" - -namespace views { - -class ServiceManagerConnection; - -class ViewsMusTestSuite : public ViewsTestSuite { - public: - ViewsMusTestSuite(int argc, char** argv); - ~ViewsMusTestSuite() override; - - private: - // ViewsTestSuite: - void Initialize() override; - void Shutdown() override; - - std::unique_ptr<ServiceManagerConnection> service_manager_connections_; - - DISALLOW_COPY_AND_ASSIGN(ViewsMusTestSuite); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_VIEWS_MUS_TEST_SUITE_H_
diff --git a/ui/views/mus/window_manager_connection.cc b/ui/views/mus/window_manager_connection.cc deleted file mode 100644 index 16fae1a..0000000 --- a/ui/views/mus/window_manager_connection.cc +++ /dev/null
@@ -1,235 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/window_manager_connection.h" - -#include <algorithm> -#include <set> -#include <utility> - -#include "base/lazy_instance.h" -#include "base/memory/ptr_util.h" -#include "base/threading/thread_local.h" -#include "services/service_manager/public/cpp/connection.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/ui/public/cpp/gpu/gpu.h" -#include "services/ui/public/cpp/property_type_converters.h" -#include "services/ui/public/cpp/window.h" -#include "services/ui/public/cpp/window_property.h" -#include "services/ui/public/cpp/window_tree_client.h" -#include "services/ui/public/interfaces/event_matcher.mojom.h" -#include "services/ui/public/interfaces/window_tree.mojom.h" -#include "ui/aura/env.h" -#include "ui/aura/mus/os_exchange_data_provider_mus.h" -#include "ui/views/mus/clipboard_mus.h" -#include "ui/views/mus/native_widget_mus.h" -#include "ui/views/mus/pointer_watcher_event_router.h" -#include "ui/views/mus/screen_mus.h" -#include "ui/views/mus/surface_context_factory.h" -#include "ui/views/pointer_watcher.h" -#include "ui/views/views_delegate.h" - -namespace views { -namespace { - -using WindowManagerConnectionPtr = - base::ThreadLocalPointer<views::WindowManagerConnection>; - -// Env is thread local so that aura may be used on multiple threads. -base::LazyInstance<WindowManagerConnectionPtr>::Leaky lazy_tls_ptr = - LAZY_INSTANCE_INITIALIZER; - -// Recursively finds the deepest visible window from |windows| that contains -// |screen_point|, when offsetting by the display origins from -// |display_origins|. -ui::Window* GetWindowFrom(const std::map<int64_t, gfx::Point>& display_origins, - const std::vector<ui::Window*>& windows, - const gfx::Point& screen_point) { - for (ui::Window* window : windows) { - if (!window->visible()) - continue; - - auto it = display_origins.find(window->display_id()); - if (it == display_origins.end()) - continue; - - gfx::Rect bounds_in_screen = window->GetBoundsInRoot(); - bounds_in_screen.Offset(it->second.x(), it->second.y()); - - if (bounds_in_screen.Contains(screen_point)) { - if (!window->children().empty()) { - ui::Window* child = - GetWindowFrom(display_origins, window->children(), screen_point); - if (child) - return child; - } - - return window; - } - } - return nullptr; -} - -aura::Window* GetAuraWindowFromUiWindow(ui::Window* window) { - if (!window) - return nullptr; - NativeWidgetMus* nw_mus = NativeWidgetMus::GetForWindow(window); - return nw_mus - ? static_cast<internal::NativeWidgetPrivate*>(nw_mus) - ->GetNativeView() - : nullptr; -} - -} // namespace - -WindowManagerConnection::~WindowManagerConnection() { - // ~WindowTreeClient calls back to us (we're its delegate), destroy it while - // we are still valid. - client_.reset(); - ui::OSExchangeDataProviderFactory::SetFactory(nullptr); - ui::Clipboard::DestroyClipboardForCurrentThread(); - gpu_.reset(); - lazy_tls_ptr.Pointer()->Set(nullptr); - - if (ViewsDelegate::GetInstance()) { - ViewsDelegate::GetInstance()->set_native_widget_factory( - ViewsDelegate::NativeWidgetFactory()); - } -} - -// static -std::unique_ptr<WindowManagerConnection> WindowManagerConnection::Create( - service_manager::Connector* connector, - const service_manager::Identity& identity, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - DCHECK(!lazy_tls_ptr.Pointer()->Get()); - WindowManagerConnection* connection = - new WindowManagerConnection(connector, identity, std::move(task_runner)); - DCHECK(lazy_tls_ptr.Pointer()->Get()); - return base::WrapUnique(connection); -} - -// static -WindowManagerConnection* WindowManagerConnection::Get() { - WindowManagerConnection* connection = lazy_tls_ptr.Pointer()->Get(); - DCHECK(connection); - return connection; -} - -// static -bool WindowManagerConnection::Exists() { - return !!lazy_tls_ptr.Pointer()->Get(); -} - -ui::Window* WindowManagerConnection::NewTopLevelWindow( - const std::map<std::string, std::vector<uint8_t>>& properties) { - return client_->NewTopLevelWindow(&properties); -} - -NativeWidget* WindowManagerConnection::CreateNativeWidgetMus( - const std::map<std::string, std::vector<uint8_t>>& props, - const Widget::InitParams& init_params, - internal::NativeWidgetDelegate* delegate) { - // TYPE_CONTROL widgets require a NativeWidgetAura. So we let this fall - // through, so that the default NativeWidgetPrivate::CreateNativeWidget() is - // used instead. - if (init_params.type == Widget::InitParams::TYPE_CONTROL) - return nullptr; - std::map<std::string, std::vector<uint8_t>> properties = props; - NativeWidgetMus::ConfigurePropertiesForNewWindow(init_params, &properties); - properties[ui::mojom::WindowManager::kAppID_Property] = - mojo::ConvertTo<std::vector<uint8_t>>(identity_.name()); - return new NativeWidgetMus(delegate, NewTopLevelWindow(properties), - ui::mojom::CompositorFrameSinkType::DEFAULT); -} - -const std::set<ui::Window*>& WindowManagerConnection::GetRoots() const { - return client_->GetRoots(); -} - -WindowManagerConnection::WindowManagerConnection( - service_manager::Connector* connector, - const service_manager::Identity& identity, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : connector_(connector), identity_(identity) { - lazy_tls_ptr.Pointer()->Set(this); - - gpu_ = ui::Gpu::Create(connector, std::move(task_runner)); - compositor_context_factory_ = - base::MakeUnique<views::SurfaceContextFactory>(gpu_.get()); - aura::Env::GetInstance()->set_context_factory( - compositor_context_factory_.get()); - client_ = base::MakeUnique<ui::WindowTreeClient>(this, nullptr, nullptr); - client_->ConnectViaWindowTreeFactory(connector_); - - pointer_watcher_event_router_ = - base::MakeUnique<PointerWatcherEventRouter>(client_.get()); - - screen_ = base::MakeUnique<ScreenMus>(this); - screen_->Init(connector); - - std::unique_ptr<ClipboardMus> clipboard = base::MakeUnique<ClipboardMus>(); - clipboard->Init(connector); - ui::Clipboard::SetClipboardForCurrentThread(std::move(clipboard)); - - ui::OSExchangeDataProviderFactory::SetFactory(this); - - ViewsDelegate::GetInstance()->set_native_widget_factory(base::Bind( - &WindowManagerConnection::CreateNativeWidgetMus, - base::Unretained(this), - std::map<std::string, std::vector<uint8_t>>())); -} - -ui::Window* WindowManagerConnection::GetUiWindowAtScreenPoint( - const gfx::Point& point) { - std::map<int64_t, gfx::Point> display_origins; - for (const display::Display& d : - display::Screen::GetScreen()->GetAllDisplays()) - display_origins[d.id()] = d.bounds().origin(); - - const std::set<ui::Window*>& roots = GetRoots(); - std::vector<ui::Window*> windows; - std::copy(roots.begin(), roots.end(), std::back_inserter(windows)); - return GetWindowFrom(display_origins, windows, point); -} - -void WindowManagerConnection::OnEmbed(ui::Window* root) {} - -void WindowManagerConnection::OnLostConnection(ui::WindowTreeClient* client) { - DCHECK_EQ(client, client_.get()); - client_.reset(); -} - -void WindowManagerConnection::OnEmbedRootDestroyed(ui::Window* root) { - // Not called for WindowManagerConnection as WindowTreeClient isn't created by - // way of an Embed(). - NOTREACHED(); -} - -void WindowManagerConnection::OnPointerEventObserved( - const ui::PointerEvent& event, - ui::Window* target) { - pointer_watcher_event_router_->OnPointerEventObserved(event, target); -} - -void WindowManagerConnection::OnWindowManagerFrameValuesChanged() { - if (client_) - NativeWidgetMus::NotifyFrameChanged(client_.get()); -} - -gfx::Point WindowManagerConnection::GetCursorScreenPoint() { - return client_->GetCursorScreenPoint(); -} - -aura::Window* WindowManagerConnection::GetWindowAtScreenPoint( - const gfx::Point& point) { - return GetAuraWindowFromUiWindow(GetUiWindowAtScreenPoint(point)); -} - -std::unique_ptr<OSExchangeData::Provider> -WindowManagerConnection::BuildProvider() { - return base::MakeUnique<aura::OSExchangeDataProviderMus>(); -} - -} // namespace views
diff --git a/ui/views/mus/window_manager_connection.h b/ui/views/mus/window_manager_connection.h deleted file mode 100644 index eaea770..0000000 --- a/ui/views/mus/window_manager_connection.h +++ /dev/null
@@ -1,126 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_WINDOW_MANAGER_CONNECTION_H_ -#define UI_VIEWS_MUS_WINDOW_MANAGER_CONNECTION_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <set> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "services/service_manager/public/cpp/identity.h" -#include "services/ui/public/cpp/window_tree_client_delegate.h" -#include "ui/base/dragdrop/os_exchange_data_provider_factory.h" -#include "ui/views/mus/mus_export.h" -#include "ui/views/mus/screen_mus_delegate.h" -#include "ui/views/widget/widget.h" - -namespace service_manager { -class Connector; -} - -namespace ui { -class Gpu; -} - -namespace views { -class NativeWidget; -class PointerWatcherEventRouter; -class ScreenMus; -class SurfaceContextFactory; -namespace internal { -class NativeWidgetDelegate; -} - -namespace test { -class WindowManagerConnectionTestApi; -} - -// Provides configuration to mus in views. This consists of the following: -// . Provides a Screen implementation backed by mus. -// . Provides a Clipboard implementation backed by mus. -// . Creates and owns a WindowTreeClient. -// . Registers itself as the factory for creating NativeWidgets so that a -// NativeWidgetMus is created. -// WindowManagerConnection is a singleton and should be created early on. -// -// TODO(sky): this name is now totally confusing. Come up with a better one. -class VIEWS_MUS_EXPORT WindowManagerConnection - : public NON_EXPORTED_BASE(ui::WindowTreeClientDelegate), - public ScreenMusDelegate, - public ui::OSExchangeDataProviderFactory::Factory { - public: - ~WindowManagerConnection() override; - - // |io_task_runner| is used by the gpu service. If no task runner is provided, - // then a new thread is created and used by ui::Gpu. - static std::unique_ptr<WindowManagerConnection> Create( - service_manager::Connector* connector, - const service_manager::Identity& identity, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr); - static WindowManagerConnection* Get(); - static bool Exists(); - - PointerWatcherEventRouter* pointer_watcher_event_router() { - return pointer_watcher_event_router_.get(); - } - service_manager::Connector* connector() { return connector_; } - ui::Gpu* gpu() { return gpu_.get(); } - ui::WindowTreeClient* client() { return client_.get(); } - - ui::Window* NewTopLevelWindow( - const std::map<std::string, std::vector<uint8_t>>& properties); - - NativeWidget* CreateNativeWidgetMus( - const std::map<std::string, std::vector<uint8_t>>& properties, - const Widget::InitParams& init_params, - internal::NativeWidgetDelegate* delegate); - - const std::set<ui::Window*>& GetRoots() const; - - private: - friend class test::WindowManagerConnectionTestApi; - - WindowManagerConnection( - service_manager::Connector* connector, - const service_manager::Identity& identity, - scoped_refptr<base::SingleThreadTaskRunner> task_runner); - - // Exposed for tests. - ui::Window* GetUiWindowAtScreenPoint(const gfx::Point& point); - - // ui::WindowTreeClientDelegate: - void OnEmbed(ui::Window* root) override; - void OnLostConnection(ui::WindowTreeClient* client) override; - void OnEmbedRootDestroyed(ui::Window* root) override; - void OnPointerEventObserved(const ui::PointerEvent& event, - ui::Window* target) override; - - // ScreenMusDelegate: - void OnWindowManagerFrameValuesChanged() override; - gfx::Point GetCursorScreenPoint() override; - aura::Window* GetWindowAtScreenPoint(const gfx::Point& point) override; - - // ui:OSExchangeDataProviderFactory::Factory: - std::unique_ptr<OSExchangeData::Provider> BuildProvider() override; - - service_manager::Connector* connector_; - service_manager::Identity identity_; - std::unique_ptr<ScreenMus> screen_; - std::unique_ptr<ui::WindowTreeClient> client_; - std::unique_ptr<ui::Gpu> gpu_; - std::unique_ptr<PointerWatcherEventRouter> pointer_watcher_event_router_; - std::unique_ptr<SurfaceContextFactory> compositor_context_factory_; - - DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_WINDOW_MANAGER_CONNECTION_H_
diff --git a/ui/views/mus/window_manager_connection_unittest.cc b/ui/views/mus/window_manager_connection_unittest.cc deleted file mode 100644 index b3f28d1..0000000 --- a/ui/views/mus/window_manager_connection_unittest.cc +++ /dev/null
@@ -1,116 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/window_manager_connection.h" - -#include "base/message_loop/message_loop.h" -#include "services/ui/public/cpp/window.h" -#include "services/ui/public/cpp/window_private.h" -#include "services/ui/public/cpp/window_tree_client.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/views/mus/screen_mus.h" -#include "ui/views/mus/test_utils.h" -#include "ui/views/test/scoped_views_test_helper.h" - -namespace views { -namespace { - -class WindowManagerConnectionTest : public testing::Test { - public: - WindowManagerConnectionTest() : message_loop_(base::MessageLoop::TYPE_UI) {} - ~WindowManagerConnectionTest() override {} - - WindowManagerConnection* connection() { - return WindowManagerConnection::Get(); - } - - ScreenMusDelegate* screen_mus_delegate() { return connection(); } - - ui::Window* GetWindowAtScreenPoint(const gfx::Point& point) { - return test::WindowManagerConnectionTestApi(connection()) - .GetUiWindowAtScreenPoint(point); - } - - private: - base::MessageLoop message_loop_; - ScopedViewsTestHelper helper_; - - DISALLOW_COPY_AND_ASSIGN(WindowManagerConnectionTest); -}; - -TEST_F(WindowManagerConnectionTest, GetWindowAtScreenPointRecurse) { - ui::Window* one = connection()->client()->NewTopLevelWindow(nullptr); - one->SetBounds(gfx::Rect(0, 0, 100, 100)); - one->SetVisible(true); - - std::vector<display::Display> displays = - display::Screen::GetScreen()->GetAllDisplays(); - ASSERT_GE(displays.size(), 1u); - ui::WindowPrivate(one).LocalSetDisplay(displays[0].id()); - - ui::Window* two = connection()->client()->NewWindow(); - one->AddChild(two); - two->SetBounds(gfx::Rect(10, 10, 80, 80)); - two->SetVisible(true); - - // Ensure that we recurse down to the second window. - EXPECT_EQ(two, GetWindowAtScreenPoint(gfx::Point(50, 50))); -} - -TEST_F(WindowManagerConnectionTest, GetWindowAtScreenPointRecurseButIgnore) { - ui::Window* one = connection()->client()->NewTopLevelWindow(nullptr); - one->SetBounds(gfx::Rect(0, 0, 100, 100)); - one->SetVisible(true); - - std::vector<display::Display> displays = - display::Screen::GetScreen()->GetAllDisplays(); - ASSERT_GE(displays.size(), 1u); - ui::WindowPrivate(one).LocalSetDisplay(displays[0].id()); - - ui::Window* two = connection()->client()->NewWindow(); - one->AddChild(two); - two->SetBounds(gfx::Rect(5, 5, 10, 10)); - two->SetVisible(true); - - // We'll recurse down, but we'll use the parent anyway because the children - // don't match the bounds. - EXPECT_EQ(one, GetWindowAtScreenPoint(gfx::Point(50, 50))); -} - -TEST_F(WindowManagerConnectionTest, GetWindowAtScreenPointDisplayOffset) { - ui::Window* one = connection()->client()->NewTopLevelWindow(nullptr); - one->SetBounds(gfx::Rect(5, 5, 5, 5)); - one->SetVisible(true); - - std::vector<display::Display> displays = - display::Screen::GetScreen()->GetAllDisplays(); - ASSERT_GE(displays.size(), 1u); - ui::WindowPrivate(one).LocalSetDisplay(displays[0].id()); - - // Make the first display offset by 50. - test::WindowManagerConnectionTestApi api(connection()); - display::Display display( - *api.screen()->display_list().FindDisplayById(displays[0].id())); - display.set_bounds(gfx::Rect(44, 44, 50, 50)); - api.screen()->display_list().UpdateDisplay(display); - - EXPECT_EQ(one, GetWindowAtScreenPoint(gfx::Point(50, 50))); -} - -TEST_F(WindowManagerConnectionTest, IgnoresHiddenWindows) { - // Hide the one window. - ui::Window* one = connection()->client()->NewTopLevelWindow(nullptr); - one->SetBounds(gfx::Rect(0, 0, 100, 100)); - one->SetVisible(false); - - std::vector<display::Display> displays = - display::Screen::GetScreen()->GetAllDisplays(); - ASSERT_GE(displays.size(), 1u); - ui::WindowPrivate(one).LocalSetDisplay(displays[0].id()); - - EXPECT_EQ(nullptr, GetWindowAtScreenPoint(gfx::Point(50, 50))); -} - -} // namespace -} // namespace views
diff --git a/ui/views/mus/window_tree_host_mus.cc b/ui/views/mus/window_tree_host_mus.cc deleted file mode 100644 index ffb4a82..0000000 --- a/ui/views/mus/window_tree_host_mus.cc +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/window_tree_host_mus.h" - -#include "base/memory/ptr_util.h" -#include "services/ui/public/cpp/window.h" -#include "ui/aura/env.h" -#include "ui/aura/window.h" -#include "ui/aura/window_event_dispatcher.h" -#include "ui/events/event.h" -#include "ui/gfx/geometry/dip_util.h" -#include "ui/platform_window/stub/stub_window.h" -#include "ui/views/mus/input_method_mus.h" -#include "ui/views/mus/native_widget_mus.h" - -namespace views { - -namespace { -static uint32_t accelerated_widget_count = 1; - -bool IsUsingTestContext() { - return aura::Env::GetInstance()->context_factory()->DoesCreateTestContexts(); -} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// WindowTreeHostMus, public: - -WindowTreeHostMus::WindowTreeHostMus(NativeWidgetMus* native_widget, - ui::Window* window) - : native_widget_(native_widget) { - CreateCompositor(); - gfx::AcceleratedWidget accelerated_widget; - if (IsUsingTestContext()) { - accelerated_widget = gfx::kNullAcceleratedWidget; - } else { - // We need accelerated widget numbers to be different for each - // window and fit in the smallest sizeof(AcceleratedWidget) uint32_t - // has this property. -#if defined(OS_WIN) || defined(OS_ANDROID) - accelerated_widget = - reinterpret_cast<gfx::AcceleratedWidget>(accelerated_widget_count++); -#else - accelerated_widget = - static_cast<gfx::AcceleratedWidget>(accelerated_widget_count++); -#endif - } - // TODO(markdittmer): Use correct device-scale-factor from |window|. - OnAcceleratedWidgetAvailable(accelerated_widget, 1.f); - - SetPlatformWindow(base::MakeUnique<ui::StubWindow>( - this, - false)); // Do not advertise accelerated widget; already set manually. - - compositor()->SetWindow(window); - - // Initialize the stub platform window bounds to those of the ui::Window. - platform_window()->SetBounds(gfx::ConvertRectToPixel( - compositor()->device_scale_factor(), window->bounds())); - - compositor()->SetHostHasTransparentBackground(true); -} - -WindowTreeHostMus::~WindowTreeHostMus() { - DestroyCompositor(); - DestroyDispatcher(); -} - -void WindowTreeHostMus::DispatchEvent(ui::Event* event) { - // Key events are sent to InputMethodMus directly from NativeWidgetMus. - DCHECK(!event->IsKeyEvent()); - WindowTreeHostPlatform::DispatchEvent(event); -} - -void WindowTreeHostMus::OnClosed() { - if (native_widget_) - native_widget_->OnPlatformWindowClosed(); -} - -void WindowTreeHostMus::OnActivationChanged(bool active) { - if (active) - GetInputMethod()->OnFocus(); - else - GetInputMethod()->OnBlur(); - if (native_widget_) - native_widget_->OnActivationChanged(active); - WindowTreeHostPlatform::OnActivationChanged(active); -} - -void WindowTreeHostMus::OnCloseRequest() { - OnHostCloseRequested(); -} - -gfx::ICCProfile WindowTreeHostMus::GetICCProfileForCurrentDisplay() { - // TODO: This should read the profile from mus. crbug.com/647510 - return gfx::ICCProfile(); -} - -} // namespace views
diff --git a/ui/views/mus/window_tree_host_mus.h b/ui/views/mus/window_tree_host_mus.h deleted file mode 100644 index c513171..0000000 --- a/ui/views/mus/window_tree_host_mus.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_WINDOW_TREE_HOST_MUS_H_ -#define UI_VIEWS_MUS_WINDOW_TREE_HOST_MUS_H_ - -#include "base/macros.h" -#include "services/service_manager/public/cpp/connector.h" -#include "ui/aura/window_tree_host_platform.h" -#include "ui/views/mus/mus_export.h" - -namespace ui { -class Window; -} - -namespace views { - -class NativeWidgetMus; - -class VIEWS_MUS_EXPORT WindowTreeHostMus : public aura::WindowTreeHostPlatform { - public: - WindowTreeHostMus(NativeWidgetMus* native_widget, ui::Window* window); - ~WindowTreeHostMus() override; - NativeWidgetMus* native_widget() { return native_widget_; } - - private: - // aura::WindowTreeHostPlatform: - void DispatchEvent(ui::Event* event) override; - void OnClosed() override; - void OnActivationChanged(bool active) override; - void OnCloseRequest() override; - gfx::ICCProfile GetICCProfileForCurrentDisplay() override; - - NativeWidgetMus* native_widget_; - - DISALLOW_COPY_AND_ASSIGN(WindowTreeHostMus); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_WINDOW_TREE_HOST_MUS_H_
diff --git a/ui/views/selection_controller.cc b/ui/views/selection_controller.cc index 4692c9c..9aecd74 100644 --- a/ui/views/selection_controller.cc +++ b/ui/views/selection_controller.cc
@@ -196,18 +196,7 @@ delegate_->OnBeforePointerAction(); - // TODO(karandeepb): See if this can be handled at the RenderText level. - const bool drags_to_end = PlatformStyle::kTextDragVerticallyDragsToEnd; - if (drags_to_end && last_drag_location_.y() < 0) { - render_text->MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, - gfx::SELECTION_RETAIN); - } else if (drags_to_end && - last_drag_location_.y() > delegate_->GetViewHeight()) { - render_text->MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, - gfx::SELECTION_RETAIN); - } else { - render_text->MoveCursorTo(last_drag_location_, true); - } + render_text->MoveCursorTo(last_drag_location_, true); if (aggregated_clicks_ == 1) { render_text->SelectWord();
diff --git a/ui/views/style/platform_style.cc b/ui/views/style/platform_style.cc index dc20e0f8..46ffecf 100644 --- a/ui/views/style/platform_style.cc +++ b/ui/views/style/platform_style.cc
@@ -41,7 +41,6 @@ const int PlatformStyle::kMinLabelButtonHeight = 33; const bool PlatformStyle::kDefaultLabelButtonHasBoldFont = true; const bool PlatformStyle::kDialogDefaultButtonCanBeCancel = true; -const bool PlatformStyle::kTextDragVerticallyDragsToEnd = false; const bool PlatformStyle::kSelectWordOnRightClick = false; const CustomButton::NotifyAction PlatformStyle::kMenuNotifyActivationAction = CustomButton::NOTIFY_ON_RELEASE;
diff --git a/ui/views/style/platform_style.h b/ui/views/style/platform_style.h index dfa434f13..e71720fbc 100644 --- a/ui/views/style/platform_style.h +++ b/ui/views/style/platform_style.h
@@ -40,10 +40,6 @@ // Whether the default button for a dialog can be the Cancel button. static const bool kDialogDefaultButtonCanBeCancel; - // Whether dragging vertically above or below a text view's bounds selects to - // the left or right end of the text from the cursor, respectively. - static const bool kTextDragVerticallyDragsToEnd; - // Whether right clicking on text, selects the word under cursor. static const bool kSelectWordOnRightClick;
diff --git a/ui/views/style/platform_style_mac.mm b/ui/views/style/platform_style_mac.mm index 97caa954..4e07484 100644 --- a/ui/views/style/platform_style_mac.mm +++ b/ui/views/style/platform_style_mac.mm
@@ -23,7 +23,6 @@ const int PlatformStyle::kMinLabelButtonHeight = 30; const bool PlatformStyle::kDefaultLabelButtonHasBoldFont = false; const bool PlatformStyle::kDialogDefaultButtonCanBeCancel = false; -const bool PlatformStyle::kTextDragVerticallyDragsToEnd = true; const bool PlatformStyle::kSelectWordOnRightClick = true; const bool PlatformStyle::kTreeViewHasFocusRing = true; const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true;
diff --git a/ui/views/test/native_widget_factory_mus.cc b/ui/views/test/native_widget_factory_mus.cc deleted file mode 100644 index 91bc6b1..0000000 --- a/ui/views/test/native_widget_factory_mus.cc +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/test/native_widget_factory.h" - -#include "ui/views/mus/window_manager_connection.h" -#include "ui/views/test/test_platform_native_widget.h" -#include "ui/views/widget/native_widget_aura.h" - -namespace views { -namespace test { - -NativeWidget* CreatePlatformNativeWidgetImpl( - const Widget::InitParams& init_params, - Widget* widget, - uint32_t type, - bool* destroyed) { - return new TestPlatformNativeWidget<NativeWidgetAura>( - widget, type == kStubCapture, destroyed); -} - -NativeWidget* CreatePlatformDesktopNativeWidgetImpl( - const Widget::InitParams& init_params, - Widget* widget, - bool* destroyed) { - return WindowManagerConnection::Get()->CreateNativeWidgetMus( - std::map<std::string, std::vector<uint8_t>>(), init_params, widget); -} - -} // namespace test -} // namespace views
diff --git a/ui/views/test/platform_test_helper.cc b/ui/views/test/platform_test_helper.cc index 488a9e58..c6204ab 100644 --- a/ui/views/test/platform_test_helper.cc +++ b/ui/views/test/platform_test_helper.cc
@@ -18,7 +18,6 @@ PlatformTestHelper::Factory test_helper_factory; bool is_mus = false; -bool is_aura_mus_client = false; } // namespace @@ -44,16 +43,6 @@ return is_mus; } -// static -void PlatformTestHelper::SetIsAuraMusClient() { - is_aura_mus_client = true; -} - -// static -bool PlatformTestHelper::IsAuraMusClient() { - return is_aura_mus_client; -} - #if defined(USE_AURA) void PlatformTestHelper::SimulateNativeDestroy(Widget* widget) { delete widget->GetNativeView();
diff --git a/ui/views/test/platform_test_helper.h b/ui/views/test/platform_test_helper.h index 909191be..fb3ab10 100644 --- a/ui/views/test/platform_test_helper.h +++ b/ui/views/test/platform_test_helper.h
@@ -24,14 +24,9 @@ static void set_factory(const Factory& factory); static std::unique_ptr<PlatformTestHelper> Create(); - // Whether we are running under the mus environment. Methods are static so - // that they can be called before Create(). static void SetIsMus(); static bool IsMus(); - static void SetIsAuraMusClient(); - static bool IsAuraMusClient(); - // Called once the ViewsTestHelper has been created, but before SetUp() is // called. virtual void OnTestHelperCreated(ViewsTestHelper* helper) {}
diff --git a/ui/views/test/scoped_views_test_helper.cc b/ui/views/test/scoped_views_test_helper.cc index a67ca6e..051f8e64 100644 --- a/ui/views/test/scoped_views_test_helper.cc +++ b/ui/views/test/scoped_views_test_helper.cc
@@ -16,10 +16,6 @@ #include "ui/views/test/test_views_delegate.h" #include "ui/views/test/views_test_helper.h" -#if defined(USE_AURA) -#include "ui/aura/env.h" -#endif - namespace views { ScopedViewsTestHelper::ScopedViewsTestHelper() @@ -31,16 +27,6 @@ platform_test_helper_(PlatformTestHelper::Create()) { // The ContextFactory must exist before any Compositors are created. bool enable_pixel_output = false; -#if defined(USE_AURA) - ui::ContextFactory* old_context_factory = nullptr; - ui::ContextFactoryPrivate* old_context_factory_private = nullptr; - if (PlatformTestHelper::IsMus()) { - old_context_factory = aura::Env::GetInstance()->context_factory(); - DCHECK(old_context_factory); - old_context_factory_private = - aura::Env::GetInstance()->context_factory_private(); - } -#endif ui::ContextFactory* context_factory = nullptr; ui::ContextFactoryPrivate* context_factory_private = nullptr; ui::InitializeContextFactoryForTests(enable_pixel_output, &context_factory, @@ -55,21 +41,6 @@ platform_test_helper_->OnTestHelperCreated(test_helper_.get()); test_helper_->SetUp(); -#if defined(USE_AURA) - // When running inside mus, the context-factory from - // ui::InitializeContextFactoryForTests() is only needed for the default - // WindowTreeHost instance created by TestScreen. After that, the - // context-factory is used when creating Widgets (to set-up the compositor for - // the corresponding ui::Windows). So restore the context-factory (which - // WindowManagerConnection would have set up), so that NativeWidgetMus - // installs the correct context-factory that can talk to mus. - if (PlatformTestHelper::IsMus()) { - aura::Env::GetInstance()->set_context_factory(old_context_factory); - aura::Env::GetInstance()->set_context_factory_private( - old_context_factory_private); - } -#endif - ui::InitializeInputMethodForTesting(); ui::TestClipboard::CreateForCurrentThread(); }
diff --git a/ui/views/test/views_test_base.cc b/ui/views/test/views_test_base.cc index d1cd2da..4147f01 100644 --- a/ui/views/test/views_test_base.cc +++ b/ui/views/test/views_test_base.cc
@@ -64,11 +64,6 @@ return PlatformTestHelper::IsMus(); } -// static -bool ViewsTestBase::IsAuraMusClient() { - return PlatformTestHelper::IsAuraMusClient(); -} - void ViewsTestBase::SetUp() { testing::Test::SetUp(); // ContentTestSuiteBase might have already initialized
diff --git a/ui/views/test/views_test_base.h b/ui/views/test/views_test_base.h index 74cfb8ea..ebdc440 100644 --- a/ui/views/test/views_test_base.h +++ b/ui/views/test/views_test_base.h
@@ -29,12 +29,9 @@ ViewsTestBase(); ~ViewsTestBase() override; - // Whether the test is running under mus. - static bool IsMus(); - // Returns true if running aura-mus in a client configuration (not the window // manager). - static bool IsAuraMusClient(); + static bool IsMus(); // testing::Test: void SetUp() override;
diff --git a/ui/views/test/views_test_helper_aura.cc b/ui/views/test/views_test_helper_aura.cc index f9fe6f1..50196b5 100644 --- a/ui/views/test/views_test_helper_aura.cc +++ b/ui/views/test/views_test_helper_aura.cc
@@ -79,7 +79,7 @@ } gfx::NativeWindow ViewsTestHelperAura::GetContext() { - if (PlatformTestHelper::IsAuraMusClient()) { + if (PlatformTestHelper::IsMus()) { // GetContext() returns the root of a WindowTreeHost associated with a // single display that is intended for an ash like environment. Such a // configuration doesn't make sense for aura-mus-client, where it's testing
diff --git a/ui/views/touchui/touch_selection_controller_impl_unittest.cc b/ui/views/touchui/touch_selection_controller_impl_unittest.cc index be377cda..83de784 100644 --- a/ui/views/touchui/touch_selection_controller_impl_unittest.cc +++ b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
@@ -77,7 +77,7 @@ ViewsTestBase::SetUp(); // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; test_cursor_client_.reset(new aura::test::TestCursorClient(GetContext())); } @@ -323,7 +323,7 @@ // a Textfield changes. TEST_F(TouchSelectionControllerImplTest, SelectionInTextfieldTest) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateTextfield(); @@ -360,7 +360,7 @@ // Tests that the selection handles are placed appropriately in bidi text. TEST_F(TouchSelectionControllerImplTest, SelectionInBidiTextfieldTest) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateTextfield(); @@ -416,7 +416,7 @@ // handles are moved. TEST_F(TouchSelectionControllerImplTest, SelectRectCallbackTest) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateTextfield(); @@ -462,7 +462,7 @@ TEST_F(TouchSelectionControllerImplTest, SelectRectInBidiCallbackTest) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateTextfield(); @@ -594,7 +594,7 @@ TEST_F(TouchSelectionControllerImplTest, HiddenSelectionHandleRetainsCursorPosition) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; static const uint32_t selection_start = 10u; @@ -616,7 +616,7 @@ // drag and that it maintains the correct orientation when exposed. TEST_F(TouchSelectionControllerImplTest, HiddenSelectionHandleExposed) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; static const uint32_t selection_start = 0u; @@ -637,7 +637,7 @@ TEST_F(TouchSelectionControllerImplTest, DoubleTapInTextfieldWithCursorHandleShouldSelectText) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateTextfield(); @@ -740,7 +740,7 @@ TEST_F(TouchSelectionControllerImplTest, VisibilityOfHandleRegardingClientBounds) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateWidget(); @@ -791,7 +791,7 @@ TEST_F(TouchSelectionControllerImplTest, HandlesStackAboveParent) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; ui::EventTarget* root = GetContext(); @@ -833,7 +833,7 @@ TEST_F(TouchSelectionControllerImplTest, MouseEventDeactivatesTouchSelection) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateTextfield(); @@ -878,7 +878,7 @@ TEST_F(TouchSelectionControllerImplTest, MouseCaptureChangedEventIgnored) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateTextfield(); @@ -901,7 +901,7 @@ TEST_F(TouchSelectionControllerImplTest, KeyEventDeactivatesTouchSelection) { // TODO: see comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; CreateTextfield();
diff --git a/ui/views/touchui/touch_selection_menu_runner_views_unittest.cc b/ui/views/touchui/touch_selection_menu_runner_views_unittest.cc index 100a396..428a7c2 100644 --- a/ui/views/touchui/touch_selection_menu_runner_views_unittest.cc +++ b/ui/views/touchui/touch_selection_menu_runner_views_unittest.cc
@@ -67,7 +67,7 @@ // and closing the menu works properly. TEST_F(TouchSelectionMenuRunnerViewsTest, InstalledAndWorksProperly) { // See comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; gfx::Rect menu_anchor(0, 0, 10, 10); @@ -98,7 +98,7 @@ // distance of handles. TEST_F(TouchSelectionMenuRunnerViewsTest, QuickMenuAdjustsAnchorRect) { // See comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; gfx::Size handle_size(10, 10); @@ -134,7 +134,7 @@ // Tests that running one of menu actions closes the menu properly. TEST_F(TouchSelectionMenuRunnerViewsTest, RunningActionClosesProperly) { // See comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; gfx::Rect menu_anchor(0, 0, 10, 10); @@ -169,7 +169,7 @@ // Tests that closing the menu widget cleans up the menu runner state properly. TEST_F(TouchSelectionMenuRunnerViewsTest, ClosingWidgetClosesProperly) { // See comment in SetUp(). - if (IsAuraMusClient()) + if (IsMus()) return; gfx::Rect menu_anchor(0, 0, 10, 10);
diff --git a/ui/views/view_unittest_aura.cc b/ui/views/view_unittest_aura.cc index 4e266048..66a9fd0f 100644 --- a/ui/views/view_unittest_aura.cc +++ b/ui/views/view_unittest_aura.cc
@@ -63,7 +63,7 @@ TEST_F(ViewAuraTest, RecreateLayersWithWindows) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; Widget* w1 = CreateControlWidget(GetContext(), gfx::Rect(0, 0, 100, 100));
diff --git a/ui/views/widget/native_widget_aura_interactive_uitest.cc b/ui/views/widget/native_widget_aura_interactive_uitest.cc index ad43feb..468ff869 100644 --- a/ui/views/widget/native_widget_aura_interactive_uitest.cc +++ b/ui/views/widget/native_widget_aura_interactive_uitest.cc
@@ -52,7 +52,7 @@ TEST_F(NativeWidgetAuraTest, NonActiveWindowRequestImeFocus) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; TestFocusRules* test_focus_rules = new TestFocusRules;
diff --git a/ui/views/widget/native_widget_unittest.cc b/ui/views/widget/native_widget_unittest.cc index 653c9be..2914d8d 100644 --- a/ui/views/widget/native_widget_unittest.cc +++ b/ui/views/widget/native_widget_unittest.cc
@@ -83,7 +83,7 @@ // |toplevel_widget| has the toplevel NativeWidget. TEST_F(NativeWidgetTest, GetTopLevelNativeWidget2) { // This test relies on GetContext(). http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; internal::NativeWidgetPrivate* child_widget = CreateNativeSubWidget();
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc index 3986ee4..5221a57 100644 --- a/ui/views/widget/widget_interactive_uitest.cc +++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -836,10 +836,6 @@ // Tests whether the focused window is set correctly when a modal window is // created and destroyed. When it is destroyed it should focus the owner window. TEST_F(WidgetTestInteractive, WindowModalWindowDestroyedActivationTest) { - // Fails on mus due to focus issues. http://crbug.com/611601 - if (IsMus()) - return; - TestWidgetFocusChangeListener focus_listener; WidgetFocusManager::GetInstance()->AddFocusChangeListener(&focus_listener); const std::vector<gfx::NativeView>& focus_changes = @@ -911,10 +907,6 @@ // Test that when opening a system-modal window, capture is released. TEST_F(WidgetTestInteractive, MAYBE_SystemModalWindowReleasesCapture) { - // Crashes on mus due to capture issue. http://crbug.com/611764 - if (IsMus()) - return; - TestWidgetFocusChangeListener focus_listener; WidgetFocusManager::GetInstance()->AddFocusChangeListener(&focus_listener); @@ -1006,7 +998,7 @@ #endif // defined(USE_AURA) TEST_F(WidgetTestInteractive, DisableViewDoesNotActivateWidget) { - // Times out on mus. See http://crbug.com/612193 + // TODO: see http://crbug.com/678070 for details. if (IsMus()) return; @@ -1199,7 +1191,7 @@ TEST_F(WidgetTestInteractive, InitialFocus) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; // By default, there is no initially focused view (even if there is a @@ -1343,6 +1335,10 @@ // See description in TestCapture(). TEST_F(WidgetCaptureTest, Capture) { + // TODO: capture isn't global in mus. http://crbug.com/678057. + if (IsMus()) + return; + TestCapture(false); } @@ -1362,11 +1358,7 @@ EXPECT_FALSE(capture_state.GetAndClearGotCaptureLost()); widget->CloseNow(); - // Fails on mus. http://crbug.com/611764 - if (IsMus()) - EXPECT_FALSE(capture_state.GetAndClearGotCaptureLost()); - else - EXPECT_TRUE(capture_state.GetAndClearGotCaptureLost()); + EXPECT_TRUE(capture_state.GetAndClearGotCaptureLost()); } TEST_F(WidgetCaptureTest, DestroyWithCapture_Close) { @@ -1400,22 +1392,15 @@ #if !defined(OS_CHROMEOS) // See description in TestCapture(). Creates DesktopNativeWidget. TEST_F(WidgetCaptureTest, CaptureDesktopNativeWidget) { - // Fails on mus. http://crbug.com/611764 - if (IsMus()) - return; - TestCapture(true); } #endif // Test that no state is set if capture fails. TEST_F(WidgetCaptureTest, FailedCaptureRequestIsNoop) { - // Fails on mus. http://crbug.com/611764 - if (IsMus()) - return; // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; Widget widget; @@ -1460,10 +1445,6 @@ // Test that a synthetic mouse exit is sent to the widget which was handling // mouse events when a different widget grabs capture. TEST_F(WidgetCaptureTest, MAYBE_MouseExitOnCaptureGrab) { - // Fails on mus. http://crbug.com/611764 - if (IsMus()) - return; - Widget widget1; Widget::InitParams params1 = CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); @@ -1527,6 +1508,10 @@ // Test that setting capture on widget activation of a non-toplevel widget // (e.g. a bubble on Linux) succeeds. TEST_F(WidgetCaptureTest, SetCaptureToNonToplevel) { + // TODO: capture isn't global in mus. http://crbug.com/678057. + if (IsMus()) + return; + Widget toplevel; Widget::InitParams toplevel_params = CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); @@ -1660,6 +1645,9 @@ // Test input method focus changes affected by top window activaction. TEST_F(WidgetInputMethodInteractiveTest, Activation) { + if (IsMus()) + return; + Widget* widget = CreateWidget(); Textfield* textfield = new Textfield; widget->GetRootView()->AddChildView(textfield); @@ -1721,10 +1709,6 @@ // Test input method focus changes affected by focus changes cross 2 windows // which shares the same top window. TEST_F(WidgetInputMethodInteractiveTest, TwoWindows) { - // Fails on mus. http://crbug.com/611766 - if (IsMus()) - return; - Widget* parent = CreateWidget(); parent->SetBounds(gfx::Rect(100, 100, 100, 100));
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index 22c6bdc..f3686be 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc
@@ -312,7 +312,7 @@ // NOTE: for aura-mus-client stacking of top-levels is not maintained in the // client, so z-order of top-levels can't be determined. - const bool check_toplevel_z_order = !IsAuraMusClient(); + const bool check_toplevel_z_order = !IsMus(); if (check_toplevel_z_order) EXPECT_TRUE(IsWindowStackedAbove(popover.get(), child)); EXPECT_TRUE(IsWindowStackedAbove(child, parent.get())); @@ -988,11 +988,6 @@ return; // Fails when swarmed. http://crbug.com/660582 #endif - if (IsMus()) { - NOTIMPLEMENTED(); - return; - } - WidgetAutoclosePtr widget; #if defined(OS_LINUX) && !defined(OS_CHROMEOS) // On desktop-Linux cheat and use non-desktop widgets. On X11, minimize is @@ -1103,7 +1098,7 @@ widget->SetSize(smaller_size); #if defined(OS_LINUX) && !defined(OS_CHROMEOS) // TODO(tapted): Desktop Linux ignores size constraints for SetSize. Fix it. - const bool use_small_size = IsMus() ? false : true; + const bool use_small_size = true; #else const bool use_small_size = false; #endif @@ -1179,11 +1174,6 @@ // Test that GetRestoredBounds() returns the original bounds of the window. TEST_F(WidgetTest, MAYBE_GetRestoredBounds) { - if (IsMus()) { - NOTIMPLEMENTED(); - return; - } - WidgetAutoclosePtr toplevel(CreateNativeDesktopWidget()); toplevel->Show(); // Initial restored bounds have non-zero size. @@ -1305,10 +1295,6 @@ // the case for desktop widgets on Windows. Other platforms retain the window // size while minimized. TEST_F(WidgetTest, TestViewWidthAfterMinimizingWidget) { - if (IsMus()) { - // This test is testing behavior specific to DesktopWindowTreeHostWin. - return; - } // Create a widget. Widget widget; Widget::InitParams init_params = @@ -1418,9 +1404,6 @@ } TEST_F(WidgetTest, DesktopNativeWidgetNoPaintAfterCloseTest) { - // TODO(sad): Desktop widgets do not work well in mus https://crbug.com/616551 - if (IsMus()) - return; DesktopAuraTestValidPaintWidget widget; widget.InitForTest(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS)); widget.WaitUntilPaint(); @@ -1433,9 +1416,6 @@ } TEST_F(WidgetTest, DesktopNativeWidgetNoPaintAfterHideTest) { - // TODO(sad): Desktop widgets do not work well in mus https://crbug.com/616551 - if (IsMus()) - return; DesktopAuraTestValidPaintWidget widget; widget.InitForTest(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS)); widget.WaitUntilPaint(); @@ -1703,7 +1683,7 @@ gfx::Point cursor_location(5, 5); ui::test::EventGenerator generator( - IsMus() || IsAuraMusClient() ? widget->GetNativeWindow() : GetContext(), + IsMus() ? widget->GetNativeWindow() : GetContext(), widget->GetNativeWindow()); generator.MoveMouseTo(cursor_location); @@ -1760,7 +1740,7 @@ event_count_view->AddPostTargetHandler(&consumer); ui::test::EventGenerator generator( - IsMus() || IsAuraMusClient() ? widget->GetNativeWindow() : GetContext(), + IsMus() ? widget->GetNativeWindow() : GetContext(), widget->GetNativeWindow()); generator.PressTouch(); generator.ClickLeftButton(); @@ -1792,7 +1772,7 @@ MousePressEventConsumer consumer; event_count_view->AddPostTargetHandler(&consumer); ui::test::EventGenerator generator( - IsMus() || IsAuraMusClient() ? widget->GetNativeWindow() : GetContext(), + IsMus() ? widget->GetNativeWindow() : GetContext(), widget->GetNativeWindow()); generator.PressLeftButton(); @@ -1855,7 +1835,7 @@ CaptureEventConsumer consumer(widget2); event_count_view->AddPostTargetHandler(&consumer); ui::test::EventGenerator generator( - IsMus() || IsAuraMusClient() ? widget->GetNativeWindow() : GetContext(), + IsMus() ? widget->GetNativeWindow() : GetContext(), widget->GetNativeWindow()); // This event should implicitly give capture to |widget|, except that // |consumer| will explicitly set capture on |widget2|. @@ -1940,17 +1920,9 @@ #endif // !OS_CHROMEOS TEST_F(WidgetTest, WidgetDeleted_InOnMousePressed) { - // This test doesn't work in mus as it assumes widget and GetContext() - // share an aura hierarchy. Test coverage of deletion from mouse pressed is - // important though and should be added, hence the NOTIMPLEMENTED(). - // http://crbug.com/594260. - if (IsMus()) { - NOTIMPLEMENTED(); - return; - } // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; Widget* widget = new Widget; @@ -1976,12 +1948,9 @@ #if !defined(OS_MACOSX) || defined(USE_AURA) TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) { - // This test doesn't make sense for mus. - if (IsMus()) - return; // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; Widget* widget = new Widget; @@ -2212,7 +2181,7 @@ TEST_F(WidgetTest, NoCrashOnWidgetDeleteWithPendingEvents) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; std::unique_ptr<Widget> widget(new Widget); @@ -3257,7 +3226,7 @@ TEST_F(WidgetTest, MouseEventTypesViaGenerator) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; EventCountView* view = new EventCountView; @@ -3534,11 +3503,6 @@ // Test that SetAlwaysOnTop and IsAlwaysOnTop are consistent. TEST_F(WidgetTest, AlwaysOnTop) { - if (IsMus()) { - NOTIMPLEMENTED(); - return; - } - WidgetAutoclosePtr widget(CreateTopLevelNativeWidget()); EXPECT_FALSE(widget->IsAlwaysOnTop()); widget->SetAlwaysOnTop(true); @@ -3573,7 +3537,7 @@ TEST_F(WidgetTest, OnDeviceScaleFactorChanged) { // This relies on the NativeWidget being the WindowDelegate, which is not the // case for aura-mus-client. - if (IsAuraMusClient()) + if (IsMus()) return; // Automatically close the widget, but not delete it. @@ -3683,7 +3647,7 @@ TEST_F(WidgetTest, MouseWheelEvent) { // TODO: test uses GetContext(), which is not applicable to aura-mus. // http://crbug.com/663809. - if (IsAuraMusClient()) + if (IsMus()) return; WidgetAutoclosePtr widget(CreateTopLevelPlatformWidget()); @@ -3725,9 +3689,6 @@ // under the currently active modal top-level window. In this instance, the // remaining top-level windows should be re-enabled. TEST_F(WidgetTest, WindowModalOwnerDestroyedEnabledTest) { - // Modality etc. are controlled by mus. - if (IsMus()) - return; // top_level_widget owns owner_dialog_widget which owns owned_dialog_widget. Widget top_level_widget; Widget owner_dialog_widget; @@ -3849,9 +3810,8 @@ InitializeWidgetForOpacity(widget, CreateParams(widget_type), opacity); // Use NativeWidgetAura directly. - if (IsMus() && - (widget_type == Widget::InitParams::TYPE_WINDOW_FRAMELESS || - widget_type == Widget::InitParams::TYPE_CONTROL)) + if (widget_type == Widget::InitParams::TYPE_WINDOW_FRAMELESS || + widget_type == Widget::InitParams::TYPE_CONTROL) continue; #if defined(OS_MACOSX) @@ -3869,11 +3829,6 @@ EXPECT_EQ(IsNativeWindowTransparent(widget.GetNativeWindow()), should_be_transparent); - // When using the Mandoline UI Service, the translucency does not rely on - // the widget type. - if (IsMus()) - continue; - #if defined(USE_X11) if (HasCompositingManager() && (widget_type == Widget::InitParams::TYPE_DRAG ||
diff --git a/ui/views/window/custom_frame_view.cc b/ui/views/window/custom_frame_view.cc index fe392518..bac98a41 100644 --- a/ui/views/window/custom_frame_view.cc +++ b/ui/views/window/custom_frame_view.cc
@@ -207,6 +207,13 @@ LayoutWindowControls(); } +void CustomFrameView::ActivationChanged(bool active) { + if (active_ == active) + return; + active_ = active; + SchedulePaint(); +} + /////////////////////////////////////////////////////////////////////////////// // CustomFrameView, View overrides:
diff --git a/ui/views/window/custom_frame_view.h b/ui/views/window/custom_frame_view.h index 8869bef..76d4fc26 100644 --- a/ui/views/window/custom_frame_view.h +++ b/ui/views/window/custom_frame_view.h
@@ -46,6 +46,7 @@ void UpdateWindowIcon() override; void UpdateWindowTitle() override; void SizeConstraintsChanged() override; + void ActivationChanged(bool active) override; // Overridden from View: void OnPaint(gfx::Canvas* canvas) override; @@ -152,6 +153,10 @@ int minimum_title_bar_x_; int maximum_title_bar_x_; + // True if the frame containing this frameview is currently active. Updated in + // ActivationChanged(). + bool active_ = false; + DISALLOW_COPY_AND_ASSIGN(CustomFrameView); };