diff --git a/DEPS b/DEPS index b43f0bd..f4313835 100644 --- a/DEPS +++ b/DEPS
@@ -115,11 +115,11 @@ # 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': '32def82f1247ccf4121345390e4a73c4b2273bd7', + 'skia_revision': '90295c73d0c1f10159d2c413212fa2d1944de3a2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '5f69146b2adcf279e719a4c86722c8ae4e666bfd', + 'v8_revision': '6b92d64803513155302b4178e8a4c09cc87d797f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -127,7 +127,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '4622905b30d17428ece05c4d6f86e2b11e9ff217', + 'angle_revision': '5a8d0bc2884bd97e572b34fb291be399a6c1beae', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -139,7 +139,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': 'a0c36804be26e4e41bd058123b7a594bb0bb836f', + 'pdfium_revision': '902c20e39cc2a6bc29c100283723d87a1a05785a', # 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. @@ -239,7 +239,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '0d95887dbc948adc317959efd1639520b32b9b11', + 'dawn_revision': '63220100145f1e1e78b4a2aaad8c014e5cc1af00', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -662,7 +662,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '1b63735bf490b1c2d5a3e990dd2059b4ff76d3f3', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '9097c295730dd2af26f81994ebad0d2c601af49f', 'condition': 'checkout_linux', }, @@ -687,7 +687,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '27c6e44188fbaf6a7a34a070e07a2b61ab569fd7', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a1e4d48a104af8e96b34eaa436138920f029469c', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1019,7 +1019,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '76717a36d3128515aefdb26c135fe951a2e85e48', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '035dc2822cf93f7ead83ac349db49f9ad0c4f13a', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1182,7 +1182,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '5b6cbd789b9b91b4e46dde883c9f2ecb31eddade', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '194d4d20fbf9e4fbd9c673e7ec9e926abce7b685', + Var('webrtc_git') + '/src.git' + '@' + '73f2da9fa7cdb9ed03095c8c815d40b1aad3618d', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1213,7 +1213,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b5c6e3aa4f146ece00fd470a6ad9929159d6fee1', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@43f0daabd71360201b00e2e026ff75339ffc91e0', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/cookie_manager.cc b/android_webview/browser/cookie_manager.cc index 6429bbb..cbdf1d7ed 100644 --- a/android_webview/browser/cookie_manager.cc +++ b/android_webview/browser/cookie_manager.cc
@@ -389,6 +389,8 @@ base::OnceClosure complete) { net::CookieOptions options; options.set_include_httponly(); + options.set_same_site_cookie_mode( + net::CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX); GetCookieStore()->GetCookieListWithOptionsAsync( host, options,
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java index f6dd08c..88adeae5 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java
@@ -123,6 +123,32 @@ } } + @Test + @MediumTest + @Feature({"AndroidWebView"}) + public void testEmbedderCanSeeRestrictedCookies() throws Throwable { + TestWebServer webServer = TestWebServer.start(); + try { + // Set a cookie with the httponly flag, one with samesite=Strict, and one with + // samesite=Lax, to ensure that they are all visible to CookieManager in the app. + String cookies[] = {"httponly=foo1; HttpOnly", "strictsamesite=foo2; SameSite=Strict", + "laxsamesite=foo3; SameSite=Lax"}; + List<Pair<String, String>> responseHeaders = new ArrayList<Pair<String, String>>(); + for (String cookie : cookies) { + responseHeaders.add(Pair.create("Set-Cookie", cookie)); + } + String url = webServer.setResponse("/", "test", responseHeaders); + mActivityTestRule.loadUrlSync( + mAwContents, mContentsClient.getOnPageFinishedHelper(), url); + waitForCookie(url); + String cookie = mCookieManager.getCookie(url); + Assert.assertNotNull(cookie); + validateCookies(cookie, "httponly", "strictsamesite", "laxsamesite"); + } finally { + webServer.shutdown(); + } + } + private void setCookieWithJavaScript(final String name, final String value) throws Throwable { JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(), @@ -807,7 +833,7 @@ foundCookieNames.add(cookie.substring(0, cookie.indexOf("=")).trim()); } List<String> expectedCookieNamesList = Arrays.asList(expectedCookieNames); - Assert.assertEquals(foundCookieNames.size(), expectedCookieNamesList.size()); + Assert.assertEquals(expectedCookieNamesList.size(), foundCookieNames.size()); Assert.assertTrue(foundCookieNames.containsAll(expectedCookieNamesList)); }
diff --git a/apps/launcher.cc b/apps/launcher.cc index aeb55f7..4d19f8f 100644 --- a/apps/launcher.cc +++ b/apps/launcher.cc
@@ -304,25 +304,28 @@ ExtensionHost* const host = process_manager->GetBackgroundHostForExtension(extension_id); DCHECK(host); - GrantAccessToFilesAndLaunch(host); + GrantAccessToFilesAndLaunch( + std::make_unique<extensions::LazyContextTaskQueue::ContextInfo>(host)); } - void GrantAccessToFilesAndLaunch(ExtensionHost* host) { + void GrantAccessToFilesAndLaunch( + std::unique_ptr<extensions::LazyContextTaskQueue::ContextInfo> + context_info) { const Extension* app = GetExtension(); if (!app) return; - // If there was an error loading the app page, |host| will be NULL. - if (!host) { + // If there was an error loading the app page, |context_info| will be NULL. + if (!context_info) { LOG(ERROR) << "Could not load app page for " << extension_id; return; } std::vector<GrantedFileEntry> granted_entries; for (size_t i = 0; i < entry_paths_.size(); ++i) { - granted_entries.push_back( - CreateFileEntry(context_, app, host->render_process_host()->GetID(), - entries_[i].path, entries_[i].is_directory)); + granted_entries.push_back(CreateFileEntry( + context_, app, context_info->render_process_host->GetID(), + entries_[i].path, entries_[i].is_directory)); } AppRuntimeEventRouter::DispatchOnLaunchedEventWithFileEntries(
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 95aade0..05c2f8504 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -929,11 +929,11 @@ return; } - // Scroll begin events should not be passed to ancestor views if it occurs - // inside the folder bounds even it is not handled. This prevents user from - // closing the folder when scrolling inside it. + // Scroll begin events should not be passed to ancestor views from apps grid + // in our current design. This prevents both ignoring horizontal scrolls in + // app list, and closing open folders. if (pagination_controller_->OnGestureEvent(*event, GetContentsBounds()) || - (folder_delegate_ && event->type() == ui::ET_GESTURE_SCROLL_BEGIN)) { + event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { event->SetHandled(); } }
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index 50826b06..523ec55 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -277,6 +277,45 @@ *actual_icon.bitmap())); } +class SearchBoxViewAssistantButtonTest : public SearchBoxViewTest { + public: + SearchBoxViewAssistantButtonTest() = default; + ~SearchBoxViewAssistantButtonTest() override = default; + + // Overridden from testing::Test + void SetUp() override { + SearchBoxViewTest::SetUp(); + view_delegate()->GetSearchModel()->search_box()->SetShowAssistantButton( + true); + } + + private: + DISALLOW_COPY_AND_ASSIGN(SearchBoxViewAssistantButtonTest); +}; + +// Tests that the assistant button is visible by default. +TEST_F(SearchBoxViewAssistantButtonTest, AssistantButtonVisibleByDefault) { + EXPECT_TRUE(view()->assistant_button()->visible()); +} + +// Tests that the assistant button is visible after the search box is activated. +TEST_F(SearchBoxViewAssistantButtonTest, + AssistantButtonVisibleAfterSearchBoxActived) { + SetSearchBoxActive(true, ui::ET_MOUSE_PRESSED); + EXPECT_TRUE(view()->assistant_button()->visible()); +} + +// Tests that the assistant button is invisible after typing in the search box, +// and comes back when search box is empty. +TEST_F(SearchBoxViewAssistantButtonTest, + AssistantButtonChangeVisibilityWithTyping) { + KeyPress(ui::VKEY_A); + EXPECT_FALSE(view()->assistant_button()->visible()); + + KeyPress(ui::VKEY_BACK); + EXPECT_TRUE(view()->assistant_button()->visible()); +} + class SearchBoxViewAutocompleteTest : public SearchBoxViewTest, public ::testing::WithParamInterface<ui::KeyboardCode> {
diff --git a/ash/media/media_notification_controller.cc b/ash/media/media_notification_controller.cc index 2be1af50..7d90410 100644 --- a/ash/media/media_notification_controller.cc +++ b/ash/media/media_notification_controller.cc
@@ -169,6 +169,9 @@ case MediaSessionAction::kNextTrack: media_controller_ptr_->NextTrack(); break; + case MediaSessionAction::kStop: + media_controller_ptr_->Stop(); + break; } }
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 3f75a8f7..da2faa0 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -821,8 +821,7 @@ // If user session is blocked (login to new user session or add user to // the existing session - multi-profile) then give 100% of work area only // if keyboard is not shown. - if (!state_.IsAddingSecondaryUser() || - !keyboard_displaced_bounds_.IsEmpty()) + if (!state_.IsAddingSecondaryUser() || IsKeyboardShown()) insets = target_bounds.work_area_insets; Shell::Get()->SetDisplayWorkAreaInsets(shelf_widget_->GetNativeWindow(), insets); @@ -842,6 +841,10 @@ status_widget->Show(); } +bool ShelfLayoutManager::IsKeyboardShown() const { + return !keyboard_displaced_bounds_.IsEmpty(); +} + void ShelfLayoutManager::StopAnimating() { GetLayer(shelf_widget_)->GetAnimator()->StopAnimating(); GetLayer(shelf_widget_->status_area_widget())->GetAnimator()->StopAnimating(); @@ -856,8 +859,7 @@ if (state.visibility_state == SHELF_AUTO_HIDE && state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) { shelf_in_screen_portion = kHiddenShelfInScreenPortion; - } else if (state.visibility_state == SHELF_HIDDEN || - !keyboard_displaced_bounds_.IsEmpty()) { + } else if (state.visibility_state == SHELF_HIDDEN || IsKeyboardShown()) { shelf_in_screen_portion = 0; } @@ -1170,6 +1172,11 @@ } int ShelfLayoutManager::GetWorkAreaInsets(const State& state, int size) const { + // The virtual keyboard always hides the shelf (in any orientation). + // Therefore, if the keyboard is shown, there is no need to reduce the work + // area by the size of the shelf. + if (IsKeyboardShown()) + return 0; if (state.visibility_state == SHELF_VISIBLE) return size; return 0;
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index a31e7b7..6771403 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -286,6 +286,9 @@ bool animate, ui::ImplicitAnimationObserver* observer); + // Returns whether the virtual keyboard is currently being shown. + bool IsKeyboardShown() const; + // Stops any animations and progresses them to the end. void StopAnimating();
diff --git a/ash/wm/pip/pip_positioner_unittest.cc b/ash/wm/pip/pip_positioner_unittest.cc index 8d7147f..ae4d2263 100644 --- a/ash/wm/pip/pip_positioner_unittest.cc +++ b/ash/wm/pip/pip_positioner_unittest.cc
@@ -8,7 +8,6 @@ #include <string> #include <vector> -#include "ash/shelf/shelf_constants.h" #include "ash/shell.h" #include "ash/system/unified/unified_system_tray.h" #include "ash/test/ash_test_base.h" @@ -115,7 +114,7 @@ ASSERT_TRUE(keyboard::WaitUntilShown()); gfx::Rect area = PipPositioner::GetMovementArea(window_state()->GetDisplay()); - EXPECT_EQ(gfx::Rect(8, 8, 384, 284 - ShelfConstants::shelf_size()), area); + EXPECT_EQ(gfx::Rect(8, 8, 384, 284), area); } TEST_F(PipPositionerTest, PipRestingPositionSnapsToClosestEdge) {
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc index cc83d3f..99e1efbd 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -238,6 +238,9 @@ main_thread_only().task_execution_allowed = false; TRACE_TASK_EXECUTION("ThreadController::Task", *task); + // Trace-parsing tools (Lighthouse, etc) consume this event to determine + // long tasks. See https://crbug.com/874982 + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("lighthouse"), "RunTask"); task_annotator_.RunTask("ThreadController::Task", &*task); task_ran = true;
diff --git a/base/threading/thread_local_storage_unittest.cc b/base/threading/thread_local_storage_unittest.cc index f07a520..681163c 100644 --- a/base/threading/thread_local_storage_unittest.cc +++ b/base/threading/thread_local_storage_unittest.cc
@@ -210,9 +210,6 @@ // in after the last destructor invocation, therefore the destructor remains // unsynchronized with the following users of the same TSD slot. This results // in race reports between the destructor and functions in other tests. -// -// It is disabled on Win x64 with incremental linking (i.e. "Debug") pending -// resolution of http://crbug.com/251251. #define MAYBE_TLSDestructors DISABLED_TLSDestructors #else #define MAYBE_TLSDestructors TLSDestructors
diff --git a/build/android/gradle/root.jinja b/build/android/gradle/root.jinja index 267070f4..715918ab 100644 --- a/build/android/gradle/root.jinja +++ b/build/android/gradle/root.jinja
@@ -10,7 +10,7 @@ } dependencies { {% if channel == 'canary' %} - classpath "com.android.tools.build:gradle:3.4.0-alpha03" + classpath "com.android.tools.build:gradle:3.4.0-alpha08" {% elif channel == 'beta' %} classpath "com.android.tools.build:gradle:3.1.0-beta4" {% else %}
diff --git a/build/chromeos/create_vm_test_script.py b/build/chromeos/create_test_runner_script.py similarity index 91% rename from build/chromeos/create_vm_test_script.py rename to build/chromeos/create_test_runner_script.py index b6ae3ad..3c26924a 100755 --- a/build/chromeos/create_vm_test_script.py +++ b/build/chromeos/create_test_runner_script.py
@@ -5,7 +5,7 @@ # found in the LICENSE file. """Creates a script that runs a CrOS VM test by delegating to -build/chromeos/run_vm_test.py. +build/chromeos/test_runner.py. """ import argparse @@ -16,7 +16,7 @@ SCRIPT_TEMPLATE = """\ #!/usr/bin/env python # -# This file was generated by build/chromeos/create_vm_test_script.py +# This file was generated by build/chromeos/create_test_runner_script.py import os import sys @@ -50,6 +50,7 @@ parser.add_argument('--runtime-deps-path') parser.add_argument('--cros-cache') parser.add_argument('--board') + parser.add_argument('--use-vm', action='store_true') parser.add_argument('--deploy-chrome', action='store_true') parser.add_argument('--suite-name') parser.add_argument('--tast-conditional') @@ -60,12 +61,14 @@ return os.path.relpath(path, os.path.dirname(args.script_output_path)) run_test_path = RelativizePathToScript( - os.path.join(os.path.dirname(__file__), 'run_vm_test.py')) + os.path.join(os.path.dirname(__file__), 'test_runner.py')) vm_test_args = [ '--board', args.board, '-v', ] + if args.use_vm: + vm_test_args += ['--use-vm'] if args.test_exe: vm_test_args.extend([
diff --git a/build/chromeos/run_vm_test.py b/build/chromeos/test_runner.py similarity index 86% rename from build/chromeos/run_vm_test.py rename to build/chromeos/test_runner.py index 9d7a891..1e6ecf7 100755 --- a/build/chromeos/run_vm_test.py +++ b/build/chromeos/test_runner.py
@@ -11,6 +11,7 @@ import pipes import re import signal +import socket import sys import tempfile @@ -34,12 +35,16 @@ CHROMIUM_SRC_PATH, 'build', 'cros_cache')) CHROMITE_PATH = os.path.abspath(os.path.join( CHROMIUM_SRC_PATH, 'third_party', 'chromite')) -CROS_RUN_VM_TEST_PATH = os.path.abspath(os.path.join( - CHROMITE_PATH, 'bin', 'cros_run_vm_test')) +CROS_RUN_TEST_PATH = os.path.abspath(os.path.join( + CHROMITE_PATH, 'bin', 'cros_run_test')) # GN target that corresponds to the cros browser sanity test. SANITY_TEST_TARGET = 'cros_vm_sanity_test' +# This is a special hostname that resolves to a different DUT in the lab +# depending on which lab machine you're on. +LAB_DUT_HOSTNAME = 'variable_chromeos_device_hostname' + class TestFormatError(Exception): pass @@ -57,13 +62,21 @@ self._timeout = None self._vm_test_cmd = [ - CROS_RUN_VM_TEST_PATH, - '--start', + CROS_RUN_TEST_PATH, '--board', args.board, '--cache-dir', args.cros_cache, - # Don't persist any filesystem changes after the VM shutsdown. - '--copy-on-write', ] + if args.use_vm: + self._vm_test_cmd += [ + '--start', + # Don't persist any filesystem changes after the VM shutsdown. + '--copy-on-write', + '--device', 'localhost' + ] + else: + self._vm_test_cmd += [ + '--device', args.device if args.device else LAB_DUT_HOSTNAME + ] if args.vm_logs_dir: self._vm_test_cmd += [ '--results-src', '/var/log/', @@ -408,13 +421,21 @@ '--path-to-outdir must be specified if --deploy-chrome is passed.') cros_run_vm_test_cmd = [ - CROS_RUN_VM_TEST_PATH, - '--start', + CROS_RUN_TEST_PATH, '--board', args.board, '--cache-dir', args.cros_cache, - # Don't persist any filesystem changes after the VM shutsdown. - '--copy-on-write', ] + if args.use_vm: + cros_run_vm_test_cmd += [ + '--start', + # Don't persist any filesystem changes after the VM shutsdown. + '--copy-on-write', + '--device', 'localhost', + ] + else: + cros_run_vm_test_cmd += [ + '--device', args.device if args.device else LAB_DUT_HOSTNAME + ] if args.verbose: cros_run_vm_test_cmd.append('--debug') @@ -456,27 +477,27 @@ def add_common_args(parser): - parser.add_argument( - '--cros-cache', type=str, default=DEFAULT_CROS_CACHE, - help='Path to cros cache.') - parser.add_argument( - '--path-to-outdir', type=str, required=True, - help='Path to output directory, all of whose contents will be ' - 'deployed to the device.') - parser.add_argument( - '--runtime-deps-path', type=str, - help='Runtime data dependency file from GN.') - parser.add_argument( - '--vpython-dir', type=str, - help='Location on host of a directory containing a vpython binary to ' - 'deploy to the VM before the test starts. The location of this ' - 'dir will be added onto PATH in the VM. WARNING: The arch of the ' - 'VM might not match the arch of the host, so avoid using ' - '"${platform}" when downloading vpython via CIPD.') - parser.add_argument( - '--vm-logs-dir', type=str, - help='Will copy everything under /var/log/ from the VM after the test ' - 'into the specified dir.') + parser.add_argument( + '--cros-cache', type=str, default=DEFAULT_CROS_CACHE, + help='Path to cros cache.') + parser.add_argument( + '--path-to-outdir', type=str, required=True, + help='Path to output directory, all of whose contents will be ' + 'deployed to the device.') + parser.add_argument( + '--runtime-deps-path', type=str, + help='Runtime data dependency file from GN.') + parser.add_argument( + '--vpython-dir', type=str, + help='Location on host of a directory containing a vpython binary to ' + 'deploy to the VM before the test starts. The location of this ' + 'dir will be added onto PATH in the VM. WARNING: The arch of the ' + 'VM might not match the arch of the host, so avoid using ' + '"${platform}" when downloading vpython via CIPD.') + parser.add_argument( + '--vm-logs-dir', type=str, + help='Will copy everything under /var/log/ from the VM after the test ' + 'into the specified dir.') def main(): @@ -485,6 +506,14 @@ # Required args. parser.add_argument( '--board', type=str, required=True, help='Type of CrOS device.') + vm_or_device_group = parser.add_mutually_exclusive_group() + vm_or_device_group.add_argument( + '--use-vm', action='store_true', + help='Will run the test in the VM instead of a device.') + vm_or_device_group.add_argument( + '--device', type=str, + help='Hostname (or IP) of device to run the test on. This arg is not ' + 'required if --use-vm is set.') subparsers = parser.add_subparsers(dest='test_type') # Host-side test args. host_cmd_parser = subparsers.add_parser( @@ -562,13 +591,26 @@ logging.basicConfig(level=logging.DEBUG if args.verbose else logging.WARN) - if not os.path.exists('/dev/kvm'): - logging.error('/dev/kvm is missing. Is KVM installed on this machine?') - return 1 - elif not os.access('/dev/kvm', os.W_OK): - logging.error( - '/dev/kvm is not writable as current user. Perhaps you should be root?') - return 1 + if not args.use_vm and not args.device: + # If we're not running on a VM, but haven't specified a hostname, assume + # we're on a lab bot and are trying to run a test on a lab DUT. See if the + # magic lab DUT hostname resolves to anything. (It will in the lab and will + # not on dev machines.) + try: + socket.getaddrinfo(LAB_DUT_HOSTNAME, None) + except socket.gaierror: + logging.error( + 'The default DUT hostname of %s is unreachable.', LAB_DUT_HOSTNAME) + return 1 + if args.use_vm: + if not os.path.exists('/dev/kvm'): + logging.error('/dev/kvm is missing. Is KVM installed on this machine?') + return 1 + elif not os.access('/dev/kvm', os.W_OK): + logging.error( + '/dev/kvm is not writable as current user. Perhaps you should be ' + 'root?') + return 1 args.cros_cache = os.path.abspath(args.cros_cache) return args.func(args, unknown_args)
diff --git a/build/config/chromeos/rules.gni b/build/config/chromeos/rules.gni index 802f335..2b93ddd 100644 --- a/build/config/chromeos/rules.gni +++ b/build/config/chromeos/rules.gni
@@ -8,6 +8,11 @@ cros_board = "" cros_sdk_version = "" } +declare_args() { + # Determines if we're running tests on VMs or on devices. + # TODO(crbug.com/866062): Is there a better way to do this? + cros_is_vm = cros_board == "amd64-generic" +} # Ensure that if one is set, the other is as well. assert(cros_board == "" == (cros_sdk_version == "")) @@ -36,13 +41,7 @@ # build dir to the VM after launching it. # runtime_deps_file: Path to file listing runtime deps for the test. If set, # all files listed will be copied to the VM before testing. -template("generate_vm_runner_script") { - _cache_path_prefix = - "//build/cros_cache/chrome-sdk/tarballs/${cros_board}+${cros_sdk_version}" - _vm_image_path = "${_cache_path_prefix}+chromiumos_qemu_image.tar.xz/" - _qemu_dir = "${_cache_path_prefix}+app-emulation/" - _firmware_dir = "${_cache_path_prefix}+sys-firmware/" - +template("generate_runner_script") { forward_variables_from(invoker, [ "deploy_chrome", @@ -57,6 +56,12 @@ deploy_chrome = false } + # These are the only 2 conditions when ${_cache_path_prefix} is used, so + # initialize it in a conditional. + if (deploy_chrome || cros_is_vm) { + _cache_path_prefix = "//build/cros_cache/chrome-sdk/tarballs/${cros_board}+${cros_sdk_version}" + } + assert(defined(generated_script), "Must specify where to place generated test launcher script via " + "'generated_script'") @@ -69,7 +74,7 @@ if (defined(runtime_deps_file)) { write_runtime_deps = runtime_deps_file } - script = "//build/chromeos/create_vm_test_script.py" + script = "//build/chromeos/create_test_runner_script.py" outputs = [ generated_script, @@ -99,10 +104,20 @@ # as data here so that changes to it will trigger analyze. "//chromeos/CHROMEOS_LKGM", "//third_party/chromite/", - _firmware_dir, - _vm_image_path, - _qemu_dir, ] + + # Add the VM/QEMU-launching bits if needed. + if (cros_is_vm) { + assert(defined(_cache_path_prefix)) + _vm_image_path = "${_cache_path_prefix}+chromiumos_qemu_image.tar.xz/" + _qemu_dir = "${_cache_path_prefix}+app-emulation/" + _firmware_dir = "${_cache_path_prefix}+sys-firmware/" + data += [ + _firmware_dir, + _vm_image_path, + _qemu_dir, + ] + } if (defined(invoker.data)) { deps += invoker.data } @@ -123,17 +138,25 @@ rebase_path(root_out_dir, root_build_dir), ] + if (cros_is_vm) { + args += [ "--use-vm" ] + } + if (deploy_chrome) { args += [ "--deploy-chrome" ] # To deploy chrome to the VM, it needs to be stripped down to fit into # the VM. This is done by using binutils in the toolchain. So add the # toolchain to the data. - data += [ "${_cache_path_prefix}+target_toolchain/" ] + assert(defined(_cache_path_prefix)) + data += [ + "${_cache_path_prefix}+environment_chromeos-base_chromeos-chrome.tar.xz", + "${_cache_path_prefix}+target_toolchain/", + ] } - # When --test-exe is specified, run_vm_test will push the exe to the VM and - # execute it. Otherwise it wraps a host-side command and just takes care + # When --test-exe is specified, test_runner.py will push the exe to the VM + # and execute it. Otherwise it wraps a host-side command and just takes care # launching & tearing-down the VM. if (defined(test_exe)) { args += [ @@ -147,8 +170,8 @@ ] } } else if (is_tast) { - # When --tast-tests is specified, run_vm_test will call local_test_runner - # on the VM to run the set of tests. + # When --tast-tests is specified, test_runner.py will call + # local_test_runner on the VM to run the set of tests. args += [ "--suite-name", target_name, @@ -174,7 +197,7 @@ assert(defined(invoker.tast_conditional) != defined(invoker.tast_tests), "Specify one of tast_tests or tast_conditional.") - generate_vm_runner_script(target_name) { + generate_runner_script(target_name) { testonly = true if (defined(invoker.tast_conditional)) { tast_conditional = invoker.tast_conditional
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index e57c350..e48c752 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -5639aa6b5daf5c85a77d65dc2918efaa5b91ca51 \ No newline at end of file +8c4293109de788c6d6e5f0a38a5cb1d483b248ca \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 11db295..e7260e0 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -61812e02a3d4422192b1749ddd912ad6be0f3e72 \ No newline at end of file +6ea74c6cbd247edc7bd2e68b44ebf8c5b95e9f46 \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java index 42614def..59e6dd41 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java
@@ -178,5 +178,5 @@ * * @param unfocusedWidth The unfocused location bar width. */ - void setUnfocusedWidth(float unfocusedWidth); + void setUnfocusedWidth(int unfocusedWidth); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index f8617bd6..2d1303d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -975,7 +975,7 @@ } @Override - public void setUnfocusedWidth(float unfocusedWidth) { + public void setUnfocusedWidth(int unfocusedWidth) { mStatusViewCoordinator.setUnfocusedLocationBarWidth(unfocusedWidth); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java index 16c67c0..7813689b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
@@ -4,6 +4,10 @@ package org.chromium.chrome.browser.omnibox.status; +import android.support.annotation.ColorRes; +import android.support.annotation.StringRes; + +import org.chromium.chrome.R; import org.chromium.chrome.browser.modelutil.PropertyModel; import org.chromium.chrome.browser.omnibox.status.StatusView.NavigationButtonType; @@ -12,6 +16,16 @@ */ class StatusMediator { private final PropertyModel mModel; + private boolean mDarkTheme; + private boolean mUrlHasFocus; + private boolean mVerboseStatusAllowed; + private boolean mVerboseStatusSpaceAvailable; + private boolean mPageIsPreview; + private boolean mPageIsOffline; + + private int mUrlMinWidth; + private int mSeparatorMinWidth; + private int mVerboseStatusTextMinWidth; public StatusMediator(PropertyModel model) { mModel = model; @@ -28,20 +42,147 @@ * Specify whether displayed page is an offline page. */ public void setPageIsOffline(boolean pageIsOffline) { - mModel.set(StatusProperties.PAGE_IS_OFFLINE, pageIsOffline); + if (mPageIsOffline != pageIsOffline) { + mPageIsOffline = pageIsOffline; + updateStatusVisibility(); + updateColorTheme(); + } } /** * Specify whether displayed page is a preview page. */ public void setPageIsPreview(boolean pageIsPreview) { - mModel.set(StatusProperties.PAGE_IS_PREVIEW, pageIsPreview); + if (mPageIsPreview != pageIsPreview) { + mPageIsPreview = pageIsPreview; + updateStatusVisibility(); + updateColorTheme(); + } + } + + /** + + /** + * Specify minimum width of the separator field. + */ + public void setSeparatorFieldMinWidth(int width) { + mSeparatorMinWidth = width; + } + + /** + * Update unfocused location bar width to determine shape and content of the + * Status view. + */ + public void setUnfocusedLocationBarWidth(int width) { + // This unfocused width is used rather than observing #onMeasure() to avoid showing the + // verbose status when the animation to unfocus the URL bar has finished. There is a call to + // LocationBarLayout#onMeasure() after the URL focus animation has finished and before the + // location bar has received its updated width layout param. + int computedSpace = width - mUrlMinWidth - mSeparatorMinWidth; + boolean hasSpaceForStatus = width >= mVerboseStatusTextMinWidth; + + if (hasSpaceForStatus) { + mModel.set(StatusProperties.VERBOSE_STATUS_TEXT_WIDTH, computedSpace); + } + + if (hasSpaceForStatus != mVerboseStatusSpaceAvailable) { + mVerboseStatusSpaceAvailable = hasSpaceForStatus; + updateStatusVisibility(); + } + } + + /** + * Report URL focus change. + */ + public void setUrlHasFocus(boolean urlHasFocus) { + mUrlHasFocus = urlHasFocus; + updateStatusVisibility(); + } + + /** + * Specify minimum width of an URL field. + */ + public void setUrlMinWidth(int width) { + mUrlMinWidth = width; } /** * Toggle between dark and light UI color theme. */ public void setUseDarkColors(boolean useDarkColors) { - mModel.set(StatusProperties.USE_DARK_COLORS, useDarkColors); + if (mDarkTheme != useDarkColors) { + mDarkTheme = useDarkColors; + updateColorTheme(); + } + } + + /** + * Specify whether parent allows verbose status text. + */ + public void setVerboseStatusTextAllowed(boolean isVerboseStatusTextAllowed) { + mVerboseStatusAllowed = isVerboseStatusTextAllowed; + updateStatusVisibility(); + } + + /** + * Specify minimum width of the verbose status text field. + */ + public void setVerboseStatusTextMinWidth(int width) { + mVerboseStatusTextMinWidth = width; + } + + /** + * Update visibility of the verbose status text field. + */ + private void updateStatusVisibility() { + @StringRes + int statusText = 0; + + if (mPageIsPreview) { + statusText = R.string.location_bar_preview_lite_page_status; + } else if (mPageIsOffline) { + statusText = R.string.location_bar_verbose_status_offline; + } + + // Decide whether presenting verbose status text makes sense. + boolean newVisibility = mVerboseStatusAllowed && mVerboseStatusSpaceAvailable + && (!mUrlHasFocus) && (statusText != 0); + + // Update status content only if it is visible. + // Note: PropertyModel will help us avoid duplicate updates with the + // same value. + if (newVisibility) { + mModel.set(StatusProperties.VERBOSE_STATUS_TEXT_STRING_RES, statusText); + } + + mModel.set(StatusProperties.VERBOSE_STATUS_TEXT_VISIBLE, newVisibility); + } + + /** + * Update color theme for all status components. + */ + private void updateColorTheme() { + @ColorRes + int separatorColor = mDarkTheme ? R.color.locationbar_status_separator_color + : R.color.locationbar_status_separator_color_light; + + @ColorRes + int textColor = 0; + if (mPageIsPreview) { + // There will never be a Preview in Incognito and the site theme color is not used. So + // ignore useDarkColors. + textColor = R.color.locationbar_status_preview_color; + } else if (mPageIsOffline) { + textColor = mDarkTheme ? R.color.locationbar_status_offline_color + : R.color.locationbar_status_offline_color_light; + } + + @ColorRes + int tintColor = mDarkTheme ? R.color.dark_mode_tint : R.color.light_mode_tint; + + mModel.set(StatusProperties.ICON_TINT_COLOR_RES, tintColor); + mModel.set(StatusProperties.SEPARATOR_COLOR_RES, separatorColor); + + if (textColor != 0) mModel.set(StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES, textColor); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java index 002bf081..98171d7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java
@@ -12,24 +12,35 @@ * Model for the Status view. */ class StatusProperties { + /** Specifies status icon tint color. */ + public static final WritableIntPropertyKey ICON_TINT_COLOR_RES = new WritableIntPropertyKey(); + /** Specifies navigation button type (eg: PAGE, MAGNIFIER) */ public static final WritableIntPropertyKey NAVIGATION_BUTTON_TYPE = new WritableIntPropertyKey(); - /** Specifies whether presented page is an offline page. */ - public static final WritableBooleanPropertyKey PAGE_IS_OFFLINE = + /** Specifies status separator color. */ + public static final WritableIntPropertyKey SEPARATOR_COLOR_RES = new WritableIntPropertyKey(); + + /** Specifies verbose status text color. */ + public static final WritableIntPropertyKey VERBOSE_STATUS_TEXT_COLOR_RES = + new WritableIntPropertyKey(); + + /** Specifies content of the verbose status text field. */ + public static final WritableIntPropertyKey VERBOSE_STATUS_TEXT_STRING_RES = + new WritableIntPropertyKey(); + + /** Specifies whether verbose status text view is visible. */ + public static final WritableBooleanPropertyKey VERBOSE_STATUS_TEXT_VISIBLE = new WritableBooleanPropertyKey(); - /** Specifies whether page is shown as a preview. */ - public static final WritableBooleanPropertyKey PAGE_IS_PREVIEW = - new WritableBooleanPropertyKey(); + /** Specifies width of the verbose status text view. */ + public static final WritableIntPropertyKey VERBOSE_STATUS_TEXT_WIDTH = + new WritableIntPropertyKey(); - /** Specifies whether dark colors should be used in the view. */ - public static final WritableBooleanPropertyKey USE_DARK_COLORS = - new WritableBooleanPropertyKey(); - - public static final PropertyKey[] ALL_KEYS = new PropertyKey[] { - NAVIGATION_BUTTON_TYPE, PAGE_IS_OFFLINE, PAGE_IS_PREVIEW, USE_DARK_COLORS}; + public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {ICON_TINT_COLOR_RES, + NAVIGATION_BUTTON_TYPE, SEPARATOR_COLOR_RES, VERBOSE_STATUS_TEXT_COLOR_RES, + VERBOSE_STATUS_TEXT_STRING_RES, VERBOSE_STATUS_TEXT_VISIBLE, VERBOSE_STATUS_TEXT_WIDTH}; private StatusProperties() {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java index cea69687..df4b47e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java
@@ -8,6 +8,7 @@ import android.graphics.drawable.Drawable; import android.support.annotation.ColorRes; import android.support.annotation.IntDef; +import android.support.annotation.StringRes; import android.util.AttributeSet; import android.view.View; import android.widget.ImageButton; @@ -15,6 +16,7 @@ import android.widget.LinearLayout; import android.widget.TextView; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import java.lang.annotation.Retention; @@ -39,10 +41,7 @@ private ImageButton mSecurityButton; private TextView mVerboseStatusTextView; private View mSeparatorView; - - public StatusView(Context context) { - super(context); - } + private View mStatusExtraSpace; public StatusView(Context context, AttributeSet attributes) { super(context, attributes); @@ -56,25 +55,58 @@ mSecurityButton = findViewById(R.id.security_button); mVerboseStatusTextView = findViewById(R.id.location_bar_verbose_status); mSeparatorView = findViewById(R.id.location_bar_verbose_status_separator); + mStatusExtraSpace = findViewById(R.id.location_bar_verbose_status_extra_space); assert mNavigationButton != null : "Missing navigation type view."; } /** - * Select visual style for Status view. - */ - public void updateVisualTheme(@ColorRes int textColor, @ColorRes int separatorColor) { - mVerboseStatusTextView.setTextColor(textColor); - mSeparatorView.setBackgroundColor(separatorColor); - } - - /** * Specify navigation button image. */ public void setNavigationIcon(Drawable image) { mNavigationButton.setImageDrawable(image); } + /** + * Select color of Separator view. + */ + public void setSeparatorColor(@ColorRes int separatorColor) { + mSeparatorView.setBackgroundColor( + ApiCompatibilityUtils.getColor(getResources(), separatorColor)); + } + + /** + * Select color of verbose status text. + */ + public void setVerboseStatusTextColor(@ColorRes int textColor) { + mVerboseStatusTextView.setTextColor( + ApiCompatibilityUtils.getColor(getResources(), textColor)); + } + + /** + * Specify content of the verbose status text. + */ + public void setVerboseStatusTextContent(@StringRes int content) { + mVerboseStatusTextView.setText(content); + } + + /** + * Specify visibility of the verbose status text. + */ + public void setVerboseStatusTextVisible(boolean visible) { + int visibility = visible ? View.VISIBLE : View.GONE; + mVerboseStatusTextView.setVisibility(visibility); + mSeparatorView.setVisibility(visibility); + mStatusExtraSpace.setVisibility(visibility); + } + + /** + * Specify width of the verbose status text. + */ + public void setVerboseStatusTextWidth(int width) { + mVerboseStatusTextView.setMaxWidth(width); + } + // TODO(ender): replace these with methods manipulating views directly. // Do not depend on these when creating new code! public ImageView getNavigationButton() { @@ -88,8 +120,4 @@ public TextView getVerboseStatusTextView() { return mVerboseStatusTextView; } - - public View getSeparatorView() { - return mSeparatorView; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java index dbe71a3..4c244739 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java
@@ -4,11 +4,9 @@ package org.chromium.chrome.browser.omnibox.status; -import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.support.annotation.ColorRes; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.modelutil.PropertyKey; import org.chromium.chrome.browser.modelutil.PropertyModel; @@ -24,61 +22,40 @@ @Override public void bind(PropertyModel model, StatusView view, PropertyKey propertyKey) { - if (StatusProperties.USE_DARK_COLORS.equals(propertyKey) - || StatusProperties.PAGE_IS_PREVIEW.equals(propertyKey) - || StatusProperties.PAGE_IS_OFFLINE.equals(propertyKey)) { - updateTextColors(view, model.get(StatusProperties.USE_DARK_COLORS), - model.get(StatusProperties.PAGE_IS_PREVIEW), - model.get(StatusProperties.PAGE_IS_OFFLINE)); + if (StatusProperties.NAVIGATION_BUTTON_TYPE.equals(propertyKey) + || StatusProperties.ICON_TINT_COLOR_RES.equals(propertyKey)) { updateNavigationButtonType(view, model.get(StatusProperties.NAVIGATION_BUTTON_TYPE), - model.get(StatusProperties.USE_DARK_COLORS)); - } else if (StatusProperties.NAVIGATION_BUTTON_TYPE.equals(propertyKey)) { - updateNavigationButtonType(view, model.get(StatusProperties.NAVIGATION_BUTTON_TYPE), - model.get(StatusProperties.USE_DARK_COLORS)); + model.get(StatusProperties.ICON_TINT_COLOR_RES)); + } else if (StatusProperties.SEPARATOR_COLOR_RES.equals(propertyKey)) { + view.setSeparatorColor(model.get(StatusProperties.SEPARATOR_COLOR_RES)); + } else if (StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES.equals(propertyKey)) { + view.setVerboseStatusTextColor( + model.get(StatusProperties.VERBOSE_STATUS_TEXT_COLOR_RES)); + } else if (StatusProperties.VERBOSE_STATUS_TEXT_STRING_RES.equals(propertyKey)) { + view.setVerboseStatusTextContent( + model.get(StatusProperties.VERBOSE_STATUS_TEXT_STRING_RES)); + } else if (StatusProperties.VERBOSE_STATUS_TEXT_VISIBLE.equals(propertyKey)) { + view.setVerboseStatusTextVisible( + model.get(StatusProperties.VERBOSE_STATUS_TEXT_VISIBLE)); + } else if (StatusProperties.VERBOSE_STATUS_TEXT_WIDTH.equals(propertyKey)) { + view.setVerboseStatusTextWidth(model.get(StatusProperties.VERBOSE_STATUS_TEXT_WIDTH)); } else { assert false : "Unhandled property update"; } } - private static void updateTextColors( - StatusView view, boolean useDarkColors, boolean pageIsPreview, boolean pageIsOffline) { - Resources res = view.getResources(); - - @ColorRes - int separatorColor = ApiCompatibilityUtils.getColor(res, - useDarkColors ? R.color.locationbar_status_separator_color - : R.color.locationbar_status_separator_color_light); - - @ColorRes - int textColor = 0; - if (pageIsPreview) { - // There will never be a Preview in Incognito and the site theme color is not used. So - // ignore useDarkColors. - textColor = - ApiCompatibilityUtils.getColor(res, R.color.locationbar_status_preview_color); - } else if (pageIsOffline) { - textColor = ApiCompatibilityUtils.getColor(res, - useDarkColors ? R.color.locationbar_status_offline_color - : R.color.locationbar_status_offline_color_light); - } - - view.updateVisualTheme(textColor, separatorColor); - } - private static void updateNavigationButtonType( - StatusView view, @NavigationButtonType int buttonType, boolean useDarkColors) { - @ColorRes - int tint = useDarkColors ? R.color.dark_mode_tint : R.color.light_mode_tint; + StatusView view, @NavigationButtonType int buttonType, @ColorRes int tintColor) { Drawable image = null; switch (buttonType) { case NavigationButtonType.PAGE: image = TintedDrawable.constructTintedDrawable( - view.getContext(), R.drawable.ic_omnibox_page, tint); + view.getContext(), R.drawable.ic_omnibox_page, tintColor); break; case NavigationButtonType.MAGNIFIER: image = TintedDrawable.constructTintedDrawable( - view.getContext(), R.drawable.omnibox_search, tint); + view.getContext(), R.drawable.omnibox_search, tintColor); break; case NavigationButtonType.EMPTY: break;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java index ec46cdfa..a97fc1bd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java
@@ -64,10 +64,6 @@ private final StatusView mStatusView; private final StatusMediator mMediator; - private final float mUrlMinWidth; - private final float mVerboseStatusMinWidth; - private final float mStatusSeparatorWidth; - private ToolbarDataProvider mToolbarDataProvider; private WindowAndroid mWindowAndroid; @@ -83,9 +79,6 @@ private AnimatorSet mNavigationIconShowAnimator; private boolean mUrlHasFocus; - private float mUnfocusedLocationBarWidth; - private int mVerboseStatusTextMaxWidth; - private boolean mHasSpaceForVerboseStatus; /** * Creates a new StatusViewCoordinator. @@ -99,10 +92,26 @@ mStatusView = statusView; mDelegate = delegate; - PropertyModel model = new PropertyModel(StatusProperties.ALL_KEYS); + PropertyModel model = new PropertyModel.Builder(StatusProperties.ALL_KEYS) + .with(StatusProperties.ICON_TINT_COLOR_RES, + R.color.locationbar_status_separator_color) + .build(); + PropertyModelChangeProcessor.create(model, mStatusView, new StatusViewBinder()); mMediator = new StatusMediator(model); + Resources res = mStatusView.getResources(); + mMediator.setUrlMinWidth(res.getDimensionPixelSize(R.dimen.location_bar_min_url_width) + + res.getDimensionPixelSize(R.dimen.location_bar_start_icon_width) + + (res.getDimensionPixelSize(R.dimen.location_bar_lateral_padding) * 2)); + + mMediator.setSeparatorFieldMinWidth( + res.getDimensionPixelSize(R.dimen.location_bar_status_separator_width) + + res.getDimensionPixelSize(R.dimen.location_bar_status_separator_spacer)); + + mMediator.setVerboseStatusTextMinWidth( + res.getDimensionPixelSize(R.dimen.location_bar_min_verbose_status_text_width)); + if (mIsTablet) { mMediator.setNavigationButtonType(NavigationButtonType.PAGE); } @@ -146,16 +155,6 @@ ObjectAnimator.ofFloat(mStatusView.getSecurityButton(), View.ALPHA, 0)); mNavigationIconShowAnimator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS); mNavigationIconShowAnimator.addListener(iconChangeAnimatorListener); - - Resources res = mStatusView.getResources(); - mUrlMinWidth = res.getDimensionPixelSize(R.dimen.location_bar_min_url_width) - + res.getDimensionPixelSize(R.dimen.location_bar_start_icon_width) - + (res.getDimensionPixelSize(R.dimen.location_bar_lateral_padding) * 2); - mStatusSeparatorWidth = - res.getDimensionPixelSize(R.dimen.location_bar_status_separator_width) - + res.getDimensionPixelSize(R.dimen.location_bar_status_separator_spacer); - mVerboseStatusMinWidth = mStatusSeparatorWidth - + res.getDimensionPixelSize(R.dimen.location_bar_min_verbose_status_text_width); } /** @@ -188,6 +187,7 @@ * @param urlHasFocus Whether the url currently has focus. */ public void onUrlFocusChange(boolean urlHasFocus) { + mMediator.setUrlHasFocus(urlHasFocus); mUrlHasFocus = urlHasFocus; changeLocationBarIcon(); updateVerboseStatusVisibility(); @@ -344,30 +344,9 @@ * omnibox. */ private void updateVerboseStatusVisibility() { - boolean verboseStatusVisible = !mUrlHasFocus - && mToolbarDataProvider.shouldShowVerboseStatus() && mHasSpaceForVerboseStatus; - - int verboseStatusVisibility = verboseStatusVisible ? View.VISIBLE : View.GONE; - - mStatusView.getVerboseStatusTextView().setVisibility(verboseStatusVisibility); - - View separator = mStatusView.findViewById(R.id.location_bar_verbose_status_separator); - separator.setVisibility(verboseStatusVisibility); - - mStatusView.findViewById(R.id.location_bar_verbose_status_extra_space) - .setVisibility(verboseStatusVisibility); - - if (!verboseStatusVisible) { - // Return early since everything past here requires the verbose status to be visible - // and able to be populated with content. - return; - } - - mStatusView.getVerboseStatusTextView().setText( - mToolbarDataProvider.getVerboseStatusString()); - // TODO(ender): turn around logic for ToolbarDataProvider to offer // notifications rather than polling for these attributes. + mMediator.setVerboseStatusTextAllowed(mToolbarDataProvider.shouldShowVerboseStatus()); mMediator.setPageIsOffline(mToolbarDataProvider.isOfflinePage()); mMediator.setPageIsPreview(mToolbarDataProvider.isPreview()); } @@ -412,33 +391,9 @@ /** * Called to set the width of the location bar when the url bar is not focused. * This value is used to determine whether the verbose status text should be visible. - * @param unfocusedWidth The unfocused location bar width. + * @param width The unfocused location bar width. */ - public void setUnfocusedLocationBarWidth(float unfocusedWidth) { - if (mUnfocusedLocationBarWidth == unfocusedWidth) return; - - // This unfocused with is used rather than observing #onMeasure() to avoid showing the - // verbose status when the animation to unfocus the URL bar has finished. There is a call to - // LocationBarLayout#onMeasure() after the URL focus animation has finished and before the - // location bar has received its updated width layout param. - mUnfocusedLocationBarWidth = unfocusedWidth; - - boolean previousHasSpace = mHasSpaceForVerboseStatus; - mHasSpaceForVerboseStatus = - mUnfocusedLocationBarWidth >= mUrlMinWidth + mVerboseStatusMinWidth; - - if (mHasSpaceForVerboseStatus) { - int previousMaxWidth = mVerboseStatusTextMaxWidth; - mVerboseStatusTextMaxWidth = - (int) (mUnfocusedLocationBarWidth - mUrlMinWidth - mStatusSeparatorWidth); - - // Skip setting the max width if it hasn't changed since TextView#setMaxWidth - // invalidates the view and requests a layout. - if (previousMaxWidth != mVerboseStatusTextMaxWidth) { - mStatusView.getVerboseStatusTextView().setMaxWidth(mVerboseStatusTextMaxWidth); - } - } - - if (previousHasSpace != mHasSpaceForVerboseStatus) updateVerboseStatusVisibility(); + public void setUnfocusedLocationBarWidth(int width) { + mMediator.setUnfocusedLocationBarWidth(width); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index ed059953..8db344ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -2483,13 +2483,16 @@ public void setTopControlsHeight(int height, boolean controlsResizeView) { float scale = getWindowAndroid().getDisplay().getDipScale(); - mTopControlsHeight = (int) (height / scale); + mTopControlsHeight = (int) Math.ceil(height / scale); mControlsResizeView = controlsResizeView; } public void setBottomControlsHeight(int height) { + // TODO(mdjones): We should use a single unit of measurement for tracking browser control + // height. Conversion to/from px and dp in various places causes complexity + // in logic and rounding errors. float scale = getWindowAndroid().getDisplay().getDipScale(); - mBottomControlsHeight = (int) (height / scale); + mBottomControlsHeight = (int) Math.ceil(height / scale); } int getTopControlsHeight() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java index b00698a9..4bed50a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java
@@ -101,21 +101,6 @@ int getSecurityIconResource(boolean isTablet); /** - * @return The resource ID of the display string for the verbose status view or 0 if none - * applies. - */ - @StringRes - default int getVerboseStatusString() { - if (isPreview()) { - return R.string.location_bar_preview_lite_page_status; - } - if (isOfflinePage()) { - return R.string.location_bar_verbose_status_offline; - } - return 0; - } - - /** * @return The resource ID of the content description for the security icon. */ @StringRes
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java index 8e33fc30..356eb9d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java
@@ -828,5 +828,5 @@ } @Override - public void setUnfocusedWidth(float unfocusedWidth) {} + public void setUnfocusedWidth(int unfocusedWidth) {} }
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index f864fb8..47907d1 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -46,7 +46,6 @@ #include "components/crash/content/app/crash_reporter_client.h" #include "components/crash/core/common/crash_key.h" #include "components/crash/core/common/crash_keys.h" -#include "components/gwp_asan/client/gwp_asan.h" #include "components/nacl/common/buildflags.h" #include "components/services/heap_profiling/public/cpp/allocator_shim.h" #include "components/services/heap_profiling/public/cpp/stream.h" @@ -78,6 +77,7 @@ #include "chrome/child/v8_crashpad_support_win.h" #include "chrome/common/child_process_logging.h" #include "chrome_elf/chrome_elf_main.h" +#include "components/gwp_asan/client/gwp_asan.h" // nogncheck #include "sandbox/win/src/sandbox.h" #include "ui/base/resource/resource_bundle_win.h" #endif
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 2013f4d..f7b03c1 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -829,7 +829,7 @@ <!-- User pod remove sync warning text --> <message name="IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC" desc="Main text shown as a warning when attempting to remove an user."> - This person's browsing data will be deleted from this device. To recover the data, sign in to Chromium as $2. + This person's browsing data will be deleted from this device. To recover the data, sign in to Chromium as <ph name="USER_EMAIL">$2<ex>foo@example.com</ex></ph>. </message> <!-- Tutorial -->
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index b7bcc95..6d773b1 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5535,7 +5535,7 @@ <message name="IDS_CHROME_CLEANUP_REBOOT_PROMPT_RESTART_BUTTON_LABEL" desc="A button in the Chrome Cleanup reboot prompt dialog. Clicking this button causes the user's computer to turn off (shut down) and turn back on again. Imperative."> Restart computer </message> - <message name="IDS_CHROME_CLEANUP_LOGS_PERMISSION" desc="A checkbox label, appearing on both the Chrome Cleanup modal dialog and webui page, asking the user for permission to send details about the cleanup operation to Google."> + <message name="IDS_CHROME_CLEANUP_LOGS_PERMISSION" desc="A checkbox label, appearing on the Chrome Cleanup modal dialog, asking the user for permission to send details about the cleanup operation to Google."> Report details to Google </message> </if>
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index a313c94..0cbbd01 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -840,7 +840,7 @@ <!-- User pod remove sync warning text --> <message name="IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC" desc="Main text shown as a warning when attempting to remove an user."> - This person's browsing data will be deleted from this device. To recover the data, sign in to Chrome as $2. + This person's browsing data will be deleted from this device. To recover the data, sign in to Chrome as <ph name="USER_EMAIL">$2<ex>foo@example.com</ex></ph>. </message> <!-- Tutorial -->
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index edb286d..3ba4cea3 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -4409,7 +4409,7 @@ <message name="IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_SCAN_ERROR" desc="Body of error message that could appear during the cleanup of harmful software."> An error occurred while Chrome was searching for harmful software </message> - <message name="IDS_SETTINGS_RESET_CLEANUP_FIND_BUTTON_LABEL" desc="Button for the 'Find and remove harmful software' item in Chrome Settings. Imperative. On click, Chrome looks for harmful software on the user's computer. Imperative."> + <message name="IDS_SETTINGS_RESET_CLEANUP_FIND_BUTTON_LABEL" desc="Button for the 'Find harmful software' item in Chrome Settings. Imperative. On click, Chrome looks for harmful software on the user's computer. Imperative."> Find </message> <message name="IDS_SETTINGS_RESET_CLEANUP_FOOTER_POWERED_BY" desc="Branding footer on the web page for Chrome Cleanup. COMPANY_NAME is the name of a technology service that Chrome uses to remove harmful software from the user's computer. It is not necessary to translate 'powered by' literally; use an appropriate word for your language to convey the meaning of 'uses'. A similar use in other Google products is 'Powered by Google Translate.'"> @@ -4433,8 +4433,8 @@ <message name="IDS_SETTINGS_RESET_CLEANUP_TITLE_ERROR_PERMISSIONS_NEEDED" desc="Title of error message that could appear during the cleanup of harmful software. 'permission' refers to the user granting permission, e.g. from an operating system prompt, before the cleanup operation can continue."> Chrome needs permission to continue </message> - <message name="IDS_SETTINGS_RESET_CLEANUP_TITLE_FIND_AND_REMOVE" desc="Title of an item in Chrome Settings. Imperative."> - Find and remove harmful software + <message name="IDS_SETTINGS_RESET_CLEANUP_TITLE_FIND_HARMFUL_SOFTWARE" desc="Title of an item in Chrome Settings. Imperative."> + Find harmful software </message> <message name="IDS_SETTINGS_RESET_CLEANUP_TITLE_NO_INTERNET_CONNECTION" desc="Title of error message that could appear during the cleanup of harmful software."> No internet connection @@ -4463,8 +4463,8 @@ <message name="IDS_SETTINGS_RESET_CLEANUP_TRY_AGAIN_BUTTON_LABEL" desc="Generic button that appears next to a message indicating that an operation failed during the cleanup of harmful software." meaning="Button referred to in the string 'Click Try Again, and accept the prompt on your computer', IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_PERMISSIONS_NEEDED"> Try again </message> - <message name="IDS_SETTINGS_RESET_CLEANUP_LOGS_PERMISSION_EXPLANATION" desc="Description for the 'Report details to Google' option. Subject, 'Details', is omitted. Although the plural subject would indicate usage of the plural verb, here, we use the plural form of the verb, 'includes', to avoid the impression that 'include' is an infinitive verb. 'Includes' is a present tense main verb. "> - Includes information about harmful software, system settings, and processes on your computer + <message name="IDS_SETTINGS_RESET_CLEANUP_LOGS_PERMISSION_PREF" desc="A checkbox label for the 'Report harmful software removal details' preference."> + Report details to Google about harmful software, system settings, and processes that were found on your computer during this cleanup </message> <message name="IDS_SETTINGS_RESET_CLEANUP_TITLE_CLEANUP_UNAVAILABLE" desc="Title of error message that could appear before the cleanup of harmful software because Chrome failed to contact the server. This message will only appear on Windows desktop/laptop computers."> Cleanup is currently unavailable
diff --git a/chrome/browser/android/metrics/android_profile_session_durations_service.cc b/chrome/browser/android/metrics/android_profile_session_durations_service.cc index 25b1f98..96bd2cd 100644 --- a/chrome/browser/android/metrics/android_profile_session_durations_service.cc +++ b/chrome/browser/android/metrics/android_profile_session_durations_service.cc
@@ -6,13 +6,11 @@ AndroidProfileSessionDurationsService::AndroidProfileSessionDurationsService( syncer::SyncService* sync_service, - identity::IdentityManager* identity_manager, - GaiaCookieManagerService* cookie_manager) + identity::IdentityManager* identity_manager) : metrics_recorder_( std::make_unique<syncer::SyncSessionDurationsMetricsRecorder>( sync_service, - identity_manager, - cookie_manager)) { + identity_manager)) { // The AndroidProfileSessionDurationsService object is created as soon as // the profile is initialized. On Android, the profile is initialized as part // of the native code initialization, which is done soon after the application
diff --git a/chrome/browser/android/metrics/android_profile_session_durations_service.h b/chrome/browser/android/metrics/android_profile_session_durations_service.h index a067d18e..59813b5a 100644 --- a/chrome/browser/android/metrics/android_profile_session_durations_service.h +++ b/chrome/browser/android/metrics/android_profile_session_durations_service.h
@@ -9,7 +9,6 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/sync/driver/sync_session_durations_metrics_recorder.h" -class GaiaCookieManagerService; namespace identity { class IdentityManager; } @@ -24,8 +23,7 @@ // Callers must ensure that the parameters outlive this object. AndroidProfileSessionDurationsService( syncer::SyncService* sync_service, - identity::IdentityManager* identity_manager, - GaiaCookieManagerService* cookie_manager); + identity::IdentityManager* identity_manager); ~AndroidProfileSessionDurationsService() override; // KeyedService:
diff --git a/chrome/browser/android/metrics/android_profile_session_durations_service_factory.cc b/chrome/browser/android/metrics/android_profile_session_durations_service_factory.cc index 7910926..dcbb3bc 100644 --- a/chrome/browser/android/metrics/android_profile_session_durations_service_factory.cc +++ b/chrome/browser/android/metrics/android_profile_session_durations_service_factory.cc
@@ -7,9 +7,7 @@ #include "chrome/browser/android/metrics/android_profile_session_durations_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -39,9 +37,8 @@ : BrowserContextKeyedServiceFactory( "AndroidProfileSessionDurationsService", BrowserContextDependencyManager::GetInstance()) { - DependsOn(GaiaCookieManagerServiceFactory::GetInstance()); DependsOn(ProfileSyncServiceFactory::GetInstance()); - DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); } AndroidProfileSessionDurationsServiceFactory:: @@ -53,12 +50,10 @@ Profile* profile = Profile::FromBrowserContext(context); syncer::SyncService* sync_service = ProfileSyncServiceFactory::GetSyncServiceForBrowserContext(profile); - GaiaCookieManagerService* cookie_manager = - GaiaCookieManagerServiceFactory::GetForProfile(profile); identity::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile); - return new AndroidProfileSessionDurationsService( - sync_service, identity_manager, cookie_manager); + return new AndroidProfileSessionDurationsService(sync_service, + identity_manager); } bool AndroidProfileSessionDurationsServiceFactory::ServiceIsNULLWhileTesting()
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index 6167c0b4..857e0b0 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -208,6 +208,37 @@ " <input type=\"text\" id=\"phone\"><br>" "</form>"; +static const char kTestShippingFormWithCompanyString[] = + "<form action=\"http://www.example.com/\" method=\"POST\">" + "<label for=\"firstname\">First name:</label>" + " <input type=\"text\" id=\"firstname\"><br>" + "<label for=\"lastname\">Last name:</label>" + " <input type=\"text\" id=\"lastname\"><br>" + "<label for=\"address1\">Address line 1:</label>" + " <input type=\"text\" id=\"address1\"><br>" + "<label for=\"address2\">Address line 2:</label>" + " <input type=\"text\" id=\"address2\"><br>" + "<label for=\"city\">City:</label>" + " <input type=\"text\" id=\"city\"><br>" + "<label for=\"state\">State:</label>" + " <select id=\"state\">" + " <option value=\"\" selected=\"yes\">--</option>" + " <option value=\"CA\">California</option>" + " <option value=\"TX\">Texas</option>" + " </select><br>" + "<label for=\"zip\">ZIP code:</label>" + " <input type=\"text\" id=\"zip\"><br>" + "<label for=\"country\">Country:</label>" + " <select id=\"country\">" + " <option value=\"\" selected=\"yes\">--</option>" + " <option value=\"CA\">Canada</option>" + " <option value=\"US\">United States</option>" + " </select><br>" + "<label for=\"phone\">Phone number:</label>" + " <input type=\"text\" id=\"phone\"><br>" + "<label for=\"company\">First company:</label>" + " <input type=\"text\" id=\"company\"><br>" + "</form>"; // Searches all frames of |web_contents| and returns one called |name|. If // there are none, returns null, if there are more, returns an arbitrary one. content::RenderFrameHost* RenderFrameHostForName( @@ -1966,6 +1997,44 @@ ExpectFieldValue("company", company_name_enabled_ ? company_name : ""); } +// Test that Autofill does not fill in Company Name if disabled +IN_PROC_BROWSER_TEST_P(AutofillCompanyInteractiveTest, + NoAutofillSugggestionForCompanyName) { + CreateTestProfile(); + + std::string company_name("Initech"); + + // Load the test page. + SetTestUrlResponse(kTestShippingFormWithCompanyString); + ASSERT_NO_FATAL_FAILURE( + ui_test_utils::NavigateToURL(browser(), GetTestUrl())); + + // Focus the company field. + FocusFieldByName("company"); + + // Now click it. + test_delegate()->Reset(); + ASSERT_NO_FATAL_FAILURE(ClickElementWithId("company")); + + bool found = test_delegate()->Wait({ObservedUiEvents::kSuggestionShown}, + base::TimeDelta::FromSeconds(3)); + + if (!company_name_enabled_) { + EXPECT_FALSE(found); + return; + } + // Press the down arrow to select the suggestion and preview the autofilled + // form. + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); + + // Press Enter to accept the autofill suggestions. + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); + + // The form should be filled. + ExpectFieldValue("company", company_name); +} + // Test that Autofill does not fill in read-only fields. IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, NoAutofillForReadOnlyFields) { std::string addr_line1("1234 H St.");
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs.cc b/chrome/browser/browser_switcher/browser_switcher_prefs.cc index b60b795..4d33e0b9 100644 --- a/chrome/browser/browser_switcher/browser_switcher_prefs.cc +++ b/chrome/browser/browser_switcher/browser_switcher_prefs.cc
@@ -26,6 +26,9 @@ // List of hosts that should not trigger a transition in either browser. const char kUrlGreylist[] = "browser_switcher.url_greylist"; +// URL with an external XML sitelist file to load. +const char kExternalSitelistUrl[] = "browser_switcher.external_sitelist_url"; + #if defined(OS_WIN) // If set to true, use the IE Enterprise Mode Sitelist policy. const char kUseIeSitelist[] = "browser_switcher.use_ie_sitelist"; @@ -36,6 +39,7 @@ registry->RegisterListPref(prefs::kAlternativeBrowserParameters); registry->RegisterListPref(prefs::kUrlList); registry->RegisterListPref(prefs::kUrlGreylist); + registry->RegisterStringPref(prefs::kExternalSitelistUrl, ""); #if defined(OS_WIN) registry->RegisterBooleanPref(prefs::kUseIeSitelist, false); #endif
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs.h b/chrome/browser/browser_switcher/browser_switcher_prefs.h index b644eea8..5b8456e 100644 --- a/chrome/browser/browser_switcher/browser_switcher_prefs.h +++ b/chrome/browser/browser_switcher/browser_switcher_prefs.h
@@ -18,6 +18,7 @@ extern const char kAlternativeBrowserParameters[]; extern const char kUrlList[]; extern const char kUrlGreylist[]; +extern const char kExternalSitelistUrl[]; #if defined(OS_WIN) extern const char kUseIeSitelist[];
diff --git a/chrome/browser/browser_switcher/browser_switcher_service.cc b/chrome/browser/browser_switcher/browser_switcher_service.cc index a5c1029..f8adc42d 100644 --- a/chrome/browser/browser_switcher/browser_switcher_service.cc +++ b/chrome/browser/browser_switcher/browser_switcher_service.cc
@@ -30,6 +30,7 @@ const wchar_t kIeSiteListKey[] = L"SOFTWARE\\Policies\\Microsoft\\Internet Explorer\\Main\\EnterpriseMode"; const wchar_t kIeSiteListValue[] = L"SiteList"; +#endif // How long to wait after |BrowserSwitcherService| is created before initiating // the sitelist fetch. @@ -47,7 +48,7 @@ description: "BrowserSwitcher may download Internet Explorer's Enterprise Mode " "SiteList XML, to load the list of URLs to open in an alternative " - "browser. This is often on the organization's intranet. For more " + "browser. This is often on the organization's intranet.For more " "information on Internet Explorer's Enterprise Mode, see: " "https://docs.microsoft.com/internet-explorer/ie11-deploy-guide" "/what-is-enterprise-mode" @@ -56,45 +57,124 @@ "starts loading. The request may be retried once if it failed the " "first time." data: - "An HTTP or HTTPS GET request to the URL configured in Internet " - "Explorer's SiteList policy." + "Up to 2 (plus retries) HTTP or HTTPS GET requests to the URLs " + "configured in Internet Explorer's SiteList policy, and Chrome's " + "BrowserSwitcherExternalSitelistUrl policy." destination: OTHER destination_other: - "URL configured in Internet Explorer's SiteList policy." + "URL configured in Internet Explorer's SiteList policy, and URL " + "configured in Chrome's BrowserSwitcherExternalSitelistUrl policy. " } policy { cookies_allowed: NO setting: "This feature cannot be disabled by settings." policy_exception_justification: - "This feature is still in development, and is disabled by default." + "This feature still in development, and is disabled by default. " + "It needs to be enabled through policies." })"); -#endif } // namespace +class XmlDownloader { + public: + // Posts a task to start downloading+parsing the rules after |delay|. Calls + // |done_callback| when done, so the caller can apply the parsed rules and + // clean up this object. + XmlDownloader(Profile* profile, + GURL url, + base::TimeDelta delay, + base::OnceCallback<void(ParsedXml)> done_callback); + virtual ~XmlDownloader() = default; + + private: + void FetchXml(); + void ParseXml(std::unique_ptr<std::string> bytes); + void DoneParsing(ParsedXml xml); + + GURL url_; + scoped_refptr<network::SharedURLLoaderFactory> factory_; + + std::unique_ptr<network::SimpleURLLoader> url_loader_; + base::OnceCallback<void(ParsedXml)> done_callback_; + + base::WeakPtrFactory<XmlDownloader> weak_ptr_factory_; +}; + +XmlDownloader::XmlDownloader(Profile* profile, + GURL url, + base::TimeDelta delay, + base::OnceCallback<void(ParsedXml)> done_callback) + : url_(std::move(url)), + done_callback_(std::move(done_callback)), + weak_ptr_factory_(this) { + factory_ = content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess(); + DCHECK(factory_); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&XmlDownloader::FetchXml, weak_ptr_factory_.GetWeakPtr()), + delay); +} + +void XmlDownloader::FetchXml() { + auto request = std::make_unique<network::ResourceRequest>(); + request->url = url_; + request->load_flags = + (net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES | + net::LOAD_DISABLE_CACHE); + url_loader_ = + network::SimpleURLLoader::Create(std::move(request), traffic_annotation); + url_loader_->SetRetryOptions( + kFetchNumRetries, + network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE); + url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + factory_.get(), + base::BindOnce(&XmlDownloader::ParseXml, weak_ptr_factory_.GetWeakPtr())); +} + +void XmlDownloader::ParseXml(std::unique_ptr<std::string> bytes) { + if (!bytes) { + DoneParsing(ParsedXml({}, {}, "could not fetch XML")); + return; + } + ParseIeemXml(*bytes, base::BindOnce(&XmlDownloader::DoneParsing, + weak_ptr_factory_.GetWeakPtr())); +} + +void XmlDownloader::DoneParsing(ParsedXml xml) { + factory_.reset(); + url_loader_.reset(); + std::move(done_callback_).Run(std::move(xml)); +} + BrowserSwitcherService::BrowserSwitcherService(Profile* profile) - : launcher_(nullptr), sitelist_(nullptr), prefs_(profile->GetPrefs()) { + : launcher_(nullptr), + sitelist_(nullptr), + prefs_(profile->GetPrefs()), + weak_ptr_factory_(this) { DCHECK(profile); DCHECK(prefs_); + + GURL external_url; + if (prefs_->IsManagedPreference(prefs::kExternalSitelistUrl)) + external_url = GURL(prefs_->GetString(prefs::kExternalSitelistUrl)); + if (external_url.is_valid()) { + external_sitelist_downloader_ = std::make_unique<XmlDownloader>( + profile, std::move(external_url), fetch_delay_, + base::BindOnce(&BrowserSwitcherService::OnExternalSitelistParsed, + weak_ptr_factory_.GetWeakPtr())); + } + #if defined(OS_WIN) if (prefs_->GetBoolean(prefs::kUseIeSitelist) && prefs_->IsManagedPreference(prefs::kUseIeSitelist)) { GURL sitelist_url = GetIeemSitelistUrl(); if (sitelist_url.is_valid()) { - auto factory = - content::BrowserContext::GetDefaultStoragePartition(profile) - ->GetURLLoaderFactoryForBrowserProcess(); - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&BrowserSwitcherService::FetchIeemSitelist, - base::Unretained(this), std::move(sitelist_url), - std::move(factory)), - fetch_sitelist_delay_); - } else { - DoneLoadingIeemSitelist(); + ieem_downloader_ = std::make_unique<XmlDownloader>( + profile, std::move(sitelist_url), fetch_delay_, + base::BindOnce(&BrowserSwitcherService::OnIeemSitelistParsed, + weak_ptr_factory_.GetWeakPtr())); } - } else { - DoneLoadingIeemSitelist(); } #endif } @@ -123,26 +203,27 @@ sitelist_ = std::move(sitelist); } +void BrowserSwitcherService::OnExternalSitelistParsed(ParsedXml xml) { + if (xml.error) { + LOG(ERROR) << "Unable to parse IEEM SiteList: " << *xml.error; + } else { + VLOG(2) << "Done parsing external SiteList. " + << "Applying rules to future navigations."; + sitelist()->SetExternalSitelist(std::move(xml)); + } + external_sitelist_downloader_.reset(); +} + +base::TimeDelta BrowserSwitcherService::fetch_delay_ = kFetchSitelistDelay; + +// static +void BrowserSwitcherService::SetFetchDelayForTesting(base::TimeDelta delay) { + fetch_delay_ = delay; +} + #if defined(OS_WIN) -base::TimeDelta BrowserSwitcherService::fetch_sitelist_delay_ = - kFetchSitelistDelay; - -// static -void BrowserSwitcherService::SetIeemFetchDelayForTesting( - base::TimeDelta delay) { - fetch_sitelist_delay_ = delay; -} - -base::OnceCallback<void()> - BrowserSwitcherService::xml_parsed_callback_for_testing_; - -// static -void BrowserSwitcherService::SetXmlParsedCallbackForTesting( - base::OnceCallback<void()> callback) { - xml_parsed_callback_for_testing_ = std::move(callback); -} - -std::string BrowserSwitcherService::ieem_sitelist_url_for_testing_; +base::Optional<std::string> + BrowserSwitcherService::ieem_sitelist_url_for_testing_; // static void BrowserSwitcherService::SetIeemSitelistUrlForTesting( @@ -150,9 +231,10 @@ ieem_sitelist_url_for_testing_ = spec; } +// static GURL BrowserSwitcherService::GetIeemSitelistUrl() { - if (!ieem_sitelist_url_for_testing_.empty()) - return GURL(ieem_sitelist_url_for_testing_); + if (ieem_sitelist_url_for_testing_ != base::nullopt) + return GURL(*ieem_sitelist_url_for_testing_); base::win::RegKey key; if (ERROR_SUCCESS != key.Open(HKEY_LOCAL_MACHINE, kIeSiteListKey, KEY_READ) && @@ -165,37 +247,7 @@ return GURL(base::UTF16ToUTF8(url_string)); } -void BrowserSwitcherService::FetchIeemSitelist( - GURL url, - scoped_refptr<network::SharedURLLoaderFactory> factory) { - DCHECK(factory); - DCHECK(!url_loader_); - auto request = std::make_unique<network::ResourceRequest>(); - request->url = url; - request->load_flags = - (net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DISABLE_CACHE); - url_loader_ = - network::SimpleURLLoader::Create(std::move(request), traffic_annotation); - url_loader_->SetRetryOptions( - kFetchNumRetries, - network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE); - url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( - factory.get(), base::BindOnce(&BrowserSwitcherService::ParseXml, - base::Unretained(this))); -} - -void BrowserSwitcherService::ParseXml(std::unique_ptr<std::string> bytes) { - if (!bytes) { - DoneLoadingIeemSitelist(); - return; - } - ParseIeemXml(*bytes, - base::BindOnce(&BrowserSwitcherService::OnIeemSitelistXmlParsed, - base::Unretained(this))); -} - -void BrowserSwitcherService::OnIeemSitelistXmlParsed(ParsedXml xml) { +void BrowserSwitcherService::OnIeemSitelistParsed(ParsedXml xml) { if (xml.error) { LOG(ERROR) << "Unable to parse IEEM SiteList: " << *xml.error; } else { @@ -203,12 +255,7 @@ << "Applying rules to future navigations."; sitelist()->SetIeemSitelist(std::move(xml)); } - DoneLoadingIeemSitelist(); -} - -void BrowserSwitcherService::DoneLoadingIeemSitelist() { - if (xml_parsed_callback_for_testing_) - std::move(xml_parsed_callback_for_testing_).Run(); + ieem_downloader_.reset(); } #endif
diff --git a/chrome/browser/browser_switcher/browser_switcher_service.h b/chrome/browser/browser_switcher/browser_switcher_service.h index 28ac72a..1684c945 100644 --- a/chrome/browser/browser_switcher/browser_switcher_service.h +++ b/chrome/browser/browser_switcher/browser_switcher_service.h
@@ -7,6 +7,8 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/time/time.h" #include "build/build_config.h" #include "components/keyed_service/core/keyed_service.h" @@ -14,11 +16,6 @@ #include <memory> -namespace network { -class SimpleURLLoader; -class SharedURLLoaderFactory; -} // namespace network - class PrefService; class Profile; @@ -27,6 +24,7 @@ class AlternativeBrowserLauncher; class BrowserSwitcherSitelist; class ParsedXml; +class XmlDownloader; // Manages per-profile resources for BrowserSwitcher. class BrowserSwitcherService : public KeyedService { @@ -41,10 +39,9 @@ std::unique_ptr<AlternativeBrowserLauncher> launcher); void SetSitelistForTesting(std::unique_ptr<BrowserSwitcherSitelist> sitelist); + static void SetFetchDelayForTesting(base::TimeDelta delay); + #if defined(OS_WIN) - static void SetIeemFetchDelayForTesting(base::TimeDelta delay); - static void SetXmlParsedCallbackForTesting( - base::OnceCallback<void()> callback); static void SetIeemSitelistUrlForTesting(const std::string& url); #endif @@ -53,36 +50,31 @@ // Returns the URL to fetch to get Internet Explorer's Enterprise Mode // sitelist, based on policy. Returns an empty (invalid) URL if IE's SiteList // policy is unset. - GURL GetIeemSitelistUrl(); + static GURL GetIeemSitelistUrl(); - // Steps to process the IEEM sitelist rules: fetch, parse, apply. - void FetchIeemSitelist( - GURL url, - scoped_refptr<network::SharedURLLoaderFactory> factory); - void ParseXml(std::unique_ptr<std::string> bytes); - void OnIeemSitelistXmlParsed(ParsedXml xml); - void DoneLoadingIeemSitelist(); + void OnIeemSitelistParsed(ParsedXml xml); - // Delay for the IEEM XML fetch task, launched from the constructor. - static base::TimeDelta fetch_sitelist_delay_; + std::unique_ptr<XmlDownloader> ieem_downloader_; // URL to fetch the IEEM sitelist from. Only used for testing. - static std::string ieem_sitelist_url_for_testing_; - - // If set, gets called once the IEEM sitelist rules are applied. Also gets - // called if any step of the process fails. - static base::OnceCallback<void()> xml_parsed_callback_for_testing_; - - // Used to fetch the IEEM XML. - std::unique_ptr<network::SimpleURLLoader> url_loader_; + static base::Optional<std::string> ieem_sitelist_url_for_testing_; #endif + void OnExternalSitelistParsed(ParsedXml xml); + + // Delay for the IEEM/external XML fetch tasks, launched from the constructor. + static base::TimeDelta fetch_delay_; + + std::unique_ptr<XmlDownloader> external_sitelist_downloader_; + // Per-profile helpers. std::unique_ptr<AlternativeBrowserLauncher> launcher_; std::unique_ptr<BrowserSwitcherSitelist> sitelist_; PrefService* const prefs_; + base::WeakPtrFactory<BrowserSwitcherService> weak_ptr_factory_; + DISALLOW_IMPLICIT_CONSTRUCTORS(BrowserSwitcherService); };
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc index 712d50c..3285331 100644 --- a/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc +++ b/chrome/browser/browser_switcher/browser_switcher_service_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/run_loop.h" #include "base/test/test_timeouts.h" +#include "build/build_config.h" #include "chrome/browser/browser_switcher/browser_switcher_prefs.h" #include "chrome/browser/browser_switcher/browser_switcher_service_factory.h" #include "chrome/browser/browser_switcher/browser_switcher_sitelist.h" @@ -56,6 +57,7 @@ EXPECT_CALL(provider_, IsInitializationComplete(testing::_)) .WillRepeatedly(testing::Return(true)); policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); + BrowserSwitcherService::SetFetchDelayForTesting(base::TimeDelta()); } void SetUseIeSitelist(bool use_ie_sitelist) { @@ -68,64 +70,164 @@ base::RunLoop().RunUntilIdle(); } + void SetExternalUrl(const std::string& url) { + policy::PolicyMap policies; + policies.Set(policy::key::kBrowserSwitcherExternalSitelistUrl, + policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_PLATFORM, + std::make_unique<base::Value>(url), nullptr); + provider_.UpdateChromePolicy(policies); + base::RunLoop().RunUntilIdle(); + } + private: policy::MockConfigurationPolicyProvider provider_; DISALLOW_COPY_AND_ASSIGN(BrowserSwitcherServiceTest); }; -IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, NotEnabledByPolicy) { - // Only load the IEEM sitelist if the 'UseIeSitelist' policy is set to true. - base::RunLoop run_loop; - BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta()); - BrowserSwitcherService::SetXmlParsedCallbackForTesting( - run_loop.QuitClosure()); - BrowserSwitcherService::SetIeemSitelistUrlForTesting(kAValidUrl); +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, ExternalSitelistInvalidUrl) { + SetExternalUrl(kAnInvalidUrl); bool fetch_happened = false; content::URLLoaderInterceptor interceptor(base::BindRepeating( - [](bool* happened, content::URLLoaderInterceptor::RequestParams*) { - *happened = true; + [](bool* happened, content::URLLoaderInterceptor::RequestParams* params) { + if (!params->url_request.url.is_valid() || + params->url_request.url.spec() == kAnInvalidUrl) { + *happened = true; + } return false; }, &fetch_happened)); // Execute everything and make sure we didn't get to the fetch step. BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](bool* happened, base::OnceClosure quit) { + EXPECT_FALSE(*happened); + std::move(quit).Run(); + }, + &fetch_happened, run_loop.QuitClosure()), + TestTimeouts::action_timeout()); run_loop.Run(); - EXPECT_FALSE(fetch_happened); } +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, + ExternalFetchAndParseAfterStartup) { + SetExternalUrl(kAValidUrl); + + content::URLLoaderInterceptor interceptor( + base::BindRepeating(ReturnValidXml)); + + // Execute everything and make sure the rules are applied correctly. + auto* service = + BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](BrowserSwitcherSitelist* sitelist, base::OnceClosure quit) { + EXPECT_FALSE(sitelist->ShouldSwitch(GURL("http://google.com/"))); + EXPECT_TRUE( + sitelist->ShouldSwitch(GURL("http://docs.google.com/"))); + std::move(quit).Run(); + }, + service->sitelist(), run_loop.QuitClosure()), + TestTimeouts::action_timeout()); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, + ExternalIgnoresFailedDownload) { + SetExternalUrl(kAValidUrl); + + content::URLLoaderInterceptor interceptor( + base::BindRepeating(FailToDownload)); + + // Execute everything and make sure no rules are applied. + auto* service = + BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](BrowserSwitcherSitelist* sitelist, base::OnceClosure quit) { + EXPECT_FALSE(sitelist->ShouldSwitch(GURL("http://google.com/"))); + EXPECT_FALSE( + sitelist->ShouldSwitch(GURL("http://docs.google.com/"))); + std::move(quit).Run(); + }, + service->sitelist(), run_loop.QuitClosure()), + TestTimeouts::action_timeout()); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, + ExternalIgnoresNonManagedPref) { + browser()->profile()->GetPrefs()->SetString(prefs::kExternalSitelistUrl, + kAValidUrl); + + bool fetch_happened = false; + content::URLLoaderInterceptor interceptor(base::BindRepeating( + [](bool* happened, content::URLLoaderInterceptor::RequestParams* params) { + if (params->url_request.url.spec() == kAValidUrl) + *happened = true; + return false; + }, + &fetch_happened)); + + // Execute everything and make sure we didn't get to the fetch step. + BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](bool* happened, base::OnceClosure quit) { + EXPECT_FALSE(*happened); + std::move(quit).Run(); + }, + &fetch_happened, run_loop.QuitClosure()), + TestTimeouts::action_timeout()); + run_loop.Run(); +} + +#if defined(OS_WIN) IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, IeemSitelistInvalidUrl) { SetUseIeSitelist(true); - - base::RunLoop run_loop; - BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta()); - BrowserSwitcherService::SetXmlParsedCallbackForTesting( - run_loop.QuitClosure()); BrowserSwitcherService::SetIeemSitelistUrlForTesting(kAnInvalidUrl); bool fetch_happened = false; content::URLLoaderInterceptor interceptor(base::BindRepeating( - [](bool* happened, content::URLLoaderInterceptor::RequestParams*) { - *happened = true; + [](bool* happened, content::URLLoaderInterceptor::RequestParams* params) { + if (!params->url_request.url.is_valid() || + params->url_request.url.spec() == kAnInvalidUrl) { + *happened = true; + } return false; }, &fetch_happened)); // Execute everything and make sure we didn't get to the fetch step. BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](bool* happened, base::OnceClosure quit) { + EXPECT_FALSE(*happened); + std::move(quit).Run(); + }, + &fetch_happened, run_loop.QuitClosure()), + TestTimeouts::action_timeout()); run_loop.Run(); - EXPECT_FALSE(fetch_happened); } -IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, FetchAndParseAfterStartup) { +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, + IeemFetchAndParseAfterStartup) { SetUseIeSitelist(true); - - base::RunLoop run_loop; - BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta()); - BrowserSwitcherService::SetXmlParsedCallbackForTesting( - run_loop.QuitClosure()); BrowserSwitcherService::SetIeemSitelistUrlForTesting(kAValidUrl); content::URLLoaderInterceptor interceptor( @@ -134,19 +236,23 @@ // Execute everything and make sure the rules are applied correctly. auto* service = BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](BrowserSwitcherSitelist* sitelist, base::OnceClosure quit) { + EXPECT_FALSE(sitelist->ShouldSwitch(GURL("http://google.com/"))); + EXPECT_TRUE( + sitelist->ShouldSwitch(GURL("http://docs.google.com/"))); + std::move(quit).Run(); + }, + service->sitelist(), run_loop.QuitClosure()), + TestTimeouts::action_timeout()); run_loop.Run(); - EXPECT_FALSE(service->sitelist()->ShouldSwitch(GURL("http://google.com/"))); - EXPECT_TRUE( - service->sitelist()->ShouldSwitch(GURL("http://docs.google.com/"))); } -IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, IgnoresFailedDownload) { +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, IeemIgnoresFailedDownload) { SetUseIeSitelist(true); - - base::RunLoop run_loop; - BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta()); - BrowserSwitcherService::SetXmlParsedCallbackForTesting( - run_loop.QuitClosure()); BrowserSwitcherService::SetIeemSitelistUrlForTesting(kAValidUrl); content::URLLoaderInterceptor interceptor( @@ -155,31 +261,48 @@ // Execute everything and make sure no rules are applied. auto* service = BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](BrowserSwitcherSitelist* sitelist, base::OnceClosure quit) { + EXPECT_FALSE(sitelist->ShouldSwitch(GURL("http://google.com/"))); + EXPECT_FALSE( + sitelist->ShouldSwitch(GURL("http://docs.google.com/"))); + std::move(quit).Run(); + }, + service->sitelist(), run_loop.QuitClosure()), + TestTimeouts::action_timeout()); run_loop.Run(); - EXPECT_FALSE(service->sitelist()->ShouldSwitch(GURL("http://google.com/"))); - EXPECT_FALSE( - service->sitelist()->ShouldSwitch(GURL("http://docs.google.com/"))); } -IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, IgnoresNonManagedPref) { +IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, IeemIgnoresNonManagedPref) { browser()->profile()->GetPrefs()->SetBoolean(prefs::kUseIeSitelist, true); - - base::RunLoop run_loop; - BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta()); - BrowserSwitcherService::SetXmlParsedCallbackForTesting( - run_loop.QuitClosure()); BrowserSwitcherService::SetIeemSitelistUrlForTesting(kAValidUrl); - content::URLLoaderInterceptor interceptor( - base::BindRepeating(FailToDownload)); + bool fetch_happened = false; + content::URLLoaderInterceptor interceptor(base::BindRepeating( + [](bool* happened, content::URLLoaderInterceptor::RequestParams* params) { + if (params->url_request.url.spec() == kAValidUrl) + *happened = true; + return false; + }, + &fetch_happened)); - // Execute everything and make sure no rules are applied. - auto* service = - BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + // Execute everything and make sure we didn't get to the fetch step. + BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile()); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](bool* happened, base::OnceClosure quit) { + EXPECT_FALSE(*happened); + std::move(quit).Run(); + }, + &fetch_happened, run_loop.QuitClosure()), + TestTimeouts::action_timeout()); run_loop.Run(); - EXPECT_FALSE(service->sitelist()->ShouldSwitch(GURL("http://google.com/"))); - EXPECT_FALSE( - service->sitelist()->ShouldSwitch(GURL("http://docs.google.com/"))); } +#endif } // namespace browser_switcher
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.cc b/chrome/browser/chromeos/accessibility/speech_monitor.cc index e041022..e4688dd 100644 --- a/chrome/browser/chromeos/accessibility/speech_monitor.cc +++ b/chrome/browser/chromeos/accessibility/speech_monitor.cc
@@ -100,18 +100,19 @@ } void SpeechMonitor::WillSpeakUtteranceWithVoice( - const content::Utterance* utterance, + const content::TtsUtterance* utterance, const content::VoiceData& voice_data) { // Blacklist some phrases. // Filter out empty utterances which can be used to trigger a start event from // tts as an earcon sync. - if (utterance->text() == "" || utterance->text() == kChromeVoxAlertMessage || - utterance->text() == kChromeVoxUpdate1 || - utterance->text() == kChromeVoxUpdate2) + if (utterance->GetText() == "" || + utterance->GetText() == kChromeVoxAlertMessage || + utterance->GetText() == kChromeVoxUpdate1 || + utterance->GetText() == kChromeVoxUpdate2) return; - VLOG(0) << "Speaking " << utterance->text(); - utterance_queue_.push_back(utterance->text()); + VLOG(0) << "Speaking " << utterance->GetText(); + utterance_queue_.push_back(utterance->GetText()); if (loop_runner_.get()) loop_runner_->Quit(); }
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.h b/chrome/browser/chromeos/accessibility/speech_monitor.h index 6812bae..96a13c91 100644 --- a/chrome/browser/chromeos/accessibility/speech_monitor.h +++ b/chrome/browser/chromeos/accessibility/speech_monitor.h
@@ -51,7 +51,7 @@ void Pause() override {} void Resume() override {} void WillSpeakUtteranceWithVoice( - const content::Utterance* utterance, + const content::TtsUtterance* utterance, const content::VoiceData& voice_data) override; bool LoadBuiltInTtsEngine(content::BrowserContext* browser_context) override; std::string GetError() override;
diff --git a/chrome/browser/chromeos/arc/tts/arc_tts_service_unittest.cc b/chrome/browser/chromeos/arc/tts/arc_tts_service_unittest.cc index a9310b12..c0e16cdc 100644 --- a/chrome/browser/chromeos/arc/tts/arc_tts_service_unittest.cc +++ b/chrome/browser/chromeos/arc/tts/arc_tts_service_unittest.cc
@@ -37,7 +37,7 @@ // Unimplemented. bool IsSpeaking() override { return false; } - void SpeakOrEnqueue(content::Utterance* utterance) override {} + void SpeakOrEnqueue(content::TtsUtterance* utterance) override {} void Stop() override {} void Pause() override {} void Resume() override {}
diff --git a/chrome/browser/chromeos/file_manager/file_browser_handlers.cc b/chrome/browser/chromeos/file_manager/file_browser_handlers.cc index 34d3a705..34752e8d 100644 --- a/chrome/browser/chromeos/file_manager/file_browser_handlers.cc +++ b/chrome/browser/chromeos/file_manager/file_browser_handlers.cc
@@ -199,7 +199,8 @@ std::unique_ptr<FileDefinitionList> file_definition_list, std::unique_ptr<EntryDefinitionList> entry_definition_list, int handler_pid_in, - extensions::ExtensionHost* host); + std::unique_ptr<extensions::LazyContextTaskQueue::ContextInfo> + context_info); // Registers file permissions from |handler_host_permissions_| with // ChildProcessSecurityPolicy for process with id |handler_pid|. @@ -368,9 +369,11 @@ std::unique_ptr<FileDefinitionList> file_definition_list, std::unique_ptr<EntryDefinitionList> entry_definition_list, int handler_pid_in, - extensions::ExtensionHost* host) { - int handler_pid = host ? host->render_process_host()->GetID() : - handler_pid_in; + std::unique_ptr<extensions::LazyContextTaskQueue::ContextInfo> + context_info) { + int handler_pid = context_info != nullptr + ? context_info->render_process_host->GetID() + : handler_pid_in; if (handler_pid <= 0) { ExecuteDoneOnUIThread(false);
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc index 4c8ac6f..f8d4fbe5 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -598,11 +598,6 @@ // Let screens to settle. base::RunLoop().RunUntilIdle(); - - // WebUI exists now, finish the setup. - InitializeWebContents(); - - base::RunLoop().RunUntilIdle(); } void SimulateOfflineEnvironment() {
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc index cf124f0..decec38 100644 --- a/chrome/browser/chromeos/login/login_manager_test.cc +++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -73,8 +73,7 @@ LoginManagerTest::LoginManagerTest(bool should_launch_browser, bool should_initialize_webui) : should_launch_browser_(should_launch_browser), - should_initialize_webui_(should_initialize_webui), - web_contents_(NULL) { + should_initialize_webui_(should_initialize_webui) { set_exit_when_last_browser_closes(false); } @@ -148,7 +147,6 @@ chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, content::NotificationService::AllSources()) .Wait(); - InitializeWebContents(); } test::UserSessionManagerTestApi session_manager_test_api( UserSessionManager::GetInstance()); @@ -216,6 +214,10 @@ EXPECT_TRUE(AddUserToSession(user_context)); } +content::WebContents* LoginManagerTest::web_contents() { + return LoginDisplayHost::default_host()->GetOobeWebContents(); +} + // static std::string LoginManagerTest::GetGaiaIDForUserID(const std::string& user_id) { if (user_id == LoginManagerTest::kEnterpriseUser1) @@ -225,13 +227,4 @@ return "gaia-id-" + user_id; } -void LoginManagerTest::InitializeWebContents() { - LoginDisplayHost* host = LoginDisplayHost::default_host(); - EXPECT_TRUE(host != NULL); - - content::WebContents* web_contents = host->GetOobeWebContents(); - EXPECT_TRUE(web_contents != NULL); - set_web_contents(web_contents); -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/login_manager_test.h b/chrome/browser/chromeos/login/login_manager_test.h index 7ccb3ce..d51142e 100644 --- a/chrome/browser/chromeos/login/login_manager_test.h +++ b/chrome/browser/chromeos/login/login_manager_test.h
@@ -35,7 +35,7 @@ bool should_initialize_webui); ~LoginManagerTest() override; - // Overridden from InProcessBrowserTest. + // InProcessBrowserTest: void TearDownOnMainThread() override; void SetUpCommandLine(base::CommandLine* command_line) override; void SetUpOnMainThread() override; @@ -65,7 +65,7 @@ // Add user with |user_id| to session. void AddUser(const AccountId& user_id); - content::WebContents* web_contents() { return web_contents_; } + content::WebContents* web_contents(); static std::string GetGaiaIDForUserID(const std::string& user_id); @@ -83,20 +83,12 @@ static const char kEnterpriseUser2GaiaId[]; protected: - void InitializeWebContents(); - FakeGaia fake_gaia_; HTTPSForwarder gaia_https_forwarder_; private: - - void set_web_contents(content::WebContents* web_contents) { - web_contents_ = web_contents; - } - const bool should_launch_browser_; const bool should_initialize_webui_; - content::WebContents* web_contents_; DISALLOW_COPY_AND_ASSIGN(LoginManagerTest); };
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc index d78c5f6..dae0a5e2 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.cc +++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -55,12 +55,7 @@ const char OobeBaseTest::kFakeSIDCookie[] = "fake-SID-cookie"; const char OobeBaseTest::kFakeLSIDCookie[] = "fake-LSID-cookie"; -OobeBaseTest::OobeBaseTest() - : fake_gaia_(new FakeGaia()), - network_portal_detector_(NULL), - needs_background_networking_(false), - gaia_frame_parent_("signin-frame"), - initialize_fake_merge_session_(true) { +OobeBaseTest::OobeBaseTest() : fake_gaia_(new FakeGaia()) { set_exit_when_last_browser_closes(false); set_chromeos_user_ = false; }
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.h b/chrome/browser/chromeos/login/test/oobe_base_test.h index 6b507b0..224a3752 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.h +++ b/chrome/browser/chromeos/login/test/oobe_base_test.h
@@ -23,10 +23,6 @@ class WindowedNotificationObserver; } // namespace content -namespace extensions { -class ScopedCurrentChannel; -} - namespace chromeos { class NetworkPortalDetectorTestImpl; @@ -107,18 +103,17 @@ const std::string& refresh_token); std::unique_ptr<FakeGaia> fake_gaia_; - NetworkPortalDetectorTestImpl* network_portal_detector_; + NetworkPortalDetectorTestImpl* network_portal_detector_ = nullptr; // Whether to use background networking. Note this is only effective when it // is set before SetUpCommandLine is invoked. - bool needs_background_networking_; + bool needs_background_networking_ = false; std::unique_ptr<content::WindowedNotificationObserver> login_screen_load_observer_; - std::unique_ptr<extensions::ScopedCurrentChannel> scoped_channel_; HTTPSForwarder gaia_https_forwarder_; - std::string gaia_frame_parent_; - bool initialize_fake_merge_session_; + std::string gaia_frame_parent_ = "signin-frame"; + bool initialize_fake_merge_session_ = true; DISALLOW_COPY_AND_ASSIGN(OobeBaseTest); };
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 0446950..71afa8c 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -555,6 +555,8 @@ // SwReporter settings. (*s_whitelist)[::prefs::kSwReporterEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_whitelist)[::prefs::kSwReporterReportingEnabled] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; #endif return *s_whitelist;
diff --git a/chrome/browser/extensions/devtools_util.cc b/chrome/browser/extensions/devtools_util.cc index 7369a048..1435663 100644 --- a/chrome/browser/extensions/devtools_util.cc +++ b/chrome/browser/extensions/devtools_util.cc
@@ -17,9 +17,10 @@ namespace { // Helper to inspect an ExtensionHost after it has been loaded. -void InspectExtensionHost(ExtensionHost* host) { - if (host) - DevToolsWindow::OpenDevToolsWindow(host->host_contents()); +void InspectExtensionHost( + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) { + if (context_info != nullptr) + DevToolsWindow::OpenDevToolsWindow(context_info->web_contents); } } // namespace @@ -29,7 +30,8 @@ ExtensionHost* host = ProcessManager::Get(profile) ->GetBackgroundHostForExtension(extension->id()); if (host) { - InspectExtensionHost(host); + InspectExtensionHost( + std::make_unique<LazyContextTaskQueue::ContextInfo>(host)); } else { LazyBackgroundTaskQueue::Get(profile)->AddPendingTask( profile, extension->id(), base::BindOnce(&InspectExtensionHost));
diff --git a/chrome/browser/extensions/extension_view_host_factory.cc b/chrome/browser/extensions/extension_view_host_factory.cc index 408d516..d321f86 100644 --- a/chrome/browser/extensions/extension_view_host_factory.cc +++ b/chrome/browser/extensions/extension_view_host_factory.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/extensions/extension_view_host_factory.h" +#include <string> + #include "chrome/browser/extensions/extension_view_host.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -21,29 +23,31 @@ // Creates a new ExtensionHost with its associated view, grouping it in the // appropriate SiteInstance (and therefore process) based on the URL and // profile. -ExtensionViewHost* CreateViewHostForExtension(const Extension* extension, - const GURL& url, - Profile* profile, - Browser* browser, - ViewType view_type) { +std::unique_ptr<ExtensionViewHost> CreateViewHostForExtension( + const Extension* extension, + const GURL& url, + Profile* profile, + Browser* browser, + ViewType view_type) { DCHECK(profile); // A NULL browser may only be given for dialogs. DCHECK(browser || view_type == VIEW_TYPE_EXTENSION_DIALOG); scoped_refptr<content::SiteInstance> site_instance = ProcessManager::Get(profile)->GetSiteInstanceForURL(url); - ExtensionViewHost* host = - new ExtensionViewHost(extension, site_instance.get(), url, view_type); + auto host = std::make_unique<ExtensionViewHost>( + extension, site_instance.get(), url, view_type); host->CreateView(browser); return host; } // Creates a view host for an extension in an incognito window. Returns NULL // if the extension is not allowed to run in incognito. -ExtensionViewHost* CreateViewHostForIncognito(const Extension* extension, - const GURL& url, - Profile* profile, - Browser* browser, - ViewType view_type) { +std::unique_ptr<ExtensionViewHost> CreateViewHostForIncognito( + const Extension* extension, + const GURL& url, + Profile* profile, + Browser* browser, + ViewType view_type) { DCHECK(extension); DCHECK(profile->IsOffTheRecord()); @@ -76,10 +80,11 @@ } // Creates and initializes an ExtensionViewHost for the extension with |url|. -ExtensionViewHost* CreateViewHost(const GURL& url, - Profile* profile, - Browser* browser, - extensions::ViewType view_type) { +std::unique_ptr<ExtensionViewHost> CreateViewHost( + const GURL& url, + Profile* profile, + Browser* browser, + extensions::ViewType view_type) { DCHECK(profile); // A NULL browser may only be given for dialogs. DCHECK(browser || view_type == VIEW_TYPE_EXTENSION_DIALOG); @@ -98,15 +103,16 @@ } // namespace // static -ExtensionViewHost* ExtensionViewHostFactory::CreatePopupHost(const GURL& url, - Browser* browser) { +std::unique_ptr<ExtensionViewHost> ExtensionViewHostFactory::CreatePopupHost( + const GURL& url, + Browser* browser) { DCHECK(browser); return CreateViewHost( url, browser->profile(), browser, VIEW_TYPE_EXTENSION_POPUP); } // static -ExtensionViewHost* ExtensionViewHostFactory::CreateDialogHost( +std::unique_ptr<ExtensionViewHost> ExtensionViewHostFactory::CreateDialogHost( const GURL& url, Profile* profile) { DCHECK(profile);
diff --git a/chrome/browser/extensions/extension_view_host_factory.h b/chrome/browser/extensions/extension_view_host_factory.h index 3ad7bbf..4a864dc 100644 --- a/chrome/browser/extensions/extension_view_host_factory.h +++ b/chrome/browser/extensions/extension_view_host_factory.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_VIEW_HOST_FACTORY_H_ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_VIEW_HOST_FACTORY_H_ +#include <memory> + #include "base/macros.h" class Browser; @@ -22,11 +24,13 @@ // Creates a new ExtensionHost with its associated view, grouping it in the // appropriate SiteInstance (and therefore process) based on the URL and // profile. - static ExtensionViewHost* CreatePopupHost(const GURL& url, Browser* browser); + static std::unique_ptr<ExtensionViewHost> CreatePopupHost(const GURL& url, + Browser* browser); // Some dialogs may not be associated with a particular browser window and // hence only require a |profile|. - static ExtensionViewHost* CreateDialogHost(const GURL& url, Profile* profile); + static std::unique_ptr<ExtensionViewHost> CreateDialogHost(const GURL& url, + Profile* profile); private: DISALLOW_COPY_AND_ASSIGN(ExtensionViewHostFactory);
diff --git a/chrome/browser/extensions/extension_view_host_factory_browsertest.cc b/chrome/browser/extensions/extension_view_host_factory_browsertest.cc index 4fde2bac..342c8ee 100644 --- a/chrome/browser/extensions/extension_view_host_factory_browsertest.cc +++ b/chrome/browser/extensions/extension_view_host_factory_browsertest.cc
@@ -26,8 +26,8 @@ content::BrowserContext* browser_context = browser()->profile(); { // Popup hosts are created with the correct type and profile. - std::unique_ptr<ExtensionViewHost> host( - ExtensionViewHostFactory::CreatePopupHost(extension->url(), browser())); + std::unique_ptr<ExtensionViewHost> host = + ExtensionViewHostFactory::CreatePopupHost(extension->url(), browser()); EXPECT_EQ(extension.get(), host->extension()); EXPECT_EQ(browser_context, host->browser_context()); EXPECT_EQ(VIEW_TYPE_EXTENSION_POPUP, host->extension_host_type()); @@ -36,9 +36,9 @@ { // Dialog hosts are created with the correct type and profile. - std::unique_ptr<ExtensionViewHost> host( + std::unique_ptr<ExtensionViewHost> host = ExtensionViewHostFactory::CreateDialogHost(extension->url(), - browser()->profile())); + browser()->profile()); EXPECT_EQ(extension.get(), host->extension()); EXPECT_EQ(browser_context, host->browser_context()); EXPECT_EQ(VIEW_TYPE_EXTENSION_DIALOG, host->extension_host_type());
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 32c1336c..fd2c1c0a 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -854,6 +854,13 @@ kEmeSessionNotFound); } +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, LoadSessionAfterClose) { + base::StringPairs query_params{{"keySystem", kExternalClearKeyKeySystem}}; + RunEncryptedMediaTestPage("eme_load_session_after_close_test.html", + kExternalClearKeyKeySystem, query_params, + media::kEnded); +} + const char kExternalClearKeyDecryptOnlyKeySystem[] = "org.chromium.externalclearkey.decryptonly";
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.cc b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.cc index 45ce483..4b20f69 100644 --- a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.cc +++ b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.cc
@@ -14,13 +14,11 @@ DesktopProfileSessionDurationsService::DesktopProfileSessionDurationsService( syncer::SyncService* sync_service, identity::IdentityManager* identity_manager, - GaiaCookieManagerService* cookie_manager, DesktopSessionDurationTracker* tracker) : metrics_recorder_( std::make_unique<syncer::SyncSessionDurationsMetricsRecorder>( sync_service, - identity_manager, - cookie_manager)), + identity_manager)), session_duration_observer_(this) { session_duration_observer_.Add(tracker); if (tracker->in_session()) {
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h index 03770063..37a2a2a 100644 --- a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h +++ b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h
@@ -10,7 +10,6 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/sync/driver/sync_session_durations_metrics_recorder.h" -class GaiaCookieManagerService; namespace identity { class IdentityManager; } @@ -30,7 +29,6 @@ DesktopProfileSessionDurationsService( syncer::SyncService* sync_service, identity::IdentityManager* identity_manager, - GaiaCookieManagerService* cookie_manager, DesktopSessionDurationTracker* tracker); ~DesktopProfileSessionDurationsService() override;
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.cc b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.cc index 741dfb73b..7b8e2eb1 100644 --- a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.cc +++ b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.cc
@@ -7,9 +7,7 @@ #include "chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_context.h" @@ -35,9 +33,8 @@ : BrowserContextKeyedServiceFactory( "DesktopProfileSessionDurationsService", BrowserContextDependencyManager::GetInstance()) { - DependsOn(GaiaCookieManagerServiceFactory::GetInstance()); DependsOn(ProfileSyncServiceFactory::GetInstance()); - DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); } DesktopProfileSessionDurationsServiceFactory:: @@ -49,13 +46,11 @@ Profile* profile = Profile::FromBrowserContext(context); syncer::SyncService* sync_service = ProfileSyncServiceFactory::GetSyncServiceForBrowserContext(profile); - GaiaCookieManagerService* cookie_manager = - GaiaCookieManagerServiceFactory::GetForProfile(profile); DesktopSessionDurationTracker* tracker = DesktopSessionDurationTracker::Get(); identity::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(profile); - return new DesktopProfileSessionDurationsService( - sync_service, identity_manager, cookie_manager, tracker); + return new DesktopProfileSessionDurationsService(sync_service, + identity_manager, tracker); } content::BrowserContext*
diff --git a/chrome/browser/navigation_predictor/navigation_predictor.cc b/chrome/browser/navigation_predictor/navigation_predictor.cc index 3013ba4..258007c 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor.cc
@@ -13,6 +13,8 @@ #include "base/optional.h" #include "base/system/sys_info.h" #include "chrome/browser/engagement/site_engagement_service.h" +#include "chrome/browser/predictors/loading_predictor.h" +#include "chrome/browser/predictors/loading_predictor_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "components/search_engines/template_url_service.h" @@ -113,7 +115,12 @@ preconnect_origin_score_threshold_(base::GetFieldTrialParamByFeatureAsInt( blink::features::kRecordAnchorMetricsVisible, "preconnect_origin_score_threshold", - 0)) + 0)), + same_origin_preconnecting_allowed_( + base::GetFieldTrialParamByFeatureAsBool( + blink::features::kRecordAnchorMetricsVisible, + "same_origin_preconnecting_allowed", + false)) #ifdef OS_ANDROID , application_status_listener_( @@ -274,20 +281,40 @@ void NavigationPredictor::TakeActionNowOnTabOrAppVisibilityChange( Action log_action) { - base::Optional<url::Origin> preconnect_origin; - if (prefetch_url_) { + MaybePreconnectNow(log_action); +} + +void NavigationPredictor::MaybePreconnectNow(Action log_action) { + base::Optional<url::Origin> preconnect_origin = preconnect_origin_; + + if (prefetch_url_ && !preconnect_origin) { // Preconnect to the origin of the prefetch URL. preconnect_origin = url::Origin::Create(prefetch_url_.value()); } if (!preconnect_origin) return; + if (preconnect_origin->scheme() != url::kHttpScheme && + preconnect_origin->scheme() != url::kHttpsScheme) { + return; + } std::string action_histogram_name = source_is_default_search_engine_page_ ? "NavigationPredictor.OnDSE.ActionTaken" : "NavigationPredictor.OnNonDSE.ActionTaken"; base::UmaHistogramEnumeration(action_histogram_name, log_action); + + if (!same_origin_preconnecting_allowed_) + return; + + auto* loading_predictor = predictors::LoadingPredictorFactory::GetForProfile( + Profile::FromBrowserContext(browser_context_)); + GURL preconnect_url_serialized(preconnect_origin->Serialize()); + DCHECK(preconnect_url_serialized.is_valid()); + loading_predictor->PrepareForPageLoad( + preconnect_url_serialized, predictors::HintOrigin::NAVIGATION_PREDICTOR, + true); } SiteEngagementService* NavigationPredictor::GetEngagementService() const { @@ -735,7 +762,7 @@ GetOriginToPreconnect(document_origin, sorted_navigation_scores); if (preconnect_origin_.has_value()) { DCHECK_EQ(document_origin.host(), preconnect_origin_->host()); - base::UmaHistogramEnumeration(action_histogram_name, Action::kPreconnect); + MaybePreconnectNow(Action::kPreconnect); return; } @@ -900,6 +927,9 @@ base::android::ApplicationState application_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!application_status_listener_) + return; + if (application_state_ != base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES || application_state != @@ -914,7 +944,9 @@ TakeActionNowOnTabOrAppVisibilityChange(Action::kPreconnectOnAppForeground); // To keep the overhead as low, Pre* action on app foreground is taken at most - // once per page. - application_status_listener_.reset(); + // once per page. Stop listening to application change events only if + // OnLoad() has been fired implying that prediction computation has finished. + if (document_loaded_timing_ != base::TimeTicks()) + application_status_listener_.reset(); } #endif // OS_ANDROID
diff --git a/chrome/browser/navigation_predictor/navigation_predictor.h b/chrome/browser/navigation_predictor/navigation_predictor.h index 0f0b9b86..90d9b4b 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor.h +++ b/chrome/browser/navigation_predictor/navigation_predictor.h
@@ -183,6 +183,9 @@ // |log_action| should be set to the reason why this method was called. void TakeActionNowOnTabOrAppVisibilityChange(Action log_action); + // MaybePreconnectNow preconnects to an origin server if it's allowed. + void MaybePreconnectNow(Action log_action); + // Used to get keyed services. content::BrowserContext* const browser_context_; @@ -223,6 +226,9 @@ // they are not comparable. const int preconnect_origin_score_threshold_; + // True if |this| is allowed to preconnect to same origin hosts. + const bool same_origin_preconnecting_allowed_; + // Timing of document loaded and last click. base::TimeTicks document_loaded_timing_; base::TimeTicks last_click_timing_;
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc b/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc index 691ec7f..78fcd9898 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_browsertest.cc
@@ -20,6 +20,7 @@ #include "content/public/test/browser_test_utils.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h" #include "third_party/blink/public/common/features.h" #include "url/gurl.h" @@ -44,6 +45,44 @@ } } +// Gets notified by the EmbeddedTestServer on incoming connections being +// accepted or read from. +class ConnectionListener + : public net::test_server::EmbeddedTestServerConnectionListener { + public: + ConnectionListener() = default; + + ~ConnectionListener() override = default; + + void ResetAcceptedSocketCount() { accepted_socket_count_ = 0; } + + size_t accepted_socket_count() const { return accepted_socket_count_; } + + void SetOnAcceptedSocketCallback( + base::OnceCallback<void()> on_accepted_socket_callback) { + on_accepted_socket_callback_ = std::move(on_accepted_socket_callback); + } + + private: + // Gets called from the EmbeddedTestServer thread to be notified that + // a connection was accepted. + void AcceptedSocket(const net::StreamSocket& connection) override { + ++accepted_socket_count_; + if (on_accepted_socket_callback_) + std::move(on_accepted_socket_callback_).Run(); + } + + // Gets called from the EmbeddedTestServer thread to be notified that + // a connection was read from. + void ReadFromSocket(const net::StreamSocket& connection, int rv) override {} + + size_t accepted_socket_count_ = 0; + + base::OnceCallback<void()> on_accepted_socket_callback_; + + DISALLOW_COPY_AND_ASSIGN(ConnectionListener); +}; + } // namespace class NavigationPredictorBrowserTest @@ -61,6 +100,7 @@ void SetUp() override { https_server_.reset( new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS)); + https_server_->SetConnectionListener(&https_connection_listener_); https_server_->ServeFilesFromSourceDirectory( "chrome/test/data/navigation_predictor"); ASSERT_TRUE(https_server_->Start()); @@ -79,6 +119,11 @@ host_resolver()->ClearRules(); } + void FlushAllSocketsAndConnections() { + http_server_->FlushAllSocketsAndConnectionsOnUIThread(); + https_server_->FlushAllSocketsAndConnectionsOnUIThread(); + } + const GURL GetTestURL(const char* file) const { return https_server_->GetURL(file); } @@ -87,11 +132,35 @@ return http_server_->GetURL(file); } + void ResetAcceptedHttpsSocketCount() { + https_connection_listener_.ResetAcceptedSocketCount(); + } + + void WaitUntilHttpsSocketAccepted() { + if (accepted_socket_count() > 0) + return; + + base::RunLoop open_loop; + auto open_callback = base::BindOnce( + [](base::OnceClosure quit_closure) { std::move(quit_closure).Run(); }, + open_loop.QuitClosure()); + + https_connection_listener_.SetOnAcceptedSocketCallback( + std::move(open_callback)); + open_loop.Run(); + } + + size_t accepted_socket_count() const { + return https_connection_listener_.accepted_socket_count(); + } + private: std::unique_ptr<net::EmbeddedTestServer> http_server_; std::unique_ptr<net::EmbeddedTestServer> https_server_; base::test::ScopedFeatureList feature_list_; + ConnectionListener https_connection_listener_; + DISALLOW_COPY_AND_ASSIGN(NavigationPredictorBrowserTest); }; @@ -310,6 +379,9 @@ kPrefetchActionClickToDifferentOrigin, 1); + FlushAllSocketsAndConnections(); + ResetAcceptedHttpsSocketCount(); + // Change to visibile. browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); histogram_tester.ExpectTotalCount("NavigationPredictor.OnNonDSE.ActionTaken", @@ -334,6 +406,67 @@ browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); histogram_tester.ExpectTotalCount("NavigationPredictor.OnNonDSE.ActionTaken", 2); +} + +// Test that the action accuracy is properly recorded and when same origin +// preconnections are enabled, then navigation predictor initiates the +// preconnection. +IN_PROC_BROWSER_TEST_F( + NavigationPredictorBrowserTest, + DISABLE_ON_CHROMEOS( + ActionAccuracy_DifferentOrigin_VisibilityChangedPreconnectEnabled)) { + std::map<std::string, std::string> parameters; + base::test::ScopedFeatureList feature_list; + parameters["same_origin_preconnecting_allowed"] = "true"; + feature_list.InitAndEnableFeatureWithParameters( + blink::features::kRecordAnchorMetricsVisible, parameters); + + base::HistogramTester histogram_tester; + + const GURL& url = GetTestURL("/page_with_same_host_anchor_element.html"); + ui_test_utils::NavigateToURL(browser(), url); + base::RunLoop().RunUntilIdle(); + + histogram_tester.ExpectUniqueSample( + "AnchorElementMetrics.Visible.NumberOfAnchorElements", 2, 1); + // Same document anchor element should be removed after merge. + histogram_tester.ExpectUniqueSample( + "AnchorElementMetrics.Visible.NumberOfAnchorElementsAfterMerge", 2, 1); + histogram_tester.ExpectUniqueSample( + "NavigationPredictor.OnNonDSE.ActionTaken", + NavigationPredictor::Action::kPrefetch, 1); + + // Change to visible. + browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); + histogram_tester.ExpectTotalCount("NavigationPredictor.OnNonDSE.ActionTaken", + 1); + + browser()->tab_strip_model()->GetActiveWebContents()->WasHidden(); + histogram_tester.ExpectTotalCount("NavigationPredictor.OnNonDSE.ActionTaken", + 1); + + FlushAllSocketsAndConnections(); + ResetAcceptedHttpsSocketCount(); + + browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); + histogram_tester.ExpectTotalCount("NavigationPredictor.OnNonDSE.ActionTaken", + 2); + histogram_tester.ExpectBucketCount( + "NavigationPredictor.OnNonDSE.ActionTaken", + NavigationPredictor::Action::kPreconnectOnVisibilityChange, 1); + + WaitUntilHttpsSocketAccepted(); + + ResetAcceptedHttpsSocketCount(); + + // Hiding and showing the tab again should not cause change in histograms + // since Pre* on tab foreground is done at most once per page. + browser()->tab_strip_model()->GetActiveWebContents()->WasHidden(); + histogram_tester.ExpectTotalCount("NavigationPredictor.OnNonDSE.ActionTaken", + 2); + browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); + histogram_tester.ExpectTotalCount("NavigationPredictor.OnNonDSE.ActionTaken", + 2); histogram_tester.ExpectBucketCount( "NavigationPredictor.OnNonDSE.ActionTaken", NavigationPredictor::Action::kPreconnectOnVisibilityChange, 1);
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc b/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc index 8badd72..770435b 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc
@@ -69,14 +69,6 @@ NavigationPredictorTest() = default; ~NavigationPredictorTest() override = default; - void SetUp() override { - SetupFieldTrial(base::nullopt /* preconnect_origin_score_threshold */, - base::nullopt /* prefetch_url_score_threshold */); - ChromeRenderViewHostTestHarness::SetUp(); - predictor_service_helper_ = std::make_unique<TestNavigationPredictor>( - mojo::MakeRequest(&predictor_service_), main_rfh()); - } - // Helper function to generate mojom metrics. blink::mojom::AnchorElementMetricsPtr CreateMetricsPtr( const std::string& source_url, @@ -106,8 +98,18 @@ } protected: + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + predictor_service_helper_ = std::make_unique<TestNavigationPredictor>( + mojo::MakeRequest(&predictor_service_), main_rfh()); + } + void SetupFieldTrial(base::Optional<int> preconnect_origin_score_threshold, base::Optional<int> prefetch_url_score_threshold) { + if (field_trial_initiated_) + return; + + field_trial_initiated_ = true; const std::string kTrialName = "TrialFoo2"; const std::string kGroupName = "GroupFoo2"; // Value not used @@ -129,6 +131,8 @@ private: base::test::ScopedFeatureList scoped_feature_list; + + bool field_trial_initiated_ = false; }; } // namespace @@ -387,10 +391,12 @@ // disabled by setting |prefetch_url_score_threshold| to too high. class NavigationPredictorPrefetchDisabledTest : public NavigationPredictorTest { public: - void SetUp() override { + NavigationPredictorPrefetchDisabledTest() { SetupFieldTrial(0 /* preconnect_origin_score_threshold */, 101 /* prefetch_url_score_threshold */); + } + void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); predictor_service_helper_ = std::make_unique<TestNavigationPredictor>( mojo::MakeRequest(&predictor_service_), main_rfh()); @@ -481,10 +487,12 @@ class NavigationPredictorPreconnectPrefetchDisabledTest : public NavigationPredictorTest { public: - void SetUp() override { + NavigationPredictorPreconnectPrefetchDisabledTest() { SetupFieldTrial(101 /* preconnect_origin_score_threshold */, 101 /* prefetch_url_score_threshold */); + } + void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); predictor_service_helper_ = std::make_unique<TestNavigationPredictor>( mojo::MakeRequest(&predictor_service_), main_rfh());
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 44e6a80..fff07a79 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -948,6 +948,9 @@ { key::kBrowserSwitcherUrlGreylist, browser_switcher::prefs::kUrlGreylist, base::Value::Type::LIST }, + { key::kBrowserSwitcherExternalSitelistUrl, + browser_switcher::prefs::kExternalSitelistUrl, + base::Value::Type::STRING }, #endif #if defined(OS_WIN) { key::kBrowserSwitcherUseIeSitelist,
diff --git a/chrome/browser/predictors/loading_predictor_config.h b/chrome/browser/predictors/loading_predictor_config.h index d8922440..340f9c81 100644 --- a/chrome/browser/predictors/loading_predictor_config.h +++ b/chrome/browser/predictors/loading_predictor_config.h
@@ -30,7 +30,7 @@ bool IsPreconnectAllowed(Profile* profile); // Indicates what caused the page load hint. -enum class HintOrigin { NAVIGATION, EXTERNAL, OMNIBOX }; +enum class HintOrigin { NAVIGATION, EXTERNAL, OMNIBOX, NAVIGATION_PREDICTOR }; // Represents the config for the Loading predictor. struct LoadingPredictorConfig {
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 92f842b..a20c1616 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -3509,7 +3509,7 @@ } void WillSpeakUtteranceWithVoice( - const content::Utterance* utterance, + const content::TtsUtterance* utterance, const content::VoiceData& voice_data) override {} void SetError(const std::string& error) override {}
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs index 0fd83b82..05c23bf 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/injected/event_watcher_test.unitjs
@@ -343,7 +343,8 @@ * The low-level details are tested in editable_text_test.js, this is * a higher-level test of how that code interacts with the event watcher. */ -TEST_F('ChromeVoxEventWatcherUnitTest', 'EditableText', function() { +// Flaky on Chromium OS: https://crbug.com/912390. +TEST_F('ChromeVoxEventWatcherUnitTest', 'DISABLED_EditableText', function() { cvox.ChromeVoxEditableTextBase.eventTypingEcho = false; this.loadHtml('<div>' + '<button id="before">Before</button>' +
diff --git a/chrome/browser/resources/omnibox/omnibox.css b/chrome/browser/resources/omnibox/omnibox.css index 4828835..a1769f4 100644 --- a/chrome/browser/resources/omnibox/omnibox.css +++ b/chrome/browser/resources/omnibox/omnibox.css
@@ -48,18 +48,11 @@ font-family: monospace; font-size: 12px; min-width: 900px; - overflow-wrap: break-word; table-layout: fixed; text-align: left; width: 100%; } -table * { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - thead tr { background-color: #f8f8f8; color: #555; @@ -67,17 +60,37 @@ font-weight: bold; letter-spacing: 0; vertical-align: bottom; - white-space: nowrap; } tbody tr { - height: 42px; - transition-duration: 300ms; + height: 66px; +} + +tbody td > * { + display: block; + max-height: 56px; +} + +tbody td * { + overflow: hidden; + word-break: break-all; +} + +tbody td:not(:hover) * { + text-overflow: ellipsis; + white-space: nowrap; +} + +tbody td:hover * { + overflow-y: auto; +} + +tbody pre.json * { + white-space: pre-line; } tbody tr:hover * { background-color: #f8f8f8; - white-space: normal; } th, @@ -86,8 +99,11 @@ } th { + overflow: hidden; padding-bottom: 6px; padding-top: 12px; + text-overflow: ellipsis; + white-space: nowrap; } .filtered-highlighted { @@ -119,19 +135,6 @@ background-color: #f0f0f0; } -tbody tr:hover pre { - white-space: pre-wrap; - overflow-y: auto; -} - -tbody pre.json * { - white-space: inherit; -} - -pre.json { - padding: 0 5px; -} - pre.json .key { color: purple; font-weight: bold;
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html index b57ce4d8..f92d46a6 100644 --- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html +++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html
@@ -11,6 +11,7 @@ <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="../controls/controlled_button.html"> <link rel="import" href="../controls/settings_toggle_button.html"> +<link rel="import" href="../prefs/prefs.html"> <link rel="import" href="../settings_shared_css.html"> <link rel="import" href="chrome_cleanup_proxy.html"> <link rel="import" href="items_to_remove_list.html"> @@ -18,6 +19,10 @@ <dom-module id="settings-chrome-cleanup-page"> <template> <style include="settings-shared"> + #status-title { + font-weight: 500; + } + #waiting-spinner { flex-shrink: 0; height: 20px; @@ -40,29 +45,20 @@ #powered-by-logo > svg { height: 22px; } - - .top-aligned-settings-box { - align-items: center; - /* override settings-box min-height since we use vertical padding */ - min-height: 0; - padding: 15px var(--settings-box-row-padding); - } </style> - <div class$="settings-box first - [[getTopSettingsBoxClass_(showExplanation_)]]"> + <div class="settings-box first"> <div class="start"> <div id="status-title" role="status" inner-h-t-m-l="[[title_]]"></div> <div hidden="[[!showExplanation_]]"> <span class="secondary">[[explanation_]]</span> </div> </div> - <cr-policy-pref-indicator - pref="[[prefs.software_reporter.enabled]]"> - </cr-policy-pref-indicator> <paper-spinner-lite id="waiting-spinner" hidden="[[!isWaitingForResult_]]" active="[[isWaitingForResult_]]"> </paper-spinner-lite> <template is="dom-if" if="[[showActionButton_]]"> + <cr-policy-pref-indicator pref="[[prefs.software_reporter.enabled]]"> + </cr-policy-pref-indicator> <div class="separator"></div> <paper-button id="action-button" class="action-button" disabled$="[[!cleanupEnabled_]]" on-click="proceed_"> @@ -70,13 +66,14 @@ </paper-button> </template> </div> - <settings-toggle-button hidden="[[!showLogsPermission_]]" - id="chromeCleanupLogsUploadControl" - label="$i18n{chromeCleanupLogsUploadPermission}" - pref="[[logsUploadPref_]]" - sub-label="$i18n{chromeCleanupTitleLogsPermissionExplanation}" - on-settings-boolean-control-change="changeLogsPermission_"> - </settings-toggle-button> + <div class="settings-box continuation"> + <settings-checkbox hidden="[[!showLogsPermission_]]" + id="chromeCleanupLogsUploadControl" + sub-label="$i18n{chromeCleanupExplanationLogsPermissionPref}" + pref="{{prefs.software_reporter.reporting}}" + disabled$="[[!cleanupEnabled_]]"> + </settings-checkbox> + </div> <div id="show-items-button" class="settings-box" actionable on-click="toggleExpandButton_" hidden="[[!showItemsToRemove_]]"> <div class="start">[[showItemsLinkLabel_]]</div>
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js index 33f3c7d..eeea5a4 100644 --- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js +++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js
@@ -113,8 +113,13 @@ behaviors: [I18nBehavior, WebUIListenerBehavior], properties: { - /** Preferences state. */ - prefs: Object, + /** + * Preferences state. + */ + prefs: { + type: Object, + notify: true, + }, /** @private */ title_: { @@ -240,8 +245,10 @@ /** @private {?function()} */ doAction_: null, - /** @private {?Map<settings.ChromeCleanerCardState, - * !settings.ChromeCleanupCardComponents>} */ + /** + * @private {?Map<settings.ChromeCleanerCardState, + * !settings.ChromeCleanupCardComponents>} + */ cardStateToComponentsMap_: null, /** @private {settings.ChromeCleanupOngoingAction} */ @@ -276,9 +283,6 @@ this.addWebUIListener( 'chrome-cleanup-on-reboot-required', this.onRebootRequired_.bind(this)); this.addWebUIListener( - 'chrome-cleanup-upload-permission-change', - this.onUploadPermissionChange_.bind(this)); - this.addWebUIListener( 'chrome-cleanup-enabled-change', this.onCleanupEnabledChange_.bind(this)); this.browserProxy_.registerChromeCleanerObserver(); @@ -293,10 +297,6 @@ this.doAction_(); }, - getTopSettingsBoxClass_: function(showDetails) { - return showDetails ? 'top-aligned-settings-box' : 'two-line'; - }, - /** * Toggles the expand button within the element being listened to. * @param {!Event} e @@ -554,24 +554,6 @@ }, /** - * @param {boolean} managed Whether uploads are controlled by policy or not. - * @param {boolean} enabled Whether logs upload is enabled. - * @private - */ - onUploadPermissionChange_: function(managed, enabled) { - const pref = { - key: '', - type: chrome.settingsPrivate.PrefType.BOOLEAN, - value: enabled, - }; - if (managed) { - pref.enforcement = chrome.settingsPrivate.Enforcement.ENFORCED; - pref.controlledBy = chrome.settingsPrivate.ControlledBy.USER_POLICY; - } - this.logsUploadPref_ = pref; - }, - - /** * @param {boolean} enabled Whether cleanup is enabled. * @private */ @@ -579,12 +561,6 @@ this.cleanupEnabled_ = enabled; }, - /** @private */ - changeLogsPermission_: function() { - const enabled = this.$.chromeCleanupLogsUploadControl.checked; - this.browserProxy_.setLogsUploadPermission(enabled); - }, - /** * Sends an action to the browser proxy to start scanning. * @private
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js index 24cac1a..6484512 100644 --- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js +++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js
@@ -29,12 +29,6 @@ restartComputer() {} /** - * Updates the cleanup logs upload permission status. - * @param {boolean} enabled - */ - setLogsUploadPermission(enabled) {} - - /** * Notifies Chrome that the state of the details section changed. * @param {boolean} enabled */ @@ -87,11 +81,6 @@ } /** @override */ - setLogsUploadPermission(enabled) { - chrome.send('setLogsUploadPermission', [enabled]); - } - - /** @override */ notifyShowDetails(enabled) { chrome.send('notifyShowDetails', [enabled]); }
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index ee48ba2..2990b14 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -178,11 +178,14 @@ <div id="autoConnectToggleLabel" class="start settings-box-text"> $i18n{networkAutoConnect} </div> - <cr-policy-network-indicator - property="[[getManagedAutoConnect_(networkProperties)]]"> - </cr-policy-network-indicator> + <template is="dom-if" if="[[isAutoConnectEnforcedByPolicy( + networkProperties, globalPolicy)]]"> + <cr-policy-indicator indicator-type="devicePolicy"> + </cr-policy-indicator> + </template> <cr-toggle checked="{{autoConnect_}}" - disabled="[[!enableAutoConnect_(networkProperties)]]" + disabled="[[isAutoConnectEnforcedByPolicy(networkProperties, + globalPolicy)]]" aria-labelledby="autoConnectToggleLabel"> </cr-toggle> </div>
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index 8a8e58a..e0c0b58d 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -1030,24 +1030,14 @@ * @return {boolean} * @private */ - enableAutoConnect_: function(networkProperties, globalPolicy) { - if (networkProperties !== undefined && - networkProperties.Type == CrOnc.Type.WI_FI && !!globalPolicy && - !!globalPolicy.AllowOnlyPolicyNetworksToAutoconnect && - !this.isPolicySource(networkProperties.Source)) { + isAutoConnectEnforcedByPolicy: function(networkProperties, globalPolicy) { + if (networkProperties === undefined || + networkProperties.Type != CrOnc.Type.WI_FI) { return false; } - return !this.isNetworkPolicyEnforced( - this.getManagedAutoConnect_(networkProperties)); - }, - - /** - * @param {!CrOnc.NetworkProperties} networkProperties - * @return {!CrOnc.ManagedProperty|undefined} Managed AutoConnect property. - * @private - */ - getManagedAutoConnect_: function(networkProperties) { - return CrOnc.getManagedAutoConnect(networkProperties); + if (this.isPolicySource(networkProperties.Source)) + return !this.isEditable(CrOnc.getManagedAutoConnect(networkProperties)); + return globalPolicy && !!globalPolicy.AllowOnlyPolicyNetworksToAutoconnect; }, /**
diff --git a/chrome/browser/resources/settings/people_page/sync_controls.html b/chrome/browser/resources/settings/people_page/sync_controls.html index 4ddc7d6..0343ab9 100644 --- a/chrome/browser/resources/settings/people_page/sync_controls.html +++ b/chrome/browser/resources/settings/people_page/sync_controls.html
@@ -174,9 +174,6 @@ disabled and unchecked if autofill is unchecked.--> <div> $i18n{enablePaymentsIntegrationCheckboxLabel} - <a href="$i18nRaw{autofillHelpURL}" target="_blank"> - $i18n{learnMore} - </a> </div> <cr-toggle checked="{{syncPrefs.paymentsIntegrationEnabled}}" on-change="onSingleSyncDataTypeChanged_"
diff --git a/chrome/browser/resources/settings/reset_page/reset_page.html b/chrome/browser/resources/settings/reset_page/reset_page.html index a70c57aa..5b28d42 100644 --- a/chrome/browser/resources/settings/reset_page/reset_page.html +++ b/chrome/browser/resources/settings/reset_page/reset_page.html
@@ -91,7 +91,7 @@ associated-control="[[$$('#chromeCleanupSubpageTrigger')]]" page-title="$i18n{resetCleanupComputerTrigger}" learn-more-url="$i18n{chromeCleanupLearnMoreUrl}"> - <settings-chrome-cleanup-page prefs="[[prefs]]"> + <settings-chrome-cleanup-page prefs="{{prefs}}"> </settings-chrome-cleanup-page> </settings-subpage> </template>
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc index 1e76621..aed752d 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
@@ -228,7 +228,6 @@ if (!g_controller) { g_controller = new ChromeCleanerControllerImpl(); - g_controller->Init(); } return g_controller; @@ -254,16 +253,13 @@ } void ChromeCleanerControllerImpl::SetLogsEnabled(bool logs_enabled) { - if (logs_enabled_ == logs_enabled) - return; - - logs_enabled_ = logs_enabled; - for (auto& observer : observer_list_) - observer.OnLogsEnabledChanged(logs_enabled_); + PrefService* local_state = g_browser_process->local_state(); + local_state->SetBoolean(prefs::kSwReporterReportingEnabled, logs_enabled); } bool ChromeCleanerControllerImpl::logs_enabled() const { - return logs_enabled_; + PrefService* local_state = g_browser_process->local_state(); + return local_state->GetBoolean(prefs::kSwReporterReportingEnabled); } void ChromeCleanerControllerImpl::ResetIdleState() { @@ -403,12 +399,12 @@ pending_invocation_type_ != SwReporterInvocationType::kUserInitiatedWithLogsDisallowed); - RecordScannerLogsAcceptanceHistogram(logs_enabled_); + const bool logs_enabled = this->logs_enabled(); + RecordScannerLogsAcceptanceHistogram(logs_enabled); SwReporterInvocationType invocation_type = - logs_enabled_ - ? SwReporterInvocationType::kUserInitiatedWithLogsAllowed - : SwReporterInvocationType::kUserInitiatedWithLogsDisallowed; + logs_enabled ? SwReporterInvocationType::kUserInitiatedWithLogsAllowed + : SwReporterInvocationType::kUserInitiatedWithLogsDisallowed; if (cached_reporter_invocations_) { SwReporterInvocationSequence copied_sequence(*cached_reporter_invocations_); @@ -557,10 +553,6 @@ ChromeCleanerControllerImpl::~ChromeCleanerControllerImpl() = default; -void ChromeCleanerControllerImpl::Init() { - logs_enabled_ = IsReportingAllowedByPolicy(); -} - void ChromeCleanerControllerImpl::NotifyObserver(Observer* observer) const { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h index 1c32ce8..ff9d6812 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h
@@ -85,8 +85,6 @@ ChromeCleanerControllerImpl(); ~ChromeCleanerControllerImpl() override; - void Init(); - void NotifyObserver(Observer* observer) const; void SetStateAndNotifyObservers(State state); // Used to invalidate weak pointers and reset accumulated data that is no @@ -126,9 +124,6 @@ extensions::ExtensionService* extension_service_; State state_ = State::kIdle; - // The logs permission checkboxes in the Chrome Cleaner dialog and webui page - // are opt out. - bool logs_enabled_ = true; // Whether Cleanup is powered by an external partner. bool powered_by_partner_ = false; IdleReason idle_reason_ = IdleReason::kInitial;
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc index 23e1a3e..5cb49f5 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc
@@ -87,7 +87,6 @@ MOCK_METHOD2(OnCleaning, void(bool, const ChromeCleanerScannerResults&)); MOCK_METHOD0(OnRebootRequired, void()); MOCK_METHOD0(OnRebootFailed, void()); - MOCK_METHOD1(OnLogsEnabledChanged, void(bool)); }; enum class MetricsStatus { @@ -543,10 +542,6 @@ controller_->ReplyWithUserResponse( profile1, service(), user_response_); }))); - // Since logs upload is enabled by default, OnLogsEnabledChanged() will be - // called only if the user response is kAcceptedWithoutLogs. - if (user_response_ == UserResponse::kAcceptedWithoutLogs) - EXPECT_CALL(mock_observer_, OnLogsEnabledChanged(false)); } else { EXPECT_CALL(mock_observer_, OnInfected(_, _)).Times(0); }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h index f9cb186..c478b08 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h
@@ -108,7 +108,6 @@ const ChromeCleanerScannerResults& scanner_results) {} virtual void OnRebootRequired() {} virtual void OnRebootFailed() {} - virtual void OnLogsEnabledChanged(bool logs_enabled) {} protected: virtual ~Observer() = default;
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_service.cc b/chrome/browser/search/one_google_bar/one_google_bar_service.cc index 2a88fb6..e2cf94a 100644 --- a/chrome/browser/search/one_google_bar/one_google_bar_service.cc +++ b/chrome/browser/search/one_google_bar/one_google_bar_service.cc
@@ -27,7 +27,8 @@ private: // IdentityManager::Observer implementation. void OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) override { + const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) override { callback_.Run(); }
diff --git a/chrome/browser/sessions/tab_restore_service_factory.cc b/chrome/browser/sessions/tab_restore_service_factory.cc index 75b493c..ca0c8677 100644 --- a/chrome/browser/sessions/tab_restore_service_factory.cc +++ b/chrome/browser/sessions/tab_restore_service_factory.cc
@@ -55,5 +55,6 @@ std::unique_ptr<sessions::TabRestoreServiceClient> client( new ChromeTabRestoreServiceClient(profile)); - return new sessions::TabRestoreServiceImpl(std::move(client), nullptr); + return new sessions::TabRestoreServiceImpl(std::move(client), + profile->GetPrefs(), nullptr); }
diff --git a/chrome/browser/sessions/tab_restore_service_unittest.cc b/chrome/browser/sessions/tab_restore_service_unittest.cc index 7740683..f695fd5 100644 --- a/chrome/browser/sessions/tab_restore_service_unittest.cc +++ b/chrome/browser/sessions/tab_restore_service_unittest.cc
@@ -26,6 +26,8 @@ #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/chrome_render_view_test.h" #include "chrome/test/base/testing_profile.h" +#include "components/history/core/common/pref_names.h" +#include "components/prefs/pref_service.h" #include "components/sessions/content/content_live_tab.h" #include "components/sessions/core/serialized_navigation_entry_test_helper.h" #include "components/sessions/core/session_types.h" @@ -94,7 +96,7 @@ time_factory_ = new TabRestoreTimeFactory(); service_.reset(new sessions::TabRestoreServiceImpl( std::make_unique<ChromeTabRestoreServiceClient>(profile()), - time_factory_)); + profile()->GetPrefs(), time_factory_)); } void TearDown() override { @@ -132,7 +134,7 @@ service_.reset(); service_.reset(new sessions::TabRestoreServiceImpl( std::make_unique<ChromeTabRestoreServiceClient>(profile()), - time_factory_)); + profile()->GetPrefs(), time_factory_)); SynchronousLoadTabsFromLastSession(); } @@ -544,8 +546,7 @@ SynchronousLoadTabsFromLastSession(); - // Because we restored a session TabRestoreServiceImpl shouldn't load - // the tabs. + // Because we restored a session TabRestoreService shouldn't load the tabs. ASSERT_EQ(0U, service_->entries().size()); } @@ -563,6 +564,35 @@ ASSERT_EQ(0U, service_->entries().size()); } +// Makes sure we don't save sessions when saving history is disabled. +TEST_F(TabRestoreServiceImplTest, DontSaveWhenSavingIsDisabled) { + profile()->GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, true); + + CreateSessionServiceWithOneWindow(false); + + SessionServiceFactory::GetForProfile(profile()) + ->MoveCurrentSessionToLastSession(); + + SynchronousLoadTabsFromLastSession(); + + ASSERT_EQ(0U, service_->entries().size()); +} + +// Makes sure we don't attempt to load previous sessions when saving history is +// disabled. +TEST_F(TabRestoreServiceImplTest, DontLoadWhenSavingIsDisabled) { + CreateSessionServiceWithOneWindow(false); + + SessionServiceFactory::GetForProfile(profile()) + ->MoveCurrentSessionToLastSession(); + + profile()->GetPrefs()->SetBoolean(prefs::kSavingBrowserHistoryDisabled, true); + + SynchronousLoadTabsFromLastSession(); + + ASSERT_EQ(0U, service_->entries().size()); +} + TEST_F(TabRestoreServiceImplTest, LoadPreviousSessionAndTabs) { CreateSessionServiceWithOneWindow(false);
diff --git a/chrome/browser/signin/oauth2_token_service_delegate_android.cc b/chrome/browser/signin/oauth2_token_service_delegate_android.cc index a8c620e..572bc85 100644 --- a/chrome/browser/signin/oauth2_token_service_delegate_android.cc +++ b/chrome/browser/signin/oauth2_token_service_delegate_android.cc
@@ -14,9 +14,7 @@ #include "base/stl_util.h" #include "chrome/browser/profiles/profile_android.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "chrome/browser/sync/profile_sync_service_android.h" #include "components/signin/core/browser/account_info.h" -#include "content/public/browser/browser_thread.h" #include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/oauth2_access_token_fetcher.h" #include "jni/OAuth2TokenService_jni.h" @@ -27,7 +25,6 @@ using base::android::JavaParamRef; using base::android::JavaRef; using base::android::ScopedJavaLocalRef; -using content::BrowserThread; namespace {
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_api.cc b/chrome/browser/speech/extension_api/tts_engine_extension_api.cc index 18907e4..a1db574 100644 --- a/chrome/browser/speech/extension_api/tts_engine_extension_api.cc +++ b/chrome/browser/speech/extension_api/tts_engine_extension_api.cc
@@ -223,7 +223,7 @@ } } -void TtsExtensionEngine::Speak(content::Utterance* utterance, +void TtsExtensionEngine::Speak(content::TtsUtterance* utterance, const content::VoiceData& voice) { // See if the engine supports the "end" event; if so, we can keep the // utterance around and track it. If not, we're finished with this @@ -232,12 +232,12 @@ voice.events.find(content::TTS_EVENT_END) != voice.events.end(); std::unique_ptr<base::ListValue> args(new base::ListValue()); - args->AppendString(utterance->text()); + args->AppendString(utterance->GetText()); // Pass through most options to the speech engine, but remove some // that are handled internally. std::unique_ptr<base::DictionaryValue> options( - static_cast<base::DictionaryValue*>(utterance->options()->DeepCopy())); + static_cast<base::DictionaryValue*>(utterance->GetOptions()->DeepCopy())); if (options->HasKey(constants::kRequiredEventTypesKey)) options->Remove(constants::kRequiredEventTypesKey, NULL); if (options->HasKey(constants::kDesiredEventTypesKey)) @@ -256,15 +256,15 @@ // http://crbug.com/463264 if (!options->HasKey(constants::kRateKey)) { options->SetDouble(constants::kRateKey, - utterance->continuous_parameters().rate); + utterance->GetContinuousParameters().rate); } if (!options->HasKey(constants::kPitchKey)) { options->SetDouble(constants::kPitchKey, - utterance->continuous_parameters().pitch); + utterance->GetContinuousParameters().pitch); } if (!options->HasKey(constants::kVolumeKey)) { options->SetDouble(constants::kVolumeKey, - utterance->continuous_parameters().volume); + utterance->GetContinuousParameters().volume); } // Add the voice name and language to the options if they're not @@ -276,49 +276,53 @@ options->SetString(constants::kLangKey, voice.lang); args->Append(std::move(options)); - args->AppendInteger(utterance->id()); + args->AppendInteger(utterance->GetId()); std::string json; base::JSONWriter::Write(*args, &json); - Profile* profile = Profile::FromBrowserContext(utterance->browser_context()); + Profile* profile = + Profile::FromBrowserContext(utterance->GetBrowserContext()); auto event = std::make_unique<extensions::Event>( extensions::events::TTS_ENGINE_ON_SPEAK, tts_engine_events::kOnSpeak, std::move(args), profile); - EventRouter::Get(profile)->DispatchEventToExtension(utterance->engine_id(), + EventRouter::Get(profile)->DispatchEventToExtension(utterance->GetEngineId(), std::move(event)); } -void TtsExtensionEngine::Stop(content::Utterance* utterance) { +void TtsExtensionEngine::Stop(content::TtsUtterance* utterance) { std::unique_ptr<base::ListValue> args(new base::ListValue()); - Profile* profile = Profile::FromBrowserContext(utterance->browser_context()); + Profile* profile = + Profile::FromBrowserContext(utterance->GetBrowserContext()); auto event = std::make_unique<extensions::Event>( extensions::events::TTS_ENGINE_ON_STOP, tts_engine_events::kOnStop, std::move(args), profile); - EventRouter::Get(profile)->DispatchEventToExtension(utterance->engine_id(), + EventRouter::Get(profile)->DispatchEventToExtension(utterance->GetEngineId(), std::move(event)); } -void TtsExtensionEngine::Pause(content::Utterance* utterance) { +void TtsExtensionEngine::Pause(content::TtsUtterance* utterance) { std::unique_ptr<base::ListValue> args(new base::ListValue()); - Profile* profile = Profile::FromBrowserContext(utterance->browser_context()); + Profile* profile = + Profile::FromBrowserContext(utterance->GetBrowserContext()); auto event = std::make_unique<extensions::Event>( extensions::events::TTS_ENGINE_ON_PAUSE, tts_engine_events::kOnPause, std::move(args), profile); EventRouter* event_router = EventRouter::Get(profile); - std::string id = utterance->engine_id(); + std::string id = utterance->GetEngineId(); event_router->DispatchEventToExtension(id, std::move(event)); WarnIfMissingPauseOrResumeListener(profile, event_router, id); } -void TtsExtensionEngine::Resume(content::Utterance* utterance) { +void TtsExtensionEngine::Resume(content::TtsUtterance* utterance) { std::unique_ptr<base::ListValue> args(new base::ListValue()); - Profile* profile = Profile::FromBrowserContext(utterance->browser_context()); + Profile* profile = + Profile::FromBrowserContext(utterance->GetBrowserContext()); auto event = std::make_unique<extensions::Event>( extensions::events::TTS_ENGINE_ON_RESUME, tts_engine_events::kOnResume, std::move(args), profile); EventRouter* event_router = EventRouter::Get(profile); - std::string id = utterance->engine_id(); + std::string id = utterance->GetEngineId(); event_router->DispatchEventToExtension(id, std::move(event)); WarnIfMissingPauseOrResumeListener(profile, event_router, id); }
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_api.h b/chrome/browser/speech/extension_api/tts_engine_extension_api.h index 6cbedb48..9c358ea 100644 --- a/chrome/browser/speech/extension_api/tts_engine_extension_api.h +++ b/chrome/browser/speech/extension_api/tts_engine_extension_api.h
@@ -11,8 +11,6 @@ #include "content/public/browser/tts_controller.h" #include "extensions/browser/extension_function.h" -class Utterance; - namespace content { class BrowserContext; } @@ -32,11 +30,11 @@ // Overridden from TtsEngineDelegate: void GetVoices(content::BrowserContext* browser_context, std::vector<content::VoiceData>* out_voices) override; - void Speak(content::Utterance* utterance, + void Speak(content::TtsUtterance* utterance, const content::VoiceData& voice) override; - void Stop(content::Utterance* utterance) override; - void Pause(content::Utterance* utterance) override; - void Resume(content::Utterance* utterance) override; + void Stop(content::TtsUtterance* utterance) override; + void Pause(content::TtsUtterance* utterance) override; + void Resume(content::TtsUtterance* utterance) override; bool LoadBuiltInTtsEngine(content::BrowserContext* browser_context) override; };
diff --git a/chrome/browser/speech/extension_api/tts_extension_api.cc b/chrome/browser/speech/extension_api/tts_extension_api.cc index e0979752..a37c3620 100644 --- a/chrome/browser/speech/extension_api/tts_extension_api.cc +++ b/chrome/browser/speech/extension_api/tts_extension_api.cc
@@ -92,7 +92,7 @@ public: explicit TtsExtensionEventHandler(const std::string& src_extension_id); - void OnTtsEvent(content::Utterance* utterance, + void OnTtsEvent(content::TtsUtterance* utterance, content::TtsEventType event_type, int char_index, const std::string& error_message) override; @@ -108,21 +108,21 @@ : src_extension_id_(src_extension_id) { } -void TtsExtensionEventHandler::OnTtsEvent(content::Utterance* utterance, +void TtsExtensionEventHandler::OnTtsEvent(content::TtsUtterance* utterance, content::TtsEventType event_type, int char_index, const std::string& error_message) { - if (utterance->src_id() < 0) { - if (utterance->finished()) + if (utterance->GetSrcId() < 0) { + if (utterance->IsFinished()) delete this; return; } const std::set<content::TtsEventType>& desired_event_types = - utterance->desired_event_types(); + utterance->GetDesiredEventTypes(); if (desired_event_types.size() > 0 && desired_event_types.find(event_type) == desired_event_types.end()) { - if (utterance->finished()) + if (utterance->IsFinished()) delete this; return; } @@ -135,20 +135,20 @@ if (event_type == content::TTS_EVENT_ERROR) { details->SetString(constants::kErrorMessageKey, error_message); } - details->SetInteger(constants::kSrcIdKey, utterance->src_id()); - details->SetBoolean(constants::kIsFinalEventKey, utterance->finished()); + details->SetInteger(constants::kSrcIdKey, utterance->GetSrcId()); + details->SetBoolean(constants::kIsFinalEventKey, utterance->IsFinished()); std::unique_ptr<base::ListValue> arguments(new base::ListValue()); arguments->Append(std::move(details)); auto event = std::make_unique<extensions::Event>( ::extensions::events::TTS_ON_EVENT, ::events::kOnEvent, - std::move(arguments), utterance->browser_context()); - event->event_url = utterance->src_url(); - extensions::EventRouter::Get(utterance->browser_context()) + std::move(arguments), utterance->GetBrowserContext()); + event->event_url = utterance->GetSrcUrl(); + extensions::EventRouter::Get(utterance->GetBrowserContext()) ->DispatchEventToExtension(src_extension_id_, std::move(event)); - if (utterance->finished()) + if (utterance->IsFinished()) delete this; } @@ -268,19 +268,20 @@ // the behavior more predictable and easier to write unit tests for too. SendResponse(true); - content::Utterance* utterance = new content::Utterance(GetProfile()); - utterance->set_text(text); - utterance->set_voice_name(voice_name); - utterance->set_src_id(src_id); - utterance->set_src_url(source_url()); - utterance->set_lang(lang); - utterance->set_continuous_parameters(rate, pitch, volume); - utterance->set_can_enqueue(can_enqueue); - utterance->set_required_event_types(required_event_types); - utterance->set_desired_event_types(desired_event_types); - utterance->set_engine_id(voice_extension_id); - utterance->set_options(options.get()); - utterance->set_event_delegate(new TtsExtensionEventHandler(extension_id())); + content::TtsUtterance* utterance = + content::TtsUtterance::Create(GetProfile()); + utterance->SetText(text); + utterance->SetVoiceName(voice_name); + utterance->SetSrcId(src_id); + utterance->SetSrcUrl(source_url()); + utterance->SetLang(lang); + utterance->SetContinuousParameters(rate, pitch, volume); + utterance->SetCanEnqueue(can_enqueue); + utterance->SetRequiredEventTypes(required_event_types); + utterance->SetDesiredEventTypes(desired_event_types); + utterance->SetEngineId(voice_extension_id); + utterance->SetOptions(options.get()); + utterance->SetEventDelegate(new TtsExtensionEventHandler(extension_id())); content::TtsController* controller = content::TtsController::GetInstance(); controller->SpeakOrEnqueue(utterance);
diff --git a/chrome/browser/speech/extension_api/tts_extension_apitest.cc b/chrome/browser/speech/extension_api/tts_extension_apitest.cc index aa29bf420..07660ff 100644 --- a/chrome/browser/speech/extension_api/tts_extension_apitest.cc +++ b/chrome/browser/speech/extension_api/tts_extension_apitest.cc
@@ -57,7 +57,7 @@ bool PlatformImplAvailable() override { return true; } void WillSpeakUtteranceWithVoice( - const content::Utterance* utterance, + const content::TtsUtterance* utterance, const content::VoiceData& voice_data) override {} bool LoadBuiltInTtsEngine(content::BrowserContext* browser_context) override {
diff --git a/chrome/browser/speech/tts_chromeos.h b/chrome/browser/speech/tts_chromeos.h index cbd7b234..799d45e 100644 --- a/chrome/browser/speech/tts_chromeos.h +++ b/chrome/browser/speech/tts_chromeos.h
@@ -31,7 +31,7 @@ void Pause() override {} void Resume() override {} void WillSpeakUtteranceWithVoice( - const content::Utterance* utterance, + const content::TtsUtterance* utterance, const content::VoiceData& voice_data) override {} // Get the single instance of this class.
diff --git a/chrome/browser/speech/tts_controller_delegate_impl.cc b/chrome/browser/speech/tts_controller_delegate_impl.cc index b33861e2..dbfed89 100644 --- a/chrome/browser/speech/tts_controller_delegate_impl.cc +++ b/chrome/browser/speech/tts_controller_delegate_impl.cc
@@ -61,7 +61,7 @@ } int TtsControllerDelegateImpl::GetMatchingVoice( - const content::Utterance* utterance, + const content::TtsUtterance* utterance, std::vector<content::VoiceData>& voices) { // Return the index of the voice that best match the utterance parameters. // @@ -102,31 +102,31 @@ int score = 0; // If the extension ID is specified, check for an exact match. - if (!utterance->engine_id().empty() && - utterance->engine_id() != voice.engine_id) + if (!utterance->GetEngineId().empty() && + utterance->GetEngineId() != voice.engine_id) continue; // If the voice name is specified, check for an exact match. - if (!utterance->voice_name().empty() && - voice.name != utterance->voice_name()) + if (!utterance->GetVoiceName().empty() && + voice.name != utterance->GetVoiceName()) continue; // Prefer the utterance language. - if (!voice.lang.empty() && !utterance->lang().empty()) { + if (!voice.lang.empty() && !utterance->GetLang().empty()) { // An exact language match is worth more than a partial match. - if (voice.lang == utterance->lang()) { + if (voice.lang == utterance->GetLang()) { score += 128; } else if (l10n_util::GetLanguage(voice.lang) == - l10n_util::GetLanguage(utterance->lang())) { + l10n_util::GetLanguage(utterance->GetLang())) { score += 64; } } // Next, prefer required event types. - if (utterance->required_event_types().size() > 0) { + if (utterance->GetRequiredEventTypes().size() > 0) { bool has_all_required_event_types = true; - for (auto iter = utterance->required_event_types().begin(); - iter != utterance->required_event_types().end(); ++iter) { + for (auto iter = utterance->GetRequiredEventTypes().begin(); + iter != utterance->GetRequiredEventTypes().end(); ++iter) { if (voice.events.find(*iter) == voice.events.end()) { has_all_required_event_types = false; break; @@ -142,9 +142,9 @@ // First prefer the user's preference voice for the utterance language, // if the utterance language is specified. std::string voice_id; - if (!utterance->lang().empty()) { - lang_to_voice_pref->GetString(l10n_util::GetLanguage(utterance->lang()), - &voice_id); + if (!utterance->GetLang().empty()) { + lang_to_voice_pref->GetString( + l10n_util::GetLanguage(utterance->GetLang()), &voice_id); if (VoiceIdMatches(voice_id, voice)) score += 16; } @@ -187,7 +187,7 @@ } void TtsControllerDelegateImpl::UpdateUtteranceDefaultsFromPrefs( - content::Utterance* utterance, + content::TtsUtterance* utterance, double* rate, double* pitch, double* volume) { @@ -211,12 +211,12 @@ } const PrefService* TtsControllerDelegateImpl::GetPrefService( - const content::Utterance* utterance) { + const content::TtsUtterance* utterance) { const PrefService* prefs = nullptr; - // The utterance->browser_context() is null in tests. - if (utterance->browser_context()) { + // The utterance->GetBrowserContext() is null in tests. + if (utterance->GetBrowserContext()) { const Profile* profile = - Profile::FromBrowserContext(utterance->browser_context()); + Profile::FromBrowserContext(utterance->GetBrowserContext()); if (profile) prefs = profile->GetPrefs(); }
diff --git a/chrome/browser/speech/tts_controller_delegate_impl.h b/chrome/browser/speech/tts_controller_delegate_impl.h index e1c47eb..80a31b0 100644 --- a/chrome/browser/speech/tts_controller_delegate_impl.h +++ b/chrome/browser/speech/tts_controller_delegate_impl.h
@@ -27,9 +27,9 @@ static TtsControllerDelegateImpl* GetInstance(); // TtsControllerDelegate overrides. - int GetMatchingVoice(const content::Utterance* utterance, + int GetMatchingVoice(const content::TtsUtterance* utterance, std::vector<content::VoiceData>& voices) override; - void UpdateUtteranceDefaultsFromPrefs(content::Utterance* utterance, + void UpdateUtteranceDefaultsFromPrefs(content::TtsUtterance* utterance, double* rate, double* pitch, double* volume) override; @@ -47,7 +47,7 @@ TestTtsControllerUtteranceDefaults); virtual const PrefService* GetPrefService( - const content::Utterance* utterance); + const content::TtsUtterance* utterance); friend struct base::DefaultSingletonTraits<TtsControllerDelegateImpl>;
diff --git a/chrome/browser/speech/tts_controller_delegate_impl_unittest.cc b/chrome/browser/speech/tts_controller_delegate_impl_unittest.cc index 4be2c7e..18491cc 100644 --- a/chrome/browser/speech/tts_controller_delegate_impl_unittest.cc +++ b/chrome/browser/speech/tts_controller_delegate_impl_unittest.cc
@@ -5,6 +5,7 @@ // Unit tests for the TTS Controller. #include "chrome/browser/speech/tts_controller_delegate_impl.h" +#include "base/memory/ptr_util.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/common/pref_names.h" @@ -27,7 +28,7 @@ private: const PrefService* GetPrefService( - const content::Utterance* utterance) override { + const content::TtsUtterance* utterance) override { return pref_service_; } }; @@ -51,26 +52,25 @@ { // Calling GetMatchingVoice with no voices returns -1. - content::Utterance utterance(nullptr); + content::TtsUtterance* utterance = content::TtsUtterance::Create(nullptr); std::vector<content::VoiceData> voices; - EXPECT_EQ(-1, - tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + EXPECT_EQ(-1, tts_controller_delegate->GetMatchingVoice(utterance, voices)); } { // Calling GetMatchingVoice with any voices returns the first one // even if there are no criteria that match. - content::Utterance utterance(nullptr); + content::TtsUtterance* utterance = content::TtsUtterance::Create(nullptr); std::vector<content::VoiceData> voices; voices.push_back(content::VoiceData()); voices.push_back(content::VoiceData()); - EXPECT_EQ(0, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + EXPECT_EQ(0, tts_controller_delegate->GetMatchingVoice(utterance, voices)); } { // If nothing else matches, the English voice is returned. // (In tests the language will always be English.) - content::Utterance utterance(nullptr); + content::TtsUtterance* utterance = content::TtsUtterance::Create(nullptr); std::vector<content::VoiceData> voices; content::VoiceData fr_voice; fr_voice.lang = "fr"; @@ -81,7 +81,7 @@ content::VoiceData de_voice; de_voice.lang = "de"; voices.push_back(de_voice); - EXPECT_EQ(1, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + EXPECT_EQ(1, tts_controller_delegate->GetMatchingVoice(utterance, voices)); } { @@ -121,45 +121,45 @@ voice8.native = true; voices.push_back(voice8); - content::Utterance utterance(nullptr); - EXPECT_EQ(0, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + content::TtsUtterance* utterance = content::TtsUtterance::Create(nullptr); + EXPECT_EQ(0, tts_controller_delegate->GetMatchingVoice(utterance, voices)); std::set<content::TtsEventType> types; types.insert(content::TTS_EVENT_WORD); - utterance.set_required_event_types(types); - EXPECT_EQ(1, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetRequiredEventTypes(types); + EXPECT_EQ(1, tts_controller_delegate->GetMatchingVoice(utterance, voices)); - utterance.set_lang("de-DE"); - EXPECT_EQ(2, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetLang("de-DE"); + EXPECT_EQ(2, tts_controller_delegate->GetMatchingVoice(utterance, voices)); - utterance.set_lang("fr-FR"); - EXPECT_EQ(3, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetLang("fr-FR"); + EXPECT_EQ(3, tts_controller_delegate->GetMatchingVoice(utterance, voices)); - utterance.set_voice_name("Voice4"); - EXPECT_EQ(4, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetVoiceName("Voice4"); + EXPECT_EQ(4, tts_controller_delegate->GetMatchingVoice(utterance, voices)); - utterance.set_voice_name(""); - utterance.set_engine_id("id5"); - EXPECT_EQ(5, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetVoiceName(""); + utterance->SetEngineId("id5"); + EXPECT_EQ(5, tts_controller_delegate->GetMatchingVoice(utterance, voices)); #if defined(OS_CHROMEOS) // Voice6 is matched when the utterance locale exactly matches its locale. - utterance.set_engine_id(""); - utterance.set_lang("es-es"); - EXPECT_EQ(6, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetEngineId(""); + utterance->SetLang("es-es"); + EXPECT_EQ(6, tts_controller_delegate->GetMatchingVoice(utterance, voices)); // The 7th voice is the default for "es", even though the utterance is // "es-ar". |voice6| is not matched because it is not the default. - utterance.set_engine_id(""); - utterance.set_lang("es-ar"); - EXPECT_EQ(7, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetEngineId(""); + utterance->SetLang("es-ar"); + EXPECT_EQ(7, tts_controller_delegate->GetMatchingVoice(utterance, voices)); // The 8th voice is like the built-in "Android" voice, it has no lang // and no extension ID. Make sure it can still be matched. - utterance.set_voice_name("Android"); - utterance.set_engine_id(""); - utterance.set_lang(""); - EXPECT_EQ(8, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetVoiceName("Android"); + utterance->SetEngineId(""); + utterance->SetLang(""); + EXPECT_EQ(8, tts_controller_delegate->GetMatchingVoice(utterance, voices)); #endif // defined(OS_CHROMEOS) } @@ -176,17 +176,17 @@ voice1.name = "voice1"; voice1.lang = "en-US"; voices.push_back(voice1); - content::Utterance utterance(nullptr); + content::TtsUtterance* utterance = content::TtsUtterance::Create(nullptr); // voice1 is matched against the exact default system language. g_browser_process->SetApplicationLocale("en-US"); - utterance.set_lang(""); - EXPECT_EQ(1, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetLang(""); + EXPECT_EQ(1, tts_controller_delegate->GetMatchingVoice(utterance, voices)); // voice0 is matched against the system language which has no region piece. g_browser_process->SetApplicationLocale("en"); - utterance.set_lang(""); - EXPECT_EQ(0, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + utterance->SetLang(""); + EXPECT_EQ(0, tts_controller_delegate->GetMatchingVoice(utterance, voices)); #if defined(OS_CHROMEOS) // Add another preference. @@ -200,7 +200,7 @@ // voice0 is matched against the pref over the system language. g_browser_process->SetApplicationLocale("en-US"); - EXPECT_EQ(0, tts_controller_delegate->GetMatchingVoice(&utterance, voices)); + EXPECT_EQ(0, tts_controller_delegate->GetMatchingVoice(utterance, voices)); #endif // defined(OS_CHROMEOS) } } @@ -214,8 +214,8 @@ double pitch = blink::kWebSpeechSynthesisDoublePrefNotSet; double volume = blink::kWebSpeechSynthesisDoublePrefNotSet; - std::unique_ptr<content::Utterance> utterance1 = - std::make_unique<content::Utterance>(nullptr); + std::unique_ptr<content::TtsUtterance> utterance1 = + base::WrapUnique(content::TtsUtterance::Create(nullptr)); tts_controller_delegate->UpdateUtteranceDefaultsFromPrefs( utterance1.get(), &rate, &pitch, &volume); // Updated to global defaults. @@ -233,8 +233,8 @@ pref_service_.registry()->RegisterDoublePref(prefs::kTextToSpeechVolume, 0.5); tts_controller_delegate->pref_service_ = &pref_service_; - std::unique_ptr<content::Utterance> utterance2 = - std::make_unique<content::Utterance>(nullptr); + std::unique_ptr<content::TtsUtterance> utterance2 = + base::WrapUnique(content::TtsUtterance::Create(nullptr)); tts_controller_delegate->UpdateUtteranceDefaultsFromPrefs( utterance2.get(), &rate, &pitch, &volume); // Updated to pref values. @@ -247,8 +247,8 @@ pitch = 1.2f; volume = 1.3f; - std::unique_ptr<content::Utterance> utterance3 = - std::make_unique<content::Utterance>(nullptr); + std::unique_ptr<content::TtsUtterance> utterance3 = + base::WrapUnique(content::TtsUtterance::Create(nullptr)); tts_controller_delegate->UpdateUtteranceDefaultsFromPrefs( utterance3.get(), &rate, &pitch, &volume); // Updated to pref values.
diff --git a/chrome/browser/speech/tts_message_filter.cc b/chrome/browser/speech/tts_message_filter.cc index 7ff9a92..b1ccc84ef 100644 --- a/chrome/browser/speech/tts_message_filter.cc +++ b/chrome/browser/speech/tts_message_filter.cc
@@ -118,18 +118,17 @@ if (!browser_context_) return; - std::unique_ptr<content::Utterance> utterance( - new content::Utterance(browser_context_)); - utterance->set_src_id(request.id); - utterance->set_text(request.text); - utterance->set_lang(request.lang); - utterance->set_voice_name(request.voice); - utterance->set_can_enqueue(true); - utterance->set_continuous_parameters(request.rate, - request.pitch, - request.volume); + std::unique_ptr<content::TtsUtterance> utterance( + content::TtsUtterance::Create((browser_context_))); + utterance->SetSrcId(request.id); + utterance->SetText(request.text); + utterance->SetLang(request.lang); + utterance->SetVoiceName(request.voice); + utterance->SetCanEnqueue(true); + utterance->SetContinuousParameters(request.rate, request.pitch, + request.volume); - utterance->set_event_delegate(this); + utterance->SetEventDelegate(this); content::TtsController::GetInstance()->SpeakOrEnqueue(utterance.release()); } @@ -149,7 +148,7 @@ content::TtsController::GetInstance()->Stop(); } -void TtsMessageFilter::OnTtsEvent(content::Utterance* utterance, +void TtsMessageFilter::OnTtsEvent(content::TtsUtterance* utterance, content::TtsEventType event_type, int char_index, const std::string& error_message) { @@ -159,35 +158,35 @@ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); switch (event_type) { case content::TTS_EVENT_START: - Send(new TtsMsg_DidStartSpeaking(utterance->src_id())); + Send(new TtsMsg_DidStartSpeaking(utterance->GetSrcId())); break; case content::TTS_EVENT_END: - Send(new TtsMsg_DidFinishSpeaking(utterance->src_id())); + Send(new TtsMsg_DidFinishSpeaking(utterance->GetSrcId())); break; case content::TTS_EVENT_WORD: - Send(new TtsMsg_WordBoundary(utterance->src_id(), char_index)); + Send(new TtsMsg_WordBoundary(utterance->GetSrcId(), char_index)); break; case content::TTS_EVENT_SENTENCE: - Send(new TtsMsg_SentenceBoundary(utterance->src_id(), char_index)); + Send(new TtsMsg_SentenceBoundary(utterance->GetSrcId(), char_index)); break; case content::TTS_EVENT_MARKER: - Send(new TtsMsg_MarkerEvent(utterance->src_id(), char_index)); + Send(new TtsMsg_MarkerEvent(utterance->GetSrcId(), char_index)); break; case content::TTS_EVENT_INTERRUPTED: - Send(new TtsMsg_WasInterrupted(utterance->src_id())); + Send(new TtsMsg_WasInterrupted(utterance->GetSrcId())); break; case content::TTS_EVENT_CANCELLED: - Send(new TtsMsg_WasCancelled(utterance->src_id())); + Send(new TtsMsg_WasCancelled(utterance->GetSrcId())); break; case content::TTS_EVENT_ERROR: - Send(new TtsMsg_SpeakingErrorOccurred( - utterance->src_id(), error_message)); + Send(new TtsMsg_SpeakingErrorOccurred(utterance->GetSrcId(), + error_message)); break; case content::TTS_EVENT_PAUSE: - Send(new TtsMsg_DidPauseSpeaking(utterance->src_id())); + Send(new TtsMsg_DidPauseSpeaking(utterance->GetSrcId())); break; case content::TTS_EVENT_RESUME: - Send(new TtsMsg_DidResumeSpeaking(utterance->src_id())); + Send(new TtsMsg_DidResumeSpeaking(utterance->GetSrcId())); break; } }
diff --git a/chrome/browser/speech/tts_message_filter.h b/chrome/browser/speech/tts_message_filter.h index 2fbbc4b4..37c62a4 100644 --- a/chrome/browser/speech/tts_message_filter.h +++ b/chrome/browser/speech/tts_message_filter.h
@@ -35,7 +35,7 @@ void OnDestruct() const override; // UtteranceEventDelegate implementation. - void OnTtsEvent(content::Utterance* utterance, + void OnTtsEvent(content::TtsUtterance* utterance, content::TtsEventType event_type, int char_index, const std::string& error_message) override;
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc index c70c1a8..e837907a 100644 --- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc +++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -419,7 +419,8 @@ EXPECT_TRUE(!!security_info.certificate); } -void CheckSecurityInfoForNonSecure(content::WebContents* contents) { +// Check that the current SecurityInfo reflects a non-committed navigation. +void CheckSecurityInfoForNonCommitted(content::WebContents* contents) { ASSERT_TRUE(contents); SecurityStateTabHelper* helper = @@ -638,9 +639,9 @@ security_info.mixed_content_status); EXPECT_FALSE(security_info.scheme_is_cryptographic); EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); - // TODO(dmcardle): Should determine the expected value for - // |security_info.connection_info_initialized|. Follow up with estark. - // See crbug.com/780972 + // We expect that the SecurityInfo fields for this committed navigation will + // be initialized to reflect the unencrypted connection. + EXPECT_TRUE(security_info.connection_info_initialized); EXPECT_FALSE(!!security_info.certificate); EXPECT_EQ(0, security_info.connection_status); } @@ -1388,7 +1389,7 @@ browser()->OpenURL(content::OpenURLParams( embedded_test_server()->GetURL("/title1.html"), content::Referrer(), WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); - CheckSecurityInfoForNonSecure( + CheckSecurityInfoForNonCommitted( browser()->tab_strip_model()->GetActiveWebContents()); } @@ -2005,7 +2006,7 @@ content::WebContents::CreateParams(tab->GetBrowserContext())); content::NavigationController& controller = new_contents->GetController(); SecurityStateTabHelper::CreateForWebContents(new_contents.get()); - CheckSecurityInfoForNonSecure(new_contents.get()); + CheckSecurityInfoForNonCommitted(new_contents.get()); controller.LoadURL(https_server_.GetURL("/title1.html"), content::Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); EXPECT_TRUE(content::WaitForLoadStop(new_contents.get()));
diff --git a/chrome/browser/sync/test/integration/two_client_wallet_sync_test.cc b/chrome/browser/sync/test/integration/two_client_wallet_sync_test.cc index 1730bc2a..818cb34 100644 --- a/chrome/browser/sync/test/integration/two_client_wallet_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_wallet_sync_test.cc
@@ -57,14 +57,19 @@ bool SetupSync() override { test_clock_.SetNow(kArbitraryDefaultTime); + // Plug in SyncService into PDM so that it can check we use full sync. We + // need to do it before starting the sync in SetupSync(). We need to setup + // the clients before that so we can access their sync service. + if (!SetupClients()) { + return false; + } + GetPersonalDataManager(0)->OnSyncServiceInitialized(GetSyncService(0)); + GetPersonalDataManager(1)->OnSyncServiceInitialized(GetSyncService(1)); + if (!SyncTest::SetupSync()) { return false; } - // Plug in SyncService into PDM so that it can check we use full sync. - GetPersonalDataManager(0)->OnSyncServiceInitialized(GetSyncService(0)); - GetPersonalDataManager(1)->OnSyncServiceInitialized(GetSyncService(1)); - // As this test does not use self notifications, wait for the metadata to // converge with the specialized wallet checker. return AutofillWalletChecker(0, 1).Wait();
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm index 18018101..3ff33b4 100644 --- a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm
@@ -35,6 +35,7 @@ MockTRS(Profile* profile) : sessions::TabRestoreServiceImpl( base::WrapUnique(new ChromeTabRestoreServiceClient(profile)), + profile->GetPrefs(), nullptr) {} MOCK_CONST_METHOD0(entries, const sessions::TabRestoreService::Entries&()); };
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index 75ca152..ac813a6 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/feature_list.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -20,6 +21,7 @@ #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_features.h" #include "content/public/common/url_constants.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -345,6 +347,11 @@ // Tests mouse lock then fullscreen. IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, MouseLockThenFullscreen) { + if (base::FeatureList::IsEnabled(features::kUserActivationV2)) { + // TODO(mustaq): UAv2 seems to make this flaky (http://crbug.com/913409). + return; + } + ASSERT_TRUE(embedded_test_server()->Start()); ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL(kFullscreenMouseLockHTML));
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.cc b/chrome/browser/ui/extensions/extension_action_view_controller.cc index f2cea443..dc82fa71 100644 --- a/chrome/browser/ui/extensions/extension_action_view_controller.cc +++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/extensions/extension_action_view_controller.h" +#include <memory> +#include <string> #include <utility> #include "base/logging.h" @@ -385,9 +387,9 @@ if (already_showing) return false; - std::unique_ptr<extensions::ExtensionViewHost> host( + std::unique_ptr<extensions::ExtensionViewHost> host = extensions::ExtensionViewHostFactory::CreatePopupHost(popup_url, - browser_)); + browser_); if (!host) return false;
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc index ecb6a4c..4f3a2a3 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -85,13 +85,11 @@ signin_metrics::AccessPoint signin_access_point, signin_metrics::Reason signin_reason, ProfileMode profile_mode, - StartSyncMode start_mode, ConfirmationRequired confirmation_required, Callback sync_setup_completed_callback) : profile_(nullptr), signin_access_point_(signin_access_point), signin_reason_(signin_reason), - start_mode_(start_mode), confirmation_required_(confirmation_required), sync_setup_completed_callback_(sync_setup_completed_callback), first_account_added_to_cookie_(false), @@ -416,19 +414,6 @@ base::RecordAction(base::UserMetricsAction("Signin_Undo_Signin")); CancelSigninAndDelete(); // This statement frees this object. } else { - // If the user clicked the "Advanced" link in the confirmation dialog, then - // override the current start_mode_ to bring up the advanced sync settings. - - // If the user signs in from the new avatar bubble, the untrusted dialog - // would dismiss the avatar bubble, thus it won't show any confirmation upon - // sign in completes. This dialog already has a settings link, thus we just - // start sync immediately . - - if (response == CONFIGURE_SYNC_FIRST) - start_mode_ = response; - else if (start_mode_ == CONFIRM_SYNC_SETTINGS_FIRST) - start_mode_ = SYNC_WITH_DEFAULT_SETTINGS; - SigninManager* signin = SigninManagerFactory::GetForProfile(profile_); signin->CompletePendingSignin(); } @@ -511,9 +496,7 @@ // Regardless of whether the account was successfully added or not, // continue with sync starting. - // The sync confirmation dialog should always be shown regardless of - // |start_mode_|. |sync_setup_completed_callback_| will be run after the - // modal is closed. + // |sync_setup_completed_callback_| will be run after the modal is closed. DisplayModalSyncConfirmationWindow(); }
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.h b/chrome/browser/ui/sync/one_click_signin_sync_starter.h index a045b11e5..3d3144ca 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter.h +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.h
@@ -100,7 +100,6 @@ signin_metrics::AccessPoint signin_access_point, signin_metrics::Reason signin_reason, ProfileMode profile_mode, - StartSyncMode start_mode, ConfirmationRequired display_confirmation, Callback callback); @@ -212,7 +211,6 @@ signin_metrics::AccessPoint signin_access_point_; signin_metrics::Reason signin_reason_; std::unique_ptr<SigninTracker> signin_tracker_; - StartSyncMode start_mode_; ConfirmationRequired confirmation_required_; // Callback executed when sync setup succeeds or fails.
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc index bd27421d..ad08bf9 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc
@@ -78,7 +78,6 @@ kTestingRefreshToken, signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN, signin_metrics::Reason::REASON_UNKNOWN_REASON, OneClickSigninSyncStarter::CURRENT_PROFILE, - OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS, OneClickSigninSyncStarter::NO_CONFIRMATION, callback); }
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc index f744ab88..e471798eb 100644 --- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc
@@ -161,7 +161,7 @@ return std::make_unique<sessions::TabRestoreServiceImpl>( base::WrapUnique(new ChromeTabRestoreServiceClient( Profile::FromBrowserContext(browser_context))), - nullptr); + nullptr, nullptr); } void RegisterRecentTabs(RecentTabsBuilderTestHelper* helper) {
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.cc b/chrome/browser/ui/views/extensions/extension_dialog.cc index 97aec52a..20b08573 100644 --- a/chrome/browser/ui/views/extensions/extension_dialog.cc +++ b/chrome/browser/ui/views/extensions/extension_dialog.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/ui/views/extensions/extension_dialog.h" +#include <memory> +#include <utility> + #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_view_host.h" #include "chrome/browser/extensions/extension_view_host_factory.h" @@ -32,23 +35,22 @@ using content::BrowserContext; using content::WebContents; -ExtensionDialog::ExtensionDialog(extensions::ExtensionViewHost* host, - ExtensionDialogObserver* observer) - : host_(host), - observer_(observer) { +ExtensionDialog::ExtensionDialog( + std::unique_ptr<extensions::ExtensionViewHost> host, + ExtensionDialogObserver* observer) + : host_(std::move(host)), observer_(observer) { AddRef(); // Balanced in DeleteDelegate(); registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD, - content::Source<BrowserContext>(host->browser_context())); + content::Source<BrowserContext>(host_->browser_context())); // Listen for the containing view calling window.close(); registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, - content::Source<BrowserContext>(host->browser_context())); + content::Source<BrowserContext>(host_->browser_context())); // Listen for a crash or other termination of the extension process. - registrar_.Add(this, - extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, - content::Source<BrowserContext>(host->browser_context())); + registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, + content::Source<BrowserContext>(host_->browser_context())); chrome::RecordDialogCreation(chrome::DialogIdentifier::EXTENSION); } @@ -67,19 +69,20 @@ int min_height, const base::string16& title, ExtensionDialogObserver* observer) { - extensions::ExtensionViewHost* host = + std::unique_ptr<extensions::ExtensionViewHost> host = extensions::ExtensionViewHostFactory::CreateDialogHost(url, profile); if (!host) return NULL; // Preferred size must be set before views::Widget::CreateWindowWithParent // is called because CreateWindowWithParent refers the result of CanResize(). - ExtensionViewViews* view = GetExtensionView(host); + ExtensionViewViews* view = GetExtensionView(host.get()); view->SetPreferredSize(gfx::Size(width, height)); view->set_minimum_size(gfx::Size(min_width, min_height)); host->SetAssociatedWebContents(web_contents); DCHECK(parent_window); - ExtensionDialog* dialog = new ExtensionDialog(host, observer); + extensions::ExtensionViewHost* host_ptr = host.get(); + ExtensionDialog* dialog = new ExtensionDialog(std::move(host), observer); dialog->set_title(title); dialog->InitWindow(parent_window, is_modal, width, height); @@ -89,7 +92,7 @@ view->SetVisible(true); // Ensure the DOM JavaScript can respond immediately to keyboard shortcuts. - host->host_contents()->Focus(); + host_ptr->host_contents()->Focus(); return dialog; }
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.h b/chrome/browser/ui/views/extensions/extension_dialog.h index 587f4150..6dc0c7b 100644 --- a/chrome/browser/ui/views/extensions/extension_dialog.h +++ b/chrome/browser/ui/views/extensions/extension_dialog.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_DIALOG_H_ #define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_DIALOG_H_ +#include <memory> + #include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -91,7 +93,7 @@ friend class base::RefCounted<ExtensionDialog>; // Use Show() to create instances. - ExtensionDialog(extensions::ExtensionViewHost* host, + ExtensionDialog(std::unique_ptr<extensions::ExtensionViewHost> host, ExtensionDialogObserver* observer); void InitWindow(gfx::NativeWindow parent_window,
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc index 3b68e81..223ed1e 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
@@ -171,7 +171,6 @@ browser()->tab_strip_model()->GetActiveWebContents()->IsLoading()); } -// If this flakes, disable and log details in http://crbug.com/523255. IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnClick) { OmniboxView* omnibox_view = NULL; ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view));
diff --git a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc index 95f0eff6..71a7acc 100644 --- a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc +++ b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc
@@ -105,14 +105,7 @@ } // namespace ChromeCleanupHandler::ChromeCleanupHandler(Profile* profile) - : controller_(ChromeCleanerController::GetInstance()), profile_(profile) { - DCHECK(g_browser_process->local_state()); - logs_enabled_pref_.Init(g_browser_process->local_state()); - logs_enabled_pref_.Add( - prefs::kSwReporterReportingEnabled, - base::BindRepeating(&ChromeCleanupHandler::OnLogsEnabledPrefChanged, - base::Unretained(this))); -} + : controller_(ChromeCleanerController::GetInstance()), profile_(profile) {} ChromeCleanupHandler::~ChromeCleanupHandler() { controller_->RemoveObserver(this); @@ -133,10 +126,6 @@ base::BindRepeating(&ChromeCleanupHandler::HandleRestartComputer, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "setLogsUploadPermission", - base::BindRepeating(&ChromeCleanupHandler::HandleSetLogsUploadPermission, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( "startCleanup", base::BindRepeating(&ChromeCleanupHandler::HandleStartCleanup, base::Unretained(this))); @@ -202,18 +191,6 @@ FireWebUIListener("chrome-cleanup-on-reboot-required"); } -void ChromeCleanupHandler::OnLogsEnabledChanged(bool logs_enabled) { - FireWebUIListener("chrome-cleanup-upload-permission-change", - base::Value(controller_->IsReportingManagedByPolicy()), - base::Value(logs_enabled)); -} - -void ChromeCleanupHandler::OnLogsEnabledPrefChanged() { - bool is_enabled = controller_->IsReportingAllowedByPolicy(); - controller_->SetLogsEnabled(is_enabled); - OnLogsEnabledChanged(is_enabled); -} - void ChromeCleanupHandler::HandleRegisterChromeCleanerObserver( const base::ListValue* args) { DCHECK_EQ(0U, args->GetSize()); @@ -223,9 +200,6 @@ base::UserMetricsAction("SoftwareReporter.CleanupWebui_Shown")); AllowJavascript(); - // Send the current logs upload state. - OnLogsEnabledChanged(controller_->logs_enabled()); - FireWebUIListener("chrome-cleanup-enabled-change", base::Value(controller_->IsAllowedByPolicy())); } @@ -256,23 +230,6 @@ controller_->Reboot(); } -void ChromeCleanupHandler::HandleSetLogsUploadPermission( - const base::ListValue* args) { - CHECK_EQ(1U, args->GetSize()); - bool allow_logs_upload = false; - args->GetBoolean(0, &allow_logs_upload); - - if (allow_logs_upload) { - base::RecordAction(base::UserMetricsAction( - "SoftwareReporter.CleanupWebui_LogsUploadEnabled")); - } else { - base::RecordAction(base::UserMetricsAction( - "SoftwareReporter.CleanupWebui_LogsUploadDisabled")); - } - - controller_->SetLogsEnabled(allow_logs_upload); -} - void ChromeCleanupHandler::HandleStartCleanup(const base::ListValue* args) { CHECK_EQ(1U, args->GetSize()); bool allow_logs_upload = false;
diff --git a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h index eb8df32..fffa41c1 100644 --- a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h +++ b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h
@@ -43,12 +43,8 @@ const safe_browsing::ChromeCleanerScannerResults& reported_results) override; void OnRebootRequired() override; - void OnLogsEnabledChanged(bool logs_enabled) override; private: - // Called when prefs::kSwReporterReportingEnabled changes. - void OnLogsEnabledPrefChanged(); - // Callback for the "registerChromeCleanerObserver" message. This registers // this object as an observer of the Chrome Cleanup global state and // and retrieves the current cleanup state. @@ -62,10 +58,6 @@ // system restart. void HandleRestartComputer(const base::ListValue* args); - // Callback for the "setLogsUploadPermission" message to keep track of - // whether the user opted-out of logs upload or not. - void HandleSetLogsUploadPermission(const base::ListValue* args); - // Callback for the "startCleanup" message to start removing unwanted // software from the user's computer. void HandleStartCleanup(const base::ListValue* args); @@ -92,7 +84,6 @@ safe_browsing::ChromeCleanerController* controller_; Profile* profile_; - PrefChangeRegistrar logs_enabled_pref_; DISALLOW_COPY_AND_ASSIGN(ChromeCleanupHandler); };
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 6d039f13..96ac9ef 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -941,7 +941,6 @@ IDS_SETTINGS_RESET_CLEANUP_FIND_BUTTON_LABEL}, {"chromeCleanupLinkShowItems", IDS_SETTINGS_RESET_CLEANUP_LINK_SHOW_FILES}, - {"chromeCleanupLogsUploadPermission", IDS_CHROME_CLEANUP_LOGS_PERMISSION}, {"chromeCleanupRemoveButtonLabel", IDS_SETTINGS_RESET_CLEANUP_REMOVE_BUTTON_LABEL}, {"chromeCleanupRestartButtonLabel", @@ -951,7 +950,7 @@ {"chromeCleanupTitleErrorPermissions", IDS_SETTINGS_RESET_CLEANUP_TITLE_ERROR_PERMISSIONS_NEEDED}, {"chromeCleanupTitleFindAndRemove", - IDS_SETTINGS_RESET_CLEANUP_TITLE_FIND_AND_REMOVE}, + IDS_SETTINGS_RESET_CLEANUP_TITLE_FIND_HARMFUL_SOFTWARE}, {"chromeCleanupTitleNoInternet", IDS_SETTINGS_RESET_CLEANUP_TITLE_NO_INTERNET_CONNECTION}, {"chromeCleanupTitleNothingFound", @@ -965,8 +964,8 @@ IDS_SETTINGS_RESET_CLEANUP_TITLE_ERROR_SCANNING_FAILED}, {"chromeCleanupTitleTryAgainButtonLabel", IDS_SETTINGS_RESET_CLEANUP_TRY_AGAIN_BUTTON_LABEL}, - {"chromeCleanupTitleLogsPermissionExplanation", - IDS_SETTINGS_RESET_CLEANUP_LOGS_PERMISSION_EXPLANATION}, + {"chromeCleanupExplanationLogsPermissionPref", + IDS_SETTINGS_RESET_CLEANUP_LOGS_PERMISSION_PREF}, {"chromeCleanupTitleCleanupUnavailable", IDS_SETTINGS_RESET_CLEANUP_TITLE_CLEANUP_UNAVAILABLE}, {"chromeCleanupExplanationCleanupUnavailable", @@ -1788,12 +1787,6 @@ } html_source->AddString("syncLearnMoreUrl", chrome::kSyncLearnMoreURL); - html_source->AddString("autofillHelpURL", -#if defined(OS_CHROMEOS) - GetHelpUrlWithBoard(autofill::kHelpURL)); -#else - autofill::kHelpURL); -#endif html_source->AddString("supervisedUsersUrl", chrome::kLegacySupervisedUserManagementURL);
diff --git a/chrome/browser/ui/webui/settings/tts_handler.cc b/chrome/browser/ui/webui/settings/tts_handler.cc index 243713f1..c3f553c2 100644 --- a/chrome/browser/ui/webui/settings/tts_handler.cc +++ b/chrome/browser/ui/webui/settings/tts_handler.cc
@@ -108,7 +108,7 @@ HandleGetTtsExtensions(nullptr); } -void TtsHandler::OnTtsEvent(content::Utterance* utterance, +void TtsHandler::OnTtsEvent(content::TtsUtterance* utterance, content::TtsEventType event_type, int char_index, const std::string& error_message) { @@ -137,13 +137,13 @@ json->GetString("name", &name); json->GetString("extension", &extension_id); - content::Utterance* utterance = - new content::Utterance(Profile::FromWebUI(web_ui())); - utterance->set_text(text); - utterance->set_voice_name(name); - utterance->set_engine_id(extension_id); - utterance->set_src_url(GURL("chrome://settings/manageAccessibility/tts")); - utterance->set_event_delegate(this); + content::TtsUtterance* utterance = + content::TtsUtterance::Create((Profile::FromWebUI(web_ui()))); + utterance->SetText(text); + utterance->SetVoiceName(name); + utterance->SetEngineId(extension_id); + utterance->SetSrcUrl(GURL("chrome://settings/manageAccessibility/tts")); + utterance->SetEventDelegate(this); content::TtsController::GetInstance()->Stop(); base::Value result(true /* preview started */);
diff --git a/chrome/browser/ui/webui/settings/tts_handler.h b/chrome/browser/ui/webui/settings/tts_handler.h index 84ec122..93fd5b90 100644 --- a/chrome/browser/ui/webui/settings/tts_handler.h +++ b/chrome/browser/ui/webui/settings/tts_handler.h
@@ -34,7 +34,7 @@ void OnVoicesChanged() override; // UtteranceEventDelegate implementation. - void OnTtsEvent(content::Utterance* utterance, + void OnTtsEvent(content::TtsUtterance* utterance, content::TtsEventType event_type, int char_index, const std::string& error_message) override;
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index f74d567..d4e81298 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -36,10 +36,8 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/local_auth.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/signin/signin_promo.h" #include "chrome/browser/signin/signin_util.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" @@ -60,7 +58,6 @@ #include "components/signin/core/browser/about_signin_internals.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" -#include "components/signin/core/browser/signin_error_controller.h" #include "components/signin/core/browser/signin_header_helper.h" #include "components/signin/core/browser/signin_investigator.h" #include "components/signin/core/browser/signin_metrics.h" @@ -176,7 +173,6 @@ const std::string& password, const std::string& auth_code, const std::string& signin_scoped_device_id, - bool choose_what_to_sync, bool confirm_untrusted_signin, bool is_force_sign_in_with_usermanager) : gaia_auth_fetcher_(this, gaia::GaiaSource::kChrome, url_loader_factory), @@ -188,7 +184,6 @@ gaia_id_(gaia_id), password_(password), auth_code_(auth_code), - choose_what_to_sync_(choose_what_to_sync), confirm_untrusted_signin_(confirm_untrusted_signin), is_force_sign_in_with_usermanager_(is_force_sign_in_with_usermanager) { DCHECK(profile_); @@ -224,8 +219,6 @@ browser = handler_->GetDesktopBrowser(); } - signin_metrics::AccessPoint access_point = - signin::GetAccessPointForPromoURL(current_url_); signin_metrics::Reason reason = signin::GetSigninReasonForPromoURL(current_url_); if (reason == signin_metrics::Reason::REASON_FETCH_LST_ONLY) { @@ -313,32 +306,16 @@ } LogSigninReason(reason); } else { - browser_sync::ProfileSyncService* sync_service = - ProfileSyncServiceFactory::GetForProfile(profile_); - SigninErrorController* error_controller = - SigninErrorControllerFactory::GetForProfile(profile_); - - OneClickSigninSyncStarter::StartSyncMode start_mode = - OneClickSigninSyncStarter::CONFIRM_SYNC_SETTINGS_FIRST; - if (access_point == signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS || - choose_what_to_sync_) { - bool show_settings_without_configure = - error_controller->HasError() && sync_service && - sync_service->IsFirstSetupComplete(); - if (!show_settings_without_configure) - start_mode = OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST; - } - OneClickSigninSyncStarter::ConfirmationRequired confirmation_required = confirm_untrusted_signin_ ? OneClickSigninSyncStarter::CONFIRM_UNTRUSTED_SIGNIN : OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN; - bool start_signin = !HandleCrossAccountError( - result.refresh_token, confirmation_required, start_mode); + bool start_signin = + !HandleCrossAccountError(result.refresh_token, confirmation_required); if (start_signin) { CreateSyncStarter(browser, current_url_, result.refresh_token, - OneClickSigninSyncStarter::CURRENT_PROFILE, start_mode, + OneClickSigninSyncStarter::CURRENT_PROFILE, confirmation_required); base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); } @@ -350,21 +327,19 @@ const GURL& current_url, const std::string& refresh_token, OneClickSigninSyncStarter::ProfileMode profile_mode, - OneClickSigninSyncStarter::StartSyncMode start_mode, OneClickSigninSyncStarter::ConfirmationRequired confirmation_required) { // OneClickSigninSyncStarter will delete itself once the job is done. new OneClickSigninSyncStarter( profile_, browser, gaia_id_, email_, password_, refresh_token, signin::GetAccessPointForPromoURL(current_url), - signin::GetSigninReasonForPromoURL(current_url), profile_mode, start_mode, + signin::GetSigninReasonForPromoURL(current_url), profile_mode, confirmation_required, base::Bind(&InlineLoginHandlerImpl::SyncStarterCallback, handler_)); } bool InlineSigninHelper::HandleCrossAccountError( const std::string& refresh_token, - OneClickSigninSyncStarter::ConfirmationRequired confirmation_required, - OneClickSigninSyncStarter::StartSyncMode start_mode) { + OneClickSigninSyncStarter::ConfirmationRequired confirmation_required) { // With force sign in enabled, cross account // sign in will be rejected in the early stage so there is no need to show the // warning page here. @@ -386,7 +361,7 @@ web_contents, profile_, last_email, email_, base::Bind(&InlineSigninHelper::ConfirmEmailAction, base::Unretained(this), web_contents, refresh_token, - confirmation_required, start_mode)); + confirmation_required)); return true; } @@ -394,7 +369,6 @@ content::WebContents* web_contents, const std::string& refresh_token, OneClickSigninSyncStarter::ConfirmationRequired confirmation_required, - OneClickSigninSyncStarter::StartSyncMode start_mode, SigninEmailConfirmationDialog::Action action) { Browser* browser = chrome::FindLastActiveWithProfile(profile_); switch (action) { @@ -402,14 +376,14 @@ base::RecordAction( base::UserMetricsAction("Signin_ImportDataPrompt_DontImport")); CreateSyncStarter(browser, current_url_, refresh_token, - OneClickSigninSyncStarter::NEW_PROFILE, start_mode, + OneClickSigninSyncStarter::NEW_PROFILE, confirmation_required); break; case SigninEmailConfirmationDialog::START_SYNC: base::RecordAction( base::UserMetricsAction("Signin_ImportDataPrompt_ImportData")); CreateSyncStarter(browser, current_url_, refresh_token, - OneClickSigninSyncStarter::CURRENT_PROFILE, start_mode, + OneClickSigninSyncStarter::CURRENT_PROFILE, confirmation_required); break; case SigninEmailConfirmationDialog::CLOSE: @@ -731,7 +705,7 @@ handler_weak_ptr, params.partition->GetURLLoaderFactoryForBrowserProcess(), profile, status, params.url, params.email, params.gaia_id, params.password, - params.auth_code, signin_scoped_device_id, params.choose_what_to_sync, + params.auth_code, signin_scoped_device_id, params.confirm_untrusted_signin, params.is_force_sign_in_with_usermanager);
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.h b/chrome/browser/ui/webui/signin/inline_login_handler_impl.h index f44827d..a41315b 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.h +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.h
@@ -148,7 +148,6 @@ const std::string& password, const std::string& auth_code, const std::string& signin_scoped_device_id, - bool choose_what_to_sync, bool confirm_untrusted_signin, bool is_force_sign_in_with_usermanager); ~InlineSigninHelper() override; @@ -163,15 +162,13 @@ // cross account error, and false otherwise. bool HandleCrossAccountError( const std::string& refresh_token, - OneClickSigninSyncStarter::ConfirmationRequired confirmation_required, - OneClickSigninSyncStarter::StartSyncMode start_mode); + OneClickSigninSyncStarter::ConfirmationRequired confirmation_required); // Callback used with ConfirmEmailDialogDelegate. void ConfirmEmailAction( content::WebContents* web_contents, const std::string& refresh_token, OneClickSigninSyncStarter::ConfirmationRequired confirmation_required, - OneClickSigninSyncStarter::StartSyncMode start_mode, SigninEmailConfirmationDialog::Action action); // Overridden from GaiaAuthConsumer. @@ -190,7 +187,6 @@ const GURL& current_url, const std::string& refresh_token, OneClickSigninSyncStarter::ProfileMode profile_mode, - OneClickSigninSyncStarter::StartSyncMode start_mode, OneClickSigninSyncStarter::ConfirmationRequired confirmation_required); GaiaAuthFetcher gaia_auth_fetcher_; @@ -202,7 +198,6 @@ std::string gaia_id_; std::string password_; std::string auth_code_; - bool choose_what_to_sync_; bool confirm_untrusted_signin_; bool is_force_sign_in_with_usermanager_;
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc b/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc index 2bed898f..211025df 100644 --- a/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc +++ b/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc
@@ -164,17 +164,15 @@ const std::string& password, const std::string& auth_code, const std::string& signin_scoped_device_id, - bool choose_what_to_sync, bool confirm_untrusted_signin); MOCK_METHOD1(OnClientOAuthSuccess, void(const ClientOAuthResult& result)); MOCK_METHOD1(OnClientOAuthFailure, void(const GoogleServiceAuthError& error)); - MOCK_METHOD6(CreateSyncStarter, + MOCK_METHOD5(CreateSyncStarter, void(Browser*, const GURL&, const std::string&, OneClickSigninSyncStarter::ProfileMode, - OneClickSigninSyncStarter::StartSyncMode, OneClickSigninSyncStarter::ConfirmationRequired)); GaiaAuthFetcher* GetGaiaAuthFetcher() { return GetGaiaAuthFetcherForTest(); } @@ -193,7 +191,6 @@ const std::string& password, const std::string& auth_code, const std::string& signin_scoped_device_id, - bool choose_what_to_sync, bool confirm_untrusted_signin) : InlineSigninHelper(handler, url_loader_factory, @@ -205,7 +202,6 @@ password, auth_code, signin_scoped_device_id, - choose_what_to_sync, confirm_untrusted_signin, false) {} @@ -223,16 +219,14 @@ const std::string& password, const std::string& auth_code, const std::string& signin_scoped_device_id, - bool choose_what_to_sync, bool confirm_untrusted_signin, bool is_force_sign_in_with_usermanager); - MOCK_METHOD6(CreateSyncStarter, + MOCK_METHOD5(CreateSyncStarter, void(Browser*, const GURL&, const std::string&, OneClickSigninSyncStarter::ProfileMode, - OneClickSigninSyncStarter::StartSyncMode, OneClickSigninSyncStarter::ConfirmationRequired)); private: @@ -249,7 +243,6 @@ const std::string& password, const std::string& auth_code, const std::string& signin_scoped_device_id, - bool choose_what_to_sync, bool confirm_untrusted_signin, bool is_force_sign_in_with_usermanager) : InlineSigninHelper(handler, @@ -262,7 +255,6 @@ password, auth_code, signin_scoped_device_id, - choose_what_to_sync, confirm_untrusted_signin, is_force_sign_in_with_usermanager) {} @@ -551,7 +543,6 @@ "gaiaid-12345", "password", "auth_code", // auth code std::string(), - false, // choose what to sync false); // confirm untrusted signin base::RunLoop run_loop; EXPECT_CALL(helper, OnClientOAuthSuccess(_)) @@ -587,14 +578,12 @@ "password", "auth_code", // auth code std::string(), - false, // choose what to sync false, // confirm untrusted signin false); EXPECT_CALL( *helper, CreateSyncStarter(_, _, "refresh_token", OneClickSigninSyncStarter::CURRENT_PROFILE, - OneClickSigninSyncStarter::CONFIRM_SYNC_SETTINGS_FIRST, OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN)); ProfileAttributesEntry* entry; @@ -630,13 +619,11 @@ "foo@gmail.com", "gaiaid-12345", "password", "auth_code", // auth code std::string(), - true, // choose what to sync false, // confirm untrusted signin false); EXPECT_CALL(*helper, CreateSyncStarter( _, _, "refresh_token", OneClickSigninSyncStarter::CURRENT_PROFILE, - OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST, OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN)); SimulateOnClientOAuthSuccess(helper, "refresh_token"); @@ -660,14 +647,12 @@ "foo@gmail.com", "gaiaid-12345", "password", "auth_code", // auth code std::string(), - false, // choose what to sync true, // confirm untrusted signin false); EXPECT_CALL( *helper, CreateSyncStarter(_, _, "refresh_token", OneClickSigninSyncStarter::CURRENT_PROFILE, - OneClickSigninSyncStarter::CONFIRM_SYNC_SETTINGS_FIRST, OneClickSigninSyncStarter::CONFIRM_UNTRUSTED_SIGNIN)); SimulateOnClientOAuthSuccess(helper, "refresh_token"); @@ -691,7 +676,6 @@ "foo@gmail.com", "gaiaid-12345", "password", "auth_code", // auth code std::string(), - false, // choose what to sync false, // confirm untrusted signin false); @@ -700,7 +684,6 @@ EXPECT_CALL(*helper, CreateSyncStarter( _, _, "refresh_token", OneClickSigninSyncStarter::CURRENT_PROFILE, - OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST, OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN)); SimulateOnClientOAuthSuccess(helper, "refresh_token"); @@ -722,7 +705,6 @@ url, "foo@gmail.com", "gaiaid-12345", "password", "auth_code", // auth code std::string(), - false, // choose what to sync false, // confirm untrusted signin false); SimulateOnClientOAuthSuccess(&helper, "refresh_token"); @@ -746,7 +728,6 @@ url, "foo@gmail.com", "gaiaid-12345", "password", "auth_code", // auth code std::string(), - false, // choose what to sync false, // confirm untrusted signin false); SimulateOnClientOAuthSuccess(&helper, "refresh_token"); @@ -765,12 +746,11 @@ new MockSyncStarterInlineSigninHelper( handler, test_shared_loader_factory(), browser()->profile(), url, "foo@gmail.com", "gaiaid-12345", "password", "auth_code", - std::string(), false, false, true); + std::string(), false, true); EXPECT_CALL( *helper, CreateSyncStarter(_, _, "refresh_token", OneClickSigninSyncStarter::CURRENT_PROFILE, - OneClickSigninSyncStarter::CONFIRM_SYNC_SETTINGS_FIRST, OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN)); ProfileAttributesEntry* entry;
diff --git a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc index fb94a4e..d1ce163 100644 --- a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc +++ b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc
@@ -26,17 +26,8 @@ #include "content/public/browser/host_zoom_map.h" #include "content/public/common/page_zoom.h" -#if defined(OS_LINUX) -#include <dlfcn.h> -#endif - namespace { -std::string GetHash(const base::FilePath& relative_path) { - size_t int_key = BASE_HASH_NAMESPACE::hash<base::FilePath>()(relative_path); - return base::NumberToString(int_key); -} - std::string GetPartitionKey(const base::FilePath& relative_path) { // Create a partition_key string with no '.'s in it. const base::FilePath::StringType& path = relative_path.value(); @@ -48,40 +39,6 @@ path.size() * sizeof(base::FilePath::StringType::value_type)); } -#if defined(OS_LINUX) -typedef size_t (*LibstdcppHashBytesType)(const void* ptr, - size_t len, - size_t seed); - -LibstdcppHashBytesType GetLibstdcppHashBytesFunction() { - static bool have_libstdcpp_hash_bytes_function = false; - static LibstdcppHashBytesType libstdcpp_hash_bytes_function = nullptr; - if (have_libstdcpp_hash_bytes_function) - return libstdcpp_hash_bytes_function; - - void* libstdcpp = dlopen("libstdc++.so.6", RTLD_LAZY); - if (libstdcpp) { - libstdcpp_hash_bytes_function = reinterpret_cast<LibstdcppHashBytesType>( - dlsym(libstdcpp, "_ZSt11_Hash_bytesPKvmm")); - } - have_libstdcpp_hash_bytes_function = true; - return libstdcpp_hash_bytes_function; -} - -// This function should only be called if -// GetLibstdcppHashBytesFunction() returns non-nullptr. -size_t LibstdcppHashString(const std::string& str) { - // This constant was copied out of the libstdc++4.8 headers from the - // Jessie sysroot, which was used before the switch to libc++. - static constexpr size_t kHashStringSeed = 0xc70f6907UL; - LibstdcppHashBytesType libstdcpp_hash_bytes_function = - GetLibstdcppHashBytesFunction(); - DCHECK(libstdcpp_hash_bytes_function); - return libstdcpp_hash_bytes_function(str.c_str(), str.length(), - kHashStringSeed); -} -#endif - const char kZoomLevelPath[] = "zoom_level"; const char kLastModifiedPath[] = "last_modified"; @@ -113,7 +70,6 @@ profile_path.IsParent(partition_path)); base::FilePath partition_relative_path; profile_path.AppendRelativePath(partition_path, &partition_relative_path); - MigrateOldZoomPreferences(partition_relative_path); partition_key_ = GetPartitionKey(partition_relative_path); } @@ -194,85 +150,6 @@ } } -void ChromeZoomLevelPrefs::MigrateOldZoomPreferences( - const base::FilePath& partition_relative_path) { - MigrateOldZoomPreferencesForKeys(GetHash(partition_relative_path), - GetPartitionKey(partition_relative_path)); -#if defined(OS_LINUX) - // On Linux, there was a bug for a brief period of time - // (https://crbug.com/727149) where the libc++ hash was used as the - // partition key. This bug was in dev and beta for a few weeks, so - // there may be users who have preferences for both the libstdc++ - // and the libc++ hashes. Since the libc++ settings are newer, make - // sure we migrate the libstdc++ settings (below) after the libc++ - // ones (above), so that the precedence is: new settings, libc++ - // settings, libstdc++ settings. - if (GetLibstdcppHashBytesFunction()) { - MigrateOldZoomPreferencesForKeys(base::NumberToString(LibstdcppHashString( - partition_relative_path.value())), - GetPartitionKey(partition_relative_path)); - } -#endif -} - -void ChromeZoomLevelPrefs::MigrateOldZoomPreferencesForKeys( - const std::string& old_key, - const std::string& new_key) { - const base::DictionaryValue* default_zoom_level_dictionary = - pref_service_->GetDictionary(prefs::kPartitionDefaultZoomLevel); - if (default_zoom_level_dictionary) { - double old_default_zoom_level = 0; - if (default_zoom_level_dictionary->GetDouble(old_key, - &old_default_zoom_level)) { - // If there was an old zoom, but no new zoom, copy the old zoom - // over. - if (!default_zoom_level_dictionary->GetDouble(new_key, nullptr)) { - DictionaryPrefUpdate update(pref_service_, - prefs::kPartitionDefaultZoomLevel); - update->SetDouble(new_key, old_default_zoom_level); - } - // Always clean up the old zoom setting. - DictionaryPrefUpdate update(pref_service_, - prefs::kPartitionDefaultZoomLevel); - update->RemoveWithoutPathExpansion(old_key, nullptr); - } - } - - DictionaryPrefUpdate update(pref_service_, - prefs::kPartitionPerHostZoomLevels); - base::DictionaryValue* host_zoom_dictionaries = update.Get(); - DCHECK(host_zoom_dictionaries); - pref_service_->GetDictionary(prefs::kPartitionPerHostZoomLevels); - const base::DictionaryValue* old_host_zoom_dictionary = nullptr; - if (host_zoom_dictionaries->GetDictionary(old_key, - &old_host_zoom_dictionary)) { - base::DictionaryValue* new_host_zoom_dictionary = nullptr; - if (!host_zoom_dictionaries->GetDictionary(new_key, - &new_host_zoom_dictionary)) { - auto host_zoom_dictionary = std::make_unique<base::DictionaryValue>(); - new_host_zoom_dictionary = host_zoom_dictionary.get(); - host_zoom_dictionaries->Set(new_key, std::move(host_zoom_dictionary)); - } - DCHECK(new_host_zoom_dictionary); - - // For each host, if there was an old zoom, but no new zoom, copy - // the old zoom setting over. - for (base::DictionaryValue::Iterator it(*old_host_zoom_dictionary); - !it.IsAtEnd(); it.Advance()) { - const std::string& host = it.key(); - double zoom_level = 0.0f; - if (it.value().GetAsDouble(&zoom_level) && - !new_host_zoom_dictionary->GetDouble(host, nullptr)) { - new_host_zoom_dictionary->SetKey(host, base::Value(zoom_level)); - } - } - // Always clean up the old dictionary. - DictionaryPrefUpdate update(pref_service_, - prefs::kPartitionPerHostZoomLevels); - update->RemoveWithoutPathExpansion(old_key, nullptr); - } -} - // TODO(wjmaclean): Remove the dictionary_path once the migration code is // removed. crbug.com/420643 void ChromeZoomLevelPrefs::ExtractPerHostZoomLevels(
diff --git a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.h b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.h index 221bdf4..805613930 100644 --- a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.h +++ b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.h
@@ -69,16 +69,6 @@ // zoom levels (if any) managed by this class (for its associated partition). void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change); - // |partition_key_| used to be a hash as returned by - // std::hash<std::string>. These functions check for zoom settings - // under the old key and copies them to the new one only if there is - // not already a new setting. - // TODO(thomasanderson): Remove these after Chrome M65 has reached - // stable. - void MigrateOldZoomPreferences(const base::FilePath& partition_relative_path); - void MigrateOldZoomPreferencesForKeys(const std::string& old_key, - const std::string& new_key); - PrefService* pref_service_; base::WeakPtr<zoom::ZoomEventManager> zoom_event_manager_; content::HostZoomMap* host_zoom_map_;
diff --git a/chrome/browser/vr/service/xr_runtime_manager_unittest.cc b/chrome/browser/vr/service/xr_runtime_manager_unittest.cc index c304220..f733b148a 100644 --- a/chrome/browser/vr/service/xr_runtime_manager_unittest.cc +++ b/chrome/browser/vr/service/xr_runtime_manager_unittest.cc
@@ -8,7 +8,6 @@ #include "base/callback.h" #include "base/macros.h" -#include "base/memory/linked_ptr.h" #include "base/memory/ptr_util.h" #include "chrome/browser/vr/service/vr_service_impl.h" #include "chrome/browser/vr/service/xr_runtime_manager.h"
diff --git a/chrome/chrome_cleaner/components/recovery_component.cc b/chrome/chrome_cleaner/components/recovery_component.cc index 87f4e9a..c263223 100644 --- a/chrome/chrome_cleaner/components/recovery_component.cc +++ b/chrome/chrome_cleaner/components/recovery_component.cc
@@ -71,7 +71,7 @@ trigger: "The user either accepted a prompt to remove unwanted software, " "or went to \"Clean up computer\" in the settings page and chose " - "to \"Find and remove harmful software\"." + "to \"Find harmful software\"." data: "None" destination: GOOGLE_OWNED_SERVICE }
diff --git a/chrome/chrome_cleaner/logging/cleaner_logging_service.cc b/chrome/chrome_cleaner/logging/cleaner_logging_service.cc index 0fb90e5..5d76031 100644 --- a/chrome/chrome_cleaner/logging/cleaner_logging_service.cc +++ b/chrome/chrome_cleaner/logging/cleaner_logging_service.cc
@@ -67,8 +67,8 @@ trigger: "The user either accepted a prompt to remove unwanted software, " "or went to \"Clean up computer\" in the settings page and chose " - "to \"Find and remove harmful software\", and enabled \"Report " - "details to Google\"." + "to \"Find harmful software\", and enabled \"Report details to " + "Google\"." data: "The user's Chrome version, Windows version, and locale, file " "metadata related to the unwanted software that was detected, "
diff --git a/chrome/chrome_cleaner/logging/reporter_logging_service.cc b/chrome/chrome_cleaner/logging/reporter_logging_service.cc index da8e2b6..68cd81b 100644 --- a/chrome/chrome_cleaner/logging/reporter_logging_service.cc +++ b/chrome/chrome_cleaner/logging/reporter_logging_service.cc
@@ -74,7 +74,7 @@ "Chrome Cleanup can also be explicitly requested by the user in " "\"Reset and clean up\" in settings under Advanced. To disable " "this report, turn off \"Report details to Google\" before " - "choosing \"Find and remove harmful software\"." + "choosing \"Find harmful software\"." chrome_policy { SafeBrowsingExtendedReportingEnabled { SafeBrowsingExtendedReportingEnabled: false
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc index 550b2e77..3b14782e 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
@@ -9,11 +9,13 @@ #include <iomanip> #include <map> +#include "base/files/file_path.h" #include "base/json/json_reader.h" #include "base/stl_util.h" #include "base/strings/string16.h" #include "base/strings/stringprintf.h" #include "base/values.h" +#include "chrome/common/chrome_version.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gaia_credential.h" #include "chrome/credential_provider/gaiacp/gaia_credential_provider_i.h" @@ -47,6 +49,7 @@ HRESULT CGaiaCredentialProvider::FinalConstruct() { LOGFN(INFO); CleanupStaleTokenHandles(); + CleanupOlderVersions(); return S_OK; } @@ -118,6 +121,12 @@ } } +void CGaiaCredentialProvider::CleanupOlderVersions() { + base::FilePath versions_directory = GetInstallDirectory(); + if (!versions_directory.empty()) + DeleteVersionsExcept(versions_directory, TEXT(CHROME_VERSION_STRING)); +} + // IGaiaCredentialProvider //////////////////////////////////////////////////// HRESULT CGaiaCredentialProvider::OnUserAuthenticated(
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.h b/chrome/credential_provider/gaiacp/gaia_credential_provider.h index 272089c..169a808 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider.h +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.h
@@ -49,6 +49,7 @@ HRESULT DestroyCredentials(); void ClearTransient(); void CleanupStaleTokenHandles(); + void CleanupOlderVersions(); // Checks of any of the Google account users need to re-auth. static unsigned __stdcall CheckReauthStatus(void* param);
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.cc b/chrome/credential_provider/gaiacp/gcp_utils.cc index 85820fd..94ba384 100644 --- a/chrome/credential_provider/gaiacp/gcp_utils.cc +++ b/chrome/credential_provider/gaiacp/gcp_utils.cc
@@ -29,7 +29,9 @@ #include "base/base64.h" #include "base/command_line.h" -#include "base/files/file_path.h" +#include "base/files/file.h" +#include "base/files/file_enumerator.h" +#include "base/files/file_util.h" #include "base/json/json_writer.h" #include "base/macros.h" #include "base/no_destructor.h" @@ -92,8 +94,92 @@ email.c_str(), mdm_url.c_str(), base::UTF8ToWide(data_encoded).c_str()); } +// Opens |path| with options that prevent the file from being read or written +// via another handle. As long as the returned object is alive, it is guaranteed +// that |path| isn't in use. It can however be deleted. +base::File GetFileLock(const base::FilePath& path) { + return base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_EXCLUSIVE_READ | + base::File::FLAG_EXCLUSIVE_WRITE | + base::File::FLAG_SHARE_DELETE); +} + +// Deletes a specific GCP version from the disk. +void DeleteVersionDirectory(const base::FilePath& version_path) { + // Lock all exes and dlls for exclusive access while allowing deletes. Mark + // the files for deletion and release them, causing them to actually be + // deleted. This allows the deletion of the version path itself. + std::vector<base::File> locks; + const int types = base::FileEnumerator::FILES; + base::FileEnumerator enumerator_version(version_path, false, types, + FILE_PATH_LITERAL("*")); + bool all_deletes_succeeded = true; + for (base::FilePath path = enumerator_version.Next(); !path.empty(); + path = enumerator_version.Next()) { + if (!path.MatchesExtension(FILE_PATH_LITERAL(".exe")) && + !path.MatchesExtension(FILE_PATH_LITERAL(".dll"))) { + continue; + } + + // Open the file for exclusive access while allowing deletes. + locks.push_back(GetFileLock(path)); + if (!locks.back().IsValid()) { + HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); + LOGFN(ERROR) << "Could not lock " << path << " hr=" << putHR(hr); + all_deletes_succeeded = false; + continue; + } + + // Mark the file for deletion. + HRESULT hr = base::DeleteFile(path, false); + if (FAILED(hr)) { + LOGFN(ERROR) << "Could not delete " << path; + all_deletes_succeeded = false; + } + } + + // Release the locks, actually deleting the files. It is now possible to + // delete the version path. + locks.clear(); + if (all_deletes_succeeded && !base::DeleteFile(version_path, true)) + LOGFN(ERROR) << "Could not delete version " << version_path.BaseName(); +} + } // namespace +base::FilePath GetInstallDirectory() { + base::FilePath dest_path; + if (!base::PathService::Get(base::DIR_PROGRAM_FILES, &dest_path)) { + HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); + LOGFN(ERROR) << "PathService::Get(DIR_PROGRAM_FILES) hr=" << putHR(hr); + return base::FilePath(); + } + + dest_path = dest_path.Append(GetInstallParentDirectoryName()) + .Append(FILE_PATH_LITERAL("Credential Provider")); + + return dest_path; +} + +void DeleteVersionsExcept(const base::FilePath& gcp_path, + const base::string16& product_version) { + base::FilePath version = base::FilePath(product_version); + const int types = base::FileEnumerator::DIRECTORIES; + base::FileEnumerator enumerator(gcp_path, false, types, + FILE_PATH_LITERAL("*")); + for (base::FilePath name = enumerator.Next(); !name.empty(); + name = enumerator.Next()) { + base::FilePath basename = name.BaseName(); + if (version == basename) + continue; + + // Found an older version on the machine that can be deleted. This is + // best effort only. If any errors occurred they are logged by + // DeleteVersionDirectory(). + DeleteVersionDirectory(gcp_path.Append(basename)); + } +} + // StdParentHandles /////////////////////////////////////////////////////////// StdParentHandles::StdParentHandles() {} @@ -697,6 +783,14 @@ return GetDictStringUTF8(dict.get(), name); } +base::FilePath::StringType GetInstallParentDirectoryName() { +#if defined(GOOGLE_CHROME_BUILD) + return FILE_PATH_LITERAL("Google"); +#else + return FILE_PATH_LITERAL("Chromium"); +#endif +} + FakesForTesting::FakesForTesting() {} FakesForTesting::~FakesForTesting() {}
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.h b/chrome/credential_provider/gaiacp/gcp_utils.h index ee34f0b..94c295f 100644 --- a/chrome/credential_provider/gaiacp/gcp_utils.h +++ b/chrome/credential_provider/gaiacp/gcp_utils.h
@@ -6,6 +6,7 @@ #define CHROME_CREDENTIAL_PROVIDER_GAIACP_GCP_UTILS_H_ #include "base/callback.h" +#include "base/files/file_path.h" #include "base/strings/string16.h" #include "base/values.h" #include "base/win/scoped_handle.h" @@ -101,6 +102,17 @@ base::string16 desktop_; }; +// Gets the brand specific path in which to install GCPW. +base::FilePath::StringType GetInstallParentDirectoryName(); + +// Gets the directory where the GCP is installed +base::FilePath GetInstallDirectory(); + +// Deletes versions of GCP found under |gcp_path| except for version +// |product_version|. +void DeleteVersionsExcept(const base::FilePath& gcp_path, + const base::string16& product_version); + // Waits for the process specified by |procinfo| to terminate. The handles // in |read_handles| can be used to read stdout/err from the process. Upon // return, |exit_code| contains one of the UIEC_xxx constants listed above,
diff --git a/chrome/credential_provider/setup/setup_lib.cc b/chrome/credential_provider/setup/setup_lib.cc index af7abf3..2e621a4 100644 --- a/chrome/credential_provider/setup/setup_lib.cc +++ b/chrome/credential_provider/setup/setup_lib.cc
@@ -50,15 +50,11 @@ // Creates the directory where GCP is to be installed. base::FilePath CreateInstallDirectory() { - base::FilePath dest_path; - if (!base::PathService::Get(base::DIR_PROGRAM_FILES, &dest_path)) { - HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); - LOGFN(ERROR) << "PathService::Get(DIR_PROGRAM_FILES) hr=" << putHR(hr); - return base::FilePath(); - } + base::FilePath dest_path = GetInstallDirectory(); - dest_path = dest_path.Append(GetInstallParentDirectoryName()) - .Append(FILE_PATH_LITERAL("Credential Provider")); + if (dest_path.empty()) { + return dest_path; + } if (!base::CreateDirectory(dest_path)) { HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); @@ -168,82 +164,6 @@ return has_failures ? E_UNEXPECTED : S_OK; } -// Opens |path| with options that prevent the file from being read or written -// via another handle. As long as the returned object is alive, it is guaranteed -// that |path| isn't in use. It can however be deleted. -base::File GetFileLock(const base::FilePath& path) { - return base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ | - base::File::FLAG_EXCLUSIVE_READ | - base::File::FLAG_EXCLUSIVE_WRITE | - base::File::FLAG_SHARE_DELETE); -} - -// Deletes a specific GCP version from the disk. -void DeleteVersionDirectory(const base::FilePath& version_path) { - // Lock all exes and dlls for exclusive access while allowing deletes. Mark - // the files for deletion and release them, causing them to actually be - // deleted. This allows the deletion of the version path itself. - std::vector<base::File> locks; - const int types = base::FileEnumerator::FILES; - base::FileEnumerator enumerator_version(version_path, false, types, - FILE_PATH_LITERAL("*")); - bool all_deletes_succeeded = true; - for (base::FilePath path = enumerator_version.Next(); !path.empty(); - path = enumerator_version.Next()) { - if (!path.MatchesExtension(FILE_PATH_LITERAL(".exe")) && - !path.MatchesExtension(FILE_PATH_LITERAL(".dll"))) { - continue; - } - - // Open the file for exclusive access while allowing deletes. - locks.push_back(GetFileLock(path)); - if (!locks.back().IsValid()) { - HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); - LOGFN(ERROR) << "Could not lock " << path << " hr=" << putHR(hr); - all_deletes_succeeded = false; - continue; - } - - // Mark the file for deletion. - HRESULT hr = base::DeleteFile(path, false); - if (FAILED(hr)) { - LOGFN(ERROR) << "Could not delete " << path; - all_deletes_succeeded = false; - } - } - - // Release the locks, actually deleting the files. It is now possible to - // delete the version path. - locks.clear(); - if (all_deletes_succeeded && !base::DeleteFile(version_path, true)) - LOGFN(ERROR) << "Could not delete version " << version_path.BaseName(); -} - -// Deletes versions of GCP found under |gcp_path| except for version -// |product_version|. -// -// TODO(crbug.com/883935): figure out how to call this from credential provider -// code too. That way if older versions cannot be deleted at install time, they -// can eventually be cleaned up at next run. -void DeleteVersionsExcept(const base::FilePath& gcp_path, - const base::string16& product_version) { - base::FilePath version = base::FilePath(product_version); - const int types = base::FileEnumerator::DIRECTORIES; - base::FileEnumerator enumerator(gcp_path, false, types, - FILE_PATH_LITERAL("*")); - for (base::FilePath name = enumerator.Next(); !name.empty(); - name = enumerator.Next()) { - base::FilePath basename = name.BaseName(); - if (version == basename) - continue; - - // Found an older version on the machine that can be deleted. This is - // best effort only. If any errors occurred they are logged by - // DeleteVersionDirectory(). - DeleteVersionDirectory(gcp_path.Append(basename)); - } -} - } // namespace namespace switches { @@ -379,12 +299,4 @@ *count = base::size(kFilenames); } -base::FilePath::StringType GetInstallParentDirectoryName() { -#if defined(GOOGLE_CHROME_BUILD) - return FILE_PATH_LITERAL("Google"); -#else - return FILE_PATH_LITERAL("Chromium"); -#endif -} - } // namespace credential_provider
diff --git a/chrome/credential_provider/setup/setup_lib.h b/chrome/credential_provider/setup/setup_lib.h index a202050c..b578537 100644 --- a/chrome/credential_provider/setup/setup_lib.h +++ b/chrome/credential_provider/setup/setup_lib.h
@@ -51,9 +51,6 @@ void GetInstalledFileBasenames(const base::FilePath::CharType* const** names, size_t* count); -// Gets the brand specific path in which to install GCPW. -base::FilePath::StringType GetInstallParentDirectoryName(); - } // namespace credential_provider #endif // CHROME_CREDENTIAL_PROVIDER_SETUP_SETUP_LIB_H_
diff --git a/chrome/credential_provider/test/gcp_setup_unittests.cc b/chrome/credential_provider/test/gcp_setup_unittests.cc index dbd820f..281f9e7 100644 --- a/chrome/credential_provider/test/gcp_setup_unittests.cc +++ b/chrome/credential_provider/test/gcp_setup_unittests.cc
@@ -3,6 +3,8 @@ // found in the LICENSE file. #include <atlbase.h> +#include <atlcom.h> +#include <atlcomcli.h> #include <lmerr.h> #include <objbase.h> #include <unknwn.h> @@ -26,6 +28,7 @@ #include "base/win/registry.h" #include "build/build_config.h" #include "chrome/credential_provider/common/gcp_strings.h" +#include "chrome/credential_provider/gaiacp/gaia_credential_provider.h" #include "chrome/credential_provider/gaiacp/gaia_credential_provider_i.h" #include "chrome/credential_provider/gaiacp/gcp_utils.h" #include "chrome/credential_provider/setup/setup_lib.h" @@ -307,6 +310,53 @@ } } +TEST_F(GcpSetupTest, LaunchGcpAfterInstall) { + logging::ResetEventSourceForTesting(); + + // Install using some old version. + const base::string16 old_version(L"1.0.0.0"); + ASSERT_EQ(S_OK, DoInstall(module_path(), old_version, fakes_for_testing())); + ExpectAllFilesToExist(true, old_version); + + // Lock the CP DLL. + base::FilePath dll_path = installed_path_for_version(old_version) + .Append(FILE_PATH_LITERAL("Gaia1_0.dll")); + base::File locked_file(dll_path, base::File::FLAG_OPEN | + base::File::FLAG_READ | + base::File::FLAG_EXCLUSIVE_READ | + base::File::FLAG_EXCLUSIVE_WRITE); + + logging::ResetEventSourceForTesting(); + + // Now install a newer version. + ASSERT_EQ(S_OK, + DoInstall(module_path(), product_version(), fakes_for_testing())); + + // Make sure newer version exists. + ExpectAllFilesToExist(true, product_version()); + + // The locked file will still exist, the others are gone. + const base::FilePath::CharType* const* filenames; + size_t count; + GetInstalledFileBasenames(&filenames, &count); + for (size_t i = 0; i < count; ++i) { + const base::FilePath path = + installed_path_for_version(old_version).Append(filenames[i]); + EXPECT_EQ(path == dll_path, base::PathExists(path)); + } + + locked_file.Close(); + + CComPtr<IGaiaCredentialProvider> provider; + ASSERT_EQ(S_OK, + CComCreator<CComObject<CGaiaCredentialProvider>>::CreateInstance( + nullptr, IID_IGaiaCredentialProvider, (void**)&provider)); + + // Make sure newer version exists and old version is gone. + ExpectAllFilesToExist(true, product_version()); + ExpectAllFilesToExist(false, old_version); +} + TEST_F(GcpSetupTest, DoUninstall) { logging::ResetEventSourceForTesting();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 0e20d646..6bcdfbe 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2013,7 +2013,6 @@ } if (is_win) { sources += [ - "../browser/browser_switcher/browser_switcher_service_browsertest.cc", "../browser/printing/pdf_to_emf_converter_browsertest.cc", "../browser/ui/startup/credential_provider_signin_dialog_win_browsertest.cc", "../browser/ui/views/accessibility/invert_bubble_view_browsertest.cc", @@ -2077,6 +2076,7 @@ sources += [ # Tests for non mobile and non CrOS (includes Linux, Win, Mac). "../browser/browser_switcher/browser_switcher_browsertest.cc", + "../browser/browser_switcher/browser_switcher_service_browsertest.cc", "../browser/browser_switcher/ieem_sitelist_parser_browsertest.cc", "../browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc", "../browser/profiles/profile_statistics_browsertest.cc",
diff --git a/chrome/test/chromedriver/chrome/ui_events.cc b/chrome/test/chromedriver/chrome/ui_events.cc index bbe36ad..6e1f485a 100644 --- a/chrome/test/chromedriver/chrome/ui_events.cc +++ b/chrome/test/chromedriver/chrome/ui_events.cc
@@ -24,6 +24,8 @@ buttons(buttons), click_count(click_count) {} +MouseEvent::MouseEvent(const MouseEvent& other) = default; + MouseEvent::~MouseEvent() {} TouchEvent::TouchEvent(TouchEventType type, @@ -33,6 +35,8 @@ x(x), y(y) {} +TouchEvent::TouchEvent(const TouchEvent& other) = default; + TouchEvent::~TouchEvent() {} KeyEvent::KeyEvent()
diff --git a/chrome/test/chromedriver/chrome/ui_events.h b/chrome/test/chromedriver/chrome/ui_events.h index cfb74eb..bf327195 100644 --- a/chrome/test/chromedriver/chrome/ui_events.h +++ b/chrome/test/chromedriver/chrome/ui_events.h
@@ -15,7 +15,8 @@ enum MouseEventType { kPressedMouseEventType = 0, kReleasedMouseEventType, - kMovedMouseEventType + kMovedMouseEventType, + kPauseMouseEventType }; // Specifies the mouse buttons. @@ -36,6 +37,7 @@ int modifiers, int buttons, int click_count); + MouseEvent(const MouseEvent& other); ~MouseEvent(); MouseEventType type; @@ -46,24 +48,23 @@ int buttons; // |click_count| should not be negative. int click_count; + std::string element_id; }; // Specifies the type of the touch event. -enum TouchEventType { - kTouchStart = 0, - kTouchEnd, - kTouchMove, -}; +enum TouchEventType { kTouchStart = 0, kTouchEnd, kTouchMove, kPause }; struct TouchEvent { TouchEvent(TouchEventType type, int x, int y); + TouchEvent(const TouchEvent& other); ~TouchEvent(); TouchEventType type; int x; int y; + std::string element_id; }; // Specifies the type of the keyboard event. @@ -72,6 +73,7 @@ kKeyUpEventType, kRawKeyDownEventType, kCharEventType, + kPauseEventType, kInvalidEventType // used by KeyEventBuilder };
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index 8f87d54..ad5b2eb 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -431,6 +431,8 @@ continue; params.SetString("type", "touchMove"); break; + default: + break; } std::unique_ptr<base::ListValue> touchPoints(new base::ListValue);
diff --git a/chrome/test/chromedriver/util.cc b/chrome/test/chromedriver/util.cc index 182ea30f..ceb11338 100644 --- a/chrome/test/chromedriver/util.cc +++ b/chrome/test/chromedriver/util.cc
@@ -442,7 +442,7 @@ if (has_value != nullptr) *has_value = false; const base::Value* value; - if (!dict->Get(path, &value) || value->is_none()) + if (!dict->Get(path, &value)) return true; if ((value->*getter)(out_value)) { if (has_value != nullptr)
diff --git a/chrome/test/chromedriver/util.h b/chrome/test/chromedriver/util.h index 65477c1..31888d4 100644 --- a/chrome/test/chromedriver/util.h +++ b/chrome/test/chromedriver/util.h
@@ -51,7 +51,7 @@ // Each function has three different outcomes: // * Value exists and is of right type: // returns true, *has_value = true, *out_value gets the actual value. -// * Value does not exist, or exists with value of undefined: +// * Value does not exist: // returns true, *has_value = false, *out_value is unchanged. // * Value exists but is of wrong type (error condition): // returns false, *has_value undefined, *out_value is unchanged. @@ -62,7 +62,7 @@ // Also, integers are limited to 32-bit. // * WebDriver spec (https://www.w3.org/TR/webdriver/#dfn-integer) defines // integer to be a number that is unchanged under the ToInteger operation, -// thus 2.0 is an integer. Also, the spec sometimes use "safe integer" +// thus 2.0 is an integer. Also, the spec sometimes uses "safe integer" // (https://www.w3.org/TR/webdriver/#dfn-maximum-safe-integer), whose // absolute value can occupy up to 53 bits. bool GetOptionalBool(const base::DictionaryValue* dict,
diff --git a/chrome/test/chromedriver/util_unittest.cc b/chrome/test/chromedriver/util_unittest.cc index b7c9dbb7b..a7af39a8 100644 --- a/chrome/test/chromedriver/util_unittest.cc +++ b/chrome/test/chromedriver/util_unittest.cc
@@ -155,28 +155,28 @@ } TEST(GetOptionalValue, BoolNull) { - TestGetOptionalValue<bool>(GetOptionalBool, DictInitNull, true, true, true, + TestGetOptionalValue<bool>(GetOptionalBool, DictInitNull, true, true, false, false); } TEST(GetOptionalValue, IntNull) { - TestGetOptionalValue<int>(GetOptionalInt, DictInitNull, 12345, 12345, true, + TestGetOptionalValue<int>(GetOptionalInt, DictInitNull, 12345, 12345, false, false); } TEST(GetOptionalValue, DoubleNull) { TestGetOptionalValue<double>(GetOptionalDouble, DictInitNull, 123.45, 123.45, - true, false); + false, false); } TEST(GetOptionalValue, StringNull) { TestGetOptionalValue<std::string>(GetOptionalString, DictInitNull, "abcde", - "abcde", true, false); + "abcde", false, false); } TEST(GetOptionalValue, SafeIntNull) { TestGetOptionalValue<int64_t>(GetOptionalSafeInt, DictInitNull, 12345, 12345, - true, false); + false, false); } TEST(GetOptionalValue, BoolWrongType) {
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index 440de91f..329646a 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc
@@ -37,6 +37,7 @@ #include "chrome/test/chromedriver/net/timeout.h" #include "chrome/test/chromedriver/session.h" #include "chrome/test/chromedriver/util.h" +#include "ui/gfx/geometry/point.h" namespace { @@ -104,6 +105,8 @@ return kReleasedMouseEventType; else if (action_type == "pointerMove") return kMovedMouseEventType; + else if (action_type == "pause") + return kPauseMouseEventType; else return kPressedMouseEventType; } @@ -130,6 +133,8 @@ return kTouchEnd; else if (action_type == "pointerMove") return kTouchMove; + else if (action_type == "pause") + return kPause; else return kTouchStart; } @@ -341,6 +346,39 @@ return Status(kOk); } +Status ElementInViewCenter(Session* session, + WebView* web_view, + std::string element_id, + int* center_x, + int* center_y) { + WebRect region; + Status status = GetElementRegion(session, web_view, element_id, ®ion); + if (status.IsError()) + return status; + WebPoint region_offset; + status = ScrollElementRegionIntoView(session, web_view, element_id, region, + true /* center */, std::string(), + ®ion_offset); + if (status.IsError()) + return status; + int innerWidth, innerHeight; + status = WindowViewportSize(session, web_view, &innerWidth, &innerHeight); + if (status.IsError()) + return status; + int left = + std::max(0, std::min(region_offset.x, region_offset.x + region.Width())); + int right = std::min( + innerWidth, std::max(region_offset.x, region_offset.x + region.Width())); + int top = + std::max(0, std::min(region_offset.y, region_offset.y + region.Height())); + int bottom = + std::min(innerHeight, + std::max(region_offset.y, region_offset.y + region.Height())); + *center_x = static_cast<int>(std::floor((left + right) / 2)); + *center_y = static_cast<int>(std::floor((top + bottom) / 2)); + return Status(kOk); +} + } // namespace Status ExecuteWindowCommand(const WindowCommand& command, @@ -1021,7 +1059,6 @@ "type of action must be the string 'keyUp', 'keyDown' or 'pause'"); action->SetString("subtype", subtype); - if (subtype == "pause") { Status status = ProcessPauseAction(action_item, action.get()); if (status.IsError()) @@ -1100,15 +1137,10 @@ Status status = ProcessPauseAction(action_item, action.get()); if (status.IsError()) return status; - } else { - int duration; - if (action_item->HasKey("duration")) { - if (!action_item->GetInteger("duration", &duration) || duration < 0) { - return Status(kInvalidArgument, - "'duration' must be a non-negative int"); - } - action->SetInteger("duration", duration); - } + } else if (subtype == "pause") { + Status status = ProcessPauseAction(action_item, action.get()); + if (status.IsError()) + return status; } } actions_result->Append(std::move(action)); @@ -1136,8 +1168,6 @@ // the processed actions base::ListValue actions_list; - // the type of each action list in actions_list - std::list<std::string> input_source_types; for (size_t i = 0; i < actions_input->GetSize(); i++) { std::unique_ptr<base::DictionaryValue> input_source_actions( @@ -1146,55 +1176,47 @@ const base::DictionaryValue* action_sequence; if (!actions_input->GetDictionary(i, &action_sequence)) return Status(kInvalidArgument, "each argument must be a dictionary"); - Status status = ProcessInputActionSequence(session, action_sequence, &input_source_actions); if (status.IsError()) return Status(kInvalidArgument, status); - std::string type; - action_sequence->GetString("type", &type); - input_source_types.push_back(type); actions_list.Append(std::move(input_source_actions)); } std::string input_pointer_type; std::set<std::string> pointer_id_set; std::string type; + std::vector<std::vector<MouseEvent>> mouse_events_list; + std::vector<std::vector<TouchEvent>> touch_events_list; + std::vector<std::vector<KeyEvent>> key_events_list; + size_t longest_mouse_list_size = 0; + size_t longest_touch_list_size = 0; + size_t longest_key_list_size = 0; for (size_t i = 0; i < actions_list.GetSize(); i++) { base::DictionaryValue* action_sequence; actions_list.GetDictionary(i, &action_sequence); const base::ListValue* actions; action_sequence->GetList("actions", &actions); DCHECK(actions); - - type = input_source_types.front(); - input_source_types.pop_front(); + action_sequence->GetString("sourceType", &type); // key actions if (type == "key") { KeyEventBuilder builder; - std::list<KeyEvent> key_events; + std::vector<KeyEvent> key_events; for (size_t j = 0; j < actions->GetSize(); j++) { const base::DictionaryValue* action; - if (!actions->GetDictionary(j, &action)) - return Status(kInvalidArgument, "each argument must be a dictionary"); + actions->GetDictionary(j, &action); std::string subtype; - if (!action->GetString("subtype", &subtype)) - return Status(kInvalidArgument, "'subtype' must be a string"); - + action->GetString("subtype", &subtype); std::string id; - if (!action->GetString("id", &id)) - return Status(kInvalidArgument, "id"); - + action->GetString("id", &id); if (subtype == "pause") { - // TODO: handle this + key_events.push_back(builder.SetType(kPauseEventType)->Build()); } else { base::DictionaryValue dispatch_params; base::string16 raw_key; - - if (!action->GetString("value", &raw_key)) - return Status(kInvalidArgument, "value"); - + action->GetString("value", &raw_key); base::char16 key = raw_key[0]; // TODO: understand necessary_modifiers int necessary_modifiers = 0; @@ -1221,9 +1243,9 @@ ->Build()); } } - Status status = web_view->DispatchKeyEvents(key_events); - if (status.IsError()) - return status; + longest_key_list_size = + std::max(key_events.size(), longest_key_list_size); + key_events_list.push_back(key_events); } else if (type == "pointer") { std::string pointer_type; action_sequence->GetString("pointerType", &pointer_type); @@ -1236,79 +1258,47 @@ "multiple input pointer types are not supported now"); } - if (pointer_type != "touch" && i > 0) { - return Status(kInvalidArgument, - "for pointer type of mouse and pen, multiple devices are " - "not supported now"); - } - std::string pointer_id; action_sequence->GetString("id", &pointer_id); if (pointer_id_set.find(pointer_id) != pointer_id_set.end()) return Status(kInvalidArgument, "'id' already exists"); pointer_id_set.insert(pointer_id); - std::list<MouseEvent> mouse_events; - std::list<TouchEvent> touch_events; - + std::vector<MouseEvent> mouse_events; + std::vector<TouchEvent> touch_events; double x = 0; double y = 0; bool has_touch_start = false; int buttons = 0; std::string button_type; + std::string element_id; for (size_t j = 0; j < actions->GetSize(); j++) { - const base::DictionaryValue* mouse_action; - actions->GetDictionary(j, &mouse_action); + const base::DictionaryValue* pointer_action; + actions->GetDictionary(j, &pointer_action); std::string action_type; - mouse_action->GetString("subtype", &action_type); + pointer_action->GetString("subtype", &action_type); if (action_type == "pointerMove") { - mouse_action->GetDouble("x", &x); - mouse_action->GetDouble("y", &y); + pointer_action->GetDouble("x", &x); + pointer_action->GetDouble("y", &y); const base::DictionaryValue* origin_dict; - if (mouse_action->HasKey("origin") && - mouse_action->GetDictionary("origin", &origin_dict)) { - std::string element_id; + element_id = ""; + if (pointer_action->HasKey("origin") && + pointer_action->GetDictionary("origin", &origin_dict)) { origin_dict->GetString(GetElementKey(), &element_id); - WebRect region; - Status status = - GetElementRegion(session, web_view, element_id, ®ion); - if (status.IsError()) - return status; - WebPoint region_offset; - status = ScrollElementRegionIntoView(session, web_view, element_id, - region, true /* center */, - std::string(), ®ion_offset); - if (status.IsError()) - return status; - int innerWidth, innerHeight; - status = WindowViewportSize(session, web_view, &innerWidth, - &innerHeight); - if (status.IsError()) - return status; - int left = std::max( - 0, std::min(region_offset.x, region_offset.x + region.Width())); - int right = std::min( - innerWidth, - std::max(region_offset.x, region_offset.x + region.Width())); - int top = std::max(0, std::min(region_offset.y, - region_offset.y + region.Height())); - int bottom = std::min( - innerHeight, - std::max(region_offset.y, region_offset.y + region.Height())); - x += (left + right) / 2; - y += (top + bottom) / 2; } } if (pointer_type == "mouse") { int click_count = 0; if (action_type == "pointerDown" || action_type == "pointerUp") { - mouse_action->GetString("button", &button_type); + pointer_action->GetString("button", &button_type); click_count = 1; } - mouse_events.push_back(MouseEvent(StringToMouseEventType(action_type), - StringToMouseButton(button_type), x, - y, 0, buttons, click_count)); + MouseEvent event(StringToMouseEventType(action_type), + StringToMouseButton(button_type), x, y, 0, buttons, + click_count); + event.element_id = element_id; + mouse_events.push_back(event); if (action_type == "pointerDown") buttons |= StringToModifierMouseButton(button_type); else if (action_type == "pointerUp") @@ -1320,19 +1310,94 @@ has_touch_start = false; if (action_type != "pointerMove" || has_touch_start) { - touch_events.push_back( - TouchEvent(StringToTouchEventType(action_type), x, y)); + TouchEvent event(StringToTouchEventType(action_type), x, y); + event.element_id = element_id; + touch_events.push_back(event); } } } - Status status(kOk); if (pointer_type == "mouse") { - status = web_view->DispatchMouseEvents(mouse_events, - session->GetCurrentFrameId()); + longest_mouse_list_size = + std::max(mouse_events.size(), longest_mouse_list_size); + mouse_events_list.push_back(mouse_events); } else if (pointer_type == "touch") { - status = web_view->DispatchTouchEvents(touch_events); + longest_touch_list_size = + std::max(touch_events.size(), longest_touch_list_size); + touch_events_list.push_back(touch_events); } + } + } + + size_t max_list_length = + std::max(std::max(longest_mouse_list_size, longest_touch_list_size), + longest_key_list_size); + std::map<std::string, gfx::Point> element_center_point; + for (size_t i = 0; i < max_list_length; i++) { + std::list<MouseEvent> dispatch_mouse_events; + for (size_t j = 0; j < mouse_events_list.size(); j++) { + if (i < mouse_events_list[j].size() && + mouse_events_list[j][i].type != kPauseMouseEventType) { + MouseEvent event = mouse_events_list[j][i]; + if (!event.element_id.empty()) { + if (event.type == kMovedMouseEventType || + element_center_point.find(event.element_id) == + element_center_point.end()) { + int center_x = 0, center_y = 0; + ElementInViewCenter(session, web_view, event.element_id, ¢er_x, + ¢er_y); + element_center_point[event.element_id] = + gfx::Point(center_x, center_y); + } + event.x += element_center_point[event.element_id].x(); + event.y += element_center_point[event.element_id].y(); + } + dispatch_mouse_events.push_back(event); + } + } + if (dispatch_mouse_events.size() > 0) { + Status status = web_view->DispatchMouseEvents( + dispatch_mouse_events, session->GetCurrentFrameId()); + if (status.IsError()) + return status; + } + + std::list<TouchEvent> dispatch_touch_events; + for (size_t j = 0; j < touch_events_list.size(); j++) { + if (i < touch_events_list[j].size() && + touch_events_list[j][i].type != kPause) { + TouchEvent event = touch_events_list[j][i]; + if (!event.element_id.empty()) { + if (event.type == kTouchMove || + element_center_point.find(event.element_id) == + element_center_point.end()) { + int center_x = 0, center_y = 0; + ElementInViewCenter(session, web_view, event.element_id, ¢er_x, + ¢er_y); + element_center_point[event.element_id] = + gfx::Point(center_x, center_y); + } + event.x += element_center_point[event.element_id].x(); + event.y += element_center_point[event.element_id].y(); + } + dispatch_touch_events.push_back(event); + } + } + if (dispatch_touch_events.size() > 0) { + Status status = web_view->DispatchTouchEvents(dispatch_touch_events); + if (status.IsError()) + return status; + } + + std::list<KeyEvent> dispatch_key_events; + for (size_t j = 0; j < key_events_list.size(); j++) { + if (i < key_events_list[j].size() && + key_events_list[j][i].type != kPauseEventType) { + dispatch_key_events.push_back(key_events_list[j][i]); + } + } + if (dispatch_key_events.size() > 0) { + Status status = web_view->DispatchKeyEvents(dispatch_key_events); if (status.IsError()) return status; }
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 4db7bd5e..f65d0ba 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -4321,5 +4321,15 @@ "pref_mappings": [ { "pref": "browser_switcher.use_ie_sitelist" } ] + }, + + "BrowserSwitcherExternalSitelistUrl": { + "os": ["win", "linux", "mac"], + "test_policy": { + "BrowserSwitcherExternalSitelistUrl": "file:///C:/src/sitelist.xml" + }, + "pref_mappings": [ + { "pref": "browser_switcher.external_sitelist_url" } + ] } }
diff --git a/chrome/test/data/webui/settings/chrome_cleanup_page_test.js b/chrome/test/data/webui/settings/chrome_cleanup_page_test.js index 5d44e6a..54bbebf 100644 --- a/chrome/test/data/webui/settings/chrome_cleanup_page_test.js +++ b/chrome/test/data/webui/settings/chrome_cleanup_page_test.js
@@ -8,7 +8,6 @@ super([ 'registerChromeCleanerObserver', 'restartComputer', - 'setLogsUploadPermission', 'startCleanup', 'startScanning', 'notifyShowDetails', @@ -29,11 +28,6 @@ } /** @override */ - setLogsUploadPermission(enabled) { - this.methodCalled('setLogsUploadPermission', enabled); - } - - /** @override */ startCleanup(logsUploadEnabled) { this.methodCalled('startCleanup', logsUploadEnabled); } @@ -160,7 +154,7 @@ 'extensions': extensions }; - cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false); + updateReportingEnabledPref(false); cr.webUIListenerCallback( 'chrome-cleanup-on-infected', true /* isPoweredByPartner */, scannerResults); @@ -216,6 +210,21 @@ } /** + * @param {boolean} newValue The new value to set to + * prefs.software_reporter.reporting. + */ +function updateReportingEnabledPref(newValue) { + chromeCleanupPage.prefs = { + software_reporter: { + reporting: { + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: newValue, + }, + }, + }; +} + +/** * @param {boolean} testingScanOffered Whether to test the case where scanning * is offered to the user. */ @@ -231,23 +240,21 @@ Polymer.dom.flush(); const logsControl = chromeCleanupPage.$$('#chromeCleanupLogsUploadControl'); - assertTrue(!!logsControl); - cr.webUIListenerCallback( - 'chrome-cleanup-upload-permission-change', false, true); - Polymer.dom.flush(); + updateReportingEnabledPref(true); + assertTrue(!!logsControl); assertTrue(logsControl.checked); - cr.webUIListenerCallback( - 'chrome-cleanup-upload-permission-change', false, false); - Polymer.dom.flush(); + logsControl.$.checkbox.click(); assertFalse(logsControl.checked); + assertFalse(chromeCleanupPage.prefs.software_reporter.reporting.value); - logsControl.$.control.click(); - return chromeCleanupProxy.whenCalled('setLogsUploadPermission') - .then(function(logsUploadEnabled) { - assertTrue(logsUploadEnabled); - }); + logsControl.$.checkbox.click(); + assertTrue(logsControl.checked); + assertTrue(chromeCleanupPage.prefs.software_reporter.reporting.value); + + updateReportingEnabledPref(false); + assertFalse(logsControl.checked); } /** @@ -276,6 +283,11 @@ PolymerTest.clearBody(); chromeCleanupPage = document.createElement('settings-chrome-cleanup-page'); + chromeCleanupPage.prefs = { + software_reporter: { + reporting: {type: chrome.settingsPrivate.PrefType.BOOLEAN, value: true}, + }, + }; document.body.appendChild(chromeCleanupPage); }); @@ -368,7 +380,7 @@ }); test('startScanFromIdle', function() { - cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false); + updateReportingEnabledPref(false); cr.webUIListenerCallback( 'chrome-cleanup-on-idle', settings.ChromeCleanupIdleReason.INITIAL); Polymer.dom.flush(); @@ -441,7 +453,7 @@ }); test('cleanupFailure', function() { - cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false); + updateReportingEnabledPref(false); cr.webUIListenerCallback( 'chrome-cleanup-on-cleaning', true /* isPoweredByPartner */, defaultScannerResults); @@ -498,4 +510,48 @@ return testPartnerLogoShown( false /* onInfected */, false /* isPoweredByPartner */); }); + + test('logsUploadingState_reporterPolicyDisabled', function() { + cr.webUIListenerCallback( + 'chrome-cleanup-on-idle', settings.ChromeCleanupIdleReason.INITIAL); + // prefs.software_reporter.enabled is not a real preference as it can't be + // set by the user. ChromeCleanupHandler can notify the JS of changes to the + // policy enforcement. + cr.webUIListenerCallback('chrome-cleanup-enabled-change', false); + Polymer.dom.flush(); + + const actionButton = chromeCleanupPage.$$('#action-button'); + assertTrue(!!actionButton); + assertTrue(actionButton.disabled); + + const logsControl = chromeCleanupPage.$$('#chromeCleanupLogsUploadControl'); + assertTrue(!!logsControl); + assertTrue(logsControl.disabled); + }); + + test('logsUploadingState_reporterReportingPolicyDisabled', function() { + cr.webUIListenerCallback( + 'chrome-cleanup-on-idle', settings.ChromeCleanupIdleReason.INITIAL); + Polymer.dom.flush(); + + chromeCleanupPage.prefs = { + software_reporter: { + reporting: { + type: chrome.settingsPrivate.PrefType.BOOLEAN, + enforcement: chrome.settingsPrivate.Enforcement.ENFORCED, + controlledBy: chrome.settingsPrivate.ControlledBy.USER_POLICY, + value: false, + } + }, + }; + + const actionButton = chromeCleanupPage.$$('#action-button'); + assertTrue(!!actionButton); + assertFalse(actionButton.disabled); + + const logsControl = chromeCleanupPage.$$('#chromeCleanupLogsUploadControl'); + assertTrue(!!logsControl); + assertFalse(logsControl.disabled); + assertTrue(logsControl.$.checkbox.disabled); + }); });
diff --git a/chrome/tools/service_discovery_sniffer/service_discovery_sniffer.cc b/chrome/tools/service_discovery_sniffer/service_discovery_sniffer.cc index 7a15a4e4..3d7b5dc 100644 --- a/chrome/tools/service_discovery_sniffer/service_discovery_sniffer.cc +++ b/chrome/tools/service_discovery_sniffer/service_discovery_sniffer.cc
@@ -83,7 +83,8 @@ void ServiceTypePrinter::OnServiceUpdated(ServiceWatcher::UpdateType update, const std::string& service_name) { if (update == ServiceWatcher::UPDATE_ADDED) { - services_[service_name].reset(new ServicePrinter(client_, service_name)); + services_[service_name] = + std::make_unique<ServicePrinter>(client_, service_name); services_[service_name]->Added(); } else if (update == ServiceWatcher::UPDATE_CHANGED) { services_[service_name]->Changed();
diff --git a/chrome/tools/service_discovery_sniffer/service_discovery_sniffer.h b/chrome/tools/service_discovery_sniffer/service_discovery_sniffer.h index f6caf84..694bc10 100644 --- a/chrome/tools/service_discovery_sniffer/service_discovery_sniffer.h +++ b/chrome/tools/service_discovery_sniffer/service_discovery_sniffer.h
@@ -10,7 +10,6 @@ #include <string> #include "base/macros.h" -#include "base/memory/linked_ptr.h" #include "chrome/browser/local_discovery/service_discovery_client.h" namespace local_discovery { @@ -50,9 +49,7 @@ const std::string& service_name); private: - typedef std::map<std::string, linked_ptr<ServicePrinter> > ServiceMap; - - ServiceMap services_; + std::map<std::string, std::unique_ptr<ServicePrinter>> services_; std::unique_ptr<ServiceWatcher> watcher_; ServiceDiscoveryClient* client_;
diff --git a/chromecast/base/cast_sys_info_android_things.cc b/chromecast/base/cast_sys_info_android_things.cc index 79d910a..2662801f 100644 --- a/chromecast/base/cast_sys_info_android_things.cc +++ b/chromecast/base/cast_sys_info_android_things.cc
@@ -67,6 +67,15 @@ env, Java_CastSysInfoAndroidThings_getFactoryLocaleList(env), &locale_list); #endif + if (locale_list.empty()) { + CastSysInfoAndroidThings sys_info; + std::string factory_locale2; + std::string factory_locale1 = sys_info.GetFactoryLocale(&factory_locale2); + locale_list = {std::move(factory_locale1)}; + if (!factory_locale2.empty()) { + locale_list.push_back(factory_locale2); + } + } return locale_list; }
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index ed0ddf8e..1bf035b 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -394,7 +394,7 @@ # https://chromium.googlesource.com/chromium/src/+/master/docs/chromeos_build_instructions.md # https://chromium.googlesource.com/chromiumos/docs/+/master/simple_chrome_workflow.md if (is_cros_chrome_sdk) { - generate_vm_runner_script("cros_vm_launcher") { + generate_runner_script("cros_vm_launcher") { generated_script = "$root_build_dir/bin/launch_cros_vm" # Assume every time we build cros_vm_launcher, we also build chrome and @@ -402,10 +402,10 @@ deploy_chrome = true } - # The sanity test's actual binary is baked into the vm image. All we need to + # The sanity test's actual binary is baked into the OS image. All we need to # do is build the test wrapper and build our own browser to push to the VM # before testing it. - generate_vm_runner_script("cros_vm_sanity_test") { + generate_runner_script("cros_vm_sanity_test") { testonly = true test_exe = "cros_vm_sanity_test" generated_script = "$root_build_dir/bin/run_cros_vm_sanity_test"
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc index 77bc28f0..a105a4e7 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.cc +++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -131,6 +131,27 @@ return true; } +// Checks if |onc| is an unmanaged wifi network that has AutoConnect=true. +bool EnablesUnmanagedWifiAutoconnect(const base::DictionaryValue* onc) { + const base::Value* type = onc->FindKeyOfType(::onc::network_config::kType, + base::Value::Type::STRING); + if (!type || type->GetString() != ::onc::network_type::kWiFi) + return false; + + const base::Value* source = onc->FindKeyOfType(::onc::network_config::kSource, + base::Value::Type::STRING); + if (!source || + source->GetString() == ::onc::network_config::kSourceDevicePolicy || + source->GetString() == ::onc::network_config::kSourceUserPolicy) { + return false; + } + + const base::Value* autoconnect = onc->FindPathOfType( + {::onc::network_config::kWiFi, ::onc::wifi::kAutoConnect}, + base::Value::Type::BOOLEAN); + return autoconnect && autoconnect->GetBool(); +} + } // namespace struct ManagedNetworkConfigurationHandlerImpl::Policies { @@ -347,6 +368,14 @@ if (validation_result == onc::Validator::VALID_WITH_WARNINGS) NET_LOG(ERROR) << "Validation of ONC user settings produced warnings."; + // Don't allow AutoConnect=true for unmanaged wifi networks if + // 'AllowOnlyPolicyNetworksToAutoconnect' policy is active. + if (EnablesUnmanagedWifiAutoconnect(validated_user_settings.get()) && + AllowOnlyPolicyNetworksToAutoconnect()) { + InvokeErrorCallback(service_path, error_callback, kInvalidUserSettings); + return; + } + // Fill in HexSSID field from contents of SSID field if not set already. onc::FillInHexSSIDFieldsInOncObject(onc::kNetworkConfigurationSignature, validated_user_settings.get());
diff --git a/chromeos/services/assistant/service.cc b/chromeos/services/assistant/service.cc index 332d860..85212bd 100644 --- a/chromeos/services/assistant/service.cc +++ b/chromeos/services/assistant/service.cc
@@ -195,12 +195,14 @@ } break; case AssistantManagerService::State::RUNNING: - case AssistantManagerService::State::STARTED: - if (assistant_state_.settings_enabled().value()) { + if (assistant_state_.settings_enabled().value()) assistant_manager_service_->SetAccessToken(access_token_.value()); - } else { + else StopAssistantManagerService(); - } + break; + case AssistantManagerService::State::STARTED: + if (!assistant_state_.settings_enabled().value()) + StopAssistantManagerService(); break; } }
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 5d4a8b08..5d68a31f 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -177,6 +177,8 @@ "suggestion_selection.cc", "suggestion_selection.h", "sync_utils.h", + "test_data_creator.cc", + "test_data_creator.h", "ui/card_unmask_prompt_controller.h", "ui/card_unmask_prompt_controller_impl.cc", "ui/card_unmask_prompt_controller_impl.h",
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 155575f7..d68e6bdf 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -2082,6 +2082,13 @@ // Don't send suggestions or track forms that should not be parsed. context->form_structure->ShouldBeParsed(); + // Early exit here in the case where we want to disable company names. + if (got_autofillable_form && + context->focused_field->Type().GetStorableType() == COMPANY_NAME && + !base::FeatureList::IsEnabled(features::kAutofillEnableCompanyName)) { + got_autofillable_form = false; + } + // Log interactions of forms that are autofillable. if (got_autofillable_form) { if (context->focused_field->Type().group() == CREDIT_CARD) {
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc index 72f60ac..e027498 100644 --- a/components/autofill/core/browser/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -13,6 +13,7 @@ #include "base/feature_list.h" #include "base/macros.h" #include "base/metrics/metrics_hashes.h" +#include "base/metrics/statistics_recorder.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" @@ -448,6 +449,30 @@ AutofillMetricsIFrameTest, testing::Bool()); +// Test parameter indicates if the metrics are being logged for a form in an +// iframe or the main frame. True means the form is in the main frame. +class AutofillMetricsCompanyTest : public AutofillMetricsTest, + public testing::WithParamInterface<bool> { + public: + AutofillMetricsCompanyTest() : company_name_enabled_(GetParam()) {} + + void SetUp() override { + scoped_feature_list_.InitWithFeatureState( + features::kAutofillEnableCompanyName, company_name_enabled_); + AutofillMetricsTest::SetUp(); + } + + protected: + const bool company_name_enabled_; + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +INSTANTIATE_TEST_CASE_P(AutofillMetricsTest, + AutofillMetricsCompanyTest, + testing::Bool()); + // Test that we log quality metrics appropriately. TEST_F(AutofillMetricsTest, QualityMetrics) { // Set up our form data. @@ -2940,6 +2965,48 @@ } } +// Test that we log the correct number of Company Name Autofill suggestions when +// filling a form. +TEST_P(AutofillMetricsCompanyTest, CompanyNameSuggestions) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin()); + + FormFieldData field; + std::vector<ServerFieldType> field_types; + test::CreateTestFormField("Name", "name", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(NAME_FULL); + test::CreateTestFormField("Email", "email", "", "email", &field); + form.fields.push_back(field); + field_types.push_back(EMAIL_ADDRESS); + test::CreateTestFormField("Company", "company", "", "text", &field); + form.fields.push_back(field); + field_types.push_back(COMPANY_NAME); + + // Simulate having seen this form on page load. + // |form_structure| will be owned by |autofill_manager_|. + autofill_manager_->AddSeenForm(form, field_types, field_types); + + { + // Simulate activating the autofill popup for the phone field. + base::HistogramTester histogram_tester; + autofill_manager_->OnQueryFormFieldAutofill( + 0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false); + + if (company_name_enabled_) { + histogram_tester.ExpectUniqueSample("Autofill.AddressSuggestionsCount", 2, + 1); + } else { + EXPECT_EQ(nullptr, base::StatisticsRecorder::FindHistogram( + "Autofill.AddressSuggestionsCount")); + } + } +} + // Test that the credit card checkout flow user actions are correctly logged. TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) { RecreateCreditCards(true /* include_local_credit_card */,
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 023e49d1..555fb3c 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -13,6 +13,7 @@ #include <string> #include <utility> +#include "base/callback.h" #include "base/feature_list.h" #include "base/i18n/case_conversion.h" #include "base/i18n/timezone.h" @@ -77,18 +78,6 @@ constexpr base::TimeDelta kDisusedAddressDeletionTimeDelta = base::TimeDelta::FromDays(395); -// Time delta to create test data. -base::TimeDelta DeletableUseDateDelta() { - static base::TimeDelta delta = - kDisusedCreditCardDeletionTimeDelta + base::TimeDelta::FromDays(5); - return delta; -} -base::TimeDelta DeletableExpiryDateDelta() { - static base::TimeDelta delta = - kDisusedCreditCardDeletionTimeDelta + base::TimeDelta::FromDays(45); - return delta; -} - template <typename T> class FormGroupMatchesByGUIDFunctor { public: @@ -162,129 +151,6 @@ return a.second < b.second; } -AutofillProfile CreateBasicTestAddress(const std::string& locale) { - const base::Time use_date = - AutofillClock::Now() - base::TimeDelta::FromDays(20); - AutofillProfile profile; - profile.SetInfo(NAME_FULL, base::UTF8ToUTF16("John McTester"), locale); - profile.SetInfo(COMPANY_NAME, base::UTF8ToUTF16("Test Inc."), locale); - profile.SetInfo(EMAIL_ADDRESS, - base::UTF8ToUTF16("jmctester@fake.chromium.org"), locale); - profile.SetInfo(ADDRESS_HOME_LINE1, base::UTF8ToUTF16("123 Invented Street"), - locale); - profile.SetInfo(ADDRESS_HOME_LINE2, base::UTF8ToUTF16("Suite A"), locale); - profile.SetInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16("Mountain View"), - locale); - profile.SetInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("California"), locale); - profile.SetInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("94043"), locale); - profile.SetInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16("US"), locale); - profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16("844-555-0173"), - locale); - profile.set_use_date(use_date); - return profile; -} - -AutofillProfile CreateDisusedTestAddress(const std::string& locale) { - const base::Time use_date = - AutofillClock::Now() - base::TimeDelta::FromDays(185); - AutofillProfile profile; - profile.SetInfo(NAME_FULL, base::UTF8ToUTF16("Polly Disused"), locale); - profile.SetInfo(COMPANY_NAME, - base::UTF8ToUTF16(base::StringPrintf( - "%lld Inc.", static_cast<long long>(use_date.ToTimeT()))), - locale); - profile.SetInfo(EMAIL_ADDRESS, - base::UTF8ToUTF16("polly.disused@fake.chromium.org"), locale); - profile.SetInfo(ADDRESS_HOME_LINE1, base::UTF8ToUTF16("456 Disused Lane"), - locale); - profile.SetInfo(ADDRESS_HOME_LINE2, base::UTF8ToUTF16("Apt. B"), locale); - profile.SetInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16("Austin"), locale); - profile.SetInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Texas"), locale); - profile.SetInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("73301"), locale); - profile.SetInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16("US"), locale); - profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16("844-555-0174"), - locale); - profile.set_use_date(use_date); - return profile; -} - -AutofillProfile CreateDisusedDeletableTestAddress(const std::string& locale) { - const base::Time use_date = - AutofillClock::Now() - base::TimeDelta::FromDays(400); - AutofillProfile profile; - profile.SetInfo(NAME_FULL, base::UTF8ToUTF16("Polly Deletable"), locale); - profile.SetInfo(COMPANY_NAME, - base::UTF8ToUTF16(base::StringPrintf( - "%lld Inc.", static_cast<long long>(use_date.ToTimeT()))), - locale); - profile.SetInfo(EMAIL_ADDRESS, - base::UTF8ToUTF16("polly.deletable@fake.chromium.org"), - locale); - profile.SetInfo(ADDRESS_HOME_LINE1, base::UTF8ToUTF16("459 Deletable Lane"), - locale); - profile.SetInfo(ADDRESS_HOME_LINE2, base::UTF8ToUTF16("Apt. B"), locale); - profile.SetInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16("Austin"), locale); - profile.SetInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Texas"), locale); - profile.SetInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("73301"), locale); - profile.SetInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16("US"), locale); - profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16("844-555-0274"), - locale); - profile.set_use_date(use_date); - return profile; -} - -// Create a card expiring 500 days from now which was last used 10 days ago. -CreditCard CreateBasicTestCreditCard(const std::string& locale) { - const base::Time now = AutofillClock::Now(); - const base::Time use_date = now - base::TimeDelta::FromDays(10); - base::Time::Exploded expiry_date; - (now + base::TimeDelta::FromDays(500)).LocalExplode(&expiry_date); - - CreditCard credit_card; - credit_card.SetInfo(CREDIT_CARD_NAME_FULL, - base::UTF8ToUTF16("Alice Testerson"), locale); - credit_card.SetInfo(CREDIT_CARD_NUMBER, base::UTF8ToUTF16("4545454545454545"), - locale); - credit_card.SetExpirationMonth(expiry_date.month); - credit_card.SetExpirationYear(expiry_date.year); - credit_card.set_use_date(use_date); - return credit_card; -} - -CreditCard CreateDisusedTestCreditCard(const std::string& locale) { - const base::Time now = AutofillClock::Now(); - const base::Time use_date = now - base::TimeDelta::FromDays(185); - base::Time::Exploded expiry_date; - (now - base::TimeDelta::FromDays(200)).LocalExplode(&expiry_date); - - CreditCard credit_card; - credit_card.SetInfo(CREDIT_CARD_NAME_FULL, base::UTF8ToUTF16("Bob Disused"), - locale); - credit_card.SetInfo(CREDIT_CARD_NUMBER, base::UTF8ToUTF16("4111111111111111"), - locale); - credit_card.SetExpirationMonth(expiry_date.month); - credit_card.SetExpirationYear(expiry_date.year); - credit_card.set_use_date(use_date); - return credit_card; -} - -CreditCard CreateDisusedDeletableTestCreditCard(const std::string& locale) { - const base::Time now = AutofillClock::Now(); - const base::Time use_date = now - DeletableUseDateDelta(); - base::Time::Exploded expiry_date; - (now - DeletableExpiryDateDelta()).LocalExplode(&expiry_date); - - CreditCard credit_card; - credit_card.SetInfo(CREDIT_CARD_NAME_FULL, - base::UTF8ToUTF16("Charlie Deletable"), locale); - credit_card.SetInfo(CREDIT_CARD_NUMBER, base::UTF8ToUTF16("378282246310005"), - locale); - credit_card.SetExpirationMonth(expiry_date.month); - credit_card.SetExpirationYear(expiry_date.year); - credit_card.set_use_date(use_date); - return credit_card; -} - } // namespace // Helper class to abstract the switching between account and profile storage @@ -400,7 +266,8 @@ }; PersonalDataManager::PersonalDataManager(const std::string& app_locale) - : app_locale_(app_locale) { + : app_locale_(app_locale), + test_data_creator_(kDisusedCreditCardDeletionTimeDelta, app_locale_) { database_helper_ = std::make_unique<PersonalDatabaseHelper>(this); } @@ -2596,32 +2463,6 @@ return server_address.guid(); } -void PersonalDataManager::MaybeCreateTestAddresses() { - if (has_created_test_addresses_) - return; - - has_created_test_addresses_ = true; - if (!base::FeatureList::IsEnabled(features::kAutofillCreateDataForTest)) - return; - - AddProfile(CreateBasicTestAddress(app_locale_)); - AddProfile(CreateDisusedTestAddress(app_locale_)); - AddProfile(CreateDisusedDeletableTestAddress(app_locale_)); -} - -void PersonalDataManager::MaybeCreateTestCreditCards() { - if (has_created_test_credit_cards_) - return; - - has_created_test_credit_cards_ = true; - if (!base::FeatureList::IsEnabled(features::kAutofillCreateDataForTest)) - return; - - AddCreditCard(CreateBasicTestCreditCard(app_locale_)); - AddCreditCard(CreateDisusedTestCreditCard(app_locale_)); - AddCreditCard(CreateDisusedDeletableTestCreditCard(app_locale_)); -} - // static bool PersonalDataManager::IsCreditCardDeletable(const CreditCard* card) { const base::Time deletion_threshold = @@ -2723,18 +2564,38 @@ } void PersonalDataManager::ApplyAddressFixesAndCleanups() { - RemoveOrphanAutofillTableRows(); // One-time fix, otherwise NOP. - ApplyDedupingRoutine(); // Once per major version, otherwise NOP. + // One-time fix, otherwise NOP. + RemoveOrphanAutofillTableRows(); + + // Once per major version, otherwise NOP. + ApplyDedupingRoutine(); + DeleteDisusedAddresses(); - MaybeCreateTestAddresses(); // Once per user profile startup. - ClearProfileNonSettingsOrigins(); // Ran everytime it is called. - MoveJapanCityToStreetAddress(); // One-time fix, otherwise NOP. + + // If feature AutofillCreateDataForTest is enabled, and once per user profile + // startup. + test_data_creator_.MaybeAddTestProfiles(base::BindRepeating( + &PersonalDataManager::AddProfile, base::Unretained(this))); + + // Ran everytime it is called. + ClearProfileNonSettingsOrigins(); + + // One-time fix, otherwise NOP. + MoveJapanCityToStreetAddress(); } void PersonalDataManager::ApplyCardFixesAndCleanups() { + DLOG(ERROR) << "CREDIT CARD SYNC !!"; + DeleteDisusedCreditCards(); - MaybeCreateTestCreditCards(); // Once per user profile startup. - ClearCreditCardNonSettingsOrigins(); // Ran everytime it is called. + + // If feature AutofillCreateDataForTest is enabled, and once per user profile + // startup. + test_data_creator_.MaybeAddTestCreditCards(base::BindRepeating( + &PersonalDataManager::AddCreditCard, base::Unretained(this))); + + // Ran everytime it is called. + ClearCreditCardNonSettingsOrigins(); } void PersonalDataManager::ResetProfileValidity() {
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index bed71ef1..929fcb0 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -27,6 +27,7 @@ #include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/suggestion.h" #include "components/autofill/core/browser/sync_utils.h" +#include "components/autofill/core/browser/test_data_creator.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h" #include "components/history/core/browser/history_service_observer.h" @@ -729,16 +730,6 @@ AutofillProfile* profile, const std::unordered_set<std::string>& used_billing_address_guids); - // If the AutofillCreateDataForTest feature is enabled, this helper creates - // autofill address data that would otherwise be difficult to create - // manually using the UI. - void MaybeCreateTestAddresses(); - - // If the AutofillCreateDataForTest feature is enabled, this helper creates - // autofill credit card data that would otherwise be difficult to create - // manually using the UI. - void MaybeCreateTestCreditCards(); - // Applies various fixes and cleanups on autofill addresses. void ApplyAddressFixesAndCleanups(); @@ -808,9 +799,10 @@ // Whether new information was received from the sync server. bool has_synced_new_data_ = false; - // True if test data has been created this session. - bool has_created_test_addresses_ = false; - bool has_created_test_credit_cards_ = false; + // Used to create test data. If the AutofillCreateDataForTest feature is + // enabled, this helper creates autofill profiles and credit card data that + // would otherwise be difficult to create manually using the UI. + TestDataCreator test_data_creator_; // Whether sync should be considered on in a test. bool is_syncing_for_test_ = false;
diff --git a/components/autofill/core/browser/test_data_creator.cc b/components/autofill/core/browser/test_data_creator.cc new file mode 100644 index 0000000..5ef8892 --- /dev/null +++ b/components/autofill/core/browser/test_data_creator.cc
@@ -0,0 +1,204 @@ +// Copyright 2018 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/autofill/core/browser/test_data_creator.h" + +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/credit_card.h" +#include "components/autofill/core/common/autofill_clock.h" +#include "components/autofill/core/common/autofill_features.h" + +namespace autofill { + +namespace { +// Time delta to create test data. +base::TimeDelta DeletableUseDateDelta( + const base::TimeDelta& cc_deletion_delta) { + static base::TimeDelta delta = + cc_deletion_delta + base::TimeDelta::FromDays(5); + return delta; +} +base::TimeDelta DeletableExpiryDateDelta( + const base::TimeDelta& cc_deletion_delta) { + static base::TimeDelta delta = + cc_deletion_delta + base::TimeDelta::FromDays(45); + return delta; +} +} // namespace + +TestDataCreator::TestDataCreator(base::TimeDelta cc_deletion_delta, + std::string app_locale) + : cc_deletion_delta_(cc_deletion_delta), app_locale_(app_locale) {} + +void TestDataCreator::MaybeAddTestProfiles( + const base::RepeatingCallback<void(const AutofillProfile&)>& + add_profile_callback) { + if (has_created_test_addresses_ || + !base::FeatureList::IsEnabled(features::kAutofillCreateDataForTest)) + return; + + has_created_test_addresses_ = true; + + for (const auto& profile : GetTestProfiles()) { + add_profile_callback.Run(profile); + } + + DLOG(WARNING) << this << " added fake autofill profiles."; +} + +void TestDataCreator::MaybeAddTestCreditCards( + const base::RepeatingCallback<void(const CreditCard&)>& add_cc_callback) { + if (has_created_test_credit_cards_ || + !base::FeatureList::IsEnabled(features::kAutofillCreateDataForTest)) + return; + + has_created_test_credit_cards_ = true; + + for (const auto& credit_card : GetTestCreditCards()) { + add_cc_callback.Run(credit_card); + } + + DLOG(WARNING) << this << " added fake credit cards."; +} + +std::vector<AutofillProfile> TestDataCreator::GetTestProfiles() { + return {CreateBasicTestAddress(), CreateDisusedTestAddress(), + CreateDisusedDeletableTestAddress()}; +} + +std::vector<CreditCard> TestDataCreator::GetTestCreditCards() { + return {CreateBasicTestCreditCard(), CreateDisusedTestCreditCard(), + CreateDisusedDeletableTestCreditCard()}; +} + +AutofillProfile TestDataCreator::CreateBasicTestAddress() { + const base::Time use_date = + AutofillClock::Now() - base::TimeDelta::FromDays(20); + AutofillProfile profile; + profile.SetInfo(NAME_FULL, base::UTF8ToUTF16("John McTester"), app_locale_); + profile.SetInfo(COMPANY_NAME, base::UTF8ToUTF16("Test Inc."), app_locale_); + profile.SetInfo(EMAIL_ADDRESS, + base::UTF8ToUTF16("jmctester@fake.chromium.org"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_LINE1, base::UTF8ToUTF16("123 Invented Street"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_LINE2, base::UTF8ToUTF16("Suite A"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16("Mountain View"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("California"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("94043"), app_locale_); + profile.SetInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16("US"), app_locale_); + profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16("844-555-0173"), + app_locale_); + profile.set_use_date(use_date); + return profile; +} + +AutofillProfile TestDataCreator::CreateDisusedTestAddress() { + const base::Time use_date = + AutofillClock::Now() - base::TimeDelta::FromDays(185); + AutofillProfile profile; + profile.SetInfo(NAME_FULL, base::UTF8ToUTF16("Polly Disused"), app_locale_); + profile.SetInfo(COMPANY_NAME, + base::UTF8ToUTF16(base::StringPrintf( + "%lld Inc.", static_cast<long long>(use_date.ToTimeT()))), + app_locale_); + profile.SetInfo(EMAIL_ADDRESS, + base::UTF8ToUTF16("polly.disused@fake.chromium.org"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_LINE1, base::UTF8ToUTF16("456 Disused Lane"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_LINE2, base::UTF8ToUTF16("Apt. B"), app_locale_); + profile.SetInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16("Austin"), app_locale_); + profile.SetInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Texas"), app_locale_); + profile.SetInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("73301"), app_locale_); + profile.SetInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16("US"), app_locale_); + profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16("844-555-0174"), + app_locale_); + profile.set_use_date(use_date); + return profile; +} + +AutofillProfile TestDataCreator::CreateDisusedDeletableTestAddress() { + const base::Time use_date = + AutofillClock::Now() - base::TimeDelta::FromDays(400); + AutofillProfile profile; + profile.SetInfo(NAME_FULL, base::UTF8ToUTF16("Polly Deletable"), app_locale_); + profile.SetInfo(COMPANY_NAME, + base::UTF8ToUTF16(base::StringPrintf( + "%lld Inc.", static_cast<long long>(use_date.ToTimeT()))), + app_locale_); + profile.SetInfo(EMAIL_ADDRESS, + base::UTF8ToUTF16("polly.deletable@fake.chromium.org"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_LINE1, base::UTF8ToUTF16("459 Deletable Lane"), + app_locale_); + profile.SetInfo(ADDRESS_HOME_LINE2, base::UTF8ToUTF16("Apt. B"), app_locale_); + profile.SetInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16("Austin"), app_locale_); + profile.SetInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Texas"), app_locale_); + profile.SetInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("73301"), app_locale_); + profile.SetInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16("US"), app_locale_); + profile.SetInfo(PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16("844-555-0274"), + app_locale_); + profile.set_use_date(use_date); + return profile; +} + +// Create a card expiring 500 days from now which was last used 10 days ago. +CreditCard TestDataCreator::CreateBasicTestCreditCard() { + const base::Time now = AutofillClock::Now(); + const base::Time use_date = now - base::TimeDelta::FromDays(10); + base::Time::Exploded expiry_date; + (now + base::TimeDelta::FromDays(500)).LocalExplode(&expiry_date); + + CreditCard credit_card; + credit_card.SetInfo(CREDIT_CARD_NAME_FULL, + base::UTF8ToUTF16("Alice Testerson"), app_locale_); + credit_card.SetInfo(CREDIT_CARD_NUMBER, base::UTF8ToUTF16("4545454545454545"), + app_locale_); + credit_card.SetExpirationMonth(expiry_date.month); + credit_card.SetExpirationYear(expiry_date.year); + credit_card.set_use_date(use_date); + return credit_card; +} + +CreditCard TestDataCreator::CreateDisusedTestCreditCard() { + const base::Time now = AutofillClock::Now(); + const base::Time use_date = now - base::TimeDelta::FromDays(185); + base::Time::Exploded expiry_date; + (now - base::TimeDelta::FromDays(200)).LocalExplode(&expiry_date); + + CreditCard credit_card; + credit_card.SetInfo(CREDIT_CARD_NAME_FULL, base::UTF8ToUTF16("Bob Disused"), + app_locale_); + credit_card.SetInfo(CREDIT_CARD_NUMBER, base::UTF8ToUTF16("4111111111111111"), + app_locale_); + credit_card.SetExpirationMonth(expiry_date.month); + credit_card.SetExpirationYear(expiry_date.year); + credit_card.set_use_date(use_date); + return credit_card; +} + +CreditCard TestDataCreator::CreateDisusedDeletableTestCreditCard() { + const base::Time now = AutofillClock::Now(); + const base::Time use_date = now - DeletableUseDateDelta(cc_deletion_delta_); + base::Time::Exploded expiry_date; + (now - DeletableExpiryDateDelta(cc_deletion_delta_)) + .LocalExplode(&expiry_date); + + CreditCard credit_card; + credit_card.SetInfo(CREDIT_CARD_NAME_FULL, + base::UTF8ToUTF16("Charlie Deletable"), app_locale_); + credit_card.SetInfo(CREDIT_CARD_NUMBER, base::UTF8ToUTF16("378282246310005"), + app_locale_); + credit_card.SetExpirationMonth(expiry_date.month); + credit_card.SetExpirationYear(expiry_date.year); + credit_card.set_use_date(use_date); + return credit_card; +} +} // namespace autofill
diff --git a/components/autofill/core/browser/test_data_creator.h b/components/autofill/core/browser/test_data_creator.h new file mode 100644 index 0000000..5a34c16 --- /dev/null +++ b/components/autofill/core/browser/test_data_creator.h
@@ -0,0 +1,52 @@ +// Copyright 2018 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 COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_DATA_CREATOR_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_DATA_CREATOR_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/credit_card.h" + +namespace autofill { + +class TestDataCreator { + public: + TestDataCreator(base::TimeDelta cc_deletion_delta, std::string app_locale); + + void MaybeAddTestProfiles( + const base::RepeatingCallback<void(const AutofillProfile&)>& + add_profile_callback); + void MaybeAddTestCreditCards( + const base::RepeatingCallback<void(const CreditCard&)>& add_cc_callback); + + private: + std::vector<AutofillProfile> GetTestProfiles(); + std::vector<CreditCard> GetTestCreditCards(); + + AutofillProfile CreateBasicTestAddress(); + AutofillProfile CreateDisusedTestAddress(); + AutofillProfile CreateDisusedDeletableTestAddress(); + + CreditCard CreateBasicTestCreditCard(); + CreditCard CreateDisusedTestCreditCard(); + CreditCard CreateDisusedDeletableTestCreditCard(); + + // Minimum amount of time since last use for a credit card to be considered + // "disused". + base::TimeDelta cc_deletion_delta_; + + std::string app_locale_; + + // True if test data has been created this session. + bool has_created_test_addresses_ = false; + bool has_created_test_credit_cards_ = false; +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_DATA_CREATOR_H_ \ No newline at end of file
diff --git a/components/autofill/core/common/autofill_constants.cc b/components/autofill/core/common/autofill_constants.cc index 53a8b46..e1ebeb1 100644 --- a/components/autofill/core/common/autofill_constants.cc +++ b/components/autofill/core/common/autofill_constants.cc
@@ -9,13 +9,6 @@ namespace autofill { -const char kHelpURL[] = -#if defined(OS_CHROMEOS) - "https://support.google.com/chromebook/?p=settings_autofill"; -#else - "https://support.google.com/chrome/?p=settings_autofill"; -#endif - const char kSettingsOrigin[] = "Chrome settings"; size_t MinRequiredFieldsForHeuristics() {
diff --git a/components/autofill/core/common/autofill_constants.h b/components/autofill/core/common/autofill_constants.h index 2ab64b6..bed7d9a6 100644 --- a/components/autofill/core/common/autofill_constants.h +++ b/components/autofill/core/common/autofill_constants.h
@@ -11,9 +11,6 @@ namespace autofill { -// Help URL for the Autofill dialog. -extern const char kHelpURL[]; - // The origin of an AutofillDataModel created or modified in the settings page. extern const char kSettingsOrigin[];
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index a4b797d9..877d6fcc 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -221,6 +221,33 @@ current_version.substr(0, current_version.find('.'))) { passphrase_prompt_triggered_by_version_ = true; } + + startup_controller_ = std::make_unique<syncer::StartupController>( + base::BindRepeating(&ProfileSyncService::GetPreferredDataTypes, + base::Unretained(this)), + base::BindRepeating(&ProfileSyncService::ShouldStartEngine, + base::Unretained(this)), + base::BindRepeating(&ProfileSyncService::StartUpSlowEngineComponents, + base::Unretained(this))); + + sync_stopped_reporter_ = std::make_unique<syncer::SyncStoppedReporter>( + sync_service_url_, local_device_->GetSyncUserAgent(), url_loader_factory_, + syncer::SyncStoppedReporter::ResultCallback()); + + if (gaia_cookie_manager_service_) + gaia_cookie_manager_service_->AddObserver(this); + +#if defined(OS_CHROMEOS) + std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); + if (bootstrap_token.empty()) { + sync_prefs_.SetEncryptionBootstrapToken( + sync_prefs_.GetSpareBootstrapToken()); + } +#endif + + memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>( + base::BindRepeating(&ProfileSyncService::OnMemoryPressure, + sync_enabled_weak_factory_.GetWeakPtr())); } ProfileSyncService::~ProfileSyncService() { @@ -235,30 +262,16 @@ void ProfileSyncService::Initialize() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // TODO(mastiz): The controllers map should be provided as argument. + data_type_controllers_ = + BuildDataTypeControllerMap(sync_client_->CreateDataTypeControllers(this)); + syncer::ModelTypeStoreService* model_type_store_service = sync_client_->GetModelTypeStoreService(); DCHECK(model_type_store_service); syncer::RepeatingModelTypeStoreFactory model_type_store_factory = model_type_store_service->GetStoreFactory(); - startup_controller_ = std::make_unique<syncer::StartupController>( - base::BindRepeating(&ProfileSyncService::GetPreferredDataTypes, - base::Unretained(this)), - base::BindRepeating(&ProfileSyncService::ShouldStartEngine, - base::Unretained(this)), - base::BindRepeating(&ProfileSyncService::StartUpSlowEngineComponents, - base::Unretained(this))); - - sync_stopped_reporter_ = std::make_unique<syncer::SyncStoppedReporter>( - sync_service_url_, local_device_->GetSyncUserAgent(), url_loader_factory_, - syncer::SyncStoppedReporter::ResultCallback()); - - // TODO(mastiz): This function should probably be deferred to the very end of - // Initialize(), or even better initiated directly by the sync client (e.g. - // inject the map as part of Init()'s parameters). - data_type_controllers_ = - BuildDataTypeControllerMap(sync_client_->CreateDataTypeControllers(this)); - device_info_sync_bridge_ = std::make_unique<syncer::DeviceInfoSyncBridge>( local_device_.get(), model_type_store_factory, std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( @@ -273,9 +286,6 @@ ->GetControllerDelegate() .get())); - if (gaia_cookie_manager_service_) - gaia_cookie_manager_service_->AddObserver(this); - sync_prefs_.AddSyncPrefObserver(this); // If sync is disallowed by policy, clean up. @@ -304,18 +314,6 @@ // account isn't initialized. RecordSyncInitialState(GetDisableReasons(), IsFirstSetupComplete()); -#if defined(OS_CHROMEOS) - std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); - if (bootstrap_token.empty()) { - sync_prefs_.SetEncryptionBootstrapToken( - sync_prefs_.GetSpareBootstrapToken()); - } -#endif - - memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>( - base::BindRepeating(&ProfileSyncService::OnMemoryPressure, - sync_enabled_weak_factory_.GetWeakPtr())); - // Auto-start means the first time the profile starts up, sync should start up // immediately. bool force_immediate = (start_behavior_ == AUTO_START &&
diff --git a/components/browser_sync/sync_auth_manager.cc b/components/browser_sync/sync_auth_manager.cc index c9f85540..86edffc 100644 --- a/components/browser_sync/sync_auth_manager.cc +++ b/components/browser_sync/sync_auth_manager.cc
@@ -346,7 +346,8 @@ } void SyncAuthManager::OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) { + const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) { UpdateSyncAccountIfNecessary(); }
diff --git a/components/browser_sync/sync_auth_manager.h b/components/browser_sync/sync_auth_manager.h index 8a943886..a860d54 100644 --- a/components/browser_sync/sync_auth_manager.h +++ b/components/browser_sync/sync_auth_manager.h
@@ -96,7 +96,8 @@ const AccountInfo& account_info) override; void OnRefreshTokenRemovedForAccount(const std::string& account_id) override; void OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) override; + const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) override; // Test-only methods for inspecting/modifying internal state. bool IsRetryingAccessTokenFetchForTest() const;
diff --git a/components/component_updater/pref_names.cc b/components/component_updater/pref_names.cc index def66fc7..10916fa 100644 --- a/components/component_updater/pref_names.cc +++ b/components/component_updater/pref_names.cc
@@ -30,7 +30,7 @@ // Enable running the SwReporter. const char kSwReporterEnabled[] = "software_reporter.enabled"; -// Control whether SwReporter results are reported to Google. +// Control whether SwReporter and Chrome Cleanup results are reported to Google. const char kSwReporterReportingEnabled[] = "software_reporter.reporting"; // The version string of the reporter that triggered an SRT prompt. An empty
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java index 2b0bbcf..2cd1231 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -921,7 +921,7 @@ } private boolean hasBytesInNetLog(File logFile) throws Exception { - return containsStringInNetLog(logFile, "\"hex_encoded_bytes\""); + return containsStringInNetLog(logFile, "\"bytes\""); } private boolean containsStringInNetLog(File logFile, String content) throws Exception {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 55e4df5..bbc0583dc 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -13863,7 +13863,7 @@ 'tags': [], 'desc': '''This policy controls the list of websites to open in an alternative browser. - Note that elements can also be added to this list through the <ph name="USE_IE_SITELIST_POLICY_NAME">BrowserSwitcherUseIeSitelist</ph> policy. + Note that elements can also be added to this list through the <ph name="USE_IE_SITELIST_POLICY_NAME">BrowserSwitcherUseIeSitelist</ph> and <ph name="EXTERNAL_SITELIST_URL_POLICY_NAME">BrowserSwitcherExternalSitelistUrl</ph> policies. When this policy is left unset, no websites are added to the list. @@ -13896,7 +13896,7 @@ 'tags': [], 'desc': '''This policy controls the list of websites that will never cause a browser switch. - Note that elements can also be added to this list through the <ph name="USE_IE_SITELIST_POLICY_NAME">BrowserSwitcherUseIeSitelist</ph> policy. + Note that elements can also be added to this list through the <ph name="USE_IE_SITELIST_POLICY_NAME">BrowserSwitcherUseIeSitelist</ph> and <ph name="EXTERNAL_SITELIST_URL_POLICY_NAME">BrowserSwitcherExternalSitelistUrl</ph> policies. When this policy is left unset, no websites are added to the list. @@ -13927,6 +13927,28 @@ For more information on Internet Explorer's <ph name="IEEM_SITELIST_POLICY">SiteList</ph> policy: https://docs.microsoft.com/internet-explorer/ie11-deploy-guide/what-is-enterprise-mode''', }, { + 'id': 511, + 'name': 'BrowserSwitcherExternalSitelistUrl', + 'future': True, + 'type': 'string', + 'schema': { 'type': 'string' }, + 'example_value': 'http://example.com/sitelist.xml', + 'features': { + 'dynamic_refresh': False, + 'per_profile': True, + }, + 'supported_on': ['chrome.*:72-'], + 'caption': '''URL of an XML file that contains URLs to load in an alternative browser.''', + 'tags': [], + 'desc': '''This policy is a URL, that points to an XML file in the same format as Internet Explorer's <ph name="IEEM_SITELIST_POLICY">SiteList</ph> policy. This loads rules from an XML file, without sharing those rules with Internet Explorer. + + When this policy is left unset, or not set to a valid URL, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> does not use it as a source of rules for switching browsers. + + When this policy is set to a valid URL, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> downloads the site list from that URL, and applies the rules as if they had been configured with the <ph name="SITELIST_POLICY_NAME">BrowserSwitcherUrlList</ph> policy. + + For more information on Internet Explorer's <ph name="IEEM_SITELIST_POLICY">SiteList</ph> policy: https://docs.microsoft.com/internet-explorer/ie11-deploy-guide/what-is-enterprise-mode''', + }, + { 'name': 'DeviceDisplayResolution', 'type': 'dict', 'schema': { @@ -14259,8 +14281,20 @@ 'desc': '''Caption text of the field 'maximum' in the summary chart of a policy in the generated documentation. Present only if policy has a maximum range restriction.''', 'text': '''Maximum:''' }, + 'deprecated_policy_group_caption': { + 'desc': '''Localized name for the deprecated policies folder, for Microsoft's Group Policy Editor.''', + 'text': '''Deprecated policies''', + }, + 'deprecated_policy_group_desc': { + 'desc': '''Localized description for the deprecated policies folder, for Microsoft's Group Policy Editor.''', + 'text': '''These policies are included here to make them easy to remove.''', + }, + 'deprecated_policy_desc': { + 'desc': '''Description shared by all deprecated policies, in Microsoft Windows' Group Policy Editor.''', + 'text': '''This policy is deprecated. Its usage is discouraged. Read more at https://support.google.com/chrome/a/answer/7643500''' + }, }, 'placeholders': [], 'deleted_policy_ids': [412], - 'highest_id_currently_used': 510, + 'highest_id_currently_used': 511 }
diff --git a/components/policy/tools/template_writers/writers/adm_writer.py b/components/policy/tools/template_writers/writers/adm_writer.py index 6bffe31f..56f185e 100755 --- a/components/policy/tools/template_writers/writers/adm_writer.py +++ b/components/policy/tools/template_writers/writers/adm_writer.py
@@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -from writers import template_writer +from writers import gpo_editor_writer import re NEWLINE = '\r\n' @@ -60,7 +60,7 @@ return NEWLINE.join(self.lines) -class AdmWriter(template_writer.TemplateWriter): +class AdmWriter(gpo_editor_writer.GpoEditorWriter): '''Class for generating policy templates in Windows ADM format. It is used by PolicyTemplateGenerator to write ADM files. ''' @@ -184,7 +184,10 @@ reference_link_text = reference_link_text.replace('$6', reference_url) if policy_desc is not None: - return policy_desc + '\n\n' + reference_link_text + policy_desc += '\n\n' + if not policy.get('deprecated', False): + policy_desc += reference_link_text + return policy_desc else: return reference_link_text
diff --git a/components/policy/tools/template_writers/writers/adm_writer_unittest.py b/components/policy/tools/template_writers/writers/adm_writer_unittest.py index 3c5b6a5..e381ded 100755 --- a/components/policy/tools/template_writers/writers/adm_writer_unittest.py +++ b/components/policy/tools/template_writers/writers/adm_writer_unittest.py
@@ -24,6 +24,17 @@ 'doc_reference_link': { 'text': 'Reference: $6', 'desc': 'bleh' }, + 'deprecated_policy_group_caption': { + 'text': 'Deprecated policies', 'desc': 'bleh' + }, + 'deprecated_policy_group_desc': { + 'desc': 'bleh', + 'text': 'These policies are included here to make them easy to remove.' + }, + 'deprecated_policy_desc': { + 'desc': 'bleh', + 'text': 'This policy is deprecated. blah blah blah' + }, }''' @@ -1101,6 +1112,80 @@ ''') self.CompareOutputs(output, expected_output) + def testDeprecatedPolicy(self): + # Tests that a deprecated policy gets placed in the special + # 'DeprecatedPolicies' group. + policy_json = ''' + { + 'policy_definitions': [ + { + 'name': 'Policy1', + 'type': 'string', + 'deprecated': True, + 'features': { 'can_be_recommended': True }, + 'supported_on': ['chrome.win:8-'], + 'caption': 'Caption of policy1.', + 'desc': """Description of policy1.""" + }, + ], + 'placeholders': [], + 'messages': %s + }''' % MESSAGES + output = self.GetOutput(policy_json, {'_chromium': '1'}, 'adm') + expected_output = self.ConstructOutput(['MACHINE', 'USER'], ''' + CATEGORY !!chromium + KEYNAME "Software\\Policies\\Chromium" + + CATEGORY !!DeprecatedPolicies_Category + POLICY !!Policy1_Policy + #if version >= 4 + SUPPORTED !!SUPPORTED_WIN7 + #endif + EXPLAIN !!Policy1_Explain + + PART !!Policy1_Part EDITTEXT + VALUENAME "Policy1" + MAXLEN 1000000 + END PART + END POLICY + + END CATEGORY + + END CATEGORY + + CATEGORY !!chromium_recommended + KEYNAME "Software\\Policies\\Chromium\\Recommended" + + CATEGORY !!DeprecatedPolicies_Category + POLICY !!Policy1_Policy + #if version >= 4 + SUPPORTED !!SUPPORTED_WIN7 + #endif + EXPLAIN !!Policy1_Explain + + PART !!Policy1_Part EDITTEXT + VALUENAME "Policy1" + MAXLEN 1000000 + END PART + END POLICY + + END CATEGORY + + END CATEGORY + + +''', '''[Strings] +SUPPORTED_WIN7="Microsoft Windows 7 or later" +chromium="Chromium" +chromium_recommended="Chromium - Recommended" +DeprecatedPolicies_Category="Deprecated policies" +Policy1_Policy="Caption of policy1." +Policy1_Explain="This policy is deprecated. blah blah blah\\n\\n" +Policy1_Part="Caption of policy1." +''') + self.CompareOutputs(output, expected_output) + + if __name__ == '__main__': unittest.main()
diff --git a/components/policy/tools/template_writers/writers/adml_writer.py b/components/policy/tools/template_writers/writers/adml_writer.py index ae59d4c..21f7ed616 100755 --- a/components/policy/tools/template_writers/writers/adml_writer.py +++ b/components/policy/tools/template_writers/writers/adml_writer.py
@@ -4,7 +4,7 @@ # found in the LICENSE file. from xml.dom import minidom -from writers import xml_formatted_writer +from writers import gpo_editor_writer, xml_formatted_writer from writers.admx_writer import AdmxElementType import json import re @@ -18,7 +18,8 @@ return ADMLWriter(['win'], config) -class ADMLWriter(xml_formatted_writer.XMLFormattedWriter): +class ADMLWriter(xml_formatted_writer.XMLFormattedWriter, + gpo_editor_writer.GpoEditorWriter): ''' Class for generating an ADML policy template. It is used by the PolicyTemplateGenerator to write the ADML file. '''
diff --git a/components/policy/tools/template_writers/writers/admx_writer.py b/components/policy/tools/template_writers/writers/admx_writer.py index 0d59bf7..dba82dd3 100755 --- a/components/policy/tools/template_writers/writers/admx_writer.py +++ b/components/policy/tools/template_writers/writers/admx_writer.py
@@ -4,7 +4,7 @@ # found in the LICENSE file. from xml.dom import minidom -from writers import xml_formatted_writer +from writers import gpo_editor_writer, xml_formatted_writer class AdmxElementType: @@ -85,7 +85,8 @@ return ADMXWriter(['win'], config) -class ADMXWriter(xml_formatted_writer.XMLFormattedWriter): +class ADMXWriter(xml_formatted_writer.XMLFormattedWriter, + gpo_editor_writer.GpoEditorWriter): '''Class for generating an ADMX policy template. It is used by the PolicyTemplateGenerator to write the admx file. '''
diff --git a/components/policy/tools/template_writers/writers/gpo_editor_writer.py b/components/policy/tools/template_writers/writers/gpo_editor_writer.py new file mode 100755 index 0000000..8aa50099 --- /dev/null +++ b/components/policy/tools/template_writers/writers/gpo_editor_writer.py
@@ -0,0 +1,83 @@ +#!/usr/bin/env python +# Copyright (c) 2018 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 writers import template_writer + + +class GpoEditorWriter(template_writer.TemplateWriter): + '''Abstract class for ADM and ADMX writers. + + It includes deprecated policies in its output, and places them in a dedicated + 'DeprecatedPolicies' group. Every deprecated policy has the same description. + + It is a superclass for AdmWriter and AdmxWriter. + ''' + + def IsDeprecatedPolicySupported(self, policy): + # Include deprecated policies in the output. + return True + + def IsVersionSupported(self, policy, supported_on): + # Include deprecated policies in the 'DeprecatedPolicies' group, even if + # they aren't supported anymore. + # + # TODO(crbug.com/463990): Eventually exclude some policies, e.g. if they were + # deprecated a long time ago. + if policy.get('deprecated', False): + return True + + return super(GpoEditorWriter, self).IsVersionSupported(policy, supported_on) + + def _FindDeprecatedPolicies(self, policy_list): + deprecated_policies = [] + for policy in policy_list: + if policy['type'] == 'group': + for p in policy['policies']: + if p.get('deprecated', False): + deprecated_policies.append(p) + else: + if policy.get('deprecated', False): + deprecated_policies.append(policy) + return deprecated_policies + + def _RemovePoliciesFromList(self, policy_list, policies_to_remove): + '''Remove policies_to_remove from groups and the top-level list.''' + # We only compare the 'name' property. + policies_to_remove = set([p['name'] for p in policies_to_remove]) + + # Remove from top-level list. + policy_list[:] = [ + p for p in policy_list if p['name'] not in policies_to_remove + ] + + # Remove from groups. + for group in policy_list: + if group['type'] != 'group': + continue + group['policies'] = [ + p for p in group['policies'] if p['name'] not in policies_to_remove + ] + + def PreprocessPolicies(self, policy_list): + '''Put deprecated policies under the 'DeprecatedPolicies' group.''' + deprecated_policies = self._FindDeprecatedPolicies(policy_list) + + self._RemovePoliciesFromList(policy_list, deprecated_policies) + + for p in deprecated_policies: + # TODO(crbug.com/463990): Also include an alternative policy in the + # description, if the policy was replaced by a newer one. + p['desc'] = self.messages['deprecated_policy_desc']['text'] + + deprecated_group = { + 'name': 'DeprecatedPolicies', + 'type': 'group', + 'caption': self.messages['deprecated_policy_group_caption']['text'], + 'desc': self.messages['deprecated_policy_group_desc']['text'], + 'policies': deprecated_policies + } + policy_list.append(deprecated_group) + + return super(GpoEditorWriter, self).SortPoliciesGroupsFirst(policy_list)
diff --git a/components/policy/tools/template_writers/writers/template_writer.py b/components/policy/tools/template_writers/writers/template_writer.py index 6a655f3..3a99248 100755 --- a/components/policy/tools/template_writers/writers/template_writer.py +++ b/components/policy/tools/template_writers/writers/template_writer.py
@@ -69,7 +69,7 @@ return False for supported_on in policy['supported_on']: - if not self._IsVersionSupported(supported_on): + if not self.IsVersionSupported(policy, supported_on): continue if '*' in self.platforms: return True @@ -111,7 +111,7 @@ for supported_on in policy['supported_on']: if (platform in supported_on['platforms'] and (not product or product in supported_on['product']) and - self._IsVersionSupported(supported_on)): + self.IsVersionSupported(policy, supported_on)): return True return False @@ -128,6 +128,18 @@ return management in policy.get('supported_chrome_os_management', ['active_directory', 'google_cloud']) + def IsVersionSupported(self, policy, supported_on): + '''Checks whether the policy is supported on current version''' + major_version = self._GetChromiumMajorVersion() + if not major_version: + return True + + since_version = supported_on.get('since_version', None) + until_version = supported_on.get('until_version', None) + + return ((not since_version or int(since_version) <= major_version) and + (not until_version or int(until_version) >= major_version)) + def _GetChromiumVersionString(self): '''Returns the Chromium version string stored in the environment variable version (if it is set). @@ -142,18 +154,6 @@ ''' return self.config.get('major_version', None) - def _IsVersionSupported(self, supported_on): - '''Checks whether the policy is supoorted on current version''' - major_version = self._GetChromiumMajorVersion() - if not major_version: - return True - - since_version = supported_on.get('since_version', None) - until_version = supported_on.get('until_version', None) - - return ((not since_version or int(since_version) <= major_version) and - (not until_version or int(until_version) >= major_version)) - def _GetPoliciesForWriter(self, group): '''Filters the list of policies in the passed group that are supported by the writer.
diff --git a/components/search_provider_logos/logo_service_impl.cc b/components/search_provider_logos/logo_service_impl.cc index cd61ca1..b4ad40e 100644 --- a/components/search_provider_logos/logo_service_impl.cc +++ b/components/search_provider_logos/logo_service_impl.cc
@@ -199,7 +199,8 @@ private: // identity::IdentityManager::Observer implementation. - void OnAccountsInCookieUpdated(const std::vector<AccountInfo>&) override { + void OnAccountsInCookieUpdated(const identity::AccountsInCookieJarInfo&, + const GoogleServiceAuthError&) override { callback_.Run(); }
diff --git a/components/sessions/core/tab_restore_service_helper.cc b/components/sessions/core/tab_restore_service_helper.cc index 8362fe3..9ae6e54 100644 --- a/components/sessions/core/tab_restore_service_helper.cc +++ b/components/sessions/core/tab_restore_service_helper.cc
@@ -46,11 +46,10 @@ TabRestoreServiceHelper::TabRestoreServiceHelper( TabRestoreService* tab_restore_service, - Observer* observer, TabRestoreServiceClient* client, TabRestoreService::TimeFactory* time_factory) : tab_restore_service_(tab_restore_service), - observer_(observer), + observer_(nullptr), client_(client), restoring_(false), time_factory_(time_factory) { @@ -61,6 +60,10 @@ base::ThreadTaskRunnerHandle::Get()); } +void TabRestoreServiceHelper::SetHelperObserver(Observer* observer) { + observer_ = observer; +} + TabRestoreServiceHelper::~TabRestoreServiceHelper() { for (auto& observer : observer_list_) observer.TabRestoreServiceDestroyed(tab_restore_service_);
diff --git a/components/sessions/core/tab_restore_service_helper.h b/components/sessions/core/tab_restore_service_helper.h index 2667d1f3..464367a 100644 --- a/components/sessions/core/tab_restore_service_helper.h +++ b/components/sessions/core/tab_restore_service_helper.h
@@ -74,12 +74,13 @@ // the current time. The TabRestoreServiceHelper does not take ownership of // |time_factory| and |observer|. Note that |observer| can also be NULL. TabRestoreServiceHelper(TabRestoreService* tab_restore_service, - Observer* observer, TabRestoreServiceClient* client, TimeFactory* time_factory); ~TabRestoreServiceHelper() override; + void SetHelperObserver(Observer* observer); + // Helper methods used to implement TabRestoreService. void AddObserver(TabRestoreServiceObserver* observer); void RemoveObserver(TabRestoreServiceObserver* observer); @@ -182,7 +183,7 @@ TabRestoreService* const tab_restore_service_; - Observer* const observer_; + Observer* observer_; TabRestoreServiceClient* client_;
diff --git a/components/sessions/core/tab_restore_service_impl.cc b/components/sessions/core/tab_restore_service_impl.cc index bc08a06..749eb25 100644 --- a/components/sessions/core/tab_restore_service_impl.cc +++ b/components/sessions/core/tab_restore_service_impl.cc
@@ -13,12 +13,14 @@ #include "base/bind.h" #include "base/compiler_specific.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/stl_util.h" -#include "base/task/cancelable_task_tracker.h" #include "base/time/time.h" +#include "components/history/core/common/pref_names.h" +#include "components/prefs/pref_service.h" #include "components/sessions/core/base_session_service.h" #include "components/sessions/core/base_session_service_commands.h" #include "components/sessions/core/base_session_service_delegate.h" @@ -338,8 +340,9 @@ // TabRestoreServiceImpl::PersistenceDelegate // --------------------------------------- -// This restore service will create and own a BaseSessionService and implement -// the required BaseSessionServiceDelegate. +// This restore service persistence delegate will create and own a +// BaseSessionService and implement the required BaseSessionServiceDelegate to +// handle all the persistence of the tab restore service implementation. class TabRestoreServiceImpl::PersistenceDelegate : public BaseSessionServiceDelegate, public TabRestoreServiceHelper::Observer { @@ -1100,11 +1103,17 @@ TabRestoreServiceImpl::TabRestoreServiceImpl( std::unique_ptr<TabRestoreServiceClient> client, + PrefService* pref_service, TimeFactory* time_factory) - : client_(std::move(client)), - persistence_delegate_(new PersistenceDelegate(client_.get())), - helper_(this, persistence_delegate_.get(), client_.get(), time_factory) { - persistence_delegate_->set_tab_restore_service_helper(&helper_); + : client_(std::move(client)), helper_(this, client_.get(), time_factory) { + if (pref_service) { + pref_change_registrar_.Init(pref_service); + pref_change_registrar_.Add( + prefs::kSavingBrowserHistoryDisabled, + base::BindRepeating(&TabRestoreServiceImpl::UpdatePersistenceDelegate, + base::Unretained(this))); + } + UpdatePersistenceDelegate(); } TabRestoreServiceImpl::~TabRestoreServiceImpl() {} @@ -1162,11 +1171,14 @@ } bool TabRestoreServiceImpl::IsLoaded() const { - return persistence_delegate_->IsLoaded(); + if (persistence_delegate_) + return persistence_delegate_->IsLoaded(); + return true; } void TabRestoreServiceImpl::DeleteLastSession() { - return persistence_delegate_->DeleteLastSession(); + if (persistence_delegate_) + persistence_delegate_->DeleteLastSession(); } bool TabRestoreServiceImpl::IsRestoring() const { @@ -1174,11 +1186,43 @@ } void TabRestoreServiceImpl::Shutdown() { - return persistence_delegate_->Shutdown(); + if (persistence_delegate_) + persistence_delegate_->Shutdown(); } void TabRestoreServiceImpl::LoadTabsFromLastSession() { - persistence_delegate_->LoadTabsFromLastSession(); + if (persistence_delegate_) + persistence_delegate_->LoadTabsFromLastSession(); +} + +void TabRestoreServiceImpl::UpdatePersistenceDelegate() { + // When a persistence delegate has been created, it must be shut down and + // deleted if a pref service is available and saving history is disabled. + if (pref_change_registrar_.prefs() && + pref_change_registrar_.prefs()->GetBoolean( + prefs::kSavingBrowserHistoryDisabled)) { + if (persistence_delegate_) { + helper_.SetHelperObserver(nullptr); + // Make sure we don't leave stale data for the next time the pref is + // changed back to enable. + persistence_delegate_->DeleteLastSession(); + persistence_delegate_->Shutdown(); + persistence_delegate_.reset(nullptr); + } else { + // In case this is the first time Chrome is launched with saving history + // disabled, we must make sure to clear the previously saved session. + PersistenceDelegate persistence_delegate(client_.get()); + persistence_delegate.DeleteLastSession(); + } + } else if (!persistence_delegate_) { + // When saving is NOT disabled (or there is no pref service available), and + // there are no persistence delegate yet, one must be created and + // initialized. + persistence_delegate_ = + std::make_unique<PersistenceDelegate>(client_.get()); + persistence_delegate_->set_tab_restore_service_helper(&helper_); + helper_.SetHelperObserver(persistence_delegate_.get()); + } } TabRestoreService::Entries* TabRestoreServiceImpl::mutable_entries() {
diff --git a/components/sessions/core/tab_restore_service_impl.h b/components/sessions/core/tab_restore_service_impl.h index be4ee6e..dd9445d 100644 --- a/components/sessions/core/tab_restore_service_impl.h +++ b/components/sessions/core/tab_restore_service_impl.h
@@ -10,11 +10,13 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "components/prefs/pref_change_registrar.h" #include "components/sessions/core/sessions_export.h" #include "components/sessions/core/tab_restore_service.h" #include "components/sessions/core/tab_restore_service_client.h" #include "components/sessions/core/tab_restore_service_helper.h" +class PrefService; class TabRestoreServiceImplTest; namespace sessions { @@ -24,6 +26,7 @@ public: // Does not take ownership of |time_factory|. TabRestoreServiceImpl(std::unique_ptr<TabRestoreServiceClient> client, + PrefService* pref_service, TimeFactory* time_factory); ~TabRestoreServiceImpl() override; @@ -54,6 +57,7 @@ friend class ::TabRestoreServiceImplTest; class PersistenceDelegate; + void UpdatePersistenceDelegate(); // Exposed for testing. Entries* mutable_entries(); @@ -62,6 +66,7 @@ std::unique_ptr<TabRestoreServiceClient> client_; std::unique_ptr<PersistenceDelegate> persistence_delegate_; TabRestoreServiceHelper helper_; + PrefChangeRegistrar pref_change_registrar_; DISALLOW_COPY_AND_ASSIGN(TabRestoreServiceImpl); };
diff --git a/components/sync/driver/sync_auth_util.cc b/components/sync/driver/sync_auth_util.cc index d413de3..6e6b6df 100644 --- a/components/sync/driver/sync_auth_util.cc +++ b/components/sync/driver/sync_auth_util.cc
@@ -31,7 +31,7 @@ // Check if there is a content area signed-in account, and we have a refresh // token for it. std::vector<AccountInfo> cookie_accounts = - identity_manager->GetAccountsInCookieJar(); + identity_manager->GetAccountsInCookieJar().accounts; if (!cookie_accounts.empty() && identity_manager->HasAccountWithRefreshToken( cookie_accounts[0].account_id)) {
diff --git a/components/sync/driver/sync_session_durations_metrics_recorder.cc b/components/sync/driver/sync_session_durations_metrics_recorder.cc index e5a7ac8..fec721a 100644 --- a/components/sync/driver/sync_session_durations_metrics_recorder.cc +++ b/components/sync/driver/sync_session_durations_metrics_recorder.cc
@@ -26,15 +26,11 @@ SyncSessionDurationsMetricsRecorder::SyncSessionDurationsMetricsRecorder( SyncService* sync_service, - identity::IdentityManager* identity_manager, - GaiaCookieManagerService* cookie_manager) + identity::IdentityManager* identity_manager) : sync_service_(sync_service), identity_manager_(identity_manager), sync_observer_(this), - identity_manager_observer_(this), - gaia_cookie_observer_(this) { - gaia_cookie_observer_.Add(cookie_manager); - + identity_manager_observer_(this) { // |sync_service| can be null if sync is disabled by a command line flag. if (sync_service_) { sync_observer_.Add(sync_service_); @@ -47,11 +43,11 @@ // Check if we already know the signed in cookies. This will trigger a fetch // if we don't have them yet. - std::vector<gaia::ListedAccount> signed_in; - std::vector<gaia::ListedAccount> signed_out; - if (cookie_manager->ListAccounts(&signed_in, &signed_out)) { - OnGaiaAccountsInCookieUpdated(signed_in, signed_out, - GoogleServiceAuthError()); + identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = + identity_manager_->GetAccountsInCookieJar(); + if (accounts_in_cookie_jar_info.accounts_are_fresh) { + OnAccountsInCookieUpdated(accounts_in_cookie_jar_info, + GoogleServiceAuthError::AuthErrorNone()); } DVLOG(1) << "Ready to track Session.TotalDuration metrics"; @@ -59,8 +55,6 @@ SyncSessionDurationsMetricsRecorder::~SyncSessionDurationsMetricsRecorder() { DCHECK(!total_session_timer_) << "Missing a call to OnSessionEnded()."; - - gaia_cookie_observer_.RemoveAll(); sync_observer_.RemoveAll(); identity_manager_observer_.RemoveAll(); } @@ -93,12 +87,12 @@ sync_account_session_timer_.reset(); } -void SyncSessionDurationsMetricsRecorder::OnGaiaAccountsInCookieUpdated( - const std::vector<gaia::ListedAccount>& accounts, - const std::vector<gaia::ListedAccount>& signed_out_accounts, +void SyncSessionDurationsMetricsRecorder::OnAccountsInCookieUpdated( + const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, const GoogleServiceAuthError& error) { - DVLOG(1) << "Cookie state change. in: " << accounts.size() - << " out: " << signed_out_accounts.size() + DVLOG(1) << "Cookie state change. accounts: " + << accounts_in_cookie_jar_info.accounts.size() + << " fresh: " << accounts_in_cookie_jar_info.accounts_are_fresh << " err: " << error.ToString(); if (error.state() != GoogleServiceAuthError::NONE) { @@ -108,7 +102,8 @@ return; } - if (accounts.empty()) { + DCHECK(accounts_in_cookie_jar_info.accounts_are_fresh); + if (accounts_in_cookie_jar_info.accounts.empty()) { // No signed in account. if (signin_status_ == FeatureState::ON && signin_session_timer_) { LogSigninDuration(signin_session_timer_->Elapsed());
diff --git a/components/sync/driver/sync_session_durations_metrics_recorder.h b/components/sync/driver/sync_session_durations_metrics_recorder.h index 642131a8..457bc02 100644 --- a/components/sync/driver/sync_session_durations_metrics_recorder.h +++ b/components/sync/driver/sync_session_durations_metrics_recorder.h
@@ -28,20 +28,13 @@ // Callers must ensure that the parameters outlive this object. SyncSessionDurationsMetricsRecorder( SyncService* sync_service, - identity::IdentityManager* identity_manager, - GaiaCookieManagerService* cookie_manager); + identity::IdentityManager* identity_manager); ~SyncSessionDurationsMetricsRecorder() override; // Informs this service that a session started at |session_start| time. void OnSessionStarted(base::TimeTicks session_start); void OnSessionEnded(base::TimeDelta session_length); - // GaiaCookieManagerService::Observer: - void OnGaiaAccountsInCookieUpdated( - const std::vector<gaia::ListedAccount>& accounts, - const std::vector<gaia::ListedAccount>& signed_out_accounts, - const GoogleServiceAuthError& error) override; - // syncer::SyncServiceObserver: void OnStateChanged(syncer::SyncService* sync) override; @@ -50,6 +43,9 @@ const AccountInfo& account_info) override; void OnRefreshTokenRemovedForAccount(const std::string& account_id) override; void OnRefreshTokensLoaded() override; + void OnAccountsInCookieUpdated( + const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) override; private: // The state the feature is in. The state starts as UNKNOWN. After it moves @@ -75,8 +71,6 @@ sync_observer_; ScopedObserver<identity::IdentityManager, identity::IdentityManager::Observer> identity_manager_observer_; - ScopedObserver<GaiaCookieManagerService, GaiaCookieManagerService::Observer> - gaia_cookie_observer_; // Tracks the elapsed active session time while the browser is open. The timer // is absent if there's no active session.
diff --git a/components/sync/engine_impl/get_updates_processor.cc b/components/sync/engine_impl/get_updates_processor.cc index 010829ed..df71de3 100644 --- a/components/sync/engine_impl/get_updates_processor.cc +++ b/components/sync/engine_impl/get_updates_processor.cc
@@ -136,7 +136,6 @@ // other of the message-building functions to make the rest of the code easier // to test. void InitDownloadUpdatesContext(SyncCycle* cycle, - bool create_mobile_bookmarks_folder, sync_pb::ClientToServerMessage* message) { message->set_share(cycle->context()->account_name()); message->set_message_contents(sync_pb::ClientToServerMessage::GET_UPDATES); @@ -148,8 +147,10 @@ // (e.g. Bookmark URLs but not their containing folders). get_updates->set_fetch_folders(true); - get_updates->set_create_mobile_bookmarks_folder( - create_mobile_bookmarks_folder); + // This is a deprecated field that should be cleaned up after server's + // behavior is updated. + get_updates->set_create_mobile_bookmarks_folder(true); + bool need_encryption_key = ShouldRequestEncryptionKey(cycle->context()); get_updates->set_need_encryption_key(need_encryption_key); @@ -165,14 +166,12 @@ GetUpdatesProcessor::~GetUpdatesProcessor() {} -SyncerError GetUpdatesProcessor::DownloadUpdates( - ModelTypeSet* request_types, - SyncCycle* cycle, - bool create_mobile_bookmarks_folder) { +SyncerError GetUpdatesProcessor::DownloadUpdates(ModelTypeSet* request_types, + SyncCycle* cycle) { TRACE_EVENT0("sync", "DownloadUpdates"); sync_pb::ClientToServerMessage message; - InitDownloadUpdatesContext(cycle, create_mobile_bookmarks_folder, &message); + InitDownloadUpdatesContext(cycle, &message); PrepareGetUpdates(*request_types, &message); SyncerError result = ExecuteDownloadUpdates(request_types, cycle, &message);
diff --git a/components/sync/engine_impl/get_updates_processor.h b/components/sync/engine_impl/get_updates_processor.h index 01fc2a0..c5560ec 100644 --- a/components/sync/engine_impl/get_updates_processor.h +++ b/components/sync/engine_impl/get_updates_processor.h
@@ -43,9 +43,7 @@ // Returns SYNCER_OK if the download succeeds, SERVER_MORE_TO_DOWNLOAD if the // download succeeded but there are still some updates left to fetch on the // server, or an appropriate error value in case of failure. - SyncerError DownloadUpdates(ModelTypeSet* request_types, - SyncCycle* cycle, - bool create_mobile_bookmarks_folder); + SyncerError DownloadUpdates(ModelTypeSet* request_types, SyncCycle* cycle); // Applies any downloaded and processed updates. void ApplyUpdates(const ModelTypeSet& gu_types,
diff --git a/components/sync/engine_impl/loopback_server/loopback_server.cc b/components/sync/engine_impl/loopback_server/loopback_server.cc index b0227b8d..a6edb23c 100644 --- a/components/sync/engine_impl/loopback_server/loopback_server.cc +++ b/components/sync/engine_impl/loopback_server/loopback_server.cc
@@ -204,11 +204,19 @@ if (model_type == syncer::BOOKMARKS) { if (!CreatePermanentBookmarkFolder(kBookmarkBarFolderServerTag, - kBookmarkBarFolderName)) + kBookmarkBarFolderName)) { return false; + } if (!CreatePermanentBookmarkFolder(kOtherBookmarksFolderServerTag, - kOtherBookmarksFolderName)) + kOtherBookmarksFolderName)) { return false; + } + // This folder is called "Synced Bookmarks" by sync and is renamed + // "Mobile Bookmarks" by the mobile client UIs. + if (!CreatePermanentBookmarkFolder(kSyncedBookmarksFolderServerTag, + kSyncedBookmarksFolderName)) { + return false; + } } } @@ -297,14 +305,6 @@ auto sieve = std::make_unique<UpdateSieve>(get_updates); - // This folder is called "Synced Bookmarks" by sync and is renamed - // "Mobile Bookmarks" by the mobile client UIs. - if (get_updates.create_mobile_bookmarks_folder() && - !CreatePermanentBookmarkFolder(kSyncedBookmarksFolderServerTag, - kSyncedBookmarksFolderName)) { - return false; - } - std::vector<const LoopbackServerEntity*> wanted_entities; for (const auto& id_and_entity : entities_) { if (sieve->ClientWantsItem(*id_and_entity.second)) {
diff --git a/components/sync/engine_impl/loopback_server/loopback_server_unittest.cc b/components/sync/engine_impl/loopback_server/loopback_server_unittest.cc index e6e03598..ca31b1d1 100644 --- a/components/sync/engine_impl/loopback_server/loopback_server_unittest.cc +++ b/components/sync/engine_impl/loopback_server/loopback_server_unittest.cc
@@ -155,8 +155,8 @@ TEST_F(LoopbackServerTest, GetUpdateCommand) { ClientToServerResponse response = GetUpdatesForType(EntitySpecifics::kBookmarkFieldNumber); - // Expect to see the three top-level folders in this update already. - EXPECT_EQ(3, response.get_updates().entries_size()); + // Expect to see the four top-level folders in this update already. + EXPECT_EQ(4, response.get_updates().entries_size()); } TEST_F(LoopbackServerTest, GetUpdateCommandShouldFilterByDataType) { @@ -241,8 +241,8 @@ &response)); EXPECT_EQ(SyncEnums::SUCCESS, response.error_code()); ASSERT_TRUE(response.has_get_updates()); - // Expect to see the three top-level folders and the newly added bookmark! - EXPECT_EQ(4, response.get_updates().entries_size()); + // Expect to see the four top-level folders and the newly added bookmark! + EXPECT_EQ(5, response.get_updates().entries_size()); EXPECT_EQ(1U, ResponseToMap(response).count(id)); } @@ -256,8 +256,8 @@ ClientToServerResponse response = GetUpdatesForType(EntitySpecifics::kBookmarkFieldNumber); ASSERT_TRUE(response.has_get_updates()); - // Expect to see no fifth bookmark! - EXPECT_EQ(4, response.get_updates().entries_size()); + // Expect to see no sixth bookmark! + EXPECT_EQ(5, response.get_updates().entries_size()); EXPECT_EQ(kUrl2, ResponseToMap(response)[id].specifics().bookmark().url()); }
diff --git a/components/sync/engine_impl/syncer.cc b/components/sync/engine_impl/syncer.cc index 768b2a8..d4d745f 100644 --- a/components/sync/engine_impl/syncer.cc +++ b/components/sync/engine_impl/syncer.cc
@@ -9,7 +9,6 @@ #include "base/auto_reset.h" #include "base/logging.h" #include "base/trace_event/trace_event.h" -#include "build/build_config.h" #include "components/sync/base/cancelation_signal.h" #include "components/sync/engine_impl/apply_control_data_updates.h" #include "components/sync/engine_impl/clear_server_data.h" @@ -26,13 +25,6 @@ namespace { -// TODO(akalin): We may want to propagate this switch up eventually. -#if defined(OS_ANDROID) || defined(OS_IOS) -static const bool kCreateMobileBookmarksFolder = true; -#else -static const bool kCreateMobileBookmarksFolder = false; -#endif - void HandleCycleBegin(SyncCycle* cycle) { cycle->mutable_status_controller()->UpdateStartTime(); cycle->SendEventNotification(SyncCycleEvent::SYNC_CYCLE_BEGIN); @@ -58,8 +50,7 @@ cycle->context()->ShouldFetchUpdatesBeforeCommit()) { VLOG(1) << "Downloading types " << ModelTypeSetToString(request_types); if (!DownloadAndApplyUpdates(&request_types, cycle, - NormalGetUpdatesDelegate(*nudge_tracker), - kCreateMobileBookmarksFolder)) { + NormalGetUpdatesDelegate(*nudge_tracker))) { return HandleCycleEnd(cycle, nudge_tracker->GetOrigin()); } } @@ -89,8 +80,7 @@ VLOG(1) << "Configuring types " << ModelTypeSetToString(still_enabled_types); HandleCycleBegin(cycle); DownloadAndApplyUpdates(&still_enabled_types, cycle, - ConfigureGetUpdatesDelegate(origin), - kCreateMobileBookmarksFolder); + ConfigureGetUpdatesDelegate(origin)); return HandleCycleEnd(cycle, origin); } @@ -98,8 +88,7 @@ base::AutoReset<bool> is_syncing(&is_syncing_, true); VLOG(1) << "Polling types " << ModelTypeSetToString(request_types); HandleCycleBegin(cycle); - DownloadAndApplyUpdates(&request_types, cycle, PollGetUpdatesDelegate(), - kCreateMobileBookmarksFolder); + DownloadAndApplyUpdates(&request_types, cycle, PollGetUpdatesDelegate()); return HandleCycleEnd(cycle, sync_pb::SyncEnums::PERIODIC); } @@ -111,8 +100,7 @@ bool Syncer::DownloadAndApplyUpdates(ModelTypeSet* request_types, SyncCycle* cycle, - const GetUpdatesDelegate& delegate, - bool create_mobile_bookmarks_folder) { + const GetUpdatesDelegate& delegate) { // CommitOnlyTypes() should not be included in the GetUpdates, but should be // included in the Commit. We are given a set of types for our SyncShare, // and we must do this filtering. Note that |request_types| is also an out @@ -125,8 +113,8 @@ cycle->context()->model_type_registry()->update_handler_map(), delegate); SyncerError download_result; do { - download_result = get_updates_processor.DownloadUpdates( - &download_types, cycle, create_mobile_bookmarks_folder); + download_result = + get_updates_processor.DownloadUpdates(&download_types, cycle); } while (download_result.value() == SyncerError::SERVER_MORE_TO_DOWNLOAD); // It is our responsibility to propagate the removal of types that occurred in
diff --git a/components/sync/engine_impl/syncer.h b/components/sync/engine_impl/syncer.h index 2aac6af..fd1203f8 100644 --- a/components/sync/engine_impl/syncer.h +++ b/components/sync/engine_impl/syncer.h
@@ -77,8 +77,7 @@ private: bool DownloadAndApplyUpdates(ModelTypeSet* request_types, SyncCycle* cycle, - const GetUpdatesDelegate& delegate, - bool create_mobile_bookmarks_folder); + const GetUpdatesDelegate& delegate); // This function will commit batches of unsynced items to the server until the // number of unsynced and ready to commit items reaches zero or an error is
diff --git a/components/sync/protocol/sync.proto b/components/sync/protocol/sync.proto index c4af311c..cd268a5 100644 --- a/components/sync/protocol/sync.proto +++ b/components/sync/protocol/sync.proto
@@ -669,8 +669,9 @@ optional bool need_encryption_key = 8 [default = false]; // Whether to create the mobile bookmarks folder if it's not - // already created. Should be set to true only by mobile clients. - optional bool create_mobile_bookmarks_folder = 1000 [default = false]; + // already created. Set to true by all modern clients. + optional bool create_mobile_bookmarks_folder = 1000 + [default = false, deprecated = true]; // This value is an updated version of the GetUpdatesCallerInfo's // GetUpdatesSource. It describes the reason for the GetUpdate request.
diff --git a/components/sync_sessions/favicon_cache.cc b/components/sync_sessions/favicon_cache.cc index 9a75025a..53014c5f 100644 --- a/components/sync_sessions/favicon_cache.cc +++ b/components/sync_sessions/favicon_cache.cc
@@ -248,10 +248,9 @@ syncer::SyncMergeResult merge_result(type); merge_result.set_num_items_before_association(synced_favicons_.size()); std::set<GURL> unsynced_favicon_urls; - for (FaviconMap::const_iterator iter = synced_favicons_.begin(); - iter != synced_favicons_.end(); ++iter) { - if (FaviconInfoHasValidTypeData(*(iter->second), type)) - unsynced_favicon_urls.insert(iter->first); + for (const auto& url_icon_pair : synced_favicons_) { + if (FaviconInfoHasValidTypeData(*url_icon_pair.second, type)) + unsynced_favicon_urls.insert(url_icon_pair.first); } syncer::SyncChangeList local_changes; @@ -406,10 +405,9 @@ if (page_task_map_.find(page_url) != page_task_map_.end()) return; - PageFaviconMap::const_iterator url_iter = page_favicon_map_.find(page_url); + auto url_iter = page_favicon_map_.find(page_url); if (url_iter != page_favicon_map_.end()) { - FaviconMap::const_iterator icon_iter = - synced_favicons_.find(url_iter->second); + auto icon_iter = synced_favicons_.find(url_iter->second); // TODO(zea): consider what to do when only a subset of supported // resolutions are available. if (icon_iter != synced_favicons_.end() && @@ -536,8 +534,8 @@ } bool FaviconCache::FaviconRecencyFunctor::operator()( - const linked_ptr<SyncedFaviconInfo>& lhs, - const linked_ptr<SyncedFaviconInfo>& rhs) const { + const SyncedFaviconInfo* lhs, + const SyncedFaviconInfo* rhs) const { // TODO(zea): incorporate bookmarked status here once we care about it. if (lhs->last_visit_time < rhs->last_visit_time) return true; @@ -622,7 +620,7 @@ return; } - FaviconMap::const_iterator iter = synced_favicons_.find(icon_url); + auto iter = synced_favicons_.find(icon_url); DCHECK(iter != synced_favicons_.end()); const SyncedFaviconInfo* favicon_info = iter->second.get(); @@ -675,32 +673,32 @@ // TODO(zea): implement in-memory eviction. DVLOG(1) << "Adding favicon info for " << icon_url.spec(); - SyncedFaviconInfo* favicon_info = new SyncedFaviconInfo(icon_url); - synced_favicons_[icon_url] = make_linked_ptr(favicon_info); - recent_favicons_.insert(synced_favicons_[icon_url]); + auto favicon_info = std::make_unique<SyncedFaviconInfo>(icon_url); + SyncedFaviconInfo* favicon_info_ptr = favicon_info.get(); + synced_favicons_[icon_url] = std::move(favicon_info); + recent_favicons_.insert(favicon_info_ptr); DCHECK_EQ(recent_favicons_.size(), synced_favicons_.size()); - return favicon_info; + return favicon_info_ptr; } void FaviconCache::UpdateFaviconVisitTime(const GURL& icon_url, base::Time time) { DCHECK_EQ(recent_favicons_.size(), synced_favicons_.size()); - FaviconMap::const_iterator iter = synced_favicons_.find(icon_url); + auto iter = synced_favicons_.find(icon_url); DCHECK(iter != synced_favicons_.end()); if (iter->second->last_visit_time >= time) return; // Erase, update the time, then re-insert to maintain ordering. - recent_favicons_.erase(iter->second); + recent_favicons_.erase(iter->second.get()); DVLOG(1) << "Updating " << icon_url.spec() << " visit time to " << syncer::GetTimeDebugString(time); iter->second->last_visit_time = time; - recent_favicons_.insert(iter->second); + recent_favicons_.insert(iter->second.get()); if (VLOG_IS_ON(2)) { - for (auto iter = recent_favicons_.begin(); iter != recent_favicons_.end(); - ++iter) { - DVLOG(2) << "Favicon " << iter->get()->favicon_url.spec() << ": " - << syncer::GetTimeDebugString(iter->get()->last_visit_time); + for (const auto* icon : recent_favicons_) { + DVLOG(2) << "Favicon " << icon->favicon_url.spec() << ": " + << syncer::GetTimeDebugString(icon->last_visit_time); } } DCHECK_EQ(recent_favicons_.size(), synced_favicons_.size()); @@ -717,7 +715,7 @@ // already in recency order, so just start from the beginning. // TODO(zea): to reduce thrashing, consider removing more than the minimum. while (recent_favicons_.size() > max_sync_favicon_limit_) { - linked_ptr<SyncedFaviconInfo> candidate = *recent_favicons_.begin(); + SyncedFaviconInfo* candidate = *recent_favicons_.begin(); DVLOG(1) << "Expiring favicon " << candidate->favicon_url.spec(); DeleteSyncedFavicon(synced_favicons_.find(candidate->favicon_url), image_changes, @@ -740,7 +738,7 @@ DCHECK(type == syncer::FAVICON_IMAGES || type == syncer::FAVICON_TRACKING); sync_pb::EntitySpecifics new_specifics; GURL favicon_url = GetFaviconURLFromSpecifics(sync_favicon.GetSpecifics()); - FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url); + auto iter = synced_favicons_.find(favicon_url); DCHECK(iter != synced_favicons_.end()); SyncedFaviconInfo* favicon_info = iter->second.get(); if (type == syncer::FAVICON_IMAGES) { @@ -910,7 +908,7 @@ FaviconMap::iterator favicon_iter, syncer::SyncChangeList* image_changes, syncer::SyncChangeList* tracking_changes) { - linked_ptr<SyncedFaviconInfo> favicon_info = favicon_iter->second; + SyncedFaviconInfo* favicon_info = favicon_iter->second.get(); if (FaviconInfoHasImages(*(favicon_iter->second))) { DVLOG(1) << "Deleting image for " << favicon_iter->second.get()->favicon_url; @@ -937,10 +935,9 @@ void FaviconCache::DropSyncedFavicon(FaviconMap::iterator favicon_iter) { DVLOG(1) << "Dropping favicon " << favicon_iter->second.get()->favicon_url; const GURL& url = favicon_iter->first; - recent_favicons_.erase(favicon_iter->second); - base::EraseIf(page_favicon_map_, [url](const PageFaviconMap::value_type& kv) { - return kv.second == url; - }); + recent_favicons_.erase(favicon_iter->second.get()); + base::EraseIf(page_favicon_map_, + [url](const auto& kv) { return kv.second == url; }); synced_favicons_.erase(favicon_iter); } @@ -976,10 +973,10 @@ DCHECK_EQ(type, syncer::FAVICON_TRACKING); DVLOG(1) << "Dropping favicon tracking " << favicon_iter->second.get()->favicon_url; - recent_favicons_.erase(favicon_iter->second); + recent_favicons_.erase(favicon_iter->second.get()); favicon_iter->second->last_visit_time = base::Time(); favicon_iter->second->is_bookmarked = false; - recent_favicons_.insert(favicon_iter->second); + recent_favicons_.insert(favicon_iter->second.get()); DCHECK(!FaviconInfoHasTracking(*favicon_iter->second)); } }
diff --git a/components/sync_sessions/favicon_cache.h b/components/sync_sessions/favicon_cache.h index 378b15d5..292636a 100644 --- a/components/sync_sessions/favicon_cache.h +++ b/components/sync_sessions/favicon_cache.h
@@ -17,7 +17,6 @@ #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/ref_counted_memory.h" #include "base/memory/weak_ptr.h" @@ -118,19 +117,14 @@ // Functor for ordering SyncedFaviconInfo objects by recency; struct FaviconRecencyFunctor { - bool operator()(const linked_ptr<SyncedFaviconInfo>& lhs, - const linked_ptr<SyncedFaviconInfo>& rhs) const; + bool operator()(const SyncedFaviconInfo* lhs, + const SyncedFaviconInfo* rhs) const; }; // Map of favicon url to favicon image. - using FaviconMap = std::map<GURL, linked_ptr<SyncedFaviconInfo>>; - using RecencySet = - std::set<linked_ptr<SyncedFaviconInfo>, FaviconRecencyFunctor>; - // Map of page url to task id (for favicon loading). - using PageTaskMap = std::map<GURL, base::CancelableTaskTracker::TaskId>; - // Map of page url to favicon url. - using PageFaviconMap = std::map<GURL, GURL>; + using FaviconMap = std::map<GURL, std::unique_ptr<SyncedFaviconInfo>>; + using RecencySet = std::set<SyncedFaviconInfo*, FaviconRecencyFunctor>; // Callback method to store a tab's favicon into its sync node once it becomes // available. Does nothing if no favicon data was available. @@ -153,8 +147,8 @@ // |synced_favicons_| and |recent_favicons_| and returns it. SyncedFaviconInfo* GetFaviconInfo(const GURL& icon_url); - // Updates the last visit time for the favicon at |icon_url| to |time| (and - // correspondly updates position in |recent_favicons_|. + // Updates the last visit time for the favicon at |icon_url| to |time| and + // correspondingly updates position in |recent_favicons_|. void UpdateFaviconVisitTime(const GURL& icon_url, base::Time time); // Expiration method. Looks through |recent_favicons_| to find any favicons @@ -205,21 +199,21 @@ favicon::FaviconService* favicon_service_; - // Trask tracker for loading favicons. + // Task tracker for loading favicons. base::CancelableTaskTracker cancelable_task_tracker_; - // Our actual cached favicon data. + // Our actual cached favicon data. Owns the favicons. FaviconMap synced_favicons_; // An LRU ordering of the favicons comprising |synced_favicons_| (oldest to // newest). RecencySet recent_favicons_; - // Our set of pending favicon loads, indexed by page url. - PageTaskMap page_task_map_; + // Pending favicon loads, map of page url to task id. + std::map<GURL, base::CancelableTaskTracker::TaskId> page_task_map_; - // Map of page and associated favicon urls. - PageFaviconMap page_favicon_map_; + // Map of page url to favicon url. + std::map<GURL, GURL> page_favicon_map_; // TODO(zea): consider creating a favicon handler here for fetching unsynced // favicons from the web.
diff --git a/components/viz/service/display/display_resource_provider.cc b/components/viz/service/display/display_resource_provider.cc index ae907da..29b7c1e3 100644 --- a/components/viz/service/display/display_resource_provider.cc +++ b/components/viz/service/display/display_resource_provider.cc
@@ -520,17 +520,14 @@ // TODO(penghuang): support software resource. DCHECK(resource->is_gpu_resource_type()); - metadata.mailbox = resource->transferable.mailbox_holder.mailbox; - metadata.backend_format = GrBackendFormat::MakeGL( - TextureStorageFormat(resource->transferable.format), - resource->transferable.mailbox_holder.texture_target); + metadata.mailbox_holder = resource->transferable.mailbox_holder; metadata.size = resource->transferable.size; metadata.mip_mapped = GrMipMapped::kNo; metadata.origin = kTopLeft_GrSurfaceOrigin; metadata.resource_format = resource->transferable.format; metadata.alpha_type = kPremul_SkAlphaType; metadata.color_space = nullptr; - metadata.sync_token = resource->sync_token(); + metadata.mailbox_holder.sync_token = resource->sync_token(); resource->locked_for_external_use = true; return metadata;
diff --git a/components/viz/service/display/display_resource_provider_unittest.cc b/components/viz/service/display/display_resource_provider_unittest.cc index 27133f3..65a47721 100644 --- a/components/viz/service/display/display_resource_provider_unittest.cc +++ b/components/viz/service/display/display_resource_provider_unittest.cc
@@ -482,8 +482,8 @@ resource_provider_.get()); ResourceMetadata metadata = lock_set.LockResource(parent_id); - ASSERT_EQ(metadata.mailbox, mailbox); - ASSERT_TRUE(metadata.sync_token.HasData()); + ASSERT_EQ(metadata.mailbox_holder.mailbox, mailbox); + ASSERT_TRUE(metadata.mailbox_holder.sync_token.HasData()); resource_provider_->DeclareUsedResourcesFromChild(child_id, ResourceIdSet()); // The resource should not be returned due to the external use lock.
diff --git a/components/viz/service/display/resource_metadata.h b/components/viz/service/display/resource_metadata.h index 691c039..864dd38 100644 --- a/components/viz/service/display/resource_metadata.h +++ b/components/viz/service/display/resource_metadata.h
@@ -7,10 +7,10 @@ #include "components/viz/common/resources/resource_format.h" #include "components/viz/service/viz_service_export.h" -#include "gpu/command_buffer/common/mailbox.h" +#include "gpu/command_buffer/common/mailbox_holder.h" #include "gpu/command_buffer/common/sync_token.h" #include "third_party/skia/include/core/SkColorSpace.h" -#include "third_party/skia/include/gpu/GrBackendSurface.h" +#include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/gpu/GrTypes.h" #include "ui/gfx/geometry/size.h" @@ -24,15 +24,8 @@ ~ResourceMetadata(); ResourceMetadata& operator=(ResourceMetadata&& other); - // A mailbox for the resource texture. - gpu::Mailbox mailbox; - - // The backend format for the resource texture. It includes sized texture - // format and texture target. Sometimes backend_format differs from - // driver_backend_format when we emulate support (e.g. BGRA8 actually - // implemented as RGBA8). - GrBackendFormat backend_format; - GrBackendFormat driver_backend_format; + // A mailbox holder for the resource texture. + gpu::MailboxHolder mailbox_holder; // The resource size. gfx::Size size; @@ -51,9 +44,6 @@ // The color space for the resource texture. It could be null. sk_sp<SkColorSpace> color_space; - - // The sync token for the resource texture. - gpu::SyncToken sync_token; }; } // namespace viz
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 7f8fefb..74968d60 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -110,7 +110,7 @@ if (!image) { auto metadata = skia_renderer->lock_set_for_external_use_.LockResource(resource_id); - DCHECK(!metadata.mailbox.IsZero()); + DCHECK(!metadata.mailbox_holder.mailbox.IsZero()); image = skia_renderer->skia_output_surface_->MakePromiseSkImage( std::move(metadata)); LOG_IF(ERROR, !image) << "Failed to create the promise sk image.";
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 1cc4967f..2bf4861 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -151,46 +151,47 @@ // The ownership of the contexts will be passed into // makeYUVAPromisTexture(). The HelperType::Done will always be called. It // will delete contexts. - const auto process_planar = [&](size_t i, auto format) { + const auto process_planar = [&](size_t i, ResourceFormat resource_format, + GLenum gl_format) { auto& metadata = metadatas[i]; - metadata.driver_backend_format = GrBackendFormat::MakeGL( - format, *metadata.backend_format.getGLTarget()); - formats[i] = metadata.driver_backend_format; + metadata.resource_format = resource_format; + formats[i] = GrBackendFormat::MakeGL( + gl_format, metadata.mailbox_holder.texture_target); yuva_sizes[i].set(metadata.size.width(), metadata.size.height()); contexts[i] = new PlaneHelper(impl->impl_on_gpu_->weak_ptr(), std::move(metadata)); }; if (is_i420) { - process_planar(0, GL_R8); + process_planar(0, RED_8, GL_R8); indices[SkYUVAIndex::kY_Index].fIndex = 0; indices[SkYUVAIndex::kY_Index].fChannel = SkColorChannel::kR; - process_planar(1, GL_R8); + process_planar(1, RED_8, GL_R8); indices[SkYUVAIndex::kU_Index].fIndex = 1; indices[SkYUVAIndex::kU_Index].fChannel = SkColorChannel::kR; - process_planar(2, GL_R8); + process_planar(2, RED_8, GL_R8); indices[SkYUVAIndex::kV_Index].fIndex = 2; indices[SkYUVAIndex::kV_Index].fChannel = SkColorChannel::kR; if (has_alpha) { - process_planar(3, GL_R8); + process_planar(3, RED_8, GL_R8); indices[SkYUVAIndex::kA_Index].fIndex = 3; indices[SkYUVAIndex::kA_Index].fChannel = SkColorChannel::kR; } } else { - process_planar(0, GL_R8); + process_planar(0, RED_8, GL_R8); indices[SkYUVAIndex::kY_Index].fIndex = 0; indices[SkYUVAIndex::kY_Index].fChannel = SkColorChannel::kR; - process_planar(1, GL_RG8); + process_planar(1, RG_88, GL_RG8); indices[SkYUVAIndex::kU_Index].fIndex = 1; indices[SkYUVAIndex::kU_Index].fChannel = SkColorChannel::kR; indices[SkYUVAIndex::kV_Index].fIndex = 1; indices[SkYUVAIndex::kV_Index].fChannel = SkColorChannel::kG; if (has_alpha) { - process_planar(2, GL_R8); + process_planar(2, RED_8, GL_R8); indices[SkYUVAIndex::kA_Index].fIndex = 2; indices[SkYUVAIndex::kA_Index].fChannel = SkColorChannel::kR; } @@ -396,29 +397,30 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(recorder_); + GrBackendFormat backend_format; if (!gpu_service_->is_using_vulkan()) { // Convert internal format from GLES2 to platform GL. const auto* version_info = impl_on_gpu_->gl_version_info(); - metadata.driver_backend_format = GrBackendFormat::MakeGL( + backend_format = GrBackendFormat::MakeGL( gl::GetInternalFormat(version_info, - *metadata.backend_format.getGLFormat()), - *metadata.backend_format.getGLTarget()); + TextureStorageFormat(metadata.resource_format)), + metadata.mailbox_holder.texture_target); } else { #if BUILDFLAG(ENABLE_VULKAN) - metadata.driver_backend_format = + backend_format = GrBackendFormat::MakeVk(ToVkFormat(metadata.resource_format)); #else NOTREACHED(); #endif } - DCHECK(!metadata.mailbox.IsZero()); - resource_sync_tokens_.push_back(metadata.sync_token); + DCHECK(!metadata.mailbox_holder.mailbox.IsZero()); + resource_sync_tokens_.push_back(metadata.mailbox_holder.sync_token); SkColorType sk_color_type = ResourceFormatToClosestSkColorType( /*gpu_compositing=*/true, metadata.resource_format); return PromiseTextureHelper<ResourceMetadata>::MakePromiseSkImage( - this, &recorder_.value(), metadata.driver_backend_format, metadata.size, + this, &recorder_.value(), backend_format, metadata.size, metadata.mip_mapped, metadata.origin, sk_color_type, metadata.alpha_type, metadata.color_space, std::move(metadata)); }
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 45723ca..f57a540 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -400,9 +400,11 @@ GrBackendTexture* backend_texture) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!*shared_image_out); - if (shared_image_representation_factory_->IsSharedImage(metadata.mailbox)) { + if (shared_image_representation_factory_->IsSharedImage( + metadata.mailbox_holder.mailbox)) { std::unique_ptr<gpu::SharedImageRepresentationSkia> shared_image = - shared_image_representation_factory_->ProduceSkia(metadata.mailbox); + shared_image_representation_factory_->ProduceSkia( + metadata.mailbox_holder.mailbox); DCHECK(shared_image); if (!shared_image->BeginReadAccess(backend_texture)) { DLOG(ERROR) @@ -421,17 +423,16 @@ } auto* mailbox_manager = gpu_service_->mailbox_manager(); - auto* texture_base = mailbox_manager->ConsumeTexture(metadata.mailbox); + auto* texture_base = + mailbox_manager->ConsumeTexture(metadata.mailbox_holder.mailbox); if (!texture_base) { DLOG(ERROR) << "Failed to fulfill the promise texture."; return; } BindOrCopyTextureIfNecessary(texture_base); - gpu::GetGrBackendTexture(texture_base->target(), metadata.size, - *metadata.backend_format.getGLFormat(), - *metadata.driver_backend_format.getGLFormat(), - texture_base->service_id(), metadata.resource_format, - backend_texture); + gpu::GetGrBackendTexture(gl_version_info_, texture_base->target(), + metadata.size, texture_base->service_id(), + metadata.resource_format, backend_texture); } void SkiaOutputSurfaceImplOnGpu::FulfillPromiseTexture(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index a969923..538e91b 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1719,6 +1719,8 @@ "speech/tts_mac.mm", "speech/tts_platform_impl.cc", "speech/tts_platform_impl.h", + "speech/tts_utterance_impl.cc", + "speech/tts_utterance_impl.h", "speech/tts_win.cc", "ssl/ssl_client_auth_handler.cc", "ssl/ssl_client_auth_handler.h",
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc index 6e1aad6..5ac3c10 100644 --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -13,8 +13,8 @@ #include "base/files/scoped_temp_dir.h" #include "base/guid.h" #include "base/logging.h" -#include "base/macros.h" #include "base/sequenced_task_runner.h" +#include "base/stl_util.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" @@ -592,7 +592,7 @@ IndexedDBKeyRange(keys[1], keys[3], false, true), IndexedDBKeyRange(keys[0], keys[3], true, true)}; - for (size_t i = 0; i < arraysize(ranges); ++i) { + for (size_t i = 0; i < base::size(ranges); ++i) { const int64_t database_id = 1; const int64_t object_store_id = i + 1; const IndexedDBKeyRange& range = ranges[i]; @@ -711,7 +711,7 @@ IndexedDBKeyRange(keys[2], keys[1], false, false), IndexedDBKeyRange(keys[2], keys[1], true, true)}; - for (size_t i = 0; i < arraysize(ranges); ++i) { + for (size_t i = 0; i < base::size(ranges); ++i) { const int64_t database_id = 1; const int64_t object_store_id = i + 1; const IndexedDBKeyRange& range = ranges[i];
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc b/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc index d77d6d18..859411e 100644 --- a/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc +++ b/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
@@ -11,7 +11,7 @@ #include <utility> #include <vector> -#include "base/macros.h" +#include "base/stl_util.h" #include "base/strings/string16.h" #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" @@ -629,7 +629,7 @@ 0 // Type is null }; encoded_paths.push_back( - std::string(expected, expected + arraysize(expected))); + std::string(expected, expected + base::size(expected))); } { @@ -639,7 +639,7 @@ 0 // Length is 0 }; encoded_paths.push_back( - std::string(expected, expected + arraysize(expected))); + std::string(expected, expected + base::size(expected))); } { @@ -649,7 +649,7 @@ 3, 0, 'f', 0, 'o', 0, 'o' // String length 3, UTF-16BE }; encoded_paths.push_back( - std::string(expected, expected + arraysize(expected))); + std::string(expected, expected + base::size(expected))); } { @@ -660,7 +660,7 @@ 'r' // String length 7, UTF-16BE }; encoded_paths.push_back( - std::string(expected, expected + arraysize(expected))); + std::string(expected, expected + base::size(expected))); } { @@ -678,7 +678,7 @@ 'r' // Member 3 (String length 7) }; encoded_paths.push_back( - std::string(expected, expected + arraysize(expected))); + std::string(expected, expected + base::size(expected))); } ASSERT_EQ(key_paths.size(), encoded_paths.size()); @@ -776,12 +776,12 @@ { key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo"))); char expected[] = {0, 'f', 0, 'o', 0, 'o'}; - encoded_paths.push_back(std::string(expected, arraysize(expected))); + encoded_paths.push_back(std::string(expected, base::size(expected))); } { key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar"))); char expected[] = {0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 'r'}; - encoded_paths.push_back(std::string(expected, arraysize(expected))); + encoded_paths.push_back(std::string(expected, base::size(expected))); } ASSERT_EQ(key_paths.size(), encoded_paths.size());
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index f8d9516..3e6cbc8 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -81,6 +81,8 @@ return MediaSessionUserAction::SeekBackward; case media_session::mojom::MediaSessionAction::kSeekForward: return MediaSessionUserAction::SeekForward; + case media_session::mojom::MediaSessionAction::kStop: + break; } NOTREACHED(); return MediaSessionUserAction::Play;
diff --git a/content/browser/speech/mock_tts_controller.cc b/content/browser/speech/mock_tts_controller.cc index db1f17e9..cf7fb8a 100644 --- a/content/browser/speech/mock_tts_controller.cc +++ b/content/browser/speech/mock_tts_controller.cc
@@ -26,7 +26,7 @@ bool IsSpeaking() override { return false; } - void SpeakOrEnqueue(Utterance* utterance) override {} + void SpeakOrEnqueue(TtsUtterance* utterance) override {} void Stop() override {}
diff --git a/content/browser/speech/tts_controller_impl.cc b/content/browser/speech/tts_controller_impl.cc index bc25e9c..8327146 100644 --- a/content/browser/speech/tts_controller_impl.cc +++ b/content/browser/speech/tts_controller_impl.cc
@@ -23,22 +23,6 @@ // A value to be used to indicate that there is no char index available. const int kInvalidCharIndex = -1; -// Returns true if this event type is one that indicates an utterance -// is finished and can be destroyed. -bool IsFinalTtsEventType(TtsEventType event_type) { - return (event_type == TTS_EVENT_END || event_type == TTS_EVENT_INTERRUPTED || - event_type == TTS_EVENT_CANCELLED || event_type == TTS_EVENT_ERROR); -} - -// -// UtteranceContinuousParameters -// - -UtteranceContinuousParameters::UtteranceContinuousParameters() - : rate(blink::kWebSpeechSynthesisDoublePrefNotSet), - pitch(blink::kWebSpeechSynthesisDoublePrefNotSet), - volume(blink::kWebSpeechSynthesisDoublePrefNotSet) {} - // // VoiceData // @@ -50,50 +34,9 @@ VoiceData::~VoiceData() {} // -// Utterance +// TtsController // -// static -int Utterance::next_utterance_id_ = 0; - -Utterance::Utterance(BrowserContext* browser_context) - : browser_context_(browser_context), - id_(next_utterance_id_++), - src_id_(-1), - can_enqueue_(false), - char_index_(0), - finished_(false) { - options_.reset(new base::DictionaryValue()); -} - -Utterance::~Utterance() { - // It's an error if an Utterance is destructed without being finished, - // unless |browser_context_| is nullptr because it's a unit test. - DCHECK(finished_ || !browser_context_); -} - -void Utterance::OnTtsEvent(TtsEventType event_type, - int char_index, - const std::string& error_message) { - if (char_index >= 0) - char_index_ = char_index; - if (IsFinalTtsEventType(event_type)) - finished_ = true; - - if (event_delegate_) - event_delegate_->OnTtsEvent(this, event_type, char_index, error_message); - if (finished_) - event_delegate_ = nullptr; -} - -void Utterance::Finish() { - finished_ = true; -} - -void Utterance::set_options(const base::Value* options) { - options_.reset(options->DeepCopy()); -} - TtsController* TtsController::GetInstance() { return TtsControllerImpl::GetInstance(); } @@ -143,17 +86,17 @@ ClearUtteranceQueue(false); // Don't sent events. } -void TtsControllerImpl::SpeakOrEnqueue(Utterance* utterance) { +void TtsControllerImpl::SpeakOrEnqueue(TtsUtterance* utterance) { // If we're paused and we get an utterance that can't be queued, // flush the queue but stay in the paused state. - if (paused_ && !utterance->can_enqueue()) { + if (paused_ && !utterance->GetCanEnqueue()) { utterance_queue_.push(utterance); Stop(); paused_ = true; return; } - if (paused_ || (IsSpeaking() && utterance->can_enqueue())) { + if (paused_ || (IsSpeaking() && utterance->GetCanEnqueue())) { utterance_queue_.push(utterance); } else { Stop(); @@ -165,7 +108,7 @@ base::RecordAction(base::UserMetricsAction("TextToSpeech.Stop")); paused_ = false; - if (current_utterance_ && !current_utterance_->engine_id().empty()) { + if (current_utterance_ && !current_utterance_->GetEngineId().empty()) { if (GetTtsControllerDelegate()->GetTtsEngineDelegate()) GetTtsControllerDelegate()->GetTtsEngineDelegate()->Stop( current_utterance_); @@ -185,7 +128,7 @@ base::RecordAction(base::UserMetricsAction("TextToSpeech.Pause")); paused_ = true; - if (current_utterance_ && !current_utterance_->engine_id().empty()) { + if (current_utterance_ && !current_utterance_->GetEngineId().empty()) { if (GetTtsControllerDelegate()->GetTtsEngineDelegate()) GetTtsControllerDelegate()->GetTtsEngineDelegate()->Pause( current_utterance_); @@ -199,7 +142,7 @@ base::RecordAction(base::UserMetricsAction("TextToSpeech.Resume")); paused_ = false; - if (current_utterance_ && !current_utterance_->engine_id().empty()) { + if (current_utterance_ && !current_utterance_->GetEngineId().empty()) { if (GetTtsControllerDelegate()->GetTtsEngineDelegate()) GetTtsControllerDelegate()->GetTtsEngineDelegate()->Resume( current_utterance_); @@ -219,7 +162,7 @@ // already finished the utterance (for example because another utterance // interrupted or we got a call to Stop). This is normal and we can // safely just ignore these events. - if (!current_utterance_ || utterance_id != current_utterance_->id()) { + if (!current_utterance_ || utterance_id != current_utterance_->GetId()) { return; } @@ -263,7 +206,7 @@ UMATextToSpeechEvent::COUNT); current_utterance_->OnTtsEvent(event_type, char_index, error_message); - if (current_utterance_->finished()) { + if (current_utterance_->IsFinished()) { FinishCurrentUtterance(); SpeakNextUtterance(); } @@ -309,20 +252,21 @@ void TtsControllerImpl::RemoveUtteranceEventDelegate( UtteranceEventDelegate* delegate) { // First clear any pending utterances with this delegate. - base::queue<Utterance*> old_queue = utterance_queue_; - utterance_queue_ = base::queue<Utterance*>(); + base::queue<TtsUtterance*> old_queue = utterance_queue_; + utterance_queue_ = base::queue<TtsUtterance*>(); while (!old_queue.empty()) { - Utterance* utterance = old_queue.front(); + TtsUtterance* utterance = old_queue.front(); old_queue.pop(); - if (utterance->event_delegate() != delegate) + if (utterance->GetEventDelegate() != delegate) utterance_queue_.push(utterance); else delete utterance; } - if (current_utterance_ && current_utterance_->event_delegate() == delegate) { - current_utterance_->set_event_delegate(nullptr); - if (!current_utterance_->engine_id().empty()) { + if (current_utterance_ && + current_utterance_->GetEventDelegate() == delegate) { + current_utterance_->SetEventDelegate(nullptr); + if (!current_utterance_->GetEngineId().empty()) { if (GetTtsControllerDelegate()->GetTtsEngineDelegate()) GetTtsControllerDelegate()->GetTtsEngineDelegate()->Stop( current_utterance_); @@ -365,18 +309,18 @@ return tts_platform_; } -void TtsControllerImpl::SpeakNow(Utterance* utterance) { +void TtsControllerImpl::SpeakNow(TtsUtterance* utterance) { if (!GetTtsControllerDelegate()) return; // Ensure we have all built-in voices loaded. This is a no-op if already // loaded. bool loaded_built_in = - GetTtsPlatform()->LoadBuiltInTtsEngine(utterance->browser_context()); + GetTtsPlatform()->LoadBuiltInTtsEngine(utterance->GetBrowserContext()); // Get all available voices and try to find a matching voice. std::vector<VoiceData> voices; - GetVoices(utterance->browser_context(), &voices); + GetVoices(utterance->GetBrowserContext(), &voices); // Get the best matching voice. If nothing matches, just set "native" // to true because that might trigger deferred loading of native voices. @@ -395,26 +339,26 @@ base::RecordAction(base::UserMetricsAction("TextToSpeech.Speak")); UMA_HISTOGRAM_COUNTS_100000("TextToSpeech.Utterance.TextLength", - utterance->text().size()); + utterance->GetText().size()); UMA_HISTOGRAM_BOOLEAN("TextToSpeech.Utterance.FromExtensionAPI", - !utterance->src_url().is_empty()); + !utterance->GetSrcUrl().is_empty()); UMA_HISTOGRAM_BOOLEAN("TextToSpeech.Utterance.HasVoiceName", - !utterance->voice_name().empty()); + !utterance->GetVoiceName().empty()); UMA_HISTOGRAM_BOOLEAN("TextToSpeech.Utterance.HasLang", - !utterance->lang().empty()); + !utterance->GetLang().empty()); UMA_HISTOGRAM_BOOLEAN("TextToSpeech.Utterance.HasRate", - utterance->continuous_parameters().rate != 1.0); + utterance->GetContinuousParameters().rate != 1.0); UMA_HISTOGRAM_BOOLEAN("TextToSpeech.Utterance.HasPitch", - utterance->continuous_parameters().pitch != 1.0); + utterance->GetContinuousParameters().pitch != 1.0); UMA_HISTOGRAM_BOOLEAN("TextToSpeech.Utterance.HasVolume", - utterance->continuous_parameters().volume != 1.0); + utterance->GetContinuousParameters().volume != 1.0); UMA_HISTOGRAM_BOOLEAN("TextToSpeech.Utterance.Native", voice.native); if (!voice.native) { #if !defined(OS_ANDROID) DCHECK(!voice.engine_id.empty()); current_utterance_ = utterance; - utterance->set_engine_id(voice.engine_id); + utterance->SetEngineId(voice.engine_id); if (GetTtsControllerDelegate()->GetTtsEngineDelegate()) GetTtsControllerDelegate()->GetTtsEngineDelegate()->Speak(utterance, voice); @@ -432,9 +376,9 @@ // during |speak|. current_utterance_ = utterance; GetTtsPlatform()->ClearError(); - bool success = GetTtsPlatform()->Speak(utterance->id(), utterance->text(), - utterance->lang(), voice, - utterance->continuous_parameters()); + bool success = GetTtsPlatform()->Speak( + utterance->GetId(), utterance->GetText(), utterance->GetLang(), voice, + utterance->GetContinuousParameters()); if (!success) current_utterance_ = nullptr; @@ -456,7 +400,7 @@ void TtsControllerImpl::ClearUtteranceQueue(bool send_events) { while (!utterance_queue_.empty()) { - Utterance* utterance = utterance_queue_.front(); + TtsUtterance* utterance = utterance_queue_.front(); utterance_queue_.pop(); if (send_events) utterance->OnTtsEvent(TTS_EVENT_CANCELLED, kInvalidCharIndex, @@ -469,7 +413,7 @@ void TtsControllerImpl::FinishCurrentUtterance() { if (current_utterance_) { - if (!current_utterance_->finished()) + if (!current_utterance_->IsFinished()) current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, std::string()); delete current_utterance_; @@ -484,16 +428,16 @@ // Start speaking the next utterance in the queue. Keep trying in case // one fails but there are still more in the queue to try. while (!utterance_queue_.empty() && !current_utterance_) { - Utterance* utterance = utterance_queue_.front(); + TtsUtterance* utterance = utterance_queue_.front(); utterance_queue_.pop(); SpeakNow(utterance); } } -void TtsControllerImpl::UpdateUtteranceDefaults(Utterance* utterance) { - double rate = utterance->continuous_parameters().rate; - double pitch = utterance->continuous_parameters().pitch; - double volume = utterance->continuous_parameters().volume; +void TtsControllerImpl::UpdateUtteranceDefaults(TtsUtterance* utterance) { + double rate = utterance->GetContinuousParameters().rate; + double pitch = utterance->GetContinuousParameters().pitch; + double volume = utterance->GetContinuousParameters().volume; #if defined(OS_CHROMEOS) GetTtsControllerDelegate()->UpdateUtteranceDefaultsFromPrefs(utterance, &rate, &pitch, &volume); @@ -507,7 +451,7 @@ if (volume == blink::kWebSpeechSynthesisDoublePrefNotSet) volume = blink::kWebSpeechSynthesisDefaultTextToSpeechVolume; #endif // defined(OS_CHROMEOS) - utterance->set_continuous_parameters(rate, pitch, volume); + utterance->SetContinuousParameters(rate, pitch, volume); } TtsControllerDelegate* TtsControllerImpl::GetTtsControllerDelegate() {
diff --git a/content/browser/speech/tts_controller_impl.h b/content/browser/speech/tts_controller_impl.h index 6675484..fb16907 100644 --- a/content/browser/speech/tts_controller_impl.h +++ b/content/browser/speech/tts_controller_impl.h
@@ -40,7 +40,7 @@ // TtsController methods bool IsSpeaking() override; - void SpeakOrEnqueue(Utterance* utterance) override; + void SpeakOrEnqueue(TtsUtterance* utterance) override; void Stop() override; void Pause() override; void Resume() override; @@ -78,7 +78,7 @@ // Start speaking the given utterance. Will either take ownership of // |utterance| or delete it if there's an error. Returns true on success. - void SpeakNow(Utterance* utterance); + void SpeakNow(TtsUtterance* utterance); // Clear the utterance queue. If send_events is true, will send // TTS_EVENT_CANCELLED events on each one. @@ -93,7 +93,7 @@ // Updates the utterance to have default values for rate, pitch, and // volume if they have not yet been set. On Chrome OS, defaults are // pulled from user prefs, and may not be the same as other platforms. - void UpdateUtteranceDefaults(Utterance* utterance); + void UpdateUtteranceDefaults(TtsUtterance* utterance); TtsControllerDelegate* GetTtsControllerDelegate(); @@ -103,7 +103,7 @@ base::ObserverList<VoicesChangedDelegate> voices_changed_delegates_; // The current utterance being spoken. - Utterance* current_utterance_; + TtsUtterance* current_utterance_; // Whether the queue is paused or not. bool paused_; @@ -113,7 +113,7 @@ TtsPlatform* tts_platform_; // A queue of utterances to speak after the current one finishes. - base::queue<Utterance*> utterance_queue_; + base::queue<TtsUtterance*> utterance_queue_; DISALLOW_COPY_AND_ASSIGN(TtsControllerImpl); };
diff --git a/content/browser/speech/tts_controller_unittest.cc b/content/browser/speech/tts_controller_unittest.cc index b0130b6..9c28787 100644 --- a/content/browser/speech/tts_controller_unittest.cc +++ b/content/browser/speech/tts_controller_unittest.cc
@@ -4,6 +4,7 @@ // Unit tests for the TTS Controller. +#include "base/memory/ptr_util.h" #include "base/values.h" #include "content/browser/speech/tts_controller_impl.h" #include "content/public/browser/tts_controller_delegate.h" @@ -36,7 +37,7 @@ bool LoadBuiltInTtsEngine(BrowserContext* browser_context) override { return false; } - void WillSpeakUtteranceWithVoice(const Utterance* utterance, + void WillSpeakUtteranceWithVoice(const TtsUtterance* utterance, const VoiceData& voice_data) override {} void SetError(const std::string& error) override {} std::string GetError() override { return std::string(); } @@ -48,13 +49,13 @@ MockTtsControllerDelegate() {} ~MockTtsControllerDelegate() override {} - int GetMatchingVoice(const content::Utterance* utterance, + int GetMatchingVoice(const content::TtsUtterance* utterance, std::vector<content::VoiceData>& voices) override { // Below 0 implies a "native" voice. return -1; } - void UpdateUtteranceDefaultsFromPrefs(content::Utterance* utterance, + void UpdateUtteranceDefaultsFromPrefs(content::TtsUtterance* utterance, double* rate, double* pitch, double* volume) override{}; @@ -81,14 +82,14 @@ controller->SetTtsPlatform(&platform_impl); - Utterance* utterance1 = new Utterance(nullptr); - utterance1->set_can_enqueue(true); - utterance1->set_src_id(1); + TtsUtterance* utterance1 = TtsUtterance::Create(nullptr); + utterance1->SetCanEnqueue(true); + utterance1->SetSrcId(1); controller->SpeakOrEnqueue(utterance1); - Utterance* utterance2 = new Utterance(nullptr); - utterance2->set_can_enqueue(true); - utterance2->set_src_id(2); + TtsUtterance* utterance2 = TtsUtterance::Create(nullptr); + utterance2->SetCanEnqueue(true); + utterance2->SetSrcId(2); controller->SpeakOrEnqueue(utterance2); // Make sure that deleting the controller when there are pending @@ -104,23 +105,24 @@ std::unique_ptr<TtsControllerForTesting> controller = std::make_unique<TtsControllerForTesting>(); - std::unique_ptr<Utterance> utterance1 = std::make_unique<Utterance>(nullptr); + std::unique_ptr<TtsUtterance> utterance1 = + base::WrapUnique(content::TtsUtterance::Create(nullptr)); // Initialized to default (unset constant) values. EXPECT_EQ(blink::kWebSpeechSynthesisDoublePrefNotSet, - utterance1->continuous_parameters().rate); + utterance1->GetContinuousParameters().rate); EXPECT_EQ(blink::kWebSpeechSynthesisDoublePrefNotSet, - utterance1->continuous_parameters().pitch); + utterance1->GetContinuousParameters().pitch); EXPECT_EQ(blink::kWebSpeechSynthesisDoublePrefNotSet, - utterance1->continuous_parameters().volume); + utterance1->GetContinuousParameters().volume); controller->UpdateUtteranceDefaults(utterance1.get()); // Updated to global defaults. EXPECT_EQ(blink::kWebSpeechSynthesisDefaultTextToSpeechRate, - utterance1->continuous_parameters().rate); + utterance1->GetContinuousParameters().rate); EXPECT_EQ(blink::kWebSpeechSynthesisDefaultTextToSpeechPitch, - utterance1->continuous_parameters().pitch); + utterance1->GetContinuousParameters().pitch); EXPECT_EQ(blink::kWebSpeechSynthesisDefaultTextToSpeechVolume, - utterance1->continuous_parameters().volume); + utterance1->GetContinuousParameters().volume); } #endif // !defined(OS_CHROMEOS)
diff --git a/content/browser/speech/tts_platform_impl.cc b/content/browser/speech/tts_platform_impl.cc index 44492180..b6805ab 100644 --- a/content/browser/speech/tts_platform_impl.cc +++ b/content/browser/speech/tts_platform_impl.cc
@@ -28,7 +28,7 @@ return false; } -void TtsPlatformImpl::WillSpeakUtteranceWithVoice(const Utterance* utterance, +void TtsPlatformImpl::WillSpeakUtteranceWithVoice(const TtsUtterance* utterance, const VoiceData& voice_data) { }
diff --git a/content/browser/speech/tts_platform_impl.h b/content/browser/speech/tts_platform_impl.h index 554f772..2efe61b 100644 --- a/content/browser/speech/tts_platform_impl.h +++ b/content/browser/speech/tts_platform_impl.h
@@ -20,7 +20,7 @@ // TtsPlatform overrides. bool LoadBuiltInTtsEngine(BrowserContext* browser_context) override; - void WillSpeakUtteranceWithVoice(const Utterance* utterance, + void WillSpeakUtteranceWithVoice(const TtsUtterance* utterance, const VoiceData& voice_data) override; std::string GetError() override; void ClearError() override;
diff --git a/content/browser/speech/tts_utterance_impl.cc b/content/browser/speech/tts_utterance_impl.cc new file mode 100644 index 0000000..1c57bc0d --- /dev/null +++ b/content/browser/speech/tts_utterance_impl.cc
@@ -0,0 +1,190 @@ +// Copyright (c) 2018 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 "content/browser/speech/tts_utterance_impl.h" +#include "base/values.h" +#include "third_party/blink/public/platform/web_speech_synthesis_constants.h" + +namespace content { + +namespace { + +// Returns true if this event type is one that indicates an utterance +// is finished and can be destroyed. +bool IsFinalTtsEventType(TtsEventType event_type) { + return (event_type == TTS_EVENT_END || event_type == TTS_EVENT_INTERRUPTED || + event_type == TTS_EVENT_CANCELLED || event_type == TTS_EVENT_ERROR); +} + +} // namespace + +// +// UtteranceContinuousParameters +// + +UtteranceContinuousParameters::UtteranceContinuousParameters() + : rate(blink::kWebSpeechSynthesisDoublePrefNotSet), + pitch(blink::kWebSpeechSynthesisDoublePrefNotSet), + volume(blink::kWebSpeechSynthesisDoublePrefNotSet) {} + +// +// Utterance +// + +// static +int TtsUtteranceImpl::next_utterance_id_ = 0; + +TtsUtterance* TtsUtterance::Create(BrowserContext* browser_context) { + return new TtsUtteranceImpl(browser_context); +} + +TtsUtteranceImpl::TtsUtteranceImpl(BrowserContext* browser_context) + : browser_context_(browser_context), + id_(next_utterance_id_++), + src_id_(-1), + can_enqueue_(false), + char_index_(0), + finished_(false) { + options_.reset(new base::DictionaryValue()); +} + +TtsUtteranceImpl::~TtsUtteranceImpl() { + // It's an error if an Utterance is destructed without being finished, + // unless |browser_context_| is nullptr because it's a unit test. + DCHECK(finished_ || !browser_context_); +} + +void TtsUtteranceImpl::OnTtsEvent(TtsEventType event_type, + int char_index, + const std::string& error_message) { + if (char_index >= 0) + char_index_ = char_index; + if (IsFinalTtsEventType(event_type)) + finished_ = true; + + if (event_delegate_) + event_delegate_->OnTtsEvent(this, event_type, char_index, error_message); + if (finished_) + event_delegate_ = nullptr; +} + +void TtsUtteranceImpl::Finish() { + finished_ = true; +} + +void TtsUtteranceImpl::SetText(const std::string& text) { + text_ = text; +} + +const std::string& TtsUtteranceImpl::GetText() const { + return text_; +} + +void TtsUtteranceImpl::SetOptions(const base::Value* options) { + options_.reset(options->DeepCopy()); +} + +const base::Value* TtsUtteranceImpl::GetOptions() const { + return options_.get(); +} + +void TtsUtteranceImpl::SetSrcId(int src_id) { + src_id_ = src_id; +} + +int TtsUtteranceImpl::GetSrcId() { + return src_id_; +} + +void TtsUtteranceImpl::SetSrcUrl(const GURL& src_url) { + src_url_ = src_url; +} +const GURL& TtsUtteranceImpl::GetSrcUrl() { + return src_url_; +} + +void TtsUtteranceImpl::SetVoiceName(const std::string& voice_name) { + voice_name_ = voice_name; +} + +const std::string& TtsUtteranceImpl::GetVoiceName() const { + return voice_name_; +} + +void TtsUtteranceImpl::SetLang(const std::string& lang) { + lang_ = lang; +} + +const std::string& TtsUtteranceImpl::GetLang() const { + return lang_; +} + +void TtsUtteranceImpl::SetContinuousParameters(const double rate, + const double pitch, + const double volume) { + continuous_parameters_.rate = rate; + continuous_parameters_.pitch = pitch; + continuous_parameters_.volume = volume; +} + +const UtteranceContinuousParameters& +TtsUtteranceImpl::GetContinuousParameters() { + return continuous_parameters_; +} + +void TtsUtteranceImpl::SetCanEnqueue(bool can_enqueue) { + can_enqueue_ = can_enqueue; +} + +bool TtsUtteranceImpl::GetCanEnqueue() const { + return can_enqueue_; +} + +void TtsUtteranceImpl::SetRequiredEventTypes( + const std::set<TtsEventType>& types) { + required_event_types_ = types; +} + +const std::set<TtsEventType>& TtsUtteranceImpl::GetRequiredEventTypes() const { + return required_event_types_; +} + +void TtsUtteranceImpl::SetDesiredEventTypes( + const std::set<TtsEventType>& types) { + desired_event_types_ = types; +} +const std::set<TtsEventType>& TtsUtteranceImpl::GetDesiredEventTypes() const { + return desired_event_types_; +} + +void TtsUtteranceImpl::SetEngineId(const std::string& engine_id) { + engine_id_ = engine_id; +} + +const std::string& TtsUtteranceImpl::GetEngineId() const { + return engine_id_; +} + +void TtsUtteranceImpl::SetEventDelegate( + UtteranceEventDelegate* event_delegate) { + event_delegate_ = event_delegate; +} + +UtteranceEventDelegate* TtsUtteranceImpl::GetEventDelegate() const { + return event_delegate_; +} + +BrowserContext* TtsUtteranceImpl::GetBrowserContext() const { + return browser_context_; +} + +int TtsUtteranceImpl::GetId() const { + return id_; +} + +bool TtsUtteranceImpl::IsFinished() const { + return finished_; +} + +} // namespace content
diff --git a/content/browser/speech/tts_utterance_impl.h b/content/browser/speech/tts_utterance_impl.h new file mode 100644 index 0000000..d8b4fa4 --- /dev/null +++ b/content/browser/speech/tts_utterance_impl.h
@@ -0,0 +1,123 @@ +// Copyright (c) 2018 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 CONTENT_BROWSER_SPEECH_TTS_UTTERANCE_IMPL_H_ +#define CONTENT_BROWSER_SPEECH_TTS_UTTERANCE_IMPL_H_ + +#include <set> +#include <string> + +#include "base/values.h" +#include "content/public/browser/tts_controller.h" +#include "content/public/browser/tts_utterance.h" + +namespace content { +class BrowserContext; + +// Implementation of TtsUtterance. +class CONTENT_EXPORT TtsUtteranceImpl : public TtsUtterance { + public: + TtsUtteranceImpl(BrowserContext* browser_context); + ~TtsUtteranceImpl() override; + + // TtsUtterance overrides. + void OnTtsEvent(TtsEventType event_type, + int char_index, + const std::string& error_message) override; + + void Finish() override; + + void SetText(const std::string& text) override; + const std::string& GetText() const override; + + void SetOptions(const base::Value* options) override; + const base::Value* GetOptions() const override; + + void SetSrcId(int src_id) override; + int GetSrcId() override; + + void SetSrcUrl(const GURL& src_url) override; + const GURL& GetSrcUrl() override; + + void SetVoiceName(const std::string& voice_name) override; + const std::string& GetVoiceName() const override; + + void SetLang(const std::string& lang) override; + const std::string& GetLang() const override; + + void SetContinuousParameters(const double rate, + const double pitch, + const double volume) override; + const UtteranceContinuousParameters& GetContinuousParameters() override; + + void SetCanEnqueue(bool can_enqueue) override; + bool GetCanEnqueue() const override; + + void SetRequiredEventTypes(const std::set<TtsEventType>& types) override; + const std::set<TtsEventType>& GetRequiredEventTypes() const override; + + void SetDesiredEventTypes(const std::set<TtsEventType>& types) override; + const std::set<TtsEventType>& GetDesiredEventTypes() const override; + + void SetEngineId(const std::string& engine_id) override; + const std::string& GetEngineId() const override; + + void SetEventDelegate(UtteranceEventDelegate* event_delegate) override; + UtteranceEventDelegate* GetEventDelegate() const override; + + BrowserContext* GetBrowserContext() const override; + int GetId() const override; + bool IsFinished() const override; + + private: + // The BrowserContext that initiated this utterance. + BrowserContext* browser_context_; + + // The content embedder engine ID of the engine providing TTS for this + // utterance, or empty if native TTS is being used. + std::string engine_id_; + + // The unique ID of this utterance, used to associate callback functions + // with utterances. + int id_; + + // The id of the next utterance, so we can associate requests with + // responses. + static int next_utterance_id_; + + // The text to speak. + std::string text_; + + // The full options arg passed to tts.speak, which may include fields + // other than the ones we explicitly parse, below. + std::unique_ptr<base::Value> options_; + + // The source engine's ID of this utterance, so that it can associate + // events with the appropriate callback. + int src_id_; + + // The URL of the page where called speak was called. + GURL src_url_; + + // The delegate to be called when an utterance event is fired. + UtteranceEventDelegate* event_delegate_; + + // The parsed options. + std::string voice_name_; + std::string lang_; + UtteranceContinuousParameters continuous_parameters_; + bool can_enqueue_; + std::set<TtsEventType> required_event_types_; + std::set<TtsEventType> desired_event_types_; + + // The index of the current char being spoken. + int char_index_; + + // True if this utterance received an event indicating it's done. + bool finished_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SPEECH_TTS_UTTERANCE_IMPL_H_ \ No newline at end of file
diff --git a/content/browser/webrtc/webrtc_browsertest.cc b/content/browser/webrtc/webrtc_browsertest.cc index 2d23159..b826eea 100644 --- a/content/browser/webrtc/webrtc_browsertest.cc +++ b/content/browser/webrtc/webrtc_browsertest.cc
@@ -238,9 +238,9 @@ } IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, - GetSettingsWhenRemoteDimensionsUnknown) { + GetSettingsReportsValuesForRemoteTracks) { MakeTypicalPeerConnectionCall( - "testGetSettingsWhenRemoteDimensionsUnknown();"); + "testGetSettingsReportsValuesForRemoteTracks();"); } #if defined(OS_ANDROID) && BUILDFLAG(USE_PROPRIETARY_CODECS)
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index 67d1230..d2830b6 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -293,6 +293,7 @@ "tts_controller.h", "tts_controller_delegate.h", "tts_platform.h", + "tts_utterance.h", "url_data_source.cc", "url_data_source.h", "url_loader_request_interceptor.h",
diff --git a/content/public/browser/media_session.h b/content/public/browser/media_session.h index e9e339f1..ef8cf165 100644 --- a/content/public/browser/media_session.h +++ b/content/public/browser/media_session.h
@@ -29,10 +29,6 @@ ~MediaSession() override = default; - // Stop the media session. - // |type| represents the origin of the request. - virtual void Stop(SuspendType suspend_type) = 0; - // Return if the session can be controlled by Resume() and Suspend() calls // above. virtual bool IsControllable() const = 0; @@ -94,6 +90,10 @@ // both positive and negative values. void Seek(base::TimeDelta seek_time) override = 0; + // Stop the media session. + // |type| represents the origin of the request. + void Stop(SuspendType suspend_type) override = 0; + protected: MediaSession() = default;
diff --git a/content/public/browser/tts_controller.h b/content/public/browser/tts_controller.h index ef7c0fc..8c03666 100644 --- a/content/public/browser/tts_controller.h +++ b/content/public/browser/tts_controller.h
@@ -15,40 +15,13 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list_types.h" #include "content/common/content_export.h" +#include "content/public/browser/tts_utterance.h" #include "url/gurl.h" -namespace base { -class Value; -} - namespace content { -class Utterance; class BrowserContext; class TtsPlatform; -// Events sent back from the TTS engine indicating the progress. -enum TtsEventType { - TTS_EVENT_START, - TTS_EVENT_END, - TTS_EVENT_WORD, - TTS_EVENT_SENTENCE, - TTS_EVENT_MARKER, - TTS_EVENT_INTERRUPTED, - TTS_EVENT_CANCELLED, - TTS_EVENT_ERROR, - TTS_EVENT_PAUSE, - TTS_EVENT_RESUME -}; - -// The continuous parameters that apply to a given utterance. -struct CONTENT_EXPORT UtteranceContinuousParameters { - UtteranceContinuousParameters(); - - double rate; - double pitch; - double volume; -}; - // Information about one voice. struct CONTENT_EXPORT VoiceData { VoiceData(); @@ -80,32 +53,22 @@ std::vector<VoiceData>* out_voices) = 0; // Speak the given utterance by sending an event to the given TTS engine. - virtual void Speak(Utterance* utterance, const VoiceData& voice) = 0; + virtual void Speak(TtsUtterance* utterance, const VoiceData& voice) = 0; // Stop speaking the given utterance by sending an event to the target // associated with this utterance. - virtual void Stop(Utterance* utterance) = 0; + virtual void Stop(TtsUtterance* utterance) = 0; // Pause in the middle of speaking this utterance. - virtual void Pause(Utterance* utterance) = 0; + virtual void Pause(TtsUtterance* utterance) = 0; // Resume speaking this utterance. - virtual void Resume(Utterance* utterance) = 0; + virtual void Resume(TtsUtterance* utterance) = 0; // Load the built-in TTS engine. virtual bool LoadBuiltInTtsEngine(BrowserContext* browser_context) = 0; }; -// Class that wants to receive events on utterances. -class CONTENT_EXPORT UtteranceEventDelegate { - public: - virtual ~UtteranceEventDelegate() {} - virtual void OnTtsEvent(Utterance* utterance, - TtsEventType event_type, - int char_index, - const std::string& error_message) = 0; -}; - // Class that wants to be notified when the set of // voices has changed. class CONTENT_EXPORT VoicesChangedDelegate : public base::CheckedObserver { @@ -113,138 +76,6 @@ virtual void OnVoicesChanged() = 0; }; -// One speech utterance. -// TODO(katie): Can Utterance be changed into a struct with business logic -// fully in the callers? If not, consider splitting it out into its own file, -// and updating it to meet requirements for content/public interfaces. -class CONTENT_EXPORT Utterance { - public: - // Construct an utterance given a profile and a completion task to call - // when the utterance is done speaking. Before speaking this utterance, - // its other parameters like text, rate, pitch, etc. should all be set. - explicit Utterance(BrowserContext* browser_context); - ~Utterance(); - - // Sends an event to the delegate. If the event type is TTS_EVENT_END - // or TTS_EVENT_ERROR, deletes the utterance. If |char_index| is -1, - // uses the last good value. - void OnTtsEvent(TtsEventType event_type, - int char_index, - const std::string& error_message); - - // Finish an utterance without sending an event to the delegate. - void Finish(); - - // Getters and setters for the text to speak and other speech options. - void set_text(const std::string& text) { text_ = text; } - const std::string& text() const { return text_; } - - void set_options(const base::Value* options); - const base::Value* options() const { return options_.get(); } - - void set_src_id(int src_id) { src_id_ = src_id; } - int src_id() { return src_id_; } - - void set_src_url(const GURL& src_url) { src_url_ = src_url; } - const GURL& src_url() { return src_url_; } - - void set_voice_name(const std::string& voice_name) { - voice_name_ = voice_name; - } - const std::string& voice_name() const { return voice_name_; } - - void set_lang(const std::string& lang) { lang_ = lang; } - const std::string& lang() const { return lang_; } - - void set_continuous_parameters(const double rate, - const double pitch, - const double volume) { - continuous_parameters_.rate = rate; - continuous_parameters_.pitch = pitch; - continuous_parameters_.volume = volume; - } - const UtteranceContinuousParameters& continuous_parameters() { - return continuous_parameters_; - } - - void set_can_enqueue(bool can_enqueue) { can_enqueue_ = can_enqueue; } - bool can_enqueue() const { return can_enqueue_; } - - void set_required_event_types(const std::set<TtsEventType>& types) { - required_event_types_ = types; - } - const std::set<TtsEventType>& required_event_types() const { - return required_event_types_; - } - - void set_desired_event_types(const std::set<TtsEventType>& types) { - desired_event_types_ = types; - } - const std::set<TtsEventType>& desired_event_types() const { - return desired_event_types_; - } - - const std::string& engine_id() const { return engine_id_; } - void set_engine_id(const std::string& engine_id) { engine_id_ = engine_id; } - - UtteranceEventDelegate* event_delegate() const { return event_delegate_; } - void set_event_delegate(UtteranceEventDelegate* event_delegate) { - event_delegate_ = event_delegate; - } - - // Getters and setters for internal state. - BrowserContext* browser_context() const { return browser_context_; } - int id() const { return id_; } - bool finished() const { return finished_; } - - private: - // The BrowserContext that initiated this utterance. - BrowserContext* browser_context_; - - // The content embedder engine ID of the engine providing TTS for this - // utterance, or empty if native TTS is being used. - std::string engine_id_; - - // The unique ID of this utterance, used to associate callback functions - // with utterances. - int id_; - - // The id of the next utterance, so we can associate requests with - // responses. - static int next_utterance_id_; - - // The text to speak. - std::string text_; - - // The full options arg passed to tts.speak, which may include fields - // other than the ones we explicitly parse, below. - std::unique_ptr<base::Value> options_; - - // The source engine's ID of this utterance, so that it can associate - // events with the appropriate callback. - int src_id_; - - // The URL of the page where called speak was called. - GURL src_url_; - - // The delegate to be called when an utterance event is fired. - UtteranceEventDelegate* event_delegate_; - - // The parsed options. - std::string voice_name_; - std::string lang_; - UtteranceContinuousParameters continuous_parameters_; - bool can_enqueue_; - std::set<TtsEventType> required_event_types_; - std::set<TtsEventType> desired_event_types_; - - // The index of the current char being spoken. - int char_index_; - - // True if this utterance received an event indicating it's done. - bool finished_; -}; - // Singleton class that manages text-to-speech for all TTS engines and // APIs, maintaining a queue of pending utterances and keeping // track of all state. @@ -260,7 +91,7 @@ // and another utterance is in progress, adds it to the end of the queue. // Otherwise, interrupts any current utterance and speaks this one // immediately. - virtual void SpeakOrEnqueue(Utterance* utterance) = 0; + virtual void SpeakOrEnqueue(TtsUtterance* utterance) = 0; // Stop all utterances and flush the queue. Implies leaving pause mode // as well.
diff --git a/content/public/browser/tts_controller_delegate.h b/content/public/browser/tts_controller_delegate.h index 96a16c1..58070f8 100644 --- a/content/public/browser/tts_controller_delegate.h +++ b/content/public/browser/tts_controller_delegate.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_TTS_CONTROLLER_DELEGATE_H_ #include "content/public/browser/tts_controller.h" +#include "content/public/browser/tts_utterance.h" namespace content { @@ -14,12 +15,12 @@ public: // Given an utterance and a vector of voices, return the // index of the voice that best matches the utterance. - virtual int GetMatchingVoice(const Utterance* utterance, + virtual int GetMatchingVoice(const TtsUtterance* utterance, std::vector<VoiceData>& voices) = 0; // Uses the user preferences to update the |rate|, |pitch| and |volume| for // a given |utterance|. - virtual void UpdateUtteranceDefaultsFromPrefs(Utterance* utterance, + virtual void UpdateUtteranceDefaultsFromPrefs(TtsUtterance* utterance, double* rate, double* pitch, double* volume) = 0;
diff --git a/content/public/browser/tts_platform.h b/content/public/browser/tts_platform.h index 0f8f64f..e344833 100644 --- a/content/public/browser/tts_platform.h +++ b/content/public/browser/tts_platform.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "content/common/content_export.h" #include "content/public/browser/tts_controller.h" +#include "content/public/browser/tts_utterance.h" namespace content { @@ -61,7 +62,7 @@ // Allows the platform to monitor speech commands and the voices used // for each one. - virtual void WillSpeakUtteranceWithVoice(const Utterance* utterance, + virtual void WillSpeakUtteranceWithVoice(const TtsUtterance* utterance, const VoiceData& voice_data) = 0; virtual std::string GetError() = 0;
diff --git a/content/public/browser/tts_utterance.h b/content/public/browser/tts_utterance.h new file mode 100644 index 0000000..310cacf --- /dev/null +++ b/content/public/browser/tts_utterance.h
@@ -0,0 +1,120 @@ +// Copyright (c) 2018 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 CONTENT_PUBLIC_BROWSER_TTS_UTTERANCE_H_ +#define CONTENT_PUBLIC_BROWSER_TTS_UTTERANCE_H_ + +#include <set> + +#include "content/common/content_export.h" +#include "url/gurl.h" + +namespace base { +class Value; +} + +namespace content { +class BrowserContext; +class TtsUtterance; + +// Events sent back from the TTS engine indicating the progress. +enum TtsEventType { + TTS_EVENT_START, + TTS_EVENT_END, + TTS_EVENT_WORD, + TTS_EVENT_SENTENCE, + TTS_EVENT_MARKER, + TTS_EVENT_INTERRUPTED, + TTS_EVENT_CANCELLED, + TTS_EVENT_ERROR, + TTS_EVENT_PAUSE, + TTS_EVENT_RESUME +}; + +// The continuous parameters that apply to a given utterance. +struct CONTENT_EXPORT UtteranceContinuousParameters { + UtteranceContinuousParameters(); + + double rate; + double pitch; + double volume; +}; + +// Class that wants to receive events on utterances. +class CONTENT_EXPORT UtteranceEventDelegate { + public: + virtual ~UtteranceEventDelegate() {} + virtual void OnTtsEvent(TtsUtterance* utterance, + TtsEventType event_type, + int char_index, + const std::string& error_message) = 0; +}; + +// One speech utterance. +class CONTENT_EXPORT TtsUtterance { + public: + // Construct an utterance given a profile and a completion task to call + // when the utterance is done speaking. Before speaking this utterance, + // its other parameters like text, rate, pitch, etc. should all be set. + static TtsUtterance* Create(BrowserContext* browser_context); + virtual ~TtsUtterance() = default; + + // Sends an event to the delegate. If the event type is TTS_EVENT_END + // or TTS_EVENT_ERROR, deletes the utterance. If |char_index| is -1, + // uses the last good value. + virtual void OnTtsEvent(TtsEventType event_type, + int char_index, + const std::string& error_message) = 0; + + // Finish an utterance without sending an event to the delegate. + virtual void Finish() = 0; + + // Getters and setters for the text to speak and other speech options. + virtual void SetText(const std::string& text) = 0; + virtual const std::string& GetText() const = 0; + + virtual void SetOptions(const base::Value* options) = 0; + virtual const base::Value* GetOptions() const = 0; + + virtual void SetSrcId(int src_id) = 0; + virtual int GetSrcId() = 0; + + virtual void SetSrcUrl(const GURL& src_url) = 0; + virtual const GURL& GetSrcUrl() = 0; + + virtual void SetVoiceName(const std::string& voice_name) = 0; + virtual const std::string& GetVoiceName() const = 0; + + virtual void SetLang(const std::string& lang) = 0; + virtual const std::string& GetLang() const = 0; + + virtual void SetContinuousParameters(const double rate, + const double pitch, + const double volume) = 0; + virtual const UtteranceContinuousParameters& GetContinuousParameters() = 0; + + virtual void SetCanEnqueue(bool can_enqueue) = 0; + virtual bool GetCanEnqueue() const = 0; + + virtual void SetRequiredEventTypes(const std::set<TtsEventType>& types) = 0; + virtual const std::set<TtsEventType>& GetRequiredEventTypes() const = 0; + + virtual void SetDesiredEventTypes(const std::set<TtsEventType>& types) = 0; + virtual const std::set<TtsEventType>& GetDesiredEventTypes() const = 0; + + virtual void SetEngineId(const std::string& engine_id) = 0; + virtual const std::string& GetEngineId() const = 0; + + virtual void SetEventDelegate(UtteranceEventDelegate* event_delegate) = 0; + virtual UtteranceEventDelegate* GetEventDelegate() const = 0; + + // Getters and setters for internal state. + virtual BrowserContext* GetBrowserContext() const = 0; + virtual int GetId() const = 0; + virtual bool IsFinished() const = 0; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_TTS_UTTERANCE_H_
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 0b9c873..9db97ce 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -291,6 +291,7 @@ "media/stream/media_stream_source.h", "media/stream/media_stream_track.cc", "media/stream/media_stream_track.h", + "media/stream/media_stream_types.h", "media/stream/media_stream_video_capturer_source.cc", "media/stream/media_stream_video_capturer_source.h", "media/stream/media_stream_video_renderer_sink.cc", @@ -397,10 +398,10 @@ "media/webrtc/webrtc_uma_histograms.cc", "media/webrtc/webrtc_uma_histograms.h", "media/webrtc/webrtc_util.h", + "media/webrtc/webrtc_video_capturer_adapter.cc", + "media/webrtc/webrtc_video_capturer_adapter.h", "media/webrtc/webrtc_video_frame_adapter.cc", "media/webrtc/webrtc_video_frame_adapter.h", - "media/webrtc/webrtc_video_track_source.cc", - "media/webrtc/webrtc_video_track_source.h", "media/webrtc/webrtc_video_utils.cc", "media/webrtc/webrtc_video_utils.h", "media/webrtc_local_audio_source_provider.cc",
diff --git a/content/renderer/media/stream/media_stream_constraints_util.h b/content/renderer/media/stream/media_stream_constraints_util.h index ca74d75..544bba0 100644 --- a/content/renderer/media/stream/media_stream_constraints_util.h +++ b/content/renderer/media/stream/media_stream_constraints_util.h
@@ -172,6 +172,17 @@ // constraints that could not be satisfied. class CONTENT_EXPORT AudioCaptureSettings { public: + enum class ProcessingType { + // System echo cancellation can be enabled, but all other processing is + // disabled. + kUnprocessed, + // System echo cancellation and audio mirroring can be enabled, but all + // other processing is disabled. + kNoApmProcessed, + // Processing is performed through WebRTC. + kApmProcessed + }; + // Creates an object without value and with an empty failed constraint name. AudioCaptureSettings();
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio.cc b/content/renderer/media/stream/media_stream_constraints_util_audio.cc index 01162296..b683f3c 100644 --- a/content/renderer/media/stream/media_stream_constraints_util_audio.cc +++ b/content/renderer/media/stream/media_stream_constraints_util_audio.cc
@@ -29,67 +29,85 @@ using EchoCancellationType = AudioProcessingProperties::EchoCancellationType; using ConstraintSet = blink::WebMediaTrackConstraintSet; +using ProcessingType = AudioCaptureSettings::ProcessingType; using StringConstraint = blink::StringConstraint; using BooleanConstraint = blink::BooleanConstraint; namespace { -template <class T> -using DiscreteSet = media_constraints::DiscreteSet<T>; +using StringSet = media_constraints::DiscreteSet<std::string>; +using BoolSet = media_constraints::DiscreteSet<bool>; +using EchoCancellationTypeSet = + media_constraints::DiscreteSet<EchoCancellationType>; // The presence of a MediaStreamAudioSource object indicates whether the source -// in question is currently in use, or not. This convenience enum helps identify -// whether a source is available and if so whether has audio processing enabled -// or disabled. -enum class SourceType { kNoSource, kUnprocessedSource, kProcessedSource }; +// in question is currently in use, or not. This convenience enum helps +// identifying whether a source is available and, if so, whether it has audio +// processing enabled or disabled. +enum class SourceType { kNone, kUnprocessed, kNoApmProcessed, kApmProcessed }; // This class encapsulates two values that together build up the score of each // processed candidate. // - Fitness, similarly defined by the W3C specification // (https://w3c.github.io/mediacapture-main/#dfn-fitness-distance); -// - Distance from the default device ID. +// - Distance from the default device ID; +// - The priority associated to the echo cancellation type selected. +// - The priority of the associated processing-based container. // // Differently from the definition in the W3C specification, the present // algorithm maximizes the score. struct Score { public: - explicit Score(double fitness, bool is_default_device_id = false) { - score = std::make_tuple(fitness, is_default_device_id); + enum class EcModeScore : int { + kDisabled = 1, + kSystem = 2, + kAec3 = 3, + kAec2 = 4 + }; + + explicit Score(double fitness, + bool is_default_device_id = false, + EcModeScore ec_mode_score = EcModeScore::kDisabled, + int processing_priority = -1) { + score = std::make_tuple(fitness, is_default_device_id, ec_mode_score, + processing_priority); } - bool operator<(const Score& other) const { return score < other.score; } + bool operator>(const Score& other) const { return score > other.score; } Score& operator+=(const Score& other) { std::get<0>(score) += std::get<0>(other.score); std::get<1>(score) |= std::get<1>(other.score); - + // Among the priorities in the two score objects, we store the highest one. + std::get<2>(score) = std::max(std::get<2>(score), std::get<2>(other.score)); + // Select the highest processing priority. + std::get<3>(score) = std::max(std::get<3>(score), std::get<3>(other.score)); return *this; } - std::tuple<double, bool> score; + Score& operator+=(double fitness) { + std::get<0>(score) += fitness; + return *this; + } + + Score& operator+=(bool is_default_device) { + std::get<1>(score) |= is_default_device; + return *this; + } + + void set_ec_mode_score(EcModeScore ec_mode_score) { + std::get<2>(score) = ec_mode_score; + } + + void set_processing_priority(int priority) { std::get<3>(score) = priority; } + + std::tuple<double, bool, EcModeScore, int> score; }; -// Selects the best value from the nonempty |set|, subject to |constraint|. The -// only decision criteria is equality to |constraint.Ideal()|. If there is no -// single best value in |set|, returns nullopt. -base::Optional<bool> SelectOptionalBool( - const DiscreteSet<bool>& set, - const blink::BooleanConstraint& constraint) { - DCHECK(!set.IsEmpty()); - if (constraint.HasIdeal() && set.Contains(constraint.Ideal())) - return constraint.Ideal(); - - if (set.is_universal()) - return base::Optional<bool>(); - - DCHECK_EQ(set.elements().size(), 1U); - return set.FirstElement(); -} - // Container for each independent boolean constrainable property. class BooleanContainer { public: - BooleanContainer(DiscreteSet<bool> allowed_values = DiscreteSet<bool>()) + BooleanContainer(BoolSet allowed_values = BoolSet()) : allowed_values_(std::move(allowed_values)) {} const char* ApplyConstraintSet(const BooleanConstraint& constraint) { @@ -116,14 +134,13 @@ bool IsEmpty() const { return allowed_values_.IsEmpty(); } private: - DiscreteSet<bool> allowed_values_; + BoolSet allowed_values_; }; // Container for each independent string constrainable property. class StringContainer { public: - explicit StringContainer( - DiscreteSet<std::string> allowed_values = DiscreteSet<std::string>()) + explicit StringContainer(StringSet allowed_values = StringSet()) : allowed_values_(std::move(allowed_values)) {} const char* ApplyConstraintSet(const StringConstraint& constraint) { @@ -159,105 +176,90 @@ bool IsEmpty() const { return allowed_values_.IsEmpty(); } private: - DiscreteSet<std::string> allowed_values_; + StringSet allowed_values_; }; // Container to manage the properties related to echo cancellation: // echoCancellation, googEchoCancellation and echoCancellationType. class EchoCancellationContainer { public: - EchoCancellationContainer(SourceType source_type, + EchoCancellationContainer(std::vector<EchoCancellationType> allowed_values, + bool has_active_source, bool is_device_capture, - media::AudioParameters parameters, + media::AudioParameters device_parameters, AudioProcessingProperties properties) - : parameters_(parameters), is_device_capture_(is_device_capture) { - if (source_type == SourceType::kNoSource) { - ec_type_allowed_values_ = - GetEchoCancellationTypesFromParameters(parameters); + : ec_mode_allowed_values_(EchoCancellationTypeSet({allowed_values})), + device_parameters_(device_parameters), + is_device_capture_(is_device_capture) { + if (!has_active_source) { +#if defined(OS_MACOSX) || defined(OS_CHROMEOS) + // If force system echo cancellation feature is enabled, only expose that + // type if available; otherwise expose no type. + if (base::FeatureList::IsEnabled(features::kForceEnableSystemAec)) { + ec_mode_allowed_values_ = + ec_mode_allowed_values_.Intersection(EchoCancellationTypeSet( + {EchoCancellationType::kEchoCancellationSystem, + EchoCancellationType::kEchoCancellationDisabled})); + } +#endif // defined(OS_MACOSX) || defined(OS_CHROMEOS) return; } - ec_allowed_values_ = DiscreteSet<bool>({IsEchoCancellationEnabled( - properties, parameters.effects(), - source_type == SourceType::kProcessedSource)}); - goog_ec_allowed_values_ = ec_allowed_values_; - - auto type = ToBlinkEchoCancellationType(properties.echo_cancellation_type); - ec_type_allowed_values_ = - type ? DiscreteSet<std::string>({*type}) : DiscreteSet<std::string>(); + ec_mode_allowed_values_ = + EchoCancellationTypeSet({properties.echo_cancellation_type}); + ec_allowed_values_ = + BoolSet({properties.echo_cancellation_type != + EchoCancellationType::kEchoCancellationDisabled}); } const char* ApplyConstraintSet(const ConstraintSet& constraint_set) { - ec_allowed_values_ = ec_allowed_values_.Intersection( - media_constraints::BoolSetFromConstraint( - constraint_set.echo_cancellation)); + // Convert the constraints into discrete sets. + BoolSet ec_set = media_constraints::BoolSetFromConstraint( + constraint_set.echo_cancellation); + BoolSet goog_ec_set = media_constraints::BoolSetFromConstraint( + constraint_set.goog_echo_cancellation); + StringSet ec_type_set = media_constraints::StringSetFromConstraint( + constraint_set.echo_cancellation_type); + + // Apply echoCancellation constraint. + ec_allowed_values_ = ec_allowed_values_.Intersection(ec_set); if (ec_allowed_values_.IsEmpty()) return constraint_set.echo_cancellation.GetName(); - - goog_ec_allowed_values_ = goog_ec_allowed_values_.Intersection( - media_constraints::BoolSetFromConstraint( - constraint_set.goog_echo_cancellation)); - if (goog_ec_allowed_values_.IsEmpty()) - return constraint_set.goog_echo_cancellation.GetName(); - - ec_type_allowed_values_ = ec_type_allowed_values_.Intersection( - media_constraints::StringSetFromConstraint( - constraint_set.echo_cancellation_type)); - if (ec_type_allowed_values_.IsEmpty()) + // Intersect echoCancellation with googEchoCancellation and determine if + // there is a contradiction. + auto ec_intersection = ec_allowed_values_.Intersection(goog_ec_set); + if (ec_intersection.IsEmpty()) + return constraint_set.echo_cancellation.GetName(); + // Apply echoCancellationType constraint. + ec_mode_allowed_values_ = ec_mode_allowed_values_.Intersection( + ToEchoCancellationTypes(ec_intersection, ec_type_set)); + if (ec_mode_allowed_values_.IsEmpty()) return constraint_set.echo_cancellation_type.GetName(); - // If the echoCancellation constraint is not true, the type set should not - // have explicit elements, otherwise the two constraints would contradict - // each other. - if (!ec_allowed_values_.Contains(true) && - constraint_set.echo_cancellation_type.HasExact()) { - return constraint_set.echo_cancellation_type.GetName(); - } - // Finally, if this container is empty, fail due to contradiction of the // resulting allowed values for goog_ec, ec, and/or ec_type. return IsEmpty() ? constraint_set.echo_cancellation.GetName() : nullptr; } - std::tuple<double, EchoCancellationType> SelectSettingsAndScore( + std::tuple<Score, EchoCancellationType> SelectSettingsAndScore( const ConstraintSet& constraint_set) const { - DCHECK(!IsEmpty()); - double fitness = 0.0; - EchoCancellationType echo_cancellation_type = - EchoCancellationType::kEchoCancellationDisabled; - if (ShouldUseEchoCancellation(constraint_set.echo_cancellation, - constraint_set.goog_echo_cancellation)) { - std::tie(echo_cancellation_type, fitness) = - SelectEchoCancellationTypeAndFitness( - constraint_set.echo_cancellation_type); - } - - return std::make_tuple(fitness, echo_cancellation_type); + EchoCancellationType selected_ec_mode = SelectBestEcMode(constraint_set); + double fitness = Fitness(selected_ec_mode, constraint_set.echo_cancellation, + constraint_set.echo_cancellation_type); + Score score(fitness); + score.set_ec_mode_score(GetEcModeScore(selected_ec_mode)); + return std::make_tuple(score, selected_ec_mode); } - bool IsEmpty() const { - // This container is empty when googEchoCancellation and echoCancellation - // constraints contradict each other. - auto ec_intersection = - ec_allowed_values_.Intersection(goog_ec_allowed_values_); - // This container is also empty if echoCancellation and - // echoCancellationType contraddict each other. - bool ec_type_contraddicts_ec = !ec_allowed_values_.Contains(false) && - ec_type_allowed_values_.IsEmpty(); - return ec_type_contraddicts_ec || ec_intersection.IsEmpty(); - } + bool IsEmpty() const { return ec_mode_allowed_values_.IsEmpty(); } // Audio-processing properties are disabled by default for content capture, // or if the |echo_cancellation| constraint is false. void UpdateDefaultValues( const BooleanConstraint& echo_cancellation_constraint, AudioProcessingProperties* properties) const { - auto echo_cancellation = - SelectOptionalBool(ec_allowed_values_, echo_cancellation_constraint); - - bool default_audio_processing_value = true; - if (!is_device_capture_ || (echo_cancellation && !*echo_cancellation)) - default_audio_processing_value = false; + bool default_audio_processing_value = + GetDefaultValueForAudioProperties(echo_cancellation_constraint); properties->goog_audio_mirroring &= default_audio_processing_value; properties->goog_auto_gain_control &= default_audio_processing_value; @@ -272,173 +274,530 @@ default_audio_processing_value; } + bool GetDefaultValueForAudioProperties( + const BooleanConstraint& ec_constraint) const { + DCHECK(!ec_mode_allowed_values_.is_universal()); + + if (ec_constraint.HasIdeal() && + ec_allowed_values_.Contains(ec_constraint.Ideal())) + return is_device_capture_ && ec_constraint.Ideal(); + + if (ec_allowed_values_.Contains(true)) + return is_device_capture_; + + return false; + } + private: - static DiscreteSet<std::string> GetEchoCancellationTypesFromParameters( - const media::AudioParameters& audio_parameters) { -#if defined(OS_MACOSX) || defined(OS_CHROMEOS) - // If force system echo cancellation feature is enabled: only expose that - // type if available, otherwise expose no type. - if (base::FeatureList::IsEnabled(features::kForceEnableSystemAec)) { - std::vector<std::string> types; - if (audio_parameters.effects() & - (media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER | - media::AudioParameters::ECHO_CANCELLER)) { - types.push_back(blink::kEchoCancellationTypeSystem); + static Score::EcModeScore GetEcModeScore(EchoCancellationType mode) { + switch (mode) { + case EchoCancellationType::kEchoCancellationDisabled: + return Score::EcModeScore::kDisabled; + case EchoCancellationType::kEchoCancellationSystem: + return Score::EcModeScore::kSystem; + case EchoCancellationType::kEchoCancellationAec3: + return Score::EcModeScore::kAec3; + case EchoCancellationType::kEchoCancellationAec2: + return Score::EcModeScore::kAec2; + } + } + + static base::Optional<EchoCancellationType> ToEchoCancellationType( + const char* blink_type) { + if (strcmp(blink_type, blink::kEchoCancellationTypeBrowser) == 0) { + return EchoCancellationType::kEchoCancellationAec2; + } else if (strcmp(blink_type, blink::kEchoCancellationTypeAec3) == 0) { + return EchoCancellationType::kEchoCancellationAec3; + } else if (strcmp(blink_type, blink::kEchoCancellationTypeSystem) == 0) { + return EchoCancellationType::kEchoCancellationSystem; + } else { + return base::nullopt; + } + } + + static std::vector<EchoCancellationType> ToEchoCancellationTypes( + const StringSet& types_set) { + std::vector<EchoCancellationType> methods; + const char* blink_types[] = {blink::kEchoCancellationTypeBrowser, + blink::kEchoCancellationTypeAec3, + blink::kEchoCancellationTypeSystem}; + + for (const char* blink_type : blink_types) { + if (types_set.Contains(blink_type)) { + base::Optional<EchoCancellationType> converted_type = + ToEchoCancellationType(blink_type); + DCHECK(converted_type); + methods.push_back(*converted_type); } - return DiscreteSet<std::string>(types); } -#endif // defined(OS_MACOSX) || defined(OS_CHROMEOS) - // The browser and AEC3 echo cancellers are always available. - std::vector<std::string> types = {blink::kEchoCancellationTypeBrowser, - blink::kEchoCancellationTypeAec3}; + return methods; + } - if (audio_parameters.effects() & - (media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER | - media::AudioParameters::ECHO_CANCELLER)) { - // If the system/hardware supports echo cancellation, add it to the set. - types.push_back(blink::kEchoCancellationTypeSystem); + static EchoCancellationTypeSet ToEchoCancellationTypes( + const BoolSet ec_set, + const StringSet ec_type_set) { + std::vector<EchoCancellationType> types; + + if (ec_set.Contains(false) && ec_type_set.is_universal()) + types.push_back(EchoCancellationType::kEchoCancellationDisabled); + + if (ec_set.Contains(true)) { + if (ec_type_set.Contains(blink::kEchoCancellationTypeBrowser)) + types.push_back(EchoCancellationType::kEchoCancellationAec2); + if (ec_type_set.Contains(blink::kEchoCancellationTypeAec3)) + types.push_back(EchoCancellationType::kEchoCancellationAec3); + if (ec_type_set.Contains(blink::kEchoCancellationTypeSystem)) + types.push_back(EchoCancellationType::kEchoCancellationSystem); } - return DiscreteSet<std::string>(types); + + return EchoCancellationTypeSet(types); } - static bool IsEchoCancellationEnabled( - const AudioProcessingProperties& properties, - int effects, - bool is_processed) { - const bool system_echo_cancellation_available = - (properties.echo_cancellation_type == - EchoCancellationType::kEchoCancellationSystem || - !is_processed) && - effects & media::AudioParameters::ECHO_CANCELLER; - - const bool experimental_system_cancellation_available = - properties.echo_cancellation_type == - EchoCancellationType::kEchoCancellationSystem && - effects & media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER; - - return properties.EchoCancellationIsWebRtcProvided() || - system_echo_cancellation_available || - experimental_system_cancellation_available; - } - - bool ShouldUseEchoCancellation( - const BooleanConstraint& echo_cancellation_constraint, - const BooleanConstraint& goog_echo_cancellation_constraint) const { - base::Optional<bool> ec = - SelectOptionalBool(ec_allowed_values_, echo_cancellation_constraint); - base::Optional<bool> goog_ec = SelectOptionalBool( - goog_ec_allowed_values_, goog_echo_cancellation_constraint); - - if (ec) - return *ec; - if (goog_ec) - return *goog_ec; - - // Echo cancellation is enabled by default for device capture and disabled - // by default for content capture. - return is_device_capture_; - } - - std::tuple<EchoCancellationType, double> SelectEchoCancellationTypeAndFitness( - const blink::StringConstraint& echo_cancellation_type) const { - double fitness = 0.0; + EchoCancellationType SelectBestEcMode( + const ConstraintSet& constraint_set) const { + DCHECK(!IsEmpty()); + DCHECK(!ec_mode_allowed_values_.is_universal()); // Try to use an ideal candidate, if supplied. - base::Optional<std::string> selected_type; - if (echo_cancellation_type.HasIdeal()) { - for (const auto& ideal : echo_cancellation_type.Ideal()) { - std::string candidate = ideal.Utf8(); - if (ec_type_allowed_values_.Contains(candidate)) { - selected_type = candidate; - fitness = 1.0; - break; - } + bool is_ec_preferred = + ShouldUseEchoCancellation(constraint_set.echo_cancellation, + constraint_set.goog_echo_cancellation); + + if (!is_ec_preferred && + ec_mode_allowed_values_.Contains( + EchoCancellationType::kEchoCancellationDisabled)) { + return EchoCancellationType::kEchoCancellationDisabled; + } + + if (constraint_set.echo_cancellation_type.HasIdeal()) { + for (const auto& ideal : constraint_set.echo_cancellation_type.Ideal()) { + base::Optional<EchoCancellationType> candidate = + ToEchoCancellationType(ideal.Utf8().c_str()); + if (candidate && ec_mode_allowed_values_.Contains(*candidate)) + return *candidate; } } - // If no ideal, or none that worked, and the set contains only one value, - // pick that. - if (!selected_type) { - if (!ec_type_allowed_values_.is_universal() && - ec_type_allowed_values_.elements().size() == 1) { - selected_type = ec_type_allowed_values_.FirstElement(); - } - } - - // Return type based on the selected type. - if (selected_type == blink::kEchoCancellationTypeBrowser) { - return std::make_tuple(EchoCancellationType::kEchoCancellationAec2, - fitness); - } else if (selected_type == blink::kEchoCancellationTypeAec3) { - return std::make_tuple(EchoCancellationType::kEchoCancellationAec3, - fitness); - } else if (selected_type == blink::kEchoCancellationTypeSystem) { - return std::make_tuple(EchoCancellationType::kEchoCancellationSystem, - fitness); - } + // If no ideal could be selected and the set contains only one value, pick + // that one. + if (ec_mode_allowed_values_.elements().size() == 1) + return ec_mode_allowed_values_.FirstElement(); // If no type has been selected, choose system if the device has the // ECHO_CANCELLER flag set. Never automatically enable an experimental // system echo canceller. - if (parameters_.IsValid() && - parameters_.effects() & media::AudioParameters::ECHO_CANCELLER) { - return std::make_tuple(EchoCancellationType::kEchoCancellationSystem, - fitness); + if (device_parameters_.IsValid() && + ec_mode_allowed_values_.Contains( + EchoCancellationType::kEchoCancellationSystem) && + device_parameters_.effects() & media::AudioParameters::ECHO_CANCELLER) { + return EchoCancellationType::kEchoCancellationSystem; } - // Finally, choose the browser provided AEC2 or AEC3 based on an optional - // override setting for AEC3 or feature. - // In unit tests not creating a message filter, |aec_dump_message_filter| - // will be null. We can just ignore that. Other unit tests and browser tests - // ensure that we do get the filter when we should. + base::Optional<bool> override_aec3 = GetOverrideAec3(); + if (override_aec3) { + bool use_aec3 = override_aec3.value_or( + base::FeatureList::IsEnabled(features::kWebRtcUseEchoCanceller3)); + if ((use_aec3 && ec_mode_allowed_values_.Contains( + EchoCancellationType::kEchoCancellationAec3)) || + (!use_aec3 && ec_mode_allowed_values_.Contains( + EchoCancellationType::kEchoCancellationAec2))) { + return use_aec3 ? EchoCancellationType::kEchoCancellationAec3 + : EchoCancellationType::kEchoCancellationAec2; + } + } + + // If the previous tie breakers were not enough to determine the selected + // mode, the resolution is based on pre-defined priorities assigned to the + // available echo cancellation modes. + DCHECK(ec_mode_allowed_values_.elements().size() > 1); + auto best_ec_type = ec_mode_allowed_values_.FirstElement(); + auto best_score = GetEcModeScore(best_ec_type); + for (const auto& type : ec_mode_allowed_values_.elements()) { + auto score = GetEcModeScore(type); + if (score > best_score) { + best_score = score; + best_ec_type = type; + } + } + return best_ec_type; + } + + // This function computes the fitness score of the given |ec_mode|. The + // fitness is determined by the ideal values of two constraints, namely + // |ec_type_constraint| and |ec_constraint|. For each constraint, a score of + // 0 is assigned if the ideal constraint cannot be satisfied, or 1 otherwise. + // If |ec_mode| satisfies both constraints, the fitness score results in a + // value of 2; if only one is satisfied, the result will be 1, and 0 when none + // of the ideal values are satisfied. + double Fitness(const EchoCancellationType& ec_mode, + const BooleanConstraint& ec_constraint, + const StringConstraint& ec_type_constraint) const { + double ec_fitness = + ec_constraint.HasIdeal() + ? ((ec_constraint.Ideal() && + ec_mode != EchoCancellationType::kEchoCancellationDisabled) || + (!ec_constraint.Ideal() && + ec_mode == EchoCancellationType::kEchoCancellationDisabled)) + : 1.0; + double ec_type_fitness = 0.0; + if (ec_type_constraint.HasIdeal()) { + for (auto ideal : ec_type_constraint.Ideal()) { + base::Optional<EchoCancellationType> ideal_type = + ToEchoCancellationType(ideal.Utf8().c_str()); + if (ideal_type && *ideal_type == ec_mode) + ec_type_fitness = 1.0; + } + } else { + ec_type_fitness = 1.0; + } + + return ec_fitness + ec_type_fitness; + } + + static base::Optional<bool> GetOverrideAec3() { base::Optional<bool> override_aec3; scoped_refptr<AecDumpMessageFilter> aec_dump_message_filter = AecDumpMessageFilter::Get(); if (aec_dump_message_filter) override_aec3 = aec_dump_message_filter->GetOverrideAec3(); - const bool use_aec3 = override_aec3.value_or( - base::FeatureList::IsEnabled(features::kWebRtcUseEchoCanceller3)); - auto ec_type = use_aec3 ? EchoCancellationType::kEchoCancellationAec3 - : EchoCancellationType::kEchoCancellationAec2; - return std::make_tuple(ec_type, fitness); + return override_aec3; } - base::Optional<std::string> ToBlinkEchoCancellationType( - EchoCancellationType type) const { - switch (type) { - case EchoCancellationType::kEchoCancellationAec2: - return blink::kEchoCancellationTypeBrowser; - case EchoCancellationType::kEchoCancellationAec3: - return blink::kEchoCancellationTypeAec3; - case EchoCancellationType::kEchoCancellationSystem: - return blink::kEchoCancellationTypeSystem; - case EchoCancellationType::kEchoCancellationDisabled: - return base::nullopt; + bool EchoCancellationModeContains(bool ec) const { + DCHECK(!ec_mode_allowed_values_.is_universal()); + + if (ec) { + return ec_mode_allowed_values_.Contains( + EchoCancellationType::kEchoCancellationAec2) || + ec_mode_allowed_values_.Contains( + EchoCancellationType::kEchoCancellationAec3) || + ec_mode_allowed_values_.Contains( + EchoCancellationType::kEchoCancellationSystem); + } + + return ec_mode_allowed_values_.Contains( + EchoCancellationType::kEchoCancellationDisabled); + } + + bool ShouldUseEchoCancellation( + const BooleanConstraint& ec_constraint, + const BooleanConstraint& goog_ec_constraint) const { + DCHECK(!ec_mode_allowed_values_.is_universal()); + + if (ec_constraint.HasIdeal() && + EchoCancellationModeContains(ec_constraint.Ideal())) + return ec_constraint.Ideal(); + + if (goog_ec_constraint.HasIdeal() && + EchoCancellationModeContains(goog_ec_constraint.Ideal())) + return goog_ec_constraint.Ideal(); + + // Echo cancellation is enabled by default for device capture and disabled + // by default for content capture. + if (EchoCancellationModeContains(true) && + EchoCancellationModeContains(false)) + return is_device_capture_; + + return EchoCancellationModeContains(true); + } + + BoolSet ec_allowed_values_; + EchoCancellationTypeSet ec_mode_allowed_values_; + media::AudioParameters device_parameters_; + bool is_device_capture_; +}; + +// This container represents the supported audio settings for a given type of +// audio source. In practice, there are three types of sources: processed using +// APM, processed without APM, and unprocessed. +class ProcessingBasedContainer { + public: + // Creates an instance of ProcessingBasedContainer for the WebRTC processed + // source type. The source type allows (a) any type of echo cancellation, + // though the system echo cancellation type depends on the availability of the + // related |parameters.effects()|, and (b) any combination of processing + // properties settings. + static ProcessingBasedContainer CreateApmProcessedContainer( + AudioProcessingProperties properties, + bool has_active_source, + bool is_device_capture, + media::AudioParameters parameters) { + return ProcessingBasedContainer( + ProcessingType::kApmProcessed, + {EchoCancellationType::kEchoCancellationAec2, + EchoCancellationType::kEchoCancellationAec3, + EchoCancellationType::kEchoCancellationDisabled}, + BoolSet(), /* goog_audio_mirroring_set */ + BoolSet(), /* goog_auto_gain_control_set */ + BoolSet(), /* goog_experimental_echo_cancellation_set */ + BoolSet(), /* goog_typing_noise_detection_set */ + BoolSet(), /* goog_noise_suppression_set */ + BoolSet(), /* goog_experimental_noise_suppression_set */ + BoolSet(), /* goog_highpass_filter_set */ + BoolSet(), /* goog_experimental_auto_gain_control_set */ + properties, has_active_source, is_device_capture, parameters); + } + + // Creates an instance of ProcessingBasedContainer for the processed source + // type. The source type allows (a) either system echo cancellation, if + // allowed by the |parameters.effects()|, or none, (b) enabled or disabled + // audio mirroring, while (c) all other processing properties settings cannot + // be enabled. + static ProcessingBasedContainer CreateNoApmProcessedContainer( + AudioProcessingProperties properties, + bool has_active_source, + bool is_device_capture, + media::AudioParameters parameters) { + return ProcessingBasedContainer( + ProcessingType::kNoApmProcessed, + {EchoCancellationType::kEchoCancellationDisabled}, + BoolSet(), /* goog_audio_mirroring_set */ + BoolSet({false}), /* goog_auto_gain_control_set */ + BoolSet({false}), /* goog_experimental_echo_cancellation_set */ + BoolSet({false}), /* goog_typing_noise_detection_set */ + BoolSet({false}), /* goog_noise_suppression_set */ + BoolSet({false}), /* goog_experimental_noise_suppression_set */ + BoolSet({false}), /* goog_highpass_filter_set */ + BoolSet({false}), /* goog_experimental_auto_gain_control_set */ + properties, has_active_source, is_device_capture, parameters); + } + + // Creates an instance of ProcessingBasedContainer for the unprocessed source + // type. The source type allows (a) either system echo cancellation, if + // allowed by the |parameters.effects()|, or none, while (c) all processing + // properties settings cannot be enabled. + static ProcessingBasedContainer CreateUnprocessedContainer( + AudioProcessingProperties properties, + bool has_active_source, + bool is_device_capture, + media::AudioParameters parameters) { + return ProcessingBasedContainer( + ProcessingType::kUnprocessed, + {EchoCancellationType::kEchoCancellationDisabled}, + BoolSet({false}), /* goog_audio_mirroring_set */ + BoolSet({false}), /* goog_auto_gain_control_set */ + BoolSet({false}), /* goog_experimental_echo_cancellation_set */ + BoolSet({false}), /* goog_typing_noise_detection_set */ + BoolSet({false}), /* goog_noise_suppression_set */ + BoolSet({false}), /* goog_experimental_noise_suppression_set */ + BoolSet({false}), /* goog_highpass_filter_set */ + BoolSet({false}), /* goog_experimental_auto_gain_control_set */ + properties, has_active_source, is_device_capture, parameters); + } + + const char* ApplyConstraintSet(const ConstraintSet& constraint_set) { + const char* failed_constraint_name = nullptr; + + failed_constraint_name = + echo_cancellation_container_->ApplyConstraintSet(constraint_set); + if (failed_constraint_name != nullptr) + return failed_constraint_name; + + for (auto& info : kBooleanPropertyContainerInfoMap) { + failed_constraint_name = + boolean_containers_[info.index].ApplyConstraintSet( + constraint_set.*(info.constraint_member)); + if (failed_constraint_name != nullptr) + return failed_constraint_name; + } + return failed_constraint_name; + } + + std::tuple<Score, AudioProcessingProperties> SelectSettingsAndScore( + const ConstraintSet& constraint_set, + bool should_disable_hardware_noise_suppression) const { + DCHECK(!IsEmpty()); + + Score score(0.0); + double sub_score(0.0); + + AudioProcessingProperties properties; + Score ec_score(0.0); + std::tie(ec_score, properties.echo_cancellation_type) = + echo_cancellation_container_->SelectSettingsAndScore(constraint_set); + score += ec_score; + + // Update the default settings for each audio-processing properties + // according to |echo_cancellation| and whether the source considered is + // device capture. + echo_cancellation_container_->UpdateDefaultValues( + constraint_set.echo_cancellation, &properties); + + for (size_t i = 0; i < kNumBooleanContainerIds; ++i) { + auto& info = kBooleanPropertyContainerInfoMap[i]; + std::tie(sub_score, properties.*(info.property_member)) = + boolean_containers_[info.index].SelectSettingsAndScore( + constraint_set.*(info.constraint_member), + properties.*(info.property_member)); + score += sub_score; + } + + score.set_processing_priority( + GetProcessingPriority(constraint_set.echo_cancellation)); + return std::make_tuple(score, properties); + } + + // The ProcessingBasedContainer is considered empty if at least one of the + // containers owned by it is empty. + bool IsEmpty() const { + DCHECK(!boolean_containers_.empty()); + + for (auto& container : boolean_containers_) { + if (container.IsEmpty()) + return true; + } + return echo_cancellation_container_->IsEmpty(); + } + + private: + enum BooleanContainerId { + kGoogAudioMirroring, + kGoogAutoGainControl, + kGoogExperimentalEchoCancellation, + kGoogTypingNoiseDetection, + kGoogNoiseSuppression, + kGoogExperimentalNoiseSuppression, + kGoogHighpassFilter, + kGoogExperimentalAutoGainControl, + kNumBooleanContainerIds + }; + + // This struct groups related fields or entries from + // AudioProcessingProperties, + // ProcessingBasedContainer::boolean_containers_, and + // blink::WebMediaTrackConstraintSet. + struct BooleanPropertyContainerInfo { + BooleanContainerId index; + BooleanConstraint ConstraintSet::*constraint_member; + bool AudioProcessingProperties::*property_member; + }; + + static constexpr BooleanPropertyContainerInfo + kBooleanPropertyContainerInfoMap[] = { + {kGoogAudioMirroring, &ConstraintSet::goog_audio_mirroring, + &AudioProcessingProperties::goog_audio_mirroring}, + {kGoogAutoGainControl, &ConstraintSet::goog_auto_gain_control, + &AudioProcessingProperties::goog_auto_gain_control}, + {kGoogExperimentalEchoCancellation, + &ConstraintSet::goog_experimental_echo_cancellation, + &AudioProcessingProperties::goog_experimental_echo_cancellation}, + {kGoogTypingNoiseDetection, + &ConstraintSet::goog_typing_noise_detection, + &AudioProcessingProperties::goog_typing_noise_detection}, + {kGoogNoiseSuppression, &ConstraintSet::goog_noise_suppression, + &AudioProcessingProperties::goog_noise_suppression}, + {kGoogExperimentalNoiseSuppression, + &ConstraintSet::goog_experimental_noise_suppression, + &AudioProcessingProperties::goog_experimental_noise_suppression}, + {kGoogHighpassFilter, &ConstraintSet::goog_highpass_filter, + &AudioProcessingProperties::goog_highpass_filter}, + {kGoogExperimentalAutoGainControl, + &ConstraintSet::goog_experimental_auto_gain_control, + &AudioProcessingProperties::goog_experimental_auto_gain_control}}; + + // Private constructor intended to instantiate different variants of this + // class based on the initial values provided. The appropriate way to + // instantiate this class is via the three factory methods provided. + // System echo cancellation should not be explicitly included in + // |echo_cancellation_type|. It is added automatically based on the value of + // |device_parameters|. + ProcessingBasedContainer( + ProcessingType processing_type, + std::vector<EchoCancellationType> echo_cancellation_types, + BoolSet goog_audio_mirroring_set, + BoolSet goog_auto_gain_control_set, + BoolSet goog_experimental_echo_cancellation_set, + BoolSet goog_typing_noise_detection_set, + BoolSet goog_noise_suppression_set, + BoolSet goog_experimental_noise_suppression_set, + BoolSet goog_highpass_filter_set, + BoolSet goog_experimental_auto_gain_control_set, + AudioProcessingProperties properties, + bool has_active_source, + bool is_device_capture, + media::AudioParameters device_parameters) + : processing_type_(processing_type) { + // If the parameters indicate that system echo cancellation is available, we + // add such value in the allowed values for the EC type. + if (device_parameters.effects() & media::AudioParameters::ECHO_CANCELLER || + device_parameters.effects() & + media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER) { + echo_cancellation_types.push_back( + EchoCancellationType::kEchoCancellationSystem); + } + echo_cancellation_container_ = EchoCancellationContainer( + echo_cancellation_types, has_active_source, is_device_capture, + device_parameters, properties); + + boolean_containers_[kGoogAudioMirroring] = + BooleanContainer(goog_audio_mirroring_set); + boolean_containers_[kGoogAutoGainControl] = + BooleanContainer(goog_auto_gain_control_set); + boolean_containers_[kGoogExperimentalEchoCancellation] = + BooleanContainer(goog_experimental_echo_cancellation_set); + boolean_containers_[kGoogTypingNoiseDetection] = + BooleanContainer(goog_typing_noise_detection_set); + boolean_containers_[kGoogNoiseSuppression] = + BooleanContainer(goog_noise_suppression_set); + boolean_containers_[kGoogExperimentalNoiseSuppression] = + BooleanContainer(goog_experimental_noise_suppression_set); + boolean_containers_[kGoogHighpassFilter] = + BooleanContainer(goog_highpass_filter_set); + boolean_containers_[kGoogExperimentalAutoGainControl] = + BooleanContainer(goog_experimental_auto_gain_control_set); + + if (!has_active_source) + return; + + for (size_t i = 0; i < kNumBooleanContainerIds; ++i) { + auto& info = kBooleanPropertyContainerInfoMap[i]; + boolean_containers_[info.index] = + BooleanContainer(BoolSet({properties.*(info.property_member)})); } } - DiscreteSet<bool> ec_allowed_values_; - DiscreteSet<bool> goog_ec_allowed_values_; - DiscreteSet<std::string> ec_type_allowed_values_; - media::AudioParameters parameters_; - bool is_device_capture_; + // The priority of each processing-based container depends on the default + // value assigned to the audio processing properties. When the value is true + // the preference gives higher priority to the WebRTC processing. + // On the contrary, if the value is false the preference is flipped towards + // the option without processing. + int GetProcessingPriority(const BooleanConstraint& ec_constraint) const { + bool use_processing_by_default = + echo_cancellation_container_->GetDefaultValueForAudioProperties( + ec_constraint); + + switch (processing_type_) { + case ProcessingType::kUnprocessed: + return use_processing_by_default ? 1 : 3; + case ProcessingType::kNoApmProcessed: + return 2; + case ProcessingType::kApmProcessed: + return use_processing_by_default ? 3 : 1; + } + } + + ProcessingType processing_type_; + std::array<BooleanContainer, kNumBooleanContainerIds> boolean_containers_; + base::Optional<EchoCancellationContainer> echo_cancellation_container_; }; +constexpr ProcessingBasedContainer::BooleanPropertyContainerInfo + ProcessingBasedContainer::kBooleanPropertyContainerInfoMap[]; + // Container for the constrainable properties of a single audio device. class DeviceContainer { public: DeviceContainer(const AudioDeviceCaptureCapability& capability, bool is_device_capture) - : parameters_(capability.Parameters()) { + : device_parameters_(capability.Parameters()) { if (!capability.DeviceID().empty()) device_id_container_ = - StringContainer(DiscreteSet<std::string>({capability.DeviceID()})); + StringContainer(StringSet({capability.DeviceID()})); if (!capability.GroupID().empty()) - group_id_container_ = - StringContainer(DiscreteSet<std::string>({capability.GroupID()})); + group_id_container_ = StringContainer(StringSet({capability.GroupID()})); // If the device is in use, a source will be provided and all containers // must be initialized such that their only supported values correspond to @@ -446,32 +805,54 @@ // all possible values. SourceType source_type; AudioProcessingProperties properties; - std::tie(source_type, properties) = InfoFromSource(capability.source()); + std::tie(source_type, properties) = + InfoFromSource(capability.source(), device_parameters_.effects()); - echo_cancellation_container_ = EchoCancellationContainer( - source_type, is_device_capture, parameters_, properties); + // Three variations of the processing-based container. Each variant is + // associated to a different type of audio processing configuration, namely + // unprocessed, processed by WebRTC, or processed by other means. + if (source_type == SourceType::kNone || + source_type == SourceType::kUnprocessed) { + processing_based_containers_.push_back( + ProcessingBasedContainer::CreateUnprocessedContainer( + properties, source_type != SourceType::kNone, is_device_capture, + device_parameters_)); + } + if (source_type == SourceType::kNone || + source_type == SourceType::kNoApmProcessed) { + processing_based_containers_.push_back( + ProcessingBasedContainer::CreateNoApmProcessedContainer( + properties, source_type != SourceType::kNone, is_device_capture, + device_parameters_)); + } + if (source_type == SourceType::kNone || + source_type == SourceType::kApmProcessed) { + processing_based_containers_.push_back( + ProcessingBasedContainer::CreateApmProcessedContainer( + properties, source_type != SourceType::kNone, is_device_capture, + device_parameters_)); + } - if (source_type == SourceType::kNoSource) +#if DCHECK_IS_ON() + if (source_type == SourceType::kNone) + DCHECK(processing_based_containers_.size() == 3); + else + DCHECK(processing_based_containers_.size() == 1); +#endif + + if (source_type == SourceType::kNone) return; MediaStreamAudioSource* source = capability.source(); boolean_containers_[kHotwordEnabled] = - BooleanContainer(DiscreteSet<bool>({source->hotword_enabled()})); + BooleanContainer(BoolSet({source->hotword_enabled()})); boolean_containers_[kDisableLocalEcho] = - BooleanContainer(DiscreteSet<bool>({source->disable_local_echo()})); + BooleanContainer(BoolSet({source->disable_local_echo()})); - boolean_containers_[kRenderToAssociatedSink] = BooleanContainer( - DiscreteSet<bool>({source->RenderToAssociatedSinkEnabled()})); + boolean_containers_[kRenderToAssociatedSink] = + BooleanContainer(BoolSet({source->RenderToAssociatedSinkEnabled()})); - for (size_t i = kGoogAudioMirroring; i < kNumBooleanContainerIds; ++i) { - auto& info = kBooleanPropertyContainerInfoMap[i]; - boolean_containers_[info.index] = BooleanContainer( - DiscreteSet<bool>({properties.*(info.property_member)})); - } - - DCHECK(echo_cancellation_container_ != base::nullopt); - DCHECK_EQ(boolean_containers_.size(), kNumBooleanContainerIds); #if DCHECK_IS_ON() for (const auto& container : boolean_containers_) DCHECK(!container.IsEmpty()); @@ -500,21 +881,32 @@ return failed_constraint_name; } - failed_constraint_name = - echo_cancellation_container_->ApplyConstraintSet(constraint_set); - if (failed_constraint_name != nullptr) + // For each processing based container, apply the constraints and only fail + // if all of them failed. + for (auto it = processing_based_containers_.begin(); + it != processing_based_containers_.end();) { + DCHECK(!it->IsEmpty()); + failed_constraint_name = it->ApplyConstraintSet(constraint_set); + if (failed_constraint_name != nullptr) + processing_based_containers_.erase(it); + else + ++it; + } + if (processing_based_containers_.empty()) { + DCHECK_NE(failed_constraint_name, nullptr); return failed_constraint_name; + } return nullptr; } - std::tuple<double, AudioCaptureSettings> SelectSettingsAndScore( + std::tuple<Score, AudioCaptureSettings> SelectSettingsAndScore( const ConstraintSet& constraint_set, bool is_destkop_source, bool should_disable_hardware_noise_suppression, std::string default_device_id) const { DCHECK(!IsEmpty()); - double score = 0.0; + Score score(0.0); double sub_score = 0.0; std::string device_id; @@ -546,32 +938,37 @@ constraint_set.render_to_associated_sink, false); score += sub_score; - AudioProcessingProperties properties; - std::tie(sub_score, properties.echo_cancellation_type) = - echo_cancellation_container_->SelectSettingsAndScore(constraint_set); - score += sub_score; + // To determine which properties to use, we have to compare and compute the + // scores of each properties set and use the best performing one. In this + // loop we are also determining the best settings that should be applied to + // the best performing candidate. + Score best_score(-1.0); + AudioProcessingProperties best_properties; + const ProcessingBasedContainer* best_container = nullptr; + for (const auto& container : processing_based_containers_) { + if (container.IsEmpty()) + continue; - // NOTE: audio-processing properties are disabled by default for content - // capture, or if the |echo_cancellation| constraint is false. This function - // call updates the default settings for such properties according to the - // value obtained for the echo cancellation property. - echo_cancellation_container_->UpdateDefaultValues( - constraint_set.echo_cancellation, &properties); - - for (size_t i = kGoogAudioMirroring; i < kNumBooleanContainerIds; ++i) { - auto& info = kBooleanPropertyContainerInfoMap[i]; - std::tie(sub_score, properties.*(info.property_member)) = - boolean_containers_[info.index].SelectSettingsAndScore( - constraint_set.*(info.constraint_member), - properties.*(info.property_member)); - score += sub_score; + Score container_score(0.0); + AudioProcessingProperties container_properties; + std::tie(container_score, container_properties) = + container.SelectSettingsAndScore( + constraint_set, should_disable_hardware_noise_suppression); + if (container_score > best_score) { + best_score = container_score; + best_properties = container_properties; + best_container = &container; + } } - // NOTE: this is a special case required to support for conditional - // constraint for echo cancellation type based on an experiment. - properties.disable_hw_noise_suppression = + DCHECK_NE(best_container, nullptr); + score += best_score; + + // Update |properties.disable_hw_noise_suppression| depending on a related + // experiment that can force-disable HW noise suppression. + best_properties.disable_hw_noise_suppression = should_disable_hardware_noise_suppression && - properties.echo_cancellation_type == + best_properties.echo_cancellation_type == EchoCancellationType::kEchoCancellationDisabled; // The score at this point can be considered complete only when the settings @@ -580,7 +977,7 @@ return std::make_tuple( score, AudioCaptureSettings(device_id, hotword_enabled, disable_local_echo, - render_to_associated_sink, properties)); + render_to_associated_sink, best_properties)); } // The DeviceContainer is considered empty if at least one of the @@ -593,89 +990,71 @@ return true; } - return device_id_container_.IsEmpty() || group_id_container_.IsEmpty() || - echo_cancellation_container_->IsEmpty(); + return device_id_container_.IsEmpty() || group_id_container_.IsEmpty(); } - std::tuple<SourceType, AudioProcessingProperties> InfoFromSource( - MediaStreamAudioSource* source) { - AudioProcessingProperties properties; + private: + enum BooleanContainerId { + kHotwordEnabled, + kDisableLocalEcho, + kRenderToAssociatedSink, + kNumBooleanContainerIds + }; + + // This struct groups related fields or entries from + // DeviceContainer::boolean_containers_ and blink::WebMediaTrackConstraintSet. + struct BooleanPropertyContainerInfo { + BooleanContainerId index; + BooleanConstraint ConstraintSet::*constraint_member; + }; + + static constexpr BooleanPropertyContainerInfo + kBooleanPropertyContainerInfoMap[] = { + {kHotwordEnabled, &ConstraintSet::hotword_enabled}, + {kDisableLocalEcho, &ConstraintSet::disable_local_echo}, + {kRenderToAssociatedSink, &ConstraintSet::render_to_associated_sink}}; + + // Utility function to determine which version of this class should be + // allocated depending on the |source| provided. This function returns the + // Type of this instance, a copy of the AudioProcessingProperties related, and + // whether processing is enabled or not. + static std::tuple<SourceType, AudioProcessingProperties> InfoFromSource( + MediaStreamAudioSource* source, + int effects) { SourceType source_type; + AudioProcessingProperties properties; ProcessedLocalAudioSource* processed_source = ProcessedLocalAudioSource::From(source); + if (source == nullptr) { - source_type = SourceType::kNoSource; + source_type = SourceType::kNone; } else if (processed_source == nullptr) { - source_type = SourceType::kUnprocessedSource; + source_type = SourceType::kUnprocessed; properties.DisableDefaultProperties(); + + // It is possible, however, that the HW echo canceller is enabled. In such + // case the property for echo cancellation type should be updated + // accordingly. + if (effects & media::AudioParameters::ECHO_CANCELLER || + effects & media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER) { + properties.echo_cancellation_type = + EchoCancellationType::kEchoCancellationSystem; + } } else { - source_type = SourceType::kProcessedSource; + source_type = properties.EchoCancellationIsWebRtcProvided() + ? SourceType::kApmProcessed + : SourceType::kNoApmProcessed; properties = processed_source->audio_processing_properties(); } return std::make_tuple(source_type, properties); } - private: - enum StringContainerId { kDeviceId, kGroupId, kNumStringContainerIds }; - - enum BooleanContainerId { - kHotwordEnabled, - kDisableLocalEcho, - kRenderToAssociatedSink, - // Audio processing properties indexes. - kGoogAudioMirroring, - kGoogAutoGainControl, - kGoogExperimentalEchoCancellation, - kGoogTypingNoiseDetection, - kGoogNoiseSuppression, - kGoogExperimentalNoiseSuppression, - kGoogHighpassFilter, - kGoogExperimentalAutoGainControl, - kNumBooleanContainerIds - }; - - // This struct groups related fields or entries from - // AudioProcessingProperties, - // SingleDeviceCandidateSet::bool_sets_ and blink::WebMediaTrackConstraintSet. - struct BooleanPropertyContainerInfo { - BooleanContainerId index; - BooleanConstraint ConstraintSet::*constraint_member; - bool AudioProcessingProperties::*property_member; - }; - - static constexpr BooleanPropertyContainerInfo - kBooleanPropertyContainerInfoMap[] = { - {kHotwordEnabled, &ConstraintSet::hotword_enabled, nullptr}, - {kDisableLocalEcho, &ConstraintSet::disable_local_echo, nullptr}, - {kRenderToAssociatedSink, &ConstraintSet::render_to_associated_sink, - nullptr}, - {kGoogAudioMirroring, &ConstraintSet::goog_audio_mirroring, - &AudioProcessingProperties::goog_audio_mirroring}, - {kGoogAutoGainControl, &ConstraintSet::goog_auto_gain_control, - &AudioProcessingProperties::goog_auto_gain_control}, - {kGoogExperimentalEchoCancellation, - &ConstraintSet::goog_experimental_echo_cancellation, - &AudioProcessingProperties::goog_experimental_echo_cancellation}, - {kGoogTypingNoiseDetection, - &ConstraintSet::goog_typing_noise_detection, - &AudioProcessingProperties::goog_typing_noise_detection}, - {kGoogNoiseSuppression, &ConstraintSet::goog_noise_suppression, - &AudioProcessingProperties::goog_noise_suppression}, - {kGoogExperimentalNoiseSuppression, - &ConstraintSet::goog_experimental_noise_suppression, - &AudioProcessingProperties::goog_experimental_noise_suppression}, - {kGoogHighpassFilter, &ConstraintSet::goog_highpass_filter, - &AudioProcessingProperties::goog_highpass_filter}, - {kGoogExperimentalAutoGainControl, - &ConstraintSet::goog_experimental_auto_gain_control, - &AudioProcessingProperties::goog_experimental_auto_gain_control}}; - - media::AudioParameters parameters_; + media::AudioParameters device_parameters_; StringContainer device_id_container_; StringContainer group_id_container_; std::array<BooleanContainer, kNumBooleanContainerIds> boolean_containers_; - base::Optional<EchoCancellationContainer> echo_cancellation_container_; + std::vector<ProcessingBasedContainer> processing_based_containers_; }; constexpr DeviceContainer::BooleanPropertyContainerInfo @@ -729,14 +1108,14 @@ AudioCaptureSettings best_settings; Score best_score(-1.0); for (const auto& candidate : devices_) { - double fitness; + Score score(0.0); AudioCaptureSettings settings; - std::tie(fitness, settings) = candidate.SelectSettingsAndScore( + std::tie(score, settings) = candidate.SelectSettingsAndScore( constraint_set, is_desktop_source, should_disable_hardware_noise_suppression, default_device_id_); - Score score(fitness, default_device_id_ == settings.device_id()); - if (best_score < score) { + score += default_device_id_ == settings.device_id(); + if (score > best_score) { best_score = score; best_settings = std::move(settings); }
diff --git a/content/renderer/media/stream/media_stream_types.h b/content/renderer/media/stream/media_stream_types.h new file mode 100644 index 0000000..26ce3c2 --- /dev/null +++ b/content/renderer/media/stream/media_stream_types.h
@@ -0,0 +1,15 @@ +// Copyright 2018 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 CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_TYPES_H_ +#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_TYPES_H_ + +namespace content { + +using VideoTrackSettingsCallback = + base::RepeatingCallback<void(int width, int height)>; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_TYPES_H_
diff --git a/content/renderer/media/stream/media_stream_video_source.cc b/content/renderer/media/stream/media_stream_video_source.cc index 99302a1..d4e3b1f 100644 --- a/content/renderer/media/stream/media_stream_video_source.cc +++ b/content/renderer/media/stream/media_stream_video_source.cc
@@ -48,6 +48,7 @@ MediaStreamVideoTrack* track, const VideoTrackAdapterSettings& track_adapter_settings, const VideoCaptureDeliverFrameCB& frame_callback, + const VideoTrackSettingsCallback& settings_callback, const ConstraintsCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!base::ContainsValue(tracks_, track)); @@ -55,7 +56,7 @@ secure_tracker_.Add(track, true); pending_tracks_.push_back(PendingTrackInfo( - track, frame_callback, + track, frame_callback, settings_callback, std::make_unique<VideoTrackAdapterSettings>(track_adapter_settings), callback)); @@ -366,6 +367,7 @@ if (result == MEDIA_DEVICE_OK) { track_adapter_->AddTrack(track_info.track, track_info.frame_callback, + track_info.settings_callback, *track_info.adapter_settings); UpdateTrackSettings(track_info.track, *track_info.adapter_settings); } @@ -431,10 +433,12 @@ MediaStreamVideoSource::PendingTrackInfo::PendingTrackInfo( MediaStreamVideoTrack* track, const VideoCaptureDeliverFrameCB& frame_callback, + const VideoTrackSettingsCallback& settings_callback, std::unique_ptr<VideoTrackAdapterSettings> adapter_settings, const ConstraintsCallback& callback) : track(track), frame_callback(frame_callback), + settings_callback(settings_callback), adapter_settings(std::move(adapter_settings)), callback(callback) {}
diff --git a/content/renderer/media/stream/media_stream_video_source.h b/content/renderer/media/stream/media_stream_video_source.h index 6213aa20..2c130f3b 100644 --- a/content/renderer/media/stream/media_stream_video_source.h +++ b/content/renderer/media/stream/media_stream_video_source.h
@@ -16,6 +16,7 @@ #include "content/common/content_export.h" #include "content/common/media/video_capture.h" #include "content/renderer/media/stream/media_stream_source.h" +#include "content/renderer/media/stream/media_stream_types.h" #include "content/renderer/media/stream/secure_display_link_tracker.h" #include "media/base/video_frame.h" #include "media/capture/video_capture_types.h" @@ -68,6 +69,7 @@ void AddTrack(MediaStreamVideoTrack* track, const VideoTrackAdapterSettings& track_adapter_settings, const VideoCaptureDeliverFrameCB& frame_callback, + const VideoTrackSettingsCallback& settings_callback, const ConstraintsCallback& callback); void RemoveTrack(MediaStreamVideoTrack* track, base::OnceClosure callback); @@ -269,6 +271,7 @@ PendingTrackInfo( MediaStreamVideoTrack* track, const VideoCaptureDeliverFrameCB& frame_callback, + const VideoTrackSettingsCallback& settings_callback, std::unique_ptr<VideoTrackAdapterSettings> adapter_settings, const ConstraintsCallback& callback); PendingTrackInfo(PendingTrackInfo&& other); @@ -277,6 +280,7 @@ MediaStreamVideoTrack* track; VideoCaptureDeliverFrameCB frame_callback; + VideoTrackSettingsCallback settings_callback; // TODO(guidou): Make |adapter_settings| a regular field instead of a // unique_ptr. std::unique_ptr<VideoTrackAdapterSettings> adapter_settings;
diff --git a/content/renderer/media/stream/media_stream_video_track.cc b/content/renderer/media/stream/media_stream_video_track.cc index 4969312..bf5bca7 100644 --- a/content/renderer/media/stream/media_stream_video_track.cc +++ b/content/renderer/media/stream/media_stream_video_track.cc
@@ -15,6 +15,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/renderer/media/stream/media_stream_constraints_util_video_device.h" +#include "media/base/bind_to_current_loop.h" #include "media/capture/video_capture_types.h" namespace content { @@ -260,11 +261,14 @@ adapter_settings_(std::make_unique<VideoTrackAdapterSettings>( VideoTrackAdapterSettings())), is_screencast_(false), - source_(source->GetWeakPtr()) { + source_(source->GetWeakPtr()), + weak_factory_(this) { source->AddTrack( this, VideoTrackAdapterSettings(), base::Bind(&MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO, frame_deliverer_), + media::BindToCurrentLoop(base::BindRepeating( + &MediaStreamVideoTrack::SetSize, weak_factory_.GetWeakPtr())), callback); } @@ -285,11 +289,14 @@ noise_reduction_(noise_reduction), is_screencast_(is_screen_cast), min_frame_rate_(min_frame_rate), - source_(source->GetWeakPtr()) { + source_(source->GetWeakPtr()), + weak_factory_(this) { source->AddTrack( this, adapter_settings, base::Bind(&MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO, frame_deliverer_), + media::BindToCurrentLoop(base::BindRepeating( + &MediaStreamVideoTrack::SetSize, weak_factory_.GetWeakPtr())), callback); }
diff --git a/content/renderer/media/stream/media_stream_video_track.h b/content/renderer/media/stream/media_stream_video_track.h index ad09c365..5760506 100644 --- a/content/renderer/media/stream/media_stream_video_track.h +++ b/content/renderer/media/stream/media_stream_video_track.h
@@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "content/common/content_export.h" #include "content/public/renderer/media_stream_video_sink.h" @@ -106,6 +107,14 @@ frame_rate_ = frame_rate; } + // Setting information about the track size. + // Passed as callback on MediaStreamVideoTrack::AddTrack, and called from + // VideoFrameResolutionAdapter on frame delivery to update track settings. + void SetSize(int width, int height) { + width_ = width; + height_ = height; + } + void SetTrackAdapterSettings(const VideoTrackAdapterSettings& settings); MediaStreamVideoSource* source() const { return source_.get(); } @@ -156,6 +165,8 @@ int height_ = 0; double frame_rate_ = 0.0; + base::WeakPtrFactory<MediaStreamVideoTrack> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoTrack); };
diff --git a/content/renderer/media/stream/media_stream_video_track_unittest.cc b/content/renderer/media/stream/media_stream_video_track_unittest.cc index 8dd3361..01ba95c 100644 --- a/content/renderer/media/stream/media_stream_video_track_unittest.cc +++ b/content/renderer/media/stream/media_stream_video_track_unittest.cc
@@ -48,18 +48,25 @@ blink::WebHeap::CollectAllGarbageForTesting(); } - void DeliverVideoFrameAndWaitForRenderer(MockMediaStreamVideoSink* sink) { + void DeliverVideoFrameAndWaitForRenderer( + const scoped_refptr<media::VideoFrame>& frame, + MockMediaStreamVideoSink* sink) { base::RunLoop run_loop; base::Closure quit_closure = run_loop.QuitClosure(); EXPECT_CALL(*sink, OnVideoFrame()) .WillOnce(RunClosure(std::move(quit_closure))); + mock_source()->DeliverVideoFrame(frame); + run_loop.Run(); + } + + void DeliverDefaultSizeVideoFrameAndWaitForRenderer( + MockMediaStreamVideoSink* sink) { const scoped_refptr<media::VideoFrame> frame = media::VideoFrame::CreateColorFrame( gfx::Size(MediaStreamVideoSource::kDefaultWidth, MediaStreamVideoSource::kDefaultHeight), kColorValue, kColorValue, kColorValue, base::TimeDelta()); - mock_source()->DeliverVideoFrame(frame); - run_loop.Run(); + DeliverVideoFrameAndWaitForRenderer(frame, sink); } protected: @@ -140,10 +147,10 @@ blink::WebMediaStreamTrack track = CreateTrack(); sink.ConnectToTrack(track); - DeliverVideoFrameAndWaitForRenderer(&sink); + DeliverDefaultSizeVideoFrameAndWaitForRenderer(&sink); EXPECT_EQ(1, sink.number_of_frames()); - DeliverVideoFrameAndWaitForRenderer(&sink); + DeliverDefaultSizeVideoFrameAndWaitForRenderer(&sink); sink.DisconnectFromTrack(); @@ -209,20 +216,20 @@ MediaStreamVideoTrack* video_track = MediaStreamVideoTrack::GetVideoTrack(track); - DeliverVideoFrameAndWaitForRenderer(&sink); + DeliverDefaultSizeVideoFrameAndWaitForRenderer(&sink); EXPECT_EQ(1, sink.number_of_frames()); EXPECT_EQ(kColorValue, *sink.last_frame()->data(media::VideoFrame::kYPlane)); video_track->SetEnabled(false); EXPECT_FALSE(sink.enabled()); - DeliverVideoFrameAndWaitForRenderer(&sink); + DeliverDefaultSizeVideoFrameAndWaitForRenderer(&sink); EXPECT_EQ(2, sink.number_of_frames()); EXPECT_EQ(kBlackValue, *sink.last_frame()->data(media::VideoFrame::kYPlane)); video_track->SetEnabled(true); EXPECT_TRUE(sink.enabled()); - DeliverVideoFrameAndWaitForRenderer(&sink); + DeliverDefaultSizeVideoFrameAndWaitForRenderer(&sink); EXPECT_EQ(3, sink.number_of_frames()); EXPECT_EQ(kColorValue, *sink.last_frame()->data(media::VideoFrame::kYPlane)); sink.DisconnectFromTrack(); @@ -341,4 +348,30 @@ EXPECT_TRUE(settings.device_id.IsNull()); } +TEST_F(MediaStreamVideoTrackTest, DeliverFramesAndGetSettings) { + InitializeSource(); + MockMediaStreamVideoSink sink; + blink::WebMediaStreamTrack track = CreateTrack(); + sink.ConnectToTrack(track); + MediaStreamVideoTrack* const native_track = + MediaStreamVideoTrack::GetVideoTrack(track); + blink::WebMediaStreamTrack::Settings settings; + + const scoped_refptr<media::VideoFrame>& frame1 = + media::VideoFrame::CreateBlackFrame(gfx::Size(600, 400)); + DeliverVideoFrameAndWaitForRenderer(frame1, &sink); + native_track->GetSettings(settings); + EXPECT_EQ(600, settings.width); + EXPECT_EQ(400, settings.height); + + const scoped_refptr<media::VideoFrame>& frame2 = + media::VideoFrame::CreateBlackFrame(gfx::Size(200, 300)); + DeliverVideoFrameAndWaitForRenderer(frame2, &sink); + native_track->GetSettings(settings); + EXPECT_EQ(200, settings.width); + EXPECT_EQ(300, settings.height); + + sink.DisconnectFromTrack(); +} + } // namespace content
diff --git a/content/renderer/media/stream/video_track_adapter.cc b/content/renderer/media/stream/video_track_adapter.cc index cfbe218..29de609 100644 --- a/content/renderer/media/stream/video_track_adapter.cc +++ b/content/renderer/media/stream/video_track_adapter.cc
@@ -13,6 +13,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/containers/flat_map.h" #include "base/location.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" @@ -47,11 +48,6 @@ // The reference to |frame| is kept in the closure that calls this method. void TrackReleaseOriginalFrame(const scoped_refptr<media::VideoFrame>& frame) {} -void ResetCallbackOnMainRenderThread( - std::unique_ptr<VideoCaptureDeliverFrameCB> callback) { - // |callback| will be deleted when this exits. -} - int ClampToValidDimension(int dimension) { return std::min(static_cast<int>(media::limits::kMaxDimension), std::max(0, dimension)); @@ -65,29 +61,32 @@ class VideoTrackAdapter::VideoFrameResolutionAdapter : public base::RefCountedThreadSafe<VideoFrameResolutionAdapter> { public: + struct VideoTrackCallbacks { + VideoCaptureDeliverFrameCB frame_callback; + VideoTrackSettingsCallback settings_callback; + }; // Setting |max_frame_rate| to 0.0, means that no frame rate limitation // will be done. VideoFrameResolutionAdapter( scoped_refptr<base::SingleThreadTaskRunner> render_message_loop, const VideoTrackAdapterSettings& settings); - // Add |callback| to receive video frames on the IO-thread. - // |callback| will however be released on the main render thread. - void AddCallback(const MediaStreamVideoTrack* track, - const VideoCaptureDeliverFrameCB& callback); + // Add |frame_callback| to receive video frames on the IO-thread and + // |settings_callback| to set track settings on the main thread. + // |frame_callback| will however be released on the main render thread. + void AddCallbacks(const MediaStreamVideoTrack* track, + VideoCaptureDeliverFrameCB frame_callback, + VideoTrackSettingsCallback settings_callback); - // Removes the callback associated with |track| from receiving video frames if - // |track| has been added. It is ok to call RemoveAndReleaseCallback() even if - // |track| has not been added. The callback is released on the main render - // thread. - void RemoveAndReleaseCallback(const MediaStreamVideoTrack* track); + // Removes the callbacks associated with |track| if |track| has been added. It + // is ok to call RemoveCallbacks() even if |track| has not been added. + void RemoveCallbacks(const MediaStreamVideoTrack* track); - // Removes the callback associated with |track| from receiving video frames if - // |track| has been added. It is ok to call RemoveAndGetCallback() even if the - // |track| has not been added. The functions returns the callback if it was - // removed, or a null pointer if |track| was not present in the adapter. - std::unique_ptr<VideoCaptureDeliverFrameCB> RemoveAndGetCallback( - const MediaStreamVideoTrack* track); + // Removes the callbacks associated with |track| if |track| has been added. It + // is ok to call RemoveAndGetCallbacks() even if the |track| has not been + // added. The function returns the callbacks if it was removed, or empty + // callbacks if |track| was not present in the adapter. + VideoTrackCallbacks RemoveAndGetCallbacks(const MediaStreamVideoTrack* track); void DeliverFrame(const scoped_refptr<media::VideoFrame>& frame, const base::TimeTicks& estimated_capture_time, @@ -110,21 +109,27 @@ bool MaybeDropFrame(const scoped_refptr<media::VideoFrame>& frame, float source_frame_rate); + // Calls |settings_callback| to update track settings if either frame width or + // height has changed since last update. + void MaybeUpdateTrackSettings( + const VideoTrackSettingsCallback& settings_callback, + const scoped_refptr<media::VideoFrame>& frame); + // Bound to the IO-thread. THREAD_CHECKER(io_thread_checker_); // The task runner where we will release VideoCaptureDeliverFrameCB - // registered in AddCallback. + // registered in AddCallbacks. const scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_; VideoTrackAdapterSettings settings_; double frame_rate_; + gfx::Size frame_size_; + base::TimeDelta last_time_stamp_; double keep_frame_counter_; - using VideoIdCallbackPair = - std::pair<const MediaStreamVideoTrack*, VideoCaptureDeliverFrameCB>; - std::vector<VideoIdCallbackPair> callbacks_; + base::flat_map<const MediaStreamVideoTrack*, VideoTrackCallbacks> callbacks_; DISALLOW_COPY_AND_ASSIGN(VideoFrameResolutionAdapter); }; @@ -162,50 +167,33 @@ DCHECK(callbacks_.empty()); } -void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallback( +void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallbacks( const MediaStreamVideoTrack* track, - const VideoCaptureDeliverFrameCB& callback) { + VideoCaptureDeliverFrameCB frame_callback, + VideoTrackSettingsCallback settings_callback) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); - callbacks_.push_back(std::make_pair(track, callback)); + callbacks_.insert( + {track, {std::move(frame_callback), std::move(settings_callback)}}); } -void VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveAndReleaseCallback( +void VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveCallbacks( const MediaStreamVideoTrack* track) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); - auto it = callbacks_.begin(); - for (; it != callbacks_.end(); ++it) { - if (it->first == track) { - // Make sure the VideoCaptureDeliverFrameCB is released on the main - // render thread since it was added on the main render thread in - // VideoTrackAdapter::AddTrack. - std::unique_ptr<VideoCaptureDeliverFrameCB> callback( - new VideoCaptureDeliverFrameCB(it->second)); - callbacks_.erase(it); - renderer_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&ResetCallbackOnMainRenderThread, - std::move(callback))); - - return; - } - } + callbacks_.erase(track); } -std::unique_ptr<VideoCaptureDeliverFrameCB> -VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveAndGetCallback( +VideoTrackAdapter::VideoFrameResolutionAdapter::VideoTrackCallbacks +VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveAndGetCallbacks( const MediaStreamVideoTrack* track) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); - std::unique_ptr<VideoCaptureDeliverFrameCB> ret; - for (auto it = callbacks_.begin(); it != callbacks_.end(); ++it) { - if (it->first == track) { - // Make sure the VideoCaptureDeliverFrameCB is released on the main - // render thread since it was added on the main render thread in - // VideoTrackAdapter::AddTrack. - ret = std::make_unique<VideoCaptureDeliverFrameCB>(it->second); - callbacks_.erase(it); - break; - } - } - return ret; + VideoTrackCallbacks track_callbacks; + auto it = callbacks_.find(track); + if (it == callbacks_.end()) + return track_callbacks; + + track_callbacks = it->second; + callbacks_.erase(it); + return track_callbacks; } void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( @@ -278,8 +266,10 @@ const scoped_refptr<media::VideoFrame>& frame, const base::TimeTicks& estimated_capture_time) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); - for (const auto& callback : callbacks_) - callback.second.Run(frame, estimated_capture_time); + for (const auto& callback : callbacks_) { + MaybeUpdateTrackSettings(callback.second.settings_callback, frame); + callback.second.frame_callback.Run(frame, estimated_capture_time); + } } bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( @@ -341,6 +331,16 @@ return true; } +void VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeUpdateTrackSettings( + const VideoTrackSettingsCallback& settings_callback, + const scoped_refptr<media::VideoFrame>& frame) { + DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); + if (frame->natural_size() != frame_size_) { + frame_size_ = frame->natural_size(); + settings_callback.Run(frame_size_.width(), frame_size_.height()); + } +} + VideoTrackAdapterSettings::VideoTrackAdapterSettings() : VideoTrackAdapterSettings(base::nullopt, 0.0, @@ -401,17 +401,20 @@ void VideoTrackAdapter::AddTrack(const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, + VideoTrackSettingsCallback settings_callback, const VideoTrackAdapterSettings& settings) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); io_task_runner_->PostTask( FROM_HERE, base::BindOnce(&VideoTrackAdapter::AddTrackOnIO, this, track, - std::move(frame_callback), settings)); + std::move(frame_callback), + std::move(settings_callback), settings)); } void VideoTrackAdapter::AddTrackOnIO( const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, + VideoTrackSettingsCallback settings_callback, const VideoTrackAdapterSettings& settings) { DCHECK(io_task_runner_->BelongsToCurrentThread()); scoped_refptr<VideoFrameResolutionAdapter> adapter; @@ -426,7 +429,8 @@ adapters_.push_back(adapter); } - adapter->AddCallback(track, std::move(frame_callback)); + adapter->AddCallbacks(track, std::move(frame_callback), + std::move(settings_callback)); } void VideoTrackAdapter::RemoveTrack(const MediaStreamVideoTrack* track) { @@ -572,7 +576,7 @@ void VideoTrackAdapter::RemoveTrackOnIO(const MediaStreamVideoTrack* track) { DCHECK(io_task_runner_->BelongsToCurrentThread()); for (auto it = adapters_.begin(); it != adapters_.end(); ++it) { - (*it)->RemoveAndReleaseCallback(track); + (*it)->RemoveCallbacks(track); if ((*it)->IsEmpty()) { adapters_.erase(it); break; @@ -585,20 +589,21 @@ const VideoTrackAdapterSettings& settings) { DCHECK(io_task_runner_->BelongsToCurrentThread()); - std::unique_ptr<VideoCaptureDeliverFrameCB> track_frame_callback; + VideoFrameResolutionAdapter::VideoTrackCallbacks track_callbacks; // Remove the track. for (auto it = adapters_.begin(); it != adapters_.end(); ++it) { - track_frame_callback = (*it)->RemoveAndGetCallback(track); + track_callbacks = (*it)->RemoveAndGetCallbacks(track); if ((*it)->IsEmpty()) { - DCHECK(track_frame_callback); + DCHECK(!track_callbacks.frame_callback.is_null()); adapters_.erase(it); break; } } // If the track was found, re-add it with new settings. - if (track_frame_callback) - AddTrackOnIO(track, std::move(*track_frame_callback), settings); + if (!track_callbacks.frame_callback.is_null()) + AddTrackOnIO(track, std::move(track_callbacks.frame_callback), + std::move(track_callbacks.settings_callback), settings); } void VideoTrackAdapter::DeliverFrameOnIO(
diff --git a/content/renderer/media/stream/video_track_adapter.h b/content/renderer/media/stream/video_track_adapter.h index a14e06a7..8bc2ee20 100644 --- a/content/renderer/media/stream/video_track_adapter.h +++ b/content/renderer/media/stream/video_track_adapter.h
@@ -14,6 +14,7 @@ #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "content/common/content_export.h" +#include "content/renderer/media/stream/media_stream_types.h" #include "content/renderer/media/stream/media_stream_video_track.h" #include "media/base/video_frame.h" #include "ui/gfx/geometry/size.h" @@ -84,13 +85,14 @@ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); // Register |track| to receive video frames in |frame_callback| with - // a resolution within the boundaries of the arguments. - // Must be called on the main render thread. |frame_callback| is guaranteed to - // be released on the main render thread. + // a resolution within the boundaries of the arguments, and settings + // updates in |settings_callback|. + // Must be called on the main render thread. // |source_frame_rate| is used to calculate a prudent interval to check for // passing frames and inform of the result via |on_muted_state_callback|. void AddTrack(const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, + VideoTrackSettingsCallback settings_callback, const VideoTrackAdapterSettings& settings); void RemoveTrack(const MediaStreamVideoTrack* track); void ReconfigureTrack(const MediaStreamVideoTrack* track, @@ -131,6 +133,7 @@ void AddTrackOnIO(const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, + VideoTrackSettingsCallback settings_callback, const VideoTrackAdapterSettings& settings); void RemoveTrackOnIO(const MediaStreamVideoTrack* track); void ReconfigureTrackOnIO(const MediaStreamVideoTrack* track, @@ -156,9 +159,9 @@ // VideoCaptureDeliverFrameCB is released on the main render thread. const scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_; - // VideoFrameResolutionAdapter is an inner class that is created on the main - // render thread but operates on the IO-thread. It does the resolution - // adaptation and delivers frames to all registered tracks on the IO-thread. + // VideoFrameResolutionAdapter is an inner class that lives on the IO-thread. + // It does the resolution adaptation and delivers frames to all registered + // tracks. class VideoFrameResolutionAdapter; using FrameAdapters = std::vector<scoped_refptr<VideoFrameResolutionAdapter>>; FrameAdapters adapters_;
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc index e93f565a..886fb45 100644 --- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc +++ b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
@@ -20,9 +20,9 @@ #include "content/renderer/media/stream/media_stream_constraints_util.h" #include "content/renderer/media/stream/media_stream_video_track.h" #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" -#include "content/renderer/media/webrtc/webrtc_video_track_source.h" #include "media/base/limits.h" #include "third_party/webrtc/api/videosourceproxy.h" +#include "third_party/webrtc/pc/videotracksource.h" namespace content { @@ -34,6 +34,37 @@ } // namespace +class MediaStreamVideoWebRtcSink::WebRtcVideoSource + : public webrtc::VideoTrackSource { + public: + WebRtcVideoSource(WebRtcVideoCapturerAdapter* capture_adapter, + bool is_screencast, + absl::optional<bool> needs_denoising) + : VideoTrackSource(false), + capture_adapter_(capture_adapter), + is_screencast_(is_screencast), + needs_denoising_(needs_denoising) {} + + WebRtcVideoCapturerAdapter* capture_adapter() const { + return capture_adapter_.get(); + } + + bool is_screencast() const override { return is_screencast_; } + absl::optional<bool> needs_denoising() const override { + return needs_denoising_; + } + + protected: + rtc::VideoSourceInterface<webrtc::VideoFrame>* source() override { + return capture_adapter_.get(); + } + + private: + std::unique_ptr<WebRtcVideoCapturerAdapter> const capture_adapter_; + const bool is_screencast_; + const absl::optional<bool> needs_denoising_; +}; + namespace { // The default number of microseconds that should elapse since the last video @@ -77,7 +108,7 @@ WebRtcVideoSourceAdapter( const scoped_refptr<base::SingleThreadTaskRunner>& libjingle_worker_thread, - const scoped_refptr<WebRtcVideoTrackSource>& source, + const scoped_refptr<WebRtcVideoSource>& source, base::TimeDelta refresh_interval, const base::RepeatingClosure& refresh_callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner); @@ -117,13 +148,15 @@ // IO-thread. scoped_refptr<base::SingleThreadTaskRunner> libjingle_worker_thread_; - scoped_refptr<WebRtcVideoTrackSource> video_source_; + scoped_refptr<webrtc::VideoTrackSourceInterface> video_source_; - // Used to protect |video_source_|. It is taken by libjingle's worker + // Used to protect |capture_adapter_|. It is taken by libjingle's worker // thread for each video frame that is delivered but only taken on the // main render thread in ReleaseSourceOnMainThread() when // the owning MediaStreamVideoWebRtcSink is being destroyed. - base::Lock video_source_stop_lock_; + base::Lock capture_adapter_stop_lock_; + // |capture_adapter_| is owned by |video_source_| + WebRtcVideoCapturerAdapter* capture_adapter_; // Requests a refresh frame at regular intervals. The delay on this timer is // reset each time a frame is received so that it will not fire for at least @@ -142,13 +175,14 @@ MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter( const scoped_refptr<base::SingleThreadTaskRunner>& libjingle_worker_thread, - const scoped_refptr<WebRtcVideoTrackSource>& source, + const scoped_refptr<WebRtcVideoSource>& source, base::TimeDelta refresh_interval, const base::RepeatingClosure& refresh_callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : render_task_runner_(std::move(task_runner)), libjingle_worker_thread_(libjingle_worker_thread), - video_source_(source) { + video_source_(source), + capture_adapter_(source->capture_adapter()) { DCHECK(render_task_runner_->RunsTasksInCurrentSequence()); io_thread_checker_.DetachFromThread(); if (!refresh_interval.is_zero()) { @@ -161,7 +195,7 @@ MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: ~WebRtcVideoSourceAdapter() { DVLOG(3) << "~WebRtcVideoSourceAdapter()"; - DCHECK(!video_source_); + DCHECK(!capture_adapter_); // This object can be destroyed on the main render thread or libjingles worker // thread since it posts video frames on that thread. But |video_source_| must // be released on the main render thread before the PeerConnectionFactory has @@ -182,7 +216,9 @@ // Since frames are posted to the worker thread, this object might be deleted // on that thread. However, since |video_source_| was created on the render // thread, it should be released on the render thread. - base::AutoLock auto_lock(video_source_stop_lock_); + base::AutoLock auto_lock(capture_adapter_stop_lock_); + // |video_source| owns |capture_adapter_|. + capture_adapter_ = nullptr; video_source_ = nullptr; } @@ -203,9 +239,9 @@ void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame) { DCHECK(libjingle_worker_thread_->BelongsToCurrentThread()); - base::AutoLock auto_lock(video_source_stop_lock_); - if (video_source_) - video_source_->OnFrameCaptured(frame); + base::AutoLock auto_lock(capture_adapter_stop_lock_); + if (capture_adapter_) + capture_adapter_->OnFrameCaptured(frame); } MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink( @@ -253,9 +289,10 @@ // TODO(pbos): Consolidate WebRtcVideoCapturerAdapter into WebRtcVideoSource // by removing the need for and dependency on a cricket::VideoCapturer. - video_source_ = scoped_refptr<WebRtcVideoTrackSource>( - new rtc::RefCountedObject<WebRtcVideoTrackSource>(is_screencast, - needs_denoising)); + video_source_ = scoped_refptr<WebRtcVideoSource>( + new rtc::RefCountedObject<WebRtcVideoSource>( + new WebRtcVideoCapturerAdapter(is_screencast), is_screencast, + needs_denoising)); // TODO(pbos): Consolidate the local video track with the source proxy and // move into PeerConnectionDependencyFactory. This now separately holds on a
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h index 4c0161f..d803928 100644 --- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h +++ b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
@@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "content/public/renderer/media_stream_video_sink.h" +#include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/webrtc/api/mediastreaminterface.h" @@ -20,7 +21,6 @@ class MediaStreamVideoTrack; class PeerConnectionDependencyFactory; -class WebRtcVideoTrackSource; // MediaStreamVideoWebRtcSink is an adapter between a // content::MediaStreamVideoTrack object and a webrtc VideoTrack that is @@ -59,10 +59,11 @@ // Used to DCHECK that we are called on the correct thread. base::ThreadChecker thread_checker_; - // |video_source_| and |video_source_proxy_| are held as - // references to outlive |video_track_| since the interfaces between them - // don't use reference counting. - scoped_refptr<WebRtcVideoTrackSource> video_source_; + // |video_source_| and |video_track_source_proxy_| are held as references to + // outlive |video_track_| since the interfaces between them don't use + // reference counting. + class WebRtcVideoSource; + scoped_refptr<WebRtcVideoSource> video_source_; scoped_refptr<webrtc::VideoTrackSourceInterface> video_source_proxy_; scoped_refptr<webrtc::VideoTrackInterface> video_track_;
diff --git a/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc index c2994a5..2a48dee4 100644 --- a/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc +++ b/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "content/renderer/media/webrtc/mock_peer_connection_impl.h" +#include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/webrtc/api/mediastreaminterface.h" #include "third_party/webrtc/rtc_base/scoped_ref_ptr.h"
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc index 56cc00ac..f8a8e5bd 100644 --- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc +++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -38,6 +38,7 @@ #include "content/renderer/media/webrtc/video_codec_factory.h" #include "content/renderer/media/webrtc/webrtc_audio_device_impl.h" #include "content/renderer/media/webrtc/webrtc_uma_histograms.h" +#include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" #include "content/renderer/media/webrtc_logging.h" #include "content/renderer/p2p/empty_network_manager.h" #include "content/renderer/p2p/filtering_network_manager.h"
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc new file mode 100644 index 0000000..546b26d --- /dev/null +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
@@ -0,0 +1,206 @@ +// Copyright 2014 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 "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" + +#include "base/bind.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/trace_event/trace_event.h" +#include "cc/paint/skia_paint_canvas.h" +#include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h" +#include "media/base/timestamp_constants.h" +#include "media/base/video_util.h" +#include "third_party/libyuv/include/libyuv/convert_from.h" +#include "third_party/libyuv/include/libyuv/scale.h" +#include "third_party/webrtc/api/video/video_rotation.h" +#include "third_party/webrtc/rtc_base/refcountedobject.h" + +namespace content { + +namespace { + +// Empty method used for keeping a reference to the original media::VideoFrame. +// The reference to |frame| is kept in the closure that calls this method. +void CapturerReleaseOriginalFrame( + const scoped_refptr<media::VideoFrame>& frame) {} + +} // anonymous namespace + +WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast) + : is_screencast_(is_screencast), running_(false) { + thread_checker_.DetachFromThread(); +} + +WebRtcVideoCapturerAdapter::~WebRtcVideoCapturerAdapter() { + DVLOG(3) << __func__; +} + +void WebRtcVideoCapturerAdapter::OnFrameCaptured( + const scoped_refptr<media::VideoFrame>& input_frame) { + DCHECK(thread_checker_.CalledOnValidThread()); + TRACE_EVENT0("media", "WebRtcVideoCapturerAdapter::OnFrameCaptured"); + if (!(input_frame->IsMappable() && + (input_frame->format() == media::PIXEL_FORMAT_I420 || + input_frame->format() == media::PIXEL_FORMAT_I420A)) && + !input_frame->HasTextures()) { + // Since connecting sources and sinks do not check the format, we need to + // just ignore formats that we can not handle. + LOG(ERROR) << "We cannot send frame with storage type: " + << input_frame->AsHumanReadableString(); + NOTREACHED(); + return; + } + scoped_refptr<media::VideoFrame> frame = input_frame; + const int orig_width = frame->natural_size().width(); + const int orig_height = frame->natural_size().height(); + int adapted_width; + int adapted_height; + // The VideoAdapter is only used for cpu-adaptation downscaling, no + // aspect changes. So we ignore these crop-related outputs. + int crop_width; + int crop_height; + int crop_x; + int crop_y; + int64_t translated_camera_time_us; + + if (!AdaptFrame(orig_width, orig_height, + frame->timestamp().InMicroseconds(), + rtc::TimeMicros(), + &adapted_width, &adapted_height, + &crop_width, &crop_height, &crop_x, &crop_y, + &translated_camera_time_us)) { + return; + } + + // Return |frame| directly if it is texture backed, because there is no + // cropping support for texture yet. See http://crbug/503653. + if (frame->HasTextures()) { + OnFrame(webrtc::VideoFrame( + new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame), + webrtc::kVideoRotation_0, translated_camera_time_us), + orig_width, orig_height); + return; + } + + // Translate crop rectangle from natural size to visible size. + gfx::Rect cropped_visible_rect( + frame->visible_rect().x() + + crop_x * frame->visible_rect().width() / orig_width, + frame->visible_rect().y() + + crop_y * frame->visible_rect().height() / orig_height, + crop_width * frame->visible_rect().width() / orig_width, + crop_height * frame->visible_rect().height() / orig_height); + + const gfx::Size adapted_size(adapted_width, adapted_height); + scoped_refptr<media::VideoFrame> video_frame = + media::VideoFrame::WrapVideoFrame(frame, frame->format(), + cropped_visible_rect, adapted_size); + if (!video_frame) + return; + + video_frame->AddDestructionObserver( + base::BindOnce(&CapturerReleaseOriginalFrame, frame)); + + // If no scaling is needed, return a wrapped version of |frame| directly. + if (video_frame->natural_size() == video_frame->visible_rect().size()) { + OnFrame(webrtc::VideoFrame( + new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(video_frame), + webrtc::kVideoRotation_0, translated_camera_time_us), + orig_width, orig_height); + return; + } + + // We need to scale the frame before we hand it over to webrtc. + const bool has_alpha = video_frame->format() == media::PIXEL_FORMAT_I420A; + scoped_refptr<media::VideoFrame> scaled_frame = + scaled_frame_pool_.CreateFrame( + has_alpha ? media::PIXEL_FORMAT_I420A : media::PIXEL_FORMAT_I420, + adapted_size, gfx::Rect(adapted_size), adapted_size, + frame->timestamp()); + libyuv::I420Scale(video_frame->visible_data(media::VideoFrame::kYPlane), + video_frame->stride(media::VideoFrame::kYPlane), + video_frame->visible_data(media::VideoFrame::kUPlane), + video_frame->stride(media::VideoFrame::kUPlane), + video_frame->visible_data(media::VideoFrame::kVPlane), + video_frame->stride(media::VideoFrame::kVPlane), + video_frame->visible_rect().width(), + video_frame->visible_rect().height(), + scaled_frame->data(media::VideoFrame::kYPlane), + scaled_frame->stride(media::VideoFrame::kYPlane), + scaled_frame->data(media::VideoFrame::kUPlane), + scaled_frame->stride(media::VideoFrame::kUPlane), + scaled_frame->data(media::VideoFrame::kVPlane), + scaled_frame->stride(media::VideoFrame::kVPlane), + adapted_width, adapted_height, libyuv::kFilterBilinear); + if (has_alpha) { + libyuv::ScalePlane(video_frame->visible_data(media::VideoFrame::kAPlane), + video_frame->stride(media::VideoFrame::kAPlane), + video_frame->visible_rect().width(), + video_frame->visible_rect().height(), + scaled_frame->data(media::VideoFrame::kAPlane), + scaled_frame->stride(media::VideoFrame::kAPlane), + adapted_width, adapted_height, libyuv::kFilterBilinear); + } + + OnFrame(webrtc::VideoFrame( + new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(scaled_frame), + webrtc::kVideoRotation_0, translated_camera_time_us), + orig_width, orig_height); +} + +cricket::CaptureState WebRtcVideoCapturerAdapter::Start( + const cricket::VideoFormat& capture_format) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!running_); + DVLOG(3) << __func__ << " capture format: " << capture_format.ToString(); + + running_ = true; + return cricket::CS_RUNNING; +} + +void WebRtcVideoCapturerAdapter::Stop() { + DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(3) << __func__; + DCHECK(running_); + running_ = false; + SetCaptureFormat(nullptr); + SignalStateChange(this, cricket::CS_STOPPED); +} + +bool WebRtcVideoCapturerAdapter::IsRunning() { + DCHECK(thread_checker_.CalledOnValidThread()); + return running_; +} + +bool WebRtcVideoCapturerAdapter::GetPreferredFourccs( + std::vector<uint32_t>* fourccs) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (!fourccs) + return false; + DCHECK(fourccs->empty()); + fourccs->push_back(cricket::FOURCC_I420); + return true; +} + +bool WebRtcVideoCapturerAdapter::IsScreencast() const { + return is_screencast_; +} + +bool WebRtcVideoCapturerAdapter::GetBestCaptureFormat( + const cricket::VideoFormat& desired, + cricket::VideoFormat* best_format) { + DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(3) << __func__ << " desired: " << desired.ToString(); + + // Capability enumeration is done in MediaStreamVideoSource. The adapter can + // just use what is provided. + // Use the desired format as the best format. + best_format->width = desired.width; + best_format->height = desired.height; + best_format->fourcc = cricket::FOURCC_I420; + best_format->interval = desired.interval; + return true; +} + +} // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h new file mode 100644 index 0000000..2b72f681 --- /dev/null +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h
@@ -0,0 +1,68 @@ +// Copyright 2014 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 CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_CAPTURER_ADAPTER_H_ +#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_CAPTURER_ADAPTER_H_ + +#include <stdint.h> + +#include <vector> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/threading/thread_checker.h" +#include "content/common/content_export.h" +#include "media/base/video_frame.h" +#include "media/base/video_frame_pool.h" +#include "media/capture/video_capture_types.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/webrtc/media/base/videocapturer.h" + +namespace content { + +// WebRtcVideoCapturerAdapter implements a simple cricket::VideoCapturer that is +// used for VideoCapturing in libJingle and especially in PeerConnections. +// The class is created and destroyed on the main render thread. +// PeerConnection access cricket::VideoCapturer from a libJingle worker thread. +// An instance of WebRtcVideoCapturerAdapter is owned by an instance of +// webrtc::VideoTrackSourceInterface in libJingle. The implementation of +// webrtc::VideoTrackSourceInterface guarantees that this object is not deleted +// while it is still used in libJingle. +class CONTENT_EXPORT WebRtcVideoCapturerAdapter + : public cricket::VideoCapturer { + public: + WebRtcVideoCapturerAdapter(bool is_screencast); + ~WebRtcVideoCapturerAdapter() override; + + // OnFrameCaptured delivers video frames to libjingle. It must be called on + // libjingles worker thread. + // This method is virtual for testing purposes. + virtual void OnFrameCaptured(const scoped_refptr<media::VideoFrame>& frame); + + private: + // cricket::VideoCapturer implementation. + // These methods are accessed from a libJingle worker thread. + cricket::CaptureState Start( + const cricket::VideoFormat& capture_format) override; + void Stop() override; + bool IsRunning() override; + bool GetPreferredFourccs(std::vector<uint32_t>* fourccs) override; + bool GetBestCaptureFormat(const cricket::VideoFormat& desired, + cricket::VideoFormat* best_format) override; + bool IsScreencast() const override; + + // |thread_checker_| is bound to the libjingle worker thread. + base::ThreadChecker thread_checker_; + + const bool is_screencast_; + bool running_; + + media::VideoFramePool scaled_frame_pool_; + + DISALLOW_COPY_AND_ASSIGN(WebRtcVideoCapturerAdapter); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_CAPTURER_ADAPTER_H_
diff --git a/content/renderer/media/webrtc/webrtc_video_track_source_unittest.cc b/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc similarity index 72% rename from content/renderer/media/webrtc/webrtc_video_track_source_unittest.cc rename to content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc index e62c137..996ba07 100644 --- a/content/renderer/media/webrtc/webrtc_video_track_source_unittest.cc +++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc
@@ -6,27 +6,24 @@ #include "base/single_thread_task_runner.h" #include "base/test/scoped_task_environment.h" +#include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" #include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h" -#include "content/renderer/media/webrtc/webrtc_video_track_source.h" #include "media/base/video_frame.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/rtc_base/refcountedobject.h" namespace content { -class WebRtcVideoTrackSourceTest +class WebRtcVideoCapturerAdapterTest : public rtc::VideoSinkInterface<webrtc::VideoFrame>, public ::testing::Test { public: - WebRtcVideoTrackSourceTest() - : track_source_(new rtc::RefCountedObject<WebRtcVideoTrackSource>( - /*is_screencast=*/false, - /*needs_denoising=*/absl::nullopt)), + WebRtcVideoCapturerAdapterTest() + : adapter_(new WebRtcVideoCapturerAdapter(false)), output_frame_width_(0), output_frame_height_(0) { - track_source_->AddOrUpdateSink(this, rtc::VideoSinkWants()); + adapter_->AddOrUpdateSink(this, rtc::VideoSinkWants()); } - ~WebRtcVideoTrackSourceTest() override { track_source_->RemoveSink(this); } + ~WebRtcVideoCapturerAdapterTest() override { adapter_->RemoveSink(this); } void TestSourceCropFrame(int capture_width, int capture_height, @@ -43,7 +40,7 @@ scoped_refptr<media::VideoFrame> frame = media::VideoFrame::CreateFrame( media::PIXEL_FORMAT_I420, coded_size, view_rect, natural_size, base::TimeDelta()); - track_source_->OnFrameCaptured(frame); + adapter_->OnFrameCaptured(frame); EXPECT_EQ(natural_width, output_frame_width_); EXPECT_EQ(natural_height, output_frame_height_); } @@ -55,20 +52,20 @@ } private: - scoped_refptr<WebRtcVideoTrackSource> track_source_; + std::unique_ptr<WebRtcVideoCapturerAdapter> adapter_; int output_frame_width_; int output_frame_height_; }; -TEST_F(WebRtcVideoTrackSourceTest, CropFrameTo640360) { +TEST_F(WebRtcVideoCapturerAdapterTest, CropFrameTo640360) { TestSourceCropFrame(640, 480, 640, 360, 640, 360); } -TEST_F(WebRtcVideoTrackSourceTest, CropFrameTo320320) { +TEST_F(WebRtcVideoCapturerAdapterTest, CropFrameTo320320) { TestSourceCropFrame(640, 480, 480, 480, 320, 320); } -TEST_F(WebRtcVideoTrackSourceTest, Scale720To640360) { +TEST_F(WebRtcVideoCapturerAdapterTest, Scale720To640360) { TestSourceCropFrame(1280, 720, 1280, 720, 640, 360); }
diff --git a/content/renderer/media/webrtc/webrtc_video_track_source.cc b/content/renderer/media/webrtc/webrtc_video_track_source.cc deleted file mode 100644 index 46ea7b5..0000000 --- a/content/renderer/media/webrtc/webrtc_video_track_source.cc +++ /dev/null
@@ -1,151 +0,0 @@ -// Copyright 2018 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 "content/renderer/media/webrtc/webrtc_video_track_source.h" - -#include "base/trace_event/trace_event.h" -#include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h" -#include "third_party/libyuv/include/libyuv/scale.h" -#include "third_party/webrtc/rtc_base/refcountedobject.h" - -namespace content { - -WebRtcVideoTrackSource::WebRtcVideoTrackSource( - bool is_screencast, - absl::optional<bool> needs_denoising) - : AdaptedVideoTrackSource(/*required_alignment=*/1), - is_screencast_(is_screencast), - needs_denoising_(needs_denoising) { - DETACH_FROM_THREAD(thread_checker_); -} - -WebRtcVideoTrackSource::~WebRtcVideoTrackSource() = default; - -WebRtcVideoTrackSource::SourceState WebRtcVideoTrackSource::state() const { - // TODO(nisse): What's supposed to change this state? - return MediaSourceInterface::SourceState::kLive; -} - -bool WebRtcVideoTrackSource::remote() const { - return false; -} - -bool WebRtcVideoTrackSource::is_screencast() const { - return is_screencast_; -} - -absl::optional<bool> WebRtcVideoTrackSource::needs_denoising() const { - return needs_denoising_; -} - -void WebRtcVideoTrackSource::OnFrameCaptured( - const scoped_refptr<media::VideoFrame>& frame) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - TRACE_EVENT0("media", "WebRtcVideoSource::OnFrameCaptured"); - if (!(frame->IsMappable() && - (frame->format() == media::PIXEL_FORMAT_I420 || - frame->format() == media::PIXEL_FORMAT_I420A)) && - !frame->HasTextures()) { - // Since connecting sources and sinks do not check the format, we need to - // just ignore formats that we can not handle. - LOG(ERROR) << "We cannot send frame with storage type: " - << frame->AsHumanReadableString(); - NOTREACHED(); - return; - } - - const int orig_width = frame->natural_size().width(); - const int orig_height = frame->natural_size().height(); - const int64_t now_us = rtc::TimeMicros(); - int adapted_width; - int adapted_height; - int crop_width; - int crop_height; - int crop_x; - int crop_y; - - if (!AdaptFrame(orig_width, orig_height, now_us, &adapted_width, - &adapted_height, &crop_width, &crop_height, &crop_x, - &crop_y)) { - return; - } - - const int64_t translated_camera_time_us = - timestamp_aligner_.TranslateTimestamp(frame->timestamp().InMicroseconds(), - now_us); - - // Return |frame| directly if it is texture backed, because there is no - // cropping support for texture yet. See http://crbug/503653. - if (frame->HasTextures()) { - OnFrame(webrtc::VideoFrame( - new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame), - webrtc::kVideoRotation_0, translated_camera_time_us)); - return; - } - - // Translate crop rectangle from natural size to visible size. - gfx::Rect cropped_visible_rect( - frame->visible_rect().x() + - crop_x * frame->visible_rect().width() / orig_width, - frame->visible_rect().y() + - crop_y * frame->visible_rect().height() / orig_height, - crop_width * frame->visible_rect().width() / orig_width, - crop_height * frame->visible_rect().height() / orig_height); - - const gfx::Size adapted_size(adapted_width, adapted_height); - scoped_refptr<media::VideoFrame> video_frame = - media::VideoFrame::WrapVideoFrame(frame, frame->format(), - cropped_visible_rect, adapted_size); - if (!video_frame) - return; - - video_frame->AddDestructionObserver(base::BindOnce( - base::DoNothing::Once<scoped_refptr<media::VideoFrame>>(), frame)); - - // If no scaling is needed, return a wrapped version of |frame| directly. - if (video_frame->natural_size() == video_frame->visible_rect().size()) { - OnFrame(webrtc::VideoFrame( - new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(video_frame), - webrtc::kVideoRotation_0, translated_camera_time_us)); - return; - } - - // We need to scale the frame before we hand it over to webrtc. - const bool has_alpha = video_frame->format() == media::PIXEL_FORMAT_I420A; - scoped_refptr<media::VideoFrame> scaled_frame = - scaled_frame_pool_.CreateFrame( - has_alpha ? media::PIXEL_FORMAT_I420A : media::PIXEL_FORMAT_I420, - adapted_size, gfx::Rect(adapted_size), adapted_size, - frame->timestamp()); - libyuv::I420Scale(video_frame->visible_data(media::VideoFrame::kYPlane), - video_frame->stride(media::VideoFrame::kYPlane), - video_frame->visible_data(media::VideoFrame::kUPlane), - video_frame->stride(media::VideoFrame::kUPlane), - video_frame->visible_data(media::VideoFrame::kVPlane), - video_frame->stride(media::VideoFrame::kVPlane), - video_frame->visible_rect().width(), - video_frame->visible_rect().height(), - scaled_frame->data(media::VideoFrame::kYPlane), - scaled_frame->stride(media::VideoFrame::kYPlane), - scaled_frame->data(media::VideoFrame::kUPlane), - scaled_frame->stride(media::VideoFrame::kUPlane), - scaled_frame->data(media::VideoFrame::kVPlane), - scaled_frame->stride(media::VideoFrame::kVPlane), - adapted_width, adapted_height, libyuv::kFilterBilinear); - if (has_alpha) { - libyuv::ScalePlane(video_frame->visible_data(media::VideoFrame::kAPlane), - video_frame->stride(media::VideoFrame::kAPlane), - video_frame->visible_rect().width(), - video_frame->visible_rect().height(), - scaled_frame->data(media::VideoFrame::kAPlane), - scaled_frame->stride(media::VideoFrame::kAPlane), - adapted_width, adapted_height, libyuv::kFilterBilinear); - } - - OnFrame(webrtc::VideoFrame( - new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(scaled_frame), - webrtc::kVideoRotation_0, translated_camera_time_us)); -} - -} // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_video_track_source.h b/content/renderer/media/webrtc/webrtc_video_track_source.h deleted file mode 100644 index 90417ba9..0000000 --- a/content/renderer/media/webrtc/webrtc_video_track_source.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2018 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 CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_TRACK_SOURCE_H_ -#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_TRACK_SOURCE_H_ - -#include "base/memory/scoped_refptr.h" -#include "base/threading/thread_checker.h" -#include "content/common/content_export.h" -#include "media/base/video_frame_pool.h" -#include "third_party/webrtc/media/base/adaptedvideotracksource.h" -#include "third_party/webrtc/rtc_base/timestampaligner.h" - -namespace content { - -class CONTENT_EXPORT WebRtcVideoTrackSource - : public rtc::AdaptedVideoTrackSource { - public: - WebRtcVideoTrackSource(bool is_screencast, - absl::optional<bool> needs_denoising); - ~WebRtcVideoTrackSource() override; - - SourceState state() const override; - - bool remote() const override; - bool is_screencast() const override; - absl::optional<bool> needs_denoising() const override; - void OnFrameCaptured(const scoped_refptr<media::VideoFrame>& frame); - - using webrtc::VideoTrackSourceInterface::AddOrUpdateSink; - using webrtc::VideoTrackSourceInterface::RemoveSink; - - private: - // |thread_checker_| is bound to the libjingle worker thread. - THREAD_CHECKER(thread_checker_); - media::VideoFramePool scaled_frame_pool_; - // State for the timestamp translation. - rtc::TimestampAligner timestamp_aligner_; - - const bool is_screencast_; - const absl::optional<bool> needs_denoising_; - - DISALLOW_COPY_AND_ASSIGN(WebRtcVideoTrackSource); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_TRACK_SOURCE_H_
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 3a919f66..538929b 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3326,6 +3326,7 @@ !FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type)); RenderFrameImpl::PrepareRenderViewForNavigation(common_params.url, request_params); + sync_navigation_callback_.Cancel(); // Log a console message for subframe loads that failed due to a legacy // Symantec certificate that has been distrusted or is slated for distrust @@ -4673,6 +4674,7 @@ void RenderFrameImpl::AbortClientNavigation() { browser_side_navigation_pending_ = false; + sync_navigation_callback_.Cancel(); if (!IsPerNavigationMojoInterfaceEnabled()) Send(new FrameHostMsg_AbortNavigation(routing_id_)); } @@ -5774,6 +5776,7 @@ const RequestNavigationParams& request_params) { browser_side_navigation_pending_ = false; browser_side_navigation_pending_url_ = GURL(); + sync_navigation_callback_.Cancel(); GetContentClient()->SetActiveURL( url, frame_->Top()->GetSecurityOrigin().ToString().Utf8()); @@ -6103,21 +6106,22 @@ for (auto& observer : observers_) observer.WillSubmitForm(info->form); } + + sync_navigation_callback_.Cancel(); + // If the navigation is not synchronous, send it to the browser. This // includes navigations with no request being sent to the network stack. if (!use_archive && IsURLHandledByNetworkStack(url)) { BeginNavigationInternal(std::move(info)); + } else if (WebDocumentLoader::WillLoadUrlAsEmpty(url) && + frame_->HasCommittedFirstRealLoad()) { + sync_navigation_callback_.Reset( + base::BindOnce(&RenderFrameImpl::CommitSyncNavigation, + weak_factory_.GetWeakPtr(), base::Passed(&info))); + frame_->GetTaskRunner(blink::TaskType::kInternalLoading) + ->PostTask(FROM_HERE, sync_navigation_callback_.callback()); } else { - // TODO(dgozman): should we follow the RFI::CommitNavigation path instead? - auto navigation_params = WebNavigationParams::CreateFromInfo(*info); - // We need the provider to be non-null, otherwise Blink crashes, even - // though the provider should not be used for any actual networking. - navigation_params->service_worker_network_provider = - BuildServiceWorkerNetworkProviderForNavigation( - nullptr /* request_params */, - nullptr /* controller_service_worker_info */); - frame_->CommitNavigation(std::move(navigation_params), - BuildDocumentState()); + CommitSyncNavigation(std::move(info)); } return; } @@ -6133,6 +6137,19 @@ } } +void RenderFrameImpl::CommitSyncNavigation( + std::unique_ptr<blink::WebNavigationInfo> info) { + // TODO(dgozman): should we follow the RFI::CommitNavigation path instead? + auto navigation_params = WebNavigationParams::CreateFromInfo(*info); + // We need the provider to be non-null, otherwise Blink crashes, even + // though the provider should not be used for any actual networking. + navigation_params->service_worker_network_provider = + BuildServiceWorkerNetworkProviderForNavigation( + nullptr /* request_params */, + nullptr /* controller_service_worker_info */); + frame_->CommitNavigation(std::move(navigation_params), BuildDocumentState()); +} + void RenderFrameImpl::OnGetSavableResourceLinks() { std::vector<GURL> resources_list; std::vector<SavableSubframe> subframes;
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 45d81f1..687d8428 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -1153,6 +1153,10 @@ // Sends a FrameHostMsg_BeginNavigation to the browser void BeginNavigationInternal(std::unique_ptr<blink::WebNavigationInfo> info); + // Commit a navigation that isn't handled by the browser (e.g., an empty + // document or an MHTML archive). + void CommitSyncNavigation(std::unique_ptr<blink::WebNavigationInfo> info); + // Decodes a data url for navigation commit. void DecodeDataURL(const CommonNavigationParams& common_params, const RequestNavigationParams& request_params, @@ -1605,6 +1609,8 @@ RenderFrameMediaPlaybackOptions renderer_media_playback_options_; + base::CancelableOnceCallback<void()> sync_navigation_callback_; + base::WeakPtrFactory<RenderFrameImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl);
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 473c5d2..8e1979d 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -833,10 +833,8 @@ navigation_info->url_request = blink::WebURLRequest(empty_url); navigation_info->navigation_policy = blink::kWebNavigationPolicyCurrentTab; frame()->BeginNavigation(std::move(navigation_info)); - // Check that we committed synchronously. - EXPECT_EQ( - blank_url, - GURL(frame()->GetWebFrame()->GetDocumentLoader()->GetRequest().Url())); + EXPECT_FALSE(render_thread_->sink().GetUniqueMessageMatching( + FrameHostMsg_OpenURL::ID)); } TEST_F(AlwaysForkingRenderViewTest, BeginNavigationDoesNotForkAboutBlank) { @@ -853,10 +851,8 @@ navigation_info->url_request = blink::WebURLRequest(blank_url); navigation_info->navigation_policy = blink::kWebNavigationPolicyCurrentTab; frame()->BeginNavigation(std::move(navigation_info)); - // Check that we committed synchronously. - EXPECT_EQ( - blank_url, - GURL(frame()->GetWebFrame()->GetDocumentLoader()->GetRequest().Url())); + EXPECT_FALSE(render_thread_->sink().GetUniqueMessageMatching( + FrameHostMsg_OpenURL::ID)); } // This test verifies that when device emulation is enabled, RenderFrameProxy
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 5913921..e3d1c15 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1780,7 +1780,7 @@ "../renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc", "../renderer/media/webrtc/webrtc_set_description_observer_unittest.cc", "../renderer/media/webrtc/webrtc_uma_histograms_unittest.cc", - "../renderer/media/webrtc/webrtc_video_track_source_unittest.cc", + "../renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc", "../renderer/media/webrtc_local_audio_source_provider_unittest.cc", "../renderer/media_capture_from_element/canvas_capture_handler_unittest.cc", "../renderer/media_capture_from_element/html_audio_element_capturer_source_unittest.cc",
diff --git a/content/test/data/media/peerconnection-call.html b/content/test/data/media/peerconnection-call.html index 97e6d611..86249906 100644 --- a/content/test/data/media/peerconnection-call.html +++ b/content/test/data/media/peerconnection-call.html
@@ -683,10 +683,8 @@ } // Makes a call between pc1 and pc2 and check that the remote video tracks - // do not report (incorrect) values for width or height. - // TODO(guidou): Make remote tracks able to report correct values. - // http://crbug.com/772400 - function testGetSettingsWhenRemoteDimensionsUnknown() { + // report values for width and height, but not for frame rate. + function testGetSettingsReportsValuesForRemoteTracks() { createConnections(null); navigator.mediaDevices.getUserMedia({audio: true, video: true}) .then(addStreamToBothConnectionsAndNegotiate) @@ -695,14 +693,14 @@ detectVideoPlaying('remote-view-1').then(() => { var settings1 = gFirstConnection.getRemoteStreams()[0].getVideoTracks()[0] .getSettings(); - assertTrue(settings1.width === undefined); - assertTrue(settings1.height === undefined); + assertTrue(settings1.width != undefined); + assertTrue(settings1.height != undefined); assertTrue(settings1.frameRate === undefined); detectVideoPlaying('remote-view-2').then(() => { var settings2 = gSecondConnection.getRemoteStreams()[0] .getVideoTracks()[0].getSettings(); - assertTrue(settings2.width === undefined); - assertTrue(settings2.height === undefined); + assertTrue(settings2.width != undefined); + assertTrue(settings2.height != undefined); assertTrue(settings2.frameRate === undefined); reportTestSuccess(); });
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py index 09da641c..54ac8fa5 100644 --- a/content/test/gpu/gpu_tests/pixel_expectations.py +++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -49,11 +49,16 @@ # TODO(vmiura) check / generate reference images for Android devices self.Fail('Pixel_SolidColorBackground', ['mac', 'android'], bug=624256) - self.Fail('Pixel_CSSFilterEffects', ['mac', ('nvidia', 0xfe9)], bug=690277) + # TODO(michaelludwig): restore after Skia roll (see below) + #self.Fail('Pixel_CSSFilterEffects', ['mac', ('nvidia', 0xfe9)], bug=690277) # Became flaky on 10.13.6. When it flakes, it flakes 3 times, so # mark failing, unfortunately. - self.Fail('Pixel_CSSFilterEffects', ['highsierra', 'amd'], bug=872423) + # TODO(michaelludwig): restore after Skia roll (see below) + #self.Fail('Pixel_CSSFilterEffects', ['highsierra', 'amd'], bug=872423) + + # TODO(michaelludwig): remove after Skia roll + self.Fail('Pixel_CSSFilterEffects', bug=915735) # TODO(kbr): flakily timing out on this configuration. self.Flaky('*', ['linux', 'intel', 'debug'], bug=648369)
diff --git a/docs/security/faq.md b/docs/security/faq.md index c808a554..f2517fd 100644 --- a/docs/security/faq.md +++ b/docs/security/faq.md
@@ -399,10 +399,10 @@ ## How does key pinning interact with local proxies and filters? To enable certificate chain validation, Chrome has access to two stores of trust -anchors: certificates that are empowered as issuers. One trust anchor store is -the system or public trust anchor store, and the other other is the local or -private trust anchor store. The public store is provided as part of the -operating system, and intended to authenticate public internet servers. The +anchors (i.e. certificates that are empowered as issuers). One trust anchor +store is the system or public trust anchor store, and the other other is the +local or private trust anchor store. The public store is provided as part of +the operating system, and intended to authenticate public internet servers. The private store contains certificates installed by the user or the administrator of the client machine. Private intranet servers should authenticate themselves with certificates issued by a private trust anchor. @@ -431,6 +431,31 @@ not trust the private trust anchor, the proxy’s attempt to mediate the connection will fail as it should. +<a name="TOC-When-is-key-pinning-enabled-"></a> +## When is key pinning enabled? + +Key pinning is enabled for Chrome-branded, non-mobile builds when the local +clock is within ten weeks of the embedded build timestamp. Key pinning is a +useful security measure but it tightly couples client and server configurations +and completely breaks when those configurations are out of sync. In order to +manage that risk we need to ensure that we can promptly update pinning clients +an in emergency and ensure that non-emergency changes can be deployed in a +reasonable timeframe. + +Each of the conditions listed above helps ensure those properties: +Chrome-branded builds are those that Google provides and they all have an +auto-update mechanism that can be used in an emergency. However, auto-update on +mobile devices is significantly less effective thus they are excluded. Even in +cases where auto-update is generally effective, there are still non-trivial +populations of stragglers for various reasons. The ten-week timeout prevents +those stragglers from causing problems for regular, non-emergency changes and +allows stuck users to still, for example, conduct searches and access Chrome's +homepage to hopefully get unstuck. + +In order to determine whether key pinning is active, try loading +[https://pinningtest.appspot.com](https://pinningtest.appspot.com). If key +pinning is active the load will _fail_ with a pinning error. + <a name="TOC-How-does-certificate-transparency-interact-with-local-proxies-and-filters-"></a> ## How does Certificate Transparency interact with local proxies and filters?
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 456bf91..d776a49 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -273,6 +273,7 @@ "lazy_background_task_queue_factory.h", "lazy_context_id.cc", "lazy_context_id.h", + "lazy_context_task_queue.cc", "lazy_context_task_queue.h", "load_monitoring_extension_host_queue.cc", "load_monitoring_extension_host_queue.h",
diff --git a/extensions/browser/api/messaging/message_service.cc b/extensions/browser/api/messaging/message_service.cc index 7d69dd6..95e8cc9 100644 --- a/extensions/browser/api/messaging/message_service.cc +++ b/extensions/browser/api/messaging/message_service.cc
@@ -32,7 +32,6 @@ #include "extensions/browser/api/messaging/messaging_delegate.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_api_frame_id_map.h" -#include "extensions/browser/extension_host.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/extension_util.h" @@ -943,17 +942,20 @@ void MessageService::PendingLazyBackgroundPageOpenChannel( std::unique_ptr<OpenChannelParams> params, int source_process_id, - ExtensionHost* host) { + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!host) + if (context_info == nullptr) return; // TODO(mpcomplete): notify source of disconnect? - params->receiver.reset( - new ExtensionMessagePort( - weak_factory_.GetWeakPtr(), params->receiver_port_id, - params->target_extension_id, host->render_process_host())); - OpenChannelImpl(host->browser_context(), std::move(params), host->extension(), + params->receiver.reset(new ExtensionMessagePort( + weak_factory_.GetWeakPtr(), params->receiver_port_id, + params->target_extension_id, context_info->render_process_host)); + const Extension* const extension = + extensions::ExtensionRegistry::Get(context_info->browser_context) + ->enabled_extensions() + .GetByID(context_info->extension_id); + OpenChannelImpl(context_info->browser_context, std::move(params), extension, true /* did_enqueue */); }
diff --git a/extensions/browser/api/messaging/message_service.h b/extensions/browser/api/messaging/message_service.h index d3d9d25..104b6954 100644 --- a/extensions/browser/api/messaging/message_service.h +++ b/extensions/browser/api/messaging/message_service.h
@@ -18,6 +18,7 @@ #include "extensions/browser/api/messaging/message_property_provider.h" #include "extensions/browser/api/messaging/native_message_host.h" #include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/lazy_context_task_queue.h" #include "extensions/common/api/messaging/message.h" #include "extensions/common/api/messaging/port_id.h" #include "extensions/common/extension_id.h" @@ -201,21 +202,23 @@ void PendingLazyBackgroundPageOpenChannel( std::unique_ptr<OpenChannelParams> params, int source_process_id, - extensions::ExtensionHost* host); - void PendingLazyBackgroundPageClosePort(const PortId& port_id, - int process_id, - int routing_id, - bool force_close, - const std::string& error_message, - extensions::ExtensionHost* host) { - if (host) + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info); + void PendingLazyBackgroundPageClosePort( + const PortId& port_id, + int process_id, + int routing_id, + bool force_close, + const std::string& error_message, + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) { + if (context_info) ClosePortImpl(port_id, process_id, routing_id, force_close, error_message); } - void PendingLazyBackgroundPagePostMessage(const PortId& port_id, - const Message& message, - extensions::ExtensionHost* host) { - if (host) + void PendingLazyBackgroundPagePostMessage( + const PortId& port_id, + const Message& message, + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) { + if (context_info) PostMessage(port_id, message); }
diff --git a/extensions/browser/api/runtime/runtime_api.cc b/extensions/browser/api/runtime/runtime_api.cc index 9c0b235a..7416632 100644 --- a/extensions/browser/api/runtime/runtime_api.cc +++ b/extensions/browser/api/runtime/runtime_api.cc
@@ -98,13 +98,14 @@ // API without a kiosk app. bool allow_non_kiosk_apps_restart_api_for_test = false; -void DispatchOnStartupEventImpl(BrowserContext* browser_context, - const std::string& extension_id, - bool first_call, - ExtensionHost* host) { - // A NULL host from the LazyBackgroundTaskQueue means the page failed to - // load. Give up. - if (!host && !first_call) +void DispatchOnStartupEventImpl( + BrowserContext* browser_context, + const std::string& extension_id, + bool first_call, + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) { + // A NULL ContextInfo from the LazyBackgroundTaskQueue means the page failed + // to load. Give up. + if (!context_info && !first_call) return; // Don't send onStartup events to incognito browser contexts. @@ -427,7 +428,7 @@ void RuntimeEventRouter::DispatchOnStartupEvent( content::BrowserContext* context, const std::string& extension_id) { - DispatchOnStartupEventImpl(context, extension_id, true, NULL); + DispatchOnStartupEventImpl(context, extension_id, true, nullptr); } // static @@ -602,7 +603,7 @@ base::BindOnce(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this)); } else if (host) { - OnPageLoaded(host); + OnPageLoaded(std::make_unique<LazyContextTaskQueue::ContextInfo>(host)); } else { return RespondNow(Error(kNoBackgroundPageError)); } @@ -610,8 +611,9 @@ return RespondLater(); } -void RuntimeGetBackgroundPageFunction::OnPageLoaded(ExtensionHost* host) { - if (host) { +void RuntimeGetBackgroundPageFunction::OnPageLoaded( + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) { + if (context_info) { Respond(NoArguments()); } else { Respond(Error(kPageLoadError));
diff --git a/extensions/browser/api/runtime/runtime_api.h b/extensions/browser/api/runtime/runtime_api.h index 4246125..8e927a8 100644 --- a/extensions/browser/api/runtime/runtime_api.h +++ b/extensions/browser/api/runtime/runtime_api.h
@@ -5,6 +5,7 @@ #ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_ #define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_ +#include <memory> #include <string> #include "base/macros.h" @@ -16,6 +17,7 @@ #include "extensions/browser/events/lazy_event_dispatch_util.h" #include "extensions/browser/extension_function.h" #include "extensions/browser/extension_registry_observer.h" +#include "extensions/browser/lazy_context_task_queue.h" #include "extensions/browser/process_manager.h" #include "extensions/browser/process_manager_observer.h" #include "extensions/browser/update_observer.h" @@ -40,7 +42,6 @@ } class Extension; -class ExtensionHost; class ExtensionRegistry; // Runtime API dispatches onStartup, onInstalled, and similar events to @@ -226,7 +227,8 @@ ResponseAction Run() override; private: - void OnPageLoaded(ExtensionHost*); + void OnPageLoaded( + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info); }; class RuntimeOpenOptionsPageFunction : public UIThreadExtensionFunction {
diff --git a/extensions/browser/guest_view/app_view/app_view_guest.cc b/extensions/browser/guest_view/app_view/app_view_guest.cc index 6114ded5..13f0910 100644 --- a/extensions/browser/guest_view/app_view/app_view_guest.cc +++ b/extensions/browser/guest_view/app_view/app_view_guest.cc
@@ -208,7 +208,9 @@ ExtensionHost* host = process_manager->GetBackgroundHostForExtension(guest_extension->id()); DCHECK(host); - LaunchAppAndFireEvent(data->CreateDeepCopy(), std::move(callback), host); + LaunchAppAndFireEvent( + data->CreateDeepCopy(), std::move(callback), + std::make_unique<LazyContextTaskQueue::ContextInfo>(host)); } void AppViewGuest::DidInitialize(const base::DictionaryValue& create_params) { @@ -253,10 +255,10 @@ void AppViewGuest::LaunchAppAndFireEvent( std::unique_ptr<base::DictionaryValue> data, WebContentsCreatedCallback callback, - ExtensionHost* extension_host) { + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) { bool has_event_listener = EventRouter::Get(browser_context()) ->ExtensionHasEventListener( - extension_host->extension()->id(), + context_info->extension_id, app_runtime::OnEmbedRequested::kEventName); if (!has_event_listener) { std::move(callback).Run(nullptr); @@ -268,8 +270,12 @@ embed_request->SetInteger(appview::kGuestInstanceID, guest_instance_id()); embed_request->SetString(appview::kEmbedderID, owner_host()); embed_request->Set(appview::kData, std::move(data)); + const Extension* const extension = + extensions::ExtensionRegistry::Get(context_info->browser_context) + ->enabled_extensions() + .GetByID(context_info->extension_id); AppRuntimeEventRouter::DispatchOnEmbedRequestedEvent( - browser_context(), std::move(embed_request), extension_host->extension()); + browser_context(), std::move(embed_request), extension); } void AppViewGuest::SetAppDelegateForTest(AppDelegate* delegate) {
diff --git a/extensions/browser/guest_view/app_view/app_view_guest.h b/extensions/browser/guest_view/app_view/app_view_guest.h index 6131834..1603f25 100644 --- a/extensions/browser/guest_view/app_view/app_view_guest.h +++ b/extensions/browser/guest_view/app_view/app_view_guest.h
@@ -5,14 +5,16 @@ #ifndef EXTENSIONS_BROWSER_GUEST_VIEW_APP_VIEW_APP_VIEW_GUEST_H_ #define EXTENSIONS_BROWSER_GUEST_VIEW_APP_VIEW_APP_VIEW_GUEST_H_ +#include <memory> + #include "base/containers/id_map.h" #include "base/macros.h" #include "components/guest_view/browser/guest_view.h" #include "extensions/browser/guest_view/app_view/app_view_guest_delegate.h" +#include "extensions/browser/lazy_context_task_queue.h" namespace extensions { class Extension; -class ExtensionHost; // An AppViewGuest provides the browser-side implementation of <appview> API. // AppViewGuest is created on attachment. That is, when a guest WebContents is @@ -71,9 +73,10 @@ const Extension* guest_extension, WebContentsCreatedCallback callback); - void LaunchAppAndFireEvent(std::unique_ptr<base::DictionaryValue> data, - WebContentsCreatedCallback callback, - ExtensionHost* extension_host); + void LaunchAppAndFireEvent( + std::unique_ptr<base::DictionaryValue> data, + WebContentsCreatedCallback callback, + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info); GURL url_; std::string guest_extension_id_;
diff --git a/extensions/browser/lazy_background_task_queue.cc b/extensions/browser/lazy_background_task_queue.cc index c578821..bfc6afc 100644 --- a/extensions/browser/lazy_background_task_queue.cc +++ b/extensions/browser/lazy_background_task_queue.cc
@@ -28,21 +28,6 @@ namespace { -// Adapts a LazyBackgroundTaskQueue pending task callback to -// LazyContextTaskQueue's callback. -void PendingTaskAdapter(LazyContextTaskQueue::PendingTask original_task, - ExtensionHost* host) { - if (!host) { - std::move(original_task).Run(nullptr); - } else { - std::move(original_task) - .Run(std::make_unique<LazyContextTaskQueue::ContextInfo>( - host->extension()->id(), host->render_process_host(), - blink::mojom::kInvalidServiceWorkerVersionId, kMainThreadId, - host->GetURL())); - } -} - // Attempts to create a background host for a lazy background page. Returns true // if the background host is created. bool CreateLazyBackgroundHost(ProcessManager* pm, const Extension* extension) { @@ -101,7 +86,7 @@ const LazyContextId& context_id, LazyContextTaskQueue::PendingTask task) { AddPendingTask(context_id.browser_context(), context_id.extension_id(), - base::BindOnce(&PendingTaskAdapter, std::move(task))); + std::move(task)); } void LazyBackgroundTaskQueue::AddPendingTask( @@ -161,7 +146,7 @@ PendingTasksList tasks; tasks.swap(*map_it->second); for (auto& task : tasks) - std::move(task).Run(host); + std::move(task).Run(host ? std::make_unique<ContextInfo>(host) : nullptr); pending_tasks_.erase(key);
diff --git a/extensions/browser/lazy_background_task_queue.h b/extensions/browser/lazy_background_task_queue.h index 377756e7..b9173320 100644 --- a/extensions/browser/lazy_background_task_queue.h +++ b/extensions/browser/lazy_background_task_queue.h
@@ -42,8 +42,6 @@ public content::NotificationObserver, public ExtensionRegistryObserver { public: - using PendingTask = base::OnceCallback<void(ExtensionHost*)>; - explicit LazyBackgroundTaskQueue(content::BrowserContext* browser_context); ~LazyBackgroundTaskQueue() override; @@ -57,18 +55,17 @@ // cancels that suspension. bool ShouldEnqueueTask(content::BrowserContext* context, const Extension* extension) override; + // TODO(lazyboy): Find a better way to use AddPendingTask instead of this. - // Currently AddPendingTask has lots of consumers that depend on - // ExtensionHost. - void AddPendingTaskToDispatchEvent( - const LazyContextId& context_id, - LazyContextTaskQueue::PendingTask task) override; + void AddPendingTaskToDispatchEvent(const LazyContextId& context_id, + PendingTask task) override; // Adds a task to the queue for a given extension. If this is the first // task added for the extension, its lazy background page will be loaded. // The task will be called either when the page is loaded, or when the // page fails to load for some reason (e.g. a crash or browser - // shutdown). In the latter case, the ExtensionHost parameter is NULL. + // shutdown). In the latter case, |task| will be called with an empty + // std::unique_ptr<ContextItem> parameter. void AddPendingTask(content::BrowserContext* context, const std::string& extension_id, PendingTask task);
diff --git a/extensions/browser/lazy_background_task_queue_unittest.cc b/extensions/browser/lazy_background_task_queue_unittest.cc index 51e81a58..740e115 100644 --- a/extensions/browser/lazy_background_task_queue_unittest.cc +++ b/extensions/browser/lazy_background_task_queue_unittest.cc
@@ -73,7 +73,7 @@ TestProcessManager* process_manager() { return process_manager_; } // A simple callback for AddPendingTask. - void RunPendingTask(ExtensionHost* host) { + void RunPendingTask(std::unique_ptr<LazyContextTaskQueue::ContextInfo>) { task_run_count_++; }
diff --git a/extensions/browser/lazy_context_task_queue.cc b/extensions/browser/lazy_context_task_queue.cc new file mode 100644 index 0000000..f9585dfa --- /dev/null +++ b/extensions/browser/lazy_context_task_queue.cc
@@ -0,0 +1,34 @@ +// Copyright 2018 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 "extensions/browser/lazy_context_task_queue.h" +#include "extensions/browser/extension_host.h" +#include "extensions/common/constants.h" +#include "extensions/common/extension.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" + +namespace extensions { + +LazyContextTaskQueue::ContextInfo::ContextInfo(ExtensionHost* host) + : extension_id(host->extension()->id()), + render_process_host(host->render_process_host()), + service_worker_version_id(blink::mojom::kInvalidServiceWorkerVersionId), + worker_thread_id(kMainThreadId), + url(host->initial_url()), + browser_context(host->browser_context()), + web_contents(host->host_contents()) {} + +LazyContextTaskQueue::ContextInfo::ContextInfo( + const ExtensionId& extension_id, + content::RenderProcessHost* render_process_host, + int64_t service_worker_version_id, + int worker_thread_id, + const GURL& url) + : extension_id(extension_id), + render_process_host(render_process_host), + service_worker_version_id(service_worker_version_id), + worker_thread_id(worker_thread_id), + url(url) {} + +} // namespace extensions
diff --git a/extensions/browser/lazy_context_task_queue.h b/extensions/browser/lazy_context_task_queue.h index 6f44cea..f6ef47f 100644 --- a/extensions/browser/lazy_context_task_queue.h +++ b/extensions/browser/lazy_context_task_queue.h
@@ -12,10 +12,12 @@ namespace content { class BrowserContext; class RenderProcessHost; +class WebContents; } // namespace content namespace extensions { class Extension; +class ExtensionHost; class LazyContextId; // Interface for performing tasks after loading lazy contexts of an extension. @@ -33,16 +35,20 @@ const int64_t service_worker_version_id; const int worker_thread_id; const GURL url; + // TODO(dbertoni): This needs to be initialized for the Service Worker + // version of the constructor. + content::BrowserContext* const browser_context = nullptr; + // This data member will have a nullptr value for Service Worker-related + // tasks. + content::WebContents* const web_contents = nullptr; + + explicit ContextInfo(ExtensionHost* host); + ContextInfo(const ExtensionId& extension_id, content::RenderProcessHost* render_process_host, int64_t service_worker_version_id, int worker_thread_id, - const GURL& url) - : extension_id(extension_id), - render_process_host(render_process_host), - service_worker_version_id(service_worker_version_id), - worker_thread_id(worker_thread_id), - url(url) {} + const GURL& url); }; using PendingTask = base::OnceCallback<void(std::unique_ptr<ContextInfo> params)>;
diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc index fde870c..882c7e7 100644 --- a/extensions/browser/process_manager.cc +++ b/extensions/browser/process_manager.cc
@@ -114,9 +114,10 @@ BackgroundInfo::GetBackgroundURL(extension)); } -void PropagateExtensionWakeResult(base::OnceCallback<void(bool)> callback, - extensions::ExtensionHost* host) { - std::move(callback).Run(host != nullptr); +void PropagateExtensionWakeResult( + base::OnceCallback<void(bool)> callback, + std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) { + std::move(callback).Run(context_info != nullptr); } } // namespace
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc index ec9f45b1..93fdae99 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -58,13 +58,9 @@ SharedImageBacking* backing, MemoryTypeTracker* tracker, GLenum target, - GLenum internal_format, - GLenum driver_internal_format, GLuint service_id) : SharedImageRepresentationSkia(manager, backing, tracker), target_(target), - internal_format_(internal_format), - driver_internal_format_(driver_internal_format), service_id_(service_id) {} ~SharedImageRepresentationSkiaGLAHB() override { DCHECK(!write_surface_); } @@ -77,8 +73,8 @@ return nullptr; GrBackendTexture backend_texture; - if (!GetGrBackendTexture(target_, size(), internal_format_, - driver_internal_format_, service_id_, format(), + if (!GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), + target_, size(), service_id_, format(), &backend_texture)) { return nullptr; } @@ -100,8 +96,8 @@ } bool BeginReadAccess(GrBackendTexture* backend_texture) override { - if (!GetGrBackendTexture(target_, size(), internal_format_, - driver_internal_format_, service_id_, format(), + if (!GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), + target_, size(), service_id_, format(), backend_texture)) { return false; } @@ -114,8 +110,6 @@ private: GLenum target_; - GLenum internal_format_ = 0; - GLenum driver_internal_format_ = 0; GLuint service_id_; SkSurface* write_surface_ = nullptr; @@ -207,8 +201,7 @@ DCHECK(texture_); return std::make_unique<SharedImageRepresentationSkiaGLAHB>( - manager, this, tracker, texture_->target(), internal_format_, - driver_internal_format_, texture_->service_id()); + manager, this, tracker, texture_->target(), texture_->service_id()); } private: @@ -275,9 +268,7 @@ texture_->SetLevelImage(target, 0, egl_image.get(), gles2::Texture::BOUND); texture_->SetImmutable(true); api->glBindTextureFn(target, old_texture_binding); - internal_format_ = egl_image->GetInternalFormat(); - driver_internal_format_ = gl::GetInternalFormat( - gl::GLContext::GetCurrent()->GetVersionInfo(), internal_format_); + DCHECK_EQ(egl_image->GetInternalFormat(), gl_format); return true; } @@ -286,8 +277,6 @@ // This texture will be lazily initialised/created when ProduceGLTexture is // called. gles2::Texture* texture_ = nullptr; - GLenum internal_format_ = 0; - GLenum driver_internal_format_ = 0; // TODO(vikassoni): In future when we add begin/end write support, we will // need to properly use this flag to pass the is_cleared_ information to
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc index 0d9ba27..bc2c6b0 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
@@ -233,13 +233,9 @@ SharedImageBacking* backing, MemoryTypeTracker* tracker, GLenum target, - GLenum internal_format, - GLenum driver_internal_format, GLuint service_id) : SharedImageRepresentationSkia(manager, backing, tracker), target_(target), - internal_format_(internal_format), - driver_internal_format_(driver_internal_format), service_id_(service_id) {} ~SharedImageRepresentationSkiaImpl() override { DCHECK(!write_surface_); } @@ -252,8 +248,8 @@ return nullptr; GrBackendTexture backend_texture; - if (!GetGrBackendTexture(target_, size(), internal_format_, - driver_internal_format_, service_id_, format(), + if (!GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), + target_, size(), service_id_, format(), &backend_texture)) { return nullptr; } @@ -274,8 +270,8 @@ } bool BeginReadAccess(GrBackendTexture* backend_texture) override { - if (!GetGrBackendTexture(target_, size(), internal_format_, - driver_internal_format_, service_id_, format(), + if (!GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), + target_, size(), service_id_, format(), backend_texture)) { return false; } @@ -288,8 +284,6 @@ private: GLenum target_; - GLenum internal_format_ = 0; - GLenum driver_internal_format_ = 0; GLuint service_id_; SkSurface* write_surface_ = nullptr; @@ -304,18 +298,14 @@ const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage, - gles2::Texture* texture, - GLenum internal_format, - GLenum driver_internal_format) + gles2::Texture* texture) : SharedImageBacking(mailbox, format, size, color_space, usage, texture->estimated_size()), - texture_(texture), - internal_format_(internal_format), - driver_internal_format_(driver_internal_format) { + texture_(texture) { DCHECK(texture_); } @@ -390,14 +380,11 @@ SharedImageManager* manager, MemoryTypeTracker* tracker) override { return std::make_unique<SharedImageRepresentationSkiaImpl>( - manager, this, tracker, texture_->target(), internal_format_, - driver_internal_format_, texture_->service_id()); + manager, this, tracker, texture_->target(), texture_->service_id()); } private: gles2::Texture* texture_ = nullptr; - GLenum internal_format_ = 0; - GLenum driver_internal_format_ = 0; }; // Implementation of SharedImageBacking that creates a GL Texture and stores it @@ -412,8 +399,6 @@ const gfx::ColorSpace& color_space, uint32_t usage, scoped_refptr<gles2::TexturePassthrough> passthrough_texture, - GLenum internal_format, - GLenum driver_internal_format, bool is_cleared) : SharedImageBacking(mailbox, format, @@ -422,8 +407,6 @@ usage, passthrough_texture->estimated_size()), texture_passthrough_(std::move(passthrough_texture)), - internal_format_(internal_format), - driver_internal_format_(driver_internal_format), is_cleared_(is_cleared) { DCHECK(texture_passthrough_); } @@ -474,14 +457,11 @@ MemoryTypeTracker* tracker) override { return std::make_unique<SharedImageRepresentationSkiaImpl>( manager, this, tracker, texture_passthrough_->target(), - internal_format_, driver_internal_format_, texture_passthrough_->service_id()); } private: scoped_refptr<gles2::TexturePassthrough> texture_passthrough_; - GLenum internal_format_ = 0; - GLenum driver_internal_format_ = 0; bool is_cleared_ = false; }; @@ -860,12 +840,6 @@ const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage) { - // Calculate |driver_internal_format| here rather than caching on - // format_info, as we need to use the |level_info_internal_format| which may - // depend on the generated |image|. - GLenum driver_internal_format = - gl::GetInternalFormat(gl::GLContext::GetCurrent()->GetVersionInfo(), - level_info_internal_format); if (use_passthrough_) { scoped_refptr<gles2::TexturePassthrough> passthrough_texture = base::MakeRefCounted<gles2::TexturePassthrough>(service_id, target); @@ -881,8 +855,7 @@ return std::make_unique<SharedImageBackingPassthroughGLTexture>( mailbox, format, size, color_space, usage, - std::move(passthrough_texture), level_info_internal_format, - driver_internal_format, is_cleared); + std::move(passthrough_texture), is_cleared); } else { gles2::Texture* texture = new gles2::Texture(service_id); texture->SetLightweightRef(); @@ -901,8 +874,7 @@ texture->SetImmutable(true); return std::make_unique<SharedImageBackingGLTexture>( - mailbox, format, size, color_space, usage, texture, - level_info_internal_format, driver_internal_format); + mailbox, format, size, color_space, usage, texture); } }
diff --git a/gpu/command_buffer/service/skia_utils.cc b/gpu/command_buffer/service/skia_utils.cc index 4c88c838..5c4466b 100644 --- a/gpu/command_buffer/service/skia_utils.cc +++ b/gpu/command_buffer/service/skia_utils.cc
@@ -5,17 +5,19 @@ #include "gpu/command_buffer/service/skia_utils.h" #include "base/logging.h" +#include "components/viz/common/resources/resource_format_utils.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" #include "ui/gfx/geometry/size.h" #include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_gl_api_implementation.h" +#include "ui/gl/gl_version_info.h" namespace gpu { -bool GetGrBackendTexture(GLenum target, +bool GetGrBackendTexture(const gl::GLVersionInfo* version_info, + GLenum target, const gfx::Size& size, - GLenum internal_format, - GLenum driver_internal_format, GLuint service_id, viz::ResourceFormat resource_format, GrBackendTexture* gr_texture) { @@ -27,58 +29,8 @@ GrGLTextureInfo texture_info; texture_info.fID = service_id; texture_info.fTarget = target; - - // |driver_internal_format| may be a base internal format but Skia requires a - // sized internal format. So this may be adjusted below. - texture_info.fFormat = driver_internal_format; - switch (resource_format) { - case viz::RGBA_4444: - if (internal_format != GL_RGBA4 && internal_format != GL_RGBA) { - LOG(ERROR) - << "GetGrBackendTexture: color type mismatch. internal_format=0x" - << std::hex << internal_format; - return false; - } - if (texture_info.fFormat == GL_RGBA) - texture_info.fFormat = GL_RGBA4; - break; - case viz::RGBA_8888: - if (internal_format != GL_RGBA8_OES && internal_format != GL_RGBA) { - LOG(ERROR) - << "GetGrBackendTexture: color type mismatch. internal_format=0x" - << std::hex << internal_format; - return false; - } - if (texture_info.fFormat == GL_RGBA) - texture_info.fFormat = GL_RGBA8_OES; - break; - case viz::RGBX_8888: - if (internal_format != GL_RGB8_OES && internal_format != GL_RGB) { - LOG(ERROR) - << "GetGrBackendTexture: color type mismatch. internal_format=0x" - << std::hex << internal_format; - return false; - } - if (texture_info.fFormat == GL_RGB) - texture_info.fFormat = GL_RGB8_OES; - break; - case viz::BGRA_8888: - if (internal_format != GL_BGRA_EXT && internal_format != GL_BGRA8_EXT) { - LOG(ERROR) - << "GetGrBackendTexture: color type mismatch. internal_format=0x" - << std::hex << internal_format; - return false; - } - if (texture_info.fFormat == GL_BGRA_EXT) - texture_info.fFormat = GL_BGRA8_EXT; - if (texture_info.fFormat == GL_RGBA) - texture_info.fFormat = GL_RGBA8_OES; - break; - default: - LOG(ERROR) << "GetGrBackendTexture: unsupported color type."; - return false; - } - + texture_info.fFormat = gl::GetInternalFormat( + version_info, viz::TextureStorageFormat(resource_format)); *gr_texture = GrBackendTexture(size.width(), size.height(), GrMipMapped::kNo, texture_info); return true;
diff --git a/gpu/command_buffer/service/skia_utils.h b/gpu/command_buffer/service/skia_utils.h index 209b37f..1663146 100644 --- a/gpu/command_buffer/service/skia_utils.h +++ b/gpu/command_buffer/service/skia_utils.h
@@ -19,13 +19,16 @@ class Size; } // namespace gfx +namespace gl { +struct GLVersionInfo; +} // namespace gl + namespace gpu { // Creates a GrBackendTexture from a service ID. Skia does not take ownership. // Returns true on success. -GPU_GLES2_EXPORT bool GetGrBackendTexture(GLenum target, +GPU_GLES2_EXPORT bool GetGrBackendTexture(const gl::GLVersionInfo* version_info, + GLenum target, const gfx::Size& size, - GLenum internal_format, - GLenum driver_internal_format, GLuint service_id, viz::ResourceFormat resource_format, GrBackendTexture* gr_texture);
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc index a16ee29b..49f4386 100644 --- a/gpu/ipc/service/gpu_channel_manager.cc +++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -170,15 +170,6 @@ void GpuChannelManager::InternalDestroyGpuMemoryBuffer( gfx::GpuMemoryBufferId id, int client_id) { - io_task_runner_->PostTask( - FROM_HERE, - base::Bind(&GpuChannelManager::InternalDestroyGpuMemoryBufferOnIO, - base::Unretained(this), id, client_id)); -} - -void GpuChannelManager::InternalDestroyGpuMemoryBufferOnIO( - gfx::GpuMemoryBufferId id, - int client_id) { gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(id, client_id); } @@ -187,8 +178,8 @@ const SyncToken& sync_token) { if (!sync_point_manager_->WaitOutOfOrder( sync_token, - base::Bind(&GpuChannelManager::InternalDestroyGpuMemoryBuffer, - base::Unretained(this), id, client_id))) { + base::BindOnce(&GpuChannelManager::InternalDestroyGpuMemoryBuffer, + base::Unretained(this), id, client_id))) { // No sync token or invalid sync token, destroy immediately. InternalDestroyGpuMemoryBuffer(id, client_id); }
diff --git a/gpu/ipc/service/gpu_channel_manager.h b/gpu/ipc/service/gpu_channel_manager.h index 5296f4a2..945be948 100644 --- a/gpu/ipc/service/gpu_channel_manager.h +++ b/gpu/ipc/service/gpu_channel_manager.h
@@ -173,8 +173,7 @@ private: void InternalDestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id); - void InternalDestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id, - int client_id); + #if defined(OS_ANDROID) void ScheduleWakeUpGpu(); void DoWakeUpGpu();
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index e47667a1..aef11c05 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -3029,6 +3029,11 @@ short_name: "win" } builders { + name: "buildbucket/luci.chromium.ci/Chromium Linux Goma RBE ToT" + category: "rbe|tot|linux|rel" + short_name: "tot" + } + builders { name: "buildbot/chromium.goma/Chromium Linux Goma RBE Staging (clobber)" name: "buildbucket/luci.chromium.ci/Chromium Linux Goma RBE Staging (clobber)" category: "rbe|staging|linux|rel"
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index d2009c96..1676ed1 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -1490,9 +1490,7 @@ // because the currentTab will change after the switch. Tab* currentTab = self.currentTabModel.currentTab; if (currentTab) { - SnapshotTabHelper::FromWebState(currentTab.webState) - ->UpdateSnapshot(/*with_overlays=*/true, - /*visible_frame_only=*/true); + SnapshotTabHelper::FromWebState(currentTab.webState)->UpdateSnapshot(); } // Not for this browser state, send it on its way. [self switchModesAndOpenNewTab:command];
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state.h b/ios/chrome/browser/browser_state/chrome_browser_state.h index 58ae986e..8b8d1b1 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state.h +++ b/ios/chrome/browser/browser_state/chrome_browser_state.h
@@ -11,7 +11,6 @@ #include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/macros.h" -#include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "ios/chrome/browser/net/net_types.h" #include "ios/web/public/browser_state.h"
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state.mm b/ios/chrome/browser/browser_state/chrome_browser_state.mm index 823bd44..d2a958c 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state.mm +++ b/ios/chrome/browser/browser_state/chrome_browser_state.mm
@@ -83,9 +83,7 @@ if (!request_context_getter_) { ProtocolHandlerMap protocol_handlers; protocol_handlers[kChromeUIScheme] = - linked_ptr<net::URLRequestJobFactory::ProtocolHandler>( - web::URLDataManagerIOSBackend::CreateProtocolHandler(this) - .release()); + web::URLDataManagerIOSBackend::CreateProtocolHandler(this); request_context_getter_ = base::WrapRefCounted(CreateRequestContext(&protocol_handlers)); }
diff --git a/ios/chrome/browser/net/net_types.h b/ios/chrome/browser/net/net_types.h index 619e994..2d96ae0 100644 --- a/ios/chrome/browser/net/net_types.h +++ b/ios/chrome/browser/net/net_types.h
@@ -6,15 +6,15 @@ #define IOS_CHROME_BROWSER_NET_NET_TYPES_H_ #include <map> +#include <memory> #include <string> -#include "base/memory/linked_ptr.h" #include "net/url_request/url_request_job_factory.h" // A mapping from the scheme name to the protocol handler that services its // content. using ProtocolHandlerMap = std::map<std::string, - linked_ptr<net::URLRequestJobFactory::ProtocolHandler>>; + std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>>; #endif // IOS_CHROME_BROWSER_NET_NET_TYPES_H_
diff --git a/ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.cc b/ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.cc index fa9847c..1af565e 100644 --- a/ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.cc +++ b/ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.cc
@@ -21,7 +21,7 @@ ios::ChromeBrowserState::FromBrowserState(context); return std::make_unique<sessions::TabRestoreServiceImpl>( base::WrapUnique(new IOSChromeTabRestoreServiceClient(browser_state)), - nullptr); + browser_state->GetPrefs(), nullptr); } } // namespace
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.h b/ios/chrome/browser/snapshots/snapshot_generator.h index b2e01f6c..ff674f5 100644 --- a/ios/chrome/browser/snapshots/snapshot_generator.h +++ b/ios/chrome/browser/snapshots/snapshot_generator.h
@@ -46,23 +46,21 @@ // |callback| will be called with nil. - (void)retrieveGreySnapshot:(void (^)(UIImage*))callback; -// Invalidates the cached snapshot for the current page, generates and caches -// a new snapshot. Returns the snapshot with or without the overlaid views -// (e.g. infobar), and either of the visible frame or of the full screen. -- (UIImage*)updateSnapshotWithOverlays:(BOOL)shouldAddOverlay - visibleFrameOnly:(BOOL)visibleFrameOnly; +// Generates a new snapshot, updates the snapshot cache, and returns the new +// snapshot image. +- (UIImage*)updateSnapshot; -// Invalidates the cached snapshot for the current page, generates and caches -// a new snapshot. Calls |completion| with a snapshot with overlaid views (e.g. -// infobar) of the visible frame. This method should only be called if the web -// state has a valid web view. +// Asynchronously generates a new snapshot, updates the snapshot cache, and runs +// |callback| with the new snapshot image. It is an error to call this method if +// the web state is showing anything other (e.g., native content) than a web +// view. - (void)updateWebViewSnapshotWithCompletion:(void (^)(UIImage*))completion; -// Generates a new snapshot for the current page including optional infobars. -// Returns the snapshot with or without the overlaid views (e.g. infobar), and -// either of the visible frame or of the full screen. -- (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay - visibleFrameOnly:(BOOL)visibleFrameOnly; +// Generates a new snapshot and returns the new snapshot image. This does not +// update the snapshot cache. If |shouldAddOverlay| is YES, overlays (e.g., +// infobars, the download manager, and sad tab view) are also captured in the +// snapshot image. +- (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay; // Requests deletion of the current page snapshot from disk and memory. - (void)removeSnapshot;
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.mm b/ios/chrome/browser/snapshots/snapshot_generator.mm index d5b319a2..ba7227ae 100644 --- a/ios/chrome/browser/snapshots/snapshot_generator.mm +++ b/ios/chrome/browser/snapshots/snapshot_generator.mm
@@ -48,17 +48,6 @@ // Class that contains information used when caching snapshots of a web page. @interface CoalescingSnapshotContext : NSObject - -// Returns the cached snapshot if there is one matching the given parameters. -// Returns nil otherwise. -- (UIImage*)cachedSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays - visibleFrameOnly:(BOOL)visibleFrameOnly; - -// Caches |snapshot| for the given |overlays| and |visibleFrameOnly|. -- (void)setCachedSnapshot:(UIImage*)snapshot - withOverlays:(NSArray<SnapshotOverlay*>*)overlays - visibleFrameOnly:(BOOL)visibleFrameOnly; - @end @implementation CoalescingSnapshotContext { @@ -66,27 +55,25 @@ } // Returns whether a snapshot should be cached in a page loaded context. -// Note: Returns YES if |overlays| is nil or empty and if |visibleFrameOnly| is -// YES as this is the only case when the snapshot taken for the page is reused. -- (BOOL)shouldCacheSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays - visibleFrameOnly:(BOOL)visibleFrameOnly { - return visibleFrameOnly && ![overlays count]; +// Note: Returns YES if |overlays| is nil or empty as this is the only case when +// the snapshot taken for the page is reused. +- (BOOL)shouldCacheSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays { + return ![overlays count]; } -- (UIImage*)cachedSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays - visibleFrameOnly:(BOOL)visibleFrameOnly { - if ([self shouldCacheSnapshotWithOverlays:overlays - visibleFrameOnly:visibleFrameOnly]) { +// Returns the cached snapshot if there is one matching the given parameters. +// Returns nil otherwise. +- (UIImage*)cachedSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays { + if ([self shouldCacheSnapshotWithOverlays:overlays]) { return _cachedSnapshot; } return nil; } +// Caches |snapshot| for the given |overlays|. - (void)setCachedSnapshot:(UIImage*)snapshot - withOverlays:(NSArray<SnapshotOverlay*>*)overlays - visibleFrameOnly:(BOOL)visibleFrameOnly { - if ([self shouldCacheSnapshotWithOverlays:overlays - visibleFrameOnly:visibleFrameOnly]) { + withOverlays:(NSArray<SnapshotOverlay*>*)overlays { + if ([self shouldCacheSnapshotWithOverlays:overlays]) { DCHECK(!_cachedSnapshot); _cachedSnapshot = snapshot; } @@ -96,24 +83,6 @@ @interface SnapshotGenerator ()<CRWWebStateObserver> -// Returns the frame of the snapshot. Will return an empty rectangle if the -// WebState is not ready to capture a snapshot. -- (CGRect)snapshotFrameVisibleFrameOnly:(BOOL)visibleFrameOnly; - -// Takes a snapshot for the supplied view (which should correspond to the given -// type of web view). Returns an autoreleased image cropped and scaled -// appropriately. The image can also contain overlays (if |overlays| is not -// nil and not empty). -- (UIImage*)generateSnapshotForView:(UIView*)view - withRect:(CGRect)rect - overlays:(NSArray<SnapshotOverlay*>*)overlays; - -// Returns an image of the |snapshot| overlaid with |overlays| with the given -// |frame|. -- (UIImage*)snapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays - snapshot:(UIImage*)snapshot - frame:(CGRect)frame; - // Property providing access to the snapshot's cache. May be nil. @property(nonatomic, readonly) SnapshotCache* snapshotCache; @@ -126,8 +95,6 @@ web::WebState* _webState; } -@synthesize delegate = _delegate; - - (instancetype)initWithWebState:(web::WebState*)webState snapshotSessionId:(NSString*)snapshotSessionId { if ((self = [super init])) { @@ -151,7 +118,7 @@ } - (CGSize)snapshotSize { - return [self snapshotFrameVisibleFrameOnly:YES].size; + return [self snapshotFrame].size; } - (void)setSnapshotCoalescingEnabled:(BOOL)snapshotCoalescingEnabled { @@ -189,7 +156,7 @@ __weak SnapshotGenerator* weakSelf = self; void (^wrappedCallback)(UIImage*) = ^(UIImage* image) { if (!image) { - image = [weakSelf updateSnapshotWithOverlays:YES visibleFrameOnly:YES]; + image = [weakSelf updateSnapshot]; if (image) image = GreyImage(image); } @@ -205,10 +172,8 @@ } } -- (UIImage*)updateSnapshotWithOverlays:(BOOL)shouldAddOverlay - visibleFrameOnly:(BOOL)visibleFrameOnly { - UIImage* snapshot = [self generateSnapshotWithOverlays:shouldAddOverlay - visibleFrameOnly:visibleFrameOnly]; +- (UIImage*)updateSnapshot { + UIImage* snapshot = [self generateSnapshotWithOverlays:YES]; // Return default snapshot without caching it if the generation failed. if (!snapshot) { return [[self class] defaultSnapshotImage]; @@ -222,9 +187,8 @@ DCHECK(_webState); UIView* snapshotView = [self.delegate snapshotGenerator:self baseViewForWebState:_webState]; - CGRect snapshotFrame = [self snapshotFrameVisibleFrameOnly:YES]; - snapshotFrame = - [_webState->GetView() convertRect:snapshotFrame fromView:snapshotView]; + CGRect snapshotFrame = [_webState->GetView() convertRect:[self snapshotFrame] + fromView:snapshotView]; if (CGRectIsEmpty(snapshotFrame)) { if (completion) { base::PostTaskWithTraits(FROM_HERE, {web::WebThread::UI}, @@ -242,8 +206,7 @@ NSArray<SnapshotOverlay*>* overlays = [_delegate snapshotGenerator:self snapshotOverlaysForWebState:_webState]; UIImage* snapshot = - [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays - visibleFrameOnly:YES]; + [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays]; if (snapshot) { if (completion) { base::PostTaskWithTraits(FROM_HERE, {web::WebThread::UI}, @@ -273,8 +236,7 @@ [strongSelf.snapshotCache setImage:snapshot withSessionID:_snapshotSessionId]; [_coalescingSnapshotContext setCachedSnapshot:snapshot - withOverlays:overlays - visibleFrameOnly:YES]; + withOverlays:overlays]; [_delegate snapshotGenerator:self didUpdateSnapshotForWebState:_webState withImage:snapshot]; @@ -283,9 +245,8 @@ })); } -- (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay - visibleFrameOnly:(BOOL)visibleFrameOnly { - CGRect frame = [self snapshotFrameVisibleFrameOnly:visibleFrameOnly]; +- (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay { + CGRect frame = [self snapshotFrame]; if (CGRectIsEmpty(frame)) return nil; @@ -294,8 +255,7 @@ snapshotOverlaysForWebState:_webState] : nil; UIImage* snapshot = - [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays - visibleFrameOnly:visibleFrameOnly]; + [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays]; if (snapshot) return snapshot; @@ -305,9 +265,7 @@ baseViewForWebState:_webState]; snapshot = [self generateSnapshotForView:view withRect:frame overlays:overlays]; - [_coalescingSnapshotContext setCachedSnapshot:snapshot - withOverlays:overlays - visibleFrameOnly:visibleFrameOnly]; + [_coalescingSnapshotContext setCachedSnapshot:snapshot withOverlays:overlays]; [_delegate snapshotGenerator:self didUpdateSnapshotForWebState:_webState withImage:snapshot]; @@ -337,7 +295,9 @@ #pragma mark - Private methods -- (CGRect)snapshotFrameVisibleFrameOnly:(BOOL)visibleFrameOnly { +// Returns the frame of the snapshot. Will return an empty rectangle if the +// WebState is not ready to capture a snapshot. +- (CGRect)snapshotFrame { // Do not generate a snapshot if web usage is disabled (as the WebState's // view is blank in that case). if (!_webState->IsWebUsageEnabled()) @@ -351,20 +311,15 @@ UIView* view = [_delegate snapshotGenerator:self baseViewForWebState:_webState]; - CGRect frame = [view bounds]; - UIEdgeInsets headerInsets = UIEdgeInsetsZero; - if (visibleFrameOnly) { - headerInsets = [_delegate snapshotGenerator:self - snapshotEdgeInsetsForWebState:_webState]; - } else if (base::FeatureList::IsEnabled( - web::features::kBrowserContainerFullscreen)) { - headerInsets = UIEdgeInsetsMake(StatusBarHeight(), 0, 0, 0); - } - frame = UIEdgeInsetsInsetRect(frame, headerInsets); - - return frame; + UIEdgeInsets headerInsets = [_delegate snapshotGenerator:self + snapshotEdgeInsetsForWebState:_webState]; + return UIEdgeInsetsInsetRect(view.bounds, headerInsets); } +// Takes a snapshot for the supplied view (which should correspond to the given +// type of web view). Returns an autoreleased image cropped and scaled +// appropriately. The image can also contain overlays (if |overlays| is not +// nil and not empty). - (UIImage*)generateSnapshotForView:(UIView*)view withRect:(CGRect)rect overlays:(NSArray<SnapshotOverlay*>*)overlays { @@ -421,6 +376,8 @@ return image; } +// Returns an image of the |snapshot| overlaid with |overlays| with the given +// |frame|. - (UIImage*)snapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays snapshot:(UIImage*)snapshot frame:(CGRect)frame { @@ -452,7 +409,7 @@ return snapshotWithOverlays; } -#pragma mark - Properties. +#pragma mark - Properties - (SnapshotCache*)snapshotCache { return SnapshotCacheFactory::GetForBrowserState(
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.h b/ios/chrome/browser/snapshots/snapshot_tab_helper.h index 4349b895..f3dbe40a 100644 --- a/ios/chrome/browser/snapshots/snapshot_tab_helper.h +++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.h
@@ -50,22 +50,17 @@ // asynchronously after retrieved from disk or re-generated. void RetrieveGreySnapshot(void (^callback)(UIImage*)); - // Invalidates the cached snapshot for the current page and forces the - // generation of a more recent snapshot. Runs |callback| with a snapshot with - // overlaid views (e.g. infobar) of the visible frame. In iOS 11+, snapshots - // of a valid web view are taken using WKWebView's snapshotting API. + // Asynchronously generates a new snapshot, updates the snapshot cache, and + // runs |callback| with the new snapshot image. void UpdateSnapshotWithCallback(void (^callback)(UIImage*)); - // Invalidates the cached snapshot for the current page and forces the - // generation of a more recent snapshot. Returns the snapshot with or - // without the overlaid views (e.g. infobar) and either of the visible frame - // or of the full screen. - UIImage* UpdateSnapshot(bool with_overlays, bool visible_frame_only); + // Generates a new snapshot, updates the snapshot cache, and returns the new + // snapshot image. + UIImage* UpdateSnapshot(); - // Generates a snapshot for the current page. Returns the snapshot with - // or without the overlaid views (e.g. infobar) and either of the visible - // frame of of the full screen. - UIImage* GenerateSnapshot(bool with_overlays, bool visible_frame_only); + // Generates a new snapshot without any overlays, and returns the new snapshot + // image. This does not update the snapshot cache. + UIImage* GenerateSnapshotWithoutOverlays(); // When snapshot coalescing is enabled, multiple calls to generate a // snapshot with the same parameters may be coalesced.
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm index 2417640..4aaab675 100644 --- a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm +++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
@@ -78,8 +78,7 @@ void SnapshotInfobarObserver::OnInfoBarChanges() { // Update the page snapshot on any infobar change. - owner_->UpdateSnapshot(/*with_overlays=*/true, - /*visible_frame_only=*/true); + owner_->UpdateSnapshot(); } void SnapshotInfobarObserver::OnManagerShuttingDown( @@ -131,24 +130,19 @@ return; } // Native content cannot utilize the WKWebView snapshotting API. - UIImage* image = - UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true); + UIImage* image = UpdateSnapshot(); dispatch_async(dispatch_get_main_queue(), ^{ if (callback) callback(image); }); } -UIImage* SnapshotTabHelper::UpdateSnapshot(bool with_overlays, - bool visible_frame_only) { - return [snapshot_generator_ updateSnapshotWithOverlays:with_overlays - visibleFrameOnly:visible_frame_only]; +UIImage* SnapshotTabHelper::UpdateSnapshot() { + return [snapshot_generator_ updateSnapshot]; } -UIImage* SnapshotTabHelper::GenerateSnapshot(bool with_overlays, - bool visible_frame_only) { - return [snapshot_generator_ generateSnapshotWithOverlays:with_overlays - visibleFrameOnly:visible_frame_only]; +UIImage* SnapshotTabHelper::GenerateSnapshotWithoutOverlays() { + return [snapshot_generator_ generateSnapshotWithOverlays:NO]; } void SnapshotTabHelper::SetSnapshotCoalescingEnabled(bool enabled) { @@ -203,7 +197,7 @@ return; } // Native content cannot utilize the WKWebView snapshotting API. - UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true); + UpdateSnapshot(); } ignore_next_load_ = false; }
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm index eaea9e0..e1bd497 100644 --- a/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm +++ b/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm
@@ -309,9 +309,8 @@ SetCachedSnapshot( UIImageWithSizeAndSolidColor(kDefaultSnapshotSize, [UIColor greenColor])); - UIImage* snapshot = SnapshotTabHelper::FromWebState(&web_state_) - ->UpdateSnapshot(/*with_overlays=*/true, - /*visibible_frame_only=*/true); + UIImage* snapshot = + SnapshotTabHelper::FromWebState(&web_state_)->UpdateSnapshot(); ASSERT_TRUE(snapshot); EXPECT_TRUE(CGSizeEqualToSize(snapshot.size, kWebStateViewSize)); @@ -326,9 +325,8 @@ // will cause a new snapshot to be generated. TEST_F(SnapshotTabHelperTest, UpdateSnapshotNoCoalescing) { for (NSUInteger ii = 0; ii < kCountSnapshotToTake; ++ii) { - UIImage* snapshot = SnapshotTabHelper::FromWebState(&web_state_) - ->UpdateSnapshot(/*with_overlays=*/true, - /*visibible_frame_only=*/true); + UIImage* snapshot = + SnapshotTabHelper::FromWebState(&web_state_)->UpdateSnapshot(); ASSERT_TRUE(snapshot); EXPECT_TRUE(CGSizeEqualToSize(snapshot.size, kWebStateViewSize)); @@ -344,9 +342,8 @@ SnapshotTabHelper::FromWebState(&web_state_) ->SetSnapshotCoalescingEnabled(true); for (NSUInteger ii = 0; ii < kCountSnapshotToTake; ++ii) { - UIImage* snapshot = SnapshotTabHelper::FromWebState(&web_state_) - ->UpdateSnapshot(/*with_overlays=*/true, - /*visibible_frame_only=*/true); + UIImage* snapshot = + SnapshotTabHelper::FromWebState(&web_state_)->UpdateSnapshot(); ASSERT_TRUE(snapshot); EXPECT_TRUE(CGSizeEqualToSize(snapshot.size, kWebStateViewSize)); @@ -365,8 +362,7 @@ UIImageWithSizeAndSolidColor(kDefaultSnapshotSize, [UIColor greenColor])); UIImage* snapshot = SnapshotTabHelper::FromWebState(&web_state_) - ->GenerateSnapshot(/*with_overlays=*/true, - /*visibible_frame_only=*/true); + ->GenerateSnapshotWithoutOverlays(); ASSERT_TRUE(snapshot); EXPECT_TRUE(CGSizeEqualToSize(snapshot.size, kWebStateViewSize)); @@ -381,8 +377,7 @@ TEST_F(SnapshotTabHelperTest, GenerateSnapshotNoCoalescing) { for (NSUInteger ii = 0; ii < kCountSnapshotToTake; ++ii) { UIImage* snapshot = SnapshotTabHelper::FromWebState(&web_state_) - ->GenerateSnapshot(/*with_overlays=*/true, - /*visibible_frame_only=*/true); + ->GenerateSnapshotWithoutOverlays(); ASSERT_TRUE(snapshot); EXPECT_TRUE(CGSizeEqualToSize(snapshot.size, kWebStateViewSize)); @@ -399,8 +394,7 @@ ->SetSnapshotCoalescingEnabled(true); for (NSUInteger ii = 0; ii < kCountSnapshotToTake; ++ii) { UIImage* snapshot = SnapshotTabHelper::FromWebState(&web_state_) - ->GenerateSnapshot(/*with_overlays=*/true, - /*visibible_frame_only=*/true); + ->GenerateSnapshotWithoutOverlays(); ASSERT_TRUE(snapshot); EXPECT_TRUE(CGSizeEqualToSize(snapshot.size, kWebStateViewSize));
diff --git a/ios/chrome/browser/ui/activity_services/chrome_activity_item_thumbnail_generator.mm b/ios/chrome/browser/ui/activity_services/chrome_activity_item_thumbnail_generator.mm index 8a71350..9d936a9 100644 --- a/ios/chrome/browser/ui/activity_services/chrome_activity_item_thumbnail_generator.mm +++ b/ios/chrome/browser/ui/activity_services/chrome_activity_item_thumbnail_generator.mm
@@ -29,8 +29,7 @@ return nil; UIImage* snapshot = SnapshotTabHelper::FromWebState(strongTab.webState) - ->GenerateSnapshot(/*with_overlays=*/false, - /*visible_frame_only=*/true); + ->GenerateSnapshotWithoutOverlays(); if (!snapshot) return nil;
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index be4ba853..f071f3c4 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -1230,8 +1230,7 @@ // have enough time to finish appearing before a snapshot is requested. Tab* currentTab = self.tabModel.currentTab; if (currentTab && self.viewVisible) { - SnapshotTabHelper::FromWebState(currentTab.webState) - ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true); + SnapshotTabHelper::FromWebState(currentTab.webState)->UpdateSnapshot(); } [self.tabModel insertTabWithLoadParams:CreateWebLoadParams( @@ -3230,8 +3229,7 @@ // Requested web state should not be blocked from opening. Tab* currentTab = LegacyTabHelper::GetTabForWebState(webState); - SnapshotTabHelper::FromWebState(currentTab.webState) - ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true); + SnapshotTabHelper::FromWebState(currentTab.webState)->UpdateSnapshot(); Tab* childTab = [[self tabModel] insertOpenByDOMTabWithOpener:currentTab]; @@ -4191,9 +4189,7 @@ // If the page has finished loading, take a snapshot. If the page is // still loading, do nothing, as the tab helper will automatically take // a snapshot once the load completes. - SnapshotTabHelper::FromWebState(newTab.webState) - ->UpdateSnapshot( - /*with_overlays=*/true, /*visible_frame_only=*/true); + SnapshotTabHelper::FromWebState(newTab.webState)->UpdateSnapshot(); } if (typed_or_generated_transition) { @@ -4594,8 +4590,7 @@ // iPad. UIImageView* exitingPage = [self pageOpenCloseAnimationView]; exitingPage.image = - SnapshotTabHelper::FromWebState(currentTab.webState) - ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true); + SnapshotTabHelper::FromWebState(currentTab.webState)->UpdateSnapshot(); // Close the actual tab, and add its image as a subview. [self.tabModel closeTabAtIndex:tabIndex]; @@ -4853,9 +4848,8 @@ newPage.userInteractionEnabled = NO; } else { UIImageView* pageScreenshot = [self pageOpenCloseAnimationView]; - pageScreenshot.image = SnapshotTabHelper::FromWebState(tab.webState) - ->UpdateSnapshot(/*with_overlays=*/true, - /*visible_frame_only=*/true); + pageScreenshot.image = + SnapshotTabHelper::FromWebState(tab.webState)->UpdateSnapshot(); newPage = pageScreenshot; } }
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm index a0813cf..5db2939 100644 --- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -243,19 +243,6 @@ @"incididunt ut labore et dolore magna aliqua."; [model addItem:multilineItem toSectionWithIdentifier:SectionIdentifierMultilineCell]; - ImportDataMultilineDetailItem* multilineDetailItem = - [[ImportDataMultilineDetailItem alloc] - initWithType:ItemTypeImportDataMultiline]; - multilineDetailItem.text = - @"Lorem ipsum dolor sit amet, consectetur " - @"adipiscing elit, sed do eiusmod tempor " - @"incididunt ut labore et dolore magna aliqua."; - multilineDetailItem.detailText = - @"Lorem ipsum dolor sit amet, consectetur " - @"adipiscing elit, sed do eiusmod tempor " - @"incididunt ut labore et dolore magna aliqua."; - [model addItem:multilineDetailItem - toSectionWithIdentifier:SectionIdentifierMultilineCell]; [model addItem:[self settingsImageDetailTextItem] toSectionWithIdentifier:SectionIdentifierMultilineCell]; SettingsImageDetailTextItem* settingsImageDetailTextItem = @@ -384,11 +371,6 @@ [model addItem:[self passwordDetailsLongItem] toSectionWithIdentifier:SectionIdentifierPasswordDetails]; - // Search cells. - [model addSectionWithIdentifier:SectionIdentifierSettingsSearchCell]; - [model addItem:[self settingsSearchItem] - toSectionWithIdentifier:SectionIdentifierSettingsSearchCell]; - // Account cells. [model addSectionWithIdentifier:SectionIdentifierAccountCell]; [model addItem:[self accountItemDetailWithError] @@ -869,11 +851,4 @@ return item; } -- (SettingsSearchItem*)settingsSearchItem { - SettingsSearchItem* item = - [[SettingsSearchItem alloc] initWithType:ItemTypeSettingsSearch]; - item.placeholder = @"Search Here"; - return item; -} - @end
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm index 57a2f27..4114126c 100644 --- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm +++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
@@ -334,7 +334,7 @@ FullscreenControllerFactory::GetInstance()->GetForBrowserState( browserState_)); SnapshotTabHelper::FromWebState([model_ currentTab].webState) - ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true); + ->UpdateSnapshot(); [[NSNotificationCenter defaultCenter] postNotificationName:kSideSwipeWillStartNotification object:nil]; @@ -525,8 +525,7 @@ } // Ensure that there's an up-to-date snapshot of the current tab. - SnapshotTabHelper::FromWebState(currentTab.webState) - ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true); + SnapshotTabHelper::FromWebState(currentTab.webState)->UpdateSnapshot(); // Hide the infobar after snapshot has been updated (see the previous line) // to avoid it obscuring the cards in the side swipe view.
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm index da73c04..a681f904 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -1671,8 +1671,7 @@ Tab* tappedTab = [_tabModel tabAtIndex:index]; Tab* currentTab = [_tabModel currentTab]; if (IsIPadIdiom() && (currentTab != tappedTab)) { - SnapshotTabHelper::FromWebState(currentTab.webState) - ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true); + SnapshotTabHelper::FromWebState(currentTab.webState)->UpdateSnapshot(); } [_tabModel setCurrentTab:tappedTab]; [self updateContentOffsetForTabIndex:index isNewTab:NO];
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc index 7032a2d..e570296 100644 --- a/media/gpu/v4l2/v4l2_device.cc +++ b/media/gpu/v4l2/v4l2_device.cc
@@ -1166,13 +1166,6 @@ int coded_height = sizeimage * 8 / coded_width / total_bpp; coded_size.SetSize(coded_width, coded_height); - // It's possible the driver gave us a slightly larger sizeimage than what - // would be calculated from coded size. This is technically not allowed, but - // some drivers (Exynos) like to have some additional alignment that is not a - // multiple of bytesperline. The best thing we can do is to compensate by - // aligning to next full row. - if (sizeimage > VideoFrame::AllocationSize(frame_format, coded_size)) - coded_size.SetSize(coded_width, coded_height + 1); DVLOGF(3) << "coded_size=" << coded_size.ToString(); // Sanity checks. Calculated coded size has to contain given visible size
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc index 77ffa63..6fc6db3 100644 --- a/media/gpu/v4l2/v4l2_image_processor.cc +++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -238,6 +238,11 @@ format.fmt.pix_mp.width = output_layout.coded_size().width(); format.fmt.pix_mp.height = output_layout.coded_size().height(); format.fmt.pix_mp.pixelformat = output_format_fourcc; + for (size_t i = 0; i < output_layout.num_buffers(); ++i) { + format.fmt.pix_mp.plane_fmt[i].sizeimage = output_layout.buffer_sizes()[i]; + format.fmt.pix_mp.plane_fmt[i].bytesperline = + output_layout.planes()[i].stride; + } if (device->Ioctl(VIDIOC_S_FMT, &format) != 0 || format.fmt.pix_mp.pixelformat != output_format_fourcc) { VLOGF(1) << "Failed to negotiate output format";
diff --git a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h index 6daf769..48b9d1f 100644 --- a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h +++ b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.h
@@ -13,7 +13,6 @@ #include "base/containers/queue.h" #include "base/macros.h" -#include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h"
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc index cba9a95..d855aef6 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -124,8 +124,6 @@ const scoped_refptr<V4L2Device>& device) : child_task_runner_(base::ThreadTaskRunnerHandle::Get()), output_buffer_byte_size_(0), - device_input_format_(PIXEL_FORMAT_UNKNOWN), - input_planes_count_(0), output_format_fourcc_(0), encoder_state_(kUninitialized), device_(device), @@ -198,9 +196,10 @@ return false; } - if (config.input_format != device_input_format_) { - VLOGF(2) << "Input format not supported by the HW, will try to convert to " - << VideoPixelFormatToString(device_input_format_); + if (config.input_format != device_input_layout_->format()) { + VLOGF(2) << "Input format: " << config.input_format << " is not supported " + << "by the HW. Will try to convert to " + << device_input_layout_->format(); if (!V4L2ImageProcessor::IsSupported()) { VLOGF(1) << "Image processor not available"; @@ -220,29 +219,21 @@ VLOGF(1) << "Invalid image processor input layout"; return false; } - auto output_layout = VideoFrameLayout::CreateWithStrides( - device_input_format_, input_allocated_size_, - std::vector<int32_t>( - VideoFrameLayout::NumPlanes(device_input_format_)) /* strides */, - std::vector<size_t>( - VideoFrameLayout::NumPlanes(device_input_format_)) /* buffers */); - if (!output_layout) { - VLOGF(1) << "Invalid image processor output layout"; - return false; - } - // Convert from |config.input_format| to |device_input_format_|, keeping the - // size at |visible_size_| and requiring the output buffers to be of at - // least |input_allocated_size_|. Unretained is safe because |this| owns - // image processor and there will be no callbacks after processor destroys. - // |input_storage_type| can be STORAGE_SHMEM and STORAGE_MOJO_SHARED_BUFFER. - // However, it doesn't matter VideoFrame::STORAGE_OWNED_MEMORY is specified - // for |input_storage_type| here, as long as VideoFrame on Process()'s data - // can be accessed by VideoFrame::data(). + // Convert from |config.input_format| to |device_input_layout_->format()|, + // keeping the size at |visible_size_| and requiring the output buffers to + // be of at least |device_input_layout_->coded_size()|. + // Unretained is safe because |this| owns image processor and there will be + // no callbacks after processor destroys. + // |input_storage_type| can be STORAGE_SHMEM and + // STORAGE_MOJO_SHARED_BUFFER. However, it doesn't matter + // VideoFrame::STORAGE_OWNED_MEMORY is specified for |input_storage_type| + // here, as long as VideoFrame on Process()'s data can be accessed by + // VideoFrame::data(). image_processor_ = V4L2ImageProcessor::Create( V4L2Device::Create(), VideoFrame::STORAGE_OWNED_MEMORY, VideoFrame::STORAGE_DMABUFS, ImageProcessor::OutputMode::ALLOCATE, - *input_layout, *output_layout, visible_size_, visible_size_, + *input_layout, *device_input_layout_, visible_size_, visible_size_, kImageProcBufferCount, base::Bind(&V4L2VideoEncodeAccelerator::ImageProcessorError, base::Unretained(this))); @@ -256,13 +247,13 @@ // input coded height of encoder. For example, suppose input size of encoder // is 320x193. It is OK if the output of processor is 320x208. if (image_processor_->output_allocated_size().width() != - input_allocated_size_.width() || + device_input_layout_->coded_size().width() || image_processor_->output_allocated_size().height() < - input_allocated_size_.height()) { + device_input_layout_->coded_size().height()) { VLOGF(1) << "Invalid image processor output coded size " << image_processor_->output_allocated_size().ToString() << ", encode input coded size is " - << input_allocated_size_.ToString(); + << device_input_layout_->coded_size().ToString(); return false; } @@ -305,7 +296,7 @@ base::Bind(&Client::RequireBitstreamBuffers, client_, kInputBufferCount, image_processor_.get() ? image_processor_->input_allocated_size() - : input_allocated_size_, + : device_input_layout_->coded_size(), output_buffer_byte_size_)); return true; } @@ -734,7 +725,7 @@ dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; dqbuf.memory = input_memory_type_; dqbuf.m.planes = planes; - dqbuf.length = input_planes_count_; + dqbuf.length = device_input_layout_->num_buffers(); if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) { if (errno == EAGAIN) { // EAGAIN if we're just out of buffers to dequeue. @@ -853,16 +844,27 @@ qbuf.timestamp.tv_usec = frame->timestamp().InMicroseconds() - frame->timestamp().InSeconds() * base::Time::kMicrosecondsPerSecond; - DCHECK_EQ(device_input_format_, frame->format()); + DCHECK_EQ(device_input_layout_->format(), frame->format()); - for (size_t i = 0; i < input_planes_count_; ++i) { - qbuf.m.planes[i].bytesused = base::checked_cast<__u32>( - VideoFrame::PlaneSize(frame->format(), i, input_allocated_size_) - .GetArea()); + for (size_t i = 0; i < device_input_layout_->num_buffers(); ++i) { + // Single-buffer input format may have multiple color planes, so bytesused + // of the single buffer should be sum of each color planes' size. + if (device_input_layout_->num_buffers() == 1) { + qbuf.m.planes[i].bytesused = VideoFrame::AllocationSize( + frame->format(), device_input_layout_->coded_size()); + } else { + DCHECK_EQ(device_input_layout_->num_buffers(), + VideoFrame::NumPlanes(device_input_layout_->format())); + qbuf.m.planes[i].bytesused = base::checked_cast<__u32>( + VideoFrame::PlaneSize(frame->format(), i, + device_input_layout_->coded_size()) + .GetArea()); + } switch (input_memory_type_) { case V4L2_MEMORY_USERPTR: - qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused; + // Use buffer_size VEA HW requested by S_FMT. + qbuf.m.planes[i].length = device_input_layout_->buffer_sizes()[i]; qbuf.m.planes[i].m.userptr = reinterpret_cast<unsigned long>(frame->data(i)); DCHECK(qbuf.m.planes[i].m.userptr); @@ -871,7 +873,7 @@ case V4L2_MEMORY_DMABUF: { const auto& fds = frame->DmabufFds(); const auto& planes = frame->layout().planes(); - DCHECK_EQ(input_planes_count_, planes.size()); + DCHECK_EQ(device_input_layout_->num_buffers(), planes.size()); qbuf.m.planes[i].m.fd = (i < fds.size()) ? fds[i].get() : fds.back().get(); // TODO(crbug.com/901264): The way to pass an offset within a DMA-buf is @@ -882,7 +884,8 @@ qbuf.m.planes[i].bytesused += qbuf.m.planes[i].data_offset; // Workaround: filling length should not be needed. This is a bug of // videobuf2 library. - qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused; + qbuf.m.planes[i].length = device_input_layout_->buffer_sizes()[i] + + qbuf.m.planes[i].data_offset; DCHECK_NE(qbuf.m.planes[i].m.fd, -1); break; } @@ -893,7 +896,7 @@ } qbuf.memory = input_memory_type_; - qbuf.length = input_planes_count_; + qbuf.length = device_input_layout_->num_buffers(); DVLOGF(4) << "Calling VIDIOC_QBUF: " << V4L2Device::V4L2BufferToString(qbuf); IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); @@ -1122,11 +1125,7 @@ DCHECK(!input_streamon_); DCHECK(!output_streamon_); - device_input_format_ = PIXEL_FORMAT_UNKNOWN; - input_planes_count_ = 0; - // First see if the device can use the provided format directly. - // V4L2 VEA only supports multi plane input pixel format. std::vector<uint32_t> pix_fmt_candidates = { V4L2Device::VideoPixelFormatToV4L2PixFmt(input_format, false)}; // Second try preferred input formats for both single-planar and @@ -1143,7 +1142,6 @@ DCHECK_LE(planes_count, static_cast<size_t>(VIDEO_MAX_PLANES)); VLOGF(2) << "Trying S_FMT with " << FourccToString(pix_fmt) << " (" << trying_format << ")."; - struct v4l2_format format; memset(&format, 0, sizeof(format)); format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; @@ -1153,24 +1151,23 @@ format.fmt.pix_mp.num_planes = planes_count; if (device_->Ioctl(VIDIOC_S_FMT, &format) == 0 && format.fmt.pix_mp.pixelformat == pix_fmt) { - VLOGF(2) << "Success: S_FMT with" << FourccToString(pix_fmt); - // Take device-adjusted sizes for allocated size. If the size is adjusted - // down, it means the input is too big and the hardware does not support - // it. - auto adjusted_size = V4L2Device::CodedSizeFromV4L2Format(format); - if (!gfx::Rect(adjusted_size).Contains(gfx::Rect(visible_size_))) { - VLOGF(1) << "Input size too big " << visible_size_.ToString() - << ", adjusted to " << adjusted_size.ToString(); + VLOGF(2) << "Success: S_FMT with " << FourccToString(pix_fmt); + device_input_layout_ = V4L2Device::V4L2FormatToVideoFrameLayout(format); + if (!device_input_layout_) { + VLOGF(1) << "Invalid device_input_layout_"; return false; } - - device_input_format_ = trying_format; - input_planes_count_ = planes_count; - input_allocated_size_ = adjusted_size; + VLOG(2) << "Negotiated device_input_layout_: " << *device_input_layout_; + if (!gfx::Rect(device_input_layout_->coded_size()) + .Contains(gfx::Rect(visible_size_))) { + VLOGF(1) << "Input size " << visible_size_.ToString() + << " exceeds encoder capability. Size encoder can handle: " + << device_input_layout_->coded_size().ToString(); + return false; + } return true; } } - return false; }
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.h b/media/gpu/v4l2/v4l2_video_encode_accelerator.h index abd3671..4d24233 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.h +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
@@ -15,7 +15,9 @@ #include "base/containers/queue.h" #include "base/files/scoped_file.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/threading/thread.h" #include "base/time/time.h" #include "media/gpu/image_processor.h" @@ -226,13 +228,9 @@ const scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; gfx::Size visible_size_; - // Input allocated size required by the device. - gfx::Size input_allocated_size_; + // Layout of device accepted input VideoFrame. + base::Optional<VideoFrameLayout> device_input_layout_; size_t output_buffer_byte_size_; - - // Formats for input frames and the output stream. - VideoPixelFormat device_input_format_; - size_t input_planes_count_; uint32_t output_format_fourcc_; //
diff --git a/media/test/data/eme_load_session_after_close_test.html b/media/test/data/eme_load_session_after_close_test.html new file mode 100644 index 0000000..e5b1f9a --- /dev/null +++ b/media/test/data/eme_load_session_after_close_test.html
@@ -0,0 +1,145 @@ +<!DOCTYPE html> +<title>Test that load() succeeds on a session just closed</title> +<div id="logs"></div> +<script src='eme_player_js/app_loader.js' type='text/javascript'></script> +<script type='text/javascript'> + // This test only uses |keySystem| and |licenseServerURL|. + var testConfig = new TestConfig(); + testConfig.loadQueryParams(); + + // Use the default KEY_ID and KEY as specified in eme_player_js/globals.js. + const keyId = KEY_ID; + const key = KEY; + + // This test only works with EXTERNAL_CLEARKEY. Persistent sessions are not + // supported by CLEARKEY, and WIDEVINE doesn't support persistent sessions + // on Linux which is the only system with a test license server. + if (testConfig.keySystem != EXTERNAL_CLEARKEY) { + Utils.timeLog('Unsupported key system ' + testConfig.keySystem); + } + + // This test doesn't play any media, so no concern with specifying multiple + // codecs. This is done to provide a set of codecs that should cover all + // user agents. However, the CDM must support persistent licenses. + const config = [{ + initDataTypes: ['webm'], + audioCapabilities: [ + {contentType: 'audio/mp4; codecs="mp4a.40.2"'}, + {contentType: 'audio/webm; codecs="opus"'}, + ], + persistentState: 'optional', + sessionTypes: ['persistent-license'], + }]; + + var mediaKeys; + var mediaKeySession; + var mediaKeySessionId; + navigator.requestMediaKeySystemAccess(testConfig.keySystem, config) + .then(function(access) { + return access.createMediaKeys(); + }) + .then(function(result) { + Utils.timeLog('Creating session'); + mediaKeys = result; + mediaKeySession = mediaKeys.createSession('persistent-license'); + + // As this is using 'webm' initDataType, the data to generateRequest() + // is simply the key ID. + Utils.timeLog('Calling generateRequest()'); + return mediaKeySession.generateRequest( + 'webm', Utils.convertToUint8Array(keyId)); + }) + .then(function() { + // Save the session ID so it can be loaded later. + mediaKeySessionId = mediaKeySession.sessionId; + + // After update() is called, a 'keystatuseschange' event will occur. + // Wait for it before checking the key statuses. Registering the event + // handler now to ensure that the event gets caught. There is no need + // to do anything in the event handler as the key statuses are on + // |mediaKeySession|, and they can be checked after the promise is + // resolved. + const waitForKeyStatusChangePromise = + Utils.waitForEvent(mediaKeySession, 'keystatuseschange'); + + Utils.timeLog('Calling update()'); + const jwkSet = Utils.createJWKData(keyId, key); + return Promise.all([ + mediaKeySession.update(jwkSet), + waitForKeyStatusChangePromise + ]); + }) + .then(function() { + // Session should have 1 usable key. + Utils.timeLog('Checking for usable keyStatuses'); + Utils.verifyKeyStatuses( + mediaKeySession.keyStatuses, [{keyId: keyId, status: 'usable'}]); + + // After close() is called, another 'keystatuseschange' event should + // occur. Wait for it as well as the result for close(). + const waitForKeyStatusChangePromise = + Utils.waitForEvent(mediaKeySession, 'keystatuseschange'); + + // Now call close() and wait for the session to be closed along with + // another 'keystatuseschange' event. + Utils.timeLog('Calling close()'); + return Promise.all([ + mediaKeySession.close(), + mediaKeySession.closed, + waitForKeyStatusChangePromise + ]); + }) + .then(function() { + // After close() there should be no keys. + Utils.timeLog('Checking for empty keyStatuses'); + Utils.verifyKeyStatuses(mediaKeySession.keyStatuses, []); + + // Create a new session object. + Utils.timeLog('Creating new session'); + mediaKeySession = mediaKeys.createSession('persistent-license'); + + // After load() is called, a 'keystatuseschange' event should occur + // for this new session. Wait for it as well as the result for load(). + const waitForKeyStatusChangePromise = + Utils.waitForEvent(mediaKeySession, 'keystatuseschange'); + + // Try to load the previous session. + Utils.timeLog('Calling load()'); + return Promise.all([ + mediaKeySession.load(mediaKeySessionId), + waitForKeyStatusChangePromise + ]); + }) + .then(function() { + // Loaded session should still have the same usable key. + Utils.timeLog('Checking for usable keyStatuses'); + Utils.verifyKeyStatuses( + mediaKeySession.keyStatuses, [{keyId: keyId, status: 'usable'}]); + + // After close() is called on the loaded session, another + // 'keystatuseschange' event should occur. Wait for it + // as well as the result for close(). + const waitForKeyStatusChangePromise = + Utils.waitForEvent(mediaKeySession, 'keystatuseschange'); + + // Now call close() and wait for the session to be closed along with + // the 'keystatuseschange' event. + Utils.timeLog('Calling close()'); + return Promise.all([ + mediaKeySession.close(), + mediaKeySession.closed, + waitForKeyStatusChangePromise + ]); + }) + .then(function() { + // After close() there should be no keys. + Utils.timeLog('Checking for empty keyStatuses'); + Utils.verifyKeyStatuses(mediaKeySession.keyStatuses, []); + Utils.setResultInTitle('ENDED'); + }) + .catch(function(error) { + Utils.timeLog(error); + Utils.failTest('Failed test.'); + }); +</script> +</html>
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index b11680a..919b7445 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -2304,22 +2304,11 @@ ASSERT_EQ(1U, ca_cert_list.size()); ScopedTestRoot test_root(ca_cert_list[0].get()); - CertificateList intermediate_cert_list = CreateCertificateListFromFile( - GetTestCertsDirectory(), "intermediate_ca_cert.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, intermediate_cert_list.size()); - std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates; - intermediates.push_back( - bssl::UpRef(intermediate_cert_list[0]->cert_buffer())); - - CertificateList cert_list = CreateCertificateListFromFile( + scoped_refptr<X509Certificate> leaf = CreateCertificateChainFromFile( GetTestCertsDirectory(), "ok_cert_by_intermediate.pem", X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, cert_list.size()); - - scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromBuffer( - bssl::UpRef(cert_list[0]->cert_buffer()), std::move(intermediates)); ASSERT_TRUE(leaf); + ASSERT_EQ(1U, leaf->intermediate_buffers().size()); int flags = 0; CertVerifyResult verify_result;
diff --git a/net/cert/mock_cert_verifier.cc b/net/cert/mock_cert_verifier.cc index 6e2c6fe..3a5161f 100644 --- a/net/cert/mock_cert_verifier.cc +++ b/net/cert/mock_cert_verifier.cc
@@ -7,9 +7,13 @@ #include <memory> #include <utility> +#include "base/bind.h" +#include "base/location.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/strings/pattern.h" #include "base/strings/string_util.h" +#include "base/threading/thread_task_runner_handle.h" #include "net/base/net_errors.h" #include "net/cert/cert_status_flags.h" #include "net/cert/cert_verify_result.h" @@ -36,7 +40,30 @@ int rv; }; -MockCertVerifier::MockCertVerifier() : default_result_(ERR_CERT_INVALID) {} +class MockCertVerifier::MockRequest : public CertVerifier::Request { + public: + MockRequest(CertVerifyResult* result, CompletionOnceCallback callback) + : result_(result), callback_(std::move(callback)), weak_factory_(this) {} + + void ReturnResultLater(int rv, const CertVerifyResult& result) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&MockRequest::ReturnResult, + weak_factory_.GetWeakPtr(), rv, result)); + } + + private: + void ReturnResult(int rv, const CertVerifyResult& result) { + *result_ = result; + std::move(callback_).Run(rv); + } + + CertVerifyResult* result_; + CompletionOnceCallback callback_; + base::WeakPtrFactory<MockRequest> weak_factory_; +}; + +MockCertVerifier::MockCertVerifier() + : default_result_(ERR_CERT_INVALID), async_(false) {} MockCertVerifier::~MockCertVerifier() = default; @@ -45,21 +72,17 @@ CompletionOnceCallback callback, std::unique_ptr<Request>* out_req, const NetLogWithSource& net_log) { - RuleList::const_iterator it; - for (it = rules_.begin(); it != rules_.end(); ++it) { - // Check just the server cert. Intermediates will be ignored. - if (!it->cert->EqualsExcludingChain(params.certificate().get())) - continue; - if (!base::MatchPattern(params.hostname(), it->hostname)) - continue; - *verify_result = it->result; - return it->rv; + if (!async_) { + return VerifyImpl(params, verify_result); } - // Fall through to the default. - verify_result->verified_cert = params.certificate(); - verify_result->cert_status = MapNetErrorToCertStatus(default_result_); - return default_result_; + auto request = + std::make_unique<MockRequest>(verify_result, std::move(callback)); + CertVerifyResult result; + int rv = VerifyImpl(params, &result); + request->ReturnResultLater(rv, result); + *out_req = std::move(request); + return ERR_IO_PENDING; } void MockCertVerifier::AddResultForCert(scoped_refptr<X509Certificate> cert, @@ -76,4 +99,22 @@ rules_.push_back(Rule(std::move(cert), host_pattern, verify_result, rv)); } +int MockCertVerifier::VerifyImpl(const RequestParams& params, + CertVerifyResult* verify_result) { + for (const Rule& rule : rules_) { + // Check just the server cert. Intermediates will be ignored. + if (!rule.cert->EqualsExcludingChain(params.certificate().get())) + continue; + if (!base::MatchPattern(params.hostname(), rule.hostname)) + continue; + *verify_result = rule.result; + return rule.rv; + } + + // Fall through to the default. + verify_result->verified_cert = params.certificate(); + verify_result->cert_status = MapNetErrorToCertStatus(default_result_); + return default_result_; +} + } // namespace net
diff --git a/net/cert/mock_cert_verifier.h b/net/cert/mock_cert_verifier.h index ad1fde4..6c34a06 100644 --- a/net/cert/mock_cert_verifier.h +++ b/net/cert/mock_cert_verifier.h
@@ -40,6 +40,9 @@ default_result_ = default_result; } + // Sets whether Verify() returns a result asynchronously. + void set_async(bool async) { async_ = async; } + // Adds a rule that will cause any call to Verify() for |cert| to return rv, // copying |verify_result| into the verified result. // Note: Only the primary certificate of |cert| is checked. Any intermediate @@ -57,10 +60,14 @@ private: struct Rule; - typedef std::list<Rule> RuleList; + using RuleList = std::list<Rule>; + class MockRequest; + + int VerifyImpl(const RequestParams& params, CertVerifyResult* verify_result); int default_result_; RuleList rules_; + bool async_; }; } // namespace net
diff --git a/net/data/ssl/certificates/ok_cert_by_intermediate.pem b/net/data/ssl/certificates/ok_cert_by_intermediate.pem index 5c92ba6f..5cd3cc1 100644 --- a/net/data/ssl/certificates/ok_cert_by_intermediate.pem +++ b/net/data/ssl/certificates/ok_cert_by_intermediate.pem
@@ -110,3 +110,80 @@ WBcVw6wZIcshKfxT5zvPwgpe9M7xnnc41MaQTpT+LpfLGpQqHow72zZlxhm61wsD IuWS4vY+35nOa0k= -----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA + Validity + Not Before: Jun 5 17:10:45 2017 GMT + Not After : Jun 3 17:10:45 2027 GMT + Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Intermediate CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:9d:e9:bd:e4:3d:4a:2f:fb:c2:f9:e6:22:2a:42: + 15:46:1c:8c:8f:47:4c:e9:c5:57:95:1f:66:70:93: + 22:f0:94:c3:bb:b5:5b:ef:a4:6f:c8:c7:89:95:75: + ba:0c:36:bf:4e:6b:a9:35:47:08:43:9e:29:6a:e2: + c3:fb:03:b7:1f:b6:e1:51:6b:ed:7b:19:c7:f9:ce: + 3b:dc:65:e9:66:c7:83:94:c4:d1:4e:ee:ed:64:4b: + 81:f1:1a:ea:5a:64:18:1b:6a:4e:93:d0:13:6c:90: + 60:ca:d2:4e:b7:24:16:f8:b2:08:58:9d:8d:a7:33: + 45:15:34:81:ad:2d:2d:9c:60:ef:f9:2b:98:fe:79: + d3:8d:2c:48:db:12:91:f4:2e:fa:bf:f5:26:c1:82: + 05:80:dd:4c:a8:70:bf:a7:bc:10:34:77:39:db:47: + 04:0f:ed:44:b2:65:46:22:20:88:59:28:0f:c7:0c: + a2:b4:91:a5:a2:aa:ca:05:9f:8a:9b:6e:a3:cb:d4: + a4:e8:24:75:9d:20:81:22:5b:5f:77:3e:c9:f1:1e: + ae:eb:8a:33:8c:27:5b:1e:be:6d:21:1b:42:72:95: + e3:9e:13:03:75:a7:58:d4:be:68:12:fe:63:8e:4b: + 11:7a:34:e7:a3:6b:dd:73:ae:3e:19:9a:ec:91:8b: + 73:af + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 17:5C:45:F3:D0:AC:1C:10:4C:8B:43:44:20:C4:DD:93:C5:C5:19:3B + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Signature Algorithm: sha256WithRSAEncryption + 3e:f5:d7:fd:82:3b:1e:34:8c:66:a2:f3:5e:18:e1:f1:a9:75: + 9f:b5:93:e7:0a:8e:cf:0a:33:ed:49:cd:ce:ce:ca:5f:a3:1d: + 64:76:d3:84:16:fe:9d:88:ac:f4:d1:f8:36:2b:20:80:52:0a: + ef:e0:0f:64:27:55:35:a3:7b:c6:8a:7c:a5:c4:29:17:b1:fa: + d2:89:5d:13:6b:b8:03:cb:d7:12:d6:ce:24:f0:af:48:17:03: + 54:99:af:e9:cb:fd:44:44:18:23:61:90:f6:bd:55:65:06:c3: + 36:98:8d:ea:7d:0f:79:ef:b6:bb:22:28:03:a6:ec:d9:d4:1b: + 47:ac:2c:25:de:ef:1a:02:69:4c:18:bb:29:48:f4:9d:e1:52: + 42:64:6c:88:46:68:86:83:fd:24:f5:7d:05:d7:1a:7e:22:bc: + 49:75:9c:8a:4d:e8:f3:a2:eb:9b:83:70:a7:d6:dd:2f:05:2d: + aa:be:d7:ee:7b:8e:75:44:3b:da:df:85:61:bf:e9:3b:13:40: + 4e:8b:52:08:d9:e4:8c:54:da:41:db:7b:2c:05:5e:99:06:0d: + 02:8c:8e:19:8e:55:b0:3a:33:18:30:03:a7:ed:4a:e4:f8:58: + cc:12:b8:af:d6:66:55:29:ec:01:1f:92:ed:3d:4d:c3:71:3b: + e0:2f:70:90 +-----BEGIN CERTIFICATE----- +MIIDizCCAnOgAwIBAgIBATANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET +MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G +A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MDYwNTE3 +MTA0NVoXDTI3MDYwMzE3MTA0NVowazELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh +bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg +Q0ExHTAbBgNVBAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAnem95D1KL/vC+eYiKkIVRhyMj0dM6cVXlR9mcJMi +8JTDu7Vb76RvyMeJlXW6DDa/TmupNUcIQ54pauLD+wO3H7bhUWvtexnH+c473GXp +ZseDlMTRTu7tZEuB8RrqWmQYG2pOk9ATbJBgytJOtyQW+LIIWJ2NpzNFFTSBrS0t +nGDv+SuY/nnTjSxI2xKR9C76v/UmwYIFgN1MqHC/p7wQNHc520cED+1EsmVGIiCI +WSgPxwyitJGloqrKBZ+Km26jy9Sk6CR1nSCBIltfdz7J8R6u64ozjCdbHr5tIRtC +cpXjnhMDdadY1L5oEv5jjksRejTno2vdc64+GZrskYtzrwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQXXEXz0KwcEEyLQ0QgxN2TxcUZOzAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAD711/2COx40jGai814Y4fGp +dZ+1k+cKjs8KM+1Jzc7Oyl+jHWR204QW/p2IrPTR+DYrIIBSCu/gD2QnVTWje8aK +fKXEKRex+tKJXRNruAPL1xLWziTwr0gXA1SZr+nL/UREGCNhkPa9VWUGwzaYjep9 +D3nvtrsiKAOm7NnUG0esLCXe7xoCaUwYuylI9J3hUkJkbIhGaIaD/ST1fQXXGn4i +vEl1nIpN6POi65uDcKfW3S8FLaq+1+57jnVEO9rfhWG/6TsTQE6LUgjZ5IxU2kHb +eywFXpkGDQKMjhmOVbA6MxgwA6ftSuT4WMwSuK/WZlUp7AEfku09TcNxO+AvcJA= +-----END CERTIFICATE-----
diff --git a/net/data/ssl/scripts/generate-test-certs.sh b/net/data/ssl/scripts/generate-test-certs.sh index 824fbd9..28a6966 100755 --- a/net/data/ssl/scripts/generate-test-certs.sh +++ b/net/data/ssl/scripts/generate-test-certs.sh
@@ -180,6 +180,7 @@ /bin/sh -c "cat out/ok_cert.key out/bad_validity.pem \ > ../certificates/bad_validity.pem" /bin/sh -c "cat out/ok_cert.key out/int/ok_cert.pem \ + out/int/2048-sha256-int.pem \ > ../certificates/ok_cert_by_intermediate.pem" /bin/sh -c "cat out/int/2048-sha256-int.key out/int/2048-sha256-int.pem \ > ../certificates/intermediate_ca_cert.pem"
diff --git a/net/quic/quic_connectivity_probing_manager.cc b/net/quic/quic_connectivity_probing_manager.cc index e89b444..69cd597 100644 --- a/net/quic/quic_connectivity_probing_manager.cc +++ b/net/quic/quic_connectivity_probing_manager.cc
@@ -125,6 +125,8 @@ std::unique_ptr<QuicChromiumPacketReader> reader, base::TimeDelta initial_timeout, const NetLogWithSource& net_log) { + DCHECK(peer_address != quic::QuicSocketAddress()); + if (IsUnderProbing(network, peer_address)) return;
diff --git a/net/quic/quic_connectivity_probing_manager_test.cc b/net/quic/quic_connectivity_probing_manager_test.cc index 9928809..f39a1367 100644 --- a/net/quic/quic_connectivity_probing_manager_test.cc +++ b/net/quic/quic_connectivity_probing_manager_test.cc
@@ -39,7 +39,7 @@ public QuicChromiumPacketReader::Visitor { public: MockQuicChromiumClientSession() - : successful_network_(NetworkChangeNotifier::kInvalidNetworkHandle) {} + : probed_network_(NetworkChangeNotifier::kInvalidNetworkHandle) {} ~MockQuicChromiumClientSession() override {} // QuicChromiumPacketReader::Visitor interface. @@ -66,15 +66,21 @@ std::unique_ptr<DatagramClientSocket> socket, std::unique_ptr<QuicChromiumPacketWriter> writer, std::unique_ptr<QuicChromiumPacketReader> reader) override { - successful_network_ = network; + probed_network_ = network; + probed_peer_address_ = peer_address; } - NetworkChangeNotifier::NetworkHandle successful_network() { - return successful_network_; + NetworkChangeNotifier::NetworkHandle probed_network() const { + return probed_network_; + } + + quic::QuicSocketAddress probed_peer_address() const { + return probed_peer_address_; } private: - NetworkChangeNotifier::NetworkHandle successful_network_; + NetworkChangeNotifier::NetworkHandle probed_network_; + quic::QuicSocketAddress probed_peer_address_; DISALLOW_COPY_AND_ASSIGN(MockQuicChromiumClientSession); }; @@ -168,7 +174,7 @@ .Times(0); probing_manager_.OnConnectivityProbingReceived(self_address_, testPeerAddress); - EXPECT_EQ(session_.successful_network(), testNetworkHandle); + EXPECT_EQ(session_.probed_network(), testNetworkHandle); EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); // Verify there's nothing to send. @@ -215,7 +221,7 @@ .Times(0); probing_manager_.OnConnectivityProbingReceived(quic::QuicSocketAddress(), testPeerAddress); - EXPECT_NE(session_.successful_network(), testNetworkHandle); + EXPECT_NE(session_.probed_network(), testNetworkHandle); EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); // Fast forward another initial_timeout_ms, another probing packet will be @@ -231,7 +237,7 @@ .Times(0); probing_manager_.OnConnectivityProbingReceived(self_address_, testPeerAddress); - EXPECT_EQ(session_.successful_network(), testNetworkHandle); + EXPECT_EQ(session_.probed_network(), testNetworkHandle); EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); // Verify there's nothing to send. @@ -390,5 +396,98 @@ EXPECT_EQ(0u, test_task_runner_->GetPendingTaskCount()); } +TEST_F(QuicConnectivityProbingManagerTest, + ProbeServerPreferredAddressSucceeded) { + int initial_timeout_ms = 100; + + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress)) + .WillOnce(Return(true)); + // A probe for server preferred address is usually initiated with an + // invalid network handle passed in. + probing_manager_.StartProbing( + NetworkChangeNotifier::kInvalidNetworkHandle, testPeerAddress, + std::move(socket_), std::move(writer_), std::move(reader_), + base::TimeDelta::FromMilliseconds(initial_timeout_ms), + bound_test_net_log_.bound()); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress)) + .WillOnce(Return(true)); + + test_task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(initial_timeout_ms)); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + + // Fast forward initial_timeout_ms, should be no-op. + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress)) + .Times(0); + test_task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(initial_timeout_ms)); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + + // Notify the manager a connectivity probing packet is received from + // testPeerAddress to |self_address_|, manager should decalre probing as + // successful, notify delegate and will no longer send connectivity probes. + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress)) + .Times(0); + probing_manager_.OnConnectivityProbingReceived(self_address_, + testPeerAddress); + + // Verify that session marked <kInvalidNetworkHandle, testPeerAddress> as + // successfully probed. + EXPECT_EQ(session_.probed_network(), + NetworkChangeNotifier::kInvalidNetworkHandle); + EXPECT_EQ(session_.probed_peer_address(), testPeerAddress); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress)) + .Times(0); + test_task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(initial_timeout_ms)); + EXPECT_EQ(0u, test_task_runner_->GetPendingTaskCount()); +} + +TEST_F(QuicConnectivityProbingManagerTest, ProbeServerPreferredAddressFailed) { + int initial_timeout_ms = 100; + + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress)) + .WillOnce(Return(true)); + QuicChromiumPacketWriter* writer_ptr = writer_.get(); + // A probe for server preferred address is usually initiated with an + // invalid network handle passed in. + probing_manager_.StartProbing( + NetworkChangeNotifier::kInvalidNetworkHandle, testPeerAddress, + std::move(socket_), std::move(writer_), std::move(reader_), + base::TimeDelta::FromMilliseconds(initial_timeout_ms), + bound_test_net_log_.bound()); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress)) + .WillOnce(Return(true)); + test_task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(initial_timeout_ms)); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + + // Fast forward initial_timeout_ms, should be no-op. + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress)) + .Times(0); + test_task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(initial_timeout_ms)); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + + // Probing packet writer received an write error, notifies manager to handle + // write error. Manager will notify session of the probe failure, cancel + // probing to prevent future connectivity probing packet to be sent. + EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, _)).Times(0); + EXPECT_CALL(session_, + OnProbeFailed(NetworkChangeNotifier::kInvalidNetworkHandle, + testPeerAddress)) + .Times(1); + writer_ptr->OnWriteComplete(ERR_CONNECTION_CLOSED); + test_task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(initial_timeout_ms)); + EXPECT_EQ(0u, test_task_runner_->GetPendingTaskCount()); +} + } // namespace test } // namespace net
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index a31d8de..7b6ada75 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -813,6 +813,10 @@ return spawned_test_server_.get(); } + void SetCertVerifier(CertVerifier* cert_verifier) { + context_.cert_verifier = cert_verifier; + } + void SetCTVerifier(CTVerifier* ct_verifier) { context_.cert_transparency_verifier = ct_verifier; } @@ -1297,6 +1301,47 @@ return ret; } +// A CertVerifier that never returns on any requests. +class HangingCertVerifier : public CertVerifier { + public: + int num_active_requests() const { return num_active_requests_; } + + void WaitForRequest() { + if (!num_active_requests_) { + run_loop_.Run(); + } + } + + int Verify(const RequestParams& params, + CertVerifyResult* verify_result, + CompletionOnceCallback callback, + std::unique_ptr<Request>* out_req, + const NetLogWithSource& net_log) override { + *out_req = std::make_unique<HangingRequest>(this); + return ERR_IO_PENDING; + } + + void SetConfig(const Config& config) override {} + + private: + class HangingRequest : public Request { + public: + explicit HangingRequest(HangingCertVerifier* verifier) + : verifier_(verifier) { + verifier_->num_active_requests_++; + verifier_->run_loop_.Quit(); + } + + ~HangingRequest() override { verifier_->num_active_requests_--; } + + private: + HangingCertVerifier* verifier_; + }; + + base::RunLoop run_loop_; + int num_active_requests_ = 0; +}; + } // namespace TEST_F(SSLClientSocketTest, Connect) { @@ -1331,6 +1376,15 @@ EXPECT_FALSE(sock->IsConnected()); } +TEST_F(SSLClientSocketTest, ConnectAsyncVerify) { + ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); + + cert_verifier_->set_async(true); + int rv; + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); + EXPECT_THAT(rv, IsError(OK)); +} + TEST_F(SSLClientSocketTest, ConnectExpired) { SpawnedTestServer::SSLOptions ssl_options( SpawnedTestServer::SSLOptions::CERT_EXPIRED); @@ -1351,6 +1405,48 @@ EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SSL_CONNECT)); } +TEST_F(SSLClientSocketTest, ConnectExpiredAsyncVerify) { + SpawnedTestServer::SSLOptions ssl_options( + SpawnedTestServer::SSLOptions::CERT_EXPIRED); + ASSERT_TRUE(StartTestServer(ssl_options)); + + cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID); + cert_verifier_->set_async(true); + + int rv; + ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); + EXPECT_THAT(rv, IsError(ERR_CERT_DATE_INVALID)); +} + +// Test that SSLClientSockets may be destroyed while waiting on a certificate +// verification. +TEST_F(SSLClientSocketTest, SocketDestroyedDuringVerify) { + ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); + + HangingCertVerifier verifier; + SetCertVerifier(&verifier); + + TestCompletionCallback callback; + auto transport = + std::make_unique<TCPClientSocket>(addr(), nullptr, &log_, NetLogSource()); + int rv = callback.GetResult(transport->Connect(callback.callback())); + ASSERT_THAT(rv, IsOk()); + + std::unique_ptr<SSLClientSocket> sock = CreateSSLClientSocket( + std::move(transport), spawned_test_server()->host_port_pair(), + SSLConfig()); + rv = sock->Connect(callback.callback()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + // The socket should attempt a certificate verification. + verifier.WaitForRequest(); + EXPECT_EQ(1, verifier.num_active_requests()); + + // Destroying the socket should cancel it. + sock = nullptr; + EXPECT_EQ(0, verifier.num_active_requests()); +} + TEST_F(SSLClientSocketTest, ConnectMismatched) { SpawnedTestServer::SSLOptions ssl_options( SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
diff --git a/net/ssl/ssl_key_logger_impl.cc b/net/ssl/ssl_key_logger_impl.cc index a6a4458..a759fee 100644 --- a/net/ssl/ssl_key_logger_impl.cc +++ b/net/ssl/ssl_key_logger_impl.cc
@@ -6,27 +6,72 @@ #include <stdio.h> +#include <algorithm> + #include "base/bind.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/location.h" #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" +#include "base/synchronization/lock.h" #include "base/task/post_task.h" #include "base/task/task_traits.h" +#include "base/thread_annotations.h" namespace net { -// An object which lives on the background SequencedTaskRunner and performs the -// blocking file operations. -class SSLKeyLoggerImpl::Core { +namespace { +// Bound the number of outstanding writes to bound memory usage. Some +// antiviruses point this at a pipe and then read too slowly. See +// https://crbug.com/566951 and https://crbug.com/914880. +static constexpr size_t kMaxOutstandingLines = 512; +} // namespace + +// An object which performs the blocking file operations on a background +// SequencedTaskRunner. +class SSLKeyLoggerImpl::Core + : public base::RefCountedThreadSafe<SSLKeyLoggerImpl::Core> { public: - Core() { DETACH_FROM_SEQUENCE(sequence_checker_); } - ~Core() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } + Core() { + DETACH_FROM_SEQUENCE(sequence_checker_); + // That the user explicitly asked for debugging information would suggest + // waiting to flush these to disk, but some buggy antiviruses point this at + // a pipe and hang, so we avoid blocking shutdown. If writing to a real + // file, writes should complete quickly enough that this does not matter. + task_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}); + } void OpenFile(const base::FilePath& path) { + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&Core::OpenFileImpl, this, path)); + } + + void WriteLine(const std::string& line) { + bool was_empty; + { + base::AutoLock lock(lock_); + was_empty = buffer_.empty(); + if (buffer_.size() < kMaxOutstandingLines) { + buffer_.push_back(line); + } else { + lines_dropped_ = true; + } + } + if (was_empty) { + task_runner_->PostTask(FROM_HERE, base::BindOnce(&Core::Flush, this)); + } + } + + private: + friend class base::RefCountedThreadSafe<Core>; + ~Core() = default; + + void OpenFileImpl(const base::FilePath& path) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!file_); file_.reset(base::OpenFile(path, "a")); @@ -34,40 +79,48 @@ LOG(WARNING) << "Could not open " << path.value(); } - void WriteLine(const std::string& line) { + void Flush() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!file_) - return; - fprintf(file_.get(), "%s\n", line.c_str()); - fflush(file_.get()); + + bool lines_dropped = false; + std::vector<std::string> buffer; + { + base::AutoLock lock(lock_); + std::swap(lines_dropped, lines_dropped_); + std::swap(buffer, buffer_); + } + + if (file_) { + for (const auto& line : buffer) { + fprintf(file_.get(), "%s\n", line.c_str()); + } + if (lines_dropped) { + fprintf(file_.get(), "# Some lines were dropped due to slow writes.\n"); + } + fflush(file_.get()); + } } - private: + scoped_refptr<base::SequencedTaskRunner> task_runner_; base::ScopedFILE file_; SEQUENCE_CHECKER(sequence_checker_); + base::Lock lock_; + bool lines_dropped_ GUARDED_BY(lock_) = false; + std::vector<std::string> buffer_ GUARDED_BY(lock_); + DISALLOW_COPY_AND_ASSIGN(Core); }; SSLKeyLoggerImpl::SSLKeyLoggerImpl(const base::FilePath& path) : core_(new Core) { - // The user explicitly asked for debugging information, so these tasks block - // shutdown to avoid dropping some log entries. - task_runner_ = base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&Core::OpenFile, base::Unretained(core_.get()), path)); + core_->OpenFile(path); } -SSLKeyLoggerImpl::~SSLKeyLoggerImpl() { - task_runner_->DeleteSoon(FROM_HERE, core_.release()); -} +SSLKeyLoggerImpl::~SSLKeyLoggerImpl() = default; void SSLKeyLoggerImpl::WriteLine(const std::string& line) { - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&Core::WriteLine, base::Unretained(core_.get()), line)); + core_->WriteLine(line); } } // namespace net
diff --git a/net/ssl/ssl_key_logger_impl.h b/net/ssl/ssl_key_logger_impl.h index 7a97b8da..61ae0d9 100644 --- a/net/ssl/ssl_key_logger_impl.h +++ b/net/ssl/ssl_key_logger_impl.h
@@ -9,13 +9,12 @@ #include <string> #include "base/macros.h" -#include "base/memory/ref_counted.h" +#include "base/memory/scoped_refptr.h" #include "net/base/net_export.h" #include "net/ssl/ssl_key_logger.h" namespace base { class FilePath; -class SequencedTaskRunner; } // namespace base namespace net { @@ -33,10 +32,7 @@ private: class Core; - - scoped_refptr<base::SequencedTaskRunner> task_runner_; - // Destroyed on |task_runner_|. - std::unique_ptr<Core> core_; + scoped_refptr<Core> core_; DISALLOW_COPY_AND_ASSIGN(SSLKeyLoggerImpl); };
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc index 435600d..371e73ab0 100644 --- a/net/test/embedded_test_server/embedded_test_server.cc +++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -316,6 +316,8 @@ return "common_name_only.pem"; case CERT_SHA1_LEAF: return "sha1_leaf.pem"; + case CERT_OK_BY_INTERMEDIATE: + return "ok_cert_by_intermediate.pem"; } return "ok_cert.pem"; @@ -326,7 +328,8 @@ base::FilePath certs_dir(GetTestCertsDirectory()); base::ScopedAllowBlockingForTesting allow_blocking; - return ImportCertFromFile(certs_dir, GetCertificateName()); + return CreateCertificateChainFromFile(certs_dir, GetCertificateName(), + X509Certificate::FORMAT_AUTO); } void EmbeddedTestServer::ServeFilesFromDirectory(
diff --git a/net/test/embedded_test_server/embedded_test_server.h b/net/test/embedded_test_server/embedded_test_server.h index f4433b3..c467cea0 100644 --- a/net/test/embedded_test_server/embedded_test_server.h +++ b/net/test/embedded_test_server/embedded_test_server.h
@@ -110,6 +110,9 @@ // A certificate that is a leaf certificate signed with SHA-1. CERT_SHA1_LEAF, + + // A certificate that is signed by an intermediate certificate. + CERT_OK_BY_INTERMEDIATE, }; typedef base::RepeatingCallback<std::unique_ptr<HttpResponse>(
diff --git a/net/test/embedded_test_server/embedded_test_server_unittest.cc b/net/test/embedded_test_server/embedded_test_server_unittest.cc index 4d6a0769..acfcb317a 100644 --- a/net/test/embedded_test_server/embedded_test_server_unittest.cc +++ b/net/test/embedded_test_server/embedded_test_server_unittest.cc
@@ -460,34 +460,36 @@ cancel_delegate.WaitUntilDone(); } -struct CertificateValuesEntry { +const struct CertificateValuesEntry { const EmbeddedTestServer::ServerCertificate server_cert; const bool is_expired; const char* common_name; - const char* root; -}; - -const CertificateValuesEntry kCertificateValuesEntry[] = { - {EmbeddedTestServer::CERT_OK, false, "127.0.0.1", "Test Root CA"}, + const char* issuer_common_name; + size_t certs_count; +} kCertificateValuesEntry[] = { + {EmbeddedTestServer::CERT_OK, false, "127.0.0.1", "Test Root CA", 1}, + {EmbeddedTestServer::CERT_OK_BY_INTERMEDIATE, false, "127.0.0.1", + "Test Intermediate CA", 2}, {EmbeddedTestServer::CERT_MISMATCHED_NAME, false, "127.0.0.1", - "Test Root CA"}, + "Test Root CA", 1}, {EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN, false, "localhost", - "Test Root CA"}, - {EmbeddedTestServer::CERT_EXPIRED, true, "127.0.0.1", "Test Root CA"}, + "Test Root CA", 1}, + {EmbeddedTestServer::CERT_EXPIRED, true, "127.0.0.1", "Test Root CA", 1}, }; TEST_P(EmbeddedTestServerTest, GetCertificate) { if (GetParam() != EmbeddedTestServer::TYPE_HTTPS) return; - for (const auto& certEntry : kCertificateValuesEntry) { - SCOPED_TRACE(certEntry.server_cert); - server_->SetSSLConfig(certEntry.server_cert); + for (const auto& cert_entry : kCertificateValuesEntry) { + SCOPED_TRACE(cert_entry.server_cert); + server_->SetSSLConfig(cert_entry.server_cert); scoped_refptr<X509Certificate> cert = server_->GetCertificate(); ASSERT_TRUE(cert); - EXPECT_EQ(cert->HasExpired(), certEntry.is_expired); - EXPECT_EQ(cert->subject().common_name, certEntry.common_name); - EXPECT_EQ(cert->issuer().common_name, certEntry.root); + EXPECT_EQ(cert->HasExpired(), cert_entry.is_expired); + EXPECT_EQ(cert->subject().common_name, cert_entry.common_name); + EXPECT_EQ(cert->issuer().common_name, cert_entry.issuer_common_name); + EXPECT_EQ(cert->intermediate_buffers().size(), cert_entry.certs_count - 1); } }
diff --git a/sandbox/win/src/interception_agent.cc b/sandbox/win/src/interception_agent.cc index a0913426..e095328 100644 --- a/sandbox/win/src/interception_agent.cc +++ b/sandbox/win/src/interception_agent.cc
@@ -185,7 +185,8 @@ return false; } - DCHECK_NT(!g_originals[function->id]); + DCHECK_NT(!g_originals[function->id] || + g_originals[function->id] == &thunks->thunks[i]); g_originals[function->id] = &thunks->thunks[i]; thunks->num_thunks++;
diff --git a/sandbox/win/src/process_mitigations_win32k_unittest.cc b/sandbox/win/src/process_mitigations_win32k_unittest.cc index e65878e..8a865305 100644 --- a/sandbox/win/src/process_mitigations_win32k_unittest.cc +++ b/sandbox/win/src/process_mitigations_win32k_unittest.cc
@@ -632,21 +632,12 @@ EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(test_policy_command.c_str())); } -// Flaky in Debug. https://crbug.com/840335 -#if !defined(NDEBUG) -#define MAYBE_CheckWin8LockDownSuccess DISABLED_CheckWin8LockDownSuccess -#define MAYBE_CheckWin8Redirection DISABLED_CheckWin8Redirection -#else -#define MAYBE_CheckWin8LockDownSuccess CheckWin8LockDownSuccess -#define MAYBE_CheckWin8Redirection CheckWin8Redirection -#endif - // This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation // along with the policy to fake user32 and gdi32 initialization successfully // launches the target process. // The test process itself links against user32/gdi32. -TEST(ProcessMitigationsWin32kTest, MAYBE_CheckWin8LockDownSuccess) { +TEST(ProcessMitigationsWin32kTest, CheckWin8LockDownSuccess) { if (base::win::GetVersion() < base::win::VERSION_WIN8) return; @@ -673,7 +664,7 @@ // This test validates the even though we're running under win32k lockdown // we can use the IPC redirection to enumerate the list of monitors. // Flaky. https://crbug.com/840335 -TEST(ProcessMitigationsWin32kTest, MAYBE_CheckWin8Redirection) { +TEST(ProcessMitigationsWin32kTest, CheckWin8Redirection) { if (base::win::GetVersion() < base::win::VERSION_WIN8) return;
diff --git a/services/identity/public/cpp/BUILD.gn b/services/identity/public/cpp/BUILD.gn index fcce44f..a353964 100644 --- a/services/identity/public/cpp/BUILD.gn +++ b/services/identity/public/cpp/BUILD.gn
@@ -8,6 +8,8 @@ "access_token_fetcher.h", "access_token_info.cc", "access_token_info.h", + "accounts_in_cookie_jar_info.cc", + "accounts_in_cookie_jar_info.h", "accounts_mutator.cc", "accounts_mutator.h", "identity_manager.cc",
diff --git a/services/identity/public/cpp/accounts_in_cookie_jar_info.cc b/services/identity/public/cpp/accounts_in_cookie_jar_info.cc new file mode 100644 index 0000000..53e05cc9 --- /dev/null +++ b/services/identity/public/cpp/accounts_in_cookie_jar_info.cc
@@ -0,0 +1,26 @@ +// Copyright 2018 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 "services/identity/public/cpp/accounts_in_cookie_jar_info.h" + +namespace identity { + +AccountsInCookieJarInfo::AccountsInCookieJarInfo() = default; + +AccountsInCookieJarInfo::AccountsInCookieJarInfo( + bool accounts_are_fresh_param, + const std::vector<AccountInfo>& accounts_param) + : accounts_are_fresh(accounts_are_fresh_param), accounts(accounts_param) {} + +AccountsInCookieJarInfo::AccountsInCookieJarInfo( + const AccountsInCookieJarInfo& other) { + if (this == &other) + return; + accounts_are_fresh = other.accounts_are_fresh; + accounts = other.accounts; +} + +AccountsInCookieJarInfo::~AccountsInCookieJarInfo() = default; + +} // namespace identity \ No newline at end of file
diff --git a/services/identity/public/cpp/accounts_in_cookie_jar_info.h b/services/identity/public/cpp/accounts_in_cookie_jar_info.h new file mode 100644 index 0000000..acb5763d --- /dev/null +++ b/services/identity/public/cpp/accounts_in_cookie_jar_info.h
@@ -0,0 +1,32 @@ +// Copyright 2018 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 SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_IN_COOKIE_JAR_INFO_H_ +#define SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_IN_COOKIE_JAR_INFO_H_ + +#include <vector> + +#include "components/signin/core/browser/account_info.h" + +namespace identity { + +// Container for a response to get the accounts in the cookie jar. +struct AccountsInCookieJarInfo { + // True if the accounts info from cookie is fresh and does not need to be + // updated. + bool accounts_are_fresh; + + // The current list of accounts from the cookie jar. + std::vector<AccountInfo> accounts; + + AccountsInCookieJarInfo(); + AccountsInCookieJarInfo(bool accounts_are_fresh_param, + const std::vector<AccountInfo>& accounts_param); + AccountsInCookieJarInfo(const AccountsInCookieJarInfo& other); + ~AccountsInCookieJarInfo(); +}; + +} // namespace identity + +#endif // _USR_LOCAL_GOOGLE_WORK_CHROMIUM_SRC_SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_IN_COOKIE_JAR_INFO_H_
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index 77465a5..e9478e7 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -95,14 +95,16 @@ return accounts; } -std::vector<AccountInfo> IdentityManager::GetAccountsInCookieJar() const { +AccountsInCookieJarInfo IdentityManager::GetAccountsInCookieJar() const { // TODO(859882): Change this implementation to interact asynchronously with // GaiaCookieManagerService as detailed in // https://docs.google.com/document/d/1hcrJ44facCSHtMGBmPusvcoP-fAR300Hi-UFez8ffYQ/edit?pli=1#heading=h.w97eil1cygs2. std::vector<gaia::ListedAccount> listed_accounts; - gaia_cookie_manager_service_->ListAccounts(&listed_accounts, nullptr); + bool accounts_are_fresh = + gaia_cookie_manager_service_->ListAccounts(&listed_accounts, nullptr); - return ListedAccountsToAccountInfos(listed_accounts); + return AccountsInCookieJarInfo(accounts_are_fresh, + ListedAccountsToAccountInfos(listed_accounts)); } bool IdentityManager::HasAccountWithRefreshToken( @@ -352,11 +354,12 @@ const std::vector<gaia::ListedAccount>& accounts, const std::vector<gaia::ListedAccount>& signed_out_accounts, const GoogleServiceAuthError& error) { - std::vector<AccountInfo> account_infos = - ListedAccountsToAccountInfos(accounts); + AccountsInCookieJarInfo accounts_in_cookie_jar_info( + error == GoogleServiceAuthError::AuthErrorNone(), + ListedAccountsToAccountInfos(accounts)); for (auto& observer : observer_list_) { - observer.OnAccountsInCookieUpdated(account_infos); + observer.OnAccountsInCookieUpdated(accounts_in_cookie_jar_info, error); } }
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index 161e0a31..3f6ee7c 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -14,6 +14,7 @@ #include "components/signin/core/browser/signin_manager_base.h" #include "components/signin/core/browser/signin_metrics.h" #include "services/identity/public/cpp/access_token_fetcher.h" +#include "services/identity/public/cpp/accounts_in_cookie_jar_info.h" #include "services/identity/public/cpp/accounts_mutator.h" #include "services/identity/public/cpp/scope_set.h" @@ -117,9 +118,19 @@ virtual void OnRefreshTokensLoaded() {} // Called whenever the list of Gaia accounts in the cookie jar has changed. - // |accounts| is ordered by the order of the accounts in the cookie. + // |accounts_in_cookie_jar_info.accounts| is ordered by the order of the + // accounts in the cookie. + // + // This observer method is also called when fetching the list of accounts + // in Gaia cookies fails after a number of internal retries. In this case: + // * |error| hold the last error to fetch the list of accounts; + // * |accounts_in_cookie_jar_info.accounts_are_fresh| is set to false as + // the accounts information is considered stale; + // * |accounts_in_cookie_jar_info.accounts| holds the last list of known + // accounts in the cookie jar. virtual void OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) {} + const AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) {} // Called whenever an attempt to add |account_id| to the list of Gaia // accounts in the cookie jar has finished. If |error| is equal to @@ -187,16 +198,11 @@ // Provides access to the latest cached information of all accounts that are // present in the Gaia cookie in the cookie jar, ordered by their order in - // the cookie. If the cached state is known to be stale by the underlying - // implementation, a call to this method will trigger an internal update and - // subsequent invocation of + // the cookie. + // If the returned accounts are not fresh, an internal update will be + // triggered and there will be a subsequent invocation of // IdentityManager::Observer::OnAccountsInCookieJarChanged(). - // NOTE: The information of whether the cached state is known to be stale by - // the underlying implementation is not currently exposed. The design for - // exposing it if necessary is tracked by https://crbug.com/859882. If the - // lack of this exposure is a blocker for you in using this API, contact - // blundell@chromium.org. - std::vector<AccountInfo> GetAccountsInCookieJar() const; + AccountsInCookieJarInfo GetAccountsInCookieJar() const; // Returns true if a refresh token exists for |account_id|. bool HasAccountWithRefreshToken(const std::string& account_id) const;
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index 38dff17b..aa3f169 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -242,8 +242,8 @@ on_accounts_in_cookie_updated_callback_ = std::move(callback); } - const std::vector<AccountInfo>& accounts_from_cookie_change_callback() { - return accounts_from_cookie_change_callback_; + const AccountsInCookieJarInfo& accounts_info_from_cookie_change_callback() { + return accounts_info_from_cookie_change_callback_; } const std::string& account_from_add_account_to_cookie_completed_callback() @@ -305,8 +305,9 @@ std::move(on_refresh_tokens_loaded_callback_).Run(); } void OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) override { - accounts_from_cookie_change_callback_ = accounts; + const AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) override { + accounts_info_from_cookie_change_callback_ = accounts_in_cookie_jar_info; if (on_accounts_in_cookie_updated_callback_) std::move(on_accounts_in_cookie_updated_callback_).Run(); } @@ -342,7 +343,7 @@ AccountInfo primary_account_from_cleared_callback_; AccountInfo account_from_refresh_token_updated_callback_; std::string account_from_refresh_token_removed_callback_; - std::vector<AccountInfo> accounts_from_cookie_change_callback_; + AccountsInCookieJarInfo accounts_info_from_cookie_change_callback_; std::string account_from_add_account_to_cookie_completed_callback_; GoogleServiceAuthError error_from_add_account_to_cookie_completed_callback_; GoogleServiceAuthError google_signin_failed_error_; @@ -1629,12 +1630,12 @@ gaia_cookie_manager_service()->SetListAccountsResponseNoAccounts(); gaia_cookie_manager_service()->TriggerListAccounts(); - run_loop.Run(); - EXPECT_TRUE(identity_manager_observer() - ->accounts_from_cookie_change_callback() - .empty()); + const AccountsInCookieJarInfo& accounts_in_cookie_jar_info = + identity_manager_observer()->accounts_info_from_cookie_change_callback(); + EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh); + EXPECT_TRUE(accounts_in_cookie_jar_info.accounts.empty()); } TEST_F(IdentityManagerTest, @@ -1648,12 +1649,12 @@ gaia_cookie_manager_service()->TriggerListAccounts(); run_loop.Run(); - EXPECT_EQ(1u, identity_manager_observer() - ->accounts_from_cookie_change_callback() - .size()); + const AccountsInCookieJarInfo& accounts_in_cookie_jar_info = + identity_manager_observer()->accounts_info_from_cookie_change_callback(); + EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh); + ASSERT_EQ(1u, accounts_in_cookie_jar_info.accounts.size()); - AccountInfo account_info = - identity_manager_observer()->accounts_from_cookie_change_callback()[0]; + AccountInfo account_info = accounts_in_cookie_jar_info.accounts[0]; EXPECT_EQ(account_tracker()->PickAccountIdForAccount(kTestGaiaId, kTestEmail), account_info.account_id); EXPECT_EQ(kTestGaiaId, account_info.gaia); @@ -1669,24 +1670,22 @@ gaia_cookie_manager_service()->SetListAccountsResponseTwoAccounts( kTestEmail, kTestGaiaId, kTestEmail2, kTestGaiaId2); gaia_cookie_manager_service()->TriggerListAccounts(); - run_loop.Run(); - EXPECT_EQ(2u, identity_manager_observer() - ->accounts_from_cookie_change_callback() - .size()); + const AccountsInCookieJarInfo& accounts_in_cookie_jar_info = + identity_manager_observer()->accounts_info_from_cookie_change_callback(); + EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh); + ASSERT_EQ(2u, accounts_in_cookie_jar_info.accounts.size()); // Verify not only that both accounts are present but that they are listed in // the expected order as well. - AccountInfo account_info1 = - identity_manager_observer()->accounts_from_cookie_change_callback()[0]; + AccountInfo account_info1 = accounts_in_cookie_jar_info.accounts[0]; EXPECT_EQ(account_tracker()->PickAccountIdForAccount(kTestGaiaId, kTestEmail), account_info1.account_id); EXPECT_EQ(kTestGaiaId, account_info1.gaia); EXPECT_EQ(kTestEmail, account_info1.email); - AccountInfo account_info2 = - identity_manager_observer()->accounts_from_cookie_change_callback()[1]; + AccountInfo account_info2 = accounts_in_cookie_jar_info.accounts[1]; EXPECT_EQ( account_tracker()->PickAccountIdForAccount(kTestGaiaId2, kTestEmail2), account_info2.account_id); @@ -1694,6 +1693,23 @@ EXPECT_EQ(kTestEmail2, account_info2.email); } +TEST_F(IdentityManagerTest, + CallbackSentOnUpdateToAccountsInCookieWithStaleAccounts) { + base::RunLoop run_loop; + identity_manager_observer()->set_on_accounts_in_cookie_updated_callback( + run_loop.QuitClosure()); + + // Configure list accounts to return a permanent Gaia auth error. + gaia_cookie_manager_service()->SetListAccountsResponseWebLoginRequired(); + gaia_cookie_manager_service()->TriggerListAccounts(); + run_loop.Run(); + + const AccountsInCookieJarInfo& accounts_in_cookie_jar_info = + identity_manager_observer()->accounts_info_from_cookie_change_callback(); + EXPECT_FALSE(accounts_in_cookie_jar_info.accounts_are_fresh); + EXPECT_TRUE(accounts_in_cookie_jar_info.accounts.empty()); +} + TEST_F(IdentityManagerTest, GetAccountsInCookieJarWithNoAccounts) { base::RunLoop run_loop; identity_manager_observer()->set_on_accounts_in_cookie_updated_callback( @@ -1704,17 +1720,20 @@ // Do an initial call to GetAccountsInCookieJar(). This call should return no // accounts but should also trigger an internal update and eventual // notification that the accounts in the cookie jar have been updated. - std::vector<AccountInfo> accounts_in_cookie_jar = + const AccountsInCookieJarInfo& accounts_in_cookie_jar = identity_manager()->GetAccountsInCookieJar(); - EXPECT_TRUE(accounts_in_cookie_jar.empty()); + EXPECT_FALSE(accounts_in_cookie_jar.accounts_are_fresh); + EXPECT_TRUE(accounts_in_cookie_jar.accounts.empty()); run_loop.Run(); // The state of the accounts in IdentityManager should now reflect the // internal update. - accounts_in_cookie_jar = identity_manager()->GetAccountsInCookieJar(); + const AccountsInCookieJarInfo updated_accounts_in_cookie_jar = + identity_manager()->GetAccountsInCookieJar(); - EXPECT_TRUE(accounts_in_cookie_jar.empty()); + EXPECT_TRUE(updated_accounts_in_cookie_jar.accounts_are_fresh); + EXPECT_TRUE(updated_accounts_in_cookie_jar.accounts.empty()); } TEST_F(IdentityManagerTest, GetAccountsInCookieJarWithOneAccount) { @@ -1728,19 +1747,22 @@ // Do an initial call to GetAccountsInCookieJar(). This call should return no // accounts but should also trigger an internal update and eventual // notification that the accounts in the cookie jar have been updated. - std::vector<AccountInfo> accounts_in_cookie_jar = + const AccountsInCookieJarInfo& accounts_in_cookie_jar = identity_manager()->GetAccountsInCookieJar(); - EXPECT_TRUE(accounts_in_cookie_jar.empty()); + EXPECT_FALSE(accounts_in_cookie_jar.accounts_are_fresh); + EXPECT_TRUE(accounts_in_cookie_jar.accounts.empty()); run_loop.Run(); // The state of the accounts in IdentityManager should now reflect the // internal update. - accounts_in_cookie_jar = identity_manager()->GetAccountsInCookieJar(); + const AccountsInCookieJarInfo& updated_accounts_in_cookie_jar = + identity_manager()->GetAccountsInCookieJar(); - EXPECT_EQ(1u, accounts_in_cookie_jar.size()); + EXPECT_TRUE(updated_accounts_in_cookie_jar.accounts_are_fresh); + ASSERT_EQ(1u, updated_accounts_in_cookie_jar.accounts.size()); - AccountInfo account_info = accounts_in_cookie_jar[0]; + AccountInfo account_info = updated_accounts_in_cookie_jar.accounts[0]; EXPECT_EQ(account_tracker()->PickAccountIdForAccount(kTestGaiaId, kTestEmail), account_info.account_id); EXPECT_EQ(kTestGaiaId, account_info.gaia); @@ -1758,27 +1780,30 @@ // Do an initial call to GetAccountsInCookieJar(). This call should return no // accounts but should also trigger an internal update and eventual // notification that the accounts in the cookie jar have been updated. - std::vector<AccountInfo> accounts_in_cookie_jar = + const AccountsInCookieJarInfo& accounts_in_cookie_jar = identity_manager()->GetAccountsInCookieJar(); - EXPECT_TRUE(accounts_in_cookie_jar.empty()); + EXPECT_FALSE(accounts_in_cookie_jar.accounts_are_fresh); + EXPECT_TRUE(accounts_in_cookie_jar.accounts.empty()); run_loop.Run(); // The state of the accounts in IdentityManager should now reflect the // internal update. - accounts_in_cookie_jar = identity_manager()->GetAccountsInCookieJar(); + const AccountsInCookieJarInfo& updated_accounts_in_cookie_jar = + identity_manager()->GetAccountsInCookieJar(); - EXPECT_EQ(2u, accounts_in_cookie_jar.size()); + EXPECT_TRUE(updated_accounts_in_cookie_jar.accounts_are_fresh); + ASSERT_EQ(2u, updated_accounts_in_cookie_jar.accounts.size()); // Verify not only that both accounts are present but that they are listed in // the expected order as well. - AccountInfo account_info1 = accounts_in_cookie_jar[0]; + AccountInfo account_info1 = updated_accounts_in_cookie_jar.accounts[0]; EXPECT_EQ(account_tracker()->PickAccountIdForAccount(kTestGaiaId, kTestEmail), account_info1.account_id); EXPECT_EQ(kTestGaiaId, account_info1.gaia); EXPECT_EQ(kTestEmail, account_info1.email); - AccountInfo account_info2 = accounts_in_cookie_jar[1]; + AccountInfo account_info2 = updated_accounts_in_cookie_jar.accounts[1]; EXPECT_EQ( account_tracker()->PickAccountIdForAccount(kTestGaiaId2, kTestEmail2), account_info2.account_id);
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc index 9093ee5..183281a 100644 --- a/services/identity/public/cpp/identity_test_utils.cc +++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -43,7 +43,8 @@ const AccountInfo& account_info) override; void OnRefreshTokenRemovedForAccount(const std::string& account_id) override; void OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) override; + const AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) override; IdentityManager* identity_manager_; base::OnceClosure done_closure_; @@ -103,7 +104,8 @@ } void OneShotIdentityManagerObserver::OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) { + const AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) { if (event_to_wait_on_ != IdentityManagerEvent::ACCOUNTS_IN_COOKIE_UPDATED) return;
diff --git a/services/identity/public/objc/identity_manager_observer_bridge.h b/services/identity/public/objc/identity_manager_observer_bridge.h index 875c787..c8c6fb8 100644 --- a/services/identity/public/objc/identity_manager_observer_bridge.h +++ b/services/identity/public/objc/identity_manager_observer_bridge.h
@@ -30,7 +30,9 @@ - (void)onRefreshTokenUpdatedForAccount:(const AccountInfo&)accountInfo; - (void)onRefreshTokenRemovedForAccount:(const std::string&)accountId; - (void)onRefreshTokensLoaded; -- (void)onAccountsInCookieUpdated:(const std::vector<AccountInfo>&)accounts; +- (void)onAccountsInCookieUpdated: + (const identity::AccountsInCookieJarInfo&)accountsInCookieJarInfo + error:(const GoogleServiceAuthError&)error; - (void)onStartBatchOfRefreshTokenStateChanges; - (void)onEndBatchOfRefreshTokenStateChanges; @@ -60,7 +62,8 @@ void OnRefreshTokenRemovedForAccount(const std::string& account_id) override; void OnRefreshTokensLoaded() override; void OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) override; + const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) override; void OnStartBatchOfRefreshTokenStateChanges() override; void OnEndBatchOfRefreshTokenStateChanges() override;
diff --git a/services/identity/public/objc/identity_manager_observer_bridge.mm b/services/identity/public/objc/identity_manager_observer_bridge.mm index c8bd4e0..3aab9a0 100644 --- a/services/identity/public/objc/identity_manager_observer_bridge.mm +++ b/services/identity/public/objc/identity_manager_observer_bridge.mm
@@ -74,9 +74,12 @@ } void IdentityManagerObserverBridge::OnAccountsInCookieUpdated( - const std::vector<AccountInfo>& accounts) { - if ([delegate_ respondsToSelector:@selector(onAccountsInCookieUpdated:)]) { - [delegate_ onAccountsInCookieUpdated:accounts]; + const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, + const GoogleServiceAuthError& error) { + if ([delegate_ respondsToSelector:@selector(onAccountsInCookieUpdated: + error:)]) { + [delegate_ onAccountsInCookieUpdated:accounts_in_cookie_jar_info + error:error]; } }
diff --git a/services/media_session/media_controller.cc b/services/media_session/media_controller.cc index 3be50c8e..a102d1d7 100644 --- a/services/media_session/media_controller.cc +++ b/services/media_session/media_controller.cc
@@ -26,6 +26,13 @@ session_->Resume(mojom::MediaSession::SuspendType::kUI); } +void MediaController::Stop() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (session_) + session_->Stop(mojom::MediaSession::SuspendType::kUI); +} + void MediaController::ToggleSuspendResume() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/services/media_session/media_controller.h b/services/media_session/media_controller.h index e162d79..3490288 100644 --- a/services/media_session/media_controller.h +++ b/services/media_session/media_controller.h
@@ -31,6 +31,7 @@ // mojom::MediaController overrides. void Suspend() override; void Resume() override; + void Stop() override; void ToggleSuspendResume() override; void AddObserver(mojom::MediaSessionObserverPtr observer) override; void PreviousTrack() override;
diff --git a/services/media_session/media_controller_unittest.cc b/services/media_session/media_controller_unittest.cc index efce085e..cea09f76 100644 --- a/services/media_session/media_controller_unittest.cc +++ b/services/media_session/media_controller_unittest.cc
@@ -354,7 +354,7 @@ { test::MockMediaSessionMojoObserver observer(media_session); RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); - media_session.Stop(); + media_session.Stop(mojom::MediaSession::SuspendType::kUI); observer.WaitForState(mojom::MediaSessionInfo::SessionState::kInactive); } @@ -602,4 +602,21 @@ } } +TEST_F(MediaControllerTest, ActiveController_Stop) { + test::MockMediaSession media_session; + media_session.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session); + RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); + observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive); + } + + { + test::MockMediaSessionMojoObserver observer(media_session); + controller()->Stop(); + observer.WaitForState(mojom::MediaSessionInfo::SessionState::kInactive); + } +} + } // namespace media_session
diff --git a/services/media_session/public/cpp/test/mock_media_session.cc b/services/media_session/public/cpp/test/mock_media_session.cc index 47939026..095bf865 100644 --- a/services/media_session/public/cpp/test/mock_media_session.cc +++ b/services/media_session/public/cpp/test/mock_media_session.cc
@@ -136,7 +136,7 @@ seek_count_++; } -void MockMediaSession::Stop() { +void MockMediaSession::Stop(SuspendType type) { SetState(mojom::MediaSessionInfo::SessionState::kInactive); }
diff --git a/services/media_session/public/cpp/test/mock_media_session.h b/services/media_session/public/cpp/test/mock_media_session.h index 5dcdc52..5cba5df1 100644 --- a/services/media_session/public/cpp/test/mock_media_session.h +++ b/services/media_session/public/cpp/test/mock_media_session.h
@@ -85,8 +85,8 @@ void PreviousTrack() override; void NextTrack() override; void Seek(base::TimeDelta seek_time) override; + void Stop(SuspendType type) override; - void Stop(); void SetIsControllable(bool value); void AbandonAudioFocusFromClient();
diff --git a/services/media_session/public/cpp/test/test_media_controller.h b/services/media_session/public/cpp/test/test_media_controller.h index 479fdf5..6e9b594a 100644 --- a/services/media_session/public/cpp/test/test_media_controller.h +++ b/services/media_session/public/cpp/test/test_media_controller.h
@@ -24,6 +24,7 @@ // mojom::MediaController: void Suspend() override; void Resume() override; + void Stop() override {} void ToggleSuspendResume() override; void AddObserver(mojom::MediaSessionObserverPtr) override; void PreviousTrack() override;
diff --git a/services/media_session/public/mojom/media_controller.mojom b/services/media_session/public/mojom/media_controller.mojom index c797bc8..7d22ef6 100644 --- a/services/media_session/public/mojom/media_controller.mojom +++ b/services/media_session/public/mojom/media_controller.mojom
@@ -17,6 +17,9 @@ // Resume the media session. Resume(); + // Stop the media session. + Stop(); + // This will either suspend or resume the media session based on the // playback state. ToggleSuspendResume();
diff --git a/services/media_session/public/mojom/media_session.mojom b/services/media_session/public/mojom/media_session.mojom index 0ba2966d..ff9a6800 100644 --- a/services/media_session/public/mojom/media_session.mojom +++ b/services/media_session/public/mojom/media_session.mojom
@@ -17,7 +17,6 @@ kPlaying, }; -// Spec: https://wicg.github.io/mediasession/ [Extensible] enum MediaSessionAction { kPlay, @@ -26,6 +25,7 @@ kNextTrack, kSeekBackward, kSeekForward, + kStop, }; // Album art in MediaMetadata @@ -106,7 +106,7 @@ // WebContents or ARC app. // TODO(https://crbug.com/875004): migrate media session from content/public // to mojo. -// Next Method ID: 10 +// Next Method ID: 11 interface MediaSession { [Extensible] enum SuspendType { @@ -156,4 +156,8 @@ // The |kDefaultSeekTimeSeconds| provides a default value for seeking by a // few seconds. Seek@9(mojo_base.mojom.TimeDelta seek_time); + + // Stop the media session. + // |type| represents the origin of the request. + Stop@10(SuspendType suspend_type); };
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index c2181d1..cb782c4 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -92,20 +92,27 @@ void TraceEventMetadataSource::StartTracing( ProducerClient* producer_client, const mojom::DataSourceConfig& data_source_config) { - origin_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&TraceEventMetadataSource::GenerateMetadata, - base::Unretained(this), - producer_client->CreateTraceWriter( - data_source_config.target_buffer))); + // TODO(eseckler): Once we support streaming of trace data, it would make + // sense to emit the metadata on startup, so the UI can display it right away. + producer_client_ = producer_client; + target_buffer_ = data_source_config.target_buffer; } void TraceEventMetadataSource::StopTracing( base::OnceClosure stop_complete_callback) { - // We bounce a task off the origin_task_runner_ that the generator - // callbacks are run from, to make sure that GenerateMetaData() has finished - // running. - origin_task_runner_->PostTaskAndReply(FROM_HERE, base::DoNothing(), - std::move(stop_complete_callback)); + if (producer_client_) { + // Write metadata at the end of tracing to make it less likely that it is + // overridden by other trace data in perfetto's ring buffer. + origin_task_runner_->PostTaskAndReply( + FROM_HERE, + base::BindOnce(&TraceEventMetadataSource::GenerateMetadata, + base::Unretained(this), + producer_client_->CreateTraceWriter(target_buffer_)), + std::move(stop_complete_callback)); + producer_client_ = nullptr; + } else { + std::move(stop_complete_callback).Run(); + } } void TraceEventMetadataSource::Flush(
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.h b/services/tracing/public/cpp/perfetto/trace_event_data_source.h index ce00e28..e53d993 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.h +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.h
@@ -46,6 +46,8 @@ std::vector<MetadataGeneratorFunction> generator_functions_; scoped_refptr<base::SequencedTaskRunner> origin_task_runner_; base::Lock lock_; + ProducerClient* producer_client_ = nullptr; + uint32_t target_buffer_ = 0; DISALLOW_COPY_AND_ASSIGN(TraceEventMetadataSource); };
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc index 09d5839..6d0e361 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -290,9 +290,9 @@ auto data_source_config = mojom::DataSourceConfig::New(); metadata_source->StartTracing(producer_client(), *data_source_config); - base::RunLoop wait_for_flush; - metadata_source->Flush(wait_for_flush.QuitClosure()); - wait_for_flush.Run(); + base::RunLoop wait_for_stop; + metadata_source->StopTracing(wait_for_stop.QuitClosure()); + wait_for_stop.Run(); auto metadata = producer_client()->GetChromeMetadata(); EXPECT_EQ(4, metadata.size());
diff --git a/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter b/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter index 742fac9..87079f70 100644 --- a/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter +++ b/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter
@@ -24,8 +24,5 @@ # https://crbug.com/912191 -ImmersiveModeBrowserViewTest.LockedFullscreenDisablesImmersive/* -# Flaky https://crbug.com/912213 --WebBluetoothTest.NavigateWithChooserCrossOrigin - # Flaky https://crbug.com/914232 -ExtensionWebRequestApiTest.WebRequestTypes
diff --git a/testing/buildbot/filters/chromeos.single_process_mash.unit_tests.filter b/testing/buildbot/filters/chromeos.single_process_mash.unit_tests.filter index 0cf42f5..cf1ca97 100644 --- a/testing/buildbot/filters/chromeos.single_process_mash.unit_tests.filter +++ b/testing/buildbot/filters/chromeos.single_process_mash.unit_tests.filter
@@ -13,6 +13,3 @@ # Fails because a MusClient is needed. Blocked on folding views_mus_test_suite # into views_test_suite. -OmniboxViewViewsSteadyStateElisionsTest.GestureTaps - -# Flaky https://crbug.com/913577 --AdaptiveScreenBrightnessManagerTest.SingleBrowser
diff --git a/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter b/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter index ba7483e..321963a 100644 --- a/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter +++ b/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter
@@ -99,6 +99,7 @@ # https://crbug.com/893576 -org.chromium.android_webview.test.CookieManagerTest.testAcceptCookie -org.chromium.android_webview.test.CookieManagerTest.testAcceptFileSchemeCookies +-org.chromium.android_webview.test.CookieManagerTest.testEmbedderCanSeeRestrictedCookies -org.chromium.android_webview.test.CookieManagerTest.testRejectFileSchemeCookies -org.chromium.android_webview.test.CookieManagerTest.testThirdPartyCookie -org.chromium.android_webview.test.CookieManagerTest.testThirdPartyCookieForWebSocketEnabledCase
diff --git a/testing/test.gni b/testing/test.gni index a67452b..57dd9bb4 100644 --- a/testing/test.gni +++ b/testing/test.gni
@@ -334,7 +334,7 @@ "$root_out_dir/gen.runtime/" + get_label_info(target_name, "dir") + "/" + get_label_info(target_name, "name") + ".runtime_deps" - generate_vm_runner_script(_gen_runner_target) { + generate_runner_script(_gen_runner_target) { testonly = true generated_script = "$root_build_dir/bin/run_" + invoker.target_name test_exe = invoker.target_name
diff --git a/third_party/android_crazy_linker/BUILD.gn b/third_party/android_crazy_linker/BUILD.gn index c635138..36001497 100644 --- a/third_party/android_crazy_linker/BUILD.gn +++ b/third_party/android_crazy_linker/BUILD.gn
@@ -3,8 +3,8 @@ # found in the LICENSE file. import("//build/config/android/config.gni") -import("//testing/test.gni") import("//testing/libfuzzer/fuzzer_test.gni") +import("//testing/test.gni") # NOTE: This file is included in Linux builds to build the # crazy_linker_zip_fuzzer target (see below). However, the rest of the @@ -102,8 +102,8 @@ "src/src/crazy_linker_system.h", "src/src/crazy_linker_system_linker.cpp", "src/src/crazy_linker_system_linker.h", - "src/src/crazy_linker_thread.cpp", - "src/src/crazy_linker_thread.h", + "src/src/crazy_linker_thread_data.cpp", + "src/src/crazy_linker_thread_data.h", "src/src/crazy_linker_util.cpp", "src/src/crazy_linker_util.h", "src/src/crazy_linker_wrappers.cpp", @@ -165,7 +165,8 @@ "src/src/crazy_linker_relr_relocations_unittest.cpp", "src/src/crazy_linker_search_path_list_unittest.cpp", "src/src/crazy_linker_system_unittest.cpp", - "src/src/crazy_linker_thread_unittest.cpp", + "src/src/crazy_linker_thread_data_unittest.cpp", + "src/src/crazy_linker_util_threads_unittest.cpp", "src/src/crazy_linker_util_unittest.cpp", "src/src/crazy_linker_zip_test_data.cpp", "src/src/crazy_linker_zip_test_data.h", @@ -386,6 +387,7 @@ sources = [ "src/tests/test_load_library_callbacks.cpp", ] + include_dirs = [ "src/src" ] # Needed for crazy_linker_util_threads.h data_deps = [ ":crazy_linker_tests_libbar", ]
diff --git a/third_party/android_crazy_linker/src/run_tests.sh b/third_party/android_crazy_linker/src/run_tests.sh index 3e94967..cb04a3ae 100755 --- a/third_party/android_crazy_linker/src/run_tests.sh +++ b/third_party/android_crazy_linker/src/run_tests.sh
@@ -65,6 +65,7 @@ VERBOSE=0 DO_HELP= DO_TEST= +DO_UNIT_TESTS= for OPT; do case $OPT in --output-dir=*) @@ -73,6 +74,9 @@ --help|-?) DO_HELP=true ;; + --unit-tests) + DO_UNIT_TESTS=true + ;; --verbose) VERBOSE=$(( $VERBOSE + 1 )) ;; @@ -109,6 +113,7 @@ --help|-? Print this message. --output-dir=<dir> Manually set the Chromium output directory. + --unit-tests Also run the unit-tests suite (for convenience). --verbose Increment verbosity. EOF @@ -152,8 +157,6 @@ libcrazy_linker_tests_libzoo_with_dlopen_handle.so \ " -# TODO(digit): Fix crazy_linker_test_load_library_callbacks and add it -# to the list. TEST_FILES="\ crazy_linker_bench_load_library \ crazy_linker_test_constructors_destructors \ @@ -162,6 +165,7 @@ crazy_linker_test_dl_wrappers_with_system_handle \ crazy_linker_test_dl_wrappers_valid_handles \ crazy_linker_test_load_library \ +crazy_linker_test_load_library_callbacks \ crazy_linker_test_load_library_depends \ crazy_linker_test_load_library_with_gnu_hash_table \ crazy_linker_test_load_library_with_relr_relocations \ @@ -195,6 +199,14 @@ run adb_shell LD_LIBRARY_PATH=$RUN_DIR $RUN_DIR/$TEST_NAME "$@" } +if [ -n "$DO_UNIT_TESTS" ]; then + UT_FLAGS= + if [ "$VERBOSE" -ge 1 ]; then + UT_FLAGS="--verbose" + fi + $PROGDIR/run_android_crazy_linker_unittests $UT_FLAGS +fi + if [ -n "$DO_TEST" ]; then run_test "$DO_TEST" else
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_api.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_api.cpp index 8fb91b40..b4d2b65d 100644 --- a/third_party/android_crazy_linker/src/src/crazy_linker_api.cpp +++ b/third_party/android_crazy_linker/src/src/crazy_linker_api.cpp
@@ -8,16 +8,16 @@ #include <string.h> -#include "crazy_linker_error.h" #include "crazy_linker_ashmem.h" +#include "crazy_linker_error.h" #include "crazy_linker_globals.h" +#include "crazy_linker_library_view.h" #include "crazy_linker_proc_maps.h" #include "crazy_linker_search_path_list.h" #include "crazy_linker_shared_library.h" -#include "crazy_linker_thread.h" -#include "crazy_linker_util.h" -#include "crazy_linker_library_view.h" #include "crazy_linker_system.h" +#include "crazy_linker_thread_data.h" +#include "crazy_linker_util.h" using crazy::Globals; using crazy::Error;
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_macros.h b/third_party/android_crazy_linker/src/src/crazy_linker_macros.h new file mode 100644 index 0000000..55c3676 --- /dev/null +++ b/third_party/android_crazy_linker/src/src/crazy_linker_macros.h
@@ -0,0 +1,26 @@ +// Copyright 2018 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 CRAZY_LINKER_MACROS_H +#define CRAZY_LINKER_MACROS_H + +// Use this inside a class declaration to disallow copy construction and +// assignment. +#define CRAZY_DISALLOW_COPY_OPERATIONS(Class) \ + Class(const Class&) = delete; \ + Class& operator=(const Class&) = delete; + +// Use this inside a class declaration to disallow move construction and +// assignment. +#define CRAZY_DISALLOW_MOVE_OPERATIONS(Class) \ + Class(Class&&) = delete; \ + Class& operator=(Class&&) = delete; + +// Use this inside a class declaration to disallow both copy and move +// construction and assignments. +#define CRAZY_DISALLOW_COPY_AND_MOVE_OPERATIONS(Class) \ + CRAZY_DISALLOW_COPY_OPERATIONS(Class) \ + CRAZY_DISALLOW_MOVE_OPERATIONS(Class) + +#endif // CRAZY_LINKER_MACROS_H
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.cpp index 6a2cd71..73c7442 100644 --- a/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.cpp +++ b/third_party/android_crazy_linker/src/src/crazy_linker_rdebug.cpp
@@ -7,7 +7,6 @@ #include <elf.h> #include <inttypes.h> #include <limits.h> -#include <pthread.h> #include <sys/mman.h> #include <unistd.h> @@ -16,6 +15,7 @@ #include "crazy_linker_proc_maps.h" #include "crazy_linker_system.h" #include "crazy_linker_util.h" +#include "crazy_linker_util_threads.h" #include "elf_traits.h" namespace crazy { @@ -241,20 +241,6 @@ namespace { -// Helper class providing a simple scoped pthreads mutex. -class ScopedMutexLock { - public: - explicit ScopedMutexLock(pthread_mutex_t* mutex) : mutex_(mutex) { - pthread_mutex_lock(mutex_); - } - ~ScopedMutexLock() { - pthread_mutex_unlock(mutex_); - } - - private: - pthread_mutex_t* mutex_; -}; - // Helper runnable class. Handler is one of the two static functions // AddEntryInternal() or DelEntryInternal(). Calling these invokes // AddEntryImpl() or DelEntryImpl() respectively on rdebug. @@ -264,11 +250,10 @@ RDebug* rdebug, link_map_t* entry, bool is_blocking) - : handler_(handler), rdebug_(rdebug), - entry_(entry), is_blocking_(is_blocking), has_run_(false) { - pthread_mutex_init(&mutex_, NULL); - pthread_cond_init(&cond_, NULL); - } + : handler_(handler), + rdebug_(rdebug), + entry_(entry), + is_blocking_(is_blocking) {} static void Run(void* opaque); static void WaitForCallback(void* opaque); @@ -278,14 +263,12 @@ RDebug* rdebug_; link_map_t* entry_; bool is_blocking_; - bool has_run_; - pthread_mutex_t mutex_; - pthread_cond_t cond_; + WaitableEvent has_run_; }; // Callback entry point. void RDebugRunnable::Run(void* opaque) { - RDebugRunnable* runnable = static_cast<RDebugRunnable*>(opaque); + auto* runnable = static_cast<RDebugRunnable*>(opaque); LOG("Callback received, runnable=%p", runnable); (*runnable->handler_)(runnable->rdebug_, runnable->entry_); @@ -296,16 +279,12 @@ } LOG("Signalling callback, runnable=%p", runnable); - { - ScopedMutexLock m(&runnable->mutex_); - runnable->has_run_ = true; - pthread_cond_signal(&runnable->cond_); - } + runnable->has_run_.Signal(); } // For blocking callbacks, wait for the call to Run(). void RDebugRunnable::WaitForCallback(void* opaque) { - RDebugRunnable* runnable = static_cast<RDebugRunnable*>(opaque); + auto* runnable = static_cast<RDebugRunnable*>(opaque); if (!runnable->is_blocking_) { LOG("Non-blocking, not waiting, runnable=%p", runnable); @@ -313,11 +292,7 @@ } LOG("Waiting for signal, runnable=%p", runnable); - { - ScopedMutexLock m(&runnable->mutex_); - while (!runnable->has_run_) - pthread_cond_wait(&runnable->cond_, &runnable->mutex_); - } + runnable->has_run_.Wait(); delete runnable; }
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp index 2bf89d0..eff2102 100644 --- a/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp +++ b/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp
@@ -17,7 +17,7 @@ #include "crazy_linker_library_view.h" #include "crazy_linker_memory_mapping.h" #include "crazy_linker_system_linker.h" -#include "crazy_linker_thread.h" +#include "crazy_linker_thread_data.h" #include "crazy_linker_util.h" #include "crazy_linker_wrappers.h" #include "linker_phdr.h"
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_thread.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_thread_data.cpp similarity index 90% rename from third_party/android_crazy_linker/src/src/crazy_linker_thread.cpp rename to third_party/android_crazy_linker/src/src/crazy_linker_thread_data.cpp index acc82fb..d685c429 100644 --- a/third_party/android_crazy_linker/src/src/crazy_linker_thread.cpp +++ b/third_party/android_crazy_linker/src/src/crazy_linker_thread_data.cpp
@@ -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 "crazy_linker_thread.h" +#include "crazy_linker_thread_data.h" #include <pthread.h> #include <stdio.h> @@ -14,7 +14,9 @@ static pthread_key_t s_thread_key; static pthread_once_t s_once = PTHREAD_ONCE_INIT; -static void ThreadDataDestroy(void* data) { free(data); } +static void ThreadDataDestroy(void* data) { + free(data); +} static void InitThreadKey() { pthread_key_create(&s_thread_key, ThreadDataDestroy); @@ -68,7 +70,9 @@ } // Set the linker error string for the current thread. -void SetLinkerErrorString(const char* str) { GetThreadData()->SetError(str); } +void SetLinkerErrorString(const char* str) { + GetThreadData()->SetError(str); +} // Set the formatted linker error for the current thread. void SetLinkerError(const char* fmt, ...) {
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_thread.h b/third_party/android_crazy_linker/src/src/crazy_linker_thread_data.h similarity index 93% rename from third_party/android_crazy_linker/src/src/crazy_linker_thread.h rename to third_party/android_crazy_linker/src/src/crazy_linker_thread_data.h index 020bf14..7cffdc5 100644 --- a/third_party/android_crazy_linker/src/src/crazy_linker_thread.h +++ b/third_party/android_crazy_linker/src/src/crazy_linker_thread_data.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 CRAZY_LINKER_THREAD_H -#define CRAZY_LINKER_THREAD_H +#ifndef CRAZY_LINKER_THREAD_DATA_H +#define CRAZY_LINKER_THREAD_DATA_H #include <stdarg.h> #include <stddef.h> @@ -12,7 +12,6 @@ // Per-thread context used during crazy linker operations. class ThreadData { - public: ThreadData() {} @@ -76,6 +75,6 @@ // Set the formatted linker error for the current thread. void SetLinkerError(const char* fmt, ...); -} // namespace crazy; +} // namespace crazy -#endif // CRAZY_LINKER_THREAD_H +#endif // CRAZY_LINKER_THREAD_DATA_H
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_thread_unittest.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_thread_data_unittest.cpp similarity index 85% rename from third_party/android_crazy_linker/src/src/crazy_linker_thread_unittest.cpp rename to third_party/android_crazy_linker/src/src/crazy_linker_thread_data_unittest.cpp index 0e34e67..783d9f8 100644 --- a/third_party/android_crazy_linker/src/src/crazy_linker_thread_unittest.cpp +++ b/third_party/android_crazy_linker/src/src/crazy_linker_thread_data_unittest.cpp
@@ -2,41 +2,41 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "crazy_linker_thread.h" +#include "crazy_linker_thread_data.h" #include <gtest/gtest.h> namespace crazy { -TEST(Thread, GetThreadData) { +TEST(ThreadData, GetThreadData) { ThreadData* data = GetThreadData(); EXPECT_TRUE(data) << "Checking first GetThreadData() call"; EXPECT_EQ(data, GetThreadData()); EXPECT_EQ(data, GetThreadDataFast()); } -TEST(Thread, GetErrorEmpty) { +TEST(ThreadData, GetErrorEmpty) { ThreadData* data = GetThreadData(); const char* error = data->GetError(); EXPECT_TRUE(error); EXPECT_STREQ("", error); } -TEST(Thread, SetError) { +TEST(ThreadData, SetError) { ThreadData* data = GetThreadData(); data->SetError("Hello"); data->SetError("World"); EXPECT_STREQ("World", data->GetError()); } -TEST(Thread, SetErrorNull) { +TEST(ThreadData, SetErrorNull) { ThreadData* data = GetThreadData(); data->SetError("Hello"); data->SetError(NULL); EXPECT_STREQ("", data->GetError()); } -TEST(Thread, GetError) { +TEST(ThreadData, GetError) { ThreadData* data = GetThreadData(); data->SetError("Hello"); @@ -47,7 +47,7 @@ EXPECT_STREQ("Hello", error); } -TEST(Thread, SwapErrorBuffers) { +TEST(ThreadData, SwapErrorBuffers) { ThreadData* data = GetThreadData(); data->SetError("Hello"); EXPECT_STREQ("Hello", data->GetError()); @@ -62,7 +62,7 @@ EXPECT_STREQ("", data->GetError()); } -TEST(Thread, AppendErrorTwice) { +TEST(ThreadData, AppendErrorTwice) { ThreadData* data = GetThreadData(); data->SetError(NULL); data->AppendError("Hello"); @@ -72,7 +72,7 @@ EXPECT_STREQ("Hello World", data->GetError()); } -TEST(Thread, AppendErrorFull) { +TEST(ThreadData, AppendErrorFull) { const size_t kMaxCount = 1000; ThreadData* data = GetThreadData(); data->SetError(NULL); @@ -91,7 +91,7 @@ } } -TEST(Thread, AppendErrorNull) { +TEST(ThreadData, AppendErrorNull) { ThreadData* data = GetThreadData(); data->SetError("Hello"); data->AppendError(NULL); @@ -99,7 +99,7 @@ EXPECT_STREQ("Hello World", data->GetError()); } -TEST(Thread, SetLinkerErrorString) { +TEST(ThreadData, SetLinkerErrorString) { ThreadData* data = GetThreadData(); SetLinkerErrorString("Hello World"); @@ -109,7 +109,7 @@ EXPECT_STREQ("", data->GetError()); } -TEST(Thread, SetLinkerError) { +TEST(ThreadData, SetLinkerError) { ThreadData* data = GetThreadData(); SetLinkerError("%s %s!", "Hi", "Captain");
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_util_threads.h b/third_party/android_crazy_linker/src/src/crazy_linker_util_threads.h new file mode 100644 index 0000000..b6b96997 --- /dev/null +++ b/third_party/android_crazy_linker/src/src/crazy_linker_util_threads.h
@@ -0,0 +1,143 @@ +// Copyright 2018 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 CRAZY_LINKER_UTIL_THREADS_H +#define CRAZY_LINKER_UTIL_THREADS_H + +#include <pthread.h> + +#include "crazy_linker_macros.h" + +// Convenience classes for managing and synchronizing threads. +// Reminder: the crazy linker cannot use std::thread and other C++ library +// features at all. + +namespace crazy { + +// Small abstraction for simple (non-recursive) mutexes. +class Mutex { + public: + Mutex() = default; + ~Mutex() { pthread_mutex_destroy(&mutex_); } + void Lock() { pthread_mutex_lock(&mutex_); } + void Unlock() { pthread_mutex_unlock(&mutex_); } + + // Futexes cannot be copied or moved to different addresses. + CRAZY_DISALLOW_COPY_AND_MOVE_OPERATIONS(Mutex) + + private: + friend class Condition; + pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER; +}; + +// Scoped auto-lock convenience class. +// Locks the mutex on construction, releases it on destruction unless +// Release() was called before. +class AutoLock { + public: + // Constructor takes pointer to Mutex instance and locks it. + AutoLock() = delete; + explicit AutoLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); } + // Destructor unlocks it if it wasn't released yet. + ~AutoLock() { + if (mutex_) + mutex_->Unlock(); + } + + CRAZY_DISALLOW_COPY_AND_MOVE_OPERATIONS(AutoLock); + + private: + Mutex* mutex_ = nullptr; +}; + +// Small abstraction for condition variables. +class Condition { + public: + // Constructor takes pointer to associated mutex. + Condition() = delete; + explicit Condition(Mutex* mutex) : mutex_(mutex) {} + ~Condition() { pthread_cond_destroy(&cond_); } + void Signal() { pthread_cond_signal(&cond_); } + void Wait() { pthread_cond_wait(&cond_, &mutex_->mutex_); } + + // Futexes cannot be copied or moved to different addresses. + CRAZY_DISALLOW_COPY_AND_MOVE_OPERATIONS(Condition); + + private: + Mutex* mutex_; + pthread_cond_t cond_ = PTHREAD_COND_INITIALIZER; +}; + +// Small waitable event to synchronize two threads. +class WaitableEvent { + public: + WaitableEvent() : mutex_(), cond_(&mutex_) {} + ~WaitableEvent() = default; + + // Returns true iff the event was signaled. + bool IsSignaled() const { + AutoLock lock(&mutex_); + return signaled_; + } + + // Signal event, it will be reset after Wait() is called. + // Can be called several times. + void Signal() { + AutoLock lock(&mutex_); + signaled_ = true; + cond_.Signal(); + } + + // Wait for the event being signaled. Always reset the event. + void Wait() { + AutoLock lock(&mutex_); + while (!signaled_) + cond_.Wait(); + signaled_ = false; + } + + private: + mutable Mutex mutex_; + Condition cond_; + bool signaled_ = false; +}; + +// Small abstract base thread class. Usage is the following: +// 1) Define derived class that implements the Main() method. +// 2) Create new instance of derived class, which starts the thread +// immediately. +// 3) Call Join() method to wait for thread exit. +// 4) Delete the instance. +class ThreadBase { + public: + // Constructor creates background thread, and starts it immediately. + ThreadBase() { + pthread_create( + &handle_, nullptr, + [](void* arg) -> void* { + reinterpret_cast<ThreadBase*>(arg)->Main(); + return nullptr; + }, + reinterpret_cast<void*>(this)); + } + + // Destructor. + virtual ~ThreadBase() = default; + + // Wait until the thread terminates. + void Join() { + void* dummy = nullptr; + pthread_join(handle_, &dummy); + } + + // Must be implemented by derived classes. + virtual void Main() = 0; + + private: + pthread_t handle_; +}; + +} // namespace crazy + +#endif // CRAZY_LINKER_UTIL_THREADS_H
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_util_threads_unittest.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_util_threads_unittest.cpp new file mode 100644 index 0000000..ae07284 --- /dev/null +++ b/third_party/android_crazy_linker/src/src/crazy_linker_util_threads_unittest.cpp
@@ -0,0 +1,135 @@ +// Copyright 2018 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 "crazy_linker_util_threads.h" + +#include <gtest/gtest.h> + +#include <memory> + +#include <sched.h> + +namespace crazy { + +TEST(ThreadBase, SimpleThread) { + // Create a test thread class that simply sets a flag to true in its + // main body and exits immediately. + class SimpleThread : public ThreadBase { + public: + SimpleThread(bool* flag_ptr) : flag_ptr_(flag_ptr) {} + + private: + void Main() override { *flag_ptr_ = true; } + bool* flag_ptr_; + }; + + bool flag = false; + SimpleThread thread(&flag); + thread.Join(); + ASSERT_TRUE(flag); +} + +TEST(Mutex, SimpleLockUnlock) { + Mutex m; + m.Lock(); + m.Unlock(); +} + +TEST(Mutex, ThreadSynchronization) { + // State shared by all threads, i.e. a mutex-protected counter. + struct SharedState { + Mutex mutex; + int counter = 0; + }; + // Create kMaxThreads that will use a common lock to increment a counter + // in succession. Each thread has a numerical id, and will loop until + // the counter reaches before incrementing it then exiting. + class TestThread : public ThreadBase { + public: + TestThread(SharedState* state, int id) : state_(state), id_(id) {} + + private: + void Main() override { + bool quit = false; + while (!quit) { + state_->mutex.Lock(); + if (state_->counter == id_) { + state_->counter += 1; + quit = true; + } else { + sched_yield(); + } + state_->mutex.Unlock(); + } + } + + SharedState* state_; + int id_; + }; + + SharedState state; + const int kMaxThreads = 100; + std::unique_ptr<TestThread> threads[kMaxThreads]; + + // Launch all threads + for (int n = kMaxThreads; n > 0; n--) { + threads[n - 1].reset(new TestThread(&state, n - 1)); + } + + // Join the last thread, this should only return when all other threads + // have completed. + threads[kMaxThreads - 1]->Join(); + + ASSERT_EQ(kMaxThreads, state.counter); + for (int n = 0; n < kMaxThreads - 1; n++) + threads[n]->Join(); +} + +TEST(Condition, ThreadSynchonization) { + // A TestThread class which will wait until Start() is called to increment + // a given integer counter then exiting. + class TestThread : public ThreadBase { + public: + TestThread(int* counter_ptr) : counter_ptr_(counter_ptr), cond_(&mutex_) {} + + void Start() { + mutex_.Lock(); + started_ = true; + cond_.Signal(); + mutex_.Unlock(); + } + + private: + void Main() override { + mutex_.Lock(); + while (!started_) + cond_.Wait(); + + *counter_ptr_ += 1; + mutex_.Unlock(); + } + + int* counter_ptr_; + Mutex mutex_; + Condition cond_; + bool started_ = false; + }; + + int counter = 0; + const int kMaxThreads = 100; + std::unique_ptr<TestThread> threads[kMaxThreads]; + + for (int n = 0; n < kMaxThreads; ++n) { + threads[n].reset(new TestThread(&counter)); + } + + ASSERT_EQ(0, counter); + for (int n = 0; n < kMaxThreads; ++n) { + threads[n]->Start(); + threads[n]->Join(); + ASSERT_EQ(n + 1, counter); + } +} + +} // namespace crazy
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_wrappers.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_wrappers.cpp index 1813fb5..d03121d5 100644 --- a/third_party/android_crazy_linker/src/src/crazy_linker_wrappers.cpp +++ b/third_party/android_crazy_linker/src/src/crazy_linker_wrappers.cpp
@@ -12,7 +12,7 @@ #include "crazy_linker_library_view.h" #include "crazy_linker_shared_library.h" #include "crazy_linker_system_linker.h" -#include "crazy_linker_thread.h" +#include "crazy_linker_thread_data.h" #include "crazy_linker_util.h" #ifdef __arm__
diff --git a/third_party/android_crazy_linker/src/tests/test_load_library_callbacks.cpp b/third_party/android_crazy_linker/src/tests/test_load_library_callbacks.cpp index c1c342d..2f8d84e 100644 --- a/third_party/android_crazy_linker/src/tests/test_load_library_callbacks.cpp +++ b/third_party/android_crazy_linker/src/tests/test_load_library_callbacks.cpp
@@ -4,106 +4,103 @@ // A crazy linker test to test callbacks for delayed execution. -#include <pthread.h> #include <stdio.h> #include <crazy_linker.h> -#include "test_util.h" +#include "test_util.h" // For Panic() + +#include "crazy_linker_util_threads.h" namespace { typedef void (*FunctionPtr)(); // Data block passed between callback poster and callback handler. -class CallbackData { +// It is used to hold a single crazy_callback_t instance while allowing +// synchronization between two threads, i.e.: +// +// - One thread can cann SetCallback() to set the callback. +// +// - Another thread can call WaitForSetCallback() to wait for the first +// one to call SetCallback() and retrieve the callback value. +// +// - Once SetCallback() was called, RunCallback() can be called to +// actually run the callback and clear the state. +// +class SharedState { public: - CallbackData() { - callback_.handler = NULL; - callback_.opaque = NULL; - pthread_mutex_init(&mutex_, NULL); - pthread_cond_init(&cond_, NULL); + SharedState() : cond_(&mutex_) {} + + // Set the callback in the shared state. This will signal WaitForSetCallback() + void SetCallback(crazy_callback_t callback) { + crazy::AutoLock m(&mutex_); + callback_ = callback; + cond_.Signal(); } - crazy_callback_t callback_; - pthread_mutex_t mutex_; - pthread_cond_t cond_; + // Returns true iff a callback is stored in this state, e.g. after + // calling SetCallback(). + bool HasCallback() const { + crazy::AutoLock m(&mutex_); + return callback_.handler != nullptr; + } + + // Wait until SetCallback() is called from another thread. + // Return the corresponding value and return the callback, clearing + // the shared state. + void WaitForCallback() { + // Wait for the library close to call PostCallback() before returning. + mutex_.Lock(); + while (!callback_.handler) { + cond_.Wait(); + } + mutex_.Unlock(); + } + + // Run the callback. This will panic if SetCallback() was not called + // previously. + void RunCallback() { + if (!callback_.handler) { + Panic("No callback set in shared state!\n"); + } + // Run the callback, then clear it. + crazy_callback_run(&callback_); + callback_.handler = nullptr; + callback_.opaque = nullptr; + } + + crazy_callback_t callback_ = {}; + mutable crazy::Mutex mutex_; + crazy::Condition cond_; }; +// This function is called from the crazy linker whenever a new pending +// operation must be run on the UI thread. |callback| will have to be +// run later from another thread in this sample program, by calling +// crazy_callback_run(). bool PostCallback(crazy_callback_t* callback, void* poster_opaque) { printf("Post callback, poster_opaque %p, handler %p, opaque %p\n", - poster_opaque, - callback->handler, - callback->opaque); - - CallbackData* callback_data = reinterpret_cast<CallbackData*>(poster_opaque); - - // Set callback_ and signal the arrival of the PostCallback() call. - pthread_mutex_lock(&callback_data->mutex_); - callback_data->callback_ = *callback; - pthread_cond_signal(&callback_data->cond_); - pthread_mutex_unlock(&callback_data->mutex_); - + poster_opaque, callback->handler, callback->opaque); + reinterpret_cast<SharedState*>(poster_opaque)->SetCallback(*callback); return true; } -void CheckAndRunCallback(CallbackData* callback_data) { - printf("Run callback, callback_data %p\n", callback_data); +// A simple thread that will close a crazy_library_t instance in its +// main body then exit immediately. Note that closing the library will +// force the linker to wait for the completion of any callbacks that +// were sent through PostCallback(). +class CloserThread : public crazy::ThreadBase { + public: + CloserThread(crazy_library_t* library, crazy_context_t* context) + : library_(library), context_(context) {} - if (!callback_data->callback_.handler) { - Panic("Post for delayed execution not invoked\n"); - } + private: + void Main() override { crazy_library_close_with_context(library_, context_); } - // Run the callback, then clear it. - crazy_callback_run(&callback_data->callback_); - callback_data->callback_.handler = NULL; - callback_data->callback_.opaque = NULL; -} - -struct ThreadData { - crazy_library_t* library; - crazy_context_t* context; + crazy_library_t* library_; + crazy_context_t* context_; }; -void* ThreadBody(void *thread_arg) { - const ThreadData* thread_data = reinterpret_cast<ThreadData*>(thread_arg); - - // Close the library, asynchronously. - crazy_library_close_with_context(thread_data->library, thread_data->context); - pthread_exit(NULL); -} - -pthread_t AsyncCrazyLibraryCloseWithContext(crazy_library_t* library, - crazy_context_t* context, - CallbackData* callback_data) { - printf("Async close, library %p, context %p\n", library, context); - - ThreadData thread_data = {library, context}; - void* thread_arg = reinterpret_cast<void*>(&thread_data); - - // Clear the indication that the new thread has called PostCallback(). - pthread_mutex_lock(&callback_data->mutex_); - callback_data->callback_.handler = NULL; - callback_data->callback_.opaque = NULL; - pthread_mutex_unlock(&callback_data->mutex_); - - // Start the thread that closes the library. - pthread_t thread; - if (pthread_create(&thread, NULL, ThreadBody, thread_arg) != 0) { - Panic("Failed to create thread for close\n"); - } - - // Wait for the library close to call PostCallback() before returning. - printf("Waiting for PostCallback() call\n"); - pthread_mutex_lock(&callback_data->mutex_); - while (!callback_data->callback_.handler) { - pthread_cond_wait(&callback_data->cond_, &callback_data->mutex_); - } - pthread_mutex_unlock(&callback_data->mutex_); - printf("Done waiting for PostCallback() call\n"); - - return thread; -} - } // namespace #define LIB_NAME "libcrazy_linker_tests_libfoo.so" @@ -115,24 +112,29 @@ // DEBUG crazy_context_set_load_address(context, 0x20000000); - // Set a callback poster. - CallbackData callback_data; - crazy_context_set_callback_poster(context, &PostCallback, &callback_data); - - crazy_callback_poster_t poster; - void* poster_opaque; - - // Check that the API returns the values we set. - crazy_context_get_callback_poster(context, &poster, &poster_opaque); - if (poster != &PostCallback || poster_opaque != &callback_data) { - Panic("Get callback poster error\n"); + // Set a callback poster, then verify it was set properly. + SharedState shared_state; + crazy_context_set_callback_poster(context, &PostCallback, &shared_state); + { + crazy_callback_poster_t poster; + void* poster_opaque; + crazy_context_get_callback_poster(context, &poster, &poster_opaque); + if (poster != &PostCallback || poster_opaque != &shared_state) { + Panic("Get callback poster error\n"); + } } - // Load library + // Load library, this will end up calling PostCallback() to register + // a delayed linker operation to modify the global list of libraries. if (!crazy_library_open(&library, LIB_NAME, context)) { Panic("Could not open library: %s\n", crazy_context_get_error(context)); } - CheckAndRunCallback(&callback_data); + + // Run the posted callback in the main thread. This should always work. + if (!shared_state.HasCallback()) { + Panic("Delayed callback was not received in main thread!\n"); + } + shared_state.RunCallback(); // Find the "Foo" symbol. FunctionPtr foo_func; @@ -144,15 +146,21 @@ // Call it. (*foo_func)(); - // Close the library. Because the close operation will wait for the - // callback before returning, we have to run it in a separate thread, and - // wait for it to call PostCallback() before continuing. - pthread_t thread = - AsyncCrazyLibraryCloseWithContext(library, context, &callback_data); - CheckAndRunCallback(&callback_data); - - if (pthread_join(thread, NULL) != 0) { - Panic("Failed to join thread for close\n"); + // Closing the library will also call PostCallback() to register another + // callback, but the linker will then wait for its explicit completion + // before returning (this ensures any trace of the library was removed + // from the global list properly). To check this here, create a background + // thread to close the library, which will block until the callback is run + // below in the main thread. + { + CloserThread thread(library, context); + printf("background closing-thread created\n"); + shared_state.WaitForCallback(); + printf("callback received from background thread\n"); + shared_state.RunCallback(); + printf("callback ran in the main thread\n"); + thread.Join(); + printf("background thread completed, library is closed\n"); } crazy_context_destroy(context);
diff --git a/third_party/blink/public/web/web_document_loader.h b/third_party/blink/public/web/web_document_loader.h index 9db3041..60cf2b9 100644 --- a/third_party/blink/public/web/web_document_loader.h +++ b/third_party/blink/public/web/web_document_loader.h
@@ -60,6 +60,8 @@ virtual ~ExtraData() = default; }; + static bool WillLoadUrlAsEmpty(const WebURL&); + // Returns the original request that resulted in this datasource. virtual const WebURLRequest& OriginalRequest() const = 0;
diff --git a/third_party/blink/public/web/web_navigation_control.h b/third_party/blink/public/web/web_navigation_control.h index d68d2b1..5492cba 100644 --- a/third_party/blink/public/web/web_navigation_control.h +++ b/third_party/blink/public/web/web_navigation_control.h
@@ -76,6 +76,7 @@ // in this frame. Used to propagate state when this frame has navigated // cross process. virtual void SetCommittedFirstRealLoad() = 0; + virtual bool HasCommittedFirstRealLoad() = 0; // Informs the frame that the navigation it asked the client to do was // dropped.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index 45f8809..a5b05239 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -364,9 +364,19 @@ v8::MicrotasksScope microtasks_scope(isolate, v8::MicrotasksScope::kRunMicrotasks); probe::CallFunction probe(context, function, depth); + + if (!depth) { + TRACE_EVENT_BEGIN1("devtools.timeline", "FunctionCall", "data", + inspector_function_call_event::Data(context, function)); + } + v8::MaybeLocal<v8::Value> result = constructor->CallAsConstructor(isolate->GetCurrentContext(), argc, argv); CHECK(!isolate->IsDead()); + + if (!depth) + TRACE_EVENT_END0("devtools.timeline", "FunctionCall"); + return result; } @@ -402,11 +412,19 @@ v8::Isolate::SafeForTerminationScope safe_for_termination(isolate); v8::MicrotasksScope microtasks_scope(isolate, v8::MicrotasksScope::kRunMicrotasks); + if (!depth) { + TRACE_EVENT_BEGIN1("devtools.timeline", "FunctionCall", "data", + inspector_function_call_event::Data(context, function)); + } + probe::CallFunction probe(context, function, depth); v8::MaybeLocal<v8::Value> result = function->Call(isolate->GetCurrentContext(), receiver, argc, args); CHECK(!isolate->IsDead()); + if (!depth) + TRACE_EVENT_END0("devtools.timeline", "FunctionCall"); + return result; }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index dd22788d..625286f6 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2454,7 +2454,8 @@ // layout tree siblings. WhitespaceAttacher local_attacher; WhitespaceAttacher* child_attacher; - if (GetLayoutObject() || !HasDisplayContentsStyle()) { + if (GetLayoutObject() || + (!HasDisplayContentsStyle() && CanParticipateInFlatTree())) { whitespace_attacher.DidVisitElement(this); if (GetDocument().GetStyleEngine().NeedsWhitespaceReattachment(this)) local_attacher.SetReattachAllWhitespaceNodes();
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue.cc b/third_party/blink/renderer/core/dom/scripted_task_queue.cc index be1b3222..6728f1ed 100644 --- a/third_party/blink/renderer/core/dom/scripted_task_queue.cc +++ b/third_party/blink/renderer/core/dom/scripted_task_queue.cc
@@ -11,44 +11,22 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/v8_task_queue_post_callback.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" +#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" #include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { -namespace { - -class TaskQueuePostCallbackWrapper { - public: - static std::unique_ptr<TaskQueuePostCallbackWrapper> Create( - int id, - ScriptedTaskQueue* task_queue) { - return std::unique_ptr<TaskQueuePostCallbackWrapper>( - new TaskQueuePostCallbackWrapper(id, task_queue)); - } - - void TaskFired() { - if (task_queue_) - task_queue_->CallbackFired(id_); - } - - private: - TaskQueuePostCallbackWrapper(int id, ScriptedTaskQueue* task_queue) - : id_(id), task_queue_(task_queue) {} - - int id_; - WeakPersistent<ScriptedTaskQueue> task_queue_; -}; - -} // namespace - class ScriptedTaskQueue::WrappedCallback - : public GarbageCollected<WrappedCallback> { + : public GarbageCollectedFinalized<WrappedCallback> { WTF_MAKE_NONCOPYABLE(WrappedCallback); public: WrappedCallback(V8TaskQueuePostCallback* callback, - ScriptPromiseResolver* resolver) - : callback_(callback), resolver_(resolver) {} + ScriptPromiseResolver* resolver, + TaskHandle task_handle) + : callback_(callback), + resolver_(resolver), + task_handle_(std::move(task_handle)) {} void Trace(Visitor* visitor) { visitor->Trace(callback_); @@ -65,19 +43,19 @@ private: TraceWrapperMember<V8TaskQueuePostCallback> callback_; Member<ScriptPromiseResolver> resolver_; + TaskHandle task_handle_; }; ScriptedTaskQueue::ScriptedTaskQueue(ExecutionContext* context, TaskType task_type) - : PausableObject(context) { + : ContextLifecycleObserver(context) { task_runner_ = GetExecutionContext()->GetTaskRunner(task_type); - PauseIfNeeded(); } void ScriptedTaskQueue::Trace(blink::Visitor* visitor) { visitor->Trace(pending_tasks_); ScriptWrappable::Trace(visitor); - PausableObject::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); } ScriptPromise ScriptedTaskQueue::postTask(ScriptState* script_state, @@ -97,23 +75,17 @@ WTF::Bind(&ScriptedTaskQueue::AbortTask, WrapPersistent(this), id)); } - pending_tasks_.Set(id, - MakeGarbageCollected<WrappedCallback>(callback, resolver)); + TaskHandle task_handle = PostCancellableTask( + *task_runner_, FROM_HERE, + WTF::Bind(&ScriptedTaskQueue::CallbackFired, WrapPersistent(this), id)); - auto callback_wrapper = TaskQueuePostCallbackWrapper::Create(id, this); - task_runner_->PostTask(FROM_HERE, - WTF::Bind(&TaskQueuePostCallbackWrapper::TaskFired, - std::move(callback_wrapper))); + pending_tasks_.Set(id, MakeGarbageCollected<WrappedCallback>( + callback, resolver, std::move(task_handle))); return resolver->Promise(); } void ScriptedTaskQueue::CallbackFired(CallbackId id) { - if (paused_) { - paused_tasks_.push_back(id); - return; - } - auto task_iter = pending_tasks_.find(id); if (task_iter == pending_tasks_.end()) return; @@ -135,24 +107,6 @@ void ScriptedTaskQueue::ContextDestroyed(ExecutionContext*) { pending_tasks_.clear(); - paused_tasks_.clear(); -} - -void ScriptedTaskQueue::Pause() { - paused_ = true; -} - -void ScriptedTaskQueue::Unpause() { - paused_ = false; - - for (auto& task_id : paused_tasks_) { - auto callback_wrapper = TaskQueuePostCallbackWrapper::Create(task_id, this); - task_runner_->PostTask(FROM_HERE, - WTF::Bind(&TaskQueuePostCallbackWrapper::TaskFired, - std::move(callback_wrapper))); - } - - paused_tasks_.clear(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue.h b/third_party/blink/renderer/core/dom/scripted_task_queue.h index a8e0154..0aa1107 100644 --- a/third_party/blink/renderer/core/dom/scripted_task_queue.h +++ b/third_party/blink/renderer/core/dom/scripted_task_queue.h
@@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_TASK_QUEUE_H_ #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" -#include "third_party/blink/renderer/core/dom/pausable_object.h" +#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -18,7 +18,7 @@ // This class corresponds to the ScriptedTaskQueue interface. class CORE_EXPORT ScriptedTaskQueue final : public ScriptWrappable, - public PausableObject { + public ContextLifecycleObserver { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(ScriptedTaskQueue); @@ -41,18 +41,14 @@ void Trace(blink::Visitor*) override; private: - // PausableObject interface. + // ContextLifecycleObserver interface. void ContextDestroyed(ExecutionContext*) override; - void Pause() override; - void Unpause() override; void AbortTask(CallbackId id); class WrappedCallback; HeapHashMap<CallbackId, TraceWrapperMember<WrappedCallback>> pending_tasks_; - Vector<CallbackId> paused_tasks_; CallbackId next_callback_id_ = 1; - bool paused_ = false; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; };
diff --git a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc index f2ffd4c..b4fcf64 100644 --- a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc +++ b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
@@ -48,6 +48,11 @@ namespace blink { +// static +bool WebDocumentLoader::WillLoadUrlAsEmpty(const WebURL& url) { + return DocumentLoader::WillLoadUrlAsEmpty(url); +} + const WebURLRequest& WebDocumentLoaderImpl::OriginalRequest() const { return original_request_wrapper_; }
diff --git a/third_party/blink/renderer/core/frame/event_handler_registry.cc b/third_party/blink/renderer/core/frame/event_handler_registry.cc index e9035652..2b3fbeb 100644 --- a/third_party/blink/renderer/core/frame/event_handler_registry.cc +++ b/third_party/blink/renderer/core/frame/event_handler_registry.cc
@@ -143,7 +143,7 @@ if (op != kRemoveAll) { if (handlers_changed) - NotifyHasHandlersChanged(target, handler_class, new_num_handlers > 0); + NotifyHandlersChanged(target, handler_class, new_num_handlers > 0); if (target_set_changed) { NotifyDidAddOrRemoveEventHandlerTarget(GetLocalFrameForTarget(target), @@ -232,7 +232,7 @@ EventHandlerClass handler_class = static_cast<EventHandlerClass>(i); if (handlers_changed[i]) { bool has_handlers = targets_[handler_class].Contains(&target); - NotifyHasHandlersChanged(&target, handler_class, has_handlers); + NotifyHandlersChanged(&target, handler_class, has_handlers); } if (target_set_changed[i]) { NotifyDidAddOrRemoveEventHandlerTarget(GetLocalFrameForTarget(&target), @@ -241,7 +241,7 @@ } } -void EventHandlerRegistry::NotifyHasHandlersChanged( +void EventHandlerRegistry::NotifyHandlersChanged( EventTarget* target, EventHandlerClass handler_class, bool has_active_handlers) {
diff --git a/third_party/blink/renderer/core/frame/event_handler_registry.h b/third_party/blink/renderer/core/frame/event_handler_registry.h index 92df7a3..1ea48478 100644 --- a/third_party/blink/renderer/core/frame/event_handler_registry.h +++ b/third_party/blink/renderer/core/frame/event_handler_registry.h
@@ -100,12 +100,12 @@ EventTarget*); // Called on the EventHandlerRegistry of the root Document to notify - // clients when we have added the first handler or removed the last one for - // a given event class. |hasActiveHandlers| can be used to distinguish - // between the two cases. - void NotifyHasHandlersChanged(EventTarget*, - EventHandlerClass, - bool has_active_handlers); + // clients when we have added or remove a handler for a given event class. + // |hasActiveHandlers| can be used to distinguish between having and not + // having an active handler. + void NotifyHandlersChanged(EventTarget*, + EventHandlerClass, + bool has_active_handlers); // Called to notify clients whenever a single event handler target is // registered or unregistered. If several handlers are registered for the
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 7d3a2e1..8f71d93 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2160,6 +2160,11 @@ GetFrame()->SetShouldSendResourceTimingInfoToParent(false); } +bool WebLocalFrameImpl::HasCommittedFirstRealLoad() { + DCHECK(GetFrame()); + return GetFrame()->Loader().StateMachine()->CommittedFirstRealDocumentLoad(); +} + void WebLocalFrameImpl::NotifyUserActivation() { LocalFrame::NotifyUserActivation(GetFrame(), UserGestureToken::kNewGesture); }
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 30cd380..c0012590a 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -314,6 +314,7 @@ const WebURLError&) const override; void RenderFallbackContent() const override; void SetCommittedFirstRealLoad() override; + bool HasCommittedFirstRealLoad() override; void ClientDroppedNavigation() override; void MarkAsLoading() override; bool CreatePlaceholderDocumentLoader(
diff --git a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc index 8b8013d..8dae62c8 100644 --- a/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc
@@ -389,8 +389,12 @@ void InspectorEmulationAgent::VirtualTimeBudgetExpired() { TRACE_EVENT_ASYNC_END0("renderer.scheduler", "VirtualTimeBudget", this); - DCHECK(web_local_frame_); - web_local_frame_->View()->Scheduler()->SetVirtualTimePolicy( + WebView* view = web_local_frame_->View(); + if (!view) { + DCHECK_EQ(false, virtual_time_setup_); + return; + } + view->Scheduler()->SetVirtualTimePolicy( PageScheduler::VirtualTimePolicy::kPause); virtual_time_policy_.Set(protocol::Emulation::VirtualTimePolicyEnum::Pause); GetFrontend()->virtualTimeBudgetExpired();
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc index a2a44cb..9461cb1 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -192,17 +192,11 @@ } void InspectorTraceEvents::Will(const probe::CallFunction& probe) { - if (probe.depth) - return; - TRACE_EVENT_BEGIN1( - "devtools.timeline", "FunctionCall", "data", - inspector_function_call_event::Data(probe.context, probe.function)); } void InspectorTraceEvents::Did(const probe::CallFunction& probe) { if (probe.depth) return; - TRACE_EVENT_END0("devtools.timeline", "FunctionCall"); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", inspector_update_counters_event::Data());
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc index b041d4c..4ac4e23 100644 --- a/third_party/blink/renderer/core/layout/layout_block.cc +++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -1807,6 +1807,9 @@ LayoutUnit LayoutBlock::FirstLineBoxBaseline() const { DCHECK(!ChildrenInline()); + if (ShouldApplyLayoutContainment()) + return LayoutUnit(-1); + if (IsWritingModeRoot() && !IsRubyRun()) return LayoutUnit(-1);
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index fa403be..3fee9b9 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -725,6 +725,8 @@ return rect; GetDocument().GetFrame()->GetSmoothScrollSequencer().AbortAnimations(); + GetDocument().GetFrame()->GetSmoothScrollSequencer().SetScrollType( + params.GetScrollType()); WebScrollIntoViewParams new_params(params); new_params.is_for_scroll_sequence |= params.GetScrollType() == kProgrammaticScroll;
diff --git a/third_party/blink/renderer/core/layout/layout_table.cc b/third_party/blink/renderer/core/layout/layout_table.cc index 050eb82b..8c02463 100644 --- a/third_party/blink/renderer/core/layout/layout_table.cc +++ b/third_party/blink/renderer/core/layout/layout_table.cc
@@ -1523,7 +1523,7 @@ // 'inline-table'). This is also needed to properly determine the baseline of // a cell if it has a table child. - if (IsWritingModeRoot()) + if (IsWritingModeRoot() || ShouldApplyLayoutContainment()) return LayoutUnit(-1); RecalcSectionsIfNeeded();
diff --git a/third_party/blink/renderer/core/layout/layout_text_control.cc b/third_party/blink/renderer/core/layout/layout_text_control.cc index e307419..63a7da56 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control.cc +++ b/third_party/blink/renderer/core/layout/layout_text_control.cc
@@ -319,6 +319,9 @@ } LayoutUnit LayoutTextControl::FirstLineBoxBaseline() const { + if (ShouldApplyLayoutContainment()) + return LayoutUnit(-1); + LayoutUnit result = LayoutBlock::FirstLineBoxBaseline(); if (result != -1) return result;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc index 03f03ee..e6b3122 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -738,6 +738,20 @@ } template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendFloating( + LayoutObject* layout_object) { + AppendOpaque(NGInlineItem::kFloating, kObjectReplacementCharacter, nullptr, + layout_object); +} + +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>:: + AppendOutOfFlowPositioned(LayoutObject* layout_object) { + AppendOpaque(NGInlineItem::kOutOfFlowPositioned, kObjectReplacementCharacter, + nullptr, layout_object); +} + +template <typename OffsetMappingBuilder> void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendOpaque( NGInlineItem::NGInlineItemType type, UChar character,
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h index 1a09cfd..e887084 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
@@ -79,6 +79,12 @@ void AppendAtomicInline(const ComputedStyle* = nullptr, LayoutObject* = nullptr); + // Append floats and positioned objects in the same way as atomic inlines. + // Because these objects need positions, they will be handled in + // NGInlineLayoutAlgorithm. + void AppendFloating(LayoutObject* layout_object); + void AppendOutOfFlowPositioned(LayoutObject* layout_object); + // Append a character. // The character is opaque to space collapsing; i.e., spaces before this // character and after this character can collapse as if this character does @@ -110,6 +116,8 @@ void SetIsSymbolMarker(bool b); + bool ShouldAbort() const { return false; } + private: static bool NeedsBoxInfo();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc index 2c1633d..e2383c0 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -81,6 +81,112 @@ ToLayoutText(object)->ClearInlineItems(); } +// This class marks appropriate line box fragments as dirty. +// +// |CollectInlinesInternal| calls this class when traversing the LayoutObject +// tree in pre-order DFS +class NGLineBoxMarker { + STACK_ALLOCATED(); + + public: + NGLineBoxMarker(NGPaintFragment* block_fragment) + : block_fragment_(block_fragment) { + DCHECK(block_fragment_); + } + + bool HandleText(LayoutText* layout_text) { + if (layout_text->SelfNeedsLayout()) + return Mark(); + return UpdateLastFragment(layout_text->FirstInlineFragment()); + } + + bool HandleInlineBox(LayoutInline* layout_inline) { + if (layout_inline->SelfNeedsLayout()) + return Mark(); + + // Do not keep fragments of LayoutInline unless it's a leaf, because + // the last fragment of LayoutInline is not the previous fragment of its + // descendants. + if (layout_inline->FirstChild()) + return false; + return UpdateLastFragment(layout_inline->FirstInlineFragment()); + } + + bool HandleAtomicInline(LayoutBox* layout_box) { + if (layout_box->NeedsLayout()) + return Mark(); + return UpdateLastFragment(layout_box->FirstInlineFragment()); + } + + private: + bool Mark() { + if (last_fragment_) { + // Changes in this LayoutObject may affect the line that contains its + // previous object. Mark the line box that contains the last fragment + // of the previous object. + last_fragment_->LastForSameLayoutObject()->MarkContainingLineBoxDirty(); + } else { + // If there were no fragments so far in this pre-order traversal, mark + // the first line box dirty. + DCHECK(block_fragment_); + if (NGPaintFragment* first_line = block_fragment_->FirstLineBox()) + first_line->MarkLineBoxDirty(); + } + return true; + } + + bool UpdateLastFragment(NGPaintFragment* fragment) { + if (fragment) + last_fragment_ = fragment; + return false; + } + + NGPaintFragment* block_fragment_; + NGPaintFragment* last_fragment_ = nullptr; +}; + +// This class has the same interface as NGInlineItemsBuilder but does nothing +// except tracking if floating or out-of-flow objects are added. +// +// |MarkLineBoxesDirty| uses this class to traverse tree without buildling +// |NGInlineItem|. +class ItemsBuilderForMarkLineBoxesDirty { + public: + void Append(const String&, const ComputedStyle*, LayoutText*) {} + bool Append(const String&, LayoutText*) { return false; } + void AppendOpaque(NGInlineItem::NGInlineItemType, + const ComputedStyle*, + LayoutObject*) {} + void AppendBreakOpportunity(const ComputedStyle*, LayoutObject*) {} + void AppendAtomicInline(const ComputedStyle*, LayoutObject*) {} + void AppendFloating(LayoutObject*) { + has_floating_or_out_of_flow_positioned_ = true; + } + void AppendOutOfFlowPositioned(LayoutObject*) { + has_floating_or_out_of_flow_positioned_ = true; + } + void SetIsSymbolMarker(bool) {} + void EnterBlock(const ComputedStyle*) {} + void ExitBlock() {} + void EnterInline(LayoutObject*) {} + void ExitInline(LayoutObject*) {} + + bool ShouldAbort() const { + // Aborting in the middle of the traversal is safe because this function + // ClearNeedsLayout() on text and LayoutInline, but since an inline + // formatting context is laid out as a whole, these flags don't matter. + // For that reason, the traversal should not ClearNeedsLayout() atomic + // inlines, floats, or OOF -- objects that need to be laid out separately + // from the inline formatting context. + // TODO(kojii): This looks a bit tricky, better to come up with clearner + // solution if any. + return has_floating_or_out_of_flow_positioned_; + } + + private: + bool has_floating_or_out_of_flow_positioned_ = false; +}; + // The function is templated to indicate the purpose of collected inlines: // - With EmptyOffsetMappingBuilder: updating layout; // - With NGOffsetMappingBuilder: building offset mapping on clean layout. @@ -91,21 +197,19 @@ // // There are also performance considerations, since template saves the overhead // for condition checking and branching. -template <typename OffsetMappingBuilder> -void CollectInlinesInternal( - LayoutBlockFlow* block, - NGInlineItemsBuilderTemplate<OffsetMappingBuilder>* builder, - String* previous_text, - bool update_layout) { +template <typename ItemsBuilder> +void CollectInlinesInternal(LayoutBlockFlow* block, + ItemsBuilder* builder, + String* previous_text, + NGLineBoxMarker* marker, + bool update_layout) { builder->EnterBlock(block->Style()); LayoutObject* node = GetLayoutObjectForFirstChildNode(block); const LayoutObject* symbol = LayoutNGListItem::FindSymbolMarkerLayoutText(block); while (node) { - if (node->IsText()) { - LayoutText* layout_text = ToLayoutText(node); - + if (LayoutText* layout_text = ToLayoutTextOrNull(node)) { // If the LayoutText element hasn't changed, reuse the existing items. // if the last ended with space and this starts with space, do not allow @@ -125,19 +229,21 @@ if (symbol == layout_text) builder->SetIsSymbolMarker(true); + if (marker && marker->HandleText(layout_text)) + marker = nullptr; + if (update_layout) ClearNeedsLayout(layout_text); } else if (node->IsFloating()) { - // Add floats and positioned objects in the same way as atomic inlines. - // Because these objects need positions, they will be handled in - // NGInlineLayoutAlgorithm. - builder->AppendOpaque(NGInlineItem::kFloating, - kObjectReplacementCharacter, nullptr, node); + builder->AppendFloating(node); + if (builder->ShouldAbort()) + return; } else if (node->IsOutOfFlowPositioned()) { - builder->AppendOpaque(NGInlineItem::kOutOfFlowPositioned, - kObjectReplacementCharacter, nullptr, node); + builder->AppendOutOfFlowPositioned(node); + if (builder->ShouldAbort()) + return; } else if (node->IsAtomicInlineLevel()) { if (node->IsLayoutNGListMarker() || node->IsListMarker()) { @@ -151,6 +257,9 @@ // algorithm. builder->AppendAtomicInline(node->Style(), node); + if (marker && marker->HandleAtomicInline(ToLayoutBox(node))) + marker = nullptr; + if (update_layout) ClearInlineFragment(node); } @@ -166,6 +275,9 @@ builder->EnterInline(layout_inline); + if (marker && marker->HandleInlineBox(layout_inline)) + marker = nullptr; + // Traverse to children if they exist. if (LayoutObject* child = layout_inline->FirstChild()) { node = child; @@ -310,7 +422,8 @@ builder.GetOffsetMappingBuilder().ReserveCapacity( EstimateOffsetMappingItemsCount(*layout_block_flow)); const bool update_layout = false; - CollectInlinesInternal(layout_block_flow, &builder, nullptr, update_layout); + CollectInlinesInternal(layout_block_flow, &builder, nullptr, nullptr, + update_layout); // We need the text for non-NG object. Otherwise |data| already has the text // from the pre-layout phase, check they match. @@ -364,12 +477,19 @@ LayoutBlockFlow* block = GetLayoutBlockFlow(); block->WillCollectInlines(); + // If we have PaintFragment, mark line boxes dirty from |NeedsLayout| flag. + base::Optional<NGLineBoxMarker> marker; + if (NGPaintFragment* block_fragment = block->PaintFragment()) + marker.emplace(block_fragment); + String* previous_text = previous_data ? &previous_data->text_content : nullptr; data->items.ReserveCapacity(EstimateInlineItemsCount(*block)); NGInlineItemsBuilder builder(&data->items); const bool update_layout = true; - CollectInlinesInternal(block, &builder, previous_text, update_layout); + CollectInlinesInternal(block, &builder, previous_text, + marker.has_value() ? &marker.value() : nullptr, + update_layout); data->text_content = builder.ToString(); // Set |is_bidi_enabled_| for all UTF-16 strings for now, because at this @@ -621,6 +741,10 @@ // If the text is from one item, use the ShapeResult as is. if (end_offset == start_item.EndOffset()) { start_item.shape_result_ = std::move(shape_result); + DCHECK_EQ(start_item.TextShapeResult()->StartIndex(), + start_item.StartOffset()); + DCHECK_EQ(start_item.TextShapeResult()->EndIndex(), + start_item.EndOffset()); index++; continue; } @@ -641,8 +765,21 @@ // item that has its first code unit keeps the glyph. item.shape_result_ = shape_result->SubRange( item.StartOffset(), item.EndOffset(), &opaque_context); + DCHECK(item.TextShapeResult()); + DCHECK_EQ(item.TextShapeResult()->StartIndex(), item.StartOffset()); + DCHECK_EQ(item.TextShapeResult()->EndIndex(), item.EndOffset()); } } + +#if DCHECK_IS_ON() + for (const NGInlineItem& item : *items) { + if (item.Type() == NGInlineItem::kText) { + DCHECK(item.TextShapeResult()); + DCHECK_EQ(item.TextShapeResult()->StartIndex(), item.StartOffset()); + DCHECK_EQ(item.TextShapeResult()->EndIndex(), item.EndOffset()); + } + } +#endif } // Create Vector<NGInlineItem> with :first-line rules applied if needed. @@ -800,86 +937,11 @@ // |DirtyLinesFromChangedChild()|, but insertions and style changes are not // marked yet. bool NGInlineNode::MarkLineBoxesDirty(LayoutBlockFlow* block_flow) { - DCHECK(block_flow); - DCHECK(block_flow->PaintFragment()); - bool has_dirtied_lines = false; - NGPaintFragment* last_fragment = nullptr; - for (LayoutObject* layout_object = block_flow->NextInPreOrder(block_flow); - layout_object;) { - bool should_dirty_lines = false; - NGPaintFragment* fragment = nullptr; - LayoutObject* next = nullptr; - if (LayoutText* layout_text = ToLayoutTextOrNull(layout_object)) { - if (!has_dirtied_lines) { - should_dirty_lines = layout_object->SelfNeedsLayout(); - if (!should_dirty_lines) - fragment = layout_text->FirstInlineFragment(); - } - next = layout_object->NextInPreOrderAfterChildren(block_flow); - layout_object->ClearNeedsLayout(); - } else if (LayoutInline* layout_inline = - ToLayoutInlineOrNull(layout_object)) { - if (!has_dirtied_lines) { - should_dirty_lines = layout_object->SelfNeedsLayout(); - // Do not keep fragments of LayoutInline unless it's a leaf, because - // the last fragment of LayoutInline is not the previous fragment of its - // descendants. - if (!should_dirty_lines && !layout_inline->FirstChild()) - fragment = layout_inline->FirstInlineFragment(); - } - next = layout_object->NextInPreOrder(block_flow); - layout_object->ClearNeedsLayout(); - } else if (UNLIKELY(layout_object->IsFloatingOrOutOfFlowPositioned())) { - // Aborting in the middle of the traversal is safe because this function - // ClearNeedsLayout() on text and LayoutInline, but since an inline - // formatting context is laid out as a whole, these flags don't matter. - // For that reason, this traversal should not ClearNeedsLayout() atomic - // inlines, floats, or OOF -- objects that need to be laid out separately - // from the inline formatting context. - // TODO(kojii): This looks a bit tricky, better to come up with clearner - // solution if any. - return false; - } else if (layout_object->IsAtomicInlineLevel()) { - if (!has_dirtied_lines) { - should_dirty_lines = layout_object->NeedsLayout(); - if (!should_dirty_lines) - fragment = layout_object->FirstInlineFragment(); - } - next = layout_object->NextInPreOrderAfterChildren(block_flow); - } else { - NOTREACHED(); - // With LayoutNGBlockFragmentation, LayoutFlowThread/LayoutMultiColumnSet - // appear in fast/multicol/paged-becomes-multicol-auto-height.html. - // crbug.com/897141 - next = layout_object->NextInPreOrder(block_flow); - } - - if (!has_dirtied_lines) { - if (should_dirty_lines) { - if (last_fragment) { - // Changes in this LayoutObject may affect the line that contains its - // previous object. Mark the line box that contains the last fragment - // of the previous object. - last_fragment->LastForSameLayoutObject() - ->MarkContainingLineBoxDirty(); - } else { - // If there were no fragments so far in this pre-order traversal, mark - // the first line box dirty. - NGPaintFragment* block_fragment = block_flow->PaintFragment(); - DCHECK(block_fragment); - if (NGPaintFragment* first_line = block_fragment->FirstLineBox()) - first_line->MarkLineBoxDirty(); - } - has_dirtied_lines = true; - } else if (fragment) { - last_fragment = fragment; - } - } - - ClearInlineFragment(layout_object); - layout_object = next; - } - return true; + NGLineBoxMarker marker(block_flow->PaintFragment()); + ItemsBuilderForMarkLineBoxesDirty builder; + const bool update_layout = true; + CollectInlinesInternal(block_flow, &builder, nullptr, &marker, update_layout); + return !builder.ShouldAbort(); } static LayoutUnit ComputeContentSize(
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc index a57a961..efb8f488 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
@@ -873,6 +873,30 @@ EXPECT_TRUE(lines[0]->IsDirty()); } +// Test marking line boxes when a span has NeedsLayout. The span has a box +// fragment. +TEST_F(NGInlineNodeTest, MarkLineBoxesDirtyInInlineBlock) { + SetupHtml("container", R"HTML( + <div id=container style="display: inline-block; font-size: 10px"> + 12345678<br> + 12345678<br> + </div> + )HTML"); + + Element* container = GetElementById("container"); + container->appendChild(GetDocument().createTextNode("append")); + + // Inline block with auto-size calls |ComputeMinMaxSize|, which may call + // |CollectInlines|. Emulate it to ensure it does not let tests to fail. + GetDocument().UpdateStyleAndLayoutTree(); + NGInlineNode(layout_block_flow_) + .ComputeMinMaxSize(layout_block_flow_->StyleRef().GetWritingMode(), {}); + + auto lines = MarkLineBoxesDirty(); + EXPECT_FALSE(lines[0]->IsDirty()); + EXPECT_TRUE(lines[1]->IsDirty()); +} + TEST_F(NGInlineNodeTest, RemoveInlineNodeDataIfBlockBecomesEmpty1) { SetupHtml("container", "<div id=container><b id=remove><i>foo</i></b></div>"); ASSERT_TRUE(layout_block_flow_->HasNGInlineNodeData());
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 3544648..a0bbaf0 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -972,12 +972,16 @@ return substitute_data_.FailingURL(); } +bool DocumentLoader::WillLoadUrlAsEmpty(const KURL& url) { + if (url.IsEmpty()) + return true; + return SchemeRegistry::ShouldLoadURLSchemeAsEmptyDocument(url.Protocol()); +} + bool DocumentLoader::MaybeLoadEmpty() { - bool should_load_empty = !substitute_data_.IsValid() && - (request_.Url().IsEmpty() || - SchemeRegistry::ShouldLoadURLSchemeAsEmptyDocument( - request_.Url().Protocol())); - if (!should_load_empty) + if (substitute_data_.IsValid()) + return false; + if (!WillLoadUrlAsEmpty(request_.Url())) return false; if (request_.Url().IsEmpty() &&
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index 470270d..8530825 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -90,6 +90,8 @@ std::unique_ptr<WebNavigationParams> navigation_params); ~DocumentLoader() override; + static bool WillLoadUrlAsEmpty(const KURL&); + LocalFrame* GetFrame() const { return frame_; } ResourceTimingInfo* GetNavigationTimingInfo() const;
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index c2735f9..f3992de 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -106,7 +106,6 @@ #include "third_party/blink/renderer/platform/network/network_utils.h" #include "third_party/blink/renderer/platform/plugins/plugin_script_forbidden_scope.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" -#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -1009,7 +1008,9 @@ RecordLatestRequiredCSP(); if (!CancelProvisionalLoaderForNewNavigation( - false /* cancel_scheduled_navigations */)) { + false /* cancel_scheduled_navigations */, + DocumentLoader::WillLoadUrlAsEmpty( + navigation_params->request.Url()))) { return; } @@ -1104,7 +1105,8 @@ WebNavigationType navigation_type, std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { if (!CancelProvisionalLoaderForNewNavigation( - true /* cancel_scheduled_navigations */)) { + true /* cancel_scheduled_navigations */, + false /* is_starting_blank_navigation */)) { return false; } @@ -1250,7 +1252,17 @@ Client()->TransitionToCommittedForNewPage(); - frame_->GetNavigationScheduler().Cancel(); + // If this is an about:blank navigation committing asynchronously, don't + // cancel scheduled navigations, so that the scheduled navigation still goes + // through. This handles the case where a navigation is scheduled between the + // about:blank navigation starting and finishing, where previously it would + // have happened after about:blank completed. + // TODO(japhet): This is an atrocious hack. Get rid of NavigationScheduler + // so it isn't needed. + if (!state_machine_.CommittedFirstRealDocumentLoad() || + !DocumentLoader::WillLoadUrlAsEmpty(document_loader_->Url())) { + frame_->GetNavigationScheduler().Cancel(); + } } bool FrameLoader::IsLoadingMainFrame() const { @@ -1530,7 +1542,8 @@ } bool FrameLoader::CancelProvisionalLoaderForNewNavigation( - bool cancel_scheduled_navigations) { + bool cancel_scheduled_navigations, + bool is_starting_blank_navigation) { bool had_placeholder_client_document_loader = provisional_document_loader_ && !provisional_document_loader_->DidStart(); @@ -1558,9 +1571,22 @@ progress_tracker_->ProgressStarted(); + // If this is an about:blank navigation committing asynchronously, don't + // cancel scheduled navigations, so that the scheduled navigation still goes + // through. This handles the case where a navigation is scheduled between the + // about:blank navigation starting and finishing, where previously it would + // have happened after about:blank completed. + // TODO(japhet): This is an atrocious hack. Get rid of NavigationScheduler + // so it isn't needed. + bool skip_cancel_for_about_blank = + state_machine_.CommittedFirstRealDocumentLoad() && + is_starting_blank_navigation; // We need to ensure that script initiated navigations are honored. - if (!had_placeholder_client_document_loader || cancel_scheduled_navigations) + if (!skip_cancel_for_about_blank && + (!had_placeholder_client_document_loader || + cancel_scheduled_navigations)) { frame_->GetNavigationScheduler().Cancel(); + } return true; }
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h index a96197ee..e284aba 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.h +++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -254,7 +254,8 @@ // Returns whether we should continue with new navigation. bool CancelProvisionalLoaderForNewNavigation( - bool cancel_scheduled_navigations); + bool cancel_scheduled_navigations, + bool is_starting_blank_navigation); void ClearInitialScrollState();
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc index ce4e12b..b883180 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -967,9 +967,6 @@ WebFrameWidgetBase* widget = WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget(); - // While a frame is shutting down, we may get called after the layerTreeView - // is gone: in this case we always expect |hasEventHandlers| to be false. - DCHECK(!widget || widget->GetLayerTreeView() || !has_event_handlers); if (widget && widget->GetLayerTreeView()) widget->GetLayerTreeView()->SetHaveScrollEventHandlers(has_event_handlers); }
diff --git a/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc b/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc index 078b0ee..c154be9 100644 --- a/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
@@ -4,6 +4,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h" +#include "third_party/blink/public/platform/web_scroll_into_view_params.h" #include "third_party/blink/public/web/web_script_source.h" #include "third_party/blink/renderer/bindings/core/v8/scroll_into_view_options_or_boolean.h" #include "third_party/blink/renderer/core/dom/element.h" @@ -13,6 +14,7 @@ #include "third_party/blink/renderer/core/frame/scroll_to_options.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/html/html_element.h" +#include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/testing/sim/sim_compositor.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" @@ -585,6 +587,40 @@ Compositor().BeginFrame(1); } +TEST_F(ScrollIntoViewTest, SmoothUserScrollNotAbortedByProgrammaticScrolls) { + v8::HandleScope HandleScope(v8::Isolate::GetCurrent()); + WebView().MainFrameWidget()->Resize(WebSize(800, 600)); + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete( + "<div id='space' style='height: 1000px'></div>" + "<div id='content' style='height: 1000px'></div>"); + + Compositor().BeginFrame(); + ASSERT_EQ(Window().scrollY(), 0); + + // A smooth UserScroll. + Element* content = GetDocument().getElementById("content"); + content->GetLayoutObject()->ScrollRectToVisible( + content->BoundingBoxForScrollIntoView(), + {ScrollAlignment::kAlignToEdgeIfNeeded, ScrollAlignment::kAlignTopAlways, + kUserScroll, false, kScrollBehaviorSmooth, true}); + + // Animating the container + Compositor().BeginFrame(); // update run_state_. + Compositor().BeginFrame(); // Set start_time = now. + Compositor().BeginFrame(0.2); + ASSERT_EQ(Window().scrollY(), 299); + + // ProgrammaticScroll that could interrupt the current smooth scroll. + Window().scrollTo(0, 0); + + // Finish scrolling the container + Compositor().BeginFrame(1); + // The programmatic scroll of Window shouldn't abort the user scroll. + ASSERT_EQ(Window().scrollY(), content->OffsetTop()); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.cc b/third_party/blink/renderer/core/scroll/scrollable_area.cc index f94fd51..c438d28 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.cc +++ b/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -187,10 +187,9 @@ void ScrollableArea::SetScrollOffset(const ScrollOffset& offset, ScrollType scroll_type, ScrollBehavior behavior) { - if (scroll_type != kSequencedScroll && scroll_type != kClampingScroll && - scroll_type != kAnchoringScroll) { - if (SmoothScrollSequencer* sequencer = GetSmoothScrollSequencer()) - sequencer->AbortAnimations(); + if (SmoothScrollSequencer* sequencer = GetSmoothScrollSequencer()) { + if (sequencer->FilterNewScrollOrAbortCurrent(scroll_type)) + return; } ScrollOffset clamped_offset = ClampScrollOffset(offset);
diff --git a/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc b/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc index 4f56b7b..6e6cfd6 100644 --- a/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc +++ b/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc
@@ -25,6 +25,7 @@ void SmoothScrollSequencer::RunQueuedAnimations() { if (queue_.IsEmpty()) { current_scrollable_ = nullptr; + scroll_type_ = kProgrammaticScroll; return; } SequencedScroll* sequenced_scroll = queue_.back(); @@ -41,6 +42,25 @@ current_scrollable_ = nullptr; } queue_.clear(); + scroll_type_ = kProgrammaticScroll; +} + +bool SmoothScrollSequencer::FilterNewScrollOrAbortCurrent( + ScrollType incoming_type) { + // Allow the incoming scroll to co-exist if its scroll type is + // kSequencedScroll, kClampingScroll, or kAnchoringScroll + if (incoming_type == kSequencedScroll || incoming_type == kClampingScroll || + incoming_type == kAnchoringScroll) + return false; + + // If the current sequenced scroll is UserScroll, but the incoming scroll is + // not, filter the incoming scroll. See crbug.com/913009 for more details. + if (scroll_type_ == kUserScroll && incoming_type != kUserScroll) + return true; + + // Otherwise, abort the current sequenced scroll. + AbortAnimations(); + return false; } void SmoothScrollSequencer::DidDisposeScrollableArea(
diff --git a/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h b/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h index a5d028e..ed301830 100644 --- a/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h +++ b/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h
@@ -42,7 +42,9 @@ class CORE_EXPORT SmoothScrollSequencer final : public GarbageCollected<SmoothScrollSequencer> { public: - SmoothScrollSequencer() = default; + SmoothScrollSequencer() : scroll_type_(kProgrammaticScroll) {} + void SetScrollType(ScrollType type) { scroll_type_ = type; } + // Add a scroll offset animation to the back of a queue. void QueueAnimation(ScrollableArea*, ScrollOffset, ScrollBehavior); @@ -52,6 +54,10 @@ // Abort the currently running animation and all the animations in the queue. void AbortAnimations(); + // Given the incoming scroll's scroll type, returns whether to filter the + // incoming scroll. It may also abort the current sequenced scroll. + bool FilterNewScrollOrAbortCurrent(ScrollType incoming_type); + void DidDisposeScrollableArea(const ScrollableArea&); void Trace(blink::Visitor*); @@ -59,6 +65,7 @@ private: HeapVector<Member<SequencedScroll>> queue_; Member<ScrollableArea> current_scrollable_; + ScrollType scroll_type_; }; } // namespace blink
diff --git a/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js b/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js index 6f49288..660e796 100644 --- a/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js +++ b/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js
@@ -38,6 +38,10 @@ constructor(dispatcher) { this._reset(); this._progress = new HeapSnapshotWorker.HeapSnapshotProgress(dispatcher); + this._buffer = ''; + this._dataCallback = null; + this._done = false; + this._parseInput(); } dispose() { @@ -46,20 +50,20 @@ _reset() { this._json = ''; - this._state = 'find-snapshot-info'; this._snapshot = {}; } close() { - if (this._json) - this._parseStringsArray(); + this._done = true; + if (this._dataCallback) + this._dataCallback(''); } /** * @return {!HeapSnapshotWorker.JSHeapSnapshot} */ buildSnapshot() { - this._progress.updateStatus('Processing snapshot\u2026'); + this._progress.updateStatus(ls`Processing snapshot\u2026`); const result = new HeapSnapshotWorker.JSHeapSnapshot(this._snapshot, this._progress); this._reset(); return result; @@ -107,7 +111,7 @@ _parseStringsArray() { this._progress.updateStatus('Parsing strings\u2026'); const closingBracketIndex = this._json.lastIndexOf(']'); - if (closingBracketIndex === -1 || this._state !== 'accumulate-strings') + if (closingBracketIndex === -1) throw new Error('Incomplete JSON'); this._json = this._json.slice(0, closingBracketIndex + 1); this._snapshot.strings = JSON.parse(this._json); @@ -117,228 +121,110 @@ * @param {string} chunk */ write(chunk) { - if (this._json !== null) - this._json += chunk; + this._buffer += chunk; + if (!this._dataCallback) + return; + this._dataCallback(this._buffer); + this._dataCallback = null; + this._buffer = ''; + } + + /** + * @return {!Promise<string>} + */ + _fetchChunk() { + return this._done ? Promise.resolve(this._buffer) : new Promise(r => this._dataCallback = r); + } + + /** + * @param {string} token + * @param {number=} startIndex + * @return {!Promise<number>} + */ + async _findToken(token, startIndex) { while (true) { - switch (this._state) { - case 'find-snapshot-info': { - const snapshotToken = '"snapshot"'; - const snapshotTokenIndex = this._json.indexOf(snapshotToken); - if (snapshotTokenIndex === -1) - throw new Error('Snapshot token not found'); - - const json = this._json.slice(snapshotTokenIndex + snapshotToken.length + 1); - this._state = 'parse-snapshot-info'; - this._progress.updateStatus('Loading snapshot info\u2026'); - this._json = null; // tokenizer takes over input. - this._jsonTokenizer = new TextUtils.TextUtils.BalancedJSONTokenizer(this._writeBalancedJSON.bind(this)); - // Fall through with adjusted payload. - chunk = json; - } - case 'parse-snapshot-info': { - this._jsonTokenizer.write(chunk); - if (this._jsonTokenizer) - return; // no remainder to process. - break; - } - case 'find-nodes': { - const nodesToken = '"nodes"'; - const nodesTokenIndex = this._json.indexOf(nodesToken); - if (nodesTokenIndex === -1) - return; - const bracketIndex = this._json.indexOf('[', nodesTokenIndex); - if (bracketIndex === -1) - return; - this._json = this._json.slice(bracketIndex + 1); - const node_fields_count = this._snapshot.snapshot.meta.node_fields.length; - const nodes_length = this._snapshot.snapshot.node_count * node_fields_count; - this._array = new Uint32Array(nodes_length); - this._arrayIndex = 0; - this._state = 'parse-nodes'; - break; - } - case 'parse-nodes': { - const hasMoreData = this._parseUintArray(); - this._progress.updateProgress('Loading nodes\u2026 %d%%', this._arrayIndex, this._array.length); - if (hasMoreData) - return; - this._snapshot.nodes = this._array; - this._state = 'find-edges'; - this._array = null; - break; - } - case 'find-edges': { - const edgesToken = '"edges"'; - const edgesTokenIndex = this._json.indexOf(edgesToken); - if (edgesTokenIndex === -1) - return; - const bracketIndex = this._json.indexOf('[', edgesTokenIndex); - if (bracketIndex === -1) - return; - this._json = this._json.slice(bracketIndex + 1); - const edge_fields_count = this._snapshot.snapshot.meta.edge_fields.length; - const edges_length = this._snapshot.snapshot.edge_count * edge_fields_count; - this._array = new Uint32Array(edges_length); - this._arrayIndex = 0; - this._state = 'parse-edges'; - break; - } - case 'parse-edges': { - const hasMoreData = this._parseUintArray(); - this._progress.updateProgress('Loading edges\u2026 %d%%', this._arrayIndex, this._array.length); - if (hasMoreData) - return; - this._snapshot.edges = this._array; - this._array = null; - // If there is allocation info parse it, otherwise jump straight to strings. - if (this._snapshot.snapshot.trace_function_count) { - this._state = 'find-trace-function-infos'; - this._progress.updateStatus('Loading allocation traces\u2026'); - } else if (this._snapshot.snapshot.meta.sample_fields) { - this._state = 'find-samples'; - this._progress.updateStatus('Loading samples\u2026'); - } else { - this._state = 'find-locations'; - } - break; - } - case 'find-trace-function-infos': { - const tracesToken = '"trace_function_infos"'; - const tracesTokenIndex = this._json.indexOf(tracesToken); - if (tracesTokenIndex === -1) - return; - const bracketIndex = this._json.indexOf('[', tracesTokenIndex); - if (bracketIndex === -1) - return; - this._json = this._json.slice(bracketIndex + 1); - - const trace_function_info_field_count = this._snapshot.snapshot.meta.trace_function_info_fields.length; - const trace_function_info_length = - this._snapshot.snapshot.trace_function_count * trace_function_info_field_count; - this._array = new Uint32Array(trace_function_info_length); - this._arrayIndex = 0; - this._state = 'parse-trace-function-infos'; - break; - } - case 'parse-trace-function-infos': { - if (this._parseUintArray()) - return; - this._snapshot.trace_function_infos = this._array; - this._array = null; - this._state = 'find-trace-tree'; - break; - } - case 'find-trace-tree': { - const tracesToken = '"trace_tree"'; - const tracesTokenIndex = this._json.indexOf(tracesToken); - if (tracesTokenIndex === -1) - return; - const bracketIndex = this._json.indexOf('[', tracesTokenIndex); - if (bracketIndex === -1) - return; - this._json = this._json.slice(bracketIndex); - this._state = 'parse-trace-tree'; - break; - } - case 'parse-trace-tree': { - // If there is samples array parse it, otherwise jump straight to strings. - const nextToken = this._snapshot.snapshot.meta.sample_fields ? '"samples"' : '"strings"'; - const nextTokenIndex = this._json.indexOf(nextToken); - if (nextTokenIndex === -1) - return; - const bracketIndex = this._json.lastIndexOf(']', nextTokenIndex); - this._snapshot.trace_tree = JSON.parse(this._json.substring(0, bracketIndex + 1)); - this._json = this._json.slice(bracketIndex + 1); - if (this._snapshot.snapshot.meta.sample_fields) { - this._state = 'find-samples'; - this._progress.updateStatus('Loading samples\u2026'); - } else { - this._state = 'find-strings'; - this._progress.updateStatus('Loading strings\u2026'); - } - break; - } - case 'find-samples': { - const samplesToken = '"samples"'; - const samplesTokenIndex = this._json.indexOf(samplesToken); - if (samplesTokenIndex === -1) - return; - const bracketIndex = this._json.indexOf('[', samplesTokenIndex); - if (bracketIndex === -1) - return; - this._json = this._json.slice(bracketIndex + 1); - this._array = []; - this._arrayIndex = 0; - this._state = 'parse-samples'; - break; - } - case 'parse-samples': { - if (this._parseUintArray()) - return; - this._snapshot.samples = this._array; - this._array = null; - this._state = 'find-locations'; - this._progress.updateStatus('Loading locations\u2026'); - break; - } - case 'find-locations': { - if (!this._snapshot.snapshot.meta.location_fields) { - // The property `locations` was added retroactively, so older - // snapshots might not contain it. In this case just expect `strings` - // as next property. - this._snapshot.locations = []; - this._array = null; - this._state = 'find-strings'; - break; - } - - const locationsToken = '"locations"'; - const locationsTokenIndex = this._json.indexOf(locationsToken); - if (locationsTokenIndex === -1) - return; - const bracketIndex = this._json.indexOf('[', locationsTokenIndex); - if (bracketIndex === -1) - return; - this._json = this._json.slice(bracketIndex + 1); - this._array = []; - this._arrayIndex = 0; - this._state = 'parse-locations'; - break; - } - case 'parse-locations': { - if (this._parseUintArray()) - return; - this._snapshot.locations = this._array; - this._array = null; - this._state = 'find-strings'; - this._progress.updateStatus('Loading strings\u2026'); - break; - } - case 'find-strings': { - const stringsToken = '"strings"'; - const stringsTokenIndex = this._json.indexOf(stringsToken); - if (stringsTokenIndex === -1) - return; - const bracketIndex = this._json.indexOf('[', stringsTokenIndex); - if (bracketIndex === -1) - return; - this._json = this._json.slice(bracketIndex); - this._state = 'accumulate-strings'; - break; - } - case 'accumulate-strings': - return; - } + const pos = this._json.indexOf(token, startIndex || 0); + if (pos !== -1) + return pos; + startIndex = this._json.length - token.length + 1; + this._json += await this._fetchChunk(); } } /** - * @param {string} data + * @param {string} name + * @param {string} title + * @param {number=} length + * @return {!Promise<!Uint32Array|!Array<number>>} */ - _writeBalancedJSON(data) { - this._json = this._jsonTokenizer.remainder(); // tokenizer releases input. - this._jsonTokenizer = null; - this._state = 'find-nodes'; - this._snapshot.snapshot = /** @type {!HeapSnapshotHeader} */ (JSON.parse(data)); + async _parseArray(name, title, length) { + const nameIndex = await this._findToken(name); + const bracketIndex = await this._findToken('[', nameIndex); + this._json = this._json.slice(bracketIndex + 1); + this._array = length ? new Uint32Array(length) : []; + this._arrayIndex = 0; + while (this._parseUintArray()) { + this._progress.updateProgress(title, this._arrayIndex, this._array.length); + this._json += await this._fetchChunk(); + } + const result = this._array; + this._array = null; + return result; + } + + async _parseInput() { + const snapshotToken = '"snapshot"'; + const snapshotTokenIndex = await this._findToken(snapshotToken); + if (snapshotTokenIndex === -1) + throw new Error('Snapshot token not found'); + + this._progress.updateStatus(ls`Loading snapshot info\u2026`); + const json = this._json.slice(snapshotTokenIndex + snapshotToken.length + 1); + this._jsonTokenizer = new TextUtils.TextUtils.BalancedJSONTokenizer(metaJSON => { + this._json = this._jsonTokenizer.remainder(); + this._jsonTokenizer = null; + this._snapshot.snapshot = /** @type {!HeapSnapshotHeader} */ (JSON.parse(metaJSON)); + }); + this._jsonTokenizer.write(json); + while (this._jsonTokenizer) + this._jsonTokenizer.write(await this._fetchChunk()); + + this._snapshot.nodes = await this._parseArray( + '"nodes"', ls`Loading nodes\u2026 %d%%`, + this._snapshot.snapshot.meta.node_fields.length * this._snapshot.snapshot.node_count); + + this._snapshot.edges = await this._parseArray( + '"edges"', ls`Loading edges\u2026 %d%%`, + this._snapshot.snapshot.meta.edge_fields.length * this._snapshot.snapshot.edge_count); + + // If there is allocation info parse it, otherwise jump straight to strings. + if (this._snapshot.snapshot.trace_function_count) { + this._snapshot.trace_function_infos = await this._parseArray( + '"trace_function_infos"', ls`Loading allocation traces\u2026 %d%%`, + this._snapshot.snapshot.meta.trace_function_info_fields.length * + this._snapshot.snapshot.trace_function_count); + + const nextToken = this._snapshot.snapshot.meta.sample_fields ? '"samples"' : '"strings"'; + const nextTokenIndex = await this._findToken(nextToken); + const bracketIndex = this._json.lastIndexOf(']', nextTokenIndex); + this._snapshot.trace_tree = JSON.parse(this._json.substring(0, bracketIndex + 1)); + this._json = this._json.slice(bracketIndex + 1); + } + + if (this._snapshot.snapshot.meta.sample_fields) + this._snapshot.samples = await this._parseArray('"samples"', ls`Loading samples\u2026`); + + if (this._snapshot.snapshot.meta['location_fields']) + this._snapshot.locations = await this._parseArray('"locations"', ls`Loading locations\u2026`); + else + this._snapshot.locations = []; + + this._progress.updateStatus(ls`Loading strings\u2026`); + const stringsTokenIndex = await this._findToken('"strings"'); + const bracketIndex = await this._findToken('[', stringsTokenIndex); + this._json = this._json.slice(bracketIndex); + while (!this._done) + this._json += await this._fetchChunk(); + this._parseStringsArray(); } };
diff --git a/third_party/blink/renderer/modules/encoding/text_decoder.cc b/third_party/blink/renderer/modules/encoding/text_decoder.cc index 12da076d1..50d8e50 100644 --- a/third_party/blink/renderer/modules/encoding/text_decoder.cc +++ b/third_party/blink/renderer/modules/encoding/text_decoder.cc
@@ -60,7 +60,6 @@ bool fatal, bool ignore_bom) : encoding_(encoding), - codec_(NewTextCodec(encoding)), fatal_(fatal), ignore_bom_(ignore_bom), bom_seen_(false) {} @@ -100,8 +99,15 @@ const TextDecodeOptions* options, ExceptionState& exception_state) { DCHECK(options); - WTF::FlushBehavior flush = options->stream() ? WTF::FlushBehavior::kDoNotFlush - : WTF::FlushBehavior::kDataEOF; + if (!do_not_flush_) { + codec_ = NewTextCodec(encoding_); + bom_seen_ = false; + } + + DCHECK(codec_); + do_not_flush_ = options->stream(); + WTF::FlushBehavior flush = do_not_flush_ ? WTF::FlushBehavior::kDoNotFlush + : WTF::FlushBehavior::kDataEOF; bool saw_error = false; String s = codec_->Decode(start, length, flush, fatal_, saw_error); @@ -119,9 +125,6 @@ s.Remove(0); } - if (flush != WTF::FlushBehavior::kDoNotFlush) - bom_seen_ = false; - return s; }
diff --git a/third_party/blink/renderer/modules/encoding/text_decoder.h b/third_party/blink/renderer/modules/encoding/text_decoder.h index cbad582e..f4637fb2 100644 --- a/third_party/blink/renderer/modules/encoding/text_decoder.h +++ b/third_party/blink/renderer/modules/encoding/text_decoder.h
@@ -73,6 +73,7 @@ WTF::TextEncoding encoding_; std::unique_ptr<WTF::TextCodec> codec_; + bool do_not_flush_ = false; bool fatal_; bool ignore_bom_; bool bom_seen_;
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc index 7ba37cb5..a208dac9 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc
@@ -379,7 +379,7 @@ // From https://w3c.github.io/encrypted-media/#createSession: // MediaKeys::createSession(), step 3. // 3.1 Let the sessionId attribute be the empty string. - DCHECK(sessionId().IsEmpty()); + DCHECK(session_id_.IsEmpty()); // 3.2 Let the expiration attribute be NaN. DCHECK(std::isnan(expiration_)); @@ -419,7 +419,7 @@ } String MediaKeySession::sessionId() const { - return session_->SessionId(); + return session_id_; } ScriptPromise MediaKeySession::closed(ScriptState* script_state) { @@ -537,7 +537,8 @@ // new DOMException whose name is the appropriate error name. // (Done by CDM calling result.completeWithError() as appropriate.) // 10.10.2 Set the sessionId attribute to session id. - DCHECK(!sessionId().IsEmpty()); + session_id_ = session_->SessionId(); + DCHECK(!session_id_.IsEmpty()); // 10.10.3 Let this object's callable be true. is_callable_ = true; @@ -655,7 +656,8 @@ // (Done by CDM calling result.completeWithError() as appropriate.) // 8.9.2 Set the sessionId attribute to sanitized session ID. - DCHECK(!sessionId().IsEmpty()); + session_id_ = session_->SessionId(); + DCHECK(!session_id_.IsEmpty()); // 8.9.3 Let this object's callable be true. is_callable_ = true; @@ -911,6 +913,11 @@ } void MediaKeySession::Close() { + // Note that this is the event from the CDM when this session is actually + // closed. The CDM can close a session at any time. Normally it would happen + // as the result of a close() call, but also happens when update() has been + // called with a record of license destruction or if the CDM crashes or + // otherwise becomes unavailable. DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")"; // From http://w3c.github.io/encrypted-media/#session-closed @@ -932,6 +939,22 @@ // 7. Resolve promise. closed_promise_->ResolveWithUndefined(); + + // Stop the CDM from firing any more events for this session. + session_.reset(); + + // Fail any pending events, except if it's a close request. + action_timer_.Stop(); + while (!pending_actions_.IsEmpty()) { + PendingAction* action = pending_actions_.TakeFirst(); + if (action->GetType() == PendingAction::kClose) { + action->Result()->Complete(); + } else { + action->Result()->CompleteWithError( + kWebContentDecryptionModuleExceptionInvalidStateError, 0, + "Session has been closed"); + } + } } void MediaKeySession::ExpirationChanged(double updated_expiry_time_in_ms) {
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h index d4d44c2..5338e6f 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h
@@ -142,6 +142,7 @@ WeakMember<MediaKeys> media_keys_; // Session properties. + String session_id_; WebEncryptedMediaSessionType session_type_; double expiration_; Member<MediaKeyStatusMap> key_statuses_map_;
diff --git a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc index cddcc73d..8767c55 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
@@ -1232,13 +1232,13 @@ composite_result->SnappedStartPositionForOffset(8)); } -TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeAcrossRuns) { +TEST_P(ShapeParameterTest, ShapeResultCopyRangeAcrossRuns) { // Create 3 runs: // [0]: 1 character. // [1]: 5 characters. // [2]: 2 character. String mixed_string(u"\u65E5Hello\u65E5\u65E5"); - TextDirection direction = TextDirection::kLtr; + TextDirection direction = GetParam(); HarfBuzzShaper shaper(mixed_string); scoped_refptr<ShapeResult> result = shaper.Shape(&font, direction); @@ -1251,6 +1251,23 @@ EXPECT_EQ(2u, target->NumCharacters()); } +TEST_P(ShapeParameterTest, ShapeResultCopyRangeContextMultiRuns) { + // Create 2 runs: + // [0]: 5 characters. + // [1]: 4 character. + String mixed_string(u"Hello\u65E5\u65E5\u65E5\u65E5"); + TextDirection direction = GetParam(); + HarfBuzzShaper shaper(mixed_string); + scoped_refptr<ShapeResult> result = shaper.Shape(&font, direction); + + // Copy multiple times using |context| from multiple runs + unsigned context = 0; + scoped_refptr<ShapeResult> sub2to4 = result->SubRange(2, 4, &context); + EXPECT_EQ(2u, sub2to4->NumCharacters()); + scoped_refptr<ShapeResult> sub5to9 = result->SubRange(5, 9, &context); + EXPECT_EQ(4u, sub5to9->NumCharacters()); +} + TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeSegmentGlyphBoundingBox) { String string(u"THello worldL"); TextDirection direction = TextDirection::kLtr;
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc index 11ca15955..fe3c0c1 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
@@ -1331,7 +1331,9 @@ // No need to process runs after the end of the range. if ((!Rtl() && end_offset <= run_end) || (Rtl() && start_offset > run_start)) { - if (start_run_index) + // RTL cannot use |start_run_index| because runs are in the descending + // order. + if (!Rtl() && start_run_index) *start_run_index = run_index; break; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc index 61413dc..6baafa3 100644 --- a/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc +++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
@@ -260,10 +260,8 @@ DCHECK(resource); if (resource->IsLoaded() && resource->DecodedSize()) { // Check to see if the remaining resources are too new to prune. - double elapsed_time = prune_frame_time_stamp_ - - resource_iter.value->last_decoded_access_time_; if (strategy == kAutomaticPrune && - elapsed_time < delay_before_live_decoded_prune_) + prune_frame_time_stamp_ < delay_before_live_decoded_prune_) continue; resource->Prune(); if (size_ <= target_size)
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache.h b/third_party/blink/renderer/platform/loader/fetch/memory_cache.h index c452243a..4db0a270 100644 --- a/third_party/blink/renderer/platform/loader/fetch/memory_cache.h +++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
@@ -53,14 +53,11 @@ return MakeGarbageCollected<MemoryCacheEntry>(resource); } - explicit MemoryCacheEntry(Resource* resource) - : last_decoded_access_time_(0.0), resource_(resource) {} + explicit MemoryCacheEntry(Resource* resource) : resource_(resource) {} void Trace(blink::Visitor*); Resource* GetResource() const { return resource_; } - double last_decoded_access_time_; // Used as a thrash guard - private: void ClearResourceWeak(Visitor*);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index 18b5158..5c2bc18 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -400,6 +400,10 @@ case TaskType::kNetworkingControl: // Loading task queues are handled separately. return base::nullopt; + case TaskType::kExperimentalWebSchedulingUserInteraction: + case TaskType::kExperimentalWebSchedulingBestEffort: + // WebScheduling queues are handled separately. + return base::nullopt; // Throttling following tasks may break existing web pages, so tentatively // these are unthrottled. // TODO(nhiroki): Throttle them again after we're convinced that it's safe @@ -472,8 +476,6 @@ case TaskType::kWorkerThreadTaskQueueDefault: case TaskType::kWorkerThreadTaskQueueV8: case TaskType::kWorkerThreadTaskQueueCompositor: - case TaskType::kExperimentalWebSchedulingUserInteraction: - case TaskType::kExperimentalWebSchedulingBestEffort: case TaskType::kCount: // Not a valid frame-level TaskType. return base::nullopt;
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint index b8357ac..3ef89fb 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -40,10 +40,7 @@ crbug.com/736052 compositing/overflow/composited-scroll-with-fractional-translation.html [ Pass ] crbug.com/857501 compositing/gestures/gesture-tapHighlight-with-filter.html [ Pass ] -Bug(none) virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure ] -Bug(none) virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure ] Bug(none) virtual/scalefactor200withzoom/fast/hidpi/static/mousewheel-scroll-amount.html [ Failure ] -Bug(none) virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure ] Bug(none) accessibility/reach-and-scroll-overflow-div-without-mouse.html [ Timeout ] Bug(none) compositing/animation/hidden-composited.html [ Failure ] @@ -361,9 +358,12 @@ Bug(none) fast/borders/overflow-hidden-border-radius-force-backing-store.html [ Failure ] # Subpixel adjustments due to differences in compositing +# They are benign but we can't rebaseline reftests crbug.com/589265 fast/forms/text/input-appearance-autocomplete-very-long-value.html [ Failure ] crbug.com/589265 animations/svg/animated-filter-svg-element.html [ Failure ] crbug.com/589265 virtual/threaded/animations/svg/animated-filter-svg-element.html [ Failure ] +crbug.com/589265 fast/pagination/repeating-thead-tfoot-paged-x.html [ Failure ] +crbug.com/589265 fast/pagination/repeating-thead-tfoot-paged-y.html [ Failure ] # virtual/threaded variants of sub-directories and tests already skipped or marked as failing above. Bug(none) virtual/threaded/http/tests/devtools/ [ Skip ] @@ -448,8 +448,6 @@ Bug(none) paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html [ Failure ] Bug(none) fast/pagination/multicol.html [ Crash ] -Bug(none) fast/pagination/repeating-thead-tfoot-paged-x.html [ Failure ] -Bug(none) fast/pagination/repeating-thead-tfoot-paged-y.html [ Failure ] Bug(none) paint/clipath/change-mask-clip-path-multicol-crash.html [ Crash ] Bug(none) paint/pagination/composited-paginated-outlined-box.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 217eb6139..31a5154 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -539,6 +539,7 @@ # [css-contain] crbug.com/880802 external/wpt/css/css-contain/contain-layout-017.html [ Failure ] +crbug.com/671132 external/wpt/css/css-contain/contain-layout-baseline-005.html [ Failure ] crbug.com/626703 external/wpt/css/css-contain/contain-layout-breaks-002.html [ Failure ] crbug.com/847274 external/wpt/css/css-contain/contain-paint-005.html [ Failure ] crbug.com/847274 external/wpt/css/css-contain/contain-paint-006.html [ Failure ] @@ -3038,7 +3039,6 @@ crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/fetch/content-type/response.window.html [ Timeout ] crbug.com/626703 [ Mac10.10 ] external/wpt/mimesniff/mime-types/parsing.any.worker.html [ Failure Timeout ] crbug.com/626703 [ Mac10.11 ] external/wpt/mimesniff/mime-types/parsing.any.worker.html [ Failure Timeout ] -crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-layout-suppress-baseline-002.html [ Failure ] crbug.com/626703 [ Mac10.10 ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Failure Timeout ] crbug.com/626703 [ Mac10.13 ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Failure Timeout ] crbug.com/626703 [ Retina ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Failure Timeout ] @@ -5756,3 +5756,6 @@ crbug.com/v8/8381 http/tests/devtools/coverage/coverage-view-filter.js [ Pass Failure ] crbug.com/v8/8381 http/tests/devtools/coverage/coverage-view.js [ Pass Failure ] crbug.com/v8/8381 http/tests/devtools/coverage/multiple-instances-merge.js [ Pass Failure ] + +# TODO (michaelludwig): Todo after Skia roll and rebaseline +crbug.com/915735 compositing/masks/mask-with-added-filters.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index 9c2c7af..edfb097a 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -283119,17 +283119,17 @@ {} ] ], - "workers/importscripts_mime.tentative.any.js": [ + "workers/importscripts_mime.any.js": [ [ - "/workers/importscripts_mime.tentative.any.serviceworker.html", + "/workers/importscripts_mime.any.serviceworker.html", {} ], [ - "/workers/importscripts_mime.tentative.any.sharedworker.html", + "/workers/importscripts_mime.any.sharedworker.html", {} ], [ - "/workers/importscripts_mime.tentative.any.worker.html", + "/workers/importscripts_mime.any.worker.html", {} ] ], @@ -352923,7 +352923,7 @@ "support" ], "css/css-text/overflow-wrap/overflow-wrap-001.html": [ - "2407942f09f8775a9b2f20e334c5c36693116551", + "3c6ee263fb47b79bc51cff530ff39d77f357f6b7", "reftest" ], "css/css-text/overflow-wrap/overflow-wrap-002-ref.html": [ @@ -352931,7 +352931,7 @@ "support" ], "css/css-text/overflow-wrap/overflow-wrap-002.html": [ - "2c6d34d01da680939df27850b64cd0091751a21a", + "e1b5c0610388b1fc8625fdd92a0889c12c406b2c", "reftest" ], "css/css-text/overflow-wrap/overflow-wrap-004-ref.html": [ @@ -352939,7 +352939,7 @@ "support" ], "css/css-text/overflow-wrap/overflow-wrap-004.html": [ - "92ad750207dbd573df83e235be4cee52d92d4add", + "166bfc1f474be5b4aad88211f5a724c55fcca000", "reftest" ], "css/css-text/overflow-wrap/overflow-wrap-break-word-001.html": [ @@ -353019,15 +353019,15 @@ "support" ], "css/css-text/overflow-wrap/word-wrap-001.html": [ - "dd5f0f2bf132de85c7a1045e88aa3ad2b72616c1", + "af326a6cdf2d02aa51e6eccfd11b90fcc4c16456", "reftest" ], "css/css-text/overflow-wrap/word-wrap-002.html": [ - "380fb8ec4fde4decb82e52961ce5ef71a0a6c965", + "24b39d6cacda38975948d42044c5b4552d1504af", "reftest" ], "css/css-text/overflow-wrap/word-wrap-004.html": [ - "ce7a2fe504747e6c6ffc35a019021bdedbec6d21", + "773c4aef6cc14d395e8a7f173e3732ddcb3474e0", "reftest" ], "css/css-text/overflow-wrap/word-wrap-alias.html": [ @@ -410827,7 +410827,7 @@ "support" ], "interfaces/input-events.idl": [ - "bd4024856b5be0483f32f65f33ef9cebe81a4521", + "0086128e562fbdb11e6c07ecd41f99a6e9a84189", "support" ], "interfaces/intersection-observer.idl": [ @@ -451750,7 +451750,7 @@ "f54faf54350990a9593e7af022c9eeb769595b15", "testharness" ], - "workers/importscripts_mime.tentative.any.js": [ + "workers/importscripts_mime.any.js": [ "04c63a3a5f6d9bd3b71d94142f65a1825358b8ed", "testharness" ],
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-layout-baseline-005.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-layout-baseline-005.html new file mode 100644 index 0000000..a447744b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-layout-baseline-005.html
@@ -0,0 +1,64 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Containment Test: Layout containment supress baseline</title> +<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout"> +<link rel="match" href="reference/contain-layout-baseline-005-ref.html"> +<meta name=assert content="This test checks that baseline is suppressed for elements with 'contain: layout', so they are treated as having no baseline (thus its baseline is synthetized)."> +<style> +.wrapper { + height: 110px; +} +.wrapper > * { + contain: layout; + background: cyan; + font-size: 20px; +} +.wrapper > :nth-child(1) { + background: magenta; +} +.inline-block { + display: inline-block; +} +canvas { + width: 100px; + height: 100px; +} +fieldset, details { + display: inline-block; + width: max-content; +} +</style> +<p>Test passes if it has the same output than the reference (all elements are aligned on the bottom edge).</p> +<div class="wrapper"> + <div class="inline-block" style="font-size: 80px;">foo</div> + <div class="inline-block">foo</div> + <div class="inline-block" style="border: solid thick; padding: 2px;">foo</div> + <div style="display: inline-flex;">foo</div> + <div style="display: inline-flex; border: solid thick; padding: 2px;">foo</div> + <div style="display: inline-grid;">foo</div> + <div style="display: inline-grid; border: solid thick; padding: 2px;">foo</div> +</div> +<div class="wrapper"> + <canvas></canvas> + <div class="inline-block">foo</div> + <button>foo</button> + <select><option>foo</option></select> + <select multiple style="height: 40px;"><option>foo</option></select> + <textarea style="height: 40px;"></textarea> +</div> +<div class="wrapper"> + <canvas></canvas> + <input value="foo"></input> + <input type="file"></input> +</div> +<div class="wrapper"> + <canvas></canvas> + <table style="display: inline-table;"><tr><td>foo</td></tr></table> + <canvas></canvas> + <fieldset></fieldset> + <fieldset><legend>foo</legend></fieldset> + <fieldset><legend>foo</legend>foo</fieldset> + <details></details> + <details><summary>foo</summary>foo</details> <details open="true"><summary>foo</summary>foo</details> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/reference/contain-layout-baseline-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-contain/reference/contain-layout-baseline-005-ref.html new file mode 100644 index 0000000..40a34f9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/reference/contain-layout-baseline-005-ref.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Containment Test: Reference file</title> +<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com"> +<style> +.wrapper { + height: 110px; +} +.wrapper > * { + vertical-align: bottom; + background: cyan; + font-size: 20px; +} +.wrapper > :nth-child(1) { + background: magenta; +} +.inline-block { + display: inline-block; +} +canvas { + width: 100px; + height: 100px; +} +fieldset, details { + display: inline-block; + width: max-content; +} +</style> +<p>Test passes if it has the same output than the reference (all elements are aligned on the bottom edge).</p> +<div class="wrapper"> + <div class="inline-block" style="font-size: 80px;">foo</div> + <div class="inline-block">foo</div> + <div class="inline-block" style="border: solid thick; padding: 2px;">foo</div> + <div style="display: inline-flex;">foo</div> + <div style="display: inline-flex; border: solid thick; padding: 2px;">foo</div> + <div style="display: inline-grid;">foo</div> + <div style="display: inline-grid; border: solid thick; padding: 2px;">foo</div> +</div> +<div class="wrapper"> + <canvas></canvas> + <div class="inline-block">foo</div> + <button>foo</button> + <select><option>foo</option></select> + <select multiple style="height: 40px;"><option>foo</option></select> + <textarea style="height: 40px;"></textarea> +</div> +<div class="wrapper"> + <canvas></canvas> + <input value="foo"></input> + <input type="file"></input> +</div> +<div class="wrapper"> + <canvas></canvas> + <table style="display: inline-table;"><tr><td>foo</td></tr></table> + <canvas></canvas> + <fieldset></fieldset> + <fieldset><legend>foo</legend></fieldset> + <fieldset><legend>foo</legend>foo</fieldset> + <details></details> + <details><summary>foo</summary>foo</details> <details open="true"><summary>foo</summary>foo</details> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-001.html index 2407942..3c6ee263 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-001.html
@@ -3,7 +3,7 @@ <title>CSS Text Test: overflow-wrap - break-word (basic)</title> <link rel="author" title="Intel" href="http://www.intel.com"> <link rel="author" title="Shiyou Tan" href="mailto:shiyoux.tan@intel.com"> -<link rel="help" title="6.2. Overflow Wrapping: the 'word-wrap'/'overflow-wrap' property" href="http://www.w3.org/TR/css-text-3/#overflow-wrap"> +<link rel="help" href="http://www.w3.org/TR/css-text-3/#overflow-wrap-property"> <link rel="match" href="overflow-wrap-001-ref.html"> <meta name="flags" content="ahem"> <meta name="assert" content="The 'overflow-wrap' property set 'break-word' breaks the word at an arbitrary point">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-002.html index 2c6d34d01..e1b5c06 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-002.html
@@ -3,7 +3,7 @@ <title>CSS Text Test: overflow-wrap - break-word and white-space - nowrap</title> <link rel="author" title="Intel" href="http://www.intel.com"> <link rel="author" title="Shiyou Tan" href="mailto:shiyoux.tan@intel.com"> -<link rel="help" title="6.2. Overflow Wrapping: the 'word-wrap'/'overflow-wrap' property" href="http://www.w3.org/TR/css-text-3/#overflow-wrap"> +<link rel="help" href="http://www.w3.org/TR/css-text-3/#overflow-wrap-property"> <link rel="help" href="http://www.w3.org/TR/css-text-3/#white-space"> <link rel="match" href="overflow-wrap-002-ref.html"> <meta name="flags" content="ahem">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-004.html index 92ad750..166bfc1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-004.html
@@ -3,7 +3,7 @@ <title>CSS Text Test: overflow-wrap - normal (basic)</title> <link rel="author" title="Intel" href="http://www.intel.com"> <link rel="author" title="Shiyou Tan" href="mailto:shiyoux.tan@intel.com"> -<link rel="help" title="6.2. Overflow Wrapping: the 'word-wrap'/'overflow-wrap' property" href="http://www.w3.org/TR/css-text-3/#overflow-wrap"> +<link rel="help" href="http://www.w3.org/TR/css-text-3/#overflow-wrap-property"> <link rel="match" href="overflow-wrap-004-ref.html"> <meta name="flags" content="ahem"> <meta name="assert" content="The 'overflow-wrap' property set 'normal' overflows container">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-001.html index dd5f0f2b..af326a6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-001.html
@@ -3,7 +3,7 @@ <title>CSS Text Test: word-wrap - break-word (basic)</title> <link rel="author" title="Intel" href="http://www.intel.com"> <link rel="author" title="Shiyou Tan" href="mailto:shiyoux.tan@intel.com"> -<link rel="help" title="6.2. Overflow Wrapping: the 'word-wrap'/'overflow-wrap' property" href="http://www.w3.org/TR/css-text-3/#overflow-wrap"> +<link rel="help" href="http://www.w3.org/TR/css-text-3/#overflow-wrapproperty"> <link rel="match" href="overflow-wrap-001-ref.html"> <meta name="flags" content="ahem"> <meta name="assert" content="The 'word-wrap' property set 'break-word' breaks the word at an arbitrary point">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-002.html index 380fb8ec..24b39d6c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-002.html
@@ -3,7 +3,7 @@ <title>CSS Text Test: word-wrap - break-word and white-space - nowrap</title> <link rel="author" title="Intel" href="http://www.intel.com"> <link rel="author" title="Shiyou Tan" href="mailto:shiyoux.tan@intel.com"> -<link rel="help" title="6.2. Overflow Wrapping: the 'word-wrap'/'overflow-wrap' property" href="http://www.w3.org/TR/css-text-3/#overflow-wrap"> +<link rel="help" href="http://www.w3.org/TR/css-text-3/#overflow-wrap-property"> <link rel="help" href="http://www.w3.org/TR/css-text-3/#white-space"> <link rel="match" href="overflow-wrap-002-ref.html"> <meta name="flags" content="ahem">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-004.html index ce7a2fe..773c4ae 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/word-wrap-004.html
@@ -3,7 +3,7 @@ <title>CSS Text Test: word-wrap - normal (basic)</title> <link rel="author" title="Intel" href="http://www.intel.com"> <link rel="author" title="Shiyou Tan" href="mailto:shiyoux.tan@intel.com"> -<link rel="help" title="6.2. Overflow Wrapping: the 'word-wrap'/'overflow-wrap' property" href="http://www.w3.org/TR/css-text-3/#overflow-wrap"> +<link rel="help" href="http://www.w3.org/TR/css-text-3/#overflow-wrap-property"> <link rel="match" href="overflow-wrap-004-ref.html"> <meta name="flags" content="ahem"> <meta name="assert" content="The 'word-wrap' property set 'normal' overflows container">
diff --git a/third_party/blink/web_tests/external/wpt/encoding/textdecoder-fatal.any.js b/third_party/blink/web_tests/external/wpt/encoding/textdecoder-fatal.any.js index 3cb7573..5884f11 100644 --- a/third_party/blink/web_tests/external/wpt/encoding/textdecoder-fatal.any.js +++ b/third_party/blink/web_tests/external/wpt/encoding/textdecoder-fatal.any.js
@@ -64,3 +64,17 @@ assert_true(new TextDecoder('utf-8', {fatal: true}).fatal, 'The fatal attribute can be set using an option.'); }, 'The fatal attribute of TextDecoder'); + +test(() => { + const bytes = new Uint8Array([226, 153, 165]); + const decoder = new TextDecoder('utf-8', {fatal: true}); + assert_equals(decoder.decode(new DataView(bytes.buffer, 0, 3)), + '♥', + 'decode() should decode full sequence'); + assert_throws(new TypeError, + () => decoder.decode(new DataView(bytes.buffer, 0, 2)), + 'decode() should throw on incomplete sequence'); + assert_equals(decoder.decode(new DataView(bytes.buffer, 0, 3)), + '♥', + 'decode() should not throw on subsequent call'); +}, 'Error seen with fatal does not prevent future decodes');
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/compile-event-handler-settings-objects-expected.txt b/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/compile-event-handler-settings-objects-expected.txt deleted file mode 100644 index 47478d93..0000000 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/scripting/events/compile-event-handler-settings-objects-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -This is a testharness.js-based test. -PASS The Function instance must be created in the Realm of the node document -PASS The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document -FAIL The incumbent settings object while executing the compiled callback via Web IDL's invoke must be that of the node document Cannot read property 'name' of undefined -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini deleted file mode 100644 index a06134a6..0000000 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini +++ /dev/null
@@ -1,4 +0,0 @@ -[elementTiming.html] - [TestDriver actions: element timing] - expected: - if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini index 00916c7a..07c05be 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini
@@ -1,7 +1,3 @@ [eventOrder.html] expected: - if product == "safari": ERROR - - [TestDriver actions: event order] - expected: - if product == "chrome": FAIL + if product == "safari": ERROR \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini index b9fb259..04b97a7 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini
@@ -1,3 +1,3 @@ [multiDevice.html] expected: - if product == "chrome" or product == "safari": ERROR + if product == "safari": ERROR
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/input-events.idl b/third_party/blink/web_tests/external/wpt/interfaces/input-events.idl index bd402485..0086128 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/input-events.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/input-events.idl
@@ -4,13 +4,11 @@ // Source: Input Events Level 1 (https://cdn.staticaly.com/gh/w3c/input-events/v1/index.html) partial interface InputEvent { - readonly attribute DOMString inputType; readonly attribute DataTransfer? dataTransfer; sequence<StaticRange> getTargetRanges(); }; partial dictionary InputEventInit { - DOMString inputType = ""; DataTransfer? dataTransfer = null; sequence<StaticRange> targetRanges = []; };
diff --git a/third_party/blink/web_tests/external/wpt/workers/importscripts_mime.tentative.any.js b/third_party/blink/web_tests/external/wpt/workers/importscripts_mime.any.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/workers/importscripts_mime.tentative.any.js rename to third_party/blink/web_tests/external/wpt/workers/importscripts_mime.any.js
diff --git a/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach-expected.html b/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach-expected.html new file mode 100644 index 0000000..fff968a0 --- /dev/null +++ b/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach-expected.html
@@ -0,0 +1,3 @@ +<!DOCTYPE html> +<p>There should be a space between 'two' and 'words' below.</p> +<div>two words</div>
diff --git a/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach-expected.txt b/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach-expected.txt new file mode 100644 index 0000000..0837904 --- /dev/null +++ b/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach-expected.txt
@@ -0,0 +1 @@ +CONSOLE WARNING: line 5: Element.createShadowRoot is deprecated and will be removed in M73, around March 2019. Please use Element.attachShadow instead. See https://www.chromestatus.com/features/4507242028072960 for more details.
diff --git a/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach.html b/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach.html new file mode 100644 index 0000000..d8aa4afa --- /dev/null +++ b/third_party/blink/web_tests/fast/dom/shadow/content-whitespace-attach.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<p>There should be a space between 'two' and 'words' below.</p> +<div id="host"><span style="display:block">two</span></div> +<script> + const root = host.createShadowRoot(); + root.innerHTML = "<content></content> <!---->words"; + document.body.offsetTop; + document.querySelector("span").style.display = "inline"; +</script>
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/compositing/new-stacking-context-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/compositing/new-stacking-context-expected.png new file mode 100644 index 0000000..32a197c --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/compositing/new-stacking-context-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png new file mode 100644 index 0000000..3113eba --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png new file mode 100644 index 0000000..4644409 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png new file mode 100644 index 0000000..4644409 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot.js b/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot.js index 96d363b..d2e8bb0 100644 --- a/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot.js +++ b/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot.js
@@ -359,7 +359,7 @@ TestRunner.assertEquals('b', names.join(','), 'edges provider names'); }, - function heapSnapshotLoaderTest() { + async function heapSnapshotLoaderTest() { var source = HeapProfilerTestRunner.createHeapSnapshotMockRaw(); var sourceStringified = JSON.stringify(source); var partSize = sourceStringified.length >> 3; @@ -368,6 +368,7 @@ for (var i = 0, l = sourceStringified.length; i < l; i += partSize) loader.write(sourceStringified.slice(i, i + partSize)); loader.close(); + await 0; // Make sure loader parses the input. var result = loader.buildSnapshot(false); result.nodes = new Uint32Array(result.nodes); result.containmentEdges = new Uint32Array(result.containmentEdges);
diff --git a/third_party/blink/web_tests/http/tests/security/synchronous-frame-load-in-javascript-url-inherits-correct-origin.html b/third_party/blink/web_tests/http/tests/security/synchronous-frame-load-in-javascript-url-inherits-correct-origin.html index bdb80cd..ac84a69 100644 --- a/third_party/blink/web_tests/http/tests/security/synchronous-frame-load-in-javascript-url-inherits-correct-origin.html +++ b/third_party/blink/web_tests/http/tests/security/synchronous-frame-load-in-javascript-url-inherits-correct-origin.html
@@ -26,7 +26,7 @@ opener.location = "javascript:alert(location)"; if (window.testRunner) - setTimeout("testRunner.notifyDone()", 0); + testRunner.notifyDone(); } + ")()<\/script>"; } + ")()"; } + ")()");
diff --git a/third_party/blink/web_tests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js b/third_party/blink/web_tests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js index 981c5281..6239b7f 100644 --- a/third_party/blink/web_tests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js +++ b/third_party/blink/web_tests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js
@@ -23,6 +23,7 @@ session.protocol.HeapProfiler.offAddHeapSnapshotChunk(onChunk); testRunner.log('Took heap snapshot'); loader.close(); + await new Promise(r => setTimeout(r)); var snapshot = loader.buildSnapshot(false); testRunner.log('Parsed snapshot'); return snapshot;
diff --git a/third_party/blink/web_tests/inspector-protocol/runtime/runtime-console-log-handle-navigate-expected.txt b/third_party/blink/web_tests/inspector-protocol/runtime/runtime-console-log-handle-navigate-expected.txt index 10bfb57..d7a9663 100644 --- a/third_party/blink/web_tests/inspector-protocol/runtime/runtime-console-log-handle-navigate-expected.txt +++ b/third_party/blink/web_tests/inspector-protocol/runtime/runtime-console-log-handle-navigate-expected.txt
@@ -1,29 +1,32 @@ This tests how navigation is handled from inside debugger code (console.log). Got new context: true { - error : { - code : -32000 - message : Cannot find context with specified id - } id : <number> + result : { + result : { + type : undefined + } + } sessionId : <string> } Got new context: true { - error : { - code : -32000 - message : Cannot find context with specified id - } id : <number> + result : { + result : { + type : undefined + } + } sessionId : <string> } Got new context: true { - error : { - code : -32000 - message : Cannot find context with specified id - } id : <number> + result : { + result : { + type : undefined + } + } sessionId : <string> }
diff --git a/third_party/blink/web_tests/inspector-protocol/runtime/runtime-console-log-handle-navigate.js b/third_party/blink/web_tests/inspector-protocol/runtime/runtime-console-log-handle-navigate.js index b183813..fa90d38 100644 --- a/third_party/blink/web_tests/inspector-protocol/runtime/runtime-console-log-handle-navigate.js +++ b/third_party/blink/web_tests/inspector-protocol/runtime/runtime-console-log-handle-navigate.js
@@ -20,6 +20,7 @@ async function checkExpression(expression) { var contextId; + await dp.Runtime.onceExecutionContextCreated(); dp.Runtime.onceExecutionContextCreated().then(result => contextId = result.params.context.id); await session.evaluateAsync(`appendIframe('${testRunner.url('../resources/console-log-navigate.html')}')`); testRunner.log(`Got new context: ${contextId !== undefined}`);
diff --git a/third_party/libwebp/fuzzing/fuzz_simple_api.cc b/third_party/libwebp/fuzzing/fuzz_simple_api.cc index 1424e4d..82dddf06 100644 --- a/third_party/libwebp/fuzzing/fuzz_simple_api.cc +++ b/third_party/libwebp/fuzzing/fuzz_simple_api.cc
@@ -32,13 +32,15 @@ if (value < 0x16) { buf = WebPDecodeRGBA(data, size, &w, &h); } else if (value < 0x2b) { - buf = WebPDecodeARGB(data, size, &w, &h); - } else if (value < 0x40) { buf = WebPDecodeBGRA(data, size, &w, &h); +#if !defined(WEBP_REDUCE_CSP) + } else if (value < 0x40) { + buf = WebPDecodeARGB(data, size, &w, &h); } else if (value < 0x55) { buf = WebPDecodeRGB(data, size, &w, &h); } else if (value < 0x6a) { buf = WebPDecodeBGR(data, size, &w, &h); +#endif // !defined(WEBP_REDUCE_CSP) } else if (value < 0x7f) { uint8_t *u, *v; int stride, uv_stride; @@ -51,14 +53,16 @@ uint8_t* const ext_buf = (uint8_t*)malloc(buf_size); if (value < 0x94) { WebPDecodeRGBAInto(data, size, ext_buf, buf_size, stride); +#if !defined(WEBP_REDUCE_CSP) } else if (value < 0xa9) { WebPDecodeARGBInto(data, size, ext_buf, buf_size, stride); } else if (value < 0xbe) { - WebPDecodeBGRAInto(data, size, ext_buf, buf_size, stride); + WebPDecodeBGRInto(data, size, ext_buf, buf_size, stride); } else if (value < 0xd3) { WebPDecodeRGBInto(data, size, ext_buf, buf_size, stride); +#endif // !defined(WEBP_REDUCE_CSP) } else { - WebPDecodeBGRInto(data, size, ext_buf, buf_size, stride); + WebPDecodeBGRAInto(data, size, ext_buf, buf_size, stride); } free(ext_buf); } else {
diff --git a/tools/android/forwarder2/device_controller.cc b/tools/android/forwarder2/device_controller.cc index 5c018d9c..19827a0 100644 --- a/tools/android/forwarder2/device_controller.cc +++ b/tools/android/forwarder2/device_controller.cc
@@ -79,9 +79,9 @@ LOG(ERROR) << "Invalid command received."; return; } - const ListenersMap::iterator listener_it = listeners_.find(port); - DeviceListener* const listener = listener_it == listeners_.end() - ? static_cast<DeviceListener*>(NULL) : listener_it->second.get(); + const auto listener_it = listeners_.find(port); + DeviceListener* const listener = + listener_it == listeners_.end() ? nullptr : listener_it->second.get(); switch (command) { case command::LISTEN: { if (listener != NULL) { @@ -100,9 +100,7 @@ // call DeviceListener::listener_port() to retrieve the currently // allocated port to this new listener. const int listener_port = new_listener->listener_port(); - listeners_.insert( - std::make_pair(listener_port, - linked_ptr<DeviceListener>(new_listener.release()))); + listeners_.emplace(listener_port, std::move(new_listener)); LOG(INFO) << "Forwarding device port " << listener_port << " to host."; break; }
diff --git a/tools/android/forwarder2/device_controller.h b/tools/android/forwarder2/device_controller.h index 28fbea4..9b3e3a1 100644 --- a/tools/android/forwarder2/device_controller.h +++ b/tools/android/forwarder2/device_controller.h
@@ -10,7 +10,6 @@ #include "base/containers/hash_tables.h" #include "base/macros.h" -#include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "tools/android/forwarder2/socket.h" @@ -36,9 +35,6 @@ void Start(); private: - typedef base::hash_map< - int /* port */, linked_ptr<DeviceListener> > ListenersMap; - DeviceController(std::unique_ptr<Socket> host_socket, int exit_notifier_fd); void AcceptHostCommandSoon(); @@ -56,7 +52,7 @@ // Lets ensure DeviceListener instances are deleted on the thread they were // created on. const scoped_refptr<base::SingleThreadTaskRunner> construction_task_runner_; - ListenersMap listeners_; + base::hash_map<int /* port */, std::unique_ptr<DeviceListener>> listeners_; //WeakPtrFactory's documentation says: // Member variables should appear before the WeakPtrFactory, to ensure
diff --git a/tools/android/forwarder2/host_controllers_manager.cc b/tools/android/forwarder2/host_controllers_manager.cc index 9f1cf3e..6362234 100644 --- a/tools/android/forwarder2/host_controllers_manager.cc +++ b/tools/android/forwarder2/host_controllers_manager.cc
@@ -118,9 +118,8 @@ if (!SendMessage(msg, client_socket)) return; host_controller->Start(); - controllers_->insert( - std::make_pair(MakeHostControllerMapKey(adb_port, device_port), - linked_ptr<HostController>(host_controller.release()))); + controllers_->emplace(MakeHostControllerMapKey(adb_port, device_port), + std::move(host_controller)); } void HostControllersManager::Unmap(const std::string& adb_path, @@ -148,9 +147,8 @@ int adb_port, Socket* client_socket) { const std::string adb_port_str = base::StringPrintf("%d", adb_port); - for (HostControllerMap::const_iterator controller_key = - controllers_->cbegin(); - controller_key != controllers_->cend(); ++controller_key) { + for (auto controller_key = controllers_->begin(); + controller_key != controllers_->end(); ++controller_key) { std::vector<std::string> pieces = base::SplitString(controller_key->first, ":", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); @@ -241,8 +239,8 @@ int port = it->second; const std::string prefix = base::StringPrintf("%d:", port); - for (HostControllerMap::const_iterator others = controllers_->begin(); - others != controllers_->end(); ++others) { + for (auto others = controllers_->begin(); others != controllers_->end(); + ++others) { if (base::StartsWith(others->first, prefix, base::CompareCase::SENSITIVE)) return; }
diff --git a/tools/android/forwarder2/host_controllers_manager.h b/tools/android/forwarder2/host_controllers_manager.h index ab5869fa..fbdb4532 100644 --- a/tools/android/forwarder2/host_controllers_manager.h +++ b/tools/android/forwarder2/host_controllers_manager.h
@@ -11,7 +11,6 @@ #include "base/at_exit.h" #include "base/containers/hash_tables.h" #include "base/gtest_prod_util.h" -#include "base/memory/linked_ptr.h" #include "base/memory/weak_ptr.h" #include "tools/android/forwarder2/host_controller.h" #include "tools/android/forwarder2/socket.h" @@ -44,8 +43,8 @@ FRIEND_TEST_ALL_PREFIXES(HostControllersManagerTest, AdbNoExtraFds); FRIEND_TEST_ALL_PREFIXES(HostControllersManagerTest, AdbArgumentSequence); - typedef base::hash_map<std::string, linked_ptr<HostController>> - HostControllerMap; + using HostControllerMap = + base::hash_map<std::string, std::unique_ptr<HostController>>; static std::string MakeHostControllerMapKey(int adb_port, int device_port);
diff --git a/tools/android/forwarder2/util.h b/tools/android/forwarder2/util.h index 9947628..40f2460 100644 --- a/tools/android/forwarder2/util.h +++ b/tools/android/forwarder2/util.h
@@ -7,6 +7,8 @@ #include "base/logging.h" +#include <utility> + namespace forwarder2 { // Safely deletes a ref-counted value in a provided map by unlinking the object @@ -23,11 +25,12 @@ return true; } -// See DeleteRefCountedValuetInMap() above. +// See DeleteRefCountedValueInMap() above. template <typename Map, typename Iterator> void DeleteRefCountedValueInMapFromIterator(Iterator it, Map* map) { DCHECK(it != map->end()); - const typename Map::value_type::second_type shared_ptr_copy = it->second; + const typename Map::value_type::second_type smart_pointer = + std::move(it->second); map->erase(it); }
diff --git a/tools/code_coverage/run_fuzz_target.py b/tools/code_coverage/run_fuzz_target.py index 3580cd6..cbd4e09f 100755 --- a/tools/code_coverage/run_fuzz_target.py +++ b/tools/code_coverage/run_fuzz_target.py
@@ -5,7 +5,9 @@ """Run a single fuzz target built with code coverage instrumentation.""" import argparse +import copy import json +import multiprocessing import os import shutil import signal @@ -176,40 +178,101 @@ os.mkdir(dir_path) +def _CreateShardedCorpus(max_shards, corpus_dir, output_dir): + """Shards the corpus and returns the directories with sharded corpus.""" + testcases = sorted(os.listdir(corpus_dir)) + shards = min(len(testcases), max_shards) + + if shards <= 1: + return [corpus_dir] + + shard_dirs = [] + testcase_per_shard = len(testcases) / shards + 1 + copy_file = os.symlink or shutil.copy2 + + index = 0 + while True: + start = index * testcase_per_shard + if start >= len(testcases): + break + + end = (index + 1) * testcase_per_shard + + shard_dir = os.path.join(output_dir, 'shard_%d' % (index + 1)) + _RecreateDir(shard_dir) + for testcase in testcases[start : end]: + copy_file(os.path.join(corpus_dir, testcase), + os.path.join(shard_dir, testcase)) + + shard_dirs.append(shard_dir) + index += 1 + + return shard_dirs + + def _RunFuzzTarget(fuzzer, fuzzer_name, output_dir, corpus_dir, timeout): # The way we run fuzz targets in code coverage config (-merge=1) requires an # empty directory to be provided to fuzz target. We run fuzz targets with # -merge=1 because that mode is crash-resistant. dummy_corpus_dir = os.path.join(output_dir, _DUMMY_CORPUS_DIRECTORY) _RecreateDir(dummy_corpus_dir) + sharded_corpus_root_dir = os.path.join(output_dir, 'shards') + _RecreateDir(sharded_corpus_root_dir) - cmd = [fuzzer] + _LIBFUZZER_FLAGS + [dummy_corpus_dir, corpus_dir] + cpu_count = multiprocessing.cpu_count() + shards = max(10, cpu_count - 5) # Use 10+ shards, but leave 5 cpu cores. + + corpus_dirs = _CreateShardedCorpus( + shards, corpus_dir, sharded_corpus_root_dir) + + cmd = [fuzzer] + _LIBFUZZER_FLAGS + [dummy_corpus_dir] try: - _RunWithTimeout(cmd, timeout) + _RunWithTimeout(cmd, timeout, corpus_dirs) except Exception as e: _Log('Failed to run {fuzzer}: {error}.'.format( fuzzer=fuzzer_name, error=str(e))) shutil.rmtree(dummy_corpus_dir) shutil.rmtree(corpus_dir) + shutil.rmtree(sharded_corpus_root_dir) -def _RunWithTimeout(cmd, timeout): - _Log('Run fuzz target using the following command: %s.' % str(cmd)) +def _RunWithTimeout(cmd, timeout, corpus_dirs): + _Log('Run fuzz target using the following command in %d shards: %s.' % ( + len(corpus_dirs), str(cmd))) # TODO: we may need to use |creationflags=subprocess.CREATE_NEW_PROCESS_GROUP| # on Windows or send |signal.CTRL_C_EVENT| signal if the process times out. - runner = subprocess.Popen(cmd) + runners = [] + for corpus_dir in corpus_dirs: + # Update LLVM_PROFILE_FILE for the fuzzer process. + env = copy.deepcopy(os.environ) + profile = env['LLVM_PROFILE_FILE'] + profile = os.path.join( + os.path.dirname(profile), os.path.basename(corpus_dir), + os.path.basename(profile)) + env['LLVM_PROFILE_FILE'] = profile + runners.append(subprocess.Popen(cmd + [corpus_dir], env=env)) + + def GetRunningProccess(): + running = [] + for runner in runners: + if runner.poll() is None: + running.append(runner) + return running timer = 0 - while timer < timeout and runner.poll() is None: + while timer < timeout: + if not GetRunningProccess(): + break time.sleep(_SLEEP_DURATION_SECONDS) timer += _SLEEP_DURATION_SECONDS - if runner.poll() is None: + timeout_runners = GetRunningProccess() + _Log('Fuzz target timed out, interrupting %d shards.' % len(timeout_runners)) + for runner in timeout_runners: try: - _Log('Fuzz target timed out, interrupting it.') # libFuzzer may spawn some child processes, that is why we have to call # os.killpg, which would send the signal to our Python process as well, so # we just catch and ignore it in this try block. @@ -225,6 +288,8 @@ def Main(): + assert 'LLVM_PROFILE_FILE' in os.environ, 'LLVM_PROFILE_FILE not set' + args = _ParseCommandArguments() fuzzer_name = os.path.splitext(os.path.basename(args.fuzzer))[0] corpus_dir = _PrepareCorpus(fuzzer_name, args.output_dir)
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 001f8a7b..cc5c617 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -295,6 +295,7 @@ 'Chromium Linux Goma GCE Staging': 'release_bot', 'Chromium Mac Goma GCE Staging': 'release_bot', 'CrWinClangGomaGCEStaging': 'win_clang_release_bot_disable_nacl', + 'Chromium Linux Goma RBE ToT': 'release_bot', 'Chromium Linux Goma RBE Staging (clobber)': 'release_bot', 'Chromium Linux Goma RBE Staging': 'release_bot', 'Chromium Linux Goma RBE Staging (dbg) (clobber)': 'debug_bot',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 60b9cd6a..a701bc3e 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -15105,6 +15105,7 @@ <int value="508" label="DeviceGpoCacheLifetime"/> <int value="509" label="DeviceAuthDataCacheLifetime"/> <int value="510" label="CloudManagementEnrollmentToken"/> + <int value="511" label="BrowserSwitcherExternalSitelistUrl"/> </enum> <enum name="EnterprisePolicyInvalidations">
diff --git a/tools/perf/core/shard_maps/android-go_webview-perf_map.json b/tools/perf/core/shard_maps/android-go_webview-perf_map.json index 665cc5d..980bd57 100644 --- a/tools/perf/core/shard_maps/android-go_webview-perf_map.json +++ b/tools/perf/core/shard_maps/android-go_webview-perf_map.json
@@ -16,7 +16,11 @@ "blink_perf.svg": {}, "dromaeo": {}, "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, + "dummy_benchmark.stable_benchmark_1": {} + } + }, + "1": { + "benchmarks": { "jetstream": {}, "kraken": {}, "loading.desktop": {}, @@ -27,59 +31,104 @@ "memory.long_running_idle_gmail_background_tbmv2": {}, "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": { - "end": 1 - } - } - }, - "1": { - "benchmarks": { - "memory.top_10_mobile": { - "begin": 1, - "end": 8 + "end": 6 } } }, "2": { "benchmarks": { "memory.top_10_mobile": { - "begin": 8, - "end": 15 + "begin": 6 } } }, "3": { "benchmarks": { - "memory.top_10_mobile": { - "begin": 15 - }, "octane": {}, "oortonline_tbmv2": {}, "power.desktop": {}, - "power.typical_10_mobile": { - "end": 4 + "power.typical_10_mobile": {}, + "rasterize_and_record_micro.partial_invalidation": {}, + "rasterize_and_record_micro.top_25": { + "end": 22 } } }, "4": { "benchmarks": { - "power.typical_10_mobile": { - "begin": 4 + "rasterize_and_record_micro.top_25": { + "begin": 22 }, - "rasterize_and_record_micro.partial_invalidation": {}, - "rasterize_and_record_micro.top_25": {}, "rendering.desktop": {}, "rendering.mobile": { - "end": 149 + "end": 43 } } }, "5": { "benchmarks": { "rendering.mobile": { - "begin": 149 + "begin": 43, + "end": 94 + } + } + }, + "6": { + "benchmarks": { + "rendering.mobile": { + "begin": 94, + "end": 149 + } + } + }, + "7": { + "benchmarks": { + "rendering.mobile": { + "begin": 149, + "end": 208 + } + } + }, + "8": { + "benchmarks": { + "rendering.mobile": { + "begin": 208, + "end": 288 + } + } + }, + "9": { + "benchmarks": { + "rendering.mobile": { + "begin": 288, + "end": 365 + } + } + }, + "10": { + "benchmarks": { + "rendering.mobile": { + "begin": 365, + "end": 417 + } + } + }, + "11": { + "benchmarks": { + "rendering.mobile": { + "begin": 417 }, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, + "smoothness.tough_pinch_zoom_cases": { + "end": 7 + } + } + }, + "12": { + "benchmarks": { + "smoothness.tough_pinch_zoom_cases": { + "begin": 7 + }, "speedometer": {}, "speedometer-future": {}, "speedometer2": {}, @@ -87,121 +136,61 @@ "startup.mobile": {}, "system_health.common_desktop": {}, "system_health.common_mobile": { - "end": 2 - } - } - }, - "6": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 2, - "end": 15 - } - } - }, - "7": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 15, - "end": 20 - } - } - }, - "8": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 20, - "end": 37 - } - } - }, - "9": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 37, - "end": 73 - } - } - }, - "10": { - "benchmarks": { - "system_health.common_mobile": { - "begin": 73 - }, - "system_health.memory_desktop": {}, - "system_health.memory_mobile": { - "end": 1 - } - } - }, - "11": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 1, "end": 8 } } }, - "12": { - "benchmarks": { - "system_health.memory_mobile": { - "begin": 8, - "end": 16 - } - } - }, "13": { "benchmarks": { - "system_health.memory_mobile": { - "begin": 16, - "end": 21 + "system_health.common_mobile": { + "begin": 8, + "end": 30 } } }, "14": { "benchmarks": { - "system_health.memory_mobile": { - "begin": 21, - "end": 24 + "system_health.common_mobile": { + "begin": 30 } } }, "15": { "benchmarks": { + "system_health.memory_desktop": {}, "system_health.memory_mobile": { - "begin": 24, - "end": 32 + "end": 13 } } }, "16": { "benchmarks": { "system_health.memory_mobile": { - "begin": 32, - "end": 48 + "begin": 13, + "end": 24 } } }, "17": { "benchmarks": { "system_health.memory_mobile": { - "begin": 48, - "end": 59 + "begin": 24, + "end": 43 } } }, "18": { "benchmarks": { "system_health.memory_mobile": { - "begin": 59, - "end": 73 + "begin": 43, + "end": 62 } } }, "19": { "benchmarks": { "system_health.memory_mobile": { - "begin": 73 + "begin": 62 } } }, @@ -213,75 +202,76 @@ "v8.browsing_desktop": {}, "v8.browsing_desktop-future": {}, "v8.browsing_mobile": { - "end": 1 + "end": 10 } } }, "21": { "benchmarks": { "v8.browsing_mobile": { - "begin": 1, - "end": 10 + "begin": 10, + "end": 22 } } }, "22": { "benchmarks": { "v8.browsing_mobile": { - "begin": 10, - "end": 14 + "begin": 22 + }, + "v8.browsing_mobile-future": { + "end": 8 } } }, "23": { "benchmarks": { - "v8.browsing_mobile": { - "begin": 14, - "end": 20 + "v8.browsing_mobile-future": { + "begin": 8, + "end": 19 } } }, "24": { "benchmarks": { - "v8.browsing_mobile": { - "begin": 20 + "v8.browsing_mobile-future": { + "begin": 19 }, - "v8.browsing_mobile-future": {}, "v8.runtime_stats.top_25": {}, "wasm": {}, "webrtc": {} } }, "extra_infos": { - "num_stories": 2037, - "predicted_min_shard_time": 1326.0, - "predicted_min_shard_index": 14, - "predicted_max_shard_time": 2418.0, - "predicted_max_shard_index": 12, - "shard #0": 1946.0, - "shard #1": 1980.0, - "shard #2": 2160.0, - "shard #3": 2066.0, - "shard #4": 1974.0, - "shard #5": 1996.0, - "shard #6": 2238.0, - "shard #7": 1584.0, - "shard #8": 2312.0, - "shard #9": 2008.0, - "shard #10": 2070.0, - "shard #11": 1812.0, - "shard #12": 2418.0, - "shard #13": 2238.0, - "shard #14": 1326.0, - "shard #15": 2346.0, - "shard #16": 2022.0, - "shard #17": 1836.0, - "shard #18": 2292.0, - "shard #19": 1908.0, - "shard #20": 1866.0, - "shard #21": 2028.0, - "shard #22": 1964.0, - "shard #23": 2142.0, - "shard #24": 2102.0 + "num_stories": 2061, + "predicted_min_shard_time": 3226.0, + "predicted_min_shard_index": 0, + "predicted_max_shard_time": 4886.0, + "predicted_max_shard_index": 1, + "shard #0": 3226.0, + "shard #1": 4886.0, + "shard #2": 4070.0, + "shard #3": 4060.0, + "shard #4": 4000.0, + "shard #5": 4064.0, + "shard #6": 3970.0, + "shard #7": 4104.0, + "shard #8": 4012.0, + "shard #9": 4082.0, + "shard #10": 4022.0, + "shard #11": 4040.0, + "shard #12": 4030.0, + "shard #13": 4072.0, + "shard #14": 4110.0, + "shard #15": 4260.0, + "shard #16": 3444.0, + "shard #17": 4296.0, + "shard #18": 4062.0, + "shard #19": 4230.0, + "shard #20": 4040.0, + "shard #21": 3864.0, + "shard #22": 4098.0, + "shard #23": 4072.0, + "shard #24": 3986.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/android-nexus5x-perf-fyi_map.json b/tools/perf/core/shard_maps/android-nexus5x-perf-fyi_map.json index 63dafa0..d2811b4 100644 --- a/tools/perf/core/shard_maps/android-nexus5x-perf-fyi_map.json +++ b/tools/perf/core/shard_maps/android-nexus5x-perf-fyi_map.json
@@ -2,41 +2,41 @@ "0": { "benchmarks": { "heap_profiling.mobile.disabled": { - "end": 2 + "end": 1 } } }, "1": { "benchmarks": { "heap_profiling.mobile.disabled": { - "begin": 2 + "begin": 1 } } }, "2": { "benchmarks": { "heap_profiling.mobile.native": { - "end": 2 + "end": 1 } } }, "3": { "benchmarks": { "heap_profiling.mobile.native": { - "begin": 2 + "begin": 1 }, "heap_profiling.mobile.pseudo": {} } }, "extra_infos": { "num_stories": 9, - "predicted_min_shard_time": 136.0, - "predicted_min_shard_index": 1, - "predicted_max_shard_time": 166.0, - "predicted_max_shard_index": 0, - "shard #0": 166.0, - "shard #1": 136.0, - "shard #2": 160.0, - "shard #3": 150.0 + "predicted_min_shard_time": 70.0, + "predicted_min_shard_index": 3, + "predicted_max_shard_time": 192.0, + "predicted_max_shard_index": 1, + "shard #0": 88.0, + "shard #1": 192.0, + "shard #2": 86.0, + "shard #3": 70.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/android-pixel2-perf_map.json b/tools/perf/core/shard_maps/android-pixel2-perf_map.json index 1ec9c8c..730c527f 100644 --- a/tools/perf/core/shard_maps/android-pixel2-perf_map.json +++ b/tools/perf/core/shard_maps/android-pixel2-perf_map.json
@@ -21,24 +21,29 @@ "kraken": {}, "loading.desktop": {}, "loading.mobile": { - "end": 23 + "end": 21 } } }, "1": { "benchmarks": { "loading.mobile": { - "begin": 23 + "begin": 21 }, "media.desktop": {}, - "media.mobile": {}, - "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {} + "media.mobile": { + "end": 20 + } } }, "2": { "benchmarks": { + "media.mobile": { + "begin": 20 + }, + "memory.desktop": {}, + "memory.long_running_idle_gmail_background_tbmv2": {}, + "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": {}, "octane": {}, "oortonline_tbmv2": {}, @@ -48,22 +53,22 @@ "rasterize_and_record_micro.top_25": {}, "rendering.desktop": {}, "rendering.mobile": { - "end": 139 + "end": 106 } } }, "3": { "benchmarks": { "rendering.mobile": { - "begin": 139, - "end": 408 + "begin": 106, + "end": 395 } } }, "4": { "benchmarks": { "rendering.mobile": { - "begin": 408 + "begin": 395 }, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, "smoothness.tough_pinch_zoom_cases": {}, @@ -76,30 +81,30 @@ "system_health.common_mobile": {}, "system_health.memory_desktop": {}, "system_health.memory_mobile": { - "end": 16 + "end": 13 } } }, "5": { "benchmarks": { "system_health.memory_mobile": { - "begin": 16 + "begin": 13 }, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, "tracing.tracing_with_background_memory_infra": {}, "v8.browsing_desktop": {}, - "v8.browsing_desktop-future": {}, - "v8.browsing_mobile": { - "end": 13 + "v8.browsing_desktop-future": { + "end": 33 } } }, "6": { "benchmarks": { - "v8.browsing_mobile": { - "begin": 13 + "v8.browsing_desktop-future": { + "begin": 33 }, + "v8.browsing_mobile": {}, "v8.browsing_mobile-future": {}, "v8.runtime_stats.top_25": {}, "wasm": {}, @@ -107,17 +112,17 @@ } }, "extra_infos": { - "num_stories": 2037, - "predicted_min_shard_time": 17352.0, - "predicted_min_shard_index": 0, - "predicted_max_shard_time": 17928.0, - "predicted_max_shard_index": 1, - "shard #0": 17352.0, - "shard #1": 17928.0, - "shard #2": 17678.0, - "shard #3": 17668.0, - "shard #4": 17740.0, - "shard #5": 17664.0, - "shard #6": 17644.0 + "num_stories": 2061, + "predicted_min_shard_time": 16218.0, + "predicted_min_shard_index": 5, + "predicted_max_shard_time": 16548.0, + "predicted_max_shard_index": 4, + "shard #0": 16282.0, + "shard #1": 16498.0, + "shard #2": 16380.0, + "shard #3": 16348.0, + "shard #4": 16548.0, + "shard #5": 16218.0, + "shard #6": 16378.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json b/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json index fad16f8..739f8f62 100644 --- a/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json +++ b/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json
@@ -20,21 +20,30 @@ "jetstream": {}, "kraken": {}, "loading.desktop": {}, - "loading.mobile": {}, + "loading.mobile": { + "end": 40 + } + } + }, + "1": { + "benchmarks": { + "loading.mobile": { + "begin": 40 + }, "media.desktop": {}, "media.mobile": {}, "memory.desktop": {}, "memory.long_running_idle_gmail_background_tbmv2": {}, "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": { - "end": 3 + "end": 14 } } }, - "1": { + "2": { "benchmarks": { "memory.top_10_mobile": { - "begin": 3 + "begin": 14 }, "octane": {}, "oortonline_tbmv2": {}, @@ -44,25 +53,26 @@ "rasterize_and_record_micro.top_25": {}, "rendering.desktop": {}, "rendering.mobile": { - "end": 71 - } - } - }, - "2": { - "benchmarks": { - "rendering.mobile": { - "begin": 71, - "end": 268 + "end": 165 } } }, "3": { "benchmarks": { "rendering.mobile": { - "begin": 268 + "begin": 165 }, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, + "smoothness.tough_pinch_zoom_cases": { + "end": 4 + } + } + }, + "4": { + "benchmarks": { + "smoothness.tough_pinch_zoom_cases": { + "begin": 4 + }, "speedometer": {}, "speedometer-future": {}, "speedometer2": {}, @@ -70,25 +80,16 @@ "startup.mobile": {}, "system_health.common_desktop": {}, "system_health.common_mobile": {}, - "system_health.memory_desktop": { - "end": 99 - } - } - }, - "4": { - "benchmarks": { - "system_health.memory_desktop": { - "begin": 99 - }, + "system_health.memory_desktop": {}, "system_health.memory_mobile": { - "end": 61 + "end": 22 } } }, "5": { "benchmarks": { "system_health.memory_mobile": { - "begin": 61 + "begin": 22 }, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, @@ -96,14 +97,14 @@ "v8.browsing_desktop": {}, "v8.browsing_desktop-future": {}, "v8.browsing_mobile": { - "end": 21 + "end": 10 } } }, "6": { "benchmarks": { "v8.browsing_mobile": { - "begin": 21 + "begin": 10 }, "v8.browsing_mobile-future": {}, "v8.runtime_stats.top_25": {}, @@ -112,17 +113,17 @@ } }, "extra_infos": { - "num_stories": 2037, - "predicted_min_shard_time": 10442.0, - "predicted_min_shard_index": 0, - "predicted_max_shard_time": 10632.0, + "num_stories": 2061, + "predicted_min_shard_time": 14198.0, + "predicted_min_shard_index": 5, + "predicted_max_shard_time": 14340.0, "predicted_max_shard_index": 1, - "shard #0": 10442.0, - "shard #1": 10632.0, - "shard #2": 10554.0, - "shard #3": 10538.0, - "shard #4": 10620.0, - "shard #5": 10450.0, - "shard #6": 10556.0 + "shard #0": 14252.0, + "shard #1": 14340.0, + "shard #2": 14242.0, + "shard #3": 14268.0, + "shard #4": 14322.0, + "shard #5": 14198.0, + "shard #6": 14298.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/android-go_webview-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-go_webview-perf_timing.json index f98811e..333b902 100644 --- a/tools/perf/core/shard_maps/timing_data/android-go_webview-perf_timing.json +++ b/tools/perf/core/shard_maps/timing_data/android-go_webview-perf_timing.json
@@ -1,10 +1,166 @@ [ { - "duration": "25.0", + "duration": "51.0", + "name": "blink_perf.accessibility/textarea-append.html" + }, + { + "duration": "84.0", + "name": "blink_perf.image_decoder/decode-gif.html" + }, + { + "duration": "26.0", + "name": "blink_perf.image_decoder/decode-jpeg.html" + }, + { + "duration": "67.0", + "name": "blink_perf.image_decoder/decode-lossless-webp.html" + }, + { + "duration": "19.0", + "name": "blink_perf.image_decoder/decode-lossy-webp.html" + }, + { + "duration": "36.0", + "name": "blink_perf.image_decoder/decode-png-palette-opaque.html" + }, + { + "duration": "23.0", + "name": "blink_perf.image_decoder/decode-png-palette.html" + }, + { + "duration": "55.0", + "name": "blink_perf.image_decoder/decode-png.html" + }, + { + "duration": "47.0", + "name": "blink_perf.owp_storage/blob-perf-files.html" + }, + { + "duration": "27.0", + "name": "blink_perf.owp_storage/blob-perf-ipc.html" + }, + { + "duration": "18.0", + "name": "blink_perf.owp_storage/blob-perf-shm.html" + }, + { + "duration": "27.0", + "name": "blink_perf.owp_storage/blob-perf-tiny.html" + }, + { + "duration": "29.0", + "name": "blink_perf.owp_storage/idb-load-docs.html" + }, + { + "duration": "37.0", + "name": "blink_perf.svg/AzLizardBenjiPark.html" + }, + { + "duration": "21.0", + "name": "blink_perf.svg/Bamboo.html" + }, + { + "duration": "11.0", + "name": "blink_perf.svg/Cactus.html" + }, + { + "duration": "12.0", + "name": "blink_perf.svg/Cowboy.html" + }, + { + "duration": "10.0", + "name": "blink_perf.svg/CrawFishGanson.html" + }, + { + "duration": "11.0", + "name": "blink_perf.svg/Debian.html" + }, + { + "duration": "10.0", + "name": "blink_perf.svg/DropsOnABlade.html" + }, + { + "duration": "10.0", + "name": "blink_perf.svg/FlowerFromMyGarden.html" + }, + { + "duration": "10.0", + "name": "blink_perf.svg/FoodLeifLodahl.html" + }, + { + "duration": "11.0", + "name": "blink_perf.svg/France.html" + }, + { + "duration": "9.0", + "name": "blink_perf.svg/FrancoBolloGnomeEzechi.html" + }, + { + "duration": "12.0", + "name": "blink_perf.svg/GearFlowers.html" + }, + { + "duration": "10.0", + "name": "blink_perf.svg/HarveyRayner.html" + }, + { + "duration": "10.0", + "name": "blink_perf.svg/HereGear.html" + }, + { + "duration": "22.0", + "name": "blink_perf.svg/MtSaintHelens.html" + }, + { + "duration": "9.0", + "name": "blink_perf.svg/Samurai.html" + }, + { + "duration": "458.0", + "name": "blink_perf.svg/SierpinskiCarpet.html" + }, + { + "duration": "14.0", + "name": "blink_perf.svg/SvgCubics.html" + }, + { + "duration": "14.0", + "name": "blink_perf.svg/SvgHitTesting.html" + }, + { + "duration": "16.0", + "name": "blink_perf.svg/SvgNestedUse.html" + }, + { + "duration": "10.0", + "name": "blink_perf.svg/UnderTheSee.html" + }, + { + "duration": "13.0", + "name": "blink_perf.svg/WorldIso.html" + }, + { + "duration": "20.0", + "name": "blink_perf.svg/Worldcup.html" + }, + { + "duration": "33.0", + "name": "dummy_benchmark.noisy_benchmark_1/dummy_page.html" + }, + { + "duration": "872.0", + "name": "jetstream/http://browserbench.org/JetStream/" + }, + { + "duration": "351.0", + "name": "memory.long_running_idle_gmail_tbmv2/https://mail.google.com/mail/" + }, + { + "duration": "26.0", "name": "memory.top_10_mobile/after_http_en_m_wikipedia_org_wiki_Science" }, { - "duration": "25.0", + "duration": "24.0", "name": "memory.top_10_mobile/after_http_m_intl_taobao_com_group_purchase_html" }, { @@ -12,15 +168,15 @@ "name": "memory.top_10_mobile/after_http_m_youtube_com_results_q_science" }, { - "duration": "33.0", + "duration": "25.0", "name": "memory.top_10_mobile/after_http_search_yahoo_com_search__ylt_p_google" }, { - "duration": "26.0", + "duration": "37.0", "name": "memory.top_10_mobile/after_http_www_amazon_com_gp_aw_s_k_nexus" }, { - "duration": "25.0", + "duration": "26.0", "name": "memory.top_10_mobile/after_http_www_baidu_com_s_word_google" }, { @@ -32,15 +188,15 @@ "name": "memory.top_10_mobile/after_https_m_facebook_com_rihanna" }, { - "duration": "40.0", + "duration": "25.0", "name": "memory.top_10_mobile/after_https_mobile_twitter_com_justinbieber_skip_interstitial_true" }, { - "duration": "26.0", + "duration": "38.0", "name": "memory.top_10_mobile/after_https_www_google_co_uk_hl_en_q_science" }, { - "duration": "33.0", + "duration": "32.0", "name": "memory.top_10_mobile/http_en_m_wikipedia_org_wiki_Science" }, { @@ -48,27 +204,27 @@ "name": "memory.top_10_mobile/http_m_intl_taobao_com_group_purchase_html" }, { - "duration": "32.0", + "duration": "30.0", "name": "memory.top_10_mobile/http_m_youtube_com_results_q_science" }, { - "duration": "29.0", + "duration": "28.0", "name": "memory.top_10_mobile/http_search_yahoo_com_search__ylt_p_google" }, { - "duration": "31.0", + "duration": "29.0", "name": "memory.top_10_mobile/http_www_amazon_com_gp_aw_s_k_nexus" }, { - "duration": "32.0", + "duration": "41.0", "name": "memory.top_10_mobile/http_www_baidu_com_s_word_google" }, { - "duration": "32.0", + "duration": "30.0", "name": "memory.top_10_mobile/http_yandex_ru_touchsearch_text_science" }, { - "duration": "29.0", + "duration": "28.0", "name": "memory.top_10_mobile/https_m_facebook_com_rihanna" }, { @@ -76,587 +232,2695 @@ "name": "memory.top_10_mobile/https_mobile_twitter_com_justinbieber_skip_interstitial_true" }, { - "duration": "31.0", - "name": "memory.top_10_mobile/https_www_google_co_uk_hl_en_q_science" + "duration": "184.0", + "name": "octane/http://chromium.github.io/octane/index.html?auto=1" }, { - "duration": "75.0", - "name": "power.typical_10_mobile/http://de.m.wikipedia.org/wiki/K%C3%B6lner_Dom" - }, - { - "duration": "80.0", - "name": "power.typical_10_mobile/http://m.chiebukuro.yahoo.co.jp/detail/q10136829180" - }, - { - "duration": "99.0", - "name": "power.typical_10_mobile/http://m.ebay.com/itm/351157205404" - }, - { - "duration": "101.0", - "name": "power.typical_10_mobile/http://m.facebook.com/barackobama" - }, - { - "duration": "75.0", - "name": "power.typical_10_mobile/http://m.huffpost.com/us/entry/6004486" - }, - { - "duration": "79.0", - "name": "power.typical_10_mobile/http://m.ynet.co.il" - }, - { - "duration": "77.0", - "name": "power.typical_10_mobile/http://siriuslymeg.tumblr.com/" - }, - { - "duration": "75.0", - "name": "power.typical_10_mobile/http://wapbaike.baidu.com/" - }, - { - "duration": "76.0", - "name": "power.typical_10_mobile/http://www.cnn.com/2014/03/31/showbiz/tv/himym-finale/index.html" - }, - { - "duration": "80.0", - "name": "power.typical_10_mobile/http://www.rg.ru/2014/10/21/cska-site.html" - }, - { - "duration": "77.0", - "name": "power.typical_10_mobile/https://en.wikipedia.org/wiki/File:Rotating_earth_(large).gif" - }, - { - "duration": "174.0", - "name": "speedometer/http://browserbench.org/Speedometer/" - }, - { - "duration": "334.0", - "name": "speedometer2/Speedometer2" - }, - { - "duration": "29.0", - "name": "system_health.common_mobile/background:media:imgur" - }, - { - "duration": "67.0", - "name": "system_health.common_mobile/background:news:nytimes" - }, - { - "duration": "36.0", - "name": "system_health.common_mobile/background:search:google" - }, - { - "duration": "59.0", - "name": "system_health.common_mobile/background:social:facebook" - }, - { - "duration": "14.0", - "name": "system_health.common_mobile/browse:chrome:newtab" - }, - { - "duration": "14.0", - "name": "system_health.common_mobile/browse:chrome:omnibox" - }, - { - "duration": "127.0", - "name": "system_health.common_mobile/browse:media:facebook_photos" - }, - { - "duration": "77.0", - "name": "system_health.common_mobile/browse:media:flickr_infinite_scroll" - }, - { - "duration": "105.0", - "name": "system_health.common_mobile/browse:media:imgur" - }, - { - "duration": "147.0", - "name": "system_health.common_mobile/browse:media:youtube" - }, - { - "duration": "285.0", - "name": "system_health.common_mobile/browse:news:cnn" - }, - { - "duration": "276.0", - "name": "system_health.common_mobile/browse:news:cnn:2018" - }, - { - "duration": "87.0", - "name": "system_health.common_mobile/browse:news:cricbuzz" - }, - { - "duration": "77.0", - "name": "system_health.common_mobile/browse:news:qq" - }, - { - "duration": "93.0", - "name": "system_health.common_mobile/browse:news:reddit" - }, - { - "duration": "74.0", - "name": "system_health.common_mobile/browse:news:washingtonpost" - }, - { - "duration": "119.0", - "name": "system_health.common_mobile/browse:shopping:amazon" - }, - { - "duration": "136.0", - "name": "system_health.common_mobile/browse:shopping:avito" - }, - { - "duration": "56.0", - "name": "system_health.common_mobile/browse:shopping:lazada" - }, - { - "duration": "110.0", - "name": "system_health.common_mobile/browse:social:facebook" - }, - { - "duration": "287.0", - "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll" - }, - { - "duration": "311.0", - "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll:2018" - }, - { - "duration": "177.0", - "name": "system_health.common_mobile/browse:social:instagram" - }, - { - "duration": "166.0", - "name": "system_health.common_mobile/browse:social:pinterest_infinite_scroll" - }, - { - "duration": "167.0", - "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll" - }, - { - "duration": "78.0", - "name": "system_health.common_mobile/browse:social:twitter" - }, - { - "duration": "113.0", - "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll" - }, - { - "duration": "155.0", - "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll:2018" - }, - { - "duration": "69.0", - "name": "system_health.common_mobile/browse:tools:maps" - }, - { - "duration": "25.0", - "name": "system_health.common_mobile/load:chrome:blank" - }, - { - "duration": "42.0", - "name": "system_health.common_mobile/load:games:bubbles" - }, - { - "duration": "26.0", - "name": "system_health.common_mobile/load:games:lazors" - }, - { - "duration": "53.0", - "name": "system_health.common_mobile/load:games:spychase" - }, - { - "duration": "38.0", - "name": "system_health.common_mobile/load:media:dailymotion" - }, - { - "duration": "31.0", - "name": "system_health.common_mobile/load:media:facebook_photos" - }, - { - "duration": "32.0", - "name": "system_health.common_mobile/load:media:google_images" - }, - { - "duration": "33.0", - "name": "system_health.common_mobile/load:media:imgur" - }, - { - "duration": "31.0", - "name": "system_health.common_mobile/load:media:youtube" - }, - { - "duration": "67.0", - "name": "system_health.common_mobile/load:news:cnn" - }, - { - "duration": "69.0", - "name": "system_health.common_mobile/load:news:cnn:2018" - }, - { - "duration": "56.0", - "name": "system_health.common_mobile/load:news:irctc" - }, - { - "duration": "42.0", - "name": "system_health.common_mobile/load:news:nytimes" - }, - { - "duration": "30.0", - "name": "system_health.common_mobile/load:news:qq" - }, - { - "duration": "34.0", - "name": "system_health.common_mobile/load:news:reddit" - }, - { - "duration": "35.0", - "name": "system_health.common_mobile/load:news:washingtonpost" - }, - { - "duration": "34.0", - "name": "system_health.common_mobile/load:news:wikipedia" - }, - { - "duration": "31.0", - "name": "system_health.common_mobile/load:search:baidu" - }, - { - "duration": "36.0", - "name": "system_health.common_mobile/load:search:ebay" - }, - { - "duration": "59.0", - "name": "system_health.common_mobile/load:search:google" - }, - { - "duration": "31.0", - "name": "system_health.common_mobile/load:search:taobao" - }, - { - "duration": "29.0", - "name": "system_health.common_mobile/load:search:yahoo" - }, - { - "duration": "65.0", - "name": "system_health.common_mobile/load:search:yandex" - }, - { - "duration": "30.0", - "name": "system_health.common_mobile/load:social:twitter" - }, - { - "duration": "29.0", - "name": "system_health.common_mobile/load:tools:docs" - }, - { - "duration": "44.0", - "name": "system_health.common_mobile/load:tools:drive" - }, - { - "duration": "28.0", - "name": "system_health.common_mobile/load:tools:dropbox" - }, - { - "duration": "32.0", - "name": "system_health.common_mobile/load:tools:stackoverflow" - }, - { - "duration": "33.0", - "name": "system_health.common_mobile/load:tools:stackoverflow:2018" - }, - { - "duration": "48.0", - "name": "system_health.common_mobile/load:tools:weather" - }, - { - "duration": "34.0", - "name": "system_health.memory_mobile/background:media:imgur" - }, - { - "duration": "38.0", - "name": "system_health.memory_mobile/background:search:google" - }, - { - "duration": "43.0", - "name": "system_health.memory_mobile/background:social:facebook" - }, - { - "duration": "103.0", - "name": "system_health.memory_mobile/browse:media:facebook_photos" + "duration": "47.0", + "name": "oortonline_tbmv2/http://oortonline.gl/#run" }, { "duration": "72.0", - "name": "system_health.memory_mobile/browse:media:flickr_infinite_scroll" + "name": "power.typical_10_mobile/http://de.m.wikipedia.org/wiki/K%C3%B6lner_Dom" }, { - "duration": "85.0", - "name": "system_health.memory_mobile/browse:media:imgur" + "duration": "91.0", + "name": "power.typical_10_mobile/http://m.chiebukuro.yahoo.co.jp/detail/q10136829180" }, { - "duration": "102.0", - "name": "system_health.memory_mobile/browse:media:youtube" - }, - { - "duration": "68.0", - "name": "system_health.memory_mobile/browse:news:cricbuzz" - }, - { - "duration": "64.0", - "name": "system_health.memory_mobile/browse:news:qq" - }, - { - "duration": "88.0", - "name": "system_health.memory_mobile/browse:news:reddit" - }, - { - "duration": "197.0", - "name": "system_health.memory_mobile/browse:news:toi" - }, - { - "duration": "61.0", - "name": "system_health.memory_mobile/browse:news:washingtonpost" - }, - { - "duration": "95.0", - "name": "system_health.memory_mobile/browse:shopping:amazon" - }, - { - "duration": "103.0", - "name": "system_health.memory_mobile/browse:shopping:avito" - }, - { - "duration": "51.0", - "name": "system_health.memory_mobile/browse:shopping:lazada" + "duration": "67.0", + "name": "power.typical_10_mobile/http://m.ebay.com/itm/351157205404" }, { "duration": "98.0", - "name": "system_health.memory_mobile/browse:social:facebook" + "name": "power.typical_10_mobile/http://m.facebook.com/barackobama" }, { - "duration": "170.0", - "name": "system_health.memory_mobile/browse:social:facebook_infinite_scroll:2018" + "duration": "77.0", + "name": "power.typical_10_mobile/http://m.huffpost.com/us/entry/6004486" }, { - "duration": "111.0", - "name": "system_health.memory_mobile/browse:social:instagram" + "duration": "76.0", + "name": "power.typical_10_mobile/http://m.ynet.co.il" }, { - "duration": "104.0", - "name": "system_health.memory_mobile/browse:social:pinterest_infinite_scroll" + "duration": "75.0", + "name": "power.typical_10_mobile/http://siriuslymeg.tumblr.com/" }, { - "duration": "65.0", - "name": "system_health.memory_mobile/browse:social:twitter" + "duration": "79.0", + "name": "power.typical_10_mobile/http://wapbaike.baidu.com/" }, { - "duration": "83.0", - "name": "system_health.memory_mobile/browse:tech:discourse_infinite_scroll" + "duration": "100.0", + "name": "power.typical_10_mobile/http://www.cnn.com/2014/03/31/showbiz/tv/himym-finale/index.html" }, { - "duration": "64.0", - "name": "system_health.memory_mobile/browse:tools:maps" + "duration": "77.0", + "name": "power.typical_10_mobile/http://www.rg.ru/2014/10/21/cska-site.html" }, { - "duration": "30.0", - "name": "system_health.memory_mobile/load:chrome:blank" + "duration": "75.0", + "name": "power.typical_10_mobile/https://en.wikipedia.org/wiki/File:Rotating_earth_(large).gif" }, { - "duration": "35.0", - "name": "system_health.memory_mobile/load:games:bubbles" + "duration": "45.0", + "name": "rasterize_and_record_micro.partial_invalidation/800_relpos_divs.html" }, { - "duration": "31.0", - "name": "system_health.memory_mobile/load:games:lazors" + "duration": "66.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/amazon.html" }, { - "duration": "54.0", - "name": "system_health.memory_mobile/load:games:spychase" - }, - { - "duration": "41.0", - "name": "system_health.memory_mobile/load:media:dailymotion" - }, - { - "duration": "34.0", - "name": "system_health.memory_mobile/load:media:facebook_photos" - }, - { - "duration": "35.0", - "name": "system_health.memory_mobile/load:media:google_images" - }, - { - "duration": "34.0", - "name": "system_health.memory_mobile/load:media:imgur" - }, - { - "duration": "35.0", - "name": "system_health.memory_mobile/load:media:youtube" - }, - { - "duration": "74.0", - "name": "system_health.memory_mobile/load:news:cnn" - }, - { - "duration": "61.0", - "name": "system_health.memory_mobile/load:news:cnn:2018" - }, - { - "duration": "43.0", - "name": "system_health.memory_mobile/load:news:irctc" - }, - { - "duration": "43.0", - "name": "system_health.memory_mobile/load:news:nytimes" - }, - { - "duration": "34.0", - "name": "system_health.memory_mobile/load:news:qq" - }, - { - "duration": "38.0", - "name": "system_health.memory_mobile/load:news:reddit" - }, - { - "duration": "37.0", - "name": "system_health.memory_mobile/load:news:washingtonpost" + "duration": "23.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/blogger.html" }, { "duration": "48.0", - "name": "system_health.memory_mobile/load:news:wikipedia" + "name": "rasterize_and_record_micro.top_25/file://static_top_25/booking.html" }, { - "duration": "35.0", - "name": "system_health.memory_mobile/load:search:baidu" + "duration": "30.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/cnn.html" + }, + { + "duration": "21.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/ebay.html" + }, + { + "duration": "46.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/espn.html" + }, + { + "duration": "36.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/facebook.html" + }, + { + "duration": "59.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/gmail.html" + }, + { + "duration": "50.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/google.html" + }, + { + "duration": "39.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/googlecalendar.html" + }, + { + "duration": "29.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/googledocs.html" + }, + { + "duration": "46.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleimagesearch.html" + }, + { + "duration": "45.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleplus.html" + }, + { + "duration": "33.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/linkedin.html" + }, + { + "duration": "14.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/pinterest.html" + }, + { + "duration": "40.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/techcrunch.html" + }, + { + "duration": "56.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/twitter.html" + }, + { + "duration": "28.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/weather.html" + }, + { + "duration": "24.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/wordpress.html" + }, + { + "duration": "33.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahooanswers.html" + }, + { + "duration": "85.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html" + }, + { + "duration": "112.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoosports.html" + }, + { + "duration": "57.0", + "name": "rasterize_and_record_micro.top_25/file://static_top_25/youtube.html" + }, + { + "duration": "93.0", + "name": "rendering.mobile/accu_weather_2018" + }, + { + "duration": "64.0", + "name": "rendering.mobile/accu_weather_desktop_gpu_raster_2018" + }, + { + "duration": "39.0", + "name": "rendering.mobile/amazon_2018" + }, + { + "duration": "39.0", + "name": "rendering.mobile/amazon_desktop_gpu_raster_2018" + }, + { + "duration": "38.0", + "name": "rendering.mobile/amazon_mobile_2018" + }, + { + "duration": "43.0", + "name": "rendering.mobile/analog_clock_svg" + }, + { + "duration": "70.0", + "name": "rendering.mobile/androidpolice_mobile_2018" + }, + { + "duration": "15.0", + "name": "rendering.mobile/animometer_webgl" + }, + { + "duration": "15.0", + "name": "rendering.mobile/aquarium" + }, + { + "duration": "48.0", + "name": "rendering.mobile/background_color_animation" + }, + { + "duration": "85.0", + "name": "rendering.mobile/background_color_animation_with_gradient" + }, + { + "duration": "42.0", + "name": "rendering.mobile/baidu_mobile_2018" + }, + { + "duration": "36.0", + "name": "rendering.mobile/balls_css_key_frame_animations" + }, + { + "duration": "32.0", + "name": "rendering.mobile/balls_css_transition_2_properties" + }, + { + "duration": "32.0", + "name": "rendering.mobile/balls_css_transition_40_properties" + }, + { + "duration": "32.0", + "name": "rendering.mobile/balls_css_transition_all_properties" + }, + { + "duration": "31.0", + "name": "rendering.mobile/balls_javascript_canvas" + }, + { + "duration": "32.0", + "name": "rendering.mobile/balls_javascript_css" + }, + { + "duration": "60.0", + "name": "rendering.mobile/balls_svg_animations" + }, + { + "duration": "41.0", + "name": "rendering.mobile/bing_mobile_2018" + }, + { + "duration": "15.0", + "name": "rendering.mobile/blob" }, { "duration": "34.0", - "name": "system_health.memory_mobile/load:search:ebay" + "name": "rendering.mobile/blogspot_2018" + }, + { + "duration": "30.0", + "name": "rendering.mobile/blogspot_desktop_gpu_raster_2018" + }, + { + "duration": "34.0", + "name": "rendering.mobile/blogspot_mobile_2018" + }, + { + "duration": "31.0", + "name": "rendering.mobile/blur_rotating_background" + }, + { + "duration": "38.0", + "name": "rendering.mobile/boingboing_mobile_2018" + }, + { + "duration": "39.0", + "name": "rendering.mobile/booking.com_2018" + }, + { + "duration": "36.0", + "name": "rendering.mobile/booking.com_desktop_gpu_raster_2018" + }, + { + "duration": "31.0", + "name": "rendering.mobile/booking.com_mobile_2018" + }, + { + "duration": "28.0", + "name": "rendering.mobile/bouncing_balls_15" + }, + { + "duration": "29.0", + "name": "rendering.mobile/bouncing_clipped_rectangles" + }, + { + "duration": "26.0", + "name": "rendering.mobile/bouncing_gradient_circles" + }, + { + "duration": "21.0", + "name": "rendering.mobile/bouncing_png_images" + }, + { + "duration": "39.0", + "name": "rendering.mobile/bouncing_svg_images" + }, + { + "duration": "15.0", + "name": "rendering.mobile/camera_to_webgl" + }, + { + "duration": "38.0", + "name": "rendering.mobile/canvas_05000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "38.0", + "name": "rendering.mobile/canvas_10000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "32.0", + "name": "rendering.mobile/canvas_15000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "28.0", + "name": "rendering.mobile/canvas_20000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "24.0", + "name": "rendering.mobile/canvas_30000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "23.0", + "name": "rendering.mobile/canvas_40000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "22.0", + "name": "rendering.mobile/canvas_50000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "22.0", + "name": "rendering.mobile/canvas_60000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "21.0", + "name": "rendering.mobile/canvas_75000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "21.0", + "name": "rendering.mobile/canvas_90000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "30.0", + "name": "rendering.mobile/canvas_animation_no_clear" + }, + { + "duration": "25.0", + "name": "rendering.mobile/canvas_arcs" + }, + { + "duration": "26.0", + "name": "rendering.mobile/canvas_font_cycler" + }, + { + "duration": "24.0", + "name": "rendering.mobile/canvas_lines" + }, + { + "duration": "30.0", + "name": "rendering.mobile/canvas_to_blob" + }, + { + "duration": "67.0", + "name": "rendering.mobile/capitolvolkswagen_mobile_2018" + }, + { + "duration": "31.0", + "name": "rendering.mobile/card_expansion" + }, + { + "duration": "35.0", + "name": "rendering.mobile/card_expansion_animated" + }, + { + "duration": "30.0", + "name": "rendering.mobile/card_expansion_images_text" + }, + { + "duration": "28.0", + "name": "rendering.mobile/card_flying" + }, + { + "duration": "18.0", + "name": "rendering.mobile/cats_unscaled" + }, + { + "duration": "17.0", + "name": "rendering.mobile/cats_viewport_width" + }, + { + "duration": "43.0", + "name": "rendering.mobile/cc_poster_circle" + }, + { + "duration": "25.0", + "name": "rendering.mobile/cc_scroll_text_only" + }, + { + "duration": "33.0", + "name": "rendering.mobile/chip_tune" + }, + { + "duration": "42.0", + "name": "rendering.mobile/cnn_2018" + }, + { + "duration": "56.0", + "name": "rendering.mobile/cnn_article_mobile_2018" + }, + { + "duration": "38.0", + "name": "rendering.mobile/cnn_desktop_gpu_raster_2018" + }, + { + "duration": "41.0", + "name": "rendering.mobile/cnn_mobile_2018" + }, + { + "duration": "39.0", + "name": "rendering.mobile/cnn_pathological_2018" + }, + { + "duration": "35.0", + "name": "rendering.mobile/compositor_heavy_animation" + }, + { + "duration": "28.0", + "name": "rendering.mobile/coordinated_animation" + }, + { + "duration": "29.0", + "name": "rendering.mobile/crafty_mind" + }, + { + "duration": "40.0", + "name": "rendering.mobile/css_animations_many_keyframes" + }, + { + "duration": "40.0", + "name": "rendering.mobile/css_animations_simultaneous_inline_style" + }, + { + "duration": "42.0", + "name": "rendering.mobile/css_animations_simultaneous_new_element" + }, + { + "duration": "40.0", + "name": "rendering.mobile/css_animations_simultaneous_style_element" + }, + { + "duration": "39.0", + "name": "rendering.mobile/css_animations_simultaneous_updating_class" + }, + { + "duration": "35.0", + "name": "rendering.mobile/css_animations_staggered_infinite_iterations" }, { "duration": "44.0", + "name": "rendering.mobile/css_animations_staggered_inline_style" + }, + { + "duration": "53.0", + "name": "rendering.mobile/css_animations_staggered_new_element" + }, + { + "duration": "55.0", + "name": "rendering.mobile/css_animations_staggered_style_element" + }, + { + "duration": "44.0", + "name": "rendering.mobile/css_animations_staggered_updating_class" + }, + { + "duration": "44.0", + "name": "rendering.mobile/css_animations_triggered_inline_style" + }, + { + "duration": "66.0", + "name": "rendering.mobile/css_animations_triggered_new_element" + }, + { + "duration": "43.0", + "name": "rendering.mobile/css_animations_triggered_style_element" + }, + { + "duration": "44.0", + "name": "rendering.mobile/css_animations_triggered_updating_class" + }, + { + "duration": "41.0", + "name": "rendering.mobile/css_opacity_plus_n_layers_0" + }, + { + "duration": "41.0", + "name": "rendering.mobile/css_opacity_plus_n_layers_75" + }, + { + "duration": "42.0", + "name": "rendering.mobile/css_opacity_plus_n_layers_99" + }, + { + "duration": "38.0", + "name": "rendering.mobile/css_transitions_inline_style" + }, + { + "duration": "39.0", + "name": "rendering.mobile/css_transitions_new_element" + }, + { + "duration": "39.0", + "name": "rendering.mobile/css_transitions_staggered_inline_style" + }, + { + "duration": "42.0", + "name": "rendering.mobile/css_transitions_staggered_new_element" + }, + { + "duration": "37.0", + "name": "rendering.mobile/css_transitions_staggered_style_element" + }, + { + "duration": "39.0", + "name": "rendering.mobile/css_transitions_staggered_updating_class" + }, + { + "duration": "37.0", + "name": "rendering.mobile/css_transitions_style_element" + }, + { + "duration": "45.0", + "name": "rendering.mobile/css_transitions_triggered_inline_style" + }, + { + "duration": "46.0", + "name": "rendering.mobile/css_transitions_triggered_new_element" + }, + { + "duration": "43.0", + "name": "rendering.mobile/css_transitions_triggered_style_element" + }, + { + "duration": "45.0", + "name": "rendering.mobile/css_transitions_triggered_updating_class" + }, + { + "duration": "38.0", + "name": "rendering.mobile/css_transitions_updating_class" + }, + { + "duration": "34.0", + "name": "rendering.mobile/css_value_type_color" + }, + { + "duration": "49.0", + "name": "rendering.mobile/css_value_type_filter" + }, + { + "duration": "31.0", + "name": "rendering.mobile/css_value_type_length" + }, + { + "duration": "33.0", + "name": "rendering.mobile/css_value_type_length_complex" + }, + { + "duration": "34.0", + "name": "rendering.mobile/css_value_type_length_simple" + }, + { + "duration": "40.0", + "name": "rendering.mobile/css_value_type_path" + }, + { + "duration": "55.0", + "name": "rendering.mobile/css_value_type_shadow" + }, + { + "duration": "31.0", + "name": "rendering.mobile/css_value_type_transform_complex" + }, + { + "duration": "31.0", + "name": "rendering.mobile/css_value_type_transform_simple" + }, + { + "duration": "52.0", + "name": "rendering.mobile/deviantart_mobile_2018" + }, + { + "duration": "34.0", + "name": "rendering.mobile/digg_mobile_2018" + }, + { + "duration": "15.0", + "name": "rendering.mobile/dynamic_cube_map" + }, + { + "duration": "15.0", + "name": "rendering.mobile/earth" + }, + { + "duration": "39.0", + "name": "rendering.mobile/ebay_2018" + }, + { + "duration": "36.0", + "name": "rendering.mobile/ebay_desktop_gpu_raster_2018" + }, + { + "duration": "33.0", + "name": "rendering.mobile/ebay_mobile_2018" + }, + { + "duration": "48.0", + "name": "rendering.mobile/ebay_scroll_2018" + }, + { + "duration": "40.0", + "name": "rendering.mobile/espn_2018" + }, + { + "duration": "35.0", + "name": "rendering.mobile/espn_desktop_gpu_raster_2018" + }, + { + "duration": "39.0", + "name": "rendering.mobile/espn_mobile_2018" + }, + { + "duration": "36.0", + "name": "rendering.mobile/espn_pathological_2018" + }, + { + "duration": "35.0", + "name": "rendering.mobile/extra_large_texture_uploads" + }, + { + "duration": "30.0", + "name": "rendering.mobile/facebook_2018" + }, + { + "duration": "25.0", + "name": "rendering.mobile/facebook_desktop_gpu_raster_2018" + }, + { + "duration": "53.0", + "name": "rendering.mobile/facebook_mobile_2018" + }, + { + "duration": "26.0", + "name": "rendering.mobile/fill_shapes" + }, + { + "duration": "45.0", + "name": "rendering.mobile/filter_terrain_svg" + }, + { + "duration": "46.0", + "name": "rendering.mobile/flickr_scroll_2018" + }, + { + "duration": "25.0", + "name": "rendering.mobile/font_wipe" + }, + { + "duration": "33.0", + "name": "rendering.mobile/forecast.io_mobile_2018" + }, + { + "duration": "24.0", + "name": "rendering.mobile/geo_apis" + }, + { + "duration": "38.0", + "name": "rendering.mobile/gmail_2018" + }, + { + "duration": "35.0", + "name": "rendering.mobile/gmail_desktop_gpu_raster_2018" + }, + { + "duration": "41.0", + "name": "rendering.mobile/google_calendar_2018" + }, + { + "duration": "41.0", + "name": "rendering.mobile/google_calendar_desktop_gpu_raster_2018" + }, + { + "duration": "45.0", + "name": "rendering.mobile/google_docs_2018" + }, + { + "duration": "44.0", + "name": "rendering.mobile/google_docs_desktop_gpu_raster_2018" + }, + { + "duration": "33.0", + "name": "rendering.mobile/google_image_search_2018" + }, + { + "duration": "33.0", + "name": "rendering.mobile/google_image_search_desktop_gpu_raster_2018" + }, + { + "duration": "38.0", + "name": "rendering.mobile/google_image_search_mobile_2018" + }, + { + "duration": "28.0", + "name": "rendering.mobile/google_news_ios" + }, + { + "duration": "44.0", + "name": "rendering.mobile/google_news_mobile_2018" + }, + { + "duration": "42.0", + "name": "rendering.mobile/google_plus_2018" + }, + { + "duration": "38.0", + "name": "rendering.mobile/google_plus_desktop_gpu_raster_2018" + }, + { + "duration": "48.0", + "name": "rendering.mobile/google_plus_mobile_2018" + }, + { + "duration": "28.0", + "name": "rendering.mobile/google_web_search_2018" + }, + { + "duration": "24.0", + "name": "rendering.mobile/google_web_search_desktop_gpu_raster_2018" + }, + { + "duration": "34.0", + "name": "rendering.mobile/google_web_search_mobile_2018" + }, + { + "duration": "37.0", + "name": "rendering.mobile/gsp.ro_mobile_2018" + }, + { + "duration": "45.0", + "name": "rendering.mobile/guardian_pathological_2018" + }, + { + "duration": "38.0", + "name": "rendering.mobile/guimark_vector_chart" + }, + { + "duration": "26.0", + "name": "rendering.mobile/gws_boogie_expansion" + }, + { + "duration": "27.0", + "name": "rendering.mobile/gws_google_expansion" + }, + { + "duration": "31.0", + "name": "rendering.mobile/hakim" + }, + { + "duration": "31.0", + "name": "rendering.mobile/horizontal_vertical_expansion" + }, + { + "duration": "47.0", + "name": "rendering.mobile/idle_power_animated_gif" + }, + { + "duration": "38.0", + "name": "rendering.mobile/idle_power_blank" + }, + { + "duration": "52.0", + "name": "rendering.mobile/idle_power_css_animation" + }, + { + "duration": "57.0", + "name": "rendering.mobile/idle_power_request_animation_frame" + }, + { + "duration": "145.0", + "name": "rendering.mobile/idle_power_set_timeout_long" + }, + { + "duration": "56.0", + "name": "rendering.mobile/idle_power_set_timetout" + }, + { + "duration": "53.0", + "name": "rendering.mobile/ie_chalkboard" + }, + { + "duration": "54.0", + "name": "rendering.mobile/ie_pirate_mark" + }, + { + "duration": "38.0", + "name": "rendering.mobile/infinite_scroll_element_n_layers_0" + }, + { + "duration": "39.0", + "name": "rendering.mobile/infinite_scroll_element_n_layers_75" + }, + { + "duration": "39.0", + "name": "rendering.mobile/infinite_scroll_element_n_layers_99" + }, + { + "duration": "39.0", + "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_0" + }, + { + "duration": "39.0", + "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_75" + }, + { + "duration": "39.0", + "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_99" + }, + { + "duration": "37.0", + "name": "rendering.mobile/infinite_scroll_root_n_layers_0" + }, + { + "duration": "38.0", + "name": "rendering.mobile/infinite_scroll_root_n_layers_75" + }, + { + "duration": "38.0", + "name": "rendering.mobile/infinite_scroll_root_n_layers_99" + }, + { + "duration": "34.0", + "name": "rendering.mobile/infinite_scrolling" + }, + { + "duration": "36.0", + "name": "rendering.mobile/jarro_doverson" + }, + { + "duration": "70.0", + "name": "rendering.mobile/js_full_screen_invalidation" + }, + { + "duration": "51.0", + "name": "rendering.mobile/js_opacity_plus_n_layers_0" + }, + { + "duration": "78.0", + "name": "rendering.mobile/js_opacity_plus_n_layers_75" + }, + { + "duration": "52.0", + "name": "rendering.mobile/js_opacity_plus_n_layers_99" + }, + { + "duration": "51.0", + "name": "rendering.mobile/js_paint_plus_n_layers_0" + }, + { + "duration": "52.0", + "name": "rendering.mobile/js_paint_plus_n_layers_75" + }, + { + "duration": "51.0", + "name": "rendering.mobile/js_paint_plus_n_layers_99" + }, + { + "duration": "52.0", + "name": "rendering.mobile/js_poster_circle" + }, + { + "duration": "21.0", + "name": "rendering.mobile/js_scroll_text_only" + }, + { + "duration": "35.0", + "name": "rendering.mobile/keyframed_animations" + }, + { + "duration": "30.0", + "name": "rendering.mobile/large_texture_uploads" + }, + { + "duration": "56.0", + "name": "rendering.mobile/latimes_pathological_2018" + }, + { + "duration": "64.0", + "name": "rendering.mobile/linkedin_2018" + }, + { + "duration": "60.0", + "name": "rendering.mobile/linkedin_desktop_gpu_raster_2018" + }, + { + "duration": "87.0", + "name": "rendering.mobile/linkedin_mobile_2018" + }, + { + "duration": "55.0", + "name": "rendering.mobile/linkedin_pathological_2018" + }, + { + "duration": "26.0", + "name": "rendering.mobile/list_animation_simple" + }, + { + "duration": "37.0", + "name": "rendering.mobile/list_recycle_transform" + }, + { + "duration": "28.0", + "name": "rendering.mobile/man_in_blue" + }, + { + "duration": "38.0", + "name": "rendering.mobile/many_images" + }, + { + "duration": "15.0", + "name": "rendering.mobile/many_planets_deep" + }, + { + "duration": "30.0", + "name": "rendering.mobile/mask_transition_animation" + }, + { + "duration": "34.0", + "name": "rendering.mobile/medium_texture_uploads" + }, + { + "duration": "28.0", + "name": "rendering.mobile/megi_dish" + }, + { + "duration": "35.0", + "name": "rendering.mobile/microsoft_asteroid_belt" + }, + { + "duration": "25.0", + "name": "rendering.mobile/microsoft_fish_ie_tank" + }, + { + "duration": "37.0", + "name": "rendering.mobile/microsoft_snow" + }, + { + "duration": "26.0", + "name": "rendering.mobile/microsoft_speed_reading" + }, + { + "duration": "32.0", + "name": "rendering.mobile/microsoft_tweet_map" + }, + { + "duration": "71.0", + "name": "rendering.mobile/microsoft_video_city" + }, + { + "duration": "26.0", + "name": "rendering.mobile/microsoft_worker_fountains" + }, + { + "duration": "28.0", + "name": "rendering.mobile/mix_10k" + }, + { + "duration": "64.0", + "name": "rendering.mobile/mix_blend_mode_animation_difference" + }, + { + "duration": "63.0", + "name": "rendering.mobile/mix_blend_mode_animation_hue" + }, + { + "duration": "40.0", + "name": "rendering.mobile/mix_blend_mode_animation_propagating_isolation" + }, + { + "duration": "38.0", + "name": "rendering.mobile/mix_blend_mode_animation_screen" + }, + { + "duration": "50.0", + "name": "rendering.mobile/mlb_mobile_2018" + }, + { + "duration": "23.0", + "name": "rendering.mobile/mobile_news_sandbox" + }, + { + "duration": "30.0", + "name": "rendering.mobile/motion_mark_canvas_fill_shapes" + }, + { + "duration": "29.0", + "name": "rendering.mobile/motion_mark_canvas_stroke_shapes" + }, + { + "duration": "29.0", + "name": "rendering.mobile/motionmark_anim_design_15" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_anim_focus_25" + }, + { + "duration": "30.0", + "name": "rendering.mobile/motionmark_anim_images_50" + }, + { + "duration": "29.0", + "name": "rendering.mobile/motionmark_anim_leaves_250" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_anim_multiply_175" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_anim_suits_125" + }, + { + "duration": "29.0", + "name": "rendering.mobile/motionmark_html_composited_transforms_125" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_html_css_bouncing_blend_circles_25" + }, + { + "duration": "29.0", + "name": "rendering.mobile/motionmark_html_css_bouncing_circles_250" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_html_css_bouncing_clipped_rects_100" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_html_css_bouncing_filter_circles_15" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_html_css_bouncing_gradient_circles_250" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_html_css_bouncing_svg_images_50" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_html_css_bouncing_tagged_images_225" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_html_dom_particles_svg_masks_25" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_html_focus_20_15" + }, + { + "duration": "32.0", + "name": "rendering.mobile/motionmark_html_leaves_20_50" + }, + { + "duration": "29.0", + "name": "rendering.mobile/motionmark_svg_bouncing_circles_250" + }, + { + "duration": "28.0", + "name": "rendering.mobile/motionmark_svg_bouncing_clipped_rects_100" + }, + { + "duration": "29.0", + "name": "rendering.mobile/motionmark_svg_bouncing_gradient_circles_200" + }, + { + "duration": "29.0", + "name": "rendering.mobile/motionmark_svg_bouncing_png_images_200" + }, + { + "duration": "38.0", + "name": "rendering.mobile/motionmark_svg_bouncing_svg_images_50" + }, + { + "duration": "45.0", + "name": "rendering.mobile/new_tilings" + }, + { + "duration": "27.0", + "name": "rendering.mobile/no_op_raf" + }, + { + "duration": "26.0", + "name": "rendering.mobile/no_op_scroll" + }, + { + "duration": "23.0", + "name": "rendering.mobile/no_op_settimeout" + }, + { + "duration": "28.0", + "name": "rendering.mobile/no_op_touch_handler" + }, + { + "duration": "15.0", + "name": "rendering.mobile/nvidia_vertex_buffer_object" + }, + { + "duration": "50.0", + "name": "rendering.mobile/nyc_gov_scroll_2018" + }, + { + "duration": "60.0", + "name": "rendering.mobile/nytimes_mobile_2018" + }, + { + "duration": "58.0", + "name": "rendering.mobile/nytimes_scroll_2018" + }, + { + "duration": "104.0", + "name": "rendering.mobile/overlay_background_color_css_transitions_page" + }, + { + "duration": "37.0", + "name": "rendering.mobile/parallax_effect" + }, + { + "duration": "15.0", + "name": "rendering.mobile/particles" + }, + { + "duration": "37.0", + "name": "rendering.mobile/pbs_pathological_2018" + }, + { + "duration": "23.0", + "name": "rendering.mobile/physical_simulation" + }, + { + "duration": "47.0", + "name": "rendering.mobile/pinterest_2018" + }, + { + "duration": "43.0", + "name": "rendering.mobile/pinterest_desktop_gpu_raster_2018" + }, + { + "duration": "26.0", + "name": "rendering.mobile/pinterest_mobile_2018" + }, + { + "duration": "26.0", + "name": "rendering.mobile/put_get_image_data" + }, + { + "duration": "39.0", + "name": "rendering.mobile/raf" + }, + { + "duration": "39.0", + "name": "rendering.mobile/raf_animation" + }, + { + "duration": "38.0", + "name": "rendering.mobile/raf_canvas" + }, + { + "duration": "39.0", + "name": "rendering.mobile/raf_touch_animation" + }, + { + "duration": "45.0", + "name": "rendering.mobile/recode_pathological_2018" + }, + { + "duration": "34.0", + "name": "rendering.mobile/reddit_mobile_2018" + }, + { + "duration": "27.0", + "name": "rendering.mobile/runway" + }, + { + "duration": "15.0", + "name": "rendering.mobile/san_angeles" + }, + { + "duration": "23.0", + "name": "rendering.mobile/second_batch_js_heavy" + }, + { + "duration": "21.0", + "name": "rendering.mobile/second_batch_js_light" + }, + { + "duration": "21.0", + "name": "rendering.mobile/second_batch_js_medium" + }, + { + "duration": "53.0", + "name": "rendering.mobile/sfgate_mobile_2018" + }, + { + "duration": "48.0", + "name": "rendering.mobile/silk_finance" + }, + { + "duration": "31.0", + "name": "rendering.mobile/simple_text_page" + }, + { + "duration": "23.0", + "name": "rendering.mobile/simple_touch_drag" + }, + { + "duration": "54.0", + "name": "rendering.mobile/slashdot_mobile_2018" + }, + { + "duration": "43.0", + "name": "rendering.mobile/small_texture_uploads" + }, + { + "duration": "29.0", + "name": "rendering.mobile/spielzeugz" + }, + { + "duration": "24.0", + "name": "rendering.mobile/sticky_using_webkit" + }, + { + "duration": "49.0", + "name": "rendering.mobile/stress_hidey_bars" + }, + { + "duration": "26.0", + "name": "rendering.mobile/stroke_shapes" + }, + { + "duration": "37.0", + "name": "rendering.mobile/svg_icon_raster" + }, + { + "duration": "39.0", + "name": "rendering.mobile/swipe_to_dismiss" + }, + { + "duration": "29.0", + "name": "rendering.mobile/sync_scroll_offset" + }, + { + "duration": "52.0", + "name": "rendering.mobile/techcrunch_2018" + }, + { + "duration": "48.0", + "name": "rendering.mobile/techcrunch_desktop_gpu_raster_2018" + }, + { + "duration": "54.0", + "name": "rendering.mobile/techcrunch_mobile_2018" + }, + { + "duration": "31.0", + "name": "rendering.mobile/text_05000_pixels_per_second" + }, + { + "duration": "31.0", + "name": "rendering.mobile/text_05000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "32.0", + "name": "rendering.mobile/text_10000_pixels_per_second" + }, + { + "duration": "32.0", + "name": "rendering.mobile/text_10000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "27.0", + "name": "rendering.mobile/text_15000_pixels_per_second" + }, + { + "duration": "27.0", + "name": "rendering.mobile/text_15000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "24.0", + "name": "rendering.mobile/text_20000_pixels_per_second" + }, + { + "duration": "24.0", + "name": "rendering.mobile/text_20000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "22.0", + "name": "rendering.mobile/text_30000_pixels_per_second" + }, + { + "duration": "22.0", + "name": "rendering.mobile/text_30000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "20.0", + "name": "rendering.mobile/text_40000_pixels_per_second" + }, + { + "duration": "21.0", + "name": "rendering.mobile/text_40000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "20.0", + "name": "rendering.mobile/text_50000_pixels_per_second" + }, + { + "duration": "20.0", + "name": "rendering.mobile/text_50000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "19.0", + "name": "rendering.mobile/text_60000_pixels_per_second" + }, + { + "duration": "19.0", + "name": "rendering.mobile/text_60000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "19.0", + "name": "rendering.mobile/text_75000_pixels_per_second" + }, + { + "duration": "19.0", + "name": "rendering.mobile/text_75000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_90000_pixels_per_second" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_90000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "33.0", + "name": "rendering.mobile/text_constant_full_page_raster_05000_pixels_per_second" + }, + { + "duration": "33.0", + "name": "rendering.mobile/text_constant_full_page_raster_05000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "33.0", + "name": "rendering.mobile/text_constant_full_page_raster_10000_pixels_per_second" + }, + { + "duration": "33.0", + "name": "rendering.mobile/text_constant_full_page_raster_10000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "29.0", + "name": "rendering.mobile/text_constant_full_page_raster_15000_pixels_per_second" + }, + { + "duration": "28.0", + "name": "rendering.mobile/text_constant_full_page_raster_15000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "26.0", + "name": "rendering.mobile/text_constant_full_page_raster_20000_pixels_per_second" + }, + { + "duration": "26.0", + "name": "rendering.mobile/text_constant_full_page_raster_20000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "24.0", + "name": "rendering.mobile/text_constant_full_page_raster_30000_pixels_per_second" + }, + { + "duration": "24.0", + "name": "rendering.mobile/text_constant_full_page_raster_30000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "23.0", + "name": "rendering.mobile/text_constant_full_page_raster_40000_pixels_per_second" + }, + { + "duration": "23.0", + "name": "rendering.mobile/text_constant_full_page_raster_40000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "22.0", + "name": "rendering.mobile/text_constant_full_page_raster_50000_pixels_per_second" + }, + { + "duration": "22.0", + "name": "rendering.mobile/text_constant_full_page_raster_50000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "22.0", + "name": "rendering.mobile/text_constant_full_page_raster_60000_pixels_per_second" + }, + { + "duration": "22.0", + "name": "rendering.mobile/text_constant_full_page_raster_60000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "21.0", + "name": "rendering.mobile/text_constant_full_page_raster_75000_pixels_per_second" + }, + { + "duration": "21.0", + "name": "rendering.mobile/text_constant_full_page_raster_75000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "21.0", + "name": "rendering.mobile/text_constant_full_page_raster_90000_pixels_per_second" + }, + { + "duration": "21.0", + "name": "rendering.mobile/text_constant_full_page_raster_90000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "24.0", + "name": "rendering.mobile/text_hover_05000_pixels_per_second" + }, + { + "duration": "24.0", + "name": "rendering.mobile/text_hover_05000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "24.0", + "name": "rendering.mobile/text_hover_10000_pixels_per_second" + }, + { + "duration": "24.0", + "name": "rendering.mobile/text_hover_10000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "22.0", + "name": "rendering.mobile/text_hover_15000_pixels_per_second" + }, + { + "duration": "22.0", + "name": "rendering.mobile/text_hover_15000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "21.0", + "name": "rendering.mobile/text_hover_20000_pixels_per_second" + }, + { + "duration": "21.0", + "name": "rendering.mobile/text_hover_20000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "19.0", + "name": "rendering.mobile/text_hover_30000_pixels_per_second" + }, + { + "duration": "19.0", + "name": "rendering.mobile/text_hover_30000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "19.0", + "name": "rendering.mobile/text_hover_40000_pixels_per_second" + }, + { + "duration": "19.0", + "name": "rendering.mobile/text_hover_40000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_hover_50000_pixels_per_second" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_hover_50000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_hover_60000_pixels_per_second" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_hover_60000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_hover_75000_pixels_per_second" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_hover_75000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_hover_90000_pixels_per_second" + }, + { + "duration": "18.0", + "name": "rendering.mobile/text_hover_90000_pixels_per_second_desktop_gpu_raster" + }, + { + "duration": "45.0", + "name": "rendering.mobile/theverge_article_mobile_2018" + }, + { + "duration": "51.0", + "name": "rendering.mobile/theverge_mobile_2018" + }, + { + "duration": "29.0", + "name": "rendering.mobile/toggle_drawer" + }, + { + "duration": "32.0", + "name": "rendering.mobile/touch_handler_scrolling" + }, + { + "duration": "39.0", + "name": "rendering.mobile/transform_transitions" + }, + { + "duration": "33.0", + "name": "rendering.mobile/transform_transitions_js_block" + }, + { + "duration": "50.0", + "name": "rendering.mobile/twitch_2018" + }, + { + "duration": "46.0", + "name": "rendering.mobile/twitch_desktop_gpu_raster_2018" + }, + { + "duration": "46.0", + "name": "rendering.mobile/twitter_2018" + }, + { + "duration": "46.0", + "name": "rendering.mobile/twitter_desktop_gpu_raster_2018" + }, + { + "duration": "29.0", + "name": "rendering.mobile/twitter_mobile_2018" + }, + { + "duration": "35.0", + "name": "rendering.mobile/update_history_state" + }, + { + "duration": "32.0", + "name": "rendering.mobile/usatoday_mobile_2018" + }, + { + "duration": "38.0", + "name": "rendering.mobile/vertical_expansion" + }, + { + "duration": "35.0", + "name": "rendering.mobile/web_animation_value_type_color" + }, + { + "duration": "31.0", + "name": "rendering.mobile/web_animation_value_type_length_3d" + }, + { + "duration": "34.0", + "name": "rendering.mobile/web_animation_value_type_length_complex" + }, + { + "duration": "34.0", + "name": "rendering.mobile/web_animation_value_type_length_simple" + }, + { + "duration": "41.0", + "name": "rendering.mobile/web_animation_value_type_path" + }, + { + "duration": "57.0", + "name": "rendering.mobile/web_animation_value_type_shadow" + }, + { + "duration": "31.0", + "name": "rendering.mobile/web_animation_value_type_transform_complex" + }, + { + "duration": "31.0", + "name": "rendering.mobile/web_animation_value_type_transform_simple" + }, + { + "duration": "51.0", + "name": "rendering.mobile/web_animations_many_keyframes" + }, + { + "duration": "31.0", + "name": "rendering.mobile/web_animations_set_current_time" + }, + { + "duration": "36.0", + "name": "rendering.mobile/web_animations_simultaneous" + }, + { + "duration": "43.0", + "name": "rendering.mobile/web_animations_staggered_chaining" + }, + { + "duration": "36.0", + "name": "rendering.mobile/web_animations_staggered_infinite_iterations" + }, + { + "duration": "45.0", + "name": "rendering.mobile/web_animations_staggered_triggering_page" + }, + { + "duration": "48.0", + "name": "rendering.mobile/wikipedia_2018" + }, + { + "duration": "49.0", + "name": "rendering.mobile/wikipedia_delayed_scroll_start_2018" + }, + { + "duration": "43.0", + "name": "rendering.mobile/wikipedia_desktop_gpu_raster_2018" + }, + { + "duration": "41.0", + "name": "rendering.mobile/wikipedia_mobile_2018" + }, + { + "duration": "49.0", + "name": "rendering.mobile/wordpress_2018" + }, + { + "duration": "45.0", + "name": "rendering.mobile/wordpress_desktop_gpu_raster_2018" + }, + { + "duration": "47.0", + "name": "rendering.mobile/wordpress_mobile_2018" + }, + { + "duration": "43.0", + "name": "rendering.mobile/worldjournal_mobile_2018" + }, + { + "duration": "51.0", + "name": "rendering.mobile/wow_wiki_pathological_2018" + }, + { + "duration": "86.0", + "name": "rendering.mobile/wowwiki_mobile_2018" + }, + { + "duration": "57.0", + "name": "rendering.mobile/wsj_mobile_2018" + }, + { + "duration": "28.0", + "name": "rendering.mobile/yahoo_answers_2018" + }, + { + "duration": "24.0", + "name": "rendering.mobile/yahoo_answers_desktop_gpu_raster_2018" + }, + { + "duration": "39.0", + "name": "rendering.mobile/yahoo_news_2018" + }, + { + "duration": "37.0", + "name": "rendering.mobile/yahoo_news_desktop_gpu_raster_2018" + }, + { + "duration": "34.0", + "name": "rendering.mobile/yahoo_news_mobile_2018" + }, + { + "duration": "41.0", + "name": "rendering.mobile/yahoo_sports_2018" + }, + { + "duration": "37.0", + "name": "rendering.mobile/yahoo_sports_desktop_gpu_raster_2018" + }, + { + "duration": "28.0", + "name": "rendering.mobile/yahoo_sports_pathological_2018" + }, + { + "duration": "45.0", + "name": "rendering.mobile/youtube_2018" + }, + { + "duration": "40.0", + "name": "rendering.mobile/youtube_desktop_gpu_raster_2018" + }, + { + "duration": "32.0", + "name": "rendering.mobile/youtube_mobile_2018" + }, + { + "duration": "75.0", + "name": "rendering.mobile/yuv_decoding" + }, + { + "duration": "76.0", + "name": "rendering.mobile/yuv_decoding_gpu_rasterization_and_decoding" + }, + { + "duration": "37.0", + "name": "rendering.mobile/zdnet_pathological_2018" + }, + { + "duration": "31.0", + "name": "rendering.mobile/zoom_in_animation" + }, + { + "duration": "70.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/accu_weather_pinch_2018" + }, + { + "duration": "46.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/amazon_pinch_2018" + }, + { + "duration": "33.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/blogspot_pinch_2018" + }, + { + "duration": "46.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/booking_pinch_2018" + }, + { + "duration": "46.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/cnn_pinch_2018" + }, + { + "duration": "34.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/ebay_pinch_2018" + }, + { + "duration": "49.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/espn_pinch_2018" + }, + { + "duration": "59.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/facebook_pinch_2018" + }, + { + "duration": "91.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/gmail_pinch_2018" + }, + { + "duration": "72.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_calendar_pinch_2018" + }, + { + "duration": "30.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_image_pinch_2018" + }, + { + "duration": "71.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_search_pinch_2018" + }, + { + "duration": "78.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/linkedin_pinch_2018" + }, + { + "duration": "58.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/twitch_pinch_2018" + }, + { + "duration": "41.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/twitter_pinch_2018" + }, + { + "duration": "71.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_news_pinch_2018" + }, + { + "duration": "75.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_sports_pinch_2018" + }, + { + "duration": "107.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/youtube_pinch_2018" + }, + { + "duration": "70.0", + "name": "smoothness.tough_pinch_zoom_cases/accu_weather_pinch_2018" + }, + { + "duration": "44.0", + "name": "smoothness.tough_pinch_zoom_cases/amazon_pinch_2018" + }, + { + "duration": "33.0", + "name": "smoothness.tough_pinch_zoom_cases/blogspot_pinch_2018" + }, + { + "duration": "45.0", + "name": "smoothness.tough_pinch_zoom_cases/booking_pinch_2018" + }, + { + "duration": "46.0", + "name": "smoothness.tough_pinch_zoom_cases/cnn_pinch_2018" + }, + { + "duration": "34.0", + "name": "smoothness.tough_pinch_zoom_cases/ebay_pinch_2018" + }, + { + "duration": "49.0", + "name": "smoothness.tough_pinch_zoom_cases/espn_pinch_2018" + }, + { + "duration": "59.0", + "name": "smoothness.tough_pinch_zoom_cases/facebook_pinch_2018" + }, + { + "duration": "90.0", + "name": "smoothness.tough_pinch_zoom_cases/gmail_pinch_2018" + }, + { + "duration": "72.0", + "name": "smoothness.tough_pinch_zoom_cases/google_calendar_pinch_2018" + }, + { + "duration": "29.0", + "name": "smoothness.tough_pinch_zoom_cases/google_image_pinch_2018" + }, + { + "duration": "71.0", + "name": "smoothness.tough_pinch_zoom_cases/google_search_pinch_2018" + }, + { + "duration": "78.0", + "name": "smoothness.tough_pinch_zoom_cases/linkedin_pinch_2018" + }, + { + "duration": "59.0", + "name": "smoothness.tough_pinch_zoom_cases/twitch_pinch_2018" + }, + { + "duration": "40.0", + "name": "smoothness.tough_pinch_zoom_cases/twitter_pinch_2018" + }, + { + "duration": "71.0", + "name": "smoothness.tough_pinch_zoom_cases/yahoo_news_pinch_2018" + }, + { + "duration": "77.0", + "name": "smoothness.tough_pinch_zoom_cases/yahoo_sports_pinch_2018" + }, + { + "duration": "107.0", + "name": "smoothness.tough_pinch_zoom_cases/youtube_pinch_2018" + }, + { + "duration": "150.0", + "name": "speedometer-future/http://browserbench.org/Speedometer/" + }, + { + "duration": "148.0", + "name": "speedometer/http://browserbench.org/Speedometer/" + }, + { + "duration": "267.0", + "name": "speedometer2-future/Speedometer2" + }, + { + "duration": "266.0", + "name": "speedometer2/Speedometer2" + }, + { + "duration": "28.0", + "name": "system_health.common_mobile/background:media:imgur" + }, + { + "duration": "61.0", + "name": "system_health.common_mobile/background:news:nytimes" + }, + { + "duration": "64.0", + "name": "system_health.common_mobile/background:search:google" + }, + { + "duration": "56.0", + "name": "system_health.common_mobile/background:social:facebook" + }, + { + "duration": "13.0", + "name": "system_health.common_mobile/browse:chrome:newtab" + }, + { + "duration": "12.0", + "name": "system_health.common_mobile/browse:chrome:omnibox" + }, + { + "duration": "123.0", + "name": "system_health.common_mobile/browse:media:facebook_photos" + }, + { + "duration": "75.0", + "name": "system_health.common_mobile/browse:media:flickr_infinite_scroll" + }, + { + "duration": "99.0", + "name": "system_health.common_mobile/browse:media:imgur" + }, + { + "duration": "157.0", + "name": "system_health.common_mobile/browse:media:youtube" + }, + { + "duration": "242.0", + "name": "system_health.common_mobile/browse:news:cnn" + }, + { + "duration": "208.0", + "name": "system_health.common_mobile/browse:news:cnn:2018" + }, + { + "duration": "89.0", + "name": "system_health.common_mobile/browse:news:cricbuzz" + }, + { + "duration": "109.0", + "name": "system_health.common_mobile/browse:news:qq" + }, + { + "duration": "109.0", + "name": "system_health.common_mobile/browse:news:reddit" + }, + { + "duration": "71.0", + "name": "system_health.common_mobile/browse:news:washingtonpost" + }, + { + "duration": "108.0", + "name": "system_health.common_mobile/browse:shopping:amazon" + }, + { + "duration": "115.0", + "name": "system_health.common_mobile/browse:shopping:avito" + }, + { + "duration": "52.0", + "name": "system_health.common_mobile/browse:shopping:lazada" + }, + { + "duration": "95.0", + "name": "system_health.common_mobile/browse:social:facebook" + }, + { + "duration": "151.0", + "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll" + }, + { + "duration": "172.0", + "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll:2018" + }, + { + "duration": "118.0", + "name": "system_health.common_mobile/browse:social:instagram" + }, + { + "duration": "123.0", + "name": "system_health.common_mobile/browse:social:pinterest_infinite_scroll" + }, + { + "duration": "152.0", + "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll" + }, + { + "duration": "75.0", + "name": "system_health.common_mobile/browse:social:twitter" + }, + { + "duration": "136.0", + "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll" + }, + { + "duration": "164.0", + "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll:2018" + }, + { + "duration": "62.0", + "name": "system_health.common_mobile/browse:tools:maps" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:chrome:blank" + }, + { + "duration": "35.0", + "name": "system_health.common_mobile/load:games:bubbles" + }, + { + "duration": "25.0", + "name": "system_health.common_mobile/load:games:lazors" + }, + { + "duration": "51.0", + "name": "system_health.common_mobile/load:games:spychase" + }, + { + "duration": "50.0", + "name": "system_health.common_mobile/load:games:spychase:2018" + }, + { + "duration": "33.0", + "name": "system_health.common_mobile/load:media:dailymotion" + }, + { + "duration": "29.0", + "name": "system_health.common_mobile/load:media:facebook_photos" + }, + { + "duration": "74.0", + "name": "system_health.common_mobile/load:media:flickr:2018" + }, + { + "duration": "29.0", + "name": "system_health.common_mobile/load:media:google_images" + }, + { + "duration": "31.0", + "name": "system_health.common_mobile/load:media:google_images:2018" + }, + { + "duration": "29.0", + "name": "system_health.common_mobile/load:media:imgur" + }, + { + "duration": "46.0", + "name": "system_health.common_mobile/load:media:imgur:2018" + }, + { + "duration": "28.0", + "name": "system_health.common_mobile/load:media:soundcloud:2018" + }, + { + "duration": "30.0", + "name": "system_health.common_mobile/load:media:youtube" + }, + { + "duration": "38.0", + "name": "system_health.common_mobile/load:media:youtube:2018" + }, + { + "duration": "64.0", + "name": "system_health.common_mobile/load:news:cnn" + }, + { + "duration": "59.0", + "name": "system_health.common_mobile/load:news:cnn:2018" + }, + { + "duration": "48.0", + "name": "system_health.common_mobile/load:news:irctc" + }, + { + "duration": "38.0", + "name": "system_health.common_mobile/load:news:nytimes" + }, + { + "duration": "41.0", + "name": "system_health.common_mobile/load:news:qq" + }, + { + "duration": "31.0", + "name": "system_health.common_mobile/load:news:reddit" + }, + { + "duration": "33.0", + "name": "system_health.common_mobile/load:news:washingtonpost" + }, + { + "duration": "31.0", + "name": "system_health.common_mobile/load:news:wikipedia" + }, + { + "duration": "28.0", + "name": "system_health.common_mobile/load:news:wikipedia:2018" + }, + { + "duration": "42.0", + "name": "system_health.common_mobile/load:search:baidu" + }, + { + "duration": "47.0", + "name": "system_health.common_mobile/load:search:baidu:2018" + }, + { + "duration": "31.0", + "name": "system_health.common_mobile/load:search:ebay" + }, + { + "duration": "36.0", + "name": "system_health.common_mobile/load:search:ebay:2018" + }, + { + "duration": "26.0", + "name": "system_health.common_mobile/load:search:google" + }, + { + "duration": "30.0", + "name": "system_health.common_mobile/load:search:google:2018" + }, + { + "duration": "33.0", + "name": "system_health.common_mobile/load:search:taobao" + }, + { + "duration": "26.0", + "name": "system_health.common_mobile/load:search:yahoo" + }, + { + "duration": "26.0", + "name": "system_health.common_mobile/load:search:yahoo:2018" + }, + { + "duration": "28.0", + "name": "system_health.common_mobile/load:search:yandex" + }, + { + "duration": "31.0", + "name": "system_health.common_mobile/load:search:yandex:2018" + }, + { + "duration": "28.0", + "name": "system_health.common_mobile/load:social:twitter" + }, + { + "duration": "27.0", + "name": "system_health.common_mobile/load:tools:docs" + }, + { + "duration": "35.0", + "name": "system_health.common_mobile/load:tools:drive" + }, + { + "duration": "26.0", + "name": "system_health.common_mobile/load:tools:dropbox" + }, + { + "duration": "29.0", + "name": "system_health.common_mobile/load:tools:stackoverflow" + }, + { + "duration": "31.0", + "name": "system_health.common_mobile/load:tools:stackoverflow:2018" + }, + { + "duration": "44.0", + "name": "system_health.common_mobile/load:tools:weather" + }, + { + "duration": "31.0", + "name": "system_health.memory_mobile/background:media:imgur" + }, + { + "duration": "37.0", + "name": "system_health.memory_mobile/background:search:google" + }, + { + "duration": "39.0", + "name": "system_health.memory_mobile/background:social:facebook" + }, + { + "duration": "15.0", + "name": "system_health.memory_mobile/browse:chrome:newtab" + }, + { + "duration": "102.0", + "name": "system_health.memory_mobile/browse:media:facebook_photos" + }, + { + "duration": "74.0", + "name": "system_health.memory_mobile/browse:media:flickr_infinite_scroll" + }, + { + "duration": "82.0", + "name": "system_health.memory_mobile/browse:media:imgur" + }, + { + "duration": "99.0", + "name": "system_health.memory_mobile/browse:media:youtube" + }, + { + "duration": "81.0", + "name": "system_health.memory_mobile/browse:news:cricbuzz" + }, + { + "duration": "96.0", + "name": "system_health.memory_mobile/browse:news:qq" + }, + { + "duration": "80.0", + "name": "system_health.memory_mobile/browse:news:reddit" + }, + { + "duration": "167.0", + "name": "system_health.memory_mobile/browse:news:toi" + }, + { + "duration": "59.0", + "name": "system_health.memory_mobile/browse:news:washingtonpost" + }, + { + "duration": "77.0", + "name": "system_health.memory_mobile/browse:shopping:amazon" + }, + { + "duration": "87.0", + "name": "system_health.memory_mobile/browse:shopping:avito" + }, + { + "duration": "47.0", + "name": "system_health.memory_mobile/browse:shopping:lazada" + }, + { + "duration": "79.0", + "name": "system_health.memory_mobile/browse:social:facebook" + }, + { + "duration": "97.0", + "name": "system_health.memory_mobile/browse:social:facebook_infinite_scroll:2018" + }, + { + "duration": "100.0", + "name": "system_health.memory_mobile/browse:social:instagram" + }, + { + "duration": "94.0", + "name": "system_health.memory_mobile/browse:social:pinterest_infinite_scroll" + }, + { + "duration": "63.0", + "name": "system_health.memory_mobile/browse:social:twitter" + }, + { + "duration": "77.0", + "name": "system_health.memory_mobile/browse:tech:discourse_infinite_scroll" + }, + { + "duration": "59.0", + "name": "system_health.memory_mobile/browse:tools:maps" + }, + { + "duration": "29.0", + "name": "system_health.memory_mobile/load:chrome:blank" + }, + { + "duration": "33.0", + "name": "system_health.memory_mobile/load:games:bubbles" + }, + { + "duration": "30.0", + "name": "system_health.memory_mobile/load:games:lazors" + }, + { + "duration": "40.0", + "name": "system_health.memory_mobile/load:games:spychase" + }, + { + "duration": "40.0", + "name": "system_health.memory_mobile/load:games:spychase:2018" + }, + { + "duration": "37.0", + "name": "system_health.memory_mobile/load:media:dailymotion" + }, + { + "duration": "33.0", + "name": "system_health.memory_mobile/load:media:facebook_photos" + }, + { + "duration": "44.0", + "name": "system_health.memory_mobile/load:media:flickr:2018" + }, + { + "duration": "32.0", + "name": "system_health.memory_mobile/load:media:google_images" + }, + { + "duration": "35.0", + "name": "system_health.memory_mobile/load:media:google_images:2018" + }, + { + "duration": "32.0", + "name": "system_health.memory_mobile/load:media:imgur" + }, + { + "duration": "41.0", + "name": "system_health.memory_mobile/load:media:imgur:2018" + }, + { + "duration": "32.0", + "name": "system_health.memory_mobile/load:media:soundcloud:2018" + }, + { + "duration": "33.0", + "name": "system_health.memory_mobile/load:media:youtube" + }, + { + "duration": "35.0", + "name": "system_health.memory_mobile/load:media:youtube:2018" + }, + { + "duration": "58.0", + "name": "system_health.memory_mobile/load:news:cnn" + }, + { + "duration": "52.0", + "name": "system_health.memory_mobile/load:news:cnn:2018" + }, + { + "duration": "39.0", + "name": "system_health.memory_mobile/load:news:irctc" + }, + { + "duration": "39.0", + "name": "system_health.memory_mobile/load:news:nytimes" + }, + { + "duration": "55.0", + "name": "system_health.memory_mobile/load:news:qq" + }, + { + "duration": "35.0", + "name": "system_health.memory_mobile/load:news:reddit" + }, + { + "duration": "35.0", + "name": "system_health.memory_mobile/load:news:washingtonpost" + }, + { + "duration": "35.0", + "name": "system_health.memory_mobile/load:news:wikipedia" + }, + { + "duration": "33.0", + "name": "system_health.memory_mobile/load:news:wikipedia:2018" + }, + { + "duration": "46.0", + "name": "system_health.memory_mobile/load:search:baidu" + }, + { + "duration": "47.0", + "name": "system_health.memory_mobile/load:search:baidu:2018" + }, + { + "duration": "32.0", + "name": "system_health.memory_mobile/load:search:ebay" + }, + { + "duration": "35.0", + "name": "system_health.memory_mobile/load:search:ebay:2018" + }, + { + "duration": "31.0", "name": "system_health.memory_mobile/load:search:google" }, { "duration": "34.0", + "name": "system_health.memory_mobile/load:search:google:2018" + }, + { + "duration": "36.0", "name": "system_health.memory_mobile/load:search:taobao" }, { - "duration": "33.0", + "duration": "31.0", "name": "system_health.memory_mobile/load:search:yahoo" }, { - "duration": "45.0", + "duration": "30.0", + "name": "system_health.memory_mobile/load:search:yahoo:2018" + }, + { + "duration": "32.0", "name": "system_health.memory_mobile/load:search:yandex" }, { "duration": "34.0", - "name": "system_health.memory_mobile/load:social:twitter" - }, - { - "duration": "33.0", - "name": "system_health.memory_mobile/load:tools:docs" + "name": "system_health.memory_mobile/load:search:yandex:2018" }, { "duration": "32.0", - "name": "system_health.memory_mobile/load:tools:dropbox" + "name": "system_health.memory_mobile/load:social:twitter" }, { - "duration": "35.0", - "name": "system_health.memory_mobile/load:tools:stackoverflow" - }, - { - "duration": "37.0", - "name": "system_health.memory_mobile/load:tools:stackoverflow:2018" - }, - { - "duration": "46.0", - "name": "system_health.memory_mobile/load:tools:weather" + "duration": "32.0", + "name": "system_health.memory_mobile/load:tools:docs" }, { "duration": "33.0", + "name": "system_health.memory_mobile/load:tools:dropbox" + }, + { + "duration": "34.0", + "name": "system_health.memory_mobile/load:tools:stackoverflow" + }, + { + "duration": "35.0", + "name": "system_health.memory_mobile/load:tools:stackoverflow:2018" + }, + { + "duration": "53.0", + "name": "system_health.memory_mobile/load:tools:weather" + }, + { + "duration": "32.0", "name": "system_health.webview_startup/load:chrome:blank" }, { - "duration": "157.0", - "name": "v8.browsing_mobile/browse:media:facebook_photos" + "duration": "22.0", + "name": "tracing.tracing_with_background_memory_infra/Facebook" }, { - "duration": "99.0", - "name": "v8.browsing_mobile/browse:media:flickr_infinite_scroll" + "duration": "23.0", + "name": "tracing.tracing_with_background_memory_infra/Wikipedia" }, { - "duration": "134.0", - "name": "v8.browsing_mobile/browse:media:imgur" + "duration": "15.0", + "name": "tracing.tracing_with_background_memory_infra/http://www.amazon.com" }, { - "duration": "420.0", - "name": "v8.browsing_mobile/browse:news:cnn:2018" + "duration": "16.0", + "name": "tracing.tracing_with_background_memory_infra/http://www.ask.com/" }, { - "duration": "150.0", - "name": "v8.browsing_mobile/browse:news:cricbuzz" + "duration": "16.0", + "name": "tracing.tracing_with_background_memory_infra/http://www.bing.com/" }, { - "duration": "95.0", - "name": "v8.browsing_mobile/browse:news:qq" + "duration": "17.0", + "name": "tracing.tracing_with_background_memory_infra/http://www.yahoo.com/" + }, + { + "duration": "18.0", + "name": "tracing.tracing_with_background_memory_infra/http://www.youtube.com" + }, + { + "duration": "44.0", + "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/#hl=en&q=barack+obama" + }, + { + "duration": "19.0", + "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/calendar/" + }, + { + "duration": "155.0", + "name": "v8.browsing_mobile-future/browse:media:facebook_photos" + }, + { + "duration": "105.0", + "name": "v8.browsing_mobile-future/browse:media:flickr_infinite_scroll" + }, + { + "duration": "127.0", + "name": "v8.browsing_mobile-future/browse:media:imgur" + }, + { + "duration": "221.0", + "name": "v8.browsing_mobile-future/browse:media:youtube" + }, + { + "duration": "456.0", + "name": "v8.browsing_mobile-future/browse:news:cnn" + }, + { + "duration": "353.0", + "name": "v8.browsing_mobile-future/browse:news:cnn:2018" }, { "duration": "122.0", - "name": "v8.browsing_mobile/browse:news:reddit" + "name": "v8.browsing_mobile-future/browse:news:cricbuzz" + }, + { + "duration": "136.0", + "name": "v8.browsing_mobile-future/browse:news:qq" + }, + { + "duration": "107.0", + "name": "v8.browsing_mobile-future/browse:news:reddit" + }, + { + "duration": "487.0", + "name": "v8.browsing_mobile-future/browse:news:toi" }, { "duration": "95.0", + "name": "v8.browsing_mobile-future/browse:news:washingtonpost" + }, + { + "duration": "183.0", + "name": "v8.browsing_mobile-future/browse:shopping:amazon" + }, + { + "duration": "181.0", + "name": "v8.browsing_mobile-future/browse:shopping:avito" + }, + { + "duration": "70.0", + "name": "v8.browsing_mobile-future/browse:shopping:lazada" + }, + { + "duration": "134.0", + "name": "v8.browsing_mobile-future/browse:social:facebook" + }, + { + "duration": "233.0", + "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll" + }, + { + "duration": "225.0", + "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll:2018" + }, + { + "duration": "192.0", + "name": "v8.browsing_mobile-future/browse:social:instagram" + }, + { + "duration": "193.0", + "name": "v8.browsing_mobile-future/browse:social:pinterest_infinite_scroll" + }, + { + "duration": "257.0", + "name": "v8.browsing_mobile-future/browse:social:tumblr_infinite_scroll" + }, + { + "duration": "88.0", + "name": "v8.browsing_mobile-future/browse:social:twitter" + }, + { + "duration": "173.0", + "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll" + }, + { + "duration": "256.0", + "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll:2018" + }, + { + "duration": "83.0", + "name": "v8.browsing_mobile-future/browse:tools:maps" + }, + { + "duration": "155.0", + "name": "v8.browsing_mobile/browse:media:facebook_photos" + }, + { + "duration": "105.0", + "name": "v8.browsing_mobile/browse:media:flickr_infinite_scroll" + }, + { + "duration": "127.0", + "name": "v8.browsing_mobile/browse:media:imgur" + }, + { + "duration": "354.0", + "name": "v8.browsing_mobile/browse:news:cnn:2018" + }, + { + "duration": "122.0", + "name": "v8.browsing_mobile/browse:news:cricbuzz" + }, + { + "duration": "136.0", + "name": "v8.browsing_mobile/browse:news:qq" + }, + { + "duration": "107.0", + "name": "v8.browsing_mobile/browse:news:reddit" + }, + { + "duration": "96.0", "name": "v8.browsing_mobile/browse:news:washingtonpost" }, { - "duration": "195.0", + "duration": "184.0", "name": "v8.browsing_mobile/browse:shopping:amazon" }, { - "duration": "207.0", + "duration": "215.0", "name": "v8.browsing_mobile/browse:shopping:avito" }, { - "duration": "74.0", + "duration": "70.0", "name": "v8.browsing_mobile/browse:shopping:lazada" }, { - "duration": "145.0", + "duration": "135.0", "name": "v8.browsing_mobile/browse:social:facebook" }, { - "duration": "461.0", + "duration": "236.0", "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll" }, { - "duration": "473.0", + "duration": "258.0", "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll:2018" }, { - "duration": "270.0", + "duration": "192.0", "name": "v8.browsing_mobile/browse:social:instagram" }, { - "duration": "232.0", + "duration": "217.0", "name": "v8.browsing_mobile/browse:social:pinterest_infinite_scroll" }, { - "duration": "230.0", + "duration": "253.0", "name": "v8.browsing_mobile/browse:social:tumblr_infinite_scroll" }, { - "duration": "92.0", + "duration": "90.0", "name": "v8.browsing_mobile/browse:social:twitter" }, { - "duration": "159.0", + "duration": "172.0", "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll" }, { - "duration": "219.0", + "duration": "288.0", "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll:2018" }, { - "duration": "94.0", + "duration": "82.0", "name": "v8.browsing_mobile/browse:tools:maps" + }, + { + "duration": "12.0", + "name": "wasm/AsmJsZenGarden" + }, + { + "duration": "54.0", + "name": "wasm/WasmSpaceBuggy" + }, + { + "duration": "12.0", + "name": "wasm/WasmStylizedRenderer" + }, + { + "duration": "12.0", + "name": "wasm/WasmSunTemple" + }, + { + "duration": "25.0", + "name": "wasm/WasmTanks" + }, + { + "duration": "12.0", + "name": "wasm/WasmZenGarden" + }, + { + "duration": "24.0", + "name": "webrtc/10s_datachannel_transfer" + }, + { + "duration": "35.0", + "name": "webrtc/canvas_capture_peer_connection" + }, + { + "duration": "45.0", + "name": "webrtc/codec_constraints_h264" + }, + { + "duration": "45.0", + "name": "webrtc/codec_constraints_vp8" + }, + { + "duration": "45.0", + "name": "webrtc/codec_constraints_vp9" + }, + { + "duration": "29.0", + "name": "webrtc/hd_local_stream_10s" + }, + { + "duration": "61.0", + "name": "webrtc/multiple_peerconnections" + }, + { + "duration": "100.0", + "name": "webrtc/pause_play_peerconnections" } ] \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/android-nexus5x-perf-fyi_timing.json b/tools/perf/core/shard_maps/timing_data/android-nexus5x-perf-fyi_timing.json index e03862c..6098db7 100644 --- a/tools/perf/core/shard_maps/timing_data/android-nexus5x-perf-fyi_timing.json +++ b/tools/perf/core/shard_maps/timing_data/android-nexus5x-perf-fyi_timing.json
@@ -1,26 +1,22 @@ [ { - "duration": "68.0", + "duration": "66.0", "name": "heap_profiling.mobile.disabled/load:news:cnn" }, { - "duration": "49.0", + "duration": "44.0", "name": "heap_profiling.mobile.disabled/load:search:google" }, { - "duration": "34.0", + "duration": "30.0", "name": "heap_profiling.mobile.disabled/load:social:twitter" }, { - "duration": "72.0", - "name": "heap_profiling.mobile.native/load:news:cnn" - }, - { - "duration": "47.0", + "duration": "43.0", "name": "heap_profiling.mobile.native/load:search:google" }, { - "duration": "33.0", + "duration": "31.0", "name": "heap_profiling.mobile.native/load:social:twitter" } ] \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json index 35daf78..b107227 100644 --- a/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json +++ b/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
@@ -1,10 +1,14 @@ [ { - "duration": "19.0", + "duration": "30.0", + "name": "blink_perf.accessibility/textarea-append.html" + }, + { + "duration": "21.0", "name": "blink_perf.bindings/append-child.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.bindings/create-element.html" }, { @@ -12,19 +16,19 @@ "name": "blink_perf.bindings/document-implementation.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.bindings/dom-attribute-on-prototoype.html" }, { - "duration": "14.0", + "duration": "11.0", "name": "blink_perf.bindings/first-child.html" }, { - "duration": "12.0", + "duration": "10.0", "name": "blink_perf.bindings/gc-forest.html" }, { - "duration": "11.0", + "duration": "13.0", "name": "blink_perf.bindings/gc-mini-tree.html" }, { @@ -32,47 +36,47 @@ "name": "blink_perf.bindings/gc-tree.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.bindings/get-attribute-rare.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.bindings/get-attribute.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.bindings/get-element-by-id.html" }, { - "duration": "10.0", + "duration": "12.0", "name": "blink_perf.bindings/get-elements-by-tag-name.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.bindings/id-getter.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.bindings/id-setter.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.bindings/indexed-getter.html" }, { - "duration": "11.0", + "duration": "13.0", "name": "blink_perf.bindings/insert-before.html" }, { - "duration": "14.0", + "duration": "11.0", "name": "blink_perf.bindings/named-property-enumerator.html" }, { - "duration": "26.0", + "duration": "24.0", "name": "blink_perf.bindings/node-list-access.html" }, { - "duration": "14.0", + "duration": "11.0", "name": "blink_perf.bindings/node-type.html" }, { @@ -80,11 +84,11 @@ "name": "blink_perf.bindings/post-message.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.bindings/sequence-conversion-array.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.bindings/sequence-conversion-custom-iterator.html" }, { @@ -92,7 +96,7 @@ "name": "blink_perf.bindings/serialize-array.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.bindings/serialize-long-string.html" }, { @@ -100,7 +104,7 @@ "name": "blink_perf.bindings/serialize-map.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.bindings/serialize-nested-array.html" }, { @@ -112,7 +116,7 @@ "name": "blink_perf.bindings/set-attribute.html" }, { - "duration": "20.0", + "duration": "17.0", "name": "blink_perf.bindings/structured-clone-json-deserialize.html" }, { @@ -120,11 +124,11 @@ "name": "blink_perf.bindings/structured-clone-json-serialize.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.bindings/typed-array-construct-from-array.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.bindings/typed-array-construct-from-same-type.html" }, { @@ -132,11 +136,11 @@ "name": "blink_perf.bindings/typed-array-construct-from-typed.html" }, { - "duration": "13.0", + "duration": "12.0", "name": "blink_perf.bindings/typed-array-set-from-typed.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.bindings/undefined-first-child.html" }, { @@ -144,10 +148,14 @@ "name": "blink_perf.bindings/undefined-get-element-by-id.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.bindings/undefined-id-getter.html" }, { + "duration": "6.0", + "name": "blink_perf.bindings/worker-structured-clone-different-payloads.html" + }, + { "duration": "29.0", "name": "blink_perf.bindings/worker-structured-clone-json-from-worker.html" }, @@ -156,39 +164,39 @@ "name": "blink_perf.bindings/worker-structured-clone-json-roundtrip.html" }, { - "duration": "32.0", + "duration": "28.0", "name": "blink_perf.bindings/worker-structured-clone-json-to-worker.html" }, { - "duration": "11.0", + "duration": "9.0", "name": "blink_perf.bindings/worker-structured-clone-workerDOM-DBMon-from-worker.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.bindings/worker-structured-clone-workerDOM-Map-from-worker.html" }, { - "duration": "70.0", + "duration": "71.0", "name": "blink_perf.bindings/worker-text-encoded-transferable-from-worker.html" }, { - "duration": "69.0", + "duration": "70.0", "name": "blink_perf.bindings/worker-text-encoded-transferable-roundtrip.html" }, { - "duration": "67.0", + "duration": "70.0", "name": "blink_perf.bindings/worker-text-encoded-transferable-to-worker.html" }, { - "duration": "16.0", + "duration": "13.0", "name": "blink_perf.bindings/worker-transferable-from-worker.html" }, { - "duration": "14.0", + "duration": "13.0", "name": "blink_perf.bindings/worker-transferable-roundtrip.html" }, { - "duration": "13.0", + "duration": "14.0", "name": "blink_perf.bindings/worker-transferable-to-worker.html" }, { @@ -196,31 +204,55 @@ "name": "blink_perf.canvas/createImageBitmapFromImageData.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.canvas/createImageBitmapFromImageData_RAF.html?RAF" }, { + "duration": "14.0", + "name": "blink_perf.canvas/docs-paper.html" + }, + { + "duration": "8.0", + "name": "blink_perf.canvas/docs-paper_RAF.html?RAF" + }, + { + "duration": "12.0", + "name": "blink_perf.canvas/docs-resume.html" + }, + { + "duration": "7.0", + "name": "blink_perf.canvas/docs-resume_RAF.html?RAF" + }, + { + "duration": "12.0", + "name": "blink_perf.canvas/docs-table.html" + }, + { + "duration": "7.0", + "name": "blink_perf.canvas/docs-table_RAF.html?RAF" + }, + { "duration": "7.0", "name": "blink_perf.canvas/draw-dynamic-canvas-2d-to-hw-accelerated-canvas-2d.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.canvas/draw-dynamic-canvas-2d-to-hw-accelerated-canvas-2d_RAF.html?RAF" }, { - "duration": "12.0", + "duration": "13.0", "name": "blink_perf.canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d.html" }, { - "duration": "10.0", + "duration": "7.0", "name": "blink_perf.canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d_RAF.html?RAF" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.canvas/draw-hw-accelerated-canvas-2d-to-sw-canvas-2d.html" }, { - "duration": "10.0", + "duration": "7.0", "name": "blink_perf.canvas/draw-hw-accelerated-canvas-2d-to-sw-canvas-2d_RAF.html?RAF" }, { @@ -228,39 +260,39 @@ "name": "blink_perf.canvas/draw-static-canvas-2d-to-hw-accelerated-canvas-2d.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.canvas/draw-static-canvas-2d-to-hw-accelerated-canvas-2d_RAF.html?RAF" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.canvas/draw-static-webgl-to-hw-accelerated-canvas-2d.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.canvas/draw-static-webgl-to-hw-accelerated-canvas-2d_RAF.html?RAF" }, { - "duration": "6.0", + "duration": "8.0", "name": "blink_perf.canvas/draw-video-to-hw-accelerated-canvas-2d.html" }, { - "duration": "7.0", + "duration": "8.0", "name": "blink_perf.canvas/draw-video-to-hw-accelerated-canvas-2d_RAF.html?RAF" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.canvas/drawimage-not-pixelaligned.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.canvas/drawimage-not-pixelaligned_RAF.html?RAF" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.canvas/drawimage.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.canvas/drawimage_RAF.html?RAF" }, { @@ -272,11 +304,11 @@ "name": "blink_perf.canvas/getImageDataColorManaged.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.canvas/getImageDataColorManaged_RAF.html?RAF" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.canvas/getImageData_RAF.html?RAF" }, { @@ -284,7 +316,7 @@ "name": "blink_perf.canvas/gpu-bound-shader.html" }, { - "duration": "8.0", + "duration": "9.0", "name": "blink_perf.canvas/gpu-bound-shader_RAF.html?RAF" }, { @@ -292,27 +324,27 @@ "name": "blink_perf.canvas/putImageData.html" }, { - "duration": "14.0", + "duration": "11.0", "name": "blink_perf.canvas/putImageData_RAF.html?RAF" }, { - "duration": "15.0", + "duration": "16.0", "name": "blink_perf.canvas/sheets-render.html" }, { - "duration": "9.0", + "duration": "7.0", "name": "blink_perf.canvas/sheets-render_RAF.html?RAF" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.canvas/toBlob_duration.html" }, { - "duration": "10.0", + "duration": "11.0", "name": "blink_perf.canvas/toBlob_duration_RAF.html?RAF" }, { - "duration": "8.0", + "duration": "9.0", "name": "blink_perf.canvas/toBlob_duration_jpeg.html" }, { @@ -328,11 +360,11 @@ "name": "blink_perf.canvas/transferFromImageBitmap_RAF.html?RAF" }, { - "duration": "8.0", + "duration": "9.0", "name": "blink_perf.canvas/upload-canvas-2d-to-texture.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.canvas/upload-canvas-2d-to-texture_RAF.html?RAF" }, { @@ -340,7 +372,7 @@ "name": "blink_perf.canvas/upload-video-to-sub-texture.html" }, { - "duration": "10.0", + "duration": "8.0", "name": "blink_perf.canvas/upload-video-to-sub-texture_RAF.html?RAF" }, { @@ -352,15 +384,15 @@ "name": "blink_perf.canvas/upload-video-to-texture_RAF.html?RAF" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.canvas/upload-webgl-to-texture.html" }, { - "duration": "9.0", + "duration": "10.0", "name": "blink_perf.canvas/upload-webgl-to-texture_RAF.html?RAF" }, { - "duration": "27.0", + "duration": "25.0", "name": "blink_perf.css/AttributeDescendantSelector.html" }, { @@ -368,75 +400,75 @@ "name": "blink_perf.css/CSSPropertySetterGetter.html" }, { - "duration": "12.0", + "duration": "13.0", "name": "blink_perf.css/CSSPropertySetterGetterMethods.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.css/CSSPropertyUpdateValue.html" }, { - "duration": "16.0", + "duration": "13.0", "name": "blink_perf.css/ChangeStyleChildClassSelector.html" }, { - "duration": "12.0", + "duration": "15.0", "name": "blink_perf.css/ChangeStyleChildElementSelectors.html" }, { - "duration": "9.0", + "duration": "14.0", "name": "blink_perf.css/ChangeStyleElementSelector.html" }, { - "duration": "13.0", + "duration": "14.0", "name": "blink_perf.css/ChangeStyleGrandChildElementSelector.html" }, { - "duration": "17.0", + "duration": "14.0", "name": "blink_perf.css/ChangeStyleMultipleClassSelector.html" }, { - "duration": "12.0", + "duration": "14.0", "name": "blink_perf.css/ChangeStyleMultipleQualifiedDataAttributesWithValuesSelector.html" }, { - "duration": "19.0", + "duration": "14.0", "name": "blink_perf.css/ChangeStyleNestedPseudoSelector.html" }, { - "duration": "16.0", + "duration": "13.0", "name": "blink_perf.css/ChangeStylePairOfNthChildSelector.html" }, { - "duration": "12.0", + "duration": "13.0", "name": "blink_perf.css/ChangeStylePartialAttributeMatchingSelector.html" }, { - "duration": "17.0", + "duration": "14.0", "name": "blink_perf.css/ChangeStyleQualifiedDataAttributeSelector.html" }, { - "duration": "11.0", + "duration": "14.0", "name": "blink_perf.css/ChangeStyleQualifiedDataAttributeWithValueSelector.html" }, { - "duration": "17.0", + "duration": "16.0", "name": "blink_perf.css/ChangeStyleShallowTree.html" }, { - "duration": "11.0", + "duration": "13.0", "name": "blink_perf.css/ChangeStyleSingleClassSelector.html" }, { - "duration": "10.0", + "duration": "14.0", "name": "blink_perf.css/ChangeStyleSingleNthChildSelector.html" }, { - "duration": "14.0", + "duration": "13.0", "name": "blink_perf.css/ChangeStyleSinglePseudoSelector.html" }, { - "duration": "14.0", + "duration": "13.0", "name": "blink_perf.css/ChangeStyleUniversalSelector.html" }, { @@ -448,11 +480,11 @@ "name": "blink_perf.css/ChangeStyleUnqualifiedDataAttributeWithValueSelector.html" }, { - "duration": "18.0", + "duration": "16.0", "name": "blink_perf.css/ClassDescendantSelector.html" }, { - "duration": "16.0", + "duration": "13.0", "name": "blink_perf.css/ClassInvalidation.html" }, { @@ -472,39 +504,39 @@ "name": "blink_perf.css/CustomPropertiesVarAlias.html" }, { - "duration": "19.0", + "duration": "15.0", "name": "blink_perf.css/FocusUpdate.html" }, { - "duration": "15.0", + "duration": "13.0", "name": "blink_perf.css/LoadBootstrapBlog.html" }, { - "duration": "12.0", + "duration": "14.0", "name": "blink_perf.css/LoadMaterializeStarterPage.html" }, { - "duration": "13.0", + "duration": "14.0", "name": "blink_perf.css/LoadSemanticPageExample.html" }, { - "duration": "11.0", + "duration": "13.0", "name": "blink_perf.css/PseudoClassSelectors.html" }, { - "duration": "16.0", + "duration": "13.0", "name": "blink_perf.css/SelectorCountScaling.html" }, { - "duration": "40.0", + "duration": "38.0", "name": "blink_perf.dom/custom-element-default-style-with-shadow.html" }, { - "duration": "24.0", + "duration": "25.0", "name": "blink_perf.dom/custom-element-default-style.html" }, { - "duration": "19.0", + "duration": "27.0", "name": "blink_perf.dom/long-sibling-list.html" }, { @@ -520,11 +552,11 @@ "name": "blink_perf.dom/modify-element-title.html" }, { - "duration": "11.0", + "duration": "13.0", "name": "blink_perf.dom/select-multiple-add.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.dom/select-single-add.html" }, { @@ -532,39 +564,47 @@ "name": "blink_perf.dom/select-single-remove.html" }, { - "duration": "20.0", + "duration": "24.0", "name": "blink_perf.events/EventsDispatching.html" }, { - "duration": "15.0", - "name": "blink_perf.events/EventsDispatchingInDeeplyNestedShadowTrees.html" + "duration": "12.0", + "name": "blink_perf.events/EventsDispatchingInDeeplyNestedV0ShadowTrees.html" }, { - "duration": "28.0", - "name": "blink_perf.events/EventsDispatchingInShadowTrees.html" + "duration": "13.0", + "name": "blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html" + }, + { + "duration": "26.0", + "name": "blink_perf.events/EventsDispatchingInV0ShadowTrees.html" + }, + { + "duration": "26.0", + "name": "blink_perf.events/EventsDispatchingInV1ShadowTrees.html" }, { "duration": "25.0", "name": "blink_perf.events/hit-test-lots-of-layers.html" }, { - "duration": "66.0", + "duration": "59.0", "name": "blink_perf.image_decoder/decode-gif.html" }, { - "duration": "24.0", + "duration": "22.0", "name": "blink_perf.image_decoder/decode-jpeg.html" }, { - "duration": "57.0", + "duration": "55.0", "name": "blink_perf.image_decoder/decode-lossless-webp.html" }, { - "duration": "13.0", + "duration": "14.0", "name": "blink_perf.image_decoder/decode-lossy-webp.html" }, { - "duration": "40.0", + "duration": "36.0", "name": "blink_perf.image_decoder/decode-png-palette-opaque.html" }, { @@ -572,27 +612,27 @@ "name": "blink_perf.image_decoder/decode-png-palette.html" }, { - "duration": "64.0", + "duration": "61.0", "name": "blink_perf.image_decoder/decode-png.html" }, { - "duration": "18.0", + "duration": "20.0", "name": "blink_perf.layout/ArabicLineLayout.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.layout/Shapes/MultipleShapes.html" }, { - "duration": "13.0", + "duration": "12.0", "name": "blink_perf.layout/SimpleTextPathLineLayout.html" }, { - "duration": "10.0", + "duration": "14.0", "name": "blink_perf.layout/add-remove-inline-floats.html" }, { - "duration": "11.0", + "duration": "13.0", "name": "blink_perf.layout/attach-inlines-2.html" }, { @@ -600,11 +640,11 @@ "name": "blink_perf.layout/attach-inlines.html" }, { - "duration": "12.0", + "duration": "13.0", "name": "blink_perf.layout/auto-grid-lots-of-data.html" }, { - "duration": "16.0", + "duration": "17.0", "name": "blink_perf.layout/change-text-css-contain.html" }, { @@ -612,31 +652,35 @@ "name": "blink_perf.layout/chapter-reflow-once-random.html" }, { - "duration": "14.0", + "duration": "13.0", "name": "blink_perf.layout/chapter-reflow-once.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.layout/chapter-reflow-thrice.html" }, { - "duration": "15.0", + "duration": "13.0", "name": "blink_perf.layout/chapter-reflow-twice.html" }, { - "duration": "10.0", + "duration": "12.0", "name": "blink_perf.layout/chapter-reflow.html" }, { - "duration": "7.0", + "duration": "16.0", "name": "blink_perf.layout/character_fallback.html" }, { - "duration": "5.0", + "duration": "7.0", "name": "blink_perf.layout/character_fallback_aat.html" }, { - "duration": "15.0", + "duration": "19.0", + "name": "blink_perf.layout/contain-content-style-change.html" + }, + { + "duration": "12.0", "name": "blink_perf.layout/fixed-grid-lots-of-data.html" }, { @@ -644,15 +688,15 @@ "name": "blink_perf.layout/fixed-grid-lots-of-stretched-data.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.layout/flexbox-column-nowrap.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.layout/flexbox-column-wrap.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.layout/flexbox-deeply-nested-column-flow.html" }, { @@ -672,47 +716,47 @@ "name": "blink_perf.layout/flexbox-row-wrap.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.layout/flexbox-with-stretch-layout.html" }, { - "duration": "19.0", + "duration": "22.0", "name": "blink_perf.layout/floats_100_100.html" }, { - "duration": "19.0", + "duration": "22.0", "name": "blink_perf.layout/floats_100_100_nested.html" }, { - "duration": "13.0", + "duration": "16.0", "name": "blink_perf.layout/floats_10_1000.html" }, { - "duration": "12.0", + "duration": "11.0", "name": "blink_perf.layout/floats_20_100.html" }, { - "duration": "10.0", + "duration": "12.0", "name": "blink_perf.layout/floats_20_100_nested.html" }, { - "duration": "10.0", + "duration": "8.0", "name": "blink_perf.layout/floats_2_100.html" }, { - "duration": "10.0", + "duration": "8.0", "name": "blink_perf.layout/floats_2_100_nested.html" }, { - "duration": "10.0", + "duration": "12.0", "name": "blink_perf.layout/floats_50_100.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.layout/floats_50_100_nested.html" }, { - "duration": "10.0", + "duration": "11.0", "name": "blink_perf.layout/hindi-line-layout.html" }, { @@ -724,15 +768,15 @@ "name": "blink_perf.layout/large-spanning-grid-item.html" }, { - "duration": "19.0", + "duration": "18.0", "name": "blink_perf.layout/large-table-with-collapsed-borders-and-colspans-wider-than-table.html" }, { - "duration": "16.0", + "duration": "18.0", "name": "blink_perf.layout/large-table-with-collapsed-borders-and-colspans.html" }, { - "duration": "16.0", + "duration": "18.0", "name": "blink_perf.layout/large-table-with-collapsed-borders-and-no-colspans.html" }, { @@ -740,27 +784,27 @@ "name": "blink_perf.layout/latin-ebook-resize.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.layout/latin-ebook.html" }, { - "duration": "9.0", + "duration": "7.0", "name": "blink_perf.layout/layers_overlap_2d.html" }, { - "duration": "9.0", + "duration": "8.0", "name": "blink_perf.layout/layers_overlap_3d.html" }, { - "duration": "16.0", + "duration": "19.0", "name": "blink_perf.layout/line-layout-line-height.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.layout/line-layout-repeat-append-select.html" }, { - "duration": "10.0", + "duration": "12.0", "name": "blink_perf.layout/line-layout-repeat-append.html" }, { @@ -772,51 +816,51 @@ "name": "blink_perf.layout/long-line-nowrap-collapse.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.layout/long-line-nowrap-spans-collapse.html" }, { - "duration": "11.0", + "duration": "9.0", "name": "blink_perf.layout/long-line-nowrap.html" }, { - "duration": "14.0", + "duration": "11.0", "name": "blink_perf.layout/many-block-children-auto-inline-size.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.layout/many-block-children-fixed-inline-size.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.layout/multicol/deeply-nested-tables.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.layout/multicol/fixed-height-with-spanner-and-nested-tables.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.layout/multicol/lots-of-text-autofill.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.layout/multicol/lots-of-text-balanced-orphans-widows.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.layout/multicol/lots-of-text-balanced.html" }, { - "duration": "14.0", + "duration": "13.0", "name": "blink_perf.layout/multicol/tall-content-short-columns-realistic.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.layout/multicol/tall-content-short-columns.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.layout/nested-blocks-with-percent-height-and-max-height.html" }, { @@ -824,67 +868,67 @@ "name": "blink_perf.layout/nested-grid.html" }, { - "duration": "36.0", + "duration": "44.0", "name": "blink_perf.layout/nested-percent-height-tables.html" }, { - "duration": "84.0", + "duration": "121.0", "name": "blink_perf.layout/subtree-detaching.html" }, { - "duration": "10.0", + "duration": "7.0", "name": "blink_perf.layout/vertical-japanese-kokoro-insert.html" }, { - "duration": "10.0", + "duration": "7.0", "name": "blink_perf.layout/word-break-break-all.html" }, { - "duration": "10.0", + "duration": "8.0", "name": "blink_perf.layout/word-break-break-word.html" }, { - "duration": "7.0", + "duration": "8.0", "name": "blink_perf.layout/word-wrap-break-word.html" }, { - "duration": "20.0", + "duration": "22.0", "name": "blink_perf.owp_storage/blob-perf-files.html" }, { - "duration": "19.0", + "duration": "17.0", "name": "blink_perf.owp_storage/blob-perf-ipc.html" }, { - "duration": "17.0", + "duration": "14.0", "name": "blink_perf.owp_storage/blob-perf-shm.html" }, { - "duration": "14.0", + "duration": "17.0", "name": "blink_perf.owp_storage/blob-perf-tiny.html" }, { - "duration": "16.0", + "duration": "18.0", "name": "blink_perf.owp_storage/idb-load-docs.html" }, { - "duration": "22.0", + "duration": "24.0", "name": "blink_perf.paint/appending-text.html" }, { - "duration": "18.0", + "duration": "19.0", "name": "blink_perf.paint/color-changes.html" }, { - "duration": "17.0", + "duration": "19.0", "name": "blink_perf.paint/complex-content-slow-scroll.html" }, { - "duration": "17.0", + "duration": "18.0", "name": "blink_perf.paint/complex-iframe-filtered.html" }, { - "duration": "21.0", + "duration": "20.0", "name": "blink_perf.paint/containment-resize.html" }, { @@ -892,59 +936,59 @@ "name": "blink_perf.paint/fixed-and-many-layers-scroll.html" }, { - "duration": "20.0", + "duration": "22.0", "name": "blink_perf.paint/large-table-background-change-with-invisible-collapsed-borders.html" }, { - "duration": "16.0", + "duration": "17.0", "name": "blink_perf.paint/large-table-background-change-with-visible-collapsed-borders.html" }, { - "duration": "21.0", + "duration": "23.0", "name": "blink_perf.paint/large-table-background-change-with-zero-width-collapsed-borders.html" }, { - "duration": "17.0", + "duration": "18.0", "name": "blink_perf.paint/large-table-collapsed-border-change-with-backgrounds.html" }, { - "duration": "20.0", + "duration": "22.0", "name": "blink_perf.paint/large-table-collapsed-border-change-with-text.html" }, { - "duration": "17.0", + "duration": "16.0", "name": "blink_perf.paint/large-table-collapsed-border-change.html" }, { - "duration": "20.0", + "duration": "22.0", "name": "blink_perf.paint/large-table-repaint.html" }, { - "duration": "17.0", + "duration": "16.0", "name": "blink_perf.paint/move-text-with-mask.html" }, { - "duration": "20.0", + "duration": "19.0", "name": "blink_perf.paint/paint-offset-changes.html" }, { - "duration": "28.0", + "duration": "27.0", "name": "blink_perf.paint/transform-changes.html" }, { - "duration": "23.0", + "duration": "21.0", "name": "blink_perf.parser/css-parser-yui.html" }, { - "duration": "23.0", + "duration": "22.0", "name": "blink_perf.parser/html-parser-threaded.html" }, { - "duration": "33.0", + "duration": "36.0", "name": "blink_perf.parser/html-parser.html" }, { - "duration": "73.0", + "duration": "90.0", "name": "blink_perf.parser/html5-full-render.html" }, { @@ -952,7 +996,7 @@ "name": "blink_perf.parser/iframe-append-remove.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.parser/innerHTML-setter-siblings.html" }, { @@ -964,7 +1008,7 @@ "name": "blink_perf.parser/query-selector-all-attribute-complex.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.parser/query-selector-all-attribute.html" }, { @@ -976,27 +1020,27 @@ "name": "blink_perf.parser/query-selector-all-class-first.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.parser/query-selector-all-class-last.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.parser/query-selector-all-class.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.parser/query-selector-all-deep.html" }, { - "duration": "12.0", + "duration": "13.0", "name": "blink_perf.parser/query-selector-all-first.html" }, { - "duration": "12.0", + "duration": "14.0", "name": "blink_perf.parser/query-selector-all-id-deep.html" }, { - "duration": "12.0", + "duration": "13.0", "name": "blink_perf.parser/query-selector-all-id-first.html" }, { @@ -1004,7 +1048,7 @@ "name": "blink_perf.parser/query-selector-all-id-last.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.parser/query-selector-all-last.html" }, { @@ -1016,7 +1060,7 @@ "name": "blink_perf.parser/query-selector-first.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.parser/query-selector-id-deep.html" }, { @@ -1024,15 +1068,15 @@ "name": "blink_perf.parser/query-selector-id-last.html" }, { - "duration": "14.0", + "duration": "12.0", "name": "blink_perf.parser/query-selector-last.html" }, { - "duration": "10.0", + "duration": "11.0", "name": "blink_perf.parser/simple-url.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.parser/textarea-parsing.html" }, { @@ -1040,31 +1084,31 @@ "name": "blink_perf.parser/tiny-innerHTML.html" }, { - "duration": "13.0", + "duration": "14.0", "name": "blink_perf.parser/url-parser.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.parser/xml-parser.html" }, { - "duration": "17.0", + "duration": "14.0", "name": "blink_perf.shadow_dom/declarative-api.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/imperative-api-appendchild.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/imperative-api-assign.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/imperative-api-assigned-elements.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/imperative-api-assigned-slot.html" }, { @@ -1076,11 +1120,11 @@ "name": "blink_perf.shadow_dom/imperative-api-custom-detail-summary.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/imperative-api-detail-summary-large.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/imperative-api-detail-summary.html" }, { @@ -1088,23 +1132,23 @@ "name": "blink_perf.shadow_dom/imperative-api-insertbefore.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/imperative-api.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.shadow_dom/shadow-style-share-attr-selectors.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.shadow_dom/shadow-style-share-media-query.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.shadow_dom/shadow-style-share-with-distribution.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/shadow-style-share.html" }, { @@ -1116,15 +1160,15 @@ "name": "blink_perf.shadow_dom/v0-changing-classname-with-shadow-dom.html" }, { - "duration": "7.0", + "duration": "8.0", "name": "blink_perf.shadow_dom/v0-changing-classname-without-shadow-dom.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.shadow_dom/v0-changing-select-with-shadow-dom.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "blink_perf.shadow_dom/v0-changing-select-without-shadow-dom.html" }, { @@ -1144,43 +1188,43 @@ "name": "blink_perf.shadow_dom/v0-shadow-reprojection.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v0-small-distribution-with-layout.html" }, { - "duration": "24.0", + "duration": "26.0", "name": "blink_perf.shadow_dom/v1-distribution-disconnected-and-reconnected.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v1-distribution.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v1-host-child-append.html" }, { - "duration": "23.0", + "duration": "26.0", "name": "blink_perf.shadow_dom/v1-large-deep-distribution.html" }, { - "duration": "51.0", + "duration": "61.0", "name": "blink_perf.shadow_dom/v1-large-deep-layout.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v1-large-shallow-distribution.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v1-large-shallow-layout.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-re-layout.html" }, { - "duration": "8.0", + "duration": "5.0", "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-slot-assigned-nodes.html" }, { @@ -1188,31 +1232,31 @@ "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-slot-flatten.html" }, { - "duration": "8.0", + "duration": "5.0", "name": "blink_perf.shadow_dom/v1-mutate-shallow-tree-then-re-layout.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v1-mutate-shallow-tree-then-slot-assigned-nodes.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v1-mutate-shallow-tree-then-slot-flatten.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v1-slot-append.html" }, { - "duration": "7.0", + "duration": "8.0", "name": "blink_perf.shadow_dom/v1-small-deep-distribution.html" }, { - "duration": "7.0", + "duration": "9.0", "name": "blink_perf.shadow_dom/v1-small-deep-layout.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.shadow_dom/v1-small-shallow-distribution.html" }, { @@ -1220,35 +1264,35 @@ "name": "blink_perf.shadow_dom/v1-small-shallow-layout.html" }, { - "duration": "14.0", + "duration": "15.0", "name": "blink_perf.svg/AzLizardBenjiPark.html" }, { - "duration": "8.0", + "duration": "9.0", "name": "blink_perf.svg/Bamboo.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.svg/Cactus.html" }, { - "duration": "9.0", + "duration": "7.0", "name": "blink_perf.svg/Cowboy.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.svg/CrawFishGanson.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.svg/Debian.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.svg/DropsOnABlade.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.svg/FlowerFromMyGarden.html" }, { @@ -1256,11 +1300,11 @@ "name": "blink_perf.svg/FoodLeifLodahl.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.svg/France.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.svg/FrancoBolloGnomeEzechi.html" }, { @@ -1268,27 +1312,27 @@ "name": "blink_perf.svg/GearFlowers.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.svg/HarveyRayner.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.svg/HereGear.html" }, { - "duration": "9.0", + "duration": "10.0", "name": "blink_perf.svg/MtSaintHelens.html" }, { - "duration": "5.0", + "duration": "6.0", "name": "blink_perf.svg/Samurai.html" }, { - "duration": "54.0", + "duration": "69.0", "name": "blink_perf.svg/SierpinskiCarpet.html" }, { - "duration": "9.0", + "duration": "7.0", "name": "blink_perf.svg/SvgCubics.html" }, { @@ -1300,11 +1344,11 @@ "name": "blink_perf.svg/SvgNestedUse.html" }, { - "duration": "8.0", + "duration": "6.0", "name": "blink_perf.svg/UnderTheSee.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.svg/WorldIso.html" }, { @@ -1316,7 +1360,7 @@ "name": "dromaeo/http://dromaeo.com?dom-attr" }, { - "duration": "36.0", + "duration": "37.0", "name": "dromaeo/http://dromaeo.com?dom-modify" }, { @@ -1328,15 +1372,15 @@ "name": "dromaeo/http://dromaeo.com?dom-traverse" }, { - "duration": "14.0", + "duration": "12.0", "name": "dummy_benchmark.noisy_benchmark_1/dummy_page.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "dummy_benchmark.stable_benchmark_1/dummy_page.html" }, { - "duration": "284.0", + "duration": "281.0", "name": "jetstream/http://browserbench.org/JetStream/" }, { @@ -1344,27 +1388,27 @@ "name": "kraken/http://krakenbenchmark.mozilla.org/kraken-1.1/driver.html" }, { - "duration": "21.0", + "duration": "19.0", "name": "loading.mobile/58Pic" }, { - "duration": "133.0", + "duration": "122.0", "name": "loading.mobile/58Pic_3g" }, { - "duration": "24.0", + "duration": "21.0", "name": "loading.mobile/Amazon" }, { - "duration": "202.0", + "duration": "197.0", "name": "loading.mobile/Amazon_3g" }, { - "duration": "27.0", + "duration": "23.0", "name": "loading.mobile/BOLNoticias" }, { - "duration": "297.0", + "duration": "265.0", "name": "loading.mobile/BOLNoticias_3g" }, { @@ -1372,171 +1416,171 @@ "name": "loading.mobile/Baidu" }, { - "duration": "155.0", + "duration": "154.0", "name": "loading.mobile/Baidu_3g" }, { - "duration": "25.0", + "duration": "21.0", "name": "loading.mobile/Bradesco" }, { - "duration": "22.0", + "duration": "20.0", "name": "loading.mobile/Dailymotion" }, { - "duration": "31.0", + "duration": "24.0", "name": "loading.mobile/Dawn" }, { - "duration": "21.0", + "duration": "19.0", "name": "loading.mobile/DevOpera_cold" }, { - "duration": "128.0", + "duration": "124.0", "name": "loading.mobile/DevOpera_cold_3g" }, { - "duration": "27.0", + "duration": "25.0", "name": "loading.mobile/DevOpera_hot" }, { - "duration": "34.0", + "duration": "30.0", "name": "loading.mobile/DevOpera_hot_3g" }, { - "duration": "24.0", + "duration": "21.0", "name": "loading.mobile/DevOpera_warm" }, { - "duration": "27.0", + "duration": "26.0", "name": "loading.mobile/DevOpera_warm_3g" }, { - "duration": "28.0", + "duration": "22.0", "name": "loading.mobile/Dramaq" }, { - "duration": "145.0", + "duration": "133.0", "name": "loading.mobile/Dramaq_3g" }, { - "duration": "21.0", + "duration": "18.0", "name": "loading.mobile/EnquiryIndianRail" }, { - "duration": "144.0", + "duration": "117.0", "name": "loading.mobile/EnquiryIndianRail_3g" }, { - "duration": "24.0", + "duration": "22.0", "name": "loading.mobile/Facebook" }, { - "duration": "232.0", + "duration": "205.0", "name": "loading.mobile/Facebook_3g" }, { - "duration": "23.0", + "duration": "20.0", "name": "loading.mobile/FlipBoard_cold" }, { - "duration": "382.0", + "duration": "342.0", "name": "loading.mobile/FlipBoard_cold_3g" }, { - "duration": "35.0", + "duration": "27.0", "name": "loading.mobile/FlipBoard_hot" }, { - "duration": "80.0", + "duration": "63.0", "name": "loading.mobile/FlipBoard_hot_3g" }, { - "duration": "27.0", + "duration": "23.0", "name": "loading.mobile/FlipBoard_warm" }, { - "duration": "85.0", + "duration": "74.0", "name": "loading.mobile/FlipBoard_warm_3g" }, { - "duration": "26.0", + "duration": "23.0", "name": "loading.mobile/FlipKart_cold" }, { - "duration": "38.0", + "duration": "28.0", "name": "loading.mobile/FlipKart_hot" }, { - "duration": "36.0", + "duration": "30.0", "name": "loading.mobile/FlipKart_hot_3g" }, { - "duration": "31.0", + "duration": "26.0", "name": "loading.mobile/FlipKart_warm" }, { - "duration": "24.0", + "duration": "19.0", "name": "loading.mobile/FranceTVInfo" }, { - "duration": "200.0", + "duration": "165.0", "name": "loading.mobile/FranceTVInfo_3g" }, { - "duration": "32.0", + "duration": "23.0", "name": "loading.mobile/GSShop" }, { - "duration": "19.0", + "duration": "18.0", "name": "loading.mobile/GoogleBrazil" }, { - "duration": "214.0", + "duration": "181.0", "name": "loading.mobile/GoogleBrazil_3g" }, { - "duration": "20.0", + "duration": "17.0", "name": "loading.mobile/GoogleIndia" }, { - "duration": "21.0", + "duration": "18.0", "name": "loading.mobile/GoogleIndonesia" }, { - "duration": "198.0", + "duration": "181.0", "name": "loading.mobile/GoogleIndonesia_3g" }, { - "duration": "23.0", + "duration": "22.0", "name": "loading.mobile/GoogleRedirectToGoogleJapan" }, { - "duration": "279.0", + "duration": "223.0", "name": "loading.mobile/GoogleRedirectToGoogleJapan_3g" }, { - "duration": "25.0", + "duration": "21.0", "name": "loading.mobile/Hongkiat" }, { - "duration": "248.0", + "duration": "230.0", "name": "loading.mobile/Hongkiat_3g" }, { - "duration": "28.0", + "duration": "23.0", "name": "loading.mobile/KapanLagi" }, { - "duration": "40.0", + "duration": "27.0", "name": "loading.mobile/Kaskus" }, { - "duration": "23.0", + "duration": "21.0", "name": "loading.mobile/LocalMoxie" }, { - "duration": "20.0", + "duration": "18.0", "name": "loading.mobile/Locanto" }, { @@ -1544,15 +1588,15 @@ "name": "loading.mobile/Locanto_3g" }, { - "duration": "23.0", + "duration": "20.0", "name": "loading.mobile/OLX" }, { - "duration": "239.0", + "duration": "220.0", "name": "loading.mobile/OLX_3g" }, { - "duration": "19.0", + "duration": "21.0", "name": "loading.mobile/QQNews" }, { @@ -1560,11 +1604,11 @@ "name": "loading.mobile/QQNews_3g" }, { - "duration": "22.0", + "duration": "19.0", "name": "loading.mobile/SlideShare" }, { - "duration": "200.0", + "duration": "188.0", "name": "loading.mobile/SlideShare_3g" }, { @@ -1572,19 +1616,19 @@ "name": "loading.mobile/Suumo_cold" }, { - "duration": "34.0", + "duration": "32.0", "name": "loading.mobile/Suumo_cold_3g" }, { - "duration": "24.0", + "duration": "22.0", "name": "loading.mobile/Suumo_hot" }, { - "duration": "31.0", + "duration": "28.0", "name": "loading.mobile/Suumo_hot_3g" }, { - "duration": "22.0", + "duration": "20.0", "name": "loading.mobile/Suumo_warm" }, { @@ -1592,15 +1636,15 @@ "name": "loading.mobile/Suumo_warm_3g" }, { - "duration": "26.0", + "duration": "19.0", "name": "loading.mobile/Thairath" }, { - "duration": "31.0", + "duration": "26.0", "name": "loading.mobile/TheStar" }, { - "duration": "30.0", + "duration": "24.0", "name": "loading.mobile/TribunNews" }, { @@ -1608,31 +1652,31 @@ "name": "loading.mobile/Twitter" }, { - "duration": "125.0", + "duration": "111.0", "name": "loading.mobile/Twitter_3g" }, { - "duration": "20.0", + "duration": "19.0", "name": "loading.mobile/VoiceMemos_cold" }, { - "duration": "142.0", + "duration": "133.0", "name": "loading.mobile/VoiceMemos_cold_3g" }, { - "duration": "29.0", + "duration": "24.0", "name": "loading.mobile/VoiceMemos_hot" }, { - "duration": "32.0", + "duration": "28.0", "name": "loading.mobile/VoiceMemos_hot_3g" }, { - "duration": "23.0", + "duration": "21.0", "name": "loading.mobile/VoiceMemos_warm" }, { - "duration": "28.0", + "duration": "26.0", "name": "loading.mobile/VoiceMemos_warm_3g" }, { @@ -1640,67 +1684,67 @@ "name": "loading.mobile/Wikipedia" }, { - "duration": "175.0", + "duration": "159.0", "name": "loading.mobile/Wikipedia_3g" }, { - "duration": "23.0", + "duration": "22.0", "name": "loading.mobile/YahooNews" }, { - "duration": "21.0", + "duration": "19.0", "name": "loading.mobile/Youtube" }, { - "duration": "28.0", + "duration": "22.0", "name": "media.mobile/mse.html?media=aac_audio.mp4" }, { - "duration": "28.0", + "duration": "25.0", "name": "media.mobile/mse.html?media=aac_audio.mp4,h264_video.mp4" }, { - "duration": "31.0", + "duration": "25.0", "name": "media.mobile/mse.html?media=aac_audio.mp4,h264_video.mp4&waitForPageLoaded=true" }, { - "duration": "30.0", + "duration": "23.0", "name": "media.mobile/mse.html?media=h264_video.mp4" }, { - "duration": "70.0", + "duration": "33.0", "name": "media.mobile/video.html?src=crowd.ogg&type=audio" }, { - "duration": "41.0", + "duration": "30.0", "name": "media.mobile/video.html?src=crowd1080_vp9.webm" }, { - "duration": "25.0", + "duration": "21.0", "name": "media.mobile/video.html?src=crowd1080_vp9.webm&seek" }, { - "duration": "37.0", + "duration": "29.0", "name": "media.mobile/video.html?src=crowd720_vp9.webm" }, { - "duration": "39.0", + "duration": "36.0", "name": "media.mobile/video.html?src=tulip2.m4a&type=audio" }, { - "duration": "39.0", + "duration": "34.0", "name": "media.mobile/video.html?src=tulip2.mp3&type=audio" }, { - "duration": "16.0", + "duration": "17.0", "name": "media.mobile/video.html?src=tulip2.mp3&type=audio&seek" }, { - "duration": "52.0", + "duration": "43.0", "name": "media.mobile/video.html?src=tulip2.mp4" }, { - "duration": "58.0", + "duration": "43.0", "name": "media.mobile/video.html?src=tulip2.mp4&busyjs" }, { @@ -1708,38 +1752,46 @@ "name": "media.mobile/video.html?src=tulip2.mp4&seek" }, { - "duration": "40.0", + "duration": "34.0", "name": "media.mobile/video.html?src=tulip2.ogg&type=audio" }, { - "duration": "15.0", + "duration": "17.0", "name": "media.mobile/video.html?src=tulip2.ogg&type=audio&seek" }, { - "duration": "58.0", + "duration": "45.0", "name": "media.mobile/video.html?src=tulip2.vp9.webm" }, { - "duration": "35.0", + "duration": "30.0", "name": "media.mobile/video.html?src=tulip2.vp9.webm&background" }, { - "duration": "23.0", + "duration": "21.0", "name": "media.mobile/video.html?src=tulip2.vp9.webm&seek" }, { - "duration": "42.0", + "duration": "79.0", + "name": "media.mobile/video.html?src=tulip2.vp9.webm_WiFi" + }, + { + "duration": "36.0", "name": "media.mobile/video.html?src=tulip2.wav&type=audio" }, { - "duration": "19.0", + "duration": "17.0", "name": "media.mobile/video.html?src=tulip2.wav&type=audio&seek" }, { - "duration": "334.0", + "duration": "318.0", "name": "memory.long_running_idle_gmail_background_tbmv2/https://mail.google.com/mail/" }, { + "duration": "282.0", + "name": "memory.long_running_idle_gmail_tbmv2/https://mail.google.com/mail/" + }, + { "duration": "22.0", "name": "memory.top_10_mobile/after_http_en_m_wikipedia_org_wiki_Science" }, @@ -1788,7 +1840,7 @@ "name": "memory.top_10_mobile/http_m_intl_taobao_com_group_purchase_html" }, { - "duration": "27.0", + "duration": "26.0", "name": "memory.top_10_mobile/http_m_youtube_com_results_q_science" }, { @@ -1796,19 +1848,19 @@ "name": "memory.top_10_mobile/http_search_yahoo_com_search__ylt_p_google" }, { - "duration": "26.0", + "duration": "27.0", "name": "memory.top_10_mobile/http_www_amazon_com_gp_aw_s_k_nexus" }, { - "duration": "27.0", + "duration": "29.0", "name": "memory.top_10_mobile/http_www_baidu_com_s_word_google" }, { - "duration": "27.0", + "duration": "26.0", "name": "memory.top_10_mobile/http_yandex_ru_touchsearch_text_science" }, { - "duration": "27.0", + "duration": "26.0", "name": "memory.top_10_mobile/https_m_facebook_com_rihanna" }, { @@ -1816,19 +1868,19 @@ "name": "memory.top_10_mobile/https_mobile_twitter_com_justinbieber_skip_interstitial_true" }, { - "duration": "28.0", + "duration": "29.0", "name": "memory.top_10_mobile/https_www_google_co_uk_hl_en_q_science" }, { - "duration": "65.0", + "duration": "61.0", "name": "octane/http://chromium.github.io/octane/index.html?auto=1" }, { - "duration": "22.0", + "duration": "23.0", "name": "oortonline_tbmv2/http://oortonline.gl/#run" }, { - "duration": "67.0", + "duration": "64.0", "name": "power.typical_10_mobile/http://de.m.wikipedia.org/wiki/K%C3%B6lner_Dom" }, { @@ -1836,15 +1888,15 @@ "name": "power.typical_10_mobile/http://m.chiebukuro.yahoo.co.jp/detail/q10136829180" }, { - "duration": "61.0", + "duration": "59.0", "name": "power.typical_10_mobile/http://m.ebay.com/itm/351157205404" }, { - "duration": "71.0", + "duration": "68.0", "name": "power.typical_10_mobile/http://m.facebook.com/barackobama" }, { - "duration": "65.0", + "duration": "63.0", "name": "power.typical_10_mobile/http://m.huffpost.com/us/entry/6004486" }, { @@ -1852,19 +1904,19 @@ "name": "power.typical_10_mobile/http://m.ynet.co.il" }, { - "duration": "63.0", + "duration": "64.0", "name": "power.typical_10_mobile/http://siriuslymeg.tumblr.com/" }, { - "duration": "58.0", + "duration": "60.0", "name": "power.typical_10_mobile/http://wapbaike.baidu.com/" }, { - "duration": "62.0", + "duration": "60.0", "name": "power.typical_10_mobile/http://www.cnn.com/2014/03/31/showbiz/tv/himym-finale/index.html" }, { - "duration": "67.0", + "duration": "65.0", "name": "power.typical_10_mobile/http://www.rg.ru/2014/10/21/cska-site.html" }, { @@ -1876,31 +1928,31 @@ "name": "rasterize_and_record_micro.partial_invalidation/800_relpos_divs.html" }, { - "duration": "28.0", + "duration": "29.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/amazon.html" }, { - "duration": "14.0", + "duration": "13.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/blogger.html" }, { - "duration": "22.0", + "duration": "23.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/booking.html" }, { - "duration": "17.0", + "duration": "16.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/cnn.html" }, { - "duration": "10.0", + "duration": "11.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/ebay.html" }, { - "duration": "20.0", + "duration": "23.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/espn.html" }, { - "duration": "21.0", + "duration": "20.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/facebook.html" }, { @@ -1908,23 +1960,23 @@ "name": "rasterize_and_record_micro.top_25/file://static_top_25/gmail.html" }, { - "duration": "38.0", + "duration": "30.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/google.html" }, { - "duration": "27.0", + "duration": "28.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/googlecalendar.html" }, { - "duration": "20.0", + "duration": "22.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/googledocs.html" }, { - "duration": "24.0", + "duration": "25.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleimagesearch.html" }, { - "duration": "19.0", + "duration": "20.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleplus.html" }, { @@ -1932,23 +1984,23 @@ "name": "rasterize_and_record_micro.top_25/file://static_top_25/linkedin.html" }, { - "duration": "10.0", + "duration": "11.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/pinterest.html" }, { - "duration": "31.0", + "duration": "16.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/techcrunch.html" }, { - "duration": "29.0", + "duration": "28.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/twitter.html" }, { - "duration": "16.0", + "duration": "15.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/weather.html" }, { - "duration": "12.0", + "duration": "13.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/wordpress.html" }, { @@ -1956,83 +2008,83 @@ "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahooanswers.html" }, { - "duration": "63.0", + "duration": "65.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html" }, { - "duration": "86.0", + "duration": "84.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoosports.html" }, { - "duration": "43.0", + "duration": "33.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/youtube.html" }, { - "duration": "59.0", + "duration": "49.0", "name": "rendering.mobile/accu_weather_2018" }, { - "duration": "39.0", + "duration": "38.0", "name": "rendering.mobile/accu_weather_desktop_gpu_raster_2018" }, { - "duration": "42.0", + "duration": "33.0", "name": "rendering.mobile/amazon_2018" }, { - "duration": "43.0", + "duration": "33.0", "name": "rendering.mobile/amazon_desktop_gpu_raster_2018" }, { - "duration": "34.0", + "duration": "32.0", "name": "rendering.mobile/amazon_mobile_2018" }, { - "duration": "32.0", + "duration": "31.0", "name": "rendering.mobile/analog_clock_svg" }, { - "duration": "65.0", + "duration": "53.0", "name": "rendering.mobile/androidpolice_mobile_2018" }, { - "duration": "28.0", + "duration": "26.0", "name": "rendering.mobile/animometer_webgl" }, { - "duration": "36.0", + "duration": "32.0", "name": "rendering.mobile/aquarium" }, { - "duration": "38.0", + "duration": "35.0", "name": "rendering.mobile/background_color_animation" }, { - "duration": "39.0", + "duration": "36.0", "name": "rendering.mobile/background_color_animation_with_gradient" }, { - "duration": "32.0", + "duration": "34.0", "name": "rendering.mobile/baidu_mobile_2018" }, { - "duration": "27.0", + "duration": "28.0", "name": "rendering.mobile/balls_css_key_frame_animations" }, { - "duration": "34.0", + "duration": "31.0", "name": "rendering.mobile/balls_css_transition_2_properties" }, { - "duration": "34.0", + "duration": "31.0", "name": "rendering.mobile/balls_css_transition_40_properties" }, { - "duration": "32.0", + "duration": "30.0", "name": "rendering.mobile/balls_css_transition_all_properties" }, { - "duration": "29.0", + "duration": "27.0", "name": "rendering.mobile/balls_javascript_canvas" }, { @@ -2040,123 +2092,127 @@ "name": "rendering.mobile/balls_javascript_css" }, { - "duration": "42.0", + "duration": "34.0", "name": "rendering.mobile/balls_svg_animations" }, { - "duration": "43.0", + "duration": "34.0", "name": "rendering.mobile/bing_mobile_2018" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/blob" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/blogspot_2018" }, { - "duration": "30.0", + "duration": "25.0", "name": "rendering.mobile/blogspot_desktop_gpu_raster_2018" }, { - "duration": "35.0", + "duration": "30.0", "name": "rendering.mobile/blogspot_mobile_2018" }, { - "duration": "37.0", + "duration": "24.0", + "name": "rendering.mobile/blur_rotating_background" + }, + { + "duration": "32.0", "name": "rendering.mobile/boingboing_mobile_2018" }, { - "duration": "44.0", + "duration": "35.0", "name": "rendering.mobile/booking.com_2018" }, { - "duration": "39.0", + "duration": "32.0", "name": "rendering.mobile/booking.com_desktop_gpu_raster_2018" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/booking.com_mobile_2018" }, { - "duration": "26.0", + "duration": "22.0", "name": "rendering.mobile/bouncing_balls_15" }, { - "duration": "19.0", + "duration": "21.0", "name": "rendering.mobile/bouncing_balls_shadow" }, { - "duration": "20.0", + "duration": "21.0", "name": "rendering.mobile/bouncing_clipped_rectangles" }, { - "duration": "20.0", + "duration": "21.0", "name": "rendering.mobile/bouncing_gradient_circles" }, { - "duration": "21.0", + "duration": "20.0", "name": "rendering.mobile/bouncing_png_images" }, { - "duration": "32.0", + "duration": "28.0", "name": "rendering.mobile/bouncing_svg_images" }, { - "duration": "35.0", + "duration": "30.0", "name": "rendering.mobile/camera_to_webgl" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/canvas_05000_pixels_per_second" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/canvas_05000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "33.0", + "duration": "28.0", "name": "rendering.mobile/canvas_10000_pixels_per_second" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/canvas_10000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "34.0", + "duration": "29.0", "name": "rendering.mobile/canvas_15000_pixels_per_second" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/canvas_15000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/canvas_20000_pixels_per_second" }, { - "duration": "31.0", + "duration": "28.0", "name": "rendering.mobile/canvas_20000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "32.0", + "duration": "28.0", "name": "rendering.mobile/canvas_30000_pixels_per_second" }, { - "duration": "33.0", + "duration": "28.0", "name": "rendering.mobile/canvas_30000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "31.0", + "duration": "27.0", "name": "rendering.mobile/canvas_40000_pixels_per_second" }, { - "duration": "29.0", + "duration": "27.0", "name": "rendering.mobile/canvas_40000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "27.0", + "duration": "24.0", "name": "rendering.mobile/canvas_50000_pixels_per_second" }, { @@ -2164,15 +2220,15 @@ "name": "rendering.mobile/canvas_50000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "27.0", + "duration": "24.0", "name": "rendering.mobile/canvas_60000_pixels_per_second" }, { - "duration": "25.0", + "duration": "24.0", "name": "rendering.mobile/canvas_60000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "25.0", + "duration": "22.0", "name": "rendering.mobile/canvas_75000_pixels_per_second" }, { @@ -2180,27 +2236,27 @@ "name": "rendering.mobile/canvas_75000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "22.0", + "duration": "21.0", "name": "rendering.mobile/canvas_90000_pixels_per_second" }, { - "duration": "23.0", + "duration": "21.0", "name": "rendering.mobile/canvas_90000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "25.0", + "duration": "23.0", "name": "rendering.mobile/canvas_animation_no_clear" }, { - "duration": "22.0", + "duration": "20.0", "name": "rendering.mobile/canvas_arcs" }, { - "duration": "23.0", + "duration": "21.0", "name": "rendering.mobile/canvas_font_cycler" }, { - "duration": "21.0", + "duration": "22.0", "name": "rendering.mobile/canvas_lines" }, { @@ -2212,83 +2268,79 @@ "name": "rendering.mobile/capitolvolkswagen_mobile_2018" }, { - "duration": "28.0", + "duration": "25.0", "name": "rendering.mobile/card_expansion" }, { - "duration": "27.0", + "duration": "25.0", "name": "rendering.mobile/card_expansion_animated" }, { - "duration": "31.0", + "duration": "25.0", "name": "rendering.mobile/card_expansion_images_text" }, { - "duration": "25.0", + "duration": "23.0", "name": "rendering.mobile/card_flying" }, { - "duration": "17.0", + "duration": "19.0", "name": "rendering.mobile/cats_unscaled" }, { - "duration": "16.0", + "duration": "18.0", "name": "rendering.mobile/cats_viewport_width" }, { - "duration": "37.0", + "duration": "34.0", "name": "rendering.mobile/cc_poster_circle" }, { - "duration": "40.0", - "name": "rendering.mobile/cc_scroll_200_layer_grid" - }, - { - "duration": "41.0", + "duration": "37.0", "name": "rendering.mobile/cc_scroll_text_only" }, { - "duration": "27.0", + "duration": "26.0", "name": "rendering.mobile/chip_tune" }, { - "duration": "39.0", + "duration": "32.0", "name": "rendering.mobile/cnn_2018" }, { - "duration": "49.0", + "duration": "39.0", "name": "rendering.mobile/cnn_article_mobile_2018" }, { - "duration": "34.0", + "duration": "28.0", "name": "rendering.mobile/cnn_desktop_gpu_raster_2018" }, { - "duration": "35.0", + "duration": "27.0", "name": "rendering.mobile/cnn_mobile_2018" }, { - "duration": "34.0", + "duration": "29.0", "name": "rendering.mobile/cnn_pathological_2018" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/compositor_heavy_animation" }, { - "duration": "25.0", + "duration": "23.0", "name": "rendering.mobile/coordinated_animation" }, { - "duration": "30.0", + "duration": "25.0", "name": "rendering.mobile/crafty_mind" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/css_animations_many_keyframes" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/css_animations_simultaneous_inline_style" }, { @@ -2296,47 +2348,47 @@ "name": "rendering.mobile/css_animations_simultaneous_new_element" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/css_animations_simultaneous_style_element" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/css_animations_simultaneous_updating_class" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/css_animations_staggered_infinite_iterations" }, { - "duration": "36.0", + "duration": "32.0", "name": "rendering.mobile/css_animations_staggered_inline_style" }, { - "duration": "39.0", + "duration": "36.0", "name": "rendering.mobile/css_animations_staggered_new_element" }, { - "duration": "32.0", + "duration": "31.0", "name": "rendering.mobile/css_animations_staggered_style_element" }, { - "duration": "34.0", + "duration": "31.0", "name": "rendering.mobile/css_animations_staggered_updating_class" }, { - "duration": "36.0", + "duration": "32.0", "name": "rendering.mobile/css_animations_triggered_inline_style" }, { - "duration": "46.0", + "duration": "37.0", "name": "rendering.mobile/css_animations_triggered_new_element" }, { - "duration": "31.0", + "duration": "41.0", "name": "rendering.mobile/css_animations_triggered_style_element" }, { - "duration": "33.0", + "duration": "31.0", "name": "rendering.mobile/css_animations_triggered_updating_class" }, { @@ -2344,35 +2396,35 @@ "name": "rendering.mobile/css_opacity_plus_n_layers_0" }, { - "duration": "36.0", + "duration": "33.0", "name": "rendering.mobile/css_opacity_plus_n_layers_75" }, { - "duration": "35.0", + "duration": "33.0", "name": "rendering.mobile/css_opacity_plus_n_layers_99" }, { - "duration": "29.0", + "duration": "35.0", "name": "rendering.mobile/css_transitions_inline_style" }, { - "duration": "36.0", + "duration": "41.0", "name": "rendering.mobile/css_transitions_new_element" }, { - "duration": "34.0", + "duration": "31.0", "name": "rendering.mobile/css_transitions_staggered_inline_style" }, { - "duration": "33.0", + "duration": "31.0", "name": "rendering.mobile/css_transitions_staggered_new_element" }, { - "duration": "30.0", + "duration": "31.0", "name": "rendering.mobile/css_transitions_staggered_style_element" }, { - "duration": "30.0", + "duration": "31.0", "name": "rendering.mobile/css_transitions_staggered_updating_class" }, { @@ -2380,147 +2432,147 @@ "name": "rendering.mobile/css_transitions_style_element" }, { - "duration": "33.0", + "duration": "31.0", "name": "rendering.mobile/css_transitions_triggered_inline_style" }, { - "duration": "47.0", + "duration": "31.0", "name": "rendering.mobile/css_transitions_triggered_new_element" }, { - "duration": "34.0", + "duration": "31.0", "name": "rendering.mobile/css_transitions_triggered_style_element" }, { - "duration": "32.0", + "duration": "37.0", "name": "rendering.mobile/css_transitions_triggered_updating_class" }, { - "duration": "36.0", + "duration": "35.0", "name": "rendering.mobile/css_transitions_updating_class" }, { - "duration": "34.0", + "duration": "47.0", "name": "rendering.mobile/css_value_type_color" }, { - "duration": "34.0", + "duration": "30.0", "name": "rendering.mobile/css_value_type_filter" }, { - "duration": "34.0", + "duration": "71.0", "name": "rendering.mobile/css_value_type_length" }, { - "duration": "36.0", + "duration": "37.0", "name": "rendering.mobile/css_value_type_length_complex" }, { - "duration": "33.0", + "duration": "77.0", "name": "rendering.mobile/css_value_type_length_simple" }, { - "duration": "30.0", + "duration": "47.0", "name": "rendering.mobile/css_value_type_path" }, { - "duration": "25.0", + "duration": "37.0", "name": "rendering.mobile/css_value_type_shadow" }, { - "duration": "31.0", + "duration": "30.0", "name": "rendering.mobile/css_value_type_transform_complex" }, { - "duration": "31.0", + "duration": "30.0", "name": "rendering.mobile/css_value_type_transform_simple" }, { - "duration": "44.0", + "duration": "54.0", "name": "rendering.mobile/deviantart_mobile_2018" }, { - "duration": "30.0", + "duration": "38.0", "name": "rendering.mobile/digg_mobile_2018" }, { - "duration": "33.0", + "duration": "28.0", "name": "rendering.mobile/dynamic_cube_map" }, { - "duration": "34.0", + "duration": "27.0", "name": "rendering.mobile/earth" }, { - "duration": "49.0", + "duration": "33.0", "name": "rendering.mobile/ebay_2018" }, { - "duration": "39.0", + "duration": "30.0", "name": "rendering.mobile/ebay_desktop_gpu_raster_2018" }, { - "duration": "38.0", + "duration": "32.0", "name": "rendering.mobile/ebay_mobile_2018" }, { - "duration": "51.0", + "duration": "42.0", "name": "rendering.mobile/ebay_scroll_2018" }, { - "duration": "31.0", + "duration": "26.0", "name": "rendering.mobile/effect_games" }, { - "duration": "39.0", + "duration": "34.0", "name": "rendering.mobile/espn_2018" }, { - "duration": "47.0", + "duration": "33.0", "name": "rendering.mobile/espn_desktop_gpu_raster_2018" }, { - "duration": "41.0", + "duration": "33.0", "name": "rendering.mobile/espn_mobile_2018" }, { - "duration": "32.0", + "duration": "27.0", "name": "rendering.mobile/espn_pathological_2018" }, { - "duration": "30.0", + "duration": "27.0", "name": "rendering.mobile/extra_large_texture_uploads" }, { - "duration": "34.0", + "duration": "29.0", "name": "rendering.mobile/facebook_2018" }, { - "duration": "27.0", + "duration": "24.0", "name": "rendering.mobile/facebook_desktop_gpu_raster_2018" }, { - "duration": "54.0", + "duration": "44.0", "name": "rendering.mobile/facebook_mobile_2018" }, { - "duration": "24.0", + "duration": "22.0", "name": "rendering.mobile/fill_shapes" }, { - "duration": "34.0", + "duration": "32.0", "name": "rendering.mobile/filter_terrain_svg" }, { - "duration": "51.0", + "duration": "40.0", "name": "rendering.mobile/flickr_scroll_2018" }, { - "duration": "25.0", + "duration": "24.0", "name": "rendering.mobile/font_wipe" }, { - "duration": "32.0", + "duration": "29.0", "name": "rendering.mobile/forecast.io_mobile_2018" }, { @@ -2528,107 +2580,107 @@ "name": "rendering.mobile/geo_apis" }, { - "duration": "30.0", + "duration": "25.0", "name": "rendering.mobile/gmail_2018" }, { - "duration": "26.0", + "duration": "23.0", "name": "rendering.mobile/gmail_desktop_gpu_raster_2018" }, { - "duration": "24.0", + "duration": "21.0", "name": "rendering.mobile/google_calendar_2018" }, { - "duration": "23.0", + "duration": "21.0", "name": "rendering.mobile/google_calendar_desktop_gpu_raster_2018" }, { - "duration": "47.0", + "duration": "36.0", "name": "rendering.mobile/google_docs_2018" }, { - "duration": "45.0", + "duration": "36.0", "name": "rendering.mobile/google_docs_desktop_gpu_raster_2018" }, { - "duration": "37.0", + "duration": "31.0", "name": "rendering.mobile/google_image_search_2018" }, { - "duration": "36.0", + "duration": "32.0", "name": "rendering.mobile/google_image_search_desktop_gpu_raster_2018" }, { - "duration": "47.0", + "duration": "36.0", "name": "rendering.mobile/google_image_search_mobile_2018" }, { - "duration": "32.0", + "duration": "28.0", "name": "rendering.mobile/google_news_ios" }, { - "duration": "29.0", + "duration": "24.0", "name": "rendering.mobile/google_news_mobile_2018" }, { - "duration": "40.0", + "duration": "33.0", "name": "rendering.mobile/google_plus_2018" }, { - "duration": "31.0", + "duration": "28.0", "name": "rendering.mobile/google_plus_desktop_gpu_raster_2018" }, { - "duration": "44.0", + "duration": "41.0", "name": "rendering.mobile/google_plus_mobile_2018" }, { - "duration": "33.0", + "duration": "30.0", "name": "rendering.mobile/google_web_search_2018" }, { - "duration": "33.0", + "duration": "26.0", "name": "rendering.mobile/google_web_search_desktop_gpu_raster_2018" }, { - "duration": "42.0", + "duration": "33.0", "name": "rendering.mobile/google_web_search_mobile_2018" }, { - "duration": "46.0", + "duration": "36.0", "name": "rendering.mobile/gsp.ro_mobile_2018" }, { - "duration": "36.0", + "duration": "37.0", "name": "rendering.mobile/guardian_pathological_2018" }, { - "duration": "40.0", + "duration": "32.0", "name": "rendering.mobile/guimark_vector_chart" }, { - "duration": "27.0", + "duration": "24.0", "name": "rendering.mobile/gws_boogie_expansion" }, { - "duration": "28.0", + "duration": "25.0", "name": "rendering.mobile/gws_google_expansion" }, { - "duration": "26.0", + "duration": "25.0", "name": "rendering.mobile/hakim" }, { - "duration": "29.0", + "duration": "25.0", "name": "rendering.mobile/horizontal_vertical_expansion" }, { - "duration": "44.0", + "duration": "41.0", "name": "rendering.mobile/idle_power_animated_gif" }, { - "duration": "36.0", + "duration": "37.0", "name": "rendering.mobile/idle_power_blank" }, { @@ -2636,115 +2688,111 @@ "name": "rendering.mobile/idle_power_css_animation" }, { - "duration": "46.0", + "duration": "43.0", "name": "rendering.mobile/idle_power_request_animation_frame" }, { - "duration": "118.0", + "duration": "114.0", "name": "rendering.mobile/idle_power_set_timeout_long" }, { - "duration": "45.0", + "duration": "44.0", "name": "rendering.mobile/idle_power_set_timetout" }, { - "duration": "51.0", + "duration": "47.0", "name": "rendering.mobile/ie_chalkboard" }, { - "duration": "39.0", + "duration": "37.0", "name": "rendering.mobile/ie_pirate_mark" }, { - "duration": "41.0", + "duration": "38.0", "name": "rendering.mobile/infinite_scroll_element_n_layers_0" }, { - "duration": "45.0", + "duration": "49.0", "name": "rendering.mobile/infinite_scroll_element_n_layers_75" }, { - "duration": "46.0", + "duration": "37.0", "name": "rendering.mobile/infinite_scroll_element_n_layers_99" }, { - "duration": "47.0", + "duration": "37.0", "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_0" }, { - "duration": "47.0", + "duration": "39.0", "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_75" }, { - "duration": "45.0", + "duration": "38.0", "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_99" }, { - "duration": "42.0", + "duration": "37.0", "name": "rendering.mobile/infinite_scroll_root_n_layers_0" }, { - "duration": "45.0", + "duration": "38.0", "name": "rendering.mobile/infinite_scroll_root_n_layers_75" }, { - "duration": "43.0", + "duration": "39.0", "name": "rendering.mobile/infinite_scroll_root_n_layers_99" }, { - "duration": "46.0", + "duration": "36.0", "name": "rendering.mobile/infinite_scrolling" }, { - "duration": "31.0", + "duration": "27.0", "name": "rendering.mobile/jarro_doverson" }, { - "duration": "49.0", + "duration": "46.0", "name": "rendering.mobile/js_full_screen_invalidation" }, { - "duration": "40.0", + "duration": "36.0", "name": "rendering.mobile/js_opacity_plus_n_layers_0" }, { - "duration": "42.0", + "duration": "34.0", "name": "rendering.mobile/js_opacity_plus_n_layers_75" }, { - "duration": "40.0", + "duration": "34.0", "name": "rendering.mobile/js_opacity_plus_n_layers_99" }, { - "duration": "44.0", + "duration": "36.0", "name": "rendering.mobile/js_paint_plus_n_layers_0" }, { - "duration": "44.0", + "duration": "37.0", "name": "rendering.mobile/js_paint_plus_n_layers_75" }, { - "duration": "41.0", + "duration": "37.0", "name": "rendering.mobile/js_paint_plus_n_layers_99" }, { - "duration": "40.0", + "duration": "37.0", "name": "rendering.mobile/js_poster_circle" }, { - "duration": "44.0", - "name": "rendering.mobile/js_scroll_200_layer_grid" - }, - { - "duration": "43.0", + "duration": "21.0", "name": "rendering.mobile/js_scroll_text_only" }, { - "duration": "29.0", + "duration": "27.0", "name": "rendering.mobile/kevs_3d" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/keyframed_animations" }, { @@ -2752,55 +2800,55 @@ "name": "rendering.mobile/large_texture_uploads" }, { - "duration": "51.0", + "duration": "40.0", "name": "rendering.mobile/latimes_pathological_2018" }, { - "duration": "42.0", + "duration": "34.0", "name": "rendering.mobile/linkedin_2018" }, { - "duration": "34.0", + "duration": "29.0", "name": "rendering.mobile/linkedin_desktop_gpu_raster_2018" }, { - "duration": "83.0", + "duration": "63.0", "name": "rendering.mobile/linkedin_mobile_2018" }, { - "duration": "50.0", + "duration": "41.0", "name": "rendering.mobile/linkedin_pathological_2018" }, { - "duration": "25.0", + "duration": "21.0", "name": "rendering.mobile/list_animation_simple" }, { - "duration": "40.0", + "duration": "36.0", "name": "rendering.mobile/list_recycle_transform" }, { - "duration": "29.0", + "duration": "25.0", "name": "rendering.mobile/man_in_blue" }, { - "duration": "34.0", + "duration": "30.0", "name": "rendering.mobile/many_images" }, { - "duration": "29.0", + "duration": "27.0", "name": "rendering.mobile/many_planets_deep" }, { - "duration": "54.0", + "duration": "42.0", "name": "rendering.mobile/maps_perf_test" }, { - "duration": "26.0", + "duration": "23.0", "name": "rendering.mobile/mask_transition_animation" }, { - "duration": "35.0", + "duration": "31.0", "name": "rendering.mobile/medium_texture_uploads" }, { @@ -2808,223 +2856,223 @@ "name": "rendering.mobile/megi_dish" }, { - "duration": "30.0", + "duration": "26.0", "name": "rendering.mobile/microsoft_asteroid_belt" }, { - "duration": "28.0", + "duration": "25.0", "name": "rendering.mobile/microsoft_fish_ie_tank" }, { - "duration": "27.0", + "duration": "24.0", "name": "rendering.mobile/microsoft_snow" }, { - "duration": "29.0", + "duration": "26.0", "name": "rendering.mobile/microsoft_speed_reading" }, { - "duration": "27.0", + "duration": "24.0", "name": "rendering.mobile/microsoft_tweet_map" }, { - "duration": "33.0", + "duration": "28.0", "name": "rendering.mobile/microsoft_video_city" }, { - "duration": "23.0", + "duration": "22.0", "name": "rendering.mobile/microsoft_worker_fountains" }, { - "duration": "26.0", + "duration": "22.0", "name": "rendering.mobile/mix_10k" }, { - "duration": "26.0", + "duration": "25.0", "name": "rendering.mobile/mix_blend_mode_animation_difference" }, { - "duration": "26.0", + "duration": "25.0", "name": "rendering.mobile/mix_blend_mode_animation_hue" }, { - "duration": "36.0", + "duration": "32.0", "name": "rendering.mobile/mix_blend_mode_animation_propagating_isolation" }, { - "duration": "28.0", + "duration": "26.0", "name": "rendering.mobile/mix_blend_mode_animation_screen" }, { - "duration": "65.0", + "duration": "48.0", "name": "rendering.mobile/mlb_mobile_2018" }, { - "duration": "24.0", + "duration": "21.0", "name": "rendering.mobile/mobile_news_sandbox" }, { - "duration": "32.0", + "duration": "29.0", "name": "rendering.mobile/motion_mark_canvas_fill_shapes" }, { - "duration": "29.0", + "duration": "27.0", "name": "rendering.mobile/motion_mark_canvas_stroke_shapes" }, { - "duration": "34.0", + "duration": "28.0", "name": "rendering.mobile/motionmark_anim_design_15" }, { - "duration": "37.0", + "duration": "33.0", "name": "rendering.mobile/motionmark_anim_focus_25" }, { - "duration": "76.0", + "duration": "54.0", "name": "rendering.mobile/motionmark_anim_images_50" }, { - "duration": "39.0", + "duration": "34.0", "name": "rendering.mobile/motionmark_anim_leaves_250" }, { - "duration": "43.0", + "duration": "33.0", "name": "rendering.mobile/motionmark_anim_multiply_175" }, { - "duration": "40.0", + "duration": "33.0", "name": "rendering.mobile/motionmark_anim_suits_125" }, { - "duration": "40.0", + "duration": "34.0", "name": "rendering.mobile/motionmark_html_composited_transforms_125" }, { - "duration": "43.0", + "duration": "35.0", "name": "rendering.mobile/motionmark_html_css_bouncing_blend_circles_25" }, { - "duration": "41.0", + "duration": "34.0", "name": "rendering.mobile/motionmark_html_css_bouncing_circles_250" }, { - "duration": "36.0", + "duration": "31.0", "name": "rendering.mobile/motionmark_html_css_bouncing_clipped_rects_100" }, { - "duration": "42.0", + "duration": "33.0", "name": "rendering.mobile/motionmark_html_css_bouncing_filter_circles_15" }, { - "duration": "36.0", + "duration": "32.0", "name": "rendering.mobile/motionmark_html_css_bouncing_gradient_circles_250" }, { - "duration": "43.0", + "duration": "35.0", "name": "rendering.mobile/motionmark_html_css_bouncing_svg_images_50" }, { - "duration": "39.0", + "duration": "33.0", "name": "rendering.mobile/motionmark_html_css_bouncing_tagged_images_225" }, { - "duration": "43.0", + "duration": "33.0", "name": "rendering.mobile/motionmark_html_dom_particles_svg_masks_25" }, { - "duration": "38.0", + "duration": "32.0", "name": "rendering.mobile/motionmark_html_focus_20_15" }, { - "duration": "41.0", + "duration": "36.0", "name": "rendering.mobile/motionmark_html_leaves_20_50" }, { - "duration": "40.0", + "duration": "36.0", "name": "rendering.mobile/motionmark_svg_bouncing_circles_250" }, { - "duration": "36.0", + "duration": "31.0", "name": "rendering.mobile/motionmark_svg_bouncing_clipped_rects_100" }, { - "duration": "37.0", + "duration": "32.0", "name": "rendering.mobile/motionmark_svg_bouncing_gradient_circles_200" }, { - "duration": "41.0", + "duration": "35.0", "name": "rendering.mobile/motionmark_svg_bouncing_png_images_200" }, { - "duration": "83.0", + "duration": "56.0", "name": "rendering.mobile/motionmark_svg_bouncing_svg_images_50" }, { - "duration": "44.0", + "duration": "38.0", "name": "rendering.mobile/new_tilings" }, { - "duration": "32.0", + "duration": "27.0", "name": "rendering.mobile/no_op_raf" }, { - "duration": "25.0", + "duration": "24.0", "name": "rendering.mobile/no_op_scroll" }, { - "duration": "24.0", + "duration": "22.0", "name": "rendering.mobile/no_op_settimeout" }, { - "duration": "31.0", + "duration": "28.0", "name": "rendering.mobile/no_op_touch_handler" }, { - "duration": "30.0", + "duration": "28.0", "name": "rendering.mobile/nvidia_vertex_buffer_object" }, { - "duration": "54.0", + "duration": "41.0", "name": "rendering.mobile/nyc_gov_scroll_2018" }, { - "duration": "47.0", + "duration": "39.0", "name": "rendering.mobile/nytimes_mobile_2018" }, { - "duration": "59.0", + "duration": "44.0", "name": "rendering.mobile/nytimes_scroll_2018" }, { - "duration": "46.0", + "duration": "37.0", "name": "rendering.mobile/overlay_background_color_css_transitions_page" }, { - "duration": "28.0", + "duration": "25.0", "name": "rendering.mobile/parallax_effect" }, { - "duration": "35.0", + "duration": "28.0", "name": "rendering.mobile/particles" }, { - "duration": "37.0", + "duration": "31.0", "name": "rendering.mobile/pbs_pathological_2018" }, { - "duration": "26.0", + "duration": "21.0", "name": "rendering.mobile/physical_simulation" }, { - "duration": "49.0", + "duration": "38.0", "name": "rendering.mobile/pinterest_2018" }, { - "duration": "40.0", + "duration": "34.0", "name": "rendering.mobile/pinterest_desktop_gpu_raster_2018" }, { - "duration": "23.0", + "duration": "25.0", "name": "rendering.mobile/pinterest_mobile_2018" }, { @@ -3032,43 +3080,43 @@ "name": "rendering.mobile/put_get_image_data" }, { - "duration": "32.0", + "duration": "28.0", "name": "rendering.mobile/raf" }, { - "duration": "33.0", + "duration": "28.0", "name": "rendering.mobile/raf_animation" }, { - "duration": "30.0", + "duration": "28.0", "name": "rendering.mobile/raf_canvas" }, { - "duration": "31.0", + "duration": "28.0", "name": "rendering.mobile/raf_touch_animation" }, { - "duration": "47.0", + "duration": "38.0", "name": "rendering.mobile/recode_pathological_2018" }, { - "duration": "52.0", + "duration": "44.0", "name": "rendering.mobile/reddit_mobile_2018" }, { - "duration": "27.0", + "duration": "24.0", "name": "rendering.mobile/runway" }, { - "duration": "30.0", + "duration": "28.0", "name": "rendering.mobile/san_angeles" }, { - "duration": "22.0", + "duration": "19.0", "name": "rendering.mobile/second_batch_js_heavy" }, { - "duration": "19.0", + "duration": "18.0", "name": "rendering.mobile/second_batch_js_light" }, { @@ -3076,239 +3124,239 @@ "name": "rendering.mobile/second_batch_js_medium" }, { - "duration": "56.0", + "duration": "43.0", "name": "rendering.mobile/sfgate_mobile_2018" }, { - "duration": "45.0", + "duration": "35.0", "name": "rendering.mobile/silk_finance" }, { - "duration": "39.0", + "duration": "31.0", "name": "rendering.mobile/simple_text_page" }, { - "duration": "24.0", + "duration": "23.0", "name": "rendering.mobile/simple_touch_drag" }, { - "duration": "47.0", + "duration": "41.0", "name": "rendering.mobile/slashdot_mobile_2018" }, { - "duration": "39.0", + "duration": "33.0", "name": "rendering.mobile/small_texture_uploads" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/smash_cat" }, { - "duration": "24.0", + "duration": "23.0", "name": "rendering.mobile/spielzeugz" }, { - "duration": "29.0", + "duration": "24.0", "name": "rendering.mobile/sticky_using_webkit" }, { - "duration": "49.0", + "duration": "40.0", "name": "rendering.mobile/stress_hidey_bars" }, { - "duration": "24.0", + "duration": "22.0", "name": "rendering.mobile/stroke_shapes" }, { - "duration": "42.0", + "duration": "35.0", "name": "rendering.mobile/svg_icon_raster" }, { - "duration": "26.0", + "duration": "24.0", "name": "rendering.mobile/swipe_to_dismiss" }, { - "duration": "38.0", + "duration": "32.0", "name": "rendering.mobile/sync_scroll_offset" }, { - "duration": "58.0", + "duration": "45.0", "name": "rendering.mobile/techcrunch_2018" }, { - "duration": "50.0", + "duration": "41.0", "name": "rendering.mobile/techcrunch_desktop_gpu_raster_2018" }, { - "duration": "63.0", + "duration": "48.0", "name": "rendering.mobile/techcrunch_mobile_2018" }, { - "duration": "36.0", + "duration": "31.0", "name": "rendering.mobile/text_05000_pixels_per_second" }, { - "duration": "36.0", + "duration": "31.0", "name": "rendering.mobile/text_05000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "37.0", + "duration": "32.0", "name": "rendering.mobile/text_10000_pixels_per_second" }, { - "duration": "36.0", + "duration": "32.0", "name": "rendering.mobile/text_10000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "40.0", + "duration": "34.0", "name": "rendering.mobile/text_15000_pixels_per_second" }, { - "duration": "41.0", + "duration": "33.0", "name": "rendering.mobile/text_15000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "39.0", + "duration": "33.0", "name": "rendering.mobile/text_20000_pixels_per_second" }, { - "duration": "41.0", + "duration": "33.0", "name": "rendering.mobile/text_20000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "41.0", + "duration": "33.0", "name": "rendering.mobile/text_30000_pixels_per_second" }, { - "duration": "42.0", + "duration": "33.0", "name": "rendering.mobile/text_30000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "40.0", + "duration": "30.0", "name": "rendering.mobile/text_40000_pixels_per_second" }, { - "duration": "34.0", + "duration": "31.0", "name": "rendering.mobile/text_40000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "30.0", + "duration": "27.0", "name": "rendering.mobile/text_50000_pixels_per_second" }, { - "duration": "36.0", + "duration": "28.0", "name": "rendering.mobile/text_50000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "32.0", + "duration": "24.0", "name": "rendering.mobile/text_60000_pixels_per_second" }, { - "duration": "31.0", + "duration": "25.0", "name": "rendering.mobile/text_60000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "29.0", + "duration": "24.0", "name": "rendering.mobile/text_75000_pixels_per_second" }, { - "duration": "27.0", + "duration": "24.0", "name": "rendering.mobile/text_75000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "25.0", + "duration": "23.0", "name": "rendering.mobile/text_90000_pixels_per_second" }, { - "duration": "25.0", + "duration": "23.0", "name": "rendering.mobile/text_90000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "31.0", + "duration": "27.0", "name": "rendering.mobile/text_constant_full_page_raster_05000_pixels_per_second" }, { - "duration": "30.0", + "duration": "28.0", "name": "rendering.mobile/text_constant_full_page_raster_05000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "32.0", + "duration": "27.0", "name": "rendering.mobile/text_constant_full_page_raster_10000_pixels_per_second" }, { - "duration": "29.0", + "duration": "27.0", "name": "rendering.mobile/text_constant_full_page_raster_10000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "31.0", + "duration": "26.0", "name": "rendering.mobile/text_constant_full_page_raster_15000_pixels_per_second" }, { - "duration": "30.0", + "duration": "27.0", "name": "rendering.mobile/text_constant_full_page_raster_15000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "30.0", + "duration": "27.0", "name": "rendering.mobile/text_constant_full_page_raster_20000_pixels_per_second" }, { - "duration": "29.0", + "duration": "27.0", "name": "rendering.mobile/text_constant_full_page_raster_20000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/text_constant_full_page_raster_30000_pixels_per_second" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/text_constant_full_page_raster_30000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "29.0", + "duration": "26.0", "name": "rendering.mobile/text_constant_full_page_raster_40000_pixels_per_second" }, { - "duration": "30.0", + "duration": "26.0", "name": "rendering.mobile/text_constant_full_page_raster_40000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "26.0", + "duration": "24.0", "name": "rendering.mobile/text_constant_full_page_raster_50000_pixels_per_second" }, { - "duration": "29.0", + "duration": "24.0", "name": "rendering.mobile/text_constant_full_page_raster_50000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "24.0", + "duration": "23.0", "name": "rendering.mobile/text_constant_full_page_raster_60000_pixels_per_second" }, { - "duration": "28.0", + "duration": "22.0", "name": "rendering.mobile/text_constant_full_page_raster_60000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "23.0", + "duration": "21.0", "name": "rendering.mobile/text_constant_full_page_raster_75000_pixels_per_second" }, { - "duration": "28.0", + "duration": "21.0", "name": "rendering.mobile/text_constant_full_page_raster_75000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "26.0", + "duration": "21.0", "name": "rendering.mobile/text_constant_full_page_raster_90000_pixels_per_second" }, { - "duration": "23.0", + "duration": "21.0", "name": "rendering.mobile/text_constant_full_page_raster_90000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "21.0", + "duration": "22.0", "name": "rendering.mobile/text_hover_05000_pixels_per_second" }, { - "duration": "25.0", + "duration": "22.0", "name": "rendering.mobile/text_hover_05000_pixels_per_second_desktop_gpu_raster" }, { @@ -3320,23 +3368,23 @@ "name": "rendering.mobile/text_hover_10000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "25.0", + "duration": "23.0", "name": "rendering.mobile/text_hover_15000_pixels_per_second" }, { - "duration": "26.0", + "duration": "22.0", "name": "rendering.mobile/text_hover_15000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "25.0", + "duration": "22.0", "name": "rendering.mobile/text_hover_20000_pixels_per_second" }, { - "duration": "22.0", + "duration": "23.0", "name": "rendering.mobile/text_hover_20000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "23.0", + "duration": "22.0", "name": "rendering.mobile/text_hover_30000_pixels_per_second" }, { @@ -3352,7 +3400,7 @@ "name": "rendering.mobile/text_hover_40000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "22.0", + "duration": "20.0", "name": "rendering.mobile/text_hover_50000_pixels_per_second" }, { @@ -3360,83 +3408,83 @@ "name": "rendering.mobile/text_hover_50000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "21.0", + "duration": "20.0", "name": "rendering.mobile/text_hover_60000_pixels_per_second" }, { - "duration": "19.0", + "duration": "20.0", "name": "rendering.mobile/text_hover_60000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "18.0", + "duration": "19.0", "name": "rendering.mobile/text_hover_75000_pixels_per_second" }, { - "duration": "18.0", + "duration": "20.0", "name": "rendering.mobile/text_hover_75000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "18.0", + "duration": "19.0", "name": "rendering.mobile/text_hover_90000_pixels_per_second" }, { - "duration": "17.0", + "duration": "18.0", "name": "rendering.mobile/text_hover_90000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "59.0", + "duration": "42.0", "name": "rendering.mobile/theverge_article_mobile_2018" }, { - "duration": "60.0", + "duration": "46.0", "name": "rendering.mobile/theverge_mobile_2018" }, { - "duration": "30.0", + "duration": "28.0", "name": "rendering.mobile/toggle_drawer" }, { - "duration": "36.0", + "duration": "31.0", "name": "rendering.mobile/touch_handler_scrolling" }, { - "duration": "35.0", + "duration": "32.0", "name": "rendering.mobile/transform_transitions" }, { - "duration": "37.0", + "duration": "33.0", "name": "rendering.mobile/transform_transitions_js_block" }, { - "duration": "40.0", + "duration": "34.0", "name": "rendering.mobile/twitch_2018" }, { - "duration": "38.0", + "duration": "30.0", "name": "rendering.mobile/twitch_desktop_gpu_raster_2018" }, { - "duration": "47.0", + "duration": "34.0", "name": "rendering.mobile/twitter_2018" }, { - "duration": "43.0", + "duration": "33.0", "name": "rendering.mobile/twitter_desktop_gpu_raster_2018" }, { - "duration": "29.0", + "duration": "31.0", "name": "rendering.mobile/twitter_mobile_2018" }, { - "duration": "30.0", + "duration": "27.0", "name": "rendering.mobile/update_history_state" }, { - "duration": "34.0", + "duration": "23.0", "name": "rendering.mobile/usatoday_mobile_2018" }, { - "duration": "30.0", + "duration": "26.0", "name": "rendering.mobile/vertical_expansion" }, { @@ -3444,31 +3492,31 @@ "name": "rendering.mobile/web_animation_value_type_color" }, { - "duration": "33.0", + "duration": "31.0", "name": "rendering.mobile/web_animation_value_type_length_3d" }, { - "duration": "35.0", + "duration": "32.0", "name": "rendering.mobile/web_animation_value_type_length_complex" }, { - "duration": "36.0", + "duration": "33.0", "name": "rendering.mobile/web_animation_value_type_length_simple" }, { - "duration": "29.0", + "duration": "30.0", "name": "rendering.mobile/web_animation_value_type_path" }, { - "duration": "25.0", + "duration": "27.0", "name": "rendering.mobile/web_animation_value_type_shadow" }, { - "duration": "33.0", + "duration": "31.0", "name": "rendering.mobile/web_animation_value_type_transform_complex" }, { - "duration": "35.0", + "duration": "32.0", "name": "rendering.mobile/web_animation_value_type_transform_simple" }, { @@ -3476,15 +3524,15 @@ "name": "rendering.mobile/web_animations_many_keyframes" }, { - "duration": "38.0", + "duration": "32.0", "name": "rendering.mobile/web_animations_set_current_time" }, { - "duration": "35.0", + "duration": "32.0", "name": "rendering.mobile/web_animations_simultaneous" }, { - "duration": "35.0", + "duration": "33.0", "name": "rendering.mobile/web_animations_staggered_chaining" }, { @@ -3492,255 +3540,255 @@ "name": "rendering.mobile/web_animations_staggered_infinite_iterations" }, { - "duration": "39.0", + "duration": "33.0", "name": "rendering.mobile/web_animations_staggered_triggering_page" }, { - "duration": "47.0", + "duration": "40.0", "name": "rendering.mobile/wikipedia_2018" }, { - "duration": "50.0", + "duration": "42.0", "name": "rendering.mobile/wikipedia_delayed_scroll_start_2018" }, { - "duration": "43.0", + "duration": "35.0", "name": "rendering.mobile/wikipedia_desktop_gpu_raster_2018" }, { - "duration": "40.0", + "duration": "35.0", "name": "rendering.mobile/wikipedia_mobile_2018" }, { - "duration": "50.0", + "duration": "42.0", "name": "rendering.mobile/wordpress_2018" }, { - "duration": "50.0", + "duration": "47.0", "name": "rendering.mobile/wordpress_desktop_gpu_raster_2018" }, { - "duration": "53.0", + "duration": "42.0", "name": "rendering.mobile/wordpress_mobile_2018" }, { - "duration": "47.0", + "duration": "37.0", "name": "rendering.mobile/worldjournal_mobile_2018" }, { - "duration": "56.0", + "duration": "43.0", "name": "rendering.mobile/wow_wiki_pathological_2018" }, { - "duration": "102.0", + "duration": "73.0", "name": "rendering.mobile/wowwiki_mobile_2018" }, { - "duration": "72.0", + "duration": "49.0", "name": "rendering.mobile/wsj_mobile_2018" }, { - "duration": "35.0", + "duration": "28.0", "name": "rendering.mobile/yahoo_answers_2018" }, { - "duration": "31.0", + "duration": "24.0", "name": "rendering.mobile/yahoo_answers_desktop_gpu_raster_2018" }, { - "duration": "33.0", + "duration": "25.0", "name": "rendering.mobile/yahoo_news_2018" }, { - "duration": "32.0", + "duration": "25.0", "name": "rendering.mobile/yahoo_news_desktop_gpu_raster_2018" }, { - "duration": "51.0", + "duration": "44.0", "name": "rendering.mobile/yahoo_news_mobile_2018" }, { - "duration": "35.0", + "duration": "33.0", "name": "rendering.mobile/yahoo_sports_2018" }, { - "duration": "30.0", + "duration": "28.0", "name": "rendering.mobile/yahoo_sports_desktop_gpu_raster_2018" }, { - "duration": "34.0", + "duration": "21.0", "name": "rendering.mobile/yahoo_sports_pathological_2018" }, { - "duration": "30.0", + "duration": "26.0", "name": "rendering.mobile/youtube_2018" }, { - "duration": "23.0", + "duration": "22.0", "name": "rendering.mobile/youtube_desktop_gpu_raster_2018" }, { - "duration": "31.0", + "duration": "27.0", "name": "rendering.mobile/youtube_mobile_2018" }, { - "duration": "39.0", + "duration": "33.0", "name": "rendering.mobile/yuv_decoding" }, { - "duration": "41.0", + "duration": "33.0", "name": "rendering.mobile/yuv_decoding_gpu_rasterization_and_decoding" }, { - "duration": "50.0", + "duration": "36.0", "name": "rendering.mobile/zdnet_pathological_2018" }, { - "duration": "28.0", + "duration": "24.0", "name": "rendering.mobile/zoom_in_animation" }, { - "duration": "61.0", + "duration": "42.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/accu_weather_pinch_2018" }, { - "duration": "40.0", + "duration": "31.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/amazon_pinch_2018" }, { - "duration": "36.0", + "duration": "28.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/blogspot_pinch_2018" }, { - "duration": "39.0", + "duration": "30.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/booking_pinch_2018" }, { - "duration": "49.0", + "duration": "32.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/cnn_pinch_2018" }, { - "duration": "32.0", + "duration": "27.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/ebay_pinch_2018" }, { - "duration": "39.0", + "duration": "31.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/espn_pinch_2018" }, { - "duration": "35.0", + "duration": "28.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/facebook_pinch_2018" }, { - "duration": "74.0", + "duration": "50.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/gmail_pinch_2018" }, { - "duration": "54.0", + "duration": "40.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_calendar_pinch_2018" }, { - "duration": "33.0", + "duration": "27.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_image_pinch_2018" }, { - "duration": "48.0", + "duration": "37.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_search_pinch_2018" }, { - "duration": "54.0", + "duration": "43.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/linkedin_pinch_2018" }, { - "duration": "34.0", + "duration": "28.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/twitch_pinch_2018" }, { - "duration": "33.0", + "duration": "28.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/twitter_pinch_2018" }, { - "duration": "52.0", + "duration": "35.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_news_pinch_2018" }, { - "duration": "57.0", + "duration": "39.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_sports_pinch_2018" }, { - "duration": "30.0", + "duration": "28.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/youtube_pinch_2018" }, { - "duration": "60.0", + "duration": "42.0", "name": "smoothness.tough_pinch_zoom_cases/accu_weather_pinch_2018" }, { - "duration": "38.0", + "duration": "31.0", "name": "smoothness.tough_pinch_zoom_cases/amazon_pinch_2018" }, { - "duration": "40.0", + "duration": "28.0", "name": "smoothness.tough_pinch_zoom_cases/blogspot_pinch_2018" }, { - "duration": "40.0", + "duration": "31.0", "name": "smoothness.tough_pinch_zoom_cases/booking_pinch_2018" }, { - "duration": "39.0", + "duration": "33.0", "name": "smoothness.tough_pinch_zoom_cases/cnn_pinch_2018" }, { - "duration": "31.0", + "duration": "28.0", "name": "smoothness.tough_pinch_zoom_cases/ebay_pinch_2018" }, { - "duration": "41.0", + "duration": "32.0", "name": "smoothness.tough_pinch_zoom_cases/espn_pinch_2018" }, { - "duration": "38.0", + "duration": "28.0", "name": "smoothness.tough_pinch_zoom_cases/facebook_pinch_2018" }, { - "duration": "68.0", + "duration": "51.0", "name": "smoothness.tough_pinch_zoom_cases/gmail_pinch_2018" }, { - "duration": "51.0", + "duration": "41.0", "name": "smoothness.tough_pinch_zoom_cases/google_calendar_pinch_2018" }, { - "duration": "32.0", + "duration": "28.0", "name": "smoothness.tough_pinch_zoom_cases/google_image_pinch_2018" }, { - "duration": "47.0", + "duration": "37.0", "name": "smoothness.tough_pinch_zoom_cases/google_search_pinch_2018" }, { - "duration": "53.0", + "duration": "43.0", "name": "smoothness.tough_pinch_zoom_cases/linkedin_pinch_2018" }, { - "duration": "32.0", + "duration": "29.0", "name": "smoothness.tough_pinch_zoom_cases/twitch_pinch_2018" }, { - "duration": "33.0", + "duration": "28.0", "name": "smoothness.tough_pinch_zoom_cases/twitter_pinch_2018" }, { - "duration": "47.0", + "duration": "36.0", "name": "smoothness.tough_pinch_zoom_cases/yahoo_news_pinch_2018" }, { - "duration": "56.0", + "duration": "41.0", "name": "smoothness.tough_pinch_zoom_cases/yahoo_sports_pinch_2018" }, { - "duration": "35.0", + "duration": "29.0", "name": "smoothness.tough_pinch_zoom_cases/youtube_pinch_2018" }, { @@ -3748,187 +3796,227 @@ "name": "speedometer-future/http://browserbench.org/Speedometer/" }, { - "duration": "34.0", + "duration": "36.0", "name": "speedometer/http://browserbench.org/Speedometer/" }, { - "duration": "59.0", + "duration": "62.0", "name": "speedometer2-future/Speedometer2" }, { - "duration": "27.0", - "name": "system_health.common_mobile/background:media:imgur" - }, - { - "duration": "28.0", - "name": "system_health.common_mobile/background:search:google" - }, - { - "duration": "39.0", - "name": "system_health.common_mobile/background:social:facebook" - }, - { - "duration": "99.0", - "name": "system_health.common_mobile/browse:chrome:newtab" - }, - { - "duration": "39.0", - "name": "system_health.common_mobile/browse:chrome:omnibox" - }, - { - "duration": "114.0", - "name": "system_health.common_mobile/browse:media:facebook_photos" - }, - { - "duration": "78.0", - "name": "system_health.common_mobile/browse:media:flickr_infinite_scroll" - }, - { - "duration": "110.0", - "name": "system_health.common_mobile/browse:media:imgur" - }, - { - "duration": "133.0", - "name": "system_health.common_mobile/browse:media:youtube" - }, - { - "duration": "149.0", - "name": "system_health.common_mobile/browse:news:cnn" - }, - { - "duration": "123.0", - "name": "system_health.common_mobile/browse:news:cnn:2018" - }, - { - "duration": "96.0", - "name": "system_health.common_mobile/browse:news:cricbuzz" - }, - { - "duration": "82.0", - "name": "system_health.common_mobile/browse:news:qq" - }, - { - "duration": "70.0", - "name": "system_health.common_mobile/browse:news:reddit" - }, - { - "duration": "218.0", - "name": "system_health.common_mobile/browse:news:toi" - }, - { - "duration": "80.0", - "name": "system_health.common_mobile/browse:news:washingtonpost" - }, - { - "duration": "109.0", - "name": "system_health.common_mobile/browse:shopping:amazon" - }, - { - "duration": "111.0", - "name": "system_health.common_mobile/browse:shopping:avito" - }, - { - "duration": "51.0", - "name": "system_health.common_mobile/browse:shopping:lazada" - }, - { - "duration": "109.0", - "name": "system_health.common_mobile/browse:social:facebook" - }, - { - "duration": "544.0", - "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll" - }, - { - "duration": "162.0", - "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll:2018" - }, - { - "duration": "108.0", - "name": "system_health.common_mobile/browse:social:instagram" - }, - { - "duration": "133.0", - "name": "system_health.common_mobile/browse:social:pinterest_infinite_scroll" - }, - { - "duration": "183.0", - "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll" - }, - { - "duration": "76.0", - "name": "system_health.common_mobile/browse:social:twitter" - }, - { - "duration": "112.0", - "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll" + "duration": "61.0", + "name": "speedometer2/Speedometer2" }, { "duration": "151.0", - "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll:2018" + "name": "startup.mobile/cct:coldish:bbc" }, { - "duration": "64.0", - "name": "system_health.common_mobile/browse:tools:maps" + "duration": "155.0", + "name": "startup.mobile/intent:coldish:bbc" + }, + { + "duration": "128.0", + "name": "startup.mobile/intent:warm:bbc" }, { "duration": "26.0", - "name": "system_health.common_mobile/load:chrome:blank" + "name": "system_health.common_mobile/background:media:imgur" }, { - "duration": "32.0", - "name": "system_health.common_mobile/load:games:bubbles" + "duration": "27.0", + "name": "system_health.common_mobile/background:search:google" + }, + { + "duration": "36.0", + "name": "system_health.common_mobile/background:social:facebook" + }, + { + "duration": "100.0", + "name": "system_health.common_mobile/browse:chrome:newtab" + }, + { + "duration": "35.0", + "name": "system_health.common_mobile/browse:chrome:omnibox" + }, + { + "duration": "93.0", + "name": "system_health.common_mobile/browse:media:facebook_photos" + }, + { + "duration": "63.0", + "name": "system_health.common_mobile/browse:media:flickr_infinite_scroll" + }, + { + "duration": "89.0", + "name": "system_health.common_mobile/browse:media:imgur" + }, + { + "duration": "111.0", + "name": "system_health.common_mobile/browse:media:youtube" + }, + { + "duration": "105.0", + "name": "system_health.common_mobile/browse:news:cnn" + }, + { + "duration": "83.0", + "name": "system_health.common_mobile/browse:news:cnn:2018" + }, + { + "duration": "74.0", + "name": "system_health.common_mobile/browse:news:cricbuzz" + }, + { + "duration": "73.0", + "name": "system_health.common_mobile/browse:news:qq" + }, + { + "duration": "62.0", + "name": "system_health.common_mobile/browse:news:reddit" + }, + { + "duration": "148.0", + "name": "system_health.common_mobile/browse:news:toi" + }, + { + "duration": "65.0", + "name": "system_health.common_mobile/browse:news:washingtonpost" + }, + { + "duration": "81.0", + "name": "system_health.common_mobile/browse:shopping:amazon" + }, + { + "duration": "77.0", + "name": "system_health.common_mobile/browse:shopping:avito" + }, + { + "duration": "41.0", + "name": "system_health.common_mobile/browse:shopping:lazada" + }, + { + "duration": "84.0", + "name": "system_health.common_mobile/browse:social:facebook" + }, + { + "duration": "217.0", + "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll" + }, + { + "duration": "122.0", + "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll:2018" + }, + { + "duration": "92.0", + "name": "system_health.common_mobile/browse:social:instagram" + }, + { + "duration": "105.0", + "name": "system_health.common_mobile/browse:social:pinterest_infinite_scroll" + }, + { + "duration": "128.0", + "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll" + }, + { + "duration": "65.0", + "name": "system_health.common_mobile/browse:social:twitter" + }, + { + "duration": "82.0", + "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll" + }, + { + "duration": "114.0", + "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll:2018" + }, + { + "duration": "54.0", + "name": "system_health.common_mobile/browse:tools:maps" }, { "duration": "23.0", - "name": "system_health.common_mobile/load:games:lazors" - }, - { - "duration": "42.0", - "name": "system_health.common_mobile/load:games:spychase" + "name": "system_health.common_mobile/load:chrome:blank" }, { "duration": "28.0", + "name": "system_health.common_mobile/load:games:bubbles" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:games:lazors" + }, + { + "duration": "36.0", + "name": "system_health.common_mobile/load:games:spychase" + }, + { + "duration": "37.0", + "name": "system_health.common_mobile/load:games:spychase:2018" + }, + { + "duration": "27.0", "name": "system_health.common_mobile/load:media:dailymotion" }, { - "duration": "30.0", + "duration": "26.0", "name": "system_health.common_mobile/load:media:facebook_photos" }, { - "duration": "27.0", + "duration": "29.0", + "name": "system_health.common_mobile/load:media:flickr:2018" + }, + { + "duration": "26.0", "name": "system_health.common_mobile/load:media:google_images" }, { - "duration": "31.0", + "duration": "25.0", + "name": "system_health.common_mobile/load:media:google_images:2018" + }, + { + "duration": "25.0", "name": "system_health.common_mobile/load:media:imgur" }, { - "duration": "27.0", + "duration": "34.0", + "name": "system_health.common_mobile/load:media:imgur:2018" + }, + { + "duration": "25.0", "name": "system_health.common_mobile/load:media:soundcloud" }, { + "duration": "25.0", + "name": "system_health.common_mobile/load:media:soundcloud:2018" + }, + { "duration": "26.0", "name": "system_health.common_mobile/load:media:youtube" }, { - "duration": "44.0", + "duration": "28.0", + "name": "system_health.common_mobile/load:media:youtube:2018" + }, + { + "duration": "36.0", "name": "system_health.common_mobile/load:news:cnn" }, { - "duration": "40.0", + "duration": "33.0", "name": "system_health.common_mobile/load:news:cnn:2018" }, { - "duration": "33.0", + "duration": "29.0", "name": "system_health.common_mobile/load:news:irctc" }, { - "duration": "31.0", + "duration": "29.0", "name": "system_health.common_mobile/load:news:nytimes" }, { - "duration": "26.0", + "duration": "27.0", "name": "system_health.common_mobile/load:news:qq" }, { @@ -3936,83 +4024,107 @@ "name": "system_health.common_mobile/load:news:reddit" }, { - "duration": "34.0", + "duration": "27.0", "name": "system_health.common_mobile/load:news:washingtonpost" }, { - "duration": "29.0", + "duration": "26.0", "name": "system_health.common_mobile/load:news:wikipedia" }, { - "duration": "25.0", + "duration": "26.0", + "name": "system_health.common_mobile/load:news:wikipedia:2018" + }, + { + "duration": "28.0", "name": "system_health.common_mobile/load:search:baidu" }, { - "duration": "31.0", + "duration": "30.0", + "name": "system_health.common_mobile/load:search:baidu:2018" + }, + { + "duration": "26.0", "name": "system_health.common_mobile/load:search:ebay" }, { - "duration": "26.0", + "duration": "28.0", + "name": "system_health.common_mobile/load:search:ebay:2018" + }, + { + "duration": "24.0", "name": "system_health.common_mobile/load:search:google" }, { - "duration": "29.0", - "name": "system_health.common_mobile/load:search:taobao" - }, - { "duration": "26.0", - "name": "system_health.common_mobile/load:search:yahoo" + "name": "system_health.common_mobile/load:search:google:2018" }, { "duration": "27.0", + "name": "system_health.common_mobile/load:search:taobao" + }, + { + "duration": "25.0", + "name": "system_health.common_mobile/load:search:yahoo" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:search:yahoo:2018" + }, + { + "duration": "25.0", "name": "system_health.common_mobile/load:search:yandex" }, { + "duration": "27.0", + "name": "system_health.common_mobile/load:search:yandex:2018" + }, + { "duration": "25.0", "name": "system_health.common_mobile/load:social:twitter" }, { - "duration": "26.0", + "duration": "25.0", "name": "system_health.common_mobile/load:tools:docs" }, { - "duration": "33.0", + "duration": "28.0", "name": "system_health.common_mobile/load:tools:drive" }, { - "duration": "28.0", + "duration": "24.0", "name": "system_health.common_mobile/load:tools:dropbox" }, { - "duration": "31.0", + "duration": "26.0", "name": "system_health.common_mobile/load:tools:stackoverflow" }, { - "duration": "30.0", + "duration": "26.0", "name": "system_health.common_mobile/load:tools:stackoverflow:2018" }, { - "duration": "36.0", + "duration": "30.0", "name": "system_health.common_mobile/load:tools:weather" }, { - "duration": "29.0", + "duration": "30.0", "name": "system_health.memory_mobile/background:media:imgur" }, { - "duration": "31.0", + "duration": "30.0", "name": "system_health.memory_mobile/background:search:google" }, { - "duration": "31.0", + "duration": "32.0", "name": "system_health.memory_mobile/background:social:facebook" }, { - "duration": "83.0", + "duration": "82.0", "name": "system_health.memory_mobile/browse:chrome:newtab" }, { - "duration": "37.0", + "duration": "36.0", "name": "system_health.memory_mobile/browse:chrome:omnibox" }, { @@ -4020,39 +4132,39 @@ "name": "system_health.memory_mobile/browse:media:facebook_photos" }, { - "duration": "53.0", + "duration": "52.0", "name": "system_health.memory_mobile/browse:media:flickr_infinite_scroll" }, { - "duration": "76.0", + "duration": "75.0", "name": "system_health.memory_mobile/browse:media:imgur" }, { - "duration": "86.0", + "duration": "87.0", "name": "system_health.memory_mobile/browse:media:youtube" }, { - "duration": "65.0", + "duration": "63.0", "name": "system_health.memory_mobile/browse:news:cnn" }, { - "duration": "57.0", + "duration": "55.0", "name": "system_health.memory_mobile/browse:news:cnn:2018" }, { - "duration": "62.0", + "duration": "64.0", "name": "system_health.memory_mobile/browse:news:cricbuzz" }, { - "duration": "53.0", + "duration": "60.0", "name": "system_health.memory_mobile/browse:news:qq" }, { - "duration": "53.0", + "duration": "54.0", "name": "system_health.memory_mobile/browse:news:reddit" }, { - "duration": "77.0", + "duration": "76.0", "name": "system_health.memory_mobile/browse:news:toi" }, { @@ -4060,55 +4172,59 @@ "name": "system_health.memory_mobile/browse:news:washingtonpost" }, { - "duration": "55.0", + "duration": "57.0", "name": "system_health.memory_mobile/browse:shopping:amazon" }, { - "duration": "40.0", + "duration": "59.0", + "name": "system_health.memory_mobile/browse:shopping:avito" + }, + { + "duration": "37.0", "name": "system_health.memory_mobile/browse:shopping:lazada" }, { - "duration": "64.0", + "duration": "65.0", "name": "system_health.memory_mobile/browse:social:facebook" }, { - "duration": "79.0", + "duration": "80.0", "name": "system_health.memory_mobile/browse:social:facebook_infinite_scroll" }, { - "duration": "81.0", + "duration": "80.0", "name": "system_health.memory_mobile/browse:social:facebook_infinite_scroll:2018" }, { - "duration": "75.0", + "duration": "76.0", "name": "system_health.memory_mobile/browse:social:instagram" }, { - "duration": "76.0", + "duration": "74.0", "name": "system_health.memory_mobile/browse:social:pinterest_infinite_scroll" }, { - "duration": "76.0", + "duration": "75.0", "name": "system_health.memory_mobile/browse:social:tumblr_infinite_scroll" }, { - "duration": "55.0", + "duration": "53.0", "name": "system_health.memory_mobile/browse:social:twitter" }, { - "duration": "59.0", + "duration": "58.0", "name": "system_health.memory_mobile/browse:tech:discourse_infinite_scroll" }, { - "duration": "71.0", + "duration": "74.0", "name": "system_health.memory_mobile/browse:tech:discourse_infinite_scroll:2018" }, { - "duration": "51.0", + "duration": "50.0", "name": "system_health.memory_mobile/browse:tools:maps" }, { - "duration": "26.0", + "duration": "27.0", "name": "system_health.memory_mobile/load:chrome:blank" }, { @@ -4116,7 +4232,7 @@ "name": "system_health.memory_mobile/load:games:bubbles" }, { - "duration": "30.0", + "duration": "28.0", "name": "system_health.memory_mobile/load:games:lazors" }, { @@ -4124,39 +4240,63 @@ "name": "system_health.memory_mobile/load:games:spychase" }, { - "duration": "29.0", + "duration": "33.0", + "name": "system_health.memory_mobile/load:games:spychase:2018" + }, + { + "duration": "30.0", "name": "system_health.memory_mobile/load:media:dailymotion" }, { - "duration": "30.0", + "duration": "29.0", "name": "system_health.memory_mobile/load:media:facebook_photos" }, { - "duration": "30.0", + "duration": "31.0", + "name": "system_health.memory_mobile/load:media:flickr:2018" + }, + { + "duration": "29.0", "name": "system_health.memory_mobile/load:media:google_images" }, { - "duration": "28.0", + "duration": "29.0", + "name": "system_health.memory_mobile/load:media:google_images:2018" + }, + { + "duration": "29.0", "name": "system_health.memory_mobile/load:media:imgur" }, { - "duration": "28.0", + "duration": "30.0", + "name": "system_health.memory_mobile/load:media:imgur:2018" + }, + { + "duration": "29.0", "name": "system_health.memory_mobile/load:media:soundcloud" }, { "duration": "28.0", + "name": "system_health.memory_mobile/load:media:soundcloud:2018" + }, + { + "duration": "29.0", "name": "system_health.memory_mobile/load:media:youtube" }, { - "duration": "32.0", - "name": "system_health.memory_mobile/load:news:cnn" + "duration": "29.0", + "name": "system_health.memory_mobile/load:media:youtube:2018" }, { "duration": "34.0", + "name": "system_health.memory_mobile/load:news:cnn" + }, + { + "duration": "32.0", "name": "system_health.memory_mobile/load:news:cnn:2018" }, { - "duration": "30.0", + "duration": "29.0", "name": "system_health.memory_mobile/load:news:irctc" }, { @@ -4164,7 +4304,7 @@ "name": "system_health.memory_mobile/load:news:nytimes" }, { - "duration": "27.0", + "duration": "31.0", "name": "system_health.memory_mobile/load:news:qq" }, { @@ -4172,27 +4312,43 @@ "name": "system_health.memory_mobile/load:news:reddit" }, { - "duration": "30.0", + "duration": "29.0", "name": "system_health.memory_mobile/load:news:washingtonpost" }, { - "duration": "30.0", + "duration": "29.0", "name": "system_health.memory_mobile/load:news:wikipedia" }, { "duration": "29.0", + "name": "system_health.memory_mobile/load:news:wikipedia:2018" + }, + { + "duration": "31.0", "name": "system_health.memory_mobile/load:search:baidu" }, { - "duration": "29.0", + "duration": "32.0", + "name": "system_health.memory_mobile/load:search:baidu:2018" + }, + { + "duration": "28.0", "name": "system_health.memory_mobile/load:search:ebay" }, { "duration": "29.0", + "name": "system_health.memory_mobile/load:search:ebay:2018" + }, + { + "duration": "28.0", "name": "system_health.memory_mobile/load:search:google" }, { "duration": "29.0", + "name": "system_health.memory_mobile/load:search:google:2018" + }, + { + "duration": "30.0", "name": "system_health.memory_mobile/load:search:taobao" }, { @@ -4201,10 +4357,18 @@ }, { "duration": "28.0", - "name": "system_health.memory_mobile/load:search:yandex" + "name": "system_health.memory_mobile/load:search:yahoo:2018" }, { "duration": "28.0", + "name": "system_health.memory_mobile/load:search:yandex" + }, + { + "duration": "29.0", + "name": "system_health.memory_mobile/load:search:yandex:2018" + }, + { + "duration": "29.0", "name": "system_health.memory_mobile/load:social:twitter" }, { @@ -4212,11 +4376,11 @@ "name": "system_health.memory_mobile/load:tools:docs" }, { - "duration": "28.0", + "duration": "29.0", "name": "system_health.memory_mobile/load:tools:drive" }, { - "duration": "29.0", + "duration": "28.0", "name": "system_health.memory_mobile/load:tools:dropbox" }, { @@ -4228,7 +4392,7 @@ "name": "system_health.memory_mobile/load:tools:stackoverflow:2018" }, { - "duration": "31.0", + "duration": "30.0", "name": "system_health.memory_mobile/load:tools:weather" }, { @@ -4236,243 +4400,239 @@ "name": "tracing.tracing_with_background_memory_infra/Facebook" }, { - "duration": "17.0", + "duration": "16.0", "name": "tracing.tracing_with_background_memory_infra/Wikipedia" }, { - "duration": "11.0", + "duration": "15.0", "name": "tracing.tracing_with_background_memory_infra/http://www.amazon.com" }, { - "duration": "13.0", + "duration": "15.0", "name": "tracing.tracing_with_background_memory_infra/http://www.ask.com/" }, { - "duration": "19.0", + "duration": "15.0", "name": "tracing.tracing_with_background_memory_infra/http://www.bing.com/" }, { - "duration": "11.0", + "duration": "15.0", "name": "tracing.tracing_with_background_memory_infra/http://www.yahoo.com/" }, { - "duration": "14.0", + "duration": "16.0", "name": "tracing.tracing_with_background_memory_infra/http://www.youtube.com" }, { - "duration": "21.0", + "duration": "22.0", "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/#hl=en&q=barack+obama" }, { - "duration": "15.0", + "duration": "16.0", "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/calendar/" }, { - "duration": "125.0", + "duration": "135.0", "name": "v8.browsing_mobile-future/browse:chrome:newtab" }, { - "duration": "44.0", + "duration": "40.0", "name": "v8.browsing_mobile-future/browse:chrome:omnibox" }, { - "duration": "149.0", + "duration": "117.0", "name": "v8.browsing_mobile-future/browse:media:facebook_photos" }, { - "duration": "122.0", + "duration": "88.0", "name": "v8.browsing_mobile-future/browse:media:flickr_infinite_scroll" }, { - "duration": "141.0", + "duration": "111.0", "name": "v8.browsing_mobile-future/browse:media:imgur" }, { - "duration": "187.0", + "duration": "135.0", "name": "v8.browsing_mobile-future/browse:media:youtube" }, { - "duration": "269.0", + "duration": "208.0", "name": "v8.browsing_mobile-future/browse:news:cnn" }, { - "duration": "195.0", + "duration": "138.0", "name": "v8.browsing_mobile-future/browse:news:cnn:2018" }, { - "duration": "133.0", + "duration": "90.0", "name": "v8.browsing_mobile-future/browse:news:cricbuzz" }, { - "duration": "113.0", + "duration": "92.0", "name": "v8.browsing_mobile-future/browse:news:qq" }, { - "duration": "95.0", + "duration": "78.0", "name": "v8.browsing_mobile-future/browse:news:reddit" }, { - "duration": "568.0", + "duration": "292.0", "name": "v8.browsing_mobile-future/browse:news:toi" }, { - "duration": "117.0", + "duration": "88.0", "name": "v8.browsing_mobile-future/browse:news:washingtonpost" }, { - "duration": "165.0", + "duration": "129.0", "name": "v8.browsing_mobile-future/browse:shopping:amazon" }, { - "duration": "153.0", - "name": "v8.browsing_mobile-future/browse:shopping:avito" - }, - { - "duration": "73.0", + "duration": "52.0", "name": "v8.browsing_mobile-future/browse:shopping:lazada" }, { - "duration": "164.0", + "duration": "120.0", "name": "v8.browsing_mobile-future/browse:social:facebook" }, { - "duration": "700.0", + "duration": "467.0", "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll" }, { - "duration": "288.0", + "duration": "246.0", "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll:2018" }, { - "duration": "168.0", + "duration": "132.0", "name": "v8.browsing_mobile-future/browse:social:instagram" }, { - "duration": "220.0", + "duration": "164.0", "name": "v8.browsing_mobile-future/browse:social:pinterest_infinite_scroll" }, { - "duration": "322.0", + "duration": "245.0", "name": "v8.browsing_mobile-future/browse:social:tumblr_infinite_scroll" }, { - "duration": "103.0", + "duration": "79.0", "name": "v8.browsing_mobile-future/browse:social:twitter" }, { - "duration": "188.0", + "duration": "136.0", "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll" }, { - "duration": "272.0", + "duration": "208.0", "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll:2018" }, { - "duration": "83.0", + "duration": "67.0", "name": "v8.browsing_mobile-future/browse:tools:maps" }, { - "duration": "125.0", + "duration": "135.0", "name": "v8.browsing_mobile/browse:chrome:newtab" }, { - "duration": "44.0", + "duration": "40.0", "name": "v8.browsing_mobile/browse:chrome:omnibox" }, { - "duration": "152.0", + "duration": "114.0", "name": "v8.browsing_mobile/browse:media:facebook_photos" }, { - "duration": "116.0", + "duration": "90.0", "name": "v8.browsing_mobile/browse:media:flickr_infinite_scroll" }, { - "duration": "146.0", + "duration": "113.0", "name": "v8.browsing_mobile/browse:media:imgur" }, { - "duration": "184.0", + "duration": "141.0", "name": "v8.browsing_mobile/browse:media:youtube" }, { - "duration": "270.0", + "duration": "197.0", "name": "v8.browsing_mobile/browse:news:cnn" }, { - "duration": "194.0", + "duration": "136.0", "name": "v8.browsing_mobile/browse:news:cnn:2018" }, { - "duration": "116.0", + "duration": "90.0", "name": "v8.browsing_mobile/browse:news:cricbuzz" }, { - "duration": "115.0", + "duration": "92.0", "name": "v8.browsing_mobile/browse:news:qq" }, { - "duration": "97.0", + "duration": "78.0", "name": "v8.browsing_mobile/browse:news:reddit" }, { - "duration": "545.0", + "duration": "304.0", "name": "v8.browsing_mobile/browse:news:toi" }, { - "duration": "122.0", + "duration": "88.0", "name": "v8.browsing_mobile/browse:news:washingtonpost" }, { - "duration": "173.0", + "duration": "126.0", "name": "v8.browsing_mobile/browse:shopping:amazon" }, { - "duration": "160.0", + "duration": "110.0", "name": "v8.browsing_mobile/browse:shopping:avito" }, { - "duration": "67.0", + "duration": "53.0", "name": "v8.browsing_mobile/browse:shopping:lazada" }, { - "duration": "179.0", + "duration": "124.0", "name": "v8.browsing_mobile/browse:social:facebook" }, { - "duration": "760.0", + "duration": "488.0", "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll" }, { - "duration": "291.0", + "duration": "248.0", "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll:2018" }, { - "duration": "169.0", + "duration": "137.0", "name": "v8.browsing_mobile/browse:social:instagram" }, { - "duration": "229.0", + "duration": "163.0", "name": "v8.browsing_mobile/browse:social:pinterest_infinite_scroll" }, { - "duration": "308.0", + "duration": "240.0", "name": "v8.browsing_mobile/browse:social:tumblr_infinite_scroll" }, { - "duration": "103.0", + "duration": "79.0", "name": "v8.browsing_mobile/browse:social:twitter" }, { - "duration": "180.0", + "duration": "136.0", "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll" }, { - "duration": "271.0", + "duration": "210.0", "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll:2018" }, { - "duration": "87.0", + "duration": "64.0", "name": "v8.browsing_mobile/browse:tools:maps" }, { @@ -4480,35 +4640,35 @@ "name": "wasm/AsmJsZenGarden" }, { - "duration": "26.0", + "duration": "22.0", "name": "wasm/WasmSpaceBuggy" }, { - "duration": "12.0", + "duration": "14.0", "name": "wasm/WasmStylizedRenderer" }, { - "duration": "13.0", + "duration": "14.0", "name": "wasm/WasmSunTemple" }, { - "duration": "22.0", + "duration": "21.0", "name": "wasm/WasmTanks" }, { - "duration": "11.0", + "duration": "15.0", "name": "wasm/WasmZenGarden" }, { - "duration": "23.0", + "duration": "24.0", "name": "webrtc/10s_datachannel_transfer" }, { - "duration": "34.0", + "duration": "28.0", "name": "webrtc/canvas_capture_peer_connection" }, { - "duration": "39.0", + "duration": "37.0", "name": "webrtc/codec_constraints_h264" }, { @@ -4516,7 +4676,7 @@ "name": "webrtc/codec_constraints_vp8" }, { - "duration": "39.0", + "duration": "37.0", "name": "webrtc/codec_constraints_vp9" }, { @@ -4524,11 +4684,11 @@ "name": "webrtc/hd_local_stream_10s" }, { - "duration": "55.0", + "duration": "45.0", "name": "webrtc/multiple_peerconnections" }, { - "duration": "91.0", + "duration": "67.0", "name": "webrtc/pause_play_peerconnections" } ] \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json index d2fcd2fa..cd64f47 100644 --- a/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json +++ b/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json
@@ -1,514 +1,38 @@ [ { - "duration": "22.0", - "name": "blink_perf.bindings/append-child.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/create-element.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/document-implementation.html" - }, - { - "duration": "10.0", - "name": "blink_perf.bindings/dom-attribute-on-prototoype.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/first-child.html" - }, - { - "duration": "9.0", - "name": "blink_perf.bindings/gc-forest.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/gc-mini-tree.html" - }, - { - "duration": "17.0", - "name": "blink_perf.bindings/gc-tree.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/get-attribute-rare.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/get-attribute.html" - }, - { - "duration": "10.0", - "name": "blink_perf.bindings/get-element-by-id.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/get-elements-by-tag-name.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/id-getter.html" - }, - { - "duration": "10.0", - "name": "blink_perf.bindings/id-setter.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/indexed-getter.html" - }, - { - "duration": "13.0", - "name": "blink_perf.bindings/insert-before.html" - }, - { - "duration": "10.0", - "name": "blink_perf.bindings/named-property-enumerator.html" + "duration": "30.0", + "name": "blink_perf.accessibility/textarea-append.html" }, { "duration": "22.0", - "name": "blink_perf.bindings/node-list-access.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/node-type.html" - }, - { - "duration": "5.0", - "name": "blink_perf.bindings/post-message.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/sequence-conversion-array.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/sequence-conversion-custom-iterator.html" - }, - { - "duration": "5.0", - "name": "blink_perf.bindings/serialize-array.html" - }, - { - "duration": "5.0", - "name": "blink_perf.bindings/serialize-long-string.html" - }, - { - "duration": "8.0", - "name": "blink_perf.bindings/serialize-map.html" - }, - { - "duration": "5.0", - "name": "blink_perf.bindings/serialize-nested-array.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/set-attribute-rare.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/set-attribute.html" - }, - { - "duration": "16.0", - "name": "blink_perf.bindings/structured-clone-json-deserialize.html" - }, - { - "duration": "16.0", - "name": "blink_perf.bindings/structured-clone-json-serialize.html" - }, - { - "duration": "8.0", - "name": "blink_perf.bindings/structured-clone-long-string-deserialize.html" - }, - { - "duration": "8.0", - "name": "blink_perf.bindings/structured-clone-long-string-serialize.html" - }, - { - "duration": "12.0", - "name": "blink_perf.bindings/typed-array-construct-from-array.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/typed-array-construct-from-same-type.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/typed-array-construct-from-typed.html" - }, - { - "duration": "10.0", - "name": "blink_perf.bindings/typed-array-set-from-typed.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/undefined-first-child.html" - }, - { - "duration": "10.0", - "name": "blink_perf.bindings/undefined-get-element-by-id.html" - }, - { - "duration": "11.0", - "name": "blink_perf.bindings/undefined-id-getter.html" - }, - { - "duration": "22.0", - "name": "blink_perf.canvas/createImageBitmapFromImageData.html" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/createImageBitmapFromImageData_RAF.html?RAF" - }, - { - "duration": "14.0", - "name": "blink_perf.canvas/docs-paper.html" - }, - { - "duration": "6.0", - "name": "blink_perf.canvas/docs-paper_RAF.html?RAF" - }, - { - "duration": "12.0", - "name": "blink_perf.canvas/docs-resume.html" - }, - { - "duration": "7.0", - "name": "blink_perf.canvas/docs-resume_RAF.html?RAF" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/docs-table.html" - }, - { - "duration": "6.0", - "name": "blink_perf.canvas/docs-table_RAF.html?RAF" - }, - { - "duration": "6.0", - "name": "blink_perf.canvas/draw-dynamic-canvas-2d-to-hw-accelerated-canvas-2d.html" - }, - { - "duration": "6.0", - "name": "blink_perf.canvas/draw-dynamic-canvas-2d-to-hw-accelerated-canvas-2d_RAF.html?RAF" - }, - { - "duration": "12.0", - "name": "blink_perf.canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d.html" - }, - { - "duration": "5.0", - "name": "blink_perf.canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d_RAF.html?RAF" - }, - { - "duration": "5.0", - "name": "blink_perf.canvas/draw-hw-accelerated-canvas-2d-to-sw-canvas-2d.html" - }, - { - "duration": "7.0", - "name": "blink_perf.canvas/draw-hw-accelerated-canvas-2d-to-sw-canvas-2d_RAF.html?RAF" - }, - { - "duration": "5.0", - "name": "blink_perf.canvas/draw-static-canvas-2d-to-hw-accelerated-canvas-2d.html" - }, - { - "duration": "7.0", - "name": "blink_perf.canvas/draw-static-canvas-2d-to-hw-accelerated-canvas-2d_RAF.html?RAF" - }, - { - "duration": "5.0", - "name": "blink_perf.canvas/draw-static-webgl-to-hw-accelerated-canvas-2d.html" - }, - { - "duration": "6.0", - "name": "blink_perf.canvas/draw-static-webgl-to-hw-accelerated-canvas-2d_RAF.html?RAF" - }, - { - "duration": "8.0", - "name": "blink_perf.canvas/draw-video-to-hw-accelerated-canvas-2d_RAF.html?RAF" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/drawimage-not-pixelaligned.html" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/drawimage-not-pixelaligned_RAF.html?RAF" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/drawimage.html" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/drawimage_RAF.html?RAF" - }, - { - "duration": "12.0", - "name": "blink_perf.canvas/getImageData.html" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/getImageData_RAF.html?RAF" - }, - { - "duration": "5.0", - "name": "blink_perf.canvas/gpu-bound-shader.html" - }, - { - "duration": "7.0", - "name": "blink_perf.canvas/gpu-bound-shader_RAF.html?RAF" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/putImageData.html" - }, - { - "duration": "11.0", - "name": "blink_perf.canvas/putImageData_RAF.html?RAF" - }, - { - "duration": "13.0", - "name": "blink_perf.canvas/sheets-render.html" - }, - { - "duration": "6.0", - "name": "blink_perf.canvas/sheets-render_RAF.html?RAF" - }, - { - "duration": "10.0", - "name": "blink_perf.canvas/toBlob_duration.html" - }, - { - "duration": "10.0", - "name": "blink_perf.canvas/toBlob_duration_RAF.html?RAF" - }, - { - "duration": "8.0", - "name": "blink_perf.canvas/toBlob_duration_jpeg.html" - }, - { - "duration": "8.0", - "name": "blink_perf.canvas/toBlob_duration_jpeg_RAF.html?RAF" - }, - { - "duration": "8.0", - "name": "blink_perf.canvas/upload-canvas-2d-to-texture.html" - }, - { - "duration": "8.0", - "name": "blink_perf.canvas/upload-canvas-2d-to-texture_RAF.html?RAF" - }, - { - "duration": "6.0", - "name": "blink_perf.canvas/upload-video-to-sub-texture_RAF.html?RAF" - }, - { - "duration": "7.0", - "name": "blink_perf.canvas/upload-video-to-texture_RAF.html?RAF" - }, - { - "duration": "8.0", - "name": "blink_perf.canvas/upload-webgl-to-texture.html" - }, - { - "duration": "8.0", - "name": "blink_perf.canvas/upload-webgl-to-texture_RAF.html?RAF" - }, - { - "duration": "28.0", - "name": "blink_perf.css/AttributeDescendantSelector.html" - }, - { - "duration": "11.0", - "name": "blink_perf.css/CSSPropertySetterGetter.html" - }, - { - "duration": "11.0", - "name": "blink_perf.css/CSSPropertySetterGetterMethods.html" - }, - { - "duration": "12.0", - "name": "blink_perf.css/CSSPropertyUpdateValue.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleChildClassSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleChildElementSelectors.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleElementSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleGrandChildElementSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleMultipleClassSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleMultipleQualifiedDataAttributesWithValuesSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleNestedPseudoSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStylePairOfNthChildSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStylePartialAttributeMatchingSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleQualifiedDataAttributeSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleQualifiedDataAttributeWithValueSelector.html" - }, - { - "duration": "12.0", - "name": "blink_perf.css/ChangeStyleShallowTree.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleSingleClassSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleSingleNthChildSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleSinglePseudoSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleUniversalSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleUnqualifiedDataAttributeSelector.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/ChangeStyleUnqualifiedDataAttributeWithValueSelector.html" - }, - { - "duration": "17.0", - "name": "blink_perf.css/ClassDescendantSelector.html" - }, - { - "duration": "11.0", - "name": "blink_perf.css/ClassInvalidation.html" - }, - { - "duration": "5.0", - "name": "blink_perf.css/CustomPropertiesCascade.html" - }, - { - "duration": "8.0", - "name": "blink_perf.css/CustomPropertiesNonRootInheritance.html" - }, - { - "duration": "8.0", - "name": "blink_perf.css/CustomPropertiesRootInheritance.html" - }, - { - "duration": "5.0", - "name": "blink_perf.css/CustomPropertiesVarAlias.html" - }, - { - "duration": "13.0", - "name": "blink_perf.css/FocusUpdate.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/LoadBootstrapBlog.html" - }, - { - "duration": "9.0", - "name": "blink_perf.css/LoadMaterializeStarterPage.html" - }, - { - "duration": "10.0", - "name": "blink_perf.css/LoadSemanticPageExample.html" - }, - { - "duration": "11.0", - "name": "blink_perf.css/PseudoClassSelectors.html" - }, - { - "duration": "13.0", - "name": "blink_perf.css/SelectorCountScaling.html" - }, - { - "duration": "45.0", - "name": "blink_perf.dom/custom-element-default-style-with-shadow.html" - }, - { - "duration": "15.0", - "name": "blink_perf.dom/long-sibling-list.html" - }, - { - "duration": "8.0", - "name": "blink_perf.dom/modify-element-classname.html" - }, - { - "duration": "6.0", - "name": "blink_perf.dom/modify-element-id.html" - }, - { - "duration": "6.0", - "name": "blink_perf.dom/modify-element-title.html" - }, - { - "duration": "12.0", - "name": "blink_perf.dom/select-multiple-add.html" - }, - { - "duration": "11.0", - "name": "blink_perf.dom/select-single-add.html" - }, - { - "duration": "11.0", - "name": "blink_perf.dom/select-single-remove.html" - }, - { - "duration": "21.0", "name": "blink_perf.events/EventsDispatching.html" }, { "duration": "12.0", - "name": "blink_perf.events/EventsDispatchingInDeeplyNestedShadowTrees.html" + "name": "blink_perf.events/EventsDispatchingInDeeplyNestedV0ShadowTrees.html" }, { - "duration": "25.0", - "name": "blink_perf.events/EventsDispatchingInShadowTrees.html" + "duration": "11.0", + "name": "blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html" + }, + { + "duration": "24.0", + "name": "blink_perf.events/EventsDispatchingInV0ShadowTrees.html" + }, + { + "duration": "23.0", + "name": "blink_perf.events/EventsDispatchingInV1ShadowTrees.html" }, { "duration": "24.0", "name": "blink_perf.events/hit-test-lots-of-layers.html" }, { - "duration": "60.0", + "duration": "65.0", "name": "blink_perf.image_decoder/decode-gif.html" }, { - "duration": "19.0", + "duration": "20.0", "name": "blink_perf.image_decoder/decode-jpeg.html" }, { @@ -516,7 +40,7 @@ "name": "blink_perf.image_decoder/decode-lossless-webp.html" }, { - "duration": "12.0", + "duration": "13.0", "name": "blink_perf.image_decoder/decode-lossy-webp.html" }, { @@ -528,7 +52,7 @@ "name": "blink_perf.image_decoder/decode-png-palette.html" }, { - "duration": "61.0", + "duration": "60.0", "name": "blink_perf.image_decoder/decode-png.html" }, { @@ -540,11 +64,11 @@ "name": "blink_perf.layout/Shapes/MultipleShapes.html" }, { - "duration": "10.0", + "duration": "11.0", "name": "blink_perf.layout/SimpleTextPathLineLayout.html" }, { - "duration": "10.0", + "duration": "8.0", "name": "blink_perf.layout/add-remove-inline-floats.html" }, { @@ -552,11 +76,11 @@ "name": "blink_perf.layout/attach-inlines-2.html" }, { - "duration": "11.0", + "duration": "10.0", "name": "blink_perf.layout/attach-inlines.html" }, { - "duration": "12.0", + "duration": "11.0", "name": "blink_perf.layout/auto-grid-lots-of-data.html" }, { @@ -564,11 +88,11 @@ "name": "blink_perf.layout/change-text-css-contain.html" }, { - "duration": "10.0", + "duration": "11.0", "name": "blink_perf.layout/chapter-reflow-once-random.html" }, { - "duration": "14.0", + "duration": "13.0", "name": "blink_perf.layout/chapter-reflow-once.html" }, { @@ -576,15 +100,15 @@ "name": "blink_perf.layout/chapter-reflow-thrice.html" }, { - "duration": "12.0", + "duration": "11.0", "name": "blink_perf.layout/chapter-reflow-twice.html" }, { - "duration": "13.0", + "duration": "11.0", "name": "blink_perf.layout/chapter-reflow.html" }, { - "duration": "6.0", + "duration": "15.0", "name": "blink_perf.layout/character_fallback.html" }, { @@ -592,11 +116,15 @@ "name": "blink_perf.layout/character_fallback_aat.html" }, { - "duration": "12.0", - "name": "blink_perf.layout/fixed-grid-lots-of-data.html" + "duration": "17.0", + "name": "blink_perf.layout/contain-content-style-change.html" }, { "duration": "11.0", + "name": "blink_perf.layout/fixed-grid-lots-of-data.html" + }, + { + "duration": "12.0", "name": "blink_perf.layout/fixed-grid-lots-of-stretched-data.html" }, { @@ -620,11 +148,11 @@ "name": "blink_perf.layout/flexbox-row-nowrap.html" }, { - "duration": "15.0", + "duration": "14.0", "name": "blink_perf.layout/flexbox-row-stretch-height-definite.html" }, { - "duration": "11.0", + "duration": "10.0", "name": "blink_perf.layout/flexbox-row-wrap.html" }, { @@ -632,15 +160,15 @@ "name": "blink_perf.layout/flexbox-with-stretch-layout.html" }, { - "duration": "23.0", + "duration": "21.0", "name": "blink_perf.layout/floats_100_100.html" }, { - "duration": "23.0", + "duration": "21.0", "name": "blink_perf.layout/floats_100_100_nested.html" }, { - "duration": "13.0", + "duration": "14.0", "name": "blink_perf.layout/floats_10_1000.html" }, { @@ -664,147 +192,11 @@ "name": "blink_perf.layout/floats_50_100.html" }, { - "duration": "12.0", + "duration": "11.0", "name": "blink_perf.layout/floats_50_100_nested.html" }, { - "duration": "10.0", - "name": "blink_perf.layout/hindi-line-layout.html" - }, - { - "duration": "6.0", - "name": "blink_perf.layout/japanese-kokoro-insert.html" - }, - { - "duration": "12.0", - "name": "blink_perf.layout/large-spanning-grid-item.html" - }, - { - "duration": "13.0", - "name": "blink_perf.layout/large-table-with-collapsed-borders-and-colspans-wider-than-table.html" - }, - { - "duration": "13.0", - "name": "blink_perf.layout/large-table-with-collapsed-borders-and-colspans.html" - }, - { - "duration": "13.0", - "name": "blink_perf.layout/large-table-with-collapsed-borders-and-no-colspans.html" - }, - { - "duration": "193.0", - "name": "blink_perf.layout/latin-ebook-resize.html" - }, - { - "duration": "27.0", - "name": "blink_perf.layout/latin-ebook.html" - }, - { - "duration": "6.0", - "name": "blink_perf.layout/layers_overlap_2d.html" - }, - { - "duration": "6.0", - "name": "blink_perf.layout/layers_overlap_3d.html" - }, - { - "duration": "16.0", - "name": "blink_perf.layout/line-layout-line-height.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/line-layout-repeat-append-select.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/line-layout-repeat-append.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/line-layout.html" - }, - { - "duration": "5.0", - "name": "blink_perf.layout/long-line-nowrap-collapse.html" - }, - { - "duration": "5.0", - "name": "blink_perf.layout/long-line-nowrap-spans-collapse.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/long-line-nowrap.html" - }, - { - "duration": "11.0", - "name": "blink_perf.layout/many-block-children-auto-inline-size.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/many-block-children-fixed-inline-size.html" - }, - { - "duration": "12.0", - "name": "blink_perf.layout/multicol/deeply-nested-tables.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/multicol/fixed-height-with-spanner-and-nested-tables.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/multicol/lots-of-text-autofill.html" - }, - { - "duration": "11.0", - "name": "blink_perf.layout/multicol/lots-of-text-balanced-orphans-widows.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/multicol/lots-of-text-balanced.html" - }, - { - "duration": "12.0", - "name": "blink_perf.layout/multicol/tall-content-short-columns-realistic.html" - }, - { - "duration": "12.0", - "name": "blink_perf.layout/multicol/tall-content-short-columns.html" - }, - { - "duration": "11.0", - "name": "blink_perf.layout/nested-blocks-with-percent-height-and-max-height.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/nested-grid.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/nested-percent-height-tables.html" - }, - { - "duration": "75.0", - "name": "blink_perf.layout/subtree-detaching.html" - }, - { - "duration": "6.0", - "name": "blink_perf.layout/vertical-japanese-kokoro-insert.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/word-break-break-all.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/word-break-break-word.html" - }, - { - "duration": "10.0", - "name": "blink_perf.layout/word-wrap-break-word.html" - }, - { - "duration": "22.0", + "duration": "23.0", "name": "blink_perf.owp_storage/blob-perf-files.html" }, { @@ -812,195 +204,39 @@ "name": "blink_perf.owp_storage/blob-perf-ipc.html" }, { - "duration": "12.0", + "duration": "11.0", "name": "blink_perf.owp_storage/blob-perf-shm.html" }, { - "duration": "15.0", + "duration": "14.0", "name": "blink_perf.owp_storage/blob-perf-tiny.html" }, { - "duration": "14.0", + "duration": "15.0", "name": "blink_perf.owp_storage/idb-load-docs.html" }, { - "duration": "22.0", - "name": "blink_perf.paint/appending-text.html" - }, - { - "duration": "17.0", - "name": "blink_perf.paint/color-changes.html" - }, - { "duration": "15.0", - "name": "blink_perf.paint/complex-content-slow-scroll.html" + "name": "blink_perf.shadow_dom/declarative-api.html" }, { - "duration": "15.0", - "name": "blink_perf.paint/complex-iframe-filtered.html" + "duration": "5.0", + "name": "blink_perf.shadow_dom/imperative-api-appendchild.html" }, { - "duration": "18.0", - "name": "blink_perf.paint/containment-resize.html" + "duration": "5.0", + "name": "blink_perf.shadow_dom/imperative-api-assign.html" }, { - "duration": "16.0", - "name": "blink_perf.paint/fixed-and-many-layers-scroll.html" + "duration": "5.0", + "name": "blink_perf.shadow_dom/imperative-api-assigned-elements.html" }, { - "duration": "17.0", - "name": "blink_perf.paint/large-table-background-change-with-invisible-collapsed-borders.html" + "duration": "5.0", + "name": "blink_perf.shadow_dom/imperative-api-assigned-slot.html" }, { - "duration": "13.0", - "name": "blink_perf.paint/large-table-background-change-with-visible-collapsed-borders.html" - }, - { - "duration": "17.0", - "name": "blink_perf.paint/large-table-background-change-with-zero-width-collapsed-borders.html" - }, - { - "duration": "15.0", - "name": "blink_perf.paint/large-table-collapsed-border-change-with-backgrounds.html" - }, - { - "duration": "15.0", - "name": "blink_perf.paint/large-table-collapsed-border-change-with-text.html" - }, - { - "duration": "13.0", - "name": "blink_perf.paint/large-table-collapsed-border-change.html" - }, - { - "duration": "14.0", - "name": "blink_perf.paint/large-table-repaint.html" - }, - { - "duration": "14.0", - "name": "blink_perf.paint/move-text-with-mask.html" - }, - { - "duration": "20.0", - "name": "blink_perf.paint/transform-changes.html" - }, - { - "duration": "22.0", - "name": "blink_perf.parser/css-parser-yui.html" - }, - { - "duration": "12.0", - "name": "blink_perf.parser/html-parser-threaded.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/html-parser.html" - }, - { - "duration": "52.0", - "name": "blink_perf.parser/html5-full-render.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/iframe-append-remove.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/innerHTML-setter-siblings.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/innerHTML-setter.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-attribute-complex.html" - }, - { - "duration": "10.0", - "name": "blink_perf.parser/query-selector-all-attribute.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-class-deep.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-class-first.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-class-last.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-class.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-deep.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-first.html" - }, - { - "duration": "13.0", - "name": "blink_perf.parser/query-selector-all-id-deep.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-id-first.html" - }, - { - "duration": "12.0", - "name": "blink_perf.parser/query-selector-all-id-last.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-all-last.html" - }, - { - "duration": "12.0", - "name": "blink_perf.parser/query-selector-deep.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-first.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-id-deep.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-id-last.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/query-selector-last.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/simple-url.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/textarea-parsing.html" - }, - { - "duration": "11.0", - "name": "blink_perf.parser/tiny-innerHTML.html" - }, - { - "duration": "12.0", - "name": "blink_perf.parser/url-parser.html" - }, - { - "duration": "10.0", - "name": "blink_perf.parser/xml-parser.html" - }, - { - "duration": "6.0", + "duration": "5.0", "name": "blink_perf.shadow_dom/imperative-api-custom-detail-summary-large.html" }, { @@ -1016,6 +252,14 @@ "name": "blink_perf.shadow_dom/imperative-api-detail-summary.html" }, { + "duration": "5.0", + "name": "blink_perf.shadow_dom/imperative-api-insertbefore.html" + }, + { + "duration": "5.0", + "name": "blink_perf.shadow_dom/imperative-api.html" + }, + { "duration": "6.0", "name": "blink_perf.shadow_dom/shadow-style-share-attr-selectors.html" }, @@ -1044,7 +288,7 @@ "name": "blink_perf.shadow_dom/v0-changing-classname-without-shadow-dom.html" }, { - "duration": "8.0", + "duration": "9.0", "name": "blink_perf.shadow_dom/v0-changing-select-with-shadow-dom.html" }, { @@ -1072,7 +316,7 @@ "name": "blink_perf.shadow_dom/v0-small-distribution-with-layout.html" }, { - "duration": "23.0", + "duration": "25.0", "name": "blink_perf.shadow_dom/v1-distribution-disconnected-and-reconnected.html" }, { @@ -1084,11 +328,11 @@ "name": "blink_perf.shadow_dom/v1-host-child-append.html" }, { - "duration": "23.0", + "duration": "25.0", "name": "blink_perf.shadow_dom/v1-large-deep-distribution.html" }, { - "duration": "48.0", + "duration": "57.0", "name": "blink_perf.shadow_dom/v1-large-deep-layout.html" }, { @@ -1100,7 +344,7 @@ "name": "blink_perf.shadow_dom/v1-large-shallow-layout.html" }, { - "duration": "6.0", + "duration": "5.0", "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-re-layout.html" }, { @@ -1112,7 +356,7 @@ "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-slot-flatten.html" }, { - "duration": "6.0", + "duration": "5.0", "name": "blink_perf.shadow_dom/v1-mutate-shallow-tree-then-re-layout.html" }, { @@ -1132,7 +376,7 @@ "name": "blink_perf.shadow_dom/v1-small-deep-distribution.html" }, { - "duration": "6.0", + "duration": "7.0", "name": "blink_perf.shadow_dom/v1-small-deep-layout.html" }, { @@ -1208,7 +452,7 @@ "name": "blink_perf.svg/Samurai.html" }, { - "duration": "52.0", + "duration": "60.0", "name": "blink_perf.svg/SierpinskiCarpet.html" }, { @@ -1236,47 +480,323 @@ "name": "blink_perf.svg/Worldcup.html" }, { - "duration": "44.0", - "name": "dromaeo/http://dromaeo.com?dom-attr" - }, - { - "duration": "37.0", - "name": "dromaeo/http://dromaeo.com?dom-modify" - }, - { - "duration": "50.0", - "name": "dromaeo/http://dromaeo.com?dom-query" - }, - { - "duration": "31.0", - "name": "dromaeo/http://dromaeo.com?dom-traverse" - }, - { - "duration": "17.0", + "duration": "13.0", "name": "dummy_benchmark.noisy_benchmark_1/dummy_page.html" }, { - "duration": "13.0", - "name": "dummy_benchmark.stable_benchmark_1/dummy_page.html" - }, - { - "duration": "267.0", + "duration": "281.0", "name": "jetstream/http://browserbench.org/JetStream/" }, { - "duration": "59.0", - "name": "kraken/http://krakenbenchmark.mozilla.org/kraken-1.1/driver.html" + "duration": "16.0", + "name": "loading.mobile/58Pic" }, { - "duration": "262.0", + "duration": "166.0", + "name": "loading.mobile/58Pic_3g" + }, + { + "duration": "19.0", + "name": "loading.mobile/Amazon" + }, + { + "duration": "233.0", + "name": "loading.mobile/Amazon_3g" + }, + { + "duration": "21.0", + "name": "loading.mobile/BOLNoticias" + }, + { + "duration": "275.0", + "name": "loading.mobile/BOLNoticias_3g" + }, + { + "duration": "22.0", + "name": "loading.mobile/Baidu" + }, + { + "duration": "173.0", + "name": "loading.mobile/Baidu_3g" + }, + { + "duration": "18.0", + "name": "loading.mobile/Bradesco" + }, + { + "duration": "18.0", + "name": "loading.mobile/Dailymotion" + }, + { + "duration": "23.0", + "name": "loading.mobile/Dawn" + }, + { + "duration": "16.0", + "name": "loading.mobile/DevOpera_cold" + }, + { + "duration": "168.0", + "name": "loading.mobile/DevOpera_cold_3g" + }, + { + "duration": "22.0", + "name": "loading.mobile/DevOpera_hot" + }, + { + "duration": "156.0", + "name": "loading.mobile/DevOpera_hot_3g" + }, + { + "duration": "19.0", + "name": "loading.mobile/DevOpera_warm" + }, + { + "duration": "148.0", + "name": "loading.mobile/DevOpera_warm_3g" + }, + { + "duration": "20.0", + "name": "loading.mobile/Dramaq" + }, + { + "duration": "141.0", + "name": "loading.mobile/Dramaq_3g" + }, + { + "duration": "15.0", + "name": "loading.mobile/EnquiryIndianRail" + }, + { + "duration": "143.0", + "name": "loading.mobile/EnquiryIndianRail_3g" + }, + { + "duration": "15.0", + "name": "loading.mobile/Facebook" + }, + { + "duration": "36.0", + "name": "loading.mobile/Facebook_3g" + }, + { + "duration": "17.0", + "name": "loading.mobile/FlipBoard_cold" + }, + { + "duration": "26.0", + "name": "loading.mobile/FlipBoard_hot" + }, + { + "duration": "38.0", + "name": "loading.mobile/FlipBoard_hot_3g" + }, + { + "duration": "21.0", + "name": "loading.mobile/FlipBoard_warm" + }, + { + "duration": "21.0", + "name": "loading.mobile/FlipKart_cold" + }, + { + "duration": "32.0", + "name": "loading.mobile/FlipKart_hot" + }, + { + "duration": "29.0", + "name": "loading.mobile/FlipKart_hot_3g" + }, + { + "duration": "25.0", + "name": "loading.mobile/FlipKart_warm" + }, + { + "duration": "252.0", + "name": "loading.mobile/FlipKart_warm_3g" + }, + { + "duration": "16.0", + "name": "loading.mobile/FranceTVInfo" + }, + { + "duration": "65.0", + "name": "loading.mobile/FranceTVInfo_3g" + }, + { + "duration": "22.0", + "name": "loading.mobile/GSShop" + }, + { + "duration": "14.0", + "name": "loading.mobile/GoogleBrazil" + }, + { + "duration": "245.0", + "name": "loading.mobile/GoogleBrazil_3g" + }, + { + "duration": "15.0", + "name": "loading.mobile/GoogleIndia" + }, + { + "duration": "15.0", + "name": "loading.mobile/GoogleIndonesia" + }, + { + "duration": "237.0", + "name": "loading.mobile/GoogleIndonesia_3g" + }, + { + "duration": "20.0", + "name": "loading.mobile/GoogleRedirectToGoogleJapan" + }, + { + "duration": "18.0", + "name": "loading.mobile/Hongkiat" + }, + { + "duration": "271.0", + "name": "loading.mobile/Hongkiat_3g" + }, + { + "duration": "20.0", + "name": "loading.mobile/KapanLagi" + }, + { + "duration": "25.0", + "name": "loading.mobile/Kaskus" + }, + { + "duration": "18.0", + "name": "loading.mobile/LocalMoxie" + }, + { + "duration": "14.0", + "name": "loading.mobile/Locanto" + }, + { + "duration": "102.0", + "name": "loading.mobile/Locanto_3g" + }, + { + "duration": "17.0", + "name": "loading.mobile/OLX" + }, + { + "duration": "249.0", + "name": "loading.mobile/OLX_3g" + }, + { + "duration": "19.0", + "name": "loading.mobile/QQNews" + }, + { + "duration": "217.0", + "name": "loading.mobile/QQNews_3g" + }, + { + "duration": "16.0", + "name": "loading.mobile/SlideShare" + }, + { + "duration": "227.0", + "name": "loading.mobile/SlideShare_3g" + }, + { + "duration": "15.0", + "name": "loading.mobile/Suumo_cold" + }, + { + "duration": "37.0", + "name": "loading.mobile/Suumo_cold_3g" + }, + { + "duration": "19.0", + "name": "loading.mobile/Suumo_hot" + }, + { + "duration": "27.0", + "name": "loading.mobile/Suumo_hot_3g" + }, + { + "duration": "17.0", + "name": "loading.mobile/Suumo_warm" + }, + { + "duration": "24.0", + "name": "loading.mobile/Suumo_warm_3g" + }, + { + "duration": "17.0", + "name": "loading.mobile/Thairath" + }, + { + "duration": "23.0", + "name": "loading.mobile/TheStar" + }, + { + "duration": "21.0", + "name": "loading.mobile/TribunNews" + }, + { + "duration": "15.0", + "name": "loading.mobile/Twitter" + }, + { + "duration": "135.0", + "name": "loading.mobile/Twitter_3g" + }, + { + "duration": "16.0", + "name": "loading.mobile/VoiceMemos_cold" + }, + { + "duration": "260.0", + "name": "loading.mobile/VoiceMemos_cold_3g" + }, + { + "duration": "22.0", + "name": "loading.mobile/VoiceMemos_hot" + }, + { + "duration": "49.0", + "name": "loading.mobile/VoiceMemos_hot_3g" + }, + { + "duration": "19.0", + "name": "loading.mobile/VoiceMemos_warm" + }, + { + "duration": "46.0", + "name": "loading.mobile/VoiceMemos_warm_3g" + }, + { + "duration": "14.0", + "name": "loading.mobile/Wikipedia" + }, + { + "duration": "191.0", + "name": "loading.mobile/Wikipedia_3g" + }, + { + "duration": "21.0", + "name": "loading.mobile/YahooNews" + }, + { + "duration": "15.0", + "name": "loading.mobile/Youtube" + }, + { + "duration": "252.0", "name": "memory.long_running_idle_gmail_tbmv2/https://mail.google.com/mail/" }, { - "duration": "21.0", + "duration": "22.0", "name": "memory.top_10_mobile/after_http_en_m_wikipedia_org_wiki_Science" }, { - "duration": "21.0", + "duration": "22.0", "name": "memory.top_10_mobile/after_http_m_intl_taobao_com_group_purchase_html" }, { @@ -1284,43 +804,39 @@ "name": "memory.top_10_mobile/after_http_m_youtube_com_results_q_science" }, { - "duration": "21.0", + "duration": "22.0", "name": "memory.top_10_mobile/after_http_search_yahoo_com_search__ylt_p_google" }, { - "duration": "21.0", + "duration": "22.0", "name": "memory.top_10_mobile/after_http_www_amazon_com_gp_aw_s_k_nexus" }, { - "duration": "21.0", + "duration": "22.0", "name": "memory.top_10_mobile/after_http_www_baidu_com_s_word_google" }, { - "duration": "21.0", + "duration": "22.0", "name": "memory.top_10_mobile/after_http_yandex_ru_touchsearch_text_science" }, { - "duration": "21.0", + "duration": "29.0", "name": "memory.top_10_mobile/after_https_m_facebook_com_rihanna" }, { - "duration": "21.0", + "duration": "22.0", "name": "memory.top_10_mobile/after_https_mobile_twitter_com_justinbieber_skip_interstitial_true" }, { - "duration": "21.0", - "name": "memory.top_10_mobile/after_https_www_google_co_uk_hl_en_q_science" - }, - { - "duration": "24.0", + "duration": "25.0", "name": "memory.top_10_mobile/http_en_m_wikipedia_org_wiki_Science" }, { - "duration": "24.0", + "duration": "25.0", "name": "memory.top_10_mobile/http_m_intl_taobao_com_group_purchase_html" }, { - "duration": "24.0", + "duration": "25.0", "name": "memory.top_10_mobile/http_m_youtube_com_results_q_science" }, { @@ -1328,30 +844,22 @@ "name": "memory.top_10_mobile/http_search_yahoo_com_search__ylt_p_google" }, { - "duration": "24.0", + "duration": "25.0", "name": "memory.top_10_mobile/http_www_amazon_com_gp_aw_s_k_nexus" }, { - "duration": "24.0", + "duration": "27.0", "name": "memory.top_10_mobile/http_www_baidu_com_s_word_google" }, { - "duration": "24.0", + "duration": "25.0", "name": "memory.top_10_mobile/http_yandex_ru_touchsearch_text_science" }, { - "duration": "24.0", - "name": "memory.top_10_mobile/https_m_facebook_com_rihanna" - }, - { - "duration": "24.0", + "duration": "25.0", "name": "memory.top_10_mobile/https_mobile_twitter_com_justinbieber_skip_interstitial_true" }, { - "duration": "26.0", - "name": "memory.top_10_mobile/https_www_google_co_uk_hl_en_q_science" - }, - { "duration": "63.0", "name": "octane/http://chromium.github.io/octane/index.html?auto=1" }, @@ -1364,7 +872,7 @@ "name": "power.typical_10_mobile/http://de.m.wikipedia.org/wiki/K%C3%B6lner_Dom" }, { - "duration": "65.0", + "duration": "67.0", "name": "power.typical_10_mobile/http://m.chiebukuro.yahoo.co.jp/detail/q10136829180" }, { @@ -1376,11 +884,11 @@ "name": "power.typical_10_mobile/http://m.facebook.com/barackobama" }, { - "duration": "62.0", + "duration": "63.0", "name": "power.typical_10_mobile/http://m.huffpost.com/us/entry/6004486" }, { - "duration": "63.0", + "duration": "62.0", "name": "power.typical_10_mobile/http://m.ynet.co.il" }, { @@ -1388,7 +896,7 @@ "name": "power.typical_10_mobile/http://siriuslymeg.tumblr.com/" }, { - "duration": "58.0", + "duration": "59.0", "name": "power.typical_10_mobile/http://wapbaike.baidu.com/" }, { @@ -1396,7 +904,7 @@ "name": "power.typical_10_mobile/http://www.cnn.com/2014/03/31/showbiz/tv/himym-finale/index.html" }, { - "duration": "59.0", + "duration": "61.0", "name": "power.typical_10_mobile/http://www.rg.ru/2014/10/21/cska-site.html" }, { @@ -1404,11 +912,11 @@ "name": "power.typical_10_mobile/https://en.wikipedia.org/wiki/File:Rotating_earth_(large).gif" }, { - "duration": "17.0", + "duration": "21.0", "name": "rasterize_and_record_micro.partial_invalidation/800_relpos_divs.html" }, { - "duration": "23.0", + "duration": "31.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/amazon.html" }, { @@ -1416,7 +924,7 @@ "name": "rasterize_and_record_micro.top_25/file://static_top_25/blogger.html" }, { - "duration": "14.0", + "duration": "22.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/booking.html" }, { @@ -1424,7 +932,7 @@ "name": "rasterize_and_record_micro.top_25/file://static_top_25/cnn.html" }, { - "duration": "9.0", + "duration": "10.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/ebay.html" }, { @@ -1432,159 +940,159 @@ "name": "rasterize_and_record_micro.top_25/file://static_top_25/espn.html" }, { - "duration": "12.0", + "duration": "20.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/facebook.html" }, { - "duration": "19.0", + "duration": "35.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/gmail.html" }, { - "duration": "20.0", + "duration": "29.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/google.html" }, { - "duration": "15.0", + "duration": "27.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/googlecalendar.html" }, { - "duration": "19.0", + "duration": "21.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/googledocs.html" }, { - "duration": "16.0", + "duration": "24.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleimagesearch.html" }, { - "duration": "25.0", + "duration": "19.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleplus.html" }, { - "duration": "12.0", + "duration": "20.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/linkedin.html" }, { - "duration": "8.0", + "duration": "9.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/pinterest.html" }, { - "duration": "27.0", + "duration": "15.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/techcrunch.html" }, { - "duration": "17.0", + "duration": "26.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/twitter.html" }, { - "duration": "14.0", + "duration": "13.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/weather.html" }, { - "duration": "11.0", + "duration": "12.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/wordpress.html" }, { - "duration": "12.0", + "duration": "20.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahooanswers.html" }, { - "duration": "27.0", + "duration": "62.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html" }, { - "duration": "84.0", + "duration": "86.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoosports.html" }, { - "duration": "29.0", + "duration": "33.0", "name": "rasterize_and_record_micro.top_25/file://static_top_25/youtube.html" }, { - "duration": "38.0", + "duration": "43.0", "name": "rendering.mobile/accu_weather_2018" }, { - "duration": "27.0", + "duration": "30.0", "name": "rendering.mobile/accu_weather_desktop_gpu_raster_2018" }, { - "duration": "28.0", + "duration": "33.0", "name": "rendering.mobile/amazon_2018" }, { - "duration": "26.0", + "duration": "34.0", "name": "rendering.mobile/amazon_desktop_gpu_raster_2018" }, { - "duration": "29.0", + "duration": "32.0", "name": "rendering.mobile/amazon_mobile_2018" }, { - "duration": "26.0", + "duration": "32.0", "name": "rendering.mobile/analog_clock_svg" }, { - "duration": "38.0", + "duration": "53.0", "name": "rendering.mobile/androidpolice_mobile_2018" }, { - "duration": "32.0", + "duration": "24.0", "name": "rendering.mobile/animometer_webgl" }, { - "duration": "32.0", + "duration": "39.0", "name": "rendering.mobile/aquarium" }, { - "duration": "37.0", + "duration": "30.0", "name": "rendering.mobile/background_color_animation" }, { - "duration": "28.0", + "duration": "65.0", "name": "rendering.mobile/background_color_animation_with_gradient" }, { - "duration": "26.0", + "duration": "31.0", "name": "rendering.mobile/baidu_mobile_2018" }, { - "duration": "27.0", + "duration": "26.0", "name": "rendering.mobile/balls_css_key_frame_animations" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/balls_css_transition_2_properties" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/balls_css_transition_40_properties" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/balls_css_transition_all_properties" }, { - "duration": "28.0", + "duration": "25.0", "name": "rendering.mobile/balls_javascript_canvas" }, { - "duration": "26.0", + "duration": "25.0", "name": "rendering.mobile/balls_javascript_css" }, { - "duration": "34.0", + "duration": "31.0", "name": "rendering.mobile/balls_svg_animations" }, { - "duration": "31.0", + "duration": "33.0", "name": "rendering.mobile/bing_mobile_2018" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/blob" }, { - "duration": "27.0", + "duration": "26.0", "name": "rendering.mobile/blogspot_2018" }, { @@ -1596,15 +1104,19 @@ "name": "rendering.mobile/blogspot_mobile_2018" }, { - "duration": "24.0", + "duration": "25.0", + "name": "rendering.mobile/blur_rotating_background" + }, + { + "duration": "30.0", "name": "rendering.mobile/boingboing_mobile_2018" }, { - "duration": "24.0", + "duration": "30.0", "name": "rendering.mobile/booking.com_2018" }, { - "duration": "20.0", + "duration": "26.0", "name": "rendering.mobile/booking.com_desktop_gpu_raster_2018" }, { @@ -1612,75 +1124,75 @@ "name": "rendering.mobile/booking.com_mobile_2018" }, { - "duration": "21.0", + "duration": "20.0", "name": "rendering.mobile/bouncing_balls_15" }, { - "duration": "20.0", + "duration": "18.0", "name": "rendering.mobile/bouncing_clipped_rectangles" }, { - "duration": "21.0", + "duration": "19.0", "name": "rendering.mobile/bouncing_gradient_circles" }, { - "duration": "18.0", + "duration": "17.0", "name": "rendering.mobile/bouncing_png_images" }, { - "duration": "23.0", + "duration": "26.0", "name": "rendering.mobile/bouncing_svg_images" }, { - "duration": "44.0", + "duration": "30.0", "name": "rendering.mobile/camera_to_webgl" }, { - "duration": "19.0", + "duration": "27.0", "name": "rendering.mobile/canvas_05000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "19.0", + "duration": "27.0", "name": "rendering.mobile/canvas_10000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "17.0", + "duration": "23.0", "name": "rendering.mobile/canvas_15000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "16.0", + "duration": "20.0", "name": "rendering.mobile/canvas_20000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "18.0", "name": "rendering.mobile/canvas_30000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "17.0", "name": "rendering.mobile/canvas_40000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "16.0", "name": "rendering.mobile/canvas_50000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "14.0", + "duration": "16.0", "name": "rendering.mobile/canvas_60000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "14.0", + "duration": "15.0", "name": "rendering.mobile/canvas_75000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "14.0", + "duration": "15.0", "name": "rendering.mobile/canvas_90000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "22.0", + "duration": "21.0", "name": "rendering.mobile/canvas_animation_no_clear" }, { - "duration": "20.0", + "duration": "19.0", "name": "rendering.mobile/canvas_arcs" }, { @@ -1696,7 +1208,7 @@ "name": "rendering.mobile/canvas_to_blob" }, { - "duration": "38.0", + "duration": "42.0", "name": "rendering.mobile/capitolvolkswagen_mobile_2018" }, { @@ -1704,11 +1216,11 @@ "name": "rendering.mobile/card_expansion" }, { - "duration": "24.0", + "duration": "23.0", "name": "rendering.mobile/card_expansion_animated" }, { - "duration": "24.0", + "duration": "23.0", "name": "rendering.mobile/card_expansion_images_text" }, { @@ -1720,7 +1232,7 @@ "name": "rendering.mobile/cats_unscaled" }, { - "duration": "13.0", + "duration": "12.0", "name": "rendering.mobile/cats_viewport_width" }, { @@ -1728,11 +1240,7 @@ "name": "rendering.mobile/cc_poster_circle" }, { - "duration": "24.0", - "name": "rendering.mobile/cc_scroll_200_layer_grid" - }, - { - "duration": "20.0", + "duration": "22.0", "name": "rendering.mobile/cc_scroll_text_only" }, { @@ -1740,23 +1248,23 @@ "name": "rendering.mobile/chip_tune" }, { - "duration": "30.0", + "duration": "31.0", "name": "rendering.mobile/cnn_2018" }, { - "duration": "31.0", + "duration": "38.0", "name": "rendering.mobile/cnn_article_mobile_2018" }, { - "duration": "26.0", + "duration": "27.0", "name": "rendering.mobile/cnn_desktop_gpu_raster_2018" }, { - "duration": "23.0", + "duration": "25.0", "name": "rendering.mobile/cnn_mobile_2018" }, { - "duration": "25.0", + "duration": "28.0", "name": "rendering.mobile/cnn_pathological_2018" }, { @@ -1764,23 +1272,23 @@ "name": "rendering.mobile/compositor_heavy_animation" }, { - "duration": "23.0", + "duration": "22.0", "name": "rendering.mobile/coordinated_animation" }, { - "duration": "26.0", + "duration": "25.0", "name": "rendering.mobile/crafty_mind" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/css_animations_many_keyframes" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/css_animations_simultaneous_inline_style" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/css_animations_simultaneous_new_element" }, { @@ -1788,19 +1296,19 @@ "name": "rendering.mobile/css_animations_simultaneous_style_element" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/css_animations_simultaneous_updating_class" }, { - "duration": "27.0", + "duration": "25.0", "name": "rendering.mobile/css_animations_staggered_infinite_iterations" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/css_animations_staggered_inline_style" }, { - "duration": "31.0", + "duration": "34.0", "name": "rendering.mobile/css_animations_staggered_new_element" }, { @@ -1812,15 +1320,15 @@ "name": "rendering.mobile/css_animations_staggered_updating_class" }, { - "duration": "30.0", + "duration": "43.0", "name": "rendering.mobile/css_animations_triggered_inline_style" }, { - "duration": "30.0", + "duration": "36.0", "name": "rendering.mobile/css_animations_triggered_new_element" }, { - "duration": "28.0", + "duration": "29.0", "name": "rendering.mobile/css_animations_triggered_style_element" }, { @@ -1828,7 +1336,7 @@ "name": "rendering.mobile/css_animations_triggered_updating_class" }, { - "duration": "32.0", + "duration": "31.0", "name": "rendering.mobile/css_opacity_plus_n_layers_0" }, { @@ -1840,15 +1348,15 @@ "name": "rendering.mobile/css_opacity_plus_n_layers_99" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/css_transitions_inline_style" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/css_transitions_new_element" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/css_transitions_staggered_inline_style" }, { @@ -1856,7 +1364,7 @@ "name": "rendering.mobile/css_transitions_staggered_new_element" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/css_transitions_staggered_style_element" }, { @@ -1864,7 +1372,7 @@ "name": "rendering.mobile/css_transitions_staggered_updating_class" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/css_transitions_style_element" }, { @@ -1872,19 +1380,19 @@ "name": "rendering.mobile/css_transitions_triggered_inline_style" }, { - "duration": "44.0", + "duration": "29.0", "name": "rendering.mobile/css_transitions_triggered_new_element" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/css_transitions_triggered_style_element" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/css_transitions_triggered_updating_class" }, { - "duration": "28.0", + "duration": "27.0", "name": "rendering.mobile/css_transitions_updating_class" }, { @@ -1892,11 +1400,11 @@ "name": "rendering.mobile/css_value_type_color" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/css_value_type_filter" }, { - "duration": "27.0", + "duration": "28.0", "name": "rendering.mobile/css_value_type_length" }, { @@ -1904,7 +1412,7 @@ "name": "rendering.mobile/css_value_type_length_complex" }, { - "duration": "30.0", + "duration": "31.0", "name": "rendering.mobile/css_value_type_length_simple" }, { @@ -1912,11 +1420,11 @@ "name": "rendering.mobile/css_value_type_path" }, { - "duration": "26.0", + "duration": "38.0", "name": "rendering.mobile/css_value_type_shadow" }, { - "duration": "28.0", + "duration": "29.0", "name": "rendering.mobile/css_value_type_transform_complex" }, { @@ -1924,23 +1432,23 @@ "name": "rendering.mobile/css_value_type_transform_simple" }, { - "duration": "35.0", + "duration": "38.0", "name": "rendering.mobile/deviantart_mobile_2018" }, { - "duration": "22.0", + "duration": "24.0", "name": "rendering.mobile/digg_mobile_2018" }, { - "duration": "27.0", + "duration": "28.0", "name": "rendering.mobile/dynamic_cube_map" }, { - "duration": "25.0", + "duration": "26.0", "name": "rendering.mobile/earth" }, { - "duration": "32.0", + "duration": "31.0", "name": "rendering.mobile/ebay_2018" }, { @@ -1948,7 +1456,7 @@ "name": "rendering.mobile/ebay_desktop_gpu_raster_2018" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/ebay_mobile_2018" }, { @@ -1956,23 +1464,23 @@ "name": "rendering.mobile/ebay_scroll_2018" }, { - "duration": "40.0", + "duration": "35.0", "name": "rendering.mobile/espn_2018" }, { - "duration": "36.0", + "duration": "33.0", "name": "rendering.mobile/espn_desktop_gpu_raster_2018" }, { - "duration": "30.0", + "duration": "31.0", "name": "rendering.mobile/espn_mobile_2018" }, { - "duration": "26.0", + "duration": "24.0", "name": "rendering.mobile/espn_pathological_2018" }, { - "duration": "38.0", + "duration": "24.0", "name": "rendering.mobile/extra_large_texture_uploads" }, { @@ -1984,15 +1492,15 @@ "name": "rendering.mobile/facebook_desktop_gpu_raster_2018" }, { - "duration": "37.0", + "duration": "42.0", "name": "rendering.mobile/facebook_mobile_2018" }, { - "duration": "20.0", + "duration": "19.0", "name": "rendering.mobile/fill_shapes" }, { - "duration": "26.0", + "duration": "30.0", "name": "rendering.mobile/filter_terrain_svg" }, { @@ -2004,23 +1512,23 @@ "name": "rendering.mobile/font_wipe" }, { - "duration": "26.0", + "duration": "27.0", "name": "rendering.mobile/forecast.io_mobile_2018" }, { - "duration": "20.0", + "duration": "21.0", "name": "rendering.mobile/geo_apis" }, { - "duration": "23.0", + "duration": "24.0", "name": "rendering.mobile/gmail_2018" }, { - "duration": "19.0", + "duration": "20.0", "name": "rendering.mobile/gmail_desktop_gpu_raster_2018" }, { - "duration": "18.0", + "duration": "19.0", "name": "rendering.mobile/google_calendar_2018" }, { @@ -2028,39 +1536,39 @@ "name": "rendering.mobile/google_calendar_desktop_gpu_raster_2018" }, { - "duration": "36.0", + "duration": "34.0", "name": "rendering.mobile/google_docs_2018" }, { - "duration": "37.0", + "duration": "34.0", "name": "rendering.mobile/google_docs_desktop_gpu_raster_2018" }, { - "duration": "21.0", + "duration": "29.0", "name": "rendering.mobile/google_image_search_2018" }, { - "duration": "21.0", + "duration": "29.0", "name": "rendering.mobile/google_image_search_desktop_gpu_raster_2018" }, { - "duration": "34.0", + "duration": "35.0", "name": "rendering.mobile/google_image_search_mobile_2018" }, { - "duration": "26.0", + "duration": "27.0", "name": "rendering.mobile/google_news_ios" }, { - "duration": "21.0", + "duration": "19.0", "name": "rendering.mobile/google_news_mobile_2018" }, { - "duration": "32.0", + "duration": "30.0", "name": "rendering.mobile/google_plus_2018" }, { - "duration": "28.0", + "duration": "26.0", "name": "rendering.mobile/google_plus_desktop_gpu_raster_2018" }, { @@ -2068,39 +1576,39 @@ "name": "rendering.mobile/google_plus_mobile_2018" }, { - "duration": "21.0", + "duration": "23.0", "name": "rendering.mobile/google_web_search_2018" }, { - "duration": "16.0", + "duration": "20.0", "name": "rendering.mobile/google_web_search_desktop_gpu_raster_2018" }, { - "duration": "31.0", + "duration": "32.0", "name": "rendering.mobile/google_web_search_mobile_2018" }, { - "duration": "35.0", + "duration": "37.0", "name": "rendering.mobile/gsp.ro_mobile_2018" }, { - "duration": "32.0", + "duration": "35.0", "name": "rendering.mobile/guardian_pathological_2018" }, { - "duration": "34.0", + "duration": "32.0", "name": "rendering.mobile/guimark_vector_chart" }, { - "duration": "21.0", + "duration": "23.0", "name": "rendering.mobile/gws_boogie_expansion" }, { - "duration": "22.0", + "duration": "23.0", "name": "rendering.mobile/gws_google_expansion" }, { - "duration": "23.0", + "duration": "25.0", "name": "rendering.mobile/hakim" }, { @@ -2108,7 +1616,7 @@ "name": "rendering.mobile/horizontal_vertical_expansion" }, { - "duration": "46.0", + "duration": "41.0", "name": "rendering.mobile/idle_power_animated_gif" }, { @@ -2116,23 +1624,23 @@ "name": "rendering.mobile/idle_power_blank" }, { - "duration": "49.0", + "duration": "45.0", "name": "rendering.mobile/idle_power_css_animation" }, { - "duration": "55.0", + "duration": "60.0", "name": "rendering.mobile/idle_power_request_animation_frame" }, { - "duration": "163.0", + "duration": "133.0", "name": "rendering.mobile/idle_power_set_timeout_long" }, { - "duration": "55.0", + "duration": "50.0", "name": "rendering.mobile/idle_power_set_timetout" }, { - "duration": "41.0", + "duration": "45.0", "name": "rendering.mobile/ie_chalkboard" }, { @@ -2140,35 +1648,35 @@ "name": "rendering.mobile/ie_pirate_mark" }, { - "duration": "34.0", + "duration": "36.0", "name": "rendering.mobile/infinite_scroll_element_n_layers_0" }, { - "duration": "35.0", + "duration": "37.0", "name": "rendering.mobile/infinite_scroll_element_n_layers_75" }, { - "duration": "35.0", + "duration": "38.0", "name": "rendering.mobile/infinite_scroll_element_n_layers_99" }, { - "duration": "34.0", + "duration": "37.0", "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_0" }, { - "duration": "35.0", + "duration": "38.0", "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_75" }, { - "duration": "35.0", + "duration": "38.0", "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_99" }, { - "duration": "34.0", + "duration": "36.0", "name": "rendering.mobile/infinite_scroll_root_n_layers_0" }, { - "duration": "34.0", + "duration": "36.0", "name": "rendering.mobile/infinite_scroll_root_n_layers_75" }, { @@ -2176,35 +1684,35 @@ "name": "rendering.mobile/infinite_scroll_root_n_layers_99" }, { - "duration": "34.0", + "duration": "35.0", "name": "rendering.mobile/infinite_scrolling" }, { - "duration": "25.0", + "duration": "26.0", "name": "rendering.mobile/jarro_doverson" }, { - "duration": "41.0", + "duration": "43.0", "name": "rendering.mobile/js_full_screen_invalidation" }, { - "duration": "32.0", + "duration": "33.0", "name": "rendering.mobile/js_opacity_plus_n_layers_0" }, { - "duration": "33.0", + "duration": "34.0", "name": "rendering.mobile/js_opacity_plus_n_layers_75" }, { - "duration": "33.0", + "duration": "34.0", "name": "rendering.mobile/js_opacity_plus_n_layers_99" }, { - "duration": "35.0", + "duration": "36.0", "name": "rendering.mobile/js_paint_plus_n_layers_0" }, { - "duration": "35.0", + "duration": "36.0", "name": "rendering.mobile/js_paint_plus_n_layers_75" }, { @@ -2216,11 +1724,7 @@ "name": "rendering.mobile/js_poster_circle" }, { - "duration": "25.0", - "name": "rendering.mobile/js_scroll_200_layer_grid" - }, - { - "duration": "24.0", + "duration": "18.0", "name": "rendering.mobile/js_scroll_text_only" }, { @@ -2228,27 +1732,27 @@ "name": "rendering.mobile/keyframed_animations" }, { - "duration": "27.0", + "duration": "25.0", "name": "rendering.mobile/large_texture_uploads" }, { - "duration": "35.0", + "duration": "38.0", "name": "rendering.mobile/latimes_pathological_2018" }, { - "duration": "30.0", + "duration": "33.0", "name": "rendering.mobile/linkedin_2018" }, { - "duration": "26.0", + "duration": "29.0", "name": "rendering.mobile/linkedin_desktop_gpu_raster_2018" }, { - "duration": "63.0", + "duration": "60.0", "name": "rendering.mobile/linkedin_mobile_2018" }, { - "duration": "41.0", + "duration": "39.0", "name": "rendering.mobile/linkedin_pathological_2018" }, { @@ -2256,15 +1760,15 @@ "name": "rendering.mobile/list_animation_simple" }, { - "duration": "33.0", + "duration": "34.0", "name": "rendering.mobile/list_recycle_transform" }, { - "duration": "26.0", + "duration": "25.0", "name": "rendering.mobile/man_in_blue" }, { - "duration": "32.0", + "duration": "30.0", "name": "rendering.mobile/many_images" }, { @@ -2272,11 +1776,11 @@ "name": "rendering.mobile/many_planets_deep" }, { - "duration": "23.0", + "duration": "22.0", "name": "rendering.mobile/mask_transition_animation" }, { - "duration": "24.0", + "duration": "29.0", "name": "rendering.mobile/medium_texture_uploads" }, { @@ -2296,15 +1800,15 @@ "name": "rendering.mobile/microsoft_snow" }, { - "duration": "21.0", + "duration": "24.0", "name": "rendering.mobile/microsoft_speed_reading" }, { - "duration": "23.0", + "duration": "22.0", "name": "rendering.mobile/microsoft_tweet_map" }, { - "duration": "32.0", + "duration": "28.0", "name": "rendering.mobile/microsoft_video_city" }, { @@ -2316,23 +1820,23 @@ "name": "rendering.mobile/mix_10k" }, { - "duration": "33.0", + "duration": "30.0", "name": "rendering.mobile/mix_blend_mode_animation_difference" }, { - "duration": "33.0", + "duration": "31.0", "name": "rendering.mobile/mix_blend_mode_animation_hue" }, { - "duration": "32.0", + "duration": "30.0", "name": "rendering.mobile/mix_blend_mode_animation_propagating_isolation" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/mix_blend_mode_animation_screen" }, { - "duration": "37.0", + "duration": "45.0", "name": "rendering.mobile/mlb_mobile_2018" }, { @@ -2340,15 +1844,15 @@ "name": "rendering.mobile/mobile_news_sandbox" }, { - "duration": "29.0", + "duration": "26.0", "name": "rendering.mobile/motion_mark_canvas_fill_shapes" }, { - "duration": "30.0", + "duration": "24.0", "name": "rendering.mobile/motion_mark_canvas_stroke_shapes" }, { - "duration": "27.0", + "duration": "26.0", "name": "rendering.mobile/motionmark_anim_design_15" }, { @@ -2356,7 +1860,7 @@ "name": "rendering.mobile/motionmark_anim_focus_25" }, { - "duration": "50.0", + "duration": "42.0", "name": "rendering.mobile/motionmark_anim_images_50" }, { @@ -2380,35 +1884,35 @@ "name": "rendering.mobile/motionmark_html_css_bouncing_blend_circles_25" }, { - "duration": "34.0", + "duration": "35.0", "name": "rendering.mobile/motionmark_html_css_bouncing_circles_250" }, { - "duration": "36.0", + "duration": "33.0", "name": "rendering.mobile/motionmark_html_css_bouncing_clipped_rects_100" }, { - "duration": "34.0", + "duration": "32.0", "name": "rendering.mobile/motionmark_html_css_bouncing_filter_circles_15" }, { - "duration": "32.0", + "duration": "34.0", "name": "rendering.mobile/motionmark_html_css_bouncing_gradient_circles_250" }, { - "duration": "43.0", + "duration": "34.0", "name": "rendering.mobile/motionmark_html_css_bouncing_svg_images_50" }, { - "duration": "34.0", + "duration": "35.0", "name": "rendering.mobile/motionmark_html_css_bouncing_tagged_images_225" }, { - "duration": "46.0", + "duration": "34.0", "name": "rendering.mobile/motionmark_html_dom_particles_svg_masks_25" }, { - "duration": "31.0", + "duration": "32.0", "name": "rendering.mobile/motionmark_html_focus_20_15" }, { @@ -2420,11 +1924,11 @@ "name": "rendering.mobile/motionmark_svg_bouncing_circles_250" }, { - "duration": "37.0", + "duration": "34.0", "name": "rendering.mobile/motionmark_svg_bouncing_clipped_rects_100" }, { - "duration": "34.0", + "duration": "35.0", "name": "rendering.mobile/motionmark_svg_bouncing_gradient_circles_200" }, { @@ -2432,15 +1936,15 @@ "name": "rendering.mobile/motionmark_svg_bouncing_png_images_200" }, { - "duration": "43.0", + "duration": "67.0", "name": "rendering.mobile/motionmark_svg_bouncing_svg_images_50" }, { - "duration": "36.0", + "duration": "35.0", "name": "rendering.mobile/new_tilings" }, { - "duration": "27.0", + "duration": "25.0", "name": "rendering.mobile/no_op_raf" }, { @@ -2452,7 +1956,7 @@ "name": "rendering.mobile/no_op_settimeout" }, { - "duration": "20.0", + "duration": "26.0", "name": "rendering.mobile/no_op_touch_handler" }, { @@ -2460,11 +1964,11 @@ "name": "rendering.mobile/nvidia_vertex_buffer_object" }, { - "duration": "36.0", + "duration": "39.0", "name": "rendering.mobile/nyc_gov_scroll_2018" }, { - "duration": "38.0", + "duration": "37.0", "name": "rendering.mobile/nytimes_mobile_2018" }, { @@ -2472,11 +1976,11 @@ "name": "rendering.mobile/nytimes_scroll_2018" }, { - "duration": "47.0", + "duration": "163.0", "name": "rendering.mobile/overlay_background_color_css_transitions_page" }, { - "duration": "24.0", + "duration": "23.0", "name": "rendering.mobile/parallax_effect" }, { @@ -2484,7 +1988,7 @@ "name": "rendering.mobile/particles" }, { - "duration": "28.0", + "duration": "30.0", "name": "rendering.mobile/pbs_pathological_2018" }, { @@ -2492,19 +1996,19 @@ "name": "rendering.mobile/physical_simulation" }, { - "duration": "38.0", + "duration": "36.0", "name": "rendering.mobile/pinterest_2018" }, { - "duration": "34.0", + "duration": "33.0", "name": "rendering.mobile/pinterest_desktop_gpu_raster_2018" }, { - "duration": "22.0", + "duration": "21.0", "name": "rendering.mobile/pinterest_mobile_2018" }, { - "duration": "32.0", + "duration": "19.0", "name": "rendering.mobile/put_get_image_data" }, { @@ -2516,11 +2020,11 @@ "name": "rendering.mobile/raf_animation" }, { - "duration": "25.0", + "duration": "27.0", "name": "rendering.mobile/raf_canvas" }, { - "duration": "26.0", + "duration": "27.0", "name": "rendering.mobile/raf_touch_animation" }, { @@ -2528,7 +2032,7 @@ "name": "rendering.mobile/recode_pathological_2018" }, { - "duration": "23.0", + "duration": "39.0", "name": "rendering.mobile/reddit_mobile_2018" }, { @@ -2536,15 +2040,15 @@ "name": "rendering.mobile/runway" }, { - "duration": "27.0", + "duration": "26.0", "name": "rendering.mobile/san_angeles" }, { - "duration": "16.0", + "duration": "15.0", "name": "rendering.mobile/second_batch_js_heavy" }, { - "duration": "16.0", + "duration": "15.0", "name": "rendering.mobile/second_batch_js_light" }, { @@ -2552,11 +2056,11 @@ "name": "rendering.mobile/second_batch_js_medium" }, { - "duration": "41.0", + "duration": "43.0", "name": "rendering.mobile/sfgate_mobile_2018" }, { - "duration": "35.0", + "duration": "32.0", "name": "rendering.mobile/silk_finance" }, { @@ -2564,19 +2068,19 @@ "name": "rendering.mobile/simple_text_page" }, { - "duration": "21.0", + "duration": "20.0", "name": "rendering.mobile/simple_touch_drag" }, { - "duration": "31.0", + "duration": "37.0", "name": "rendering.mobile/slashdot_mobile_2018" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/small_texture_uploads" }, { - "duration": "23.0", + "duration": "22.0", "name": "rendering.mobile/spielzeugz" }, { @@ -2584,15 +2088,15 @@ "name": "rendering.mobile/sticky_using_webkit" }, { - "duration": "36.0", + "duration": "38.0", "name": "rendering.mobile/stress_hidey_bars" }, { - "duration": "22.0", + "duration": "19.0", "name": "rendering.mobile/stroke_shapes" }, { - "duration": "35.0", + "duration": "34.0", "name": "rendering.mobile/svg_icon_raster" }, { @@ -2600,83 +2104,83 @@ "name": "rendering.mobile/swipe_to_dismiss" }, { - "duration": "26.0", + "duration": "27.0", "name": "rendering.mobile/sync_scroll_offset" }, { - "duration": "40.0", + "duration": "43.0", "name": "rendering.mobile/techcrunch_2018" }, { - "duration": "37.0", + "duration": "39.0", "name": "rendering.mobile/techcrunch_desktop_gpu_raster_2018" }, { - "duration": "43.0", + "duration": "45.0", "name": "rendering.mobile/techcrunch_mobile_2018" }, { - "duration": "20.0", + "duration": "29.0", "name": "rendering.mobile/text_05000_pixels_per_second" }, { - "duration": "20.0", + "duration": "28.0", "name": "rendering.mobile/text_05000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "20.0", + "duration": "29.0", "name": "rendering.mobile/text_10000_pixels_per_second" }, { - "duration": "20.0", + "duration": "29.0", "name": "rendering.mobile/text_10000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "18.0", + "duration": "25.0", "name": "rendering.mobile/text_15000_pixels_per_second" }, { - "duration": "18.0", + "duration": "25.0", "name": "rendering.mobile/text_15000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "17.0", + "duration": "22.0", "name": "rendering.mobile/text_20000_pixels_per_second" }, { - "duration": "17.0", + "duration": "22.0", "name": "rendering.mobile/text_20000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "16.0", + "duration": "19.0", "name": "rendering.mobile/text_30000_pixels_per_second" }, { - "duration": "16.0", + "duration": "19.0", "name": "rendering.mobile/text_30000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "17.0", "name": "rendering.mobile/text_40000_pixels_per_second" }, { - "duration": "15.0", + "duration": "17.0", "name": "rendering.mobile/text_40000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "17.0", "name": "rendering.mobile/text_50000_pixels_per_second" }, { - "duration": "15.0", + "duration": "16.0", "name": "rendering.mobile/text_50000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "16.0", "name": "rendering.mobile/text_60000_pixels_per_second" }, { - "duration": "15.0", + "duration": "16.0", "name": "rendering.mobile/text_60000_pixels_per_second_desktop_gpu_raster" }, { @@ -2684,7 +2188,7 @@ "name": "rendering.mobile/text_75000_pixels_per_second" }, { - "duration": "14.0", + "duration": "15.0", "name": "rendering.mobile/text_75000_pixels_per_second_desktop_gpu_raster" }, { @@ -2692,47 +2196,47 @@ "name": "rendering.mobile/text_90000_pixels_per_second" }, { - "duration": "14.0", + "duration": "15.0", "name": "rendering.mobile/text_90000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "20.0", + "duration": "25.0", "name": "rendering.mobile/text_constant_full_page_raster_05000_pixels_per_second" }, { - "duration": "19.0", + "duration": "25.0", "name": "rendering.mobile/text_constant_full_page_raster_05000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "20.0", + "duration": "24.0", "name": "rendering.mobile/text_constant_full_page_raster_10000_pixels_per_second" }, { - "duration": "19.0", + "duration": "25.0", "name": "rendering.mobile/text_constant_full_page_raster_10000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "18.0", + "duration": "21.0", "name": "rendering.mobile/text_constant_full_page_raster_15000_pixels_per_second" }, { - "duration": "17.0", + "duration": "21.0", "name": "rendering.mobile/text_constant_full_page_raster_15000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "17.0", + "duration": "19.0", "name": "rendering.mobile/text_constant_full_page_raster_20000_pixels_per_second" }, { - "duration": "16.0", + "duration": "19.0", "name": "rendering.mobile/text_constant_full_page_raster_20000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "16.0", + "duration": "17.0", "name": "rendering.mobile/text_constant_full_page_raster_30000_pixels_per_second" }, { - "duration": "15.0", + "duration": "17.0", "name": "rendering.mobile/text_constant_full_page_raster_30000_pixels_per_second_desktop_gpu_raster" }, { @@ -2740,7 +2244,7 @@ "name": "rendering.mobile/text_constant_full_page_raster_40000_pixels_per_second" }, { - "duration": "15.0", + "duration": "16.0", "name": "rendering.mobile/text_constant_full_page_raster_40000_pixels_per_second_desktop_gpu_raster" }, { @@ -2756,19 +2260,19 @@ "name": "rendering.mobile/text_constant_full_page_raster_60000_pixels_per_second" }, { - "duration": "14.0", + "duration": "15.0", "name": "rendering.mobile/text_constant_full_page_raster_60000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "14.0", "name": "rendering.mobile/text_constant_full_page_raster_75000_pixels_per_second" }, { - "duration": "14.0", + "duration": "15.0", "name": "rendering.mobile/text_constant_full_page_raster_75000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "14.0", "name": "rendering.mobile/text_constant_full_page_raster_90000_pixels_per_second" }, { @@ -2776,19 +2280,19 @@ "name": "rendering.mobile/text_constant_full_page_raster_90000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "18.0", + "duration": "19.0", "name": "rendering.mobile/text_hover_05000_pixels_per_second" }, { - "duration": "18.0", + "duration": "19.0", "name": "rendering.mobile/text_hover_05000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "18.0", + "duration": "19.0", "name": "rendering.mobile/text_hover_10000_pixels_per_second" }, { - "duration": "18.0", + "duration": "19.0", "name": "rendering.mobile/text_hover_10000_pixels_per_second_desktop_gpu_raster" }, { @@ -2816,11 +2320,11 @@ "name": "rendering.mobile/text_hover_30000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "15.0", + "duration": "14.0", "name": "rendering.mobile/text_hover_40000_pixels_per_second" }, { - "duration": "15.0", + "duration": "14.0", "name": "rendering.mobile/text_hover_40000_pixels_per_second_desktop_gpu_raster" }, { @@ -2840,43 +2344,43 @@ "name": "rendering.mobile/text_hover_60000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "14.0", + "duration": "13.0", "name": "rendering.mobile/text_hover_75000_pixels_per_second" }, { - "duration": "14.0", + "duration": "13.0", "name": "rendering.mobile/text_hover_75000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "14.0", + "duration": "13.0", "name": "rendering.mobile/text_hover_90000_pixels_per_second" }, { - "duration": "14.0", + "duration": "13.0", "name": "rendering.mobile/text_hover_90000_pixels_per_second_desktop_gpu_raster" }, { - "duration": "35.0", + "duration": "40.0", "name": "rendering.mobile/theverge_article_mobile_2018" }, { - "duration": "42.0", + "duration": "43.0", "name": "rendering.mobile/theverge_mobile_2018" }, { - "duration": "26.0", + "duration": "25.0", "name": "rendering.mobile/toggle_drawer" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/touch_handler_scrolling" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/transform_transitions" }, { - "duration": "31.0", + "duration": "29.0", "name": "rendering.mobile/transform_transitions_js_block" }, { @@ -2884,19 +2388,19 @@ "name": "rendering.mobile/twitch_2018" }, { - "duration": "25.0", + "duration": "26.0", "name": "rendering.mobile/twitch_desktop_gpu_raster_2018" }, { - "duration": "25.0", + "duration": "31.0", "name": "rendering.mobile/twitter_2018" }, { - "duration": "25.0", + "duration": "31.0", "name": "rendering.mobile/twitter_desktop_gpu_raster_2018" }, { - "duration": "22.0", + "duration": "23.0", "name": "rendering.mobile/twitter_mobile_2018" }, { @@ -2904,15 +2408,15 @@ "name": "rendering.mobile/update_history_state" }, { - "duration": "19.0", + "duration": "20.0", "name": "rendering.mobile/usatoday_mobile_2018" }, { - "duration": "23.0", + "duration": "24.0", "name": "rendering.mobile/vertical_expansion" }, { - "duration": "29.0", + "duration": "28.0", "name": "rendering.mobile/web_animation_value_type_color" }, { @@ -2920,11 +2424,11 @@ "name": "rendering.mobile/web_animation_value_type_length_3d" }, { - "duration": "30.0", + "duration": "29.0", "name": "rendering.mobile/web_animation_value_type_length_complex" }, { - "duration": "31.0", + "duration": "30.0", "name": "rendering.mobile/web_animation_value_type_length_simple" }, { @@ -2932,7 +2436,7 @@ "name": "rendering.mobile/web_animation_value_type_path" }, { - "duration": "26.0", + "duration": "37.0", "name": "rendering.mobile/web_animation_value_type_shadow" }, { @@ -2960,7 +2464,7 @@ "name": "rendering.mobile/web_animations_staggered_chaining" }, { - "duration": "27.0", + "duration": "25.0", "name": "rendering.mobile/web_animations_staggered_infinite_iterations" }, { @@ -2968,15 +2472,15 @@ "name": "rendering.mobile/web_animations_staggered_triggering_page" }, { - "duration": "27.0", + "duration": "36.0", "name": "rendering.mobile/wikipedia_2018" }, { - "duration": "38.0", + "duration": "39.0", "name": "rendering.mobile/wikipedia_delayed_scroll_start_2018" }, { - "duration": "23.0", + "duration": "32.0", "name": "rendering.mobile/wikipedia_desktop_gpu_raster_2018" }, { @@ -2992,71 +2496,79 @@ "name": "rendering.mobile/wordpress_desktop_gpu_raster_2018" }, { - "duration": "40.0", + "duration": "41.0", "name": "rendering.mobile/wordpress_mobile_2018" }, { - "duration": "33.0", + "duration": "35.0", "name": "rendering.mobile/worldjournal_mobile_2018" }, { - "duration": "38.0", + "duration": "42.0", "name": "rendering.mobile/wow_wiki_pathological_2018" }, { - "duration": "59.0", + "duration": "71.0", "name": "rendering.mobile/wowwiki_mobile_2018" }, { - "duration": "54.0", + "duration": "47.0", "name": "rendering.mobile/wsj_mobile_2018" }, { - "duration": "23.0", + "duration": "26.0", "name": "rendering.mobile/yahoo_answers_2018" }, { - "duration": "19.0", + "duration": "23.0", "name": "rendering.mobile/yahoo_answers_desktop_gpu_raster_2018" }, { - "duration": "19.0", + "duration": "23.0", "name": "rendering.mobile/yahoo_news_2018" }, { - "duration": "19.0", + "duration": "24.0", "name": "rendering.mobile/yahoo_news_desktop_gpu_raster_2018" }, { - "duration": "40.0", + "duration": "36.0", "name": "rendering.mobile/yahoo_news_mobile_2018" }, { - "duration": "30.0", + "duration": "32.0", "name": "rendering.mobile/yahoo_sports_2018" }, { - "duration": "27.0", + "duration": "28.0", "name": "rendering.mobile/yahoo_sports_desktop_gpu_raster_2018" }, { - "duration": "21.0", + "duration": "19.0", "name": "rendering.mobile/yahoo_sports_pathological_2018" }, { + "duration": "29.0", + "name": "rendering.mobile/youtube_2018" + }, + { + "duration": "26.0", + "name": "rendering.mobile/youtube_desktop_gpu_raster_2018" + }, + { "duration": "24.0", "name": "rendering.mobile/youtube_mobile_2018" }, { - "duration": "28.0", + "duration": "31.0", "name": "rendering.mobile/yuv_decoding" }, { - "duration": "30.0", + "duration": "31.0", "name": "rendering.mobile/yuv_decoding_gpu_rasterization_and_decoding" }, { - "duration": "32.0", + "duration": "34.0", "name": "rendering.mobile/zdnet_pathological_2018" }, { @@ -3064,31 +2576,31 @@ "name": "rendering.mobile/zoom_in_animation" }, { - "duration": "37.0", + "duration": "43.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/accu_weather_pinch_2018" }, { - "duration": "27.0", + "duration": "28.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/amazon_pinch_2018" }, { - "duration": "23.0", + "duration": "25.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/blogspot_pinch_2018" }, { - "duration": "24.0", + "duration": "28.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/booking_pinch_2018" }, { - "duration": "26.0", + "duration": "30.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/cnn_pinch_2018" }, { - "duration": "22.0", + "duration": "24.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/ebay_pinch_2018" }, { - "duration": "27.0", + "duration": "30.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/espn_pinch_2018" }, { @@ -3096,11 +2608,11 @@ "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/facebook_pinch_2018" }, { - "duration": "45.0", + "duration": "47.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/gmail_pinch_2018" }, { - "duration": "34.0", + "duration": "38.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_calendar_pinch_2018" }, { @@ -3108,55 +2620,59 @@ "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_image_pinch_2018" }, { - "duration": "33.0", + "duration": "36.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_search_pinch_2018" }, { - "duration": "37.0", + "duration": "41.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/linkedin_pinch_2018" }, { - "duration": "27.0", + "duration": "28.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/twitch_pinch_2018" }, { - "duration": "24.0", + "duration": "25.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/twitter_pinch_2018" }, { - "duration": "26.0", + "duration": "35.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_news_pinch_2018" }, { - "duration": "31.0", + "duration": "37.0", "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_sports_pinch_2018" }, { - "duration": "34.0", + "duration": "26.0", + "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/youtube_pinch_2018" + }, + { + "duration": "42.0", "name": "smoothness.tough_pinch_zoom_cases/accu_weather_pinch_2018" }, { - "duration": "27.0", + "duration": "28.0", "name": "smoothness.tough_pinch_zoom_cases/amazon_pinch_2018" }, { - "duration": "23.0", + "duration": "25.0", "name": "smoothness.tough_pinch_zoom_cases/blogspot_pinch_2018" }, { - "duration": "23.0", + "duration": "28.0", "name": "smoothness.tough_pinch_zoom_cases/booking_pinch_2018" }, { - "duration": "27.0", + "duration": "30.0", "name": "smoothness.tough_pinch_zoom_cases/cnn_pinch_2018" }, { - "duration": "22.0", + "duration": "24.0", "name": "smoothness.tough_pinch_zoom_cases/ebay_pinch_2018" }, { - "duration": "28.0", + "duration": "30.0", "name": "smoothness.tough_pinch_zoom_cases/espn_pinch_2018" }, { @@ -3164,11 +2680,11 @@ "name": "smoothness.tough_pinch_zoom_cases/facebook_pinch_2018" }, { - "duration": "44.0", + "duration": "47.0", "name": "smoothness.tough_pinch_zoom_cases/gmail_pinch_2018" }, { - "duration": "35.0", + "duration": "38.0", "name": "smoothness.tough_pinch_zoom_cases/google_calendar_pinch_2018" }, { @@ -3180,7 +2696,7 @@ "name": "smoothness.tough_pinch_zoom_cases/google_search_pinch_2018" }, { - "duration": "38.0", + "duration": "41.0", "name": "smoothness.tough_pinch_zoom_cases/linkedin_pinch_2018" }, { @@ -3192,47 +2708,335 @@ "name": "smoothness.tough_pinch_zoom_cases/twitter_pinch_2018" }, { - "duration": "30.0", + "duration": "35.0", "name": "smoothness.tough_pinch_zoom_cases/yahoo_news_pinch_2018" }, { - "duration": "34.0", + "duration": "37.0", "name": "smoothness.tough_pinch_zoom_cases/yahoo_sports_pinch_2018" }, { - "duration": "43.0", + "duration": "26.0", + "name": "smoothness.tough_pinch_zoom_cases/youtube_pinch_2018" + }, + { + "duration": "38.0", "name": "speedometer-future/http://browserbench.org/Speedometer/" }, { - "duration": "43.0", + "duration": "38.0", "name": "speedometer/http://browserbench.org/Speedometer/" }, { - "duration": "73.0", + "duration": "62.0", "name": "speedometer2-future/Speedometer2" }, { - "duration": "73.0", + "duration": "62.0", "name": "speedometer2/Speedometer2" }, { - "duration": "36.0", + "duration": "24.0", + "name": "system_health.common_mobile/background:media:imgur" + }, + { + "duration": "25.0", + "name": "system_health.common_mobile/background:search:google" + }, + { + "duration": "35.0", "name": "system_health.common_mobile/background:social:facebook" }, { - "duration": "27.0", - "name": "system_health.memory_mobile/background:media:imgur" + "duration": "10.0", + "name": "system_health.common_mobile/browse:chrome:newtab" }, { - "duration": "28.0", - "name": "system_health.memory_mobile/background:search:google" + "duration": "10.0", + "name": "system_health.common_mobile/browse:chrome:omnibox" + }, + { + "duration": "95.0", + "name": "system_health.common_mobile/browse:media:facebook_photos" + }, + { + "duration": "63.0", + "name": "system_health.common_mobile/browse:media:flickr_infinite_scroll" + }, + { + "duration": "88.0", + "name": "system_health.common_mobile/browse:media:imgur" + }, + { + "duration": "112.0", + "name": "system_health.common_mobile/browse:media:youtube" + }, + { + "duration": "109.0", + "name": "system_health.common_mobile/browse:news:cnn" + }, + { + "duration": "89.0", + "name": "system_health.common_mobile/browse:news:cnn:2018" + }, + { + "duration": "76.0", + "name": "system_health.common_mobile/browse:news:cricbuzz" + }, + { + "duration": "72.0", + "name": "system_health.common_mobile/browse:news:qq" + }, + { + "duration": "60.0", + "name": "system_health.common_mobile/browse:news:reddit" + }, + { + "duration": "162.0", + "name": "system_health.common_mobile/browse:news:toi" + }, + { + "duration": "65.0", + "name": "system_health.common_mobile/browse:news:washingtonpost" + }, + { + "duration": "82.0", + "name": "system_health.common_mobile/browse:shopping:amazon" + }, + { + "duration": "81.0", + "name": "system_health.common_mobile/browse:shopping:avito" + }, + { + "duration": "41.0", + "name": "system_health.common_mobile/browse:shopping:lazada" + }, + { + "duration": "76.0", + "name": "system_health.common_mobile/browse:social:facebook" + }, + { + "duration": "270.0", + "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll" + }, + { + "duration": "126.0", + "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll:2018" + }, + { + "duration": "86.0", + "name": "system_health.common_mobile/browse:social:instagram" + }, + { + "duration": "106.0", + "name": "system_health.common_mobile/browse:social:pinterest_infinite_scroll" + }, + { + "duration": "136.0", + "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll" + }, + { + "duration": "64.0", + "name": "system_health.common_mobile/browse:social:twitter" + }, + { + "duration": "82.0", + "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll" + }, + { + "duration": "113.0", + "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll:2018" + }, + { + "duration": "51.0", + "name": "system_health.common_mobile/browse:tools:maps" + }, + { + "duration": "21.0", + "name": "system_health.common_mobile/load:chrome:blank" + }, + { + "duration": "27.0", + "name": "system_health.common_mobile/load:games:bubbles" + }, + { + "duration": "22.0", + "name": "system_health.common_mobile/load:games:lazors" + }, + { + "duration": "35.0", + "name": "system_health.common_mobile/load:games:spychase" + }, + { + "duration": "36.0", + "name": "system_health.common_mobile/load:games:spychase:2018" + }, + { + "duration": "27.0", + "name": "system_health.common_mobile/load:media:dailymotion" + }, + { + "duration": "26.0", + "name": "system_health.common_mobile/load:media:facebook_photos" + }, + { + "duration": "30.0", + "name": "system_health.common_mobile/load:media:flickr:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:media:google_images" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:media:google_images:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:media:imgur" + }, + { + "duration": "35.0", + "name": "system_health.common_mobile/load:media:imgur:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:media:soundcloud:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:media:youtube" + }, + { + "duration": "26.0", + "name": "system_health.common_mobile/load:media:youtube:2018" + }, + { + "duration": "38.0", + "name": "system_health.common_mobile/load:news:cnn" + }, + { + "duration": "37.0", + "name": "system_health.common_mobile/load:news:cnn:2018" }, { "duration": "29.0", + "name": "system_health.common_mobile/load:news:irctc" + }, + { + "duration": "28.0", + "name": "system_health.common_mobile/load:news:nytimes" + }, + { + "duration": "27.0", + "name": "system_health.common_mobile/load:news:qq" + }, + { + "duration": "25.0", + "name": "system_health.common_mobile/load:news:reddit" + }, + { + "duration": "27.0", + "name": "system_health.common_mobile/load:news:washingtonpost" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:news:wikipedia" + }, + { + "duration": "23.0", + "name": "system_health.common_mobile/load:news:wikipedia:2018" + }, + { + "duration": "26.0", + "name": "system_health.common_mobile/load:search:baidu" + }, + { + "duration": "28.0", + "name": "system_health.common_mobile/load:search:baidu:2018" + }, + { + "duration": "26.0", + "name": "system_health.common_mobile/load:search:ebay" + }, + { + "duration": "30.0", + "name": "system_health.common_mobile/load:search:ebay:2018" + }, + { + "duration": "23.0", + "name": "system_health.common_mobile/load:search:google" + }, + { + "duration": "25.0", + "name": "system_health.common_mobile/load:search:google:2018" + }, + { + "duration": "25.0", + "name": "system_health.common_mobile/load:search:taobao" + }, + { + "duration": "23.0", + "name": "system_health.common_mobile/load:search:yahoo" + }, + { + "duration": "22.0", + "name": "system_health.common_mobile/load:search:yahoo:2018" + }, + { + "duration": "23.0", + "name": "system_health.common_mobile/load:search:yandex" + }, + { + "duration": "25.0", + "name": "system_health.common_mobile/load:search:yandex:2018" + }, + { + "duration": "23.0", + "name": "system_health.common_mobile/load:social:twitter" + }, + { + "duration": "25.0", + "name": "system_health.common_mobile/load:tools:docs" + }, + { + "duration": "28.0", + "name": "system_health.common_mobile/load:tools:drive" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:tools:dropbox" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:tools:stackoverflow" + }, + { + "duration": "24.0", + "name": "system_health.common_mobile/load:tools:stackoverflow:2018" + }, + { + "duration": "29.0", + "name": "system_health.common_mobile/load:tools:weather" + }, + { + "duration": "28.0", + "name": "system_health.memory_mobile/background:media:imgur" + }, + { + "duration": "29.0", + "name": "system_health.memory_mobile/background:search:google" + }, + { + "duration": "32.0", "name": "system_health.memory_mobile/background:social:facebook" }, { - "duration": "75.0", + "duration": "12.0", + "name": "system_health.memory_mobile/browse:chrome:newtab" + }, + { + "duration": "79.0", "name": "system_health.memory_mobile/browse:media:facebook_photos" }, { @@ -3240,35 +3044,39 @@ "name": "system_health.memory_mobile/browse:media:flickr_infinite_scroll" }, { - "duration": "73.0", + "duration": "74.0", "name": "system_health.memory_mobile/browse:media:imgur" }, { - "duration": "63.0", + "duration": "84.0", + "name": "system_health.memory_mobile/browse:media:youtube" + }, + { + "duration": "62.0", "name": "system_health.memory_mobile/browse:news:cnn" }, { - "duration": "60.0", + "duration": "55.0", "name": "system_health.memory_mobile/browse:news:cnn:2018" }, { - "duration": "49.0", + "duration": "60.0", "name": "system_health.memory_mobile/browse:news:cricbuzz" }, { - "duration": "52.0", + "duration": "58.0", "name": "system_health.memory_mobile/browse:news:qq" }, { - "duration": "55.0", + "duration": "52.0", "name": "system_health.memory_mobile/browse:news:reddit" }, { - "duration": "73.0", + "duration": "76.0", "name": "system_health.memory_mobile/browse:news:toi" }, { - "duration": "51.0", + "duration": "50.0", "name": "system_health.memory_mobile/browse:news:washingtonpost" }, { @@ -3276,7 +3084,7 @@ "name": "system_health.memory_mobile/browse:shopping:amazon" }, { - "duration": "68.0", + "duration": "58.0", "name": "system_health.memory_mobile/browse:shopping:avito" }, { @@ -3284,39 +3092,39 @@ "name": "system_health.memory_mobile/browse:shopping:lazada" }, { - "duration": "62.0", + "duration": "60.0", "name": "system_health.memory_mobile/browse:social:facebook" }, { - "duration": "80.0", + "duration": "81.0", "name": "system_health.memory_mobile/browse:social:facebook_infinite_scroll:2018" }, { - "duration": "92.0", + "duration": "75.0", "name": "system_health.memory_mobile/browse:social:instagram" }, { - "duration": "75.0", + "duration": "74.0", "name": "system_health.memory_mobile/browse:social:pinterest_infinite_scroll" }, { - "duration": "75.0", + "duration": "74.0", "name": "system_health.memory_mobile/browse:social:tumblr_infinite_scroll" }, { - "duration": "53.0", + "duration": "52.0", "name": "system_health.memory_mobile/browse:social:twitter" }, { - "duration": "59.0", + "duration": "58.0", "name": "system_health.memory_mobile/browse:tech:discourse_infinite_scroll" }, { - "duration": "47.0", + "duration": "48.0", "name": "system_health.memory_mobile/browse:tools:maps" }, { - "duration": "25.0", + "duration": "26.0", "name": "system_health.memory_mobile/load:chrome:blank" }, { @@ -3332,35 +3140,59 @@ "name": "system_health.memory_mobile/load:games:spychase" }, { + "duration": "32.0", + "name": "system_health.memory_mobile/load:games:spychase:2018" + }, + { "duration": "28.0", "name": "system_health.memory_mobile/load:media:dailymotion" }, { - "duration": "27.0", + "duration": "28.0", "name": "system_health.memory_mobile/load:media:facebook_photos" }, { - "duration": "27.0", + "duration": "30.0", + "name": "system_health.memory_mobile/load:media:flickr:2018" + }, + { + "duration": "28.0", "name": "system_health.memory_mobile/load:media:google_images" }, { "duration": "27.0", + "name": "system_health.memory_mobile/load:media:google_images:2018" + }, + { + "duration": "27.0", "name": "system_health.memory_mobile/load:media:imgur" }, { + "duration": "29.0", + "name": "system_health.memory_mobile/load:media:imgur:2018" + }, + { + "duration": "27.0", + "name": "system_health.memory_mobile/load:media:soundcloud:2018" + }, + { "duration": "27.0", "name": "system_health.memory_mobile/load:media:youtube" }, { - "duration": "32.0", + "duration": "26.0", + "name": "system_health.memory_mobile/load:media:youtube:2018" + }, + { + "duration": "31.0", "name": "system_health.memory_mobile/load:news:cnn" }, { - "duration": "32.0", + "duration": "31.0", "name": "system_health.memory_mobile/load:news:cnn:2018" }, { - "duration": "27.0", + "duration": "28.0", "name": "system_health.memory_mobile/load:news:irctc" }, { @@ -3368,11 +3200,11 @@ "name": "system_health.memory_mobile/load:news:nytimes" }, { - "duration": "26.0", + "duration": "29.0", "name": "system_health.memory_mobile/load:news:qq" }, { - "duration": "27.0", + "duration": "28.0", "name": "system_health.memory_mobile/load:news:reddit" }, { @@ -3380,23 +3212,39 @@ "name": "system_health.memory_mobile/load:news:washingtonpost" }, { - "duration": "27.0", + "duration": "29.0", "name": "system_health.memory_mobile/load:news:wikipedia" }, { - "duration": "27.0", + "duration": "30.0", + "name": "system_health.memory_mobile/load:news:wikipedia:2018" + }, + { + "duration": "29.0", "name": "system_health.memory_mobile/load:search:baidu" }, { - "duration": "26.0", + "duration": "30.0", + "name": "system_health.memory_mobile/load:search:baidu:2018" + }, + { + "duration": "27.0", "name": "system_health.memory_mobile/load:search:ebay" }, { - "duration": "26.0", + "duration": "28.0", + "name": "system_health.memory_mobile/load:search:ebay:2018" + }, + { + "duration": "27.0", "name": "system_health.memory_mobile/load:search:google" }, { "duration": "27.0", + "name": "system_health.memory_mobile/load:search:google:2018" + }, + { + "duration": "28.0", "name": "system_health.memory_mobile/load:search:taobao" }, { @@ -3405,10 +3253,18 @@ }, { "duration": "26.0", + "name": "system_health.memory_mobile/load:search:yahoo:2018" + }, + { + "duration": "27.0", "name": "system_health.memory_mobile/load:search:yandex" }, { "duration": "27.0", + "name": "system_health.memory_mobile/load:search:yandex:2018" + }, + { + "duration": "28.0", "name": "system_health.memory_mobile/load:social:twitter" }, { @@ -3420,19 +3276,19 @@ "name": "system_health.memory_mobile/load:tools:dropbox" }, { - "duration": "27.0", + "duration": "28.0", "name": "system_health.memory_mobile/load:tools:stackoverflow" }, { - "duration": "27.0", + "duration": "28.0", "name": "system_health.memory_mobile/load:tools:stackoverflow:2018" }, { - "duration": "29.0", + "duration": "30.0", "name": "system_health.memory_mobile/load:tools:weather" }, { - "duration": "27.0", + "duration": "26.0", "name": "system_health.webview_startup/load:chrome:blank" }, { @@ -3440,7 +3296,7 @@ "name": "tracing.tracing_with_background_memory_infra/Facebook" }, { - "duration": "12.0", + "duration": "13.0", "name": "tracing.tracing_with_background_memory_infra/Wikipedia" }, { @@ -3456,15 +3312,15 @@ "name": "tracing.tracing_with_background_memory_infra/http://www.bing.com/" }, { - "duration": "10.0", + "duration": "11.0", "name": "tracing.tracing_with_background_memory_infra/http://www.yahoo.com/" }, { - "duration": "12.0", + "duration": "13.0", "name": "tracing.tracing_with_background_memory_infra/http://www.youtube.com" }, { - "duration": "20.0", + "duration": "21.0", "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/#hl=en&q=barack+obama" }, { @@ -3472,187 +3328,183 @@ "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/calendar/" }, { - "duration": "124.0", + "duration": "122.0", "name": "v8.browsing_mobile-future/browse:media:facebook_photos" }, { - "duration": "97.0", + "duration": "93.0", "name": "v8.browsing_mobile-future/browse:media:flickr_infinite_scroll" }, { - "duration": "124.0", + "duration": "116.0", "name": "v8.browsing_mobile-future/browse:media:imgur" }, { - "duration": "144.0", + "duration": "148.0", "name": "v8.browsing_mobile-future/browse:media:youtube" }, { - "duration": "195.0", + "duration": "211.0", "name": "v8.browsing_mobile-future/browse:news:cnn" }, { - "duration": "140.0", + "duration": "147.0", "name": "v8.browsing_mobile-future/browse:news:cnn:2018" }, { - "duration": "96.0", + "duration": "102.0", "name": "v8.browsing_mobile-future/browse:news:cricbuzz" }, { - "duration": "94.0", + "duration": "95.0", "name": "v8.browsing_mobile-future/browse:news:qq" }, { - "duration": "83.0", + "duration": "78.0", "name": "v8.browsing_mobile-future/browse:news:reddit" }, { - "duration": "280.0", + "duration": "336.0", "name": "v8.browsing_mobile-future/browse:news:toi" }, { - "duration": "99.0", + "duration": "94.0", "name": "v8.browsing_mobile-future/browse:news:washingtonpost" }, { - "duration": "142.0", + "duration": "138.0", "name": "v8.browsing_mobile-future/browse:shopping:amazon" }, { - "duration": "135.0", - "name": "v8.browsing_mobile-future/browse:shopping:avito" - }, - { - "duration": "56.0", + "duration": "53.0", "name": "v8.browsing_mobile-future/browse:shopping:lazada" }, { - "duration": "122.0", + "duration": "114.0", "name": "v8.browsing_mobile-future/browse:social:facebook" }, { - "duration": "706.0", + "duration": "621.0", "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll" }, { - "duration": "227.0", + "duration": "282.0", "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll:2018" }, { - "duration": "180.0", + "duration": "138.0", "name": "v8.browsing_mobile-future/browse:social:instagram" }, { - "duration": "246.0", + "duration": "190.0", "name": "v8.browsing_mobile-future/browse:social:pinterest_infinite_scroll" }, { - "duration": "233.0", + "duration": "279.0", "name": "v8.browsing_mobile-future/browse:social:tumblr_infinite_scroll" }, { - "duration": "84.0", + "duration": "81.0", "name": "v8.browsing_mobile-future/browse:social:twitter" }, { - "duration": "142.0", + "duration": "143.0", "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll" }, { - "duration": "208.0", + "duration": "243.0", "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll:2018" }, { - "duration": "72.0", + "duration": "68.0", "name": "v8.browsing_mobile-future/browse:tools:maps" }, { - "duration": "123.0", + "duration": "121.0", "name": "v8.browsing_mobile/browse:media:facebook_photos" }, { - "duration": "100.0", + "duration": "93.0", "name": "v8.browsing_mobile/browse:media:flickr_infinite_scroll" }, { - "duration": "127.0", + "duration": "115.0", "name": "v8.browsing_mobile/browse:media:imgur" }, { - "duration": "141.0", + "duration": "146.0", "name": "v8.browsing_mobile/browse:news:cnn:2018" }, { - "duration": "97.0", + "duration": "98.0", "name": "v8.browsing_mobile/browse:news:cricbuzz" }, { - "duration": "93.0", + "duration": "104.0", "name": "v8.browsing_mobile/browse:news:qq" }, { - "duration": "84.0", + "duration": "78.0", "name": "v8.browsing_mobile/browse:news:reddit" }, { - "duration": "278.0", + "duration": "350.0", "name": "v8.browsing_mobile/browse:news:toi" }, { - "duration": "99.0", + "duration": "94.0", "name": "v8.browsing_mobile/browse:news:washingtonpost" }, { - "duration": "144.0", + "duration": "137.0", "name": "v8.browsing_mobile/browse:shopping:amazon" }, { - "duration": "132.0", + "duration": "119.0", "name": "v8.browsing_mobile/browse:shopping:avito" }, { - "duration": "55.0", + "duration": "52.0", "name": "v8.browsing_mobile/browse:shopping:lazada" }, { - "duration": "135.0", + "duration": "114.0", "name": "v8.browsing_mobile/browse:social:facebook" }, { - "duration": "740.0", + "duration": "631.0", "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll" }, { - "duration": "228.0", + "duration": "285.0", "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll:2018" }, { - "duration": "182.0", + "duration": "137.0", "name": "v8.browsing_mobile/browse:social:instagram" }, { - "duration": "247.0", + "duration": "188.0", "name": "v8.browsing_mobile/browse:social:pinterest_infinite_scroll" }, { - "duration": "229.0", + "duration": "281.0", "name": "v8.browsing_mobile/browse:social:tumblr_infinite_scroll" }, { - "duration": "85.0", + "duration": "81.0", "name": "v8.browsing_mobile/browse:social:twitter" }, { - "duration": "144.0", + "duration": "143.0", "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll" }, { - "duration": "212.0", + "duration": "237.0", "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll:2018" }, { - "duration": "71.0", + "duration": "68.0", "name": "v8.browsing_mobile/browse:tools:maps" }, { @@ -3660,7 +3512,7 @@ "name": "wasm/AsmJsZenGarden" }, { - "duration": "22.0", + "duration": "20.0", "name": "wasm/WasmSpaceBuggy" }, { @@ -3676,39 +3528,39 @@ "name": "wasm/WasmTanks" }, { - "duration": "9.0", + "duration": "8.0", "name": "wasm/WasmZenGarden" }, { - "duration": "22.0", + "duration": "20.0", "name": "webrtc/10s_datachannel_transfer" }, { - "duration": "28.0", + "duration": "25.0", "name": "webrtc/canvas_capture_peer_connection" }, { - "duration": "38.0", + "duration": "35.0", "name": "webrtc/codec_constraints_h264" }, { - "duration": "38.0", + "duration": "35.0", "name": "webrtc/codec_constraints_vp8" }, { - "duration": "38.0", + "duration": "35.0", "name": "webrtc/codec_constraints_vp9" }, { - "duration": "24.0", + "duration": "22.0", "name": "webrtc/hd_local_stream_10s" }, { - "duration": "46.0", + "duration": "43.0", "name": "webrtc/multiple_peerconnections" }, { - "duration": "68.0", + "duration": "65.0", "name": "webrtc/pause_play_peerconnections" } ] \ No newline at end of file
diff --git a/tools/perf/page_sets/data/rendering_desktop.json b/tools/perf/page_sets/data/rendering_desktop.json index d48067d..0347c85 100644 --- a/tools/perf/page_sets/data/rendering_desktop.json +++ b/tools/perf/page_sets/data/rendering_desktop.json
@@ -18,6 +18,9 @@ "animometer_webgl": { "DEFAULT": "rendering_desktop_011.wprgo" }, + "animometer_webgl_multi_draw": { + "DEFAULT": "rendering_desktop_a8987d91b9.wprgo" + }, "aquarium": { "DEFAULT": "rendering_desktop_011.wprgo" },
diff --git a/tools/perf/page_sets/data/rendering_desktop_a8987d91b9.wprgo.sha1 b/tools/perf/page_sets/data/rendering_desktop_a8987d91b9.wprgo.sha1 new file mode 100644 index 0000000..f11450656 --- /dev/null +++ b/tools/perf/page_sets/data/rendering_desktop_a8987d91b9.wprgo.sha1
@@ -0,0 +1 @@ +a8987d91b93f67c7d4f8d2679bcb5199dc0b2cad \ No newline at end of file
diff --git a/tools/perf/page_sets/data/rendering_mobile.json b/tools/perf/page_sets/data/rendering_mobile.json index 9de2edd..94af3c1 100644 --- a/tools/perf/page_sets/data/rendering_mobile.json +++ b/tools/perf/page_sets/data/rendering_mobile.json
@@ -24,6 +24,9 @@ "animometer_webgl": { "DEFAULT": "rendering_mobile_026.wprgo" }, + "animometer_webgl_multi_draw": { + "DEFAULT": "rendering_mobile_490dc1e73f.wprgo" + }, "aquarium": { "DEFAULT": "rendering_mobile_026.wprgo" },
diff --git a/tools/perf/page_sets/data/rendering_mobile_490dc1e73f.wprgo.sha1 b/tools/perf/page_sets/data/rendering_mobile_490dc1e73f.wprgo.sha1 new file mode 100644 index 0000000..7c61f061 --- /dev/null +++ b/tools/perf/page_sets/data/rendering_mobile_490dc1e73f.wprgo.sha1
@@ -0,0 +1 @@ +490dc1e73f7f6ee154a2f273b233d4ffdc9b9684 \ No newline at end of file
diff --git a/tools/perf/page_sets/rendering/tough_webgl_cases.py b/tools/perf/page_sets/rendering/tough_webgl_cases.py index 2d9e6f34..fff0311 100644 --- a/tools/perf/page_sets/rendering/tough_webgl_cases.py +++ b/tools/perf/page_sets/rendering/tough_webgl_cases.py
@@ -15,6 +15,9 @@ shared_page_state_class, name_suffix='', extra_browser_args=None): + if extra_browser_args is None: + extra_browser_args = [] + extra_browser_args.append("--enable-webgl-draft-extensions") super(ToughWebglPage, self).__init__( page_set=page_set, shared_page_state_class=shared_page_state_class, @@ -92,6 +95,10 @@ # pylint: disable=line-too-long URL = 'http://kenrussell.github.io/webgl-animometer/Animometer/tests/3d/webgl.html' +class AnimometerWebGLMultiDrawPage(ToughWebglPage): + BASE_NAME = 'animometer_webgl_multi_draw' + # pylint: disable=line-too-long + URL = 'http://kenrussell.github.io/webgl-animometer/Animometer/tests/3d/webgl.html?webgl_version=2&use_ubos=1&use_multi_draw=1' class CameraToWebGLPage(ToughWebglPage): TAGS = ToughWebglPage.TAGS + [story_tags.USE_FAKE_CAMERA_DEVICE]
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 5ba18d3..5a01aac 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -32,7 +32,7 @@ <item id="blob_reader" hash_code="5154306" type="0" deprecated="2018-06-14" content_hash_code="39702178" file_path=""/> <item id="bluetooth_socket" hash_code="94099818" type="0" content_hash_code="30932349" os_list="linux,windows" file_path="device/bluetooth/bluetooth_socket_net.cc"/> <item id="brandcode_config" hash_code="109679553" type="0" content_hash_code="128843792" os_list="linux,windows" file_path="chrome/browser/profile_resetter/brandcode_config_fetcher.cc"/> - <item id="browser_switcher_ieem_sitelist" hash_code="97159948" type="0" content_hash_code="9996111" os_list="windows" file_path="chrome/browser/browser_switcher/browser_switcher_service.cc"/> + <item id="browser_switcher_ieem_sitelist" hash_code="97159948" type="0" content_hash_code="40881413" os_list="linux,windows" file_path="chrome/browser/browser_switcher/browser_switcher_service.cc"/> <item id="captive_portal_service" hash_code="88754904" type="0" content_hash_code="70737580" os_list="linux,windows" file_path="chrome/browser/captive_portal/captive_portal_service.cc"/> <item id="cast_channel_send" hash_code="103172229" type="0" deprecated="2018-08-23" content_hash_code="33946302" file_path=""/> <item id="cast_keep_alive_delegate" hash_code="134755844" type="0" deprecated="2018-08-23" content_hash_code="66118796" file_path=""/> @@ -43,7 +43,7 @@ <item id="certificate_verifier" hash_code="113553577" type="0" content_hash_code="62346354" os_list="linux,windows" file_path="net/cert_net/cert_net_fetcher_impl.cc"/> <item id="chrome_apps_socket_api" hash_code="8591273" type="0" content_hash_code="70868355" os_list="linux,windows" file_path="extensions/browser/api/socket/socket.cc"/> <item id="chrome_cleaner" hash_code="27071967" type="0" content_hash_code="111240292" os_list="windows" file_path="chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc"/> - <item id="chrome_cleanup_report" hash_code="71102679" type="0" content_hash_code="26537237" os_list="windows" file_path="chrome/chrome_cleaner/logging/cleaner_logging_service.cc"/> + <item id="chrome_cleanup_report" hash_code="71102679" type="0" content_hash_code="50235856" os_list="windows" file_path="chrome/chrome_cleaner/logging/cleaner_logging_service.cc"/> <item id="chrome_feedback_report_app" hash_code="134729048" type="0" content_hash_code="73916972" os_list="linux,windows" file_path="components/feedback/feedback_uploader.cc"/> <item id="chrome_variations_service" hash_code="115188287" type="0" content_hash_code="32485683" os_list="linux,windows" file_path="components/variations/service/variations_service.cc"/> <item id="client_download_request" hash_code="125522256" type="0" content_hash_code="23897505" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/check_client_download_request.cc"/> @@ -91,7 +91,7 @@ <item id="doodle_service" hash_code="41154842" type="0" deprecated="2017-08-28" content_hash_code="28273962" file_path=""/> <item id="download_internals_webui_source" hash_code="38670228" type="0" content_hash_code="129391056" os_list="linux,windows" file_path="chrome/browser/ui/webui/download_internals/download_internals_ui_message_handler.cc"/> <item id="download_manager_resume" hash_code="35380758" type="0" content_hash_code="41227674" os_list="linux,windows" file_path="components/download/internal/common/download_item_impl.cc"/> - <item id="download_recovery_component" hash_code="131711536" type="0" content_hash_code="110581751" os_list="windows" file_path="chrome/chrome_cleaner/components/recovery_component.cc"/> + <item id="download_recovery_component" hash_code="131711536" type="0" content_hash_code="3243311" os_list="windows" file_path="chrome/chrome_cleaner/components/recovery_component.cc"/> <item id="download_web_contents_frame" hash_code="56351037" type="0" content_hash_code="3657889" os_list="linux,windows" file_path="content/browser/web_contents/web_contents_impl.cc"/> <item id="downloads_api_run_async" hash_code="121068967" type="0" content_hash_code="87443585" os_list="linux,windows" file_path="chrome/browser/extensions/api/downloads/downloads_api.cc"/> <item id="drag_download_file" hash_code="95910019" type="0" content_hash_code="126492858" os_list="linux,windows" file_path="content/browser/download/drag_download_file.cc"/> @@ -270,7 +270,7 @@ <item id="translate_url_fetcher" hash_code="137116619" type="0" content_hash_code="104217506" os_list="linux,windows" file_path="components/translate/core/browser/translate_url_fetcher.cc"/> <item id="ui_devtools_server" hash_code="4986170" type="0" content_hash_code="62670263" os_list="linux,windows" file_path="components/ui_devtools/devtools_server.cc"/> <item id="undefined" hash_code="45578882" type="0" reserved="1" os_list="linux,windows" file_path=""/> - <item id="unwanted_software_report" hash_code="43759504" type="0" content_hash_code="111455033" os_list="windows" file_path="chrome/chrome_cleaner/logging/reporter_logging_service.cc"/> + <item id="unwanted_software_report" hash_code="43759504" type="0" content_hash_code="43217092" os_list="windows" file_path="chrome/chrome_cleaner/logging/reporter_logging_service.cc"/> <item id="url_fetcher_downloader" hash_code="113231892" type="0" content_hash_code="61085066" os_list="linux,windows" file_path="components/update_client/url_fetcher_downloader.cc"/> <item id="url_prevision_fetcher" hash_code="118389509" type="0" content_hash_code="66145513" os_list="linux,windows" file_path="content/browser/media/url_provision_fetcher.cc"/> <item id="user_info_fetcher" hash_code="22265491" type="0" content_hash_code="72016232" os_list="linux,windows" file_path="components/policy/core/common/cloud/user_info_fetcher.cc"/>
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc index 7bb88f6..97f093d 100644 --- a/ui/events/blink/input_handler_proxy.cc +++ b/ui/events/blink/input_handler_proxy.cc
@@ -198,8 +198,7 @@ // Note: Other input can race ahead of gesture input as they don't have to go // through the queue, but we believe it's OK to do so. - if (!compositor_event_queue_ || - !IsGestureScrollOrPinch(event_with_callback->event().GetType())) { + if (!IsGestureScrollOrPinch(event_with_callback->event().GetType())) { DispatchSingleInputEvent(std::move(event_with_callback), tick_clock_->NowTicks()); return; @@ -254,8 +253,7 @@ void InputHandlerProxy::DispatchSingleInputEvent( std::unique_ptr<EventWithCallback> event_with_callback, const base::TimeTicks now) { - if (compositor_event_queue_ && - IsGestureScrollOrPinch(event_with_callback->event().GetType())) { + if (IsGestureScrollOrPinch(event_with_callback->event().GetType())) { // Report the coalesced count only for continuous events to avoid the noise // from non-continuous events. if (IsContinuousGestureEvent(event_with_callback->event().GetType())) { @@ -315,9 +313,6 @@ } void InputHandlerProxy::DispatchQueuedInputEvents() { - if (!compositor_event_queue_) - return; - // Calling |NowTicks()| is expensive so we only want to do it once. base::TimeTicks now = tick_clock_->NowTicks(); while (!compositor_event_queue_->empty()) { @@ -582,7 +577,7 @@ const WebGestureEvent& gesture_event) { TRACE_EVENT0("input", "InputHandlerProxy::HandleGestureScrollBegin"); - if (compositor_event_queue_ && scroll_predictor_) + if (scroll_predictor_) scroll_predictor_->ResetOnGestureScrollBegin(gesture_event); #if DCHECK_IS_ON()
diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc index 3fe6a6f..8e2b0d9 100644 --- a/ui/gfx/image/image.cc +++ b/ui/gfx/image/image.cc
@@ -368,11 +368,11 @@ Image::Image(const Image& other) = default; -Image::Image(Image&& other) = default; +Image::Image(Image&& other) noexcept = default; Image& Image::operator=(const Image& other) = default; -Image& Image::operator=(Image&& other) = default; +Image& Image::operator=(Image&& other) noexcept = default; Image::~Image() {}
diff --git a/ui/gfx/image/image.h b/ui/gfx/image/image.h index e33e535..d2dbcd28 100644 --- a/ui/gfx/image/image.h +++ b/ui/gfx/image/image.h
@@ -80,14 +80,14 @@ // Moves a reference from |other| to the new image without changing the // reference count. - Image(Image&& other); + Image(Image&& other) noexcept; // Copies a reference to |other|'s storage. Image& operator=(const Image& other); // Moves a reference from |other|'s storage without changing the reference // count. - Image& operator=(Image&& other); + Image& operator=(Image&& other) noexcept; // Deletes the image and, if the only owner of the storage, all of its cached // representations.
diff --git a/ui/views/cocoa/bridged_native_widget_host_impl.h b/ui/views/cocoa/bridged_native_widget_host_impl.h index d1a7fd5a..b661e41f 100644 --- a/ui/views/cocoa/bridged_native_widget_host_impl.h +++ b/ui/views/cocoa/bridged_native_widget_host_impl.h
@@ -274,6 +274,11 @@ bool GetWindowFrameTitlebarHeight(bool* override_titlebar_height, float* titlebar_height) override; void OnFocusWindowToolbar() override; + void SetRemoteAccessibilityTokens( + const std::vector<uint8_t>& window_token, + const std::vector<uint8_t>& view_token) override; + bool GetRootViewAccessibilityToken(int64_t* pid, + std::vector<uint8_t>* token) override; bool ValidateUserInterfaceItem( int32_t command, views_bridge_mac::mojom::ValidateUserInterfaceItemResultPtr* out_result) @@ -313,9 +318,8 @@ void GetCanWindowClose(GetCanWindowCloseCallback callback) override; void GetWindowFrameTitlebarHeight( GetWindowFrameTitlebarHeightCallback callback) override; - void GetAccessibilityTokens(const std::vector<uint8_t>& window_token, - const std::vector<uint8_t>& view_token, - GetAccessibilityTokensCallback callback) override; + void GetRootViewAccessibilityToken( + GetRootViewAccessibilityTokenCallback callback) override; void ValidateUserInterfaceItem( int32_t command, ValidateUserInterfaceItemCallback callback) override;
diff --git a/ui/views/cocoa/bridged_native_widget_host_impl.mm b/ui/views/cocoa/bridged_native_widget_host_impl.mm index 75d5c76..fffc715 100644 --- a/ui/views/cocoa/bridged_native_widget_host_impl.mm +++ b/ui/views/cocoa/bridged_native_widget_host_impl.mm
@@ -893,6 +893,27 @@ native_widget_mac_->OnFocusWindowToolbar(); } +void BridgedNativeWidgetHostImpl::SetRemoteAccessibilityTokens( + const std::vector<uint8_t>& window_token, + const std::vector<uint8_t>& view_token) { + remote_window_accessible_ = + ui::RemoteAccessibility::GetRemoteElementFromToken(window_token); + remote_view_accessible_ = + ui::RemoteAccessibility::GetRemoteElementFromToken(view_token); + [remote_view_accessible_ setWindowUIElement:remote_window_accessible_.get()]; + [remote_view_accessible_ + setTopLevelUIElement:remote_window_accessible_.get()]; +} + +bool BridgedNativeWidgetHostImpl::GetRootViewAccessibilityToken( + int64_t* pid, + std::vector<uint8_t>* token) { + *pid = getpid(); + id element_id = GetNativeViewAccessible(); + *token = ui::RemoteAccessibility::GetTokenForLocalElement(element_id); + return true; +} + bool BridgedNativeWidgetHostImpl::ValidateUserInterfaceItem( int32_t command, views_bridge_mac::mojom::ValidateUserInterfaceItemResultPtr* out_result) { @@ -1037,21 +1058,12 @@ std::move(callback).Run(override_titlebar_height, titlebar_height); } -void BridgedNativeWidgetHostImpl::GetAccessibilityTokens( - const std::vector<uint8_t>& window_token, - const std::vector<uint8_t>& view_token, - GetAccessibilityTokensCallback callback) { - remote_window_accessible_ = - ui::RemoteAccessibility::GetRemoteElementFromToken(window_token); - remote_view_accessible_ = - ui::RemoteAccessibility::GetRemoteElementFromToken(view_token); - [remote_view_accessible_ setWindowUIElement:remote_window_accessible_.get()]; - [remote_view_accessible_ - setTopLevelUIElement:remote_window_accessible_.get()]; - - id element_id = GetNativeViewAccessible(); - std::move(callback).Run( - getpid(), ui::RemoteAccessibility::GetTokenForLocalElement(element_id)); +void BridgedNativeWidgetHostImpl::GetRootViewAccessibilityToken( + GetRootViewAccessibilityTokenCallback callback) { + std::vector<uint8_t> token; + int64_t pid; + GetRootViewAccessibilityToken(&pid, &token); + std::move(callback).Run(pid, token); } void BridgedNativeWidgetHostImpl::ValidateUserInterfaceItem(
diff --git a/ui/views_bridge_mac/bridge_factory_impl.mm b/ui/views_bridge_mac/bridge_factory_impl.mm index d4ba3ea..c939c56 100644 --- a/ui/views_bridge_mac/bridge_factory_impl.mm +++ b/ui/views_bridge_mac/bridge_factory_impl.mm
@@ -41,12 +41,7 @@ if (!remote_accessibility_element_) { int64_t browser_pid = 0; std::vector<uint8_t> element_token; - host_ptr_->GetAccessibilityTokens( - ui::RemoteAccessibility::GetTokenForLocalElement( - bridge_impl_->ns_window()), - ui::RemoteAccessibility::GetTokenForLocalElement( - bridge_impl_->ns_view()), - &browser_pid, &element_token); + host_ptr_->GetRootViewAccessibilityToken(&browser_pid, &element_token); [NSAccessibilityRemoteUIElement registerRemoteUIProcessIdentifier:browser_pid]; remote_accessibility_element_ =
diff --git a/ui/views_bridge_mac/bridged_native_widget_impl.mm b/ui/views_bridge_mac/bridged_native_widget_impl.mm index 1ec64c2..72c6de9 100644 --- a/ui/views_bridge_mac/bridged_native_widget_impl.mm +++ b/ui/views_bridge_mac/bridged_native_widget_impl.mm
@@ -19,6 +19,7 @@ #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" #include "ui/base/cocoa/cocoa_base_utils.h" #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" +#include "ui/base/cocoa/remote_accessibility_api.h" #import "ui/base/cocoa/window_size_constants.h" #include "ui/base/hit_test.h" #include "ui/base/layout.h" @@ -520,6 +521,11 @@ // this should be treated as an error and caught early. CHECK(bridged_view_); + // Send the accessibility tokens for the NSView now that it exists. + host_->SetRemoteAccessibilityTokens( + ui::RemoteAccessibility::GetTokenForLocalElement(window_), + ui::RemoteAccessibility::GetTokenForLocalElement(bridged_view_)); + // Beware: This view was briefly removed (in favor of a bare CALayer) in // crrev/c/1236675. The ordering of unassociated layers relative to NSView // layers is undefined on macOS 10.12 and earlier, so the compositor layer
diff --git a/ui/views_bridge_mac/mojo/bridged_native_widget_host.mojom b/ui/views_bridge_mac/mojo/bridged_native_widget_host.mojom index b94a097b..40ea3fed 100644 --- a/ui/views_bridge_mac/mojo/bridged_native_widget_host.mojom +++ b/ui/views_bridge_mac/mojo/bridged_native_widget_host.mojom
@@ -192,13 +192,14 @@ // Handle "Move focus to the window toolbar" shortcut. OnFocusWindowToolbar(); - // Return in |element_token| the token for the AX node for this view. Return - // the pid of the browser process to be registered as a remote UI process. Set - // the AX node for this view to have the element indicated by |window_token| - // as its window and the element indicated by |view_token| as its parent. + // Send the token for the NSWindow and NSView for this widget. + SetRemoteAccessibilityTokens( + array<uint8> window_token, array<uint8> view_token); + + // Return in |element_token| the token for the root views AX node for this + // view and in |host_pid| the pid for the host process. [Sync] - GetAccessibilityTokens(array<uint8> window_token, - array<uint8> view_token) => + GetRootViewAccessibilityToken() => (int64 host_pid, array<uint8> element_token); // Return the result for -[NSUserInterfaceValidations